From fed07c01ce0c874365bc2fb614aa1a195e40e582 Mon Sep 17 00:00:00 2001 From: Wyatt Lowery Date: Sat, 16 May 2026 19:34:26 -0500 Subject: [PATCH 01/12] Math primitive inlien functions for block diagrams [skip ci] --- GridKit/CommonMath.hpp | 93 +++++++++++++++++++ GridKit/CommonMath.md | 66 +++++++++---- .../Math/SmoothnessIndicatorTests.hpp | 79 ++++++++++++++++ .../Math/runSmoothnessIndicatorTests.cpp | 4 + 4 files changed, 222 insertions(+), 20 deletions(-) diff --git a/GridKit/CommonMath.hpp b/GridKit/CommonMath.hpp index 7077c2076..ba119af79 100644 --- a/GridKit/CommonMath.hpp +++ b/GridKit/CommonMath.hpp @@ -29,6 +29,99 @@ namespace GridKit return ONE / (ONE + std::exp(-MU * x)); } + /** + * @brief Smooth one-sided ramp function + * + * Smooth approximation to max(x, 0), using a stable softplus form with + * the same scale as the rest of CommonMath. + * + * @tparam ScalarT - scalar data type + * + * @param[in] x - expected to be of order 1 + * @return value of the smooth ramp function + */ + template + __attribute__((always_inline)) inline ScalarT ramp(const ScalarT x) + { + using RealT = typename GridKit::ScalarTraits::RealT; + static constexpr RealT MU = 240.0; + + if (x > ZERO) + { + return x + (ONE / MU) * std::log(ONE + std::exp(-MU * x)); + } + + return (ONE / MU) * std::log(ONE + std::exp(MU * x)); + } + + /** + * @brief Smooth clamp function + * + * Smooth approximation to min(max(x, lower), upper), composed from the + * smooth ramp function. + * + * @tparam ScalarT - scalar data type + * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * + * @param[in] x - expected to be of order 1 + * @param[in] lower - Lower limit + * @param[in] upper - Upper limit + * @return value of the smooth clamp function + */ + template + __attribute__((always_inline)) inline ScalarT clamp( + const ScalarT x, + const RealT lower, + const RealT upper) + { + return lower + ramp(x - lower) - ramp(x - upper); + } + + /** + * @brief Smooth slew-rate limiter + * + * Smooth approximation to min(max(f, -rate), rate). + * + * @tparam ScalarT - scalar data type + * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * + * @param[in] f - Pre-limit derivative or rate signal + * @param[in] rate - Symmetric positive rate limit + * @return Slew-rate-limited value of f + */ + template + __attribute__((always_inline)) inline ScalarT slew( + const ScalarT f, + const RealT rate) + { + return clamp(f, -rate, rate); + } + + /** + * @brief Smooth saturating ramp function + * + * Smooth approximation to a monotone linear ramp saturating from zero to + * height over the interval [lower, upper]. + * + * @tparam ScalarT - scalar data type + * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * + * @param[in] x - Input signal + * @param[in] lower - Lower breakpoint + * @param[in] upper - Upper breakpoint + * @param[in] height - Saturated value above the upper breakpoint + * @return Saturating ramp value + */ + template + __attribute__((always_inline)) inline ScalarT rampsat( + const ScalarT x, + const RealT lower, + const RealT upper, + const RealT height) + { + return height / (upper - lower) * (ramp(x - lower) - ramp(x - upper)); + } + /** * @brief Derivative of the scaled sigmoid activation function * (i.e., approximation to the delta dirac function) diff --git a/GridKit/CommonMath.md b/GridKit/CommonMath.md index c4369c303..a8631d5d6 100644 --- a/GridKit/CommonMath.md +++ b/GridKit/CommonMath.md @@ -1,34 +1,51 @@ # CommonMath -Numerical utilities in [CommonMath.hpp](CommonMath.hpp): smooth, autodiff-friendly replacements for piecewise functions used across GridKit component models. +Smooth, autodiff-friendly replacements for piecewise functions used across GridKit component models. See [CommonMath.hpp](CommonMath.hpp) for implementation details. -## Sigmoid +## Primitives -Smooth approximation to the step function. +| Name | Exact Target | Smooth Approximation | Description | +|------|--------------|----------------------|-------------| +| `sigmoid` | $H(x)$ | $\sigma(x) = \frac{1}{1+\exp(-\mu x)}$ | Step function | +| `ramp` | $\max(x,0)$ | $\rho(x)=\mu^{-1}\log(1+\exp(\mu x))$ | Smooth one-sided ramp | + +The scale $\mu=240$ is chosen so $\sigma$ behaves like a step on inputs of order 1 while keeping derivatives finite. As $\mu \to \infty$, these functions approach their exact targets. + +Softplus avoids the negative undershoot of $x\sigma(x)$, with a small positive breakpoint bias: ```math -\sigma(x) = \dfrac{1}{1+\exp(-\alpha x)} +\rho(0)=\frac{\log 2}{\mu}. ``` -The scale $\alpha$ (currently $240$) is chosen large enough that $\sigma$ behaves as a step on inputs of order 1. +## Derived Functions -## Limit Indicators +| Name | Exact Target | Smooth Approximation | Description | +|------|--------------|----------------------|-------------| +| `clamp` | $\min(\max(x,\ell),u)$ | $\ell + \rho(x-\ell) - \rho(x-u)$ | Bounded saturation | +| `slew` | $\min(\max(f,-r),r)$ | $-r + \rho(f+r) - \rho(f-r)$ | Symmetric slew-rate limiter | +| `rampsat` | $h\,\operatorname{clamp}\!\left(\frac{x-a}{b-a},0,1\right)$ | $\frac{h}{b-a}\left[\rho(x-a)-\rho(x-b)\right]$ | Saturating linear ramp | -For a state variable $x$ with limits $(x_{\min}, x_{\max})$: +`rampsat` is a monotone saturating linear ramp, implemented as the difference of two smooth ramps: ```math -\begin{aligned} - \phi_L(x) &= \sigma(x - x_{\min}) \\ - \phi_U(x) &= \sigma(x_{\max} - x) \\ - \phi_0(x) &= \phi_L + \phi_U - 1 -\end{aligned} +\operatorname{rampsat}(x;\,a,b,h) += +\frac{h}{b-a}\left[\rho(x-a)-\rho(x-b)\right]. ``` -$\phi_L$ and $\phi_U$ are soft indicators for "above lower limit" and "below upper limit"; their product (or $\phi_0$) is an interior indicator. +It is not a signal-processing window function. + +## Anti-Windup + +For a limited state $x \in [x_{\min}, x_{\max}]$, the indicators are: -## Anti-Windup Indicator +| Name | Exact Target | Smooth Approximation | Description | +|------|--------------|----------------------|-------------| +| $\phi_L$ | $H(x-x_{\min})$ | $\sigma(x-x_{\min})$ | Above-lower-limit indicator | +| $\phi_U$ | $H(x_{\max}-x)$ | $\sigma(x_{\max}-x)$ | Below-upper-limit indicator | +| $\phi_0$ | $\begin{cases}1 & x_{\min} + #include #include @@ -14,6 +16,83 @@ namespace GridKit SmoothnessIndicatorTests() = default; ~SmoothnessIndicatorTests() = default; + TestOutcome clamp() + { + TestStatus success = true; + + const ScalarT lower = -0.25; + const ScalarT upper = 0.75; + + success *= (Math::clamp(static_cast(-1.0), lower, upper) < lower + static_cast(0.01)); + success *= (Math::clamp(static_cast(0.4), lower, upper) > lower); + success *= (Math::clamp(static_cast(0.4), lower, upper) < upper); + success *= (Math::clamp(static_cast(1.5), lower, upper) > upper - static_cast(0.01)); + + return success.report(__func__); + } + + TestOutcome slew() + { + TestStatus success = true; + + const ScalarT rate = 0.5; + + success *= (Math::slew(static_cast(2.0), rate) < static_cast(0.51)); + success *= (Math::slew(static_cast(-2.0), rate) > static_cast(-0.51)); + success *= (Math::slew(static_cast(0.2), rate) > static_cast(0.19)); + success *= (Math::slew(static_cast(-0.2), rate) < static_cast(-0.19)); + + return success.report(__func__); + } + + TestOutcome rampsat() + { + TestStatus success = true; + + success *= (Math::rampsat(static_cast(-1.0), + static_cast(0.0), + static_cast(2.0), + static_cast(4.0)) < static_cast(0.01)); + success *= (Math::rampsat(static_cast(1.0), + static_cast(0.0), + static_cast(2.0), + static_cast(4.0)) > static_cast(1.99)); + success *= (Math::rampsat(static_cast(1.0), + static_cast(0.0), + static_cast(2.0), + static_cast(4.0)) < static_cast(2.01)); + success *= (Math::rampsat(static_cast(3.0), + static_cast(0.0), + static_cast(2.0), + static_cast(4.0)) > static_cast(3.99)); + + return success.report(__func__); + } + + TestOutcome ramp() + { + TestStatus success = true; + + const ScalarT tau = static_cast(1.0 / 240.0); + const ScalarT at_zero = tau * std::log(static_cast(2.0)); + + success *= (Math::ramp(static_cast(1.0)) > static_cast(0.99)); + success *= (Math::ramp(static_cast(-1.0)) < static_cast(0.01)); + success *= (std::abs(Math::ramp(static_cast(0.0)) - at_zero) < static_cast(1.0e-12)); + success *= (Math::ramp(static_cast(-0.01)) > static_cast(0.0)); + success *= (Math::ramp(static_cast(0.01)) > Math::ramp(static_cast(0.0))); + + const ScalarT lower = -0.25; + const ScalarT upper = 0.75; + const ScalarT x = 0.4; + + const ScalarT smooth_clip = lower + Math::ramp(x - lower) - Math::ramp(x - upper); + success *= (smooth_clip > lower); + success *= (smooth_clip < upper); + + return success.report(__func__); + } + TestOutcome antiWindupIndicator() { TestStatus success = true; diff --git a/tests/UnitTests/Math/runSmoothnessIndicatorTests.cpp b/tests/UnitTests/Math/runSmoothnessIndicatorTests.cpp index 3da97577f..6edb891f0 100644 --- a/tests/UnitTests/Math/runSmoothnessIndicatorTests.cpp +++ b/tests/UnitTests/Math/runSmoothnessIndicatorTests.cpp @@ -6,6 +6,10 @@ int main() GridKit::Testing::SmoothnessIndicatorTests test; + result += test.clamp(); + result += test.slew(); + result += test.rampsat(); + result += test.ramp(); result += test.antiWindupIndicator(); return result.summary(); From 56685938b35af7a566369f4c20f39a0eb3c239e7 Mon Sep 17 00:00:00 2001 From: lukelowry Date: Sun, 17 May 2026 12:56:21 -0500 Subject: [PATCH 02/12] Improve math primitives with branchless ramp --- .../DependencyTracking/VariableOperators.hpp | 7 +++++ GridKit/CommonMath.hpp | 10 +++---- GridKit/CommonMath.md | 4 +-- .../PhasorDynamics/Exciter/IEEET1/README.md | 6 ++--- .../Stabilizer/IEEEST/README.md | 12 ++++++--- .../Math/SmoothnessIndicatorTests.hpp | 26 ++++++++++++++----- 6 files changed, 44 insertions(+), 21 deletions(-) diff --git a/GridKit/AutomaticDifferentiation/DependencyTracking/VariableOperators.hpp b/GridKit/AutomaticDifferentiation/DependencyTracking/VariableOperators.hpp index 5f2ed91ba..de7a29008 100644 --- a/GridKit/AutomaticDifferentiation/DependencyTracking/VariableOperators.hpp +++ b/GridKit/AutomaticDifferentiation/DependencyTracking/VariableOperators.hpp @@ -311,6 +311,12 @@ namespace GridKit return 1.0 / x; } + /// Derivative of log(1 + x). + inline double log1p_derivative(double x) + { + return 1.0 / (1.0 + x); + } + /// Derivative of logarithm to base 10 function: 1/(x*log(10)). inline double log10_derivative(double x) { @@ -377,6 +383,7 @@ namespace std IMPL_FUN_1(tanh, GridKit::DependencyTracking::tanh_derivative) IMPL_FUN_1(exp, GridKit::DependencyTracking::exp_derivative) IMPL_FUN_1(log, GridKit::DependencyTracking::log_derivative) + IMPL_FUN_1(log1p, GridKit::DependencyTracking::log1p_derivative) IMPL_FUN_1(log10, GridKit::DependencyTracking::log10_derivative) IMPL_FUN_1(sqrt, GridKit::DependencyTracking::sqrt_derivative) IMPL_FUN_1(abs, GridKit::DependencyTracking::abs_derivative) diff --git a/GridKit/CommonMath.hpp b/GridKit/CommonMath.hpp index ba119af79..1bd330d14 100644 --- a/GridKit/CommonMath.hpp +++ b/GridKit/CommonMath.hpp @@ -46,12 +46,9 @@ namespace GridKit using RealT = typename GridKit::ScalarTraits::RealT; static constexpr RealT MU = 240.0; - if (x > ZERO) - { - return x + (ONE / MU) * std::log(ONE + std::exp(-MU * x)); - } - - return (ONE / MU) * std::log(ONE + std::exp(MU * x)); + ScalarT z = MU * x; + ScalarT a = std::abs(z); + return (HALF * (z + a) + std::log1p(std::exp(-a))) / MU; } /** @@ -180,6 +177,7 @@ namespace GridKit * @tparam ScalarT - Scalar data type * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) * + * @param[in] limit_min - Minimum limit * @param[in] limit_max - Maximum limit * @param[in] x - State variable * @return Scalar value indicating limit activation diff --git a/GridKit/CommonMath.md b/GridKit/CommonMath.md index a8631d5d6..af75ef7f7 100644 --- a/GridKit/CommonMath.md +++ b/GridKit/CommonMath.md @@ -83,6 +83,6 @@ Anti-windup gate (`Math::indicator`): - [TGOV1](Model/PhasorDynamics/Governor/Tgov1/README.md): gates $\dot P_v$ on $P_v \in (P_{vmin}, P_{vmax})$ - [SEXS-PTI](Model/PhasorDynamics/Exciter/SEXS-PTI/README.md): gates $\dot E_{fd}$ on $E_{fd} \in (E_{fd,\min}, E_{fd,\max})$ -Interior indicator (`Math::indicator_zero`): +Window gate (`Math::sigmoid((x - lower)(upper - x) / (upper - lower))`): -- [IEEEST](Model/PhasorDynamics/Stabilizer/IEEEST/README.md): clips stabilizer output $v_7$ to $[L_{s\min}, L_{s\max}]$ +- [IEEEST](Model/PhasorDynamics/Stabilizer/IEEEST/README.md): gates $V_s$ by the $V_{ct}$ cutout window $[V_{cl}, V_{cu}]$ diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md index 7b2c6e358..ccac7885e 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md @@ -162,11 +162,11 @@ For the algebraic piecewise functions (non-flags), this implementation is straig E_{fd} &=(1 + \omega I_{spdlm})E_{fd}' \\ k_{sat} - &=S_B\left[(E_{fd}' -S_A) \cdot \sigma (E_{fd}' -S_A)\right]^2 + &=S_B\left[(E_{fd}' -S_A) \cdot \sigma (E_{fd}' -S_A)\right]^2 \end{aligned} ``` -The approximation approaches an exact solution as $\alpha\to\infty$. +The approximation approaches an exact solution as the sigmoid steepness increases. ## Initialization @@ -192,4 +192,4 @@ All internal derivatives initialize to zero. The field voltage, $E_{fd}$, is an internal model variable. -The magnetic saturation coefficient $k_{sat}$ is calculated from $E_{fd}$ using the the smooth piecewise version (above). +The magnetic saturation coefficient $k_{sat}$ is calculated from $E_{fd}$ using the smooth piecewise version above. diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/README.md b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/README.md index 7a5e7b57c..4bf26c3fe 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/README.md +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/README.md @@ -32,8 +32,8 @@ $T_4$ | [s] | Lead–lag 2 denominator time constant | 0.0 $T_5$ | [s] | Washout numerator time constant | 1.65 $T_6$ | [s] | Washout denominator time constant | 1.65 $K_s$ | [p.u.] | Stabilizer gain | 3.0 -$L_{s\min}$ | [p.u.] | Minimum stabilizer output limit | 0.1 -$L_{s\max}$ | [p.u.] | Maximum stabilizer output limit | -0.1 +$L_{s\min}$ | [p.u.] | Minimum stabilizer output limit | -0.1 +$L_{s\max}$ | [p.u.] | Maximum stabilizer output limit | 0.1 $V_{cl}$ | [p.u.] | Lower input cutout threshold | 0.0 $V_{cu}$ | [p.u.] | Upper input cutout threshold | 0.0 $T_{delay}$ | [s] | Input time delay | 0.0 @@ -115,7 +115,7 @@ $V_{ct}$ | [p.u.] | Cutout signal (compared to $V_{cl},V_{cu}$) | from the block 0 &= -v_5 + x_5 + \dfrac{T_1}{T_2}(v_4 - x_5) \\ 0 &= -v_6 + x_6 + \dfrac{T_3}{T_4}(v_5 - x_6) \\ 0 &= -v_7 + K_s \dfrac{T_5}{T_6}(v_6 - x_7) \\ -0 &= -V_{ss} + \min\!\big(\max(v_7, L_{s\min}), L_{s\max}\big) \\ +0 &= -V_{ss} + \operatorname{clamp}(v_7,L_{s\min},L_{s\max}) \\ 0 &= -V_s + \begin{cases} V_{ss}, & V_{cl} < V_{ct} < V_{cu} \\ @@ -123,3 +123,9 @@ V_{ss}, & V_{cl} < V_{ct} < V_{cu} \\ \end{cases} \end{aligned} ``` + +In simulation, the output limiter uses a smooth clamp approximation. +The cutout case statement is smoothed as the product of lower and upper +sigmoid indicators, $\sigma(V_{ct}-V_{cl})\sigma(V_{cu}-V_{ct})$. +The parameter convention $V_{cl}=V_{cu}=0$ disables the cutout and passes +$V_{ss}$ through. diff --git a/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp b/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp index a98e64a5b..f7588faaf 100644 --- a/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp +++ b/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp @@ -52,19 +52,23 @@ namespace GridKit success *= (Math::rampsat(static_cast(-1.0), static_cast(0.0), static_cast(2.0), - static_cast(4.0)) < static_cast(0.01)); + static_cast(4.0)) + < static_cast(0.01)); success *= (Math::rampsat(static_cast(1.0), static_cast(0.0), static_cast(2.0), - static_cast(4.0)) > static_cast(1.99)); + static_cast(4.0)) + > static_cast(1.99)); success *= (Math::rampsat(static_cast(1.0), static_cast(0.0), static_cast(2.0), - static_cast(4.0)) < static_cast(2.01)); + static_cast(4.0)) + < static_cast(2.01)); success *= (Math::rampsat(static_cast(3.0), static_cast(0.0), static_cast(2.0), - static_cast(4.0)) > static_cast(3.99)); + static_cast(4.0)) + > static_cast(3.99)); return success.report(__func__); } @@ -81,14 +85,22 @@ namespace GridKit success *= (std::abs(Math::ramp(static_cast(0.0)) - at_zero) < static_cast(1.0e-12)); success *= (Math::ramp(static_cast(-0.01)) > static_cast(0.0)); success *= (Math::ramp(static_cast(0.01)) > Math::ramp(static_cast(0.0))); + success *= std::isfinite(Math::ramp(static_cast(4.0))); + success *= (Math::ramp(static_cast(4.0)) > static_cast(3.99)); + success *= std::isfinite(Math::ramp(static_cast(-4.0))); + success *= (Math::ramp(static_cast(-4.0)) < static_cast(1.0e-12)); const ScalarT lower = -0.25; const ScalarT upper = 0.75; const ScalarT x = 0.4; - const ScalarT smooth_clip = lower + Math::ramp(x - lower) - Math::ramp(x - upper); - success *= (smooth_clip > lower); - success *= (smooth_clip < upper); + const ScalarT smooth_clip = lower + Math::ramp(x - lower) - Math::ramp(x - upper); + success *= (smooth_clip > lower); + success *= (smooth_clip < upper); + success *= std::isfinite(Math::clamp(static_cast(4.0), lower, upper)); + success *= (Math::clamp(static_cast(4.0), lower, upper) < upper + static_cast(1.0e-12)); + success *= std::isfinite(Math::clamp(static_cast(-4.0), lower, upper)); + success *= (Math::clamp(static_cast(-4.0), lower, upper) > lower - static_cast(1.0e-12)); return success.report(__func__); } From 9af3e016857722880329c870ffd6bb187786916e Mon Sep 17 00:00:00 2001 From: lukelowry Date: Sun, 17 May 2026 13:04:20 -0500 Subject: [PATCH 03/12] Add REGCA converter documentation --- .../Model/PhasorDynamics/Converter/README.md | 13 + .../PhasorDynamics/Converter/REGCA/README.md | 311 ++++++++++++++++++ .../PhasorDynamics/Converter/REGCB/README.md | 112 +++++++ docs/Figures/PhasorDynamics_REGCA_Diagram.png | Bin 0 -> 89982 bytes docs/Figures/PhasorDynamics_REGCB_Diagram.png | Bin 0 -> 119201 bytes examples/PhasorDynamics/Large/WECC/README.md | 2 +- .../PhasorDynamics/Medium/Hawaii/README.md | 2 +- 7 files changed, 438 insertions(+), 2 deletions(-) create mode 100644 GridKit/Model/PhasorDynamics/Converter/README.md create mode 100644 GridKit/Model/PhasorDynamics/Converter/REGCA/README.md create mode 100644 GridKit/Model/PhasorDynamics/Converter/REGCB/README.md create mode 100644 docs/Figures/PhasorDynamics_REGCA_Diagram.png create mode 100644 docs/Figures/PhasorDynamics_REGCB_Diagram.png diff --git a/GridKit/Model/PhasorDynamics/Converter/README.md b/GridKit/Model/PhasorDynamics/Converter/README.md new file mode 100644 index 000000000..cb5902190 --- /dev/null +++ b/GridKit/Model/PhasorDynamics/Converter/README.md @@ -0,0 +1,13 @@ +# **Converter Models** + +## Introduction + +Converter models represent inverter-coupled resources in the phasor dynamics model. They provide the network interface between renewable-energy control +models and the bus equations, typically through commanded active and reactive current components. + +## Types + +The GridKit converter documentation includes: + +- Renewable Energy Generator/Converter Model REGCA (See [REGCA](REGCA/README.md)) +- Renewable Energy Generator/Converter Model REGCB (See [REGCB](REGCB/README.md)) diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md b/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md new file mode 100644 index 000000000..9e61ca924 --- /dev/null +++ b/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md @@ -0,0 +1,311 @@ +# **Renewable Energy Generator/Converter Model (REGCA)** + +REGCA is a first-generation WECC renewable generator/converter model for +inverter-coupled resources. In GridKit it is represented as a controlled +current source at the network interface. + +Notes: +- LVACM uses the unfiltered terminal voltage $V_T$; LVPL uses the filtered voltage $V_M$. +- Internal currents are on converter base; bus injections are converted to system base in the network interface. +- HVRCM is represented by internal algebraic current $I_{\mathrm{q}}^{\mathrm{extra}}$. + +## Block Diagram + +Standard REGCA converter-interface model. + +
+ + + Figure 1: Generator/Converter REGCA model. Figure courtesy of [PowerWorld](https://www.powerworld.com/WebHelp/) +
+ +## Model Parameters + +Symbol | Units | Description | Typical Value | Note +---------------------------------|----------|-------------------------------------------------------|---------------|------ +$P_{\mathrm{0}}$ | [p.u.] | Initial active power injection | | On system base +$Q_{\mathrm{0}}$ | [p.u.] | Initial reactive power injection | | On system base +$S^{\mathrm{conv}}$ | [MVA] | Converter/model power base | TBD | +$T_{\mathrm{g}}$ | [sec] | Converter current-control lag time constant | TBD | +$T_M$ | [sec] | Terminal voltage sensor time constant | TBD | Block name: `Tfltr` +$R_{\mathrm{q}}^{\max}$ | [p.u./s] | Reactive-current recovery positive rate limit | TBD | Block name: `Iqrmax` +$R_{\mathrm{q}}^{\min}$ | [p.u./s] | Reactive-current recovery negative rate limit | TBD | Block name: `Iqrmin` +$R_{\mathrm{p}}^{\max}$ | [p.u./s] | Active-current magnitude recovery rate limit | TBD | Block name: `rrpwr` +$s_L$ | [binary] | LVPL switch | TBD | Block name: `LPVLSW` +$I_{L1}$ | [p.u.] | LVPL upper-current ceiling | TBD | Block name: `Lvpl1` +$V_{L0}$ | [p.u.] | LVPL zero-crossing voltage | TBD | Block name: `xerox` +$V_{L1}$ | [p.u.] | LVPL upper breakpoint voltage | TBD | Block name: `brkpt` +$V_{A0}$ | [p.u.] | LVACM lower breakpoint voltage | TBD | Block name: `Lvpnt0` +$V_{A1}$ | [p.u.] | LVACM upper breakpoint voltage | TBD | Block name: `Lvpnt1` +$V_{\mathrm{hv}}^{\max}$ | [p.u.] | Terminal-voltage ceiling for HV reactive management | TBD | Block name: `Vlim` + +### Parameter Validation + +Implementations should reject or report invalid parameter sets: + +```math +\begin{aligned} + S^{\mathrm{conv}} &> 0 & + T_{\mathrm{g}} &> 0 & + T_M &> 0 \\ + R_{\mathrm{p}}^{\max} &> 0 & + R_{\mathrm{q}}^{\min} &< 0 < R_{\mathrm{q}}^{\max} & + s_L &\in \{0,1\} \\ + I_{L1} &\ge 0 & + 0 &\le V_{L0} < V_{L1} & + 0 &\le V_{A0} < V_{A1} \\ + V_{\mathrm{hv}}^{\max} &> 0 +\end{aligned} +``` + +### Model Derived Parameters + +The smooth active-current bound equations use $M_{\mathrm{p}}$, a numerical +relaxation for inactive $\pm\infty$ rate bounds: + +```math +M_{\mathrm{p}} = 100 R_{\mathrm{p}}^{\max} +``` + +$M_{\mathrm{p}}$ is not a physical REGCA parameter; it should be large enough +that inactive bounds do not bind expected $f_{\mathrm{p}}$ values while staying +moderate enough to keep the smooth clamp well conditioned. + +## Model Variables + +### Internal Variables + +#### Differential + +Symbol | Units | Description | Note +----------------------|--------|---------------------------|------ +$V_M$ | [p.u.] | Filtered terminal voltage | State 3 in Fig. 1 +$I_{\mathrm{q}}$ | [p.u.] | Reactive-current state | State 1 in Fig. 1 before the `-1` block; converter base +$I_{\mathrm{p}}$ | [p.u.] | Active-current state | State 2 in Fig. 1; converter base + +#### Algebraic + +Symbol | Units | Description | Note +---------------------------|--------|-------------------------------------------------------------|------ +$V_T$ | [p.u.] | Terminal voltage magnitude | +$I_{\mathrm{i}}$ | [p.u.] | Injected current, imaginary component on network reference frame | Converter base +$I_{\mathrm{q}}^{\mathrm{extra}}$ | [p.u.] | Extra inductive current from high-voltage reactive current management | Converter base +$I_L$ | [p.u.] | LVPL upper-limit current curve | Function of $V_M$ +$I_{\mathrm{r}}$ | [p.u.] | Injected current, real component on network reference frame | Converter base +$\ell_{\mathrm{p}}$ | [p.u./s] | Smooth active-current lower rate bound | Equivalent to diagram `Rdown` +$u_{\mathrm{p}}$ | [p.u./s] | Smooth active-current upper rate bound | Effective `Rup`; includes LVPL anti-windup when $s_L=1$ + +### External Variables + +#### Differential +None. + +#### Algebraic + +Symbol | Units | Description | Note +--------------------------------|--------|------------------------------------------------------------------|------ +$V_{\mathrm{r}}$ | [p.u.] | Terminal voltage, real component on network reference frame | Owned by bus object +$V_{\mathrm{i}}$ | [p.u.] | Terminal voltage, imaginary component on network reference frame | Owned by bus object +$I_{\mathrm{q}}^{\mathrm{cmd}}$ | [p.u.] | Reactive-current command | Converter base; owned by REEC, constant if no REEC is connected +$I_{\mathrm{p}}^{\mathrm{cmd}}$ | [p.u.] | Active-current command | Converter base; owned by REEC, constant if no REEC is connected + +## Model Equations + +Define the pre-limit current derivatives: + +```math +\begin{aligned} + f_{\mathrm{q}} &= \dfrac{1}{T_{\mathrm{g}}}(I_{\mathrm{q}}^{\mathrm{cmd}} - I_{\mathrm{q}}) \\ + f_{\mathrm{p}} &= \dfrac{1}{T_{\mathrm{g}}}(I_{\mathrm{p}}^{\mathrm{cmd}} - I_{\mathrm{p}}) +\end{aligned} +``` + +### Differential Equations + +The exact state equations are + +```math +\begin{aligned} + \dot V_M &= \dfrac{1}{T_M}(V_T - V_M) \\ + \dot I_{\mathrm{q}} &= + \begin{cases} + \min(f_{\mathrm{q}}, R_{\mathrm{q}}^{\max}) & Q_{\mathrm{0}} > 0 \\ + \max(f_{\mathrm{q}}, R_{\mathrm{q}}^{\min}) & Q_{\mathrm{0}} \le 0 + \end{cases} \\ + \dot I_{\mathrm{p}} &= \operatorname{clamp}(f_{\mathrm{p}}, \ell_{\mathrm{p}}, u_{\mathrm{p}}) +\end{aligned} +``` + +The implemented smooth state equations are + +```math +\begin{aligned} + \dot V_M &= \dfrac{1}{T_M}(V_T - V_M) \\ + \dot I_{\mathrm{q}} &= + \begin{cases} + f_{\mathrm{q}} - \rho(f_{\mathrm{q}} - R_{\mathrm{q}}^{\max}) + & Q_{\mathrm{0}} > 0 \\ + f_{\mathrm{q}} + \rho(R_{\mathrm{q}}^{\min} - f_{\mathrm{q}}) + & Q_{\mathrm{0}} \le 0 + \end{cases} \\ + \dot I_{\mathrm{p}} &= + \ell_{\mathrm{p}} + + \rho(f_{\mathrm{p}} - \ell_{\mathrm{p}}) + - \rho(f_{\mathrm{p}} - u_{\mathrm{p}}) +\end{aligned} +``` + +Here $\rho$ is GridKit's smooth ramp function. The $I_{\mathrm{q}}$ branch is +selected by initial reactive power $Q_{\mathrm{0}}$. The $I_{\mathrm{p}}$ +equation is the smooth clamp of $f_{\mathrm{p}}$ between the algebraic bounds +$\ell_{\mathrm{p}}$ and $u_{\mathrm{p}}$. + +### Algebraic Equations + +The piecewise definitions in this section switch on continuous states, unlike +the $I_{\mathrm{q}}$ differential branch selected by initial conditions. The +exact algebraic targets are: + +```math +\begin{aligned} + V_T &= \sqrt{V_{\mathrm{r}}^2 + V_{\mathrm{i}}^2} \\ + I_{\mathrm{i}} &= -I_{\mathrm{q}} + I_{\mathrm{q}}^{\mathrm{extra}} \\ + 0 &= + \begin{cases} + I_{\mathrm{q}}^{\mathrm{extra}} + & V_T < V_{\mathrm{hv}}^{\max} \\ + V_T - V_{\mathrm{hv}}^{\max} + & I_{\mathrm{q}}^{\mathrm{extra}} > 0 + \end{cases} \\ + I_L &= I_{L1} + \begin{cases} + 0 & V_M \le V_{L0} \\ + \dfrac{V_M - V_{L0}}{V_{L1} - V_{L0}} & V_{L0} < V_M < V_{L1} \\ + 1 & V_M \ge V_{L1} + \end{cases} \\ + I_{\mathrm{r}} &= I_{\mathrm{p}} + \begin{cases} + 0 & V_T \le V_{A0} \\ + \dfrac{V_T - V_{A0}}{V_{A1} - V_{A0}} & V_{A0} < V_T < V_{A1} \\ + 1 & V_T \ge V_{A1} + \end{cases} \\ + \ell_{\mathrm{p}} &= + \begin{cases} + -R_{\mathrm{p}}^{\max} & I_{\mathrm{p}} \le 0 \\ + -\infty & I_{\mathrm{p}} > 0 + \end{cases} \\ + u_{\mathrm{p}} &= + \begin{cases} + R_{\mathrm{p}}^{\max} & I_{\mathrm{p}} \ge 0 \ \land\ (s_L = 0 \lor I_{\mathrm{p}} < I_L) \\ + 0 & s_L = 1 \ \land\ I_{\mathrm{p}} \ge I_L \\ + \infty & I_{\mathrm{p}} < 0 + \end{cases} +\end{aligned} +``` + +The implemented algebraic residuals use smooth $\operatorname{rampsat}$, +$\rho$, and $\sigma$ operators: + +```math +\begin{aligned} + 0 &= V_T^2 - V_{\mathrm{r}}^2 - V_{\mathrm{i}}^2 \\ + 0 &= -I_{\mathrm{i}} - I_{\mathrm{q}} + I_{\mathrm{q}}^{\mathrm{extra}} \\ + 0 &= -I_{\mathrm{q}}^{\mathrm{extra}} + + \rho\!\left(I_{\mathrm{q}}^{\mathrm{extra}} - (V_{\mathrm{hv}}^{\max} - V_T)\right) \\ + 0 &= -I_L + + \operatorname{rampsat}(V_M;\ V_{L0},\ V_{L1},\ I_{L1}) \\ + 0 &= -I_{\mathrm{r}} + + I_{\mathrm{p}}\operatorname{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1) \\ + 0 &= -\ell_{\mathrm{p}} + - R_{\mathrm{p}}^{\max} + - (M_{\mathrm{p}} - R_{\mathrm{p}}^{\max})\sigma(I_{\mathrm{p}}) \\ + 0 &= -u_{\mathrm{p}} + + \begin{cases} + M_{\mathrm{p}}(1-\sigma(I_{\mathrm{p}})) + + R_{\mathrm{p}}^{\max}\sigma(I_{\mathrm{p}}) + \sigma(I_L - I_{\mathrm{p}}) + & s_L = 1 \\ + M_{\mathrm{p}}(1-\sigma(I_{\mathrm{p}})) + + R_{\mathrm{p}}^{\max}\sigma(I_{\mathrm{p}}) + & s_L = 0 + \end{cases} +\end{aligned} +``` + +The $V_T$ residual is kept in squared form for smoothness at the origin. + +## Network Interface + +The bus receives system-base current injections converted from converter-base +REGCA currents: + +```math +\begin{aligned} + I_{\mathrm{r}}^{\mathrm{inj}} &:= I_{\mathrm{r}}\dfrac{S^{\mathrm{conv}}}{S^{\mathrm{sys}}} \\ + I_{\mathrm{i}}^{\mathrm{inj}} &:= I_{\mathrm{i}}\dfrac{S^{\mathrm{conv}}}{S^{\mathrm{sys}}} +\end{aligned} +``` + +Positive current injection is into the bus. + +## Initialization + +Given initialized bus voltage $V_{\mathrm{r}}, V_{\mathrm{i}}$, compute the +steady-state initial values: + +```math +\begin{aligned} + V_T &= \sqrt{V_{\mathrm{r}}^2 + V_{\mathrm{i}}^2} \\ + I_{\mathrm{r0}} &= \dfrac{P_{\mathrm{0}}V_{\mathrm{r}} + Q_{\mathrm{0}}V_{\mathrm{i}}}{V_T^2} + \dfrac{S^{\mathrm{sys}}}{S^{\mathrm{conv}}} \\ + I_{\mathrm{i0}} &= \dfrac{P_{\mathrm{0}}V_{\mathrm{i}} - Q_{\mathrm{0}}V_{\mathrm{r}}}{V_T^2} + \dfrac{S^{\mathrm{sys}}}{S^{\mathrm{conv}}} \\ + V_{M0} &= V_T \\ + I_{L0} &= \operatorname{rampsat}(V_T;\ V_{L0},\ V_{L1},\ I_{L1}) \\ + I_{\mathrm{p0}} &= \dfrac{I_{\mathrm{r0}}} + {\operatorname{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1)} \\ + \ell_{\mathrm{p0}} &= -R_{\mathrm{p}}^{\max} + - (M_{\mathrm{p}} - R_{\mathrm{p}}^{\max})\sigma(I_{\mathrm{p0}}) \\ + u_{\mathrm{p0}} &= + \begin{cases} + M_{\mathrm{p}}(1-\sigma(I_{\mathrm{p0}})) + + R_{\mathrm{p}}^{\max}\sigma(I_{\mathrm{p0}}) + \sigma(I_{L0} - I_{\mathrm{p0}}) + & s_L = 1 \\ + M_{\mathrm{p}}(1-\sigma(I_{\mathrm{p0}})) + + R_{\mathrm{p}}^{\max}\sigma(I_{\mathrm{p0}}) + & s_L = 0 + \end{cases} \\ + I_{\mathrm{q0}}^{\mathrm{extra}} &= 0 \\ + I_{\mathrm{q0}} &= -I_{\mathrm{i0}} + I_{\mathrm{q0}}^{\mathrm{extra}} \\ + I_{\mathrm{p0}}^{\mathrm{cmd}} &= I_{\mathrm{p0}} \\ + I_{\mathrm{q0}}^{\mathrm{cmd}} &= I_{\mathrm{q0}} +\end{aligned} +``` + +For normal power-flow starts, $V_T > V_{A1}$, so +$\operatorname{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1) = 1$ and the +$I_{\mathrm{p0}}$ formula is well defined. + +Initialization should verify: +- $V_T \le V_{\mathrm{hv}}^{\max}$. If $V_T \ge V_{\mathrm{hv}}^{\max}$, + $I_{\mathrm{q0}}^{\mathrm{extra}} = 0$ may not satisfy the HVRCM algebraic + condition, and a nonzero value should be solved or the initialization rejected. +- $\operatorname{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1) > 0$ when + $I_{\mathrm{r0}} \ne 0$. If the LVACM gain is zero, no finite + $I_{\mathrm{p0}}$ can reproduce nonzero initial active current. + +All internal derivatives initialize to zero. + +## Model Outputs + +Real and imaginary injected currents, $I_{\mathrm{r}}$ and +$I_{\mathrm{i}}$, are converter-base algebraic variables. System-base power +outputs use the bus-facing currents: +```math +\begin{aligned} + P &= V_{\mathrm{r}} I_{\mathrm{r}}^{\mathrm{inj}} + V_{\mathrm{i}} I_{\mathrm{i}}^{\mathrm{inj}} \\ + Q &= V_{\mathrm{i}} I_{\mathrm{r}}^{\mathrm{inj}} - V_{\mathrm{r}} I_{\mathrm{i}}^{\mathrm{inj}} +\end{aligned} +``` +Power outputs are positive leaving the converter and entering the bus. diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCB/README.md b/GridKit/Model/PhasorDynamics/Converter/REGCB/README.md new file mode 100644 index 000000000..453df3b13 --- /dev/null +++ b/GridKit/Model/PhasorDynamics/Converter/REGCB/README.md @@ -0,0 +1,112 @@ +# **Renewable Energy Generator/Converter Model (REGCB)** + +REGCB is a WECC renewable energy generator/converter model for inverter-coupled +resources. This document is a skeleton for the model specification; parameters, +equations, initialization details, and default values must be validated against +the REGCB source standard before implementation. + +## Block Diagram + +Standard model diagram for the REGCB converter interface. + +
+ + + Figure 1: Generator/Converter REGCB model. Figure courtesy of [PowerWorld](https://www.powerworld.com/WebHelp/) +
+ +## Model Parameters + +TODO: Populate from the validated REGCB source standard. + +Symbol | Units | Description | Typical Value | Note +------ | ----- | ----------- | ------------- | ---- +TODO | TODO | TODO | TODO | TODO + +### Model Derived Parameters + +TODO: Add derived parameters and their mathematical definitions after the model +parameter set and limiter behavior are validated. + +## Model Variables + +### Internal Variables + +#### Differential + +TODO: Populate from the validated REGCB state definitions. + +Symbol | Units | Description | Note +------ | ----- | ----------- | ---- +TODO | TODO | TODO | TODO + +#### Algebraic + +TODO: Populate from the validated REGCB algebraic variables. + +Symbol | Units | Description | Note +------ | ----- | ----------- | ---- +TODO | TODO | TODO | TODO + +### External Variables + +#### Differential + +None. + +#### Algebraic + +TODO: Populate from the validated REGCB external ports and signal inputs. + +Symbol | Units | Description | Note +------ | ----- | ----------- | ---- +TODO | TODO | TODO | TODO + +## Model Equations + +### Differential Equations + +TODO: Add differential equations after the state definitions, limiter behavior, +and smooth approximations are validated. + +```math +\begin{aligned} + \text{TODO} +\end{aligned} +``` + +### Algebraic Equations + +TODO: Add algebraic equations after the network-interface convention and current +limit logic are validated. + +```math +\begin{aligned} + \text{TODO} +\end{aligned} +``` + +## Initialization + +TODO: Add the initialization procedure in the order computations are performed, +including steady-state assumptions and initial values for external commands. + +## Model Outputs + +TODO: Populate the monitored output list after the algebraic variables are +validated. + +Real and imaginary injected currents, when defined by the model, should use +$I_r$ and $I_i$ and be oriented as leaving the converter (i.e. entering the bus). + +Active and reactive power outputs, when defined, should follow the GridKit +phasor dynamics convention: + +```math +\begin{aligned} + P &= V_r I_r + V_i I_i \\ + Q &= V_i I_r - V_r I_i +\end{aligned} +``` + +Power outputs should be oriented as leaving the converter (i.e. entering the bus). diff --git a/docs/Figures/PhasorDynamics_REGCA_Diagram.png b/docs/Figures/PhasorDynamics_REGCA_Diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..35cb516dd403f4f900aa1d5f2a626d1d5455a186 GIT binary patch literal 89982 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 literal 0 HcmV?d00001 diff --git a/docs/Figures/PhasorDynamics_REGCB_Diagram.png b/docs/Figures/PhasorDynamics_REGCB_Diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed6747d34fde526a24cce19546a2daaf54e5034 GIT binary patch literal 119201 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 z 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

yyDjPQ-bd3Fg! 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 z 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 S{)Pek=-o29S$@O*+5Z8nwrLaq literal 0 HcmV?d00001 diff --git a/examples/PhasorDynamics/Large/WECC/README.md b/examples/PhasorDynamics/Large/WECC/README.md index c84cfdedb..373ed3302 100644 --- a/examples/PhasorDynamics/Large/WECC/README.md +++ b/examples/PhasorDynamics/Large/WECC/README.md @@ -44,7 +44,7 @@ The following event types are provided for this case. Only one exciter model is outstanding: - REECB1 - GAST_PTI -- REGC_A +- REGCA - REPCA1 The following examples needs to be constructed with this case. diff --git a/examples/PhasorDynamics/Medium/Hawaii/README.md b/examples/PhasorDynamics/Medium/Hawaii/README.md index 7ffca21bf..9923641ca 100644 --- a/examples/PhasorDynamics/Medium/Hawaii/README.md +++ b/examples/PhasorDynamics/Medium/Hawaii/README.md @@ -42,7 +42,7 @@ The following event types are provided for this case. The following models are not implemented in GridKit and are represented using surrogate models. - IEEEST (In GridKit, not yet added to this case) -- REGC_A +- REGCA - IEEEG1 - GGOV1 - ESST4B From f5f409a4b216b1368f3352088108786ad7ba0a7a Mon Sep 17 00:00:00 2001 From: lukelowry Date: Sun, 17 May 2026 17:45:26 -0500 Subject: [PATCH 04/12] doc latex change for rendering on github --- GridKit/CommonMath.md | 6 +++--- .../PhasorDynamics/Converter/REGCA/README.md | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/GridKit/CommonMath.md b/GridKit/CommonMath.md index af75ef7f7..0cad2019f 100644 --- a/GridKit/CommonMath.md +++ b/GridKit/CommonMath.md @@ -23,12 +23,12 @@ Softplus avoids the negative undershoot of $x\sigma(x)$, with a small positive b |------|--------------|----------------------|-------------| | `clamp` | $\min(\max(x,\ell),u)$ | $\ell + \rho(x-\ell) - \rho(x-u)$ | Bounded saturation | | `slew` | $\min(\max(f,-r),r)$ | $-r + \rho(f+r) - \rho(f-r)$ | Symmetric slew-rate limiter | -| `rampsat` | $h\,\operatorname{clamp}\!\left(\frac{x-a}{b-a},0,1\right)$ | $\frac{h}{b-a}\left[\rho(x-a)-\rho(x-b)\right]$ | Saturating linear ramp | +| `rampsat` | $h\,\text{clamp}\!\left(\frac{x-a}{b-a},0,1\right)$ | $\frac{h}{b-a}\left[\rho(x-a)-\rho(x-b)\right]$ | Saturating linear ramp | `rampsat` is a monotone saturating linear ramp, implemented as the difference of two smooth ramps: ```math -\operatorname{rampsat}(x;\,a,b,h) +\text{rampsat}(x;\,a,b,h) = \frac{h}{b-a}\left[\rho(x-a)-\rho(x-b)\right]. ``` @@ -73,7 +73,7 @@ Ramp (`Math::ramp`, $\rho$): - [IEEET1](Model/PhasorDynamics/Exciter/IEEET1/README.md): smooth magnetic saturation above the saturation knee - REGCA: applies reactive-current and active-current rate-limit corrections -Saturating ramp (`Math::rampsat`, $\operatorname{rampsat}$): +Saturating ramp (`Math::rampsat`, $\text{rampsat}$): - REGCA: defines the LVPL and LVACM piecewise-linear curves diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md b/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md index 9e61ca924..0413b9d97 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md +++ b/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md @@ -132,7 +132,7 @@ The exact state equations are \min(f_{\mathrm{q}}, R_{\mathrm{q}}^{\max}) & Q_{\mathrm{0}} > 0 \\ \max(f_{\mathrm{q}}, R_{\mathrm{q}}^{\min}) & Q_{\mathrm{0}} \le 0 \end{cases} \\ - \dot I_{\mathrm{p}} &= \operatorname{clamp}(f_{\mathrm{p}}, \ell_{\mathrm{p}}, u_{\mathrm{p}}) + \dot I_{\mathrm{p}} &= \text{clamp}(f_{\mathrm{p}}, \ell_{\mathrm{p}}, u_{\mathrm{p}}) \end{aligned} ``` @@ -203,7 +203,7 @@ exact algebraic targets are: \end{aligned} ``` -The implemented algebraic residuals use smooth $\operatorname{rampsat}$, +The implemented algebraic residuals use smooth $\text{rampsat}$, $\rho$, and $\sigma$ operators: ```math @@ -213,9 +213,9 @@ $\rho$, and $\sigma$ operators: 0 &= -I_{\mathrm{q}}^{\mathrm{extra}} + \rho\!\left(I_{\mathrm{q}}^{\mathrm{extra}} - (V_{\mathrm{hv}}^{\max} - V_T)\right) \\ 0 &= -I_L - + \operatorname{rampsat}(V_M;\ V_{L0},\ V_{L1},\ I_{L1}) \\ + + \text{rampsat}(V_M;\ V_{L0},\ V_{L1},\ I_{L1}) \\ 0 &= -I_{\mathrm{r}} - + I_{\mathrm{p}}\operatorname{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1) \\ + + I_{\mathrm{p}}\text{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1) \\ 0 &= -\ell_{\mathrm{p}} - R_{\mathrm{p}}^{\max} - (M_{\mathrm{p}} - R_{\mathrm{p}}^{\max})\sigma(I_{\mathrm{p}}) \\ @@ -261,9 +261,9 @@ steady-state initial values: I_{\mathrm{i0}} &= \dfrac{P_{\mathrm{0}}V_{\mathrm{i}} - Q_{\mathrm{0}}V_{\mathrm{r}}}{V_T^2} \dfrac{S^{\mathrm{sys}}}{S^{\mathrm{conv}}} \\ V_{M0} &= V_T \\ - I_{L0} &= \operatorname{rampsat}(V_T;\ V_{L0},\ V_{L1},\ I_{L1}) \\ + I_{L0} &= \text{rampsat}(V_T;\ V_{L0},\ V_{L1},\ I_{L1}) \\ I_{\mathrm{p0}} &= \dfrac{I_{\mathrm{r0}}} - {\operatorname{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1)} \\ + {\text{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1)} \\ \ell_{\mathrm{p0}} &= -R_{\mathrm{p}}^{\max} - (M_{\mathrm{p}} - R_{\mathrm{p}}^{\max})\sigma(I_{\mathrm{p0}}) \\ u_{\mathrm{p0}} &= @@ -284,14 +284,14 @@ steady-state initial values: ``` For normal power-flow starts, $V_T > V_{A1}$, so -$\operatorname{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1) = 1$ and the +$\text{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1) = 1$ and the $I_{\mathrm{p0}}$ formula is well defined. Initialization should verify: - $V_T \le V_{\mathrm{hv}}^{\max}$. If $V_T \ge V_{\mathrm{hv}}^{\max}$, $I_{\mathrm{q0}}^{\mathrm{extra}} = 0$ may not satisfy the HVRCM algebraic condition, and a nonzero value should be solved or the initialization rejected. -- $\operatorname{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1) > 0$ when +- $\text{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1) > 0$ when $I_{\mathrm{r0}} \ne 0$. If the LVACM gain is zero, no finite $I_{\mathrm{p0}}$ can reproduce nonzero initial active current. From 5589f6433482b4de85764b12d4b24003b5a0b698 Mon Sep 17 00:00:00 2001 From: lukelowry Date: Mon, 18 May 2026 15:56:56 -0500 Subject: [PATCH 05/12] improve common functions, stabilizer corrections, polish docs --- GridKit/CommonMath.hpp | 185 ++++++++++++++---- GridKit/CommonMath.md | 94 +++++---- .../PhasorDynamics/Converter/REGCA/README.md | 30 +-- .../Exciter/IEEET1/Ieeet1Impl.hpp | 2 +- .../Exciter/SEXS-PTI/SexsPtiImpl.hpp | 2 +- .../Governor/Tgov1/Tgov1Impl.hpp | 2 +- GridKit/Model/PhasorDynamics/INPUT_FORMAT.md | 2 +- .../Stabilizer/IEEEST/Ieeest.hpp | 13 +- .../Stabilizer/IEEEST/IeeestData.hpp | 7 +- .../Stabilizer/IEEEST/IeeestImpl.hpp | 78 ++------ .../Stabilizer/IEEEST/README.md | 143 ++++++-------- GridKit/Model/PhasorDynamics/SystemModel.hpp | 8 +- .../Math/SmoothnessIndicatorTests.hpp | 182 ++++++++++++++--- .../Math/runSmoothnessIndicatorTests.cpp | 6 +- .../PhasorDynamics/StabilizerIeeestTests.hpp | 85 ++++---- 15 files changed, 526 insertions(+), 313 deletions(-) diff --git a/GridKit/CommonMath.hpp b/GridKit/CommonMath.hpp index 1bd330d14..f995bf4c9 100644 --- a/GridKit/CommonMath.hpp +++ b/GridKit/CommonMath.hpp @@ -51,27 +51,94 @@ namespace GridKit return (HALF * (z + a) + std::log1p(std::exp(-a))) / MU; } + /** + * @brief Smooth binary maximum function + * + * Smooth approximation to max(x, y), composed from the smooth ramp + * function. + * + * @tparam LeftT - left scalar data type + * @tparam RightT - right scalar data type + * + * @param[in] x - First input signal + * @param[in] y - Second input signal + * @return Smooth maximum of x and y + */ + template + __attribute__((always_inline)) inline auto max( + const LeftT x, + const RightT y) + { + return y + ramp(x - y); + } + + /** + * @brief Smooth binary minimum function + * + * Smooth approximation to min(x, y), composed from the smooth ramp + * function. + * + * @tparam LeftT - left scalar data type + * @tparam RightT - right scalar data type + * + * @param[in] x - First input signal + * @param[in] y - Second input signal + * @return Smooth minimum of x and y + */ + template + __attribute__((always_inline)) inline auto min( + const LeftT x, + const RightT y) + { + return x - ramp(x - y); + } + /** * @brief Smooth clamp function * * Smooth approximation to min(max(x, lower), upper), composed from the - * smooth ramp function. + * smooth ramp function. Lower and upper bounds may be independent types + * (e.g. constant Real bounds or algebraic-variable bounds). * - * @tparam ScalarT - scalar data type - * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * @tparam ScalarT - scalar data type of the input signal + * @tparam LowerT - data type of the lower bound + * @tparam UpperT - data type of the upper bound * * @param[in] x - expected to be of order 1 * @param[in] lower - Lower limit * @param[in] upper - Upper limit * @return value of the smooth clamp function */ + template + __attribute__((always_inline)) inline auto clamp( + const ScalarT x, + const LowerT lower, + const UpperT upper) + { + return lower + ramp(x - lower) - ramp(x - upper); + } + + /** + * @brief Smooth two-sided deadband function + * + * Smooth approximation to x - min(max(x, lower), upper), composed from the + * smooth ramp function. + * + * @tparam ScalarT - scalar data type + * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * + * @param[in] x - Input signal + * @param[in] lower - Lower breakpoint + * @param[in] upper - Upper breakpoint + * @return Smooth deadbanded value + */ template - __attribute__((always_inline)) inline ScalarT clamp( + __attribute__((always_inline)) inline ScalarT deadband( const ScalarT x, const RealT lower, const RealT upper) { - return lower + ramp(x - lower) - ramp(x - upper); + return ramp(x - upper) - ramp(-(x - lower)); } /** @@ -95,10 +162,11 @@ namespace GridKit } /** - * @brief Smooth saturating ramp function + * @brief Smooth linear segment contribution * - * Smooth approximation to a monotone linear ramp saturating from zero to - * height over the interval [lower, upper]. + * Smooth approximation to a linear segment contribution that is zero below + * lower, linear over [lower, upper], and saturated at height above upper. + * Callers should supply lower < upper; height may be positive or negative. * * @tparam ScalarT - scalar data type * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) @@ -107,10 +175,10 @@ namespace GridKit * @param[in] lower - Lower breakpoint * @param[in] upper - Upper breakpoint * @param[in] height - Saturated value above the upper breakpoint - * @return Saturating ramp value + * @return Smooth linear segment contribution */ template - __attribute__((always_inline)) inline ScalarT rampsat( + __attribute__((always_inline)) inline ScalarT linseg( const ScalarT x, const RealT lower, const RealT upper, @@ -136,87 +204,134 @@ namespace GridKit } /** - * @brief Low indicator function for regulator limits + * @brief Smooth above-limit indicator * * @tparam ScalarT - Scalar data type * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) * - * @param[in] limit_min - Minimum limit * @param[in] x - State variable - * @return Scalar value indicating limit activation + * @param[in] limit_min - Minimum limit + * @return Smooth indicator that x is above limit_min */ template - __attribute__((always_inline)) inline ScalarT indicator_low( - const RealT limit_min, - const ScalarT x) + __attribute__((always_inline)) inline ScalarT above( + const ScalarT x, + const RealT limit_min) { return sigmoid(x - limit_min); } /** - * @brief High indicator function for regulator limits + * @brief Smooth below-limit indicator * * @tparam ScalarT - Scalar data type * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) * - * @param[in] limit_max - Maximum limit * @param[in] x - State variable - * @return Scalar value indicating limit activation + * @param[in] limit_max - Maximum limit + * @return Smooth indicator that x is below limit_max */ template - __attribute__((always_inline)) inline ScalarT indicator_high( - const RealT limit_max, - const ScalarT x) + __attribute__((always_inline)) inline ScalarT below( + const ScalarT x, + const RealT limit_max) { return sigmoid(limit_max - x); } /** - * @brief Zero indicator function for regulator limits + * @brief Smooth inside-limits indicator * * @tparam ScalarT - Scalar data type * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) * + * @param[in] x - State variable * @param[in] limit_min - Minimum limit * @param[in] limit_max - Maximum limit - * @param[in] x - State variable - * @return Scalar value indicating limit activation + * @return Smooth indicator that x is inside [limit_min, limit_max] */ template - __attribute__((always_inline)) inline ScalarT indicator_zero( + __attribute__((always_inline)) inline ScalarT inside( + const ScalarT x, const RealT limit_min, - const RealT limit_max, - const ScalarT x) + const RealT limit_max) { - return indicator_low(limit_min, x) + indicator_high(limit_max, x) - ONE; + return above(x, limit_min) + below(x, limit_max) - ONE; } /** - * @brief Smooth anti-windup indicator for a limited state variable + * @brief Smooth outside-limits indicator * * @tparam ScalarT - Scalar data type * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) * + * @param[in] x - State variable * @param[in] limit_min - Minimum limit * @param[in] limit_max - Maximum limit + * @return Smooth indicator that x is outside [limit_min, limit_max] + */ + template + __attribute__((always_inline)) inline ScalarT outside( + const ScalarT x, + const RealT limit_min, + const RealT limit_max) + { + return below(x, limit_min) + above(x, limit_max); + } + + /** + * @brief Smooth anti-windup indicator for a limited state variable + * + * @tparam ScalarT - Scalar data type + * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * * @param[in] x - State variable * @param[in] f - Pre-limit derivative of the state variable + * @param[in] limit_min - Minimum limit + * @param[in] limit_max - Maximum limit * @return Scalar value in [0, 1]: 1 when dynamics should pass through, * 0 when integration should be blocked. */ template __attribute__((always_inline)) inline ScalarT indicator( - const RealT limit_min, - const RealT limit_max, const ScalarT x, - const ScalarT f) + const ScalarT f, + const RealT limit_min, + const RealT limit_max) { - ScalarT above_min = indicator_low(limit_min, x); - ScalarT below_max = indicator_high(limit_max, x); + ScalarT above_min = above(x, limit_min); + ScalarT below_max = below(x, limit_max); return above_min * below_max + // (ONE - below_max) * sigmoid(-f) + // (ONE - above_min) * sigmoid(f); } + + /** + * @brief Smooth anti-windup limited derivative + * + * Applies the smooth anti-windup indicator gate to a pre-limit derivative. + * The returned value approximates the conditional-integration rule that + * passes interior dynamics, passes restoring motion from saturated limits, + * and blocks motion that would push further into saturation. + * + * @tparam ScalarT - Scalar data type + * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * + * @param[in] x - Limited state or limited output signal + * @param[in] f - Pre-limit derivative + * @param[in] limit_min - Minimum limit + * @param[in] limit_max - Maximum limit + * @return Smooth anti-windup limited derivative + */ + template + __attribute__((always_inline)) inline ScalarT antiwindup( + const ScalarT x, + const ScalarT f, + const RealT limit_min, + const RealT limit_max) + { + return indicator(x, f, limit_min, limit_max) * f; + } } // namespace Math } // namespace GridKit diff --git a/GridKit/CommonMath.md b/GridKit/CommonMath.md index 0cad2019f..bbfc7180b 100644 --- a/GridKit/CommonMath.md +++ b/GridKit/CommonMath.md @@ -21,44 +21,54 @@ Softplus avoids the negative undershoot of $x\sigma(x)$, with a small positive b | Name | Exact Target | Smooth Approximation | Description | |------|--------------|----------------------|-------------| -| `clamp` | $\min(\max(x,\ell),u)$ | $\ell + \rho(x-\ell) - \rho(x-u)$ | Bounded saturation | -| `slew` | $\min(\max(f,-r),r)$ | $-r + \rho(f+r) - \rho(f-r)$ | Symmetric slew-rate limiter | -| `rampsat` | $h\,\text{clamp}\!\left(\frac{x-a}{b-a},0,1\right)$ | $\frac{h}{b-a}\left[\rho(x-a)-\rho(x-b)\right]$ | Saturating linear ramp | - -`rampsat` is a monotone saturating linear ramp, implemented as the difference of two smooth ramps: +| `max` | $\begin{cases}x & x>y\\y & x\le y\end{cases}$ | $y+\rho(x-y)$ | Smooth binary maximum | +| `min` | $\begin{cases}x & xu\end{cases}$ | $\ell + \rho(x-\ell) - \rho(x-u)$ | Bounded saturation | +| `deadband` | $\begin{cases}x-\ell & x<\ell\\0 & \ell\le x\le u\\x-u & x>u\end{cases}$ | $\rho(x-u)-\rho(\ell-x)$ | Signed two-sided deadband | +| `slew` | $\begin{cases}-r & f<-r\\f & -r\le f\le r\\r & f>r\end{cases}$ | $-r + \rho(f+r) - \rho(f-r)$ | Symmetric slew-rate limiter | +| `linseg` | $\begin{cases}0 & xb\end{cases}$ | $\frac{h}{b-a}\left[\rho(x-a)-\rho(x-b)\right]$ | Saturated linear segment contribution | +| `above` | $\begin{cases}0 & x\le x_{\min}\\1 & x>x_{\min}\end{cases}$ | $\sigma(x-x_{\min})$ | Above-lower-limit indicator | +| `below` | $\begin{cases}1 & xx_{\max}\\0 & \text{else}\end{cases}$ | $\sigma(x_{\min}-x)+\sigma(x-x_{\max})$ | Outside-band indicator | +| `antiwindup` | $\begin{cases}f & x_{\min}0\\f & x\ge x_{\max}\land f<0\\0 & \text{otherwise}\end{cases}$ | $\phi(x,f)f$ | Anti-windup limited derivative | + +Binary `min` and `max` inherit the ramp breakpoint bias: ```math -\text{rampsat}(x;\,a,b,h) -= -\frac{h}{b-a}\left[\rho(x-a)-\rho(x-b)\right]. +\text{max}(x,x)=x+\rho(0), \qquad +\text{min}(x,x)=x-\rho(0). ``` -It is not a signal-processing window function. +`deadband` is the signed complement of `clamp`, implemented as the difference +of the upper and lower one-sided deadband ramps: -## Anti-Windup - -For a limited state $x \in [x_{\min}, x_{\max}]$, the indicators are: +```math +\text{deadband}(x;\,\ell,u)=\rho(x-u)-\rho(\ell-x). +``` -| Name | Exact Target | Smooth Approximation | Description | -|------|--------------|----------------------|-------------| -| $\phi_L$ | $H(x-x_{\min})$ | $\sigma(x-x_{\min})$ | Above-lower-limit indicator | -| $\phi_U$ | $H(x_{\max}-x)$ | $\sigma(x_{\max}-x)$ | Below-upper-limit indicator | -| $\phi_0$ | $\begin{cases}1 & x_{\min} 0) & \lor \\ - & \quad (x \geq x_{\max} \land f < 0) \\ - 0 & \text{else} - \end{cases} +\text{linseg}(x;\,a,b,h) += +\frac{h}{b-a}\left[\rho(x-a)-\rho(x-b)\right]. ``` -GridKit uses the smooth gate $\dot x = \phi(x,f)f$, where +Callers should supply $a < b$. The height $h$ may be positive or negative. It +is not a signal-processing window function. + +## Anti-Windup Indicator + +For a limited state $x \in [x_{\min}, x_{\max}]$, define +$\phi_L=\text{above}(x,x_{\min})$ and +$\phi_U=\text{below}(x,x_{\max})$. + +GridKit's `indicator` function is the smooth anti-windup gate $\phi(x,f)$, +where ```math \phi(x, f) = \phi_L \phi_U + (1 - \phi_U)\,\sigma(-f) + (1 - \phi_L)\,\sigma(f). @@ -71,18 +81,32 @@ The first term passes interior dynamics. The second and third terms pass restori Ramp (`Math::ramp`, $\rho$): - [IEEET1](Model/PhasorDynamics/Exciter/IEEET1/README.md): smooth magnetic saturation above the saturation knee -- REGCA: applies reactive-current and active-current rate-limit corrections +- [REGCA](Model/PhasorDynamics/Converter/REGCA/README.md): applies reactive-current and active-current rate-limit corrections + +Binary min/max (`Math::min`, `Math::max`): + +- [REECA](Model/PhasorDynamics/Converter/REECA/README.md): forms the safe measured voltage floor and final current limits + +Linear segment (`Math::linseg`, $\text{linseg}$): + +- [REGCA](Model/PhasorDynamics/Converter/REGCA/README.md): defines the LVPL and LVACM piecewise-linear curves +- [REECA](Model/PhasorDynamics/Converter/REECA/README.md): defines smooth voltage-dependent current-limit interpolation curves + +Deadband (`Math::deadband`): -Saturating ramp (`Math::rampsat`, $\text{rampsat}$): +- [REECA](Model/PhasorDynamics/Converter/REECA/README.md): smooths the two-sided voltage-error deadband -- REGCA: defines the LVPL and LVACM piecewise-linear curves +Inside indicator (`Math::inside`): -Anti-windup gate (`Math::indicator`): +- [IEEEST](Model/PhasorDynamics/Stabilizer/IEEEST/README.md): forms the smooth output limiter for $v_7$ over $[L_{smin}, L_{smax}]$ + +Outside indicator (`Math::outside`): + +- [REECA](Model/PhasorDynamics/Converter/REECA/README.md): forms the smooth voltage dip/overvoltage indicator for $s_{\mathrm{dip}}$ + +Anti-windup (`Math::antiwindup`, with gate `Math::indicator`): - [IEEET1](Model/PhasorDynamics/Exciter/IEEET1/README.md): gates $\dot V_R$ on $V_R \in (V_{rmin}, V_{rmax})$ - [TGOV1](Model/PhasorDynamics/Governor/Tgov1/README.md): gates $\dot P_v$ on $P_v \in (P_{vmin}, P_{vmax})$ - [SEXS-PTI](Model/PhasorDynamics/Exciter/SEXS-PTI/README.md): gates $\dot E_{fd}$ on $E_{fd} \in (E_{fd,\min}, E_{fd,\max})$ - -Window gate (`Math::sigmoid((x - lower)(upper - x) / (upper - lower))`): - -- [IEEEST](Model/PhasorDynamics/Stabilizer/IEEEST/README.md): gates $V_s$ by the $V_{ct}$ cutout window $[V_{cl}, V_{cu}]$ +- [REECA](Model/PhasorDynamics/Converter/REECA/README.md): gates PI-controller and active-power-order dynamics during output saturation diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md b/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md index 0413b9d97..c647cbf14 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md +++ b/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md @@ -126,13 +126,13 @@ The exact state equations are ```math \begin{aligned} - \dot V_M &= \dfrac{1}{T_M}(V_T - V_M) \\ - \dot I_{\mathrm{q}} &= + 0 &= -T_M \dot V_M - V_M + V_T \\ + 0 &= -\dot I_{\mathrm{q}} + \begin{cases} \min(f_{\mathrm{q}}, R_{\mathrm{q}}^{\max}) & Q_{\mathrm{0}} > 0 \\ \max(f_{\mathrm{q}}, R_{\mathrm{q}}^{\min}) & Q_{\mathrm{0}} \le 0 \end{cases} \\ - \dot I_{\mathrm{p}} &= \text{clamp}(f_{\mathrm{p}}, \ell_{\mathrm{p}}, u_{\mathrm{p}}) + 0 &= -\dot I_{\mathrm{p}} + \text{clamp}(f_{\mathrm{p}}, \ell_{\mathrm{p}}, u_{\mathrm{p}}) \end{aligned} ``` @@ -140,15 +140,15 @@ The implemented smooth state equations are ```math \begin{aligned} - \dot V_M &= \dfrac{1}{T_M}(V_T - V_M) \\ - \dot I_{\mathrm{q}} &= + 0 &= -T_M \dot V_M - V_M + V_T \\ + 0 &= -\dot I_{\mathrm{q}} + \begin{cases} f_{\mathrm{q}} - \rho(f_{\mathrm{q}} - R_{\mathrm{q}}^{\max}) & Q_{\mathrm{0}} > 0 \\ f_{\mathrm{q}} + \rho(R_{\mathrm{q}}^{\min} - f_{\mathrm{q}}) & Q_{\mathrm{0}} \le 0 \end{cases} \\ - \dot I_{\mathrm{p}} &= + 0 &= -\dot I_{\mathrm{p}} + \ell_{\mathrm{p}} + \rho(f_{\mathrm{p}} - \ell_{\mathrm{p}}) - \rho(f_{\mathrm{p}} - u_{\mathrm{p}}) @@ -168,7 +168,7 @@ exact algebraic targets are: ```math \begin{aligned} - V_T &= \sqrt{V_{\mathrm{r}}^2 + V_{\mathrm{i}}^2} \\ + 0 &= -V_T^2 + V_{\mathrm{r}}^2 + V_{\mathrm{i}}^2 \\ I_{\mathrm{i}} &= -I_{\mathrm{q}} + I_{\mathrm{q}}^{\mathrm{extra}} \\ 0 &= \begin{cases} @@ -203,19 +203,19 @@ exact algebraic targets are: \end{aligned} ``` -The implemented algebraic residuals use smooth $\text{rampsat}$, +The implemented algebraic residuals use smooth $\text{linseg}$, $\rho$, and $\sigma$ operators: ```math \begin{aligned} - 0 &= V_T^2 - V_{\mathrm{r}}^2 - V_{\mathrm{i}}^2 \\ + 0 &= -V_T^2 + V_{\mathrm{r}}^2 + V_{\mathrm{i}}^2 \\ 0 &= -I_{\mathrm{i}} - I_{\mathrm{q}} + I_{\mathrm{q}}^{\mathrm{extra}} \\ 0 &= -I_{\mathrm{q}}^{\mathrm{extra}} + \rho\!\left(I_{\mathrm{q}}^{\mathrm{extra}} - (V_{\mathrm{hv}}^{\max} - V_T)\right) \\ 0 &= -I_L - + \text{rampsat}(V_M;\ V_{L0},\ V_{L1},\ I_{L1}) \\ + + \text{linseg}(V_M;\ V_{L0},\ V_{L1},\ I_{L1}) \\ 0 &= -I_{\mathrm{r}} - + I_{\mathrm{p}}\text{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1) \\ + + I_{\mathrm{p}}\text{linseg}(V_T;\ V_{A0},\ V_{A1},\ 1) \\ 0 &= -\ell_{\mathrm{p}} - R_{\mathrm{p}}^{\max} - (M_{\mathrm{p}} - R_{\mathrm{p}}^{\max})\sigma(I_{\mathrm{p}}) \\ @@ -261,9 +261,9 @@ steady-state initial values: I_{\mathrm{i0}} &= \dfrac{P_{\mathrm{0}}V_{\mathrm{i}} - Q_{\mathrm{0}}V_{\mathrm{r}}}{V_T^2} \dfrac{S^{\mathrm{sys}}}{S^{\mathrm{conv}}} \\ V_{M0} &= V_T \\ - I_{L0} &= \text{rampsat}(V_T;\ V_{L0},\ V_{L1},\ I_{L1}) \\ + I_{L0} &= \text{linseg}(V_T;\ V_{L0},\ V_{L1},\ I_{L1}) \\ I_{\mathrm{p0}} &= \dfrac{I_{\mathrm{r0}}} - {\text{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1)} \\ + {\text{linseg}(V_T;\ V_{A0},\ V_{A1},\ 1)} \\ \ell_{\mathrm{p0}} &= -R_{\mathrm{p}}^{\max} - (M_{\mathrm{p}} - R_{\mathrm{p}}^{\max})\sigma(I_{\mathrm{p0}}) \\ u_{\mathrm{p0}} &= @@ -284,14 +284,14 @@ steady-state initial values: ``` For normal power-flow starts, $V_T > V_{A1}$, so -$\text{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1) = 1$ and the +$\text{linseg}(V_T;\ V_{A0},\ V_{A1},\ 1) = 1$ and the $I_{\mathrm{p0}}$ formula is well defined. Initialization should verify: - $V_T \le V_{\mathrm{hv}}^{\max}$. If $V_T \ge V_{\mathrm{hv}}^{\max}$, $I_{\mathrm{q0}}^{\mathrm{extra}} = 0$ may not satisfy the HVRCM algebraic condition, and a nonzero value should be solved or the initialization rejected. -- $\text{rampsat}(V_T;\ V_{A0},\ V_{A1},\ 1) > 0$ when +- $\text{linseg}(V_T;\ V_{A0},\ V_{A1},\ 1) > 0$ when $I_{\mathrm{r0}} \ne 0$. If the LVACM gain is zero, no finite $I_{\mathrm{p0}}$ can reproduce nonzero initial active current. diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp index e2fa7dab5..2b310f65b 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp @@ -325,7 +325,7 @@ namespace GridKit // The 'pre-limit' derivative of Vr. ScalarT func = (-vr + Ka_ * vtr) / Ta_; ScalarT func_normalized = func / static_cast(500.0); // TODO This is arbitrary, need more general conditioning method that is fast - ScalarT vr_ind = Math::indicator(Vrmin_, Vrmax_, vr, func_normalized); + ScalarT vr_ind = Math::indicator(vr, func_normalized, Vrmin_, Vrmax_); // Internal Differential Equations f[0] = -vts_dot + (Ec - vts) / Tr_; diff --git a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp index ceebbac4a..f09fd3b5f 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp @@ -199,7 +199,7 @@ namespace GridKit ScalarT func = (-efd + (K_ / Tb_) * (-vr + Ta_ * vtr)) / Te_; ScalarT func_normalized = func / static_cast(100.0); // TODO arbitrary conditioning; see IEEET1 - ScalarT efd_ind = Math::indicator(Efdmin_, Efdmax_, efd, func_normalized); + ScalarT efd_ind = Math::indicator(efd, func_normalized, Efdmin_, Efdmax_); f[0] = -vr_dot + (-vr + Ta_ * vtr) / Tb_ - vtr; f[1] = -efd_dot + efd_ind * func; diff --git a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp index 2d7c7d87a..104976d97 100644 --- a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp @@ -258,7 +258,7 @@ namespace GridKit // The 'pre-limit' derivative of Pv ScalarT func = (-pv + (pref_ - omega) / R_) / T1_; - ScalarT valv_ind = Math::indicator(Pvmin_, Pvmax_, pv, func); + ScalarT valv_ind = Math::indicator(pv, func, Pvmin_, Pvmax_); // Internal Differential Equations f[0] = -ptx_dot + pv - (ptx + T2_ * pv) / T3_; diff --git a/GridKit/Model/PhasorDynamics/INPUT_FORMAT.md b/GridKit/Model/PhasorDynamics/INPUT_FORMAT.md index 06dccb66c..72d732a0d 100644 --- a/GridKit/Model/PhasorDynamics/INPUT_FORMAT.md +++ b/GridKit/Model/PhasorDynamics/INPUT_FORMAT.md @@ -147,7 +147,7 @@ are specified: `Tgov1 ` | the TGOV1 governor model | `pmech`, `speed` | `R`, `T1`, `T2`, `T3`, `Pvmax`, `Pvmin`, `Dt` | `none` `Ieeet1` | the IEEET1 exciter model | `bus`, `speed`, `efd`, `vs`\* | `Tr`, `Ka`, `Ta`, `Ke`, `Te`, `Kf`, `Tf`, `Vrmin`, `Vrmax`, `E1`, `E2`, `Se1`, `Se2`, `Ispdlim` | `efd`, `ksat` `SexsPti` | the SEXS-PTI simplified exciter model | `bus`, `efd`, `vs`\* | `Ta`, `Tb`, `Te`, `K`, `Efdmax`, `Efdmin` | `efd` - `Ieeest` | the IEEEST stabilizer model | `input`, `output`, `cutout`\* | `A1`, `A2`, `A3`, `A4`, `A5`, `A6`, `T1`, `T2`, `T3`, `T4`, `T5`, `T6`, `Ks`, `Lsmin`, `Lsmax`, `Vcl`, `Vcu`, `Tdelay` | `vs` + `Ieeest` | the IEEEST stabilizer model | `input`, `output` | `A1`, `A2`, `A3`, `A4`, `A5`, `A6`, `T1`, `T2`, `T3`, `T4`, `T5`, `T6`, `Ks`, `Lsmin`, `Lsmax`, `Vcl`, `Vcu`, `Tdelay` | `vss` `BusFault` | simple impedance-based fault at a bus | `bus`, `status`\* | `state0`, `R`, `X` | `state`, `ir`, `ii` Ports marked with \* are optional and, if missing, will be assumed to be diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp index b495a49d3..10a137d2f 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp @@ -46,16 +46,14 @@ namespace GridKit V5, ///< Lead-lag 1 output V6, ///< Lead-lag 2 output V7, ///< Unlimited stabilizer signal - VSS, ///< Limited stabilizer signal - VS, ///< Stabilizer output + VSS, ///< Limited stabilizer signal (model output) MAXIMUM, }; /// External variables of a `Ieeest` enum class IeeestExternalVariables : size_t { - U, ///< Stabilizer input signal - VCT, ///< Cutout signal + U, ///< Stabilizer input signal MAXIMUM, }; @@ -134,7 +132,7 @@ namespace GridKit RealT Lsmin_{-0.1}; RealT Lsmax_{0.1}; RealT Vcl_{0}; - RealT Vcu_{1.5}; + RealT Vcu_{0}; RealT Tdelay_{0}; RealT a0_{1}; @@ -154,15 +152,10 @@ namespace GridKit RealT safe_inv_a2_{0}; RealT use_T2_block_{1}; RealT bypass_T2_block_{0}; - RealT safe_inv_T2_{1}; RealT use_T4_block_{1}; RealT bypass_T4_block_{0}; - RealT safe_inv_T4_{1}; RealT use_T6_block_{1}; RealT bypass_T6_block_{0}; - RealT safe_inv_T6_{1}; - RealT use_cutout_{1}; - RealT bypass_cutout_{0}; ComponentSignals signals_; diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestData.hpp b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestData.hpp index 00d728a58..49b241832 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestData.hpp +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestData.hpp @@ -34,8 +34,8 @@ namespace GridKit Ks, ///< Stabilizer gain Lsmin, ///< Minimum stabilizer output limit Lsmax, ///< Maximum stabilizer output limit - Vcl, ///< Lower input cutout threshold - Vcu, ///< Upper input cutout threshold + Vcl, ///< Lower input cutout threshold (not modeled) + Vcu, ///< Upper input cutout threshold (not modeled) Tdelay, ///< Input time delay (not modeled) }; @@ -45,7 +45,6 @@ namespace GridKit enum class IeeestPorts { input, ///< Unique ID of the stabilizer input signal - cutout, ///< Unique ID of the cutout signal output, ///< Unique ID of the stabilizer output signal }; @@ -54,7 +53,7 @@ namespace GridKit */ enum class IeeestMonitorableVariables { - vs, ///< Stabilizer output + vss, ///< Stabilizer output (limited signal) }; /** diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp index b0c815d90..e428c601a 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp @@ -26,7 +26,7 @@ namespace GridKit template Ieeest::Ieeest() { - size_ = 13; + size_ = 12; } template @@ -35,7 +35,7 @@ namespace GridKit { initializeParameters(data); initializeMonitor(); - size_ = 13; + size_ = 12; } template @@ -138,19 +138,12 @@ namespace GridKit use_T2_block_ = static_cast(T2_ != 0.0); bypass_T2_block_ = 1.0 - use_T2_block_; - safe_inv_T2_ = use_T2_block_ / (T2_ + bypass_T2_block_); use_T4_block_ = static_cast(T4_ != 0.0); bypass_T4_block_ = 1.0 - use_T4_block_; - safe_inv_T4_ = use_T4_block_ / (T4_ + bypass_T4_block_); use_T6_block_ = static_cast(T6_ != 0.0); bypass_T6_block_ = 1.0 - use_T6_block_; - safe_inv_T6_ = use_T6_block_ / (T6_ + bypass_T6_block_); - - // Vcl = Vcu = 0 means "cutout disabled" (passthrough: vs = vss). - use_cutout_ = static_cast(Vcl_ != 0.0 || Vcu_ != 0.0); - bypass_cutout_ = 1.0 - use_cutout_; } template @@ -171,12 +164,10 @@ namespace GridKit variable_indices_.resize(size); residual_indices_.resize(size); - ws_.resize(2); - ws_indices_.resize(2); + ws_.resize(1); + ws_indices_.resize(1); ws_[0] = 0.0; ws_indices_[0] = INVALID_INDEX; - ws_[1] = 0.0; - ws_indices_[1] = INVALID_INDEX; for (IdxT j = 0; j < size_; ++j) { @@ -184,10 +175,10 @@ namespace GridKit this->setResidualIndex(j, j); } - if (signals_.template isAssigned()) + if (signals_.template isAssigned()) { - signals_.template getSignalNode()->set( - &y_[12], &(this->getVariableIndex(12))); + signals_.template getSignalNode()->set( + &y_[11], &(this->getVariableIndex(11))); } return 0; @@ -212,15 +203,6 @@ namespace GridKit ret += 1; } - if (signals_.template isAttached()) - { - if (!signals_.template isLinked()) - { - Log::error() << "Ieeest: cutout signal VCT attached with no linked source\n"; - ret += 1; - } - } - if (a4_ == 0 && a3_ == 0 && a2_ == 0 && a1_ != 0) { Log::error() << "Ieeest: a2, a3, and a4 are all zero - no valid notch filter\n"; @@ -249,15 +231,14 @@ namespace GridKit tag_[1] = true; tag_[2] = true; tag_[3] = true; - tag_[4] = true; - tag_[5] = true; - tag_[6] = true; + tag_[4] = (T2_ != 0.0); + tag_[5] = (T4_ != 0.0); + tag_[6] = (T6_ != 0.0); tag_[7] = false; tag_[8] = false; tag_[9] = false; tag_[10] = false; tag_[11] = false; - tag_[12] = false; return 0; } @@ -282,7 +263,6 @@ namespace GridKit ScalarT v6 = y[9]; ScalarT v7 = y[10]; ScalarT vss = y[11]; - ScalarT vs = y[12]; ScalarT x1_dot = yp[0]; ScalarT x2_dot = yp[1]; @@ -292,31 +272,22 @@ namespace GridKit ScalarT x6_dot = yp[5]; ScalarT x7_dot = yp[6]; - ScalarT u = ws[0]; - ScalarT vct = ws[1]; + ScalarT u = ws[0]; f[0] = -x1_dot + use_notch_ * x2; f[1] = -x2_dot + (use_4th_order_ + use_3rd_order_) * x3 + use_2nd_order_ * (-a0_ * x1 - a1_ * x2 + u) * safe_inv_a2_; f[2] = -x3_dot + use_4th_order_ * x4 + use_3rd_order_ * (-a0_ * x1 - a1_ * x2 - a2_ * x3 + u) * safe_inv_a3_; - f[3] = -x4_dot + use_4th_order_ * (-a0_ * x1 - a1_ * x2 - a2_ * x3 - a3_ * x4 + u) * safe_inv_a4_; - - f[4] = -x5_dot + use_T2_block_ * (v4 - x5) * safe_inv_T2_; - f[5] = -x6_dot + use_T4_block_ * (v5 - x6) * safe_inv_T4_; - f[6] = -x7_dot + use_T6_block_ * (v6 - x7) * safe_inv_T6_; - + f[3] = -x4_dot + use_4th_order_ * (-a0_ * x1 - a1_ * x2 - a2_ * x3 - a3_ * x4 + u) * safe_inv_a4_; + f[4] = -T2_ * x5_dot - x5 + v4; + f[5] = -T4_ * x6_dot - x6 + v5; + f[6] = -T6_ * x7_dot - x7 + v6; f[7] = -v4 + bypass_notch_ * u + use_notch_ * (x1 + A5_ * x2 + (use_4th_order_ + use_3rd_order_) * A6_ * x3); - f[8] = -v5 + bypass_T2_block_ * v4 + use_T2_block_ * (x5 + T1_ * (v4 - x5) * safe_inv_T2_); - f[9] = -v6 + bypass_T4_block_ * v5 + use_T4_block_ * (x6 + T3_ * (v5 - x6) * safe_inv_T4_); - f[10] = -v7 + bypass_T6_block_ * Ks_ * v6 + use_T6_block_ * Ks_ * T5_ * (v6 - x7) * safe_inv_T6_; - - f[11] = -vss + v7 * Math::indicator_zero(Lsmin_, Lsmax_, v7) - + Lsmin_ * Math::sigmoid(Lsmin_ - v7) - + Lsmax_ * Math::sigmoid(v7 - Lsmax_); - // Cutout: Vcl=Vcu=0 means disabled (passthrough). Otherwise, sigmoid window. - f[12] = -vs + bypass_cutout_ * vss - + use_cutout_ * vss * Math::sigmoid(vct - Vcl_) * Math::sigmoid(Vcu_ - vct); + f[8] = use_T2_block_ * (-T2_ * (v5 - x5) + T1_ * (v4 - x5)) + bypass_T2_block_ * (v4 - v5); + f[9] = use_T4_block_ * (-T4_ * (v6 - x6) + T3_ * (v5 - x6)) + bypass_T4_block_ * (v5 - v6); + f[10] = use_T6_block_ * (-T6_ * v7 + Ks_ * T5_ * (v6 - x7)) + bypass_T6_block_ * (Ks_ * v6 - v7); + f[11] = -vss + Math::clamp(v7, Lsmin_, Lsmax_); return 0; } @@ -330,13 +301,6 @@ namespace GridKit ws_indices_[0] = signals_.template readExternalVariableIndex(); } - ws_[1] = (Vcl_ + Vcu_) / TWO; - if (signals_.template isAttached()) - { - ws_[1] = signals_.template readExternalVariable(); - ws_indices_[1] = signals_.template readExternalVariableIndex(); - } - evaluateInternalResidual(y_.data(), yp_.data(), wb_.data(), ws_.data(), f_.data()); return 0; @@ -352,8 +316,8 @@ namespace GridKit void Ieeest::initializeMonitor() { using Variable = typename model_data_type::MonitorableVariables; - monitor_->set(Variable::vs, [this] - { return y_[12]; }); + monitor_->set(Variable::vss, [this] + { return y_[11]; }); } } // namespace Stabilizer diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/README.md b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/README.md index 4bf26c3fe..6612b9cd2 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/README.md +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/README.md @@ -1,10 +1,7 @@ -# IEEEST +# **IEEE Stabilizer Model (IEEEST)** -The **IEEEST** model is a standard IEEE power system stabilizer used in transient stability simulations. -It consists of a 4th-order notch filter, two lead–lag blocks, a washout block, and an output limiter with input cutout logic. - -Notes: -- The **cutout logic uses** $V_{ct}$ (as labeled in the block diagram), not $u_d$. +Standard IEEE power system stabilizer: 4th-order notch filter, two lead–lag +blocks, washout, and output limiter. ## Block Diagram @@ -14,31 +11,32 @@ Notes: Figure 1: Stabilizer IEEEST model. Figure courtesy of [PowerWorld](https://www.powerworld.com/WebHelp/) - ## Model Parameters -Symbol | Units | Description | Typical Value | Note ------- | ----- | ----------- | -------------- | ---- -$A_1$ | [s] | Notch filter denominator coefficient | 1.013 -$A_2$ | [s²] | Notch filter denominator coefficient | 0.013 -$A_3$ | [s] | Notch filter denominator coefficient | 0.0 -$A_4$ | [s²] | Notch filter denominator coefficient | 0.0 -$A_5$ | [s] | Notch filter numerator coefficient | 1.013 -$A_6$ | [s²] | Notch filter numerator coefficient | 0.113 -$T_1$ | [s] | Lead–lag 1 numerator time constant | 0.0 -$T_2$ | [s] | Lead–lag 1 denominator time constant | 0.02 -$T_3$ | [s] | Lead–lag 2 numerator time constant | 0.0 -$T_4$ | [s] | Lead–lag 2 denominator time constant | 0.0 -$T_5$ | [s] | Washout numerator time constant | 1.65 -$T_6$ | [s] | Washout denominator time constant | 1.65 -$K_s$ | [p.u.] | Stabilizer gain | 3.0 -$L_{s\min}$ | [p.u.] | Minimum stabilizer output limit | -0.1 -$L_{s\max}$ | [p.u.] | Maximum stabilizer output limit | 0.1 -$V_{cl}$ | [p.u.] | Lower input cutout threshold | 0.0 -$V_{cu}$ | [p.u.] | Upper input cutout threshold | 0.0 -$T_{delay}$ | [s] | Input time delay | 0.0 - -### Model Derived Parameters +Symbol | Units | Description | Typical Value +------------|--------|--------------------------------------|-------------- +$A_1$ | [s] | Notch denominator coefficient | 1.013 +$A_2$ | [s²] | Notch denominator coefficient | 0.013 +$A_3$ | [s] | Notch denominator coefficient | 0.0 +$A_4$ | [s²] | Notch denominator coefficient | 0.0 +$A_5$ | [s] | Notch numerator coefficient | 1.013 +$A_6$ | [s²] | Notch numerator coefficient | 0.113 +$T_1$ | [s] | Lead–lag 1 numerator time constant | 0.0 +$T_2$ | [s] | Lead–lag 1 denominator time constant | 0.02 +$T_3$ | [s] | Lead–lag 2 numerator time constant | 0.0 +$T_4$ | [s] | Lead–lag 2 denominator time constant | 0.0 +$T_5$ | [s] | Washout numerator time constant | 1.65 +$T_6$ | [s] | Washout denominator time constant | 1.65 +$K_s$ | [p.u.] | Stabilizer gain | 3.0 +$L_{s\min}$ | [p.u.] | Minimum stabilizer output limit | -0.1 +$L_{s\max}$ | [p.u.] | Maximum stabilizer output limit | 0.1 + +The IEEE 421.5 IEEEST also defines a cutout window ($V_{cl}$, $V_{cu}$) and an +input delay ($T_{delay}$). These parameters are accepted for input-format +compatibility but are not modeled here. + +### Derived Parameters + ```math \begin{aligned} a_0 &= 1 \\ @@ -55,77 +53,64 @@ a_4 &= A_2 A_4 #### Differential -Symbol | Units | Description | Note ------- | ----- | ----------- | ---- -$x_1$ | [-] | Notch filter state | -$x_2$ | [-] | Notch filter state | -$x_3$ | [-] | Notch filter state | -$x_4$ | [-] | Notch filter state | -$x_5$ | [-] | Lead–lag 1 state | -$x_6$ | [-] | Lead–lag 2 state | -$x_7$ | [-] | Washout state | +Symbol | Units | Description +----------------------|--------|------------ +$x_1, x_2, x_3, x_4$ | [-] | Notch filter states +$x_5$ | [-] | Lead–lag 1 state +$x_6$ | [-] | Lead–lag 2 state +$x_7$ | [-] | Washout state #### Algebraic -Symbol | Units | Description | Note ------- | ----- | ----------- | ---- -$v_4$ | [p.u.] | Notch filter output | -$v_5$ | [p.u.] | Lead–lag 1 output | -$v_6$ | [p.u.] | Lead–lag 2 output | -$v_7$ | [p.u.] | Unlimited stabilizer signal | -$V_{ss}$ | [p.u.] | Limited stabilizer signal | -$V_s$ | [p.u.] | Stabilizer output | +Symbol | Units | Description +-----------|--------|------------ +$v_4$ | [p.u.] | Notch filter output +$v_5$ | [p.u.] | Lead–lag 1 output +$v_6$ | [p.u.] | Lead–lag 2 output +$v_7$ | [p.u.] | Unlimited stabilizer signal +$V_{ss}$ | [p.u.] | Limited stabilizer signal (model output) ### External Variables -#### Differential - -None. - #### Algebraic -Symbol | Units | Description | Note ------- | ----- | ----------- | ---- -$u$ | [p.u.] | Stabilizer input signal | -$V_{ct}$ | [p.u.] | Cutout signal (compared to $V_{cl},V_{cu}$) | from the block diagram +Symbol | Units | Description +-------|--------|------------ +$u$ | [p.u.] | Stabilizer input signal ## Model Equations ### Differential Equations + ```math \begin{aligned} -\dot{x}_1 &= x_2 \\ -\dot{x}_2 &= x_3 \\ -\dot{x}_3 &= x_4 \\ -\dot{x}_4 &= -\dfrac{a_0}{a_4}x_1 - -\dfrac{a_1}{a_4}x_2 - -\dfrac{a_2}{a_4}x_3 - -\dfrac{a_3}{a_4}x_4 - +\dfrac{1}{a_4}u\\ -\dot{x}_5 &= \dfrac{1}{T_2}(v_4 - x_5) \\ -\dot{x}_6 &= \dfrac{1}{T_4}(v_5 - x_6)\\ -\dot{x}_7 &= \dfrac{1}{T_6}(v_6 - x_7) +0 &= -\dot{x}_1 + x_2 \\ +0 &= -\dot{x}_2 + x_3 \\ +0 &= -\dot{x}_3 + x_4 \\ +0 &= -\dot{x}_4 - \dfrac{a_0}{a_4}x_1 - \dfrac{a_1}{a_4}x_2 - \dfrac{a_2}{a_4}x_3 - \dfrac{a_3}{a_4}x_4 + \dfrac{1}{a_4}u \\ +0 &= -T_2 \dot{x}_5 - x_5 + v_4 \\ +0 &= -T_4 \dot{x}_6 - x_6 + v_5 \\ +0 &= -T_6 \dot{x}_7 - x_7 + v_6 \end{aligned} ``` ### Algebraic Equations + ```math \begin{aligned} 0 &= -v_4 + x_1 + A_5 x_2 + A_6 x_3 \\ -0 &= -v_5 + x_5 + \dfrac{T_1}{T_2}(v_4 - x_5) \\ -0 &= -v_6 + x_6 + \dfrac{T_3}{T_4}(v_5 - x_6) \\ -0 &= -v_7 + K_s \dfrac{T_5}{T_6}(v_6 - x_7) \\ -0 &= -V_{ss} + \operatorname{clamp}(v_7,L_{s\min},L_{s\max}) \\ -0 &= -V_s + -\begin{cases} -V_{ss}, & V_{cl} < V_{ct} < V_{cu} \\ -0, & \text{otherwise} -\end{cases} +0 &= -T_2(v_5 - x_5) + T_1(v_4 - x_5) \\ +0 &= -T_4(v_6 - x_6) + T_3(v_5 - x_6) \\ +0 &= -T_6 v_7 + K_s T_5(v_6 - x_7) \\ +0 &= -V_{ss} + \operatorname{clamp}(v_7, L_{s\min}, L_{s\max}) \end{aligned} ``` -In simulation, the output limiter uses a smooth clamp approximation. -The cutout case statement is smoothed as the product of lower and upper -sigmoid indicators, $\sigma(V_{ct}-V_{cl})\sigma(V_{cu}-V_{ct})$. -The parameter convention $V_{cl}=V_{cu}=0$ disables the cutout and passes -$V_{ss}$ through. +The output limiter uses GridKit's smooth +[Clamp](../../../../CommonMath.md#derived-functions). + +## Initialization + +All states and their derivatives initialize to zero. The stabilizer comes +online at rest and produces signal only in response to deviations in the input +$u$. diff --git a/GridKit/Model/PhasorDynamics/SystemModel.hpp b/GridKit/Model/PhasorDynamics/SystemModel.hpp index 53f2d990e..43cb02cf6 100644 --- a/GridKit/Model/PhasorDynamics/SystemModel.hpp +++ b/GridKit/Model/PhasorDynamics/SystemModel.hpp @@ -319,16 +319,10 @@ namespace GridKit stabilizer->getSignals().template attachSignalNode(getSignal(input)); } - if (stabdata.ports.contains(IeeestPorts::cutout)) - { - IdxT cutout = stabdata.ports.at(IeeestPorts::cutout); - stabilizer->getSignals().template attachSignalNode(getSignal(cutout)); - } - if (stabdata.ports.contains(IeeestPorts::output)) { IdxT output = stabdata.ports.at(IeeestPorts::output); - stabilizer->getSignals().template assignSignalNode(getSignal(output)); + stabilizer->getSignals().template assignSignalNode(getSignal(output)); } addComponent(stabilizer); diff --git a/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp b/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp index f7588faaf..336c3afba 100644 --- a/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp +++ b/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp @@ -31,6 +31,75 @@ namespace GridKit return success.report(__func__); } + TestOutcome deadband() + { + TestStatus success = true; + + const ScalarT lower = -0.05; + const ScalarT upper = 0.10; + + success *= (Math::deadband(static_cast(-1.0), lower, upper) < static_cast(-0.94)); + success *= (Math::deadband(static_cast(-1.0), lower, upper) > static_cast(-0.96)); + success *= (std::abs(Math::deadband(static_cast(0.02), lower, upper)) < static_cast(1.0e-8)); + success *= (Math::deadband(static_cast(1.0), lower, upper) > static_cast(0.89)); + success *= (Math::deadband(static_cast(1.0), lower, upper) < static_cast(0.91)); + + const ScalarT lower_breakpoint = Math::deadband(lower, lower, upper); + const ScalarT upper_breakpoint = Math::deadband(upper, lower, upper); + + success *= (lower_breakpoint < static_cast(0.0)); + success *= (upper_breakpoint > static_cast(0.0)); + success *= (std::abs(lower_breakpoint) < static_cast(0.003)); + success *= (std::abs(upper_breakpoint) < static_cast(0.003)); + + const ScalarT x = -0.4; + success *= (std::abs(Math::deadband(x, lower, upper) + - (x - Math::clamp(x, lower, upper))) + < static_cast(1.0e-12)); + + success *= std::isfinite(Math::deadband(static_cast(4.0), lower, upper)); + success *= (Math::deadband(static_cast(4.0), lower, upper) > static_cast(3.89)); + success *= std::isfinite(Math::deadband(static_cast(-4.0), lower, upper)); + success *= (Math::deadband(static_cast(-4.0), lower, upper) < static_cast(-3.94)); + + const ScalarT point = 0.25; + success *= (std::abs(Math::deadband(static_cast(0.75), point, point) - static_cast(0.5)) + < static_cast(1.0e-12)); + success *= (std::abs(Math::deadband(static_cast(-0.25), point, point) + static_cast(0.5)) + < static_cast(1.0e-12)); + + return success.report(__func__); + } + + TestOutcome limitIndicators() + { + TestStatus success = true; + + const ScalarT limit_min = 0.0; + const ScalarT limit_max = 3.0; + + success *= (Math::above(static_cast(1.0), limit_min) > static_cast(0.99)); + success *= (Math::above(static_cast(-0.2), limit_min) < static_cast(0.1)); + success *= (Math::below(static_cast(1.0), limit_max) > static_cast(0.99)); + success *= (Math::below(static_cast(3.2), limit_max) < static_cast(0.1)); + + success *= (Math::inside(static_cast(1.5), limit_min, limit_max) > static_cast(0.99)); + success *= (Math::inside(static_cast(-0.2), limit_min, limit_max) < static_cast(0.1)); + success *= (Math::inside(static_cast(3.2), limit_min, limit_max) < static_cast(0.1)); + + success *= (Math::outside(static_cast(1.5), limit_min, limit_max) < static_cast(0.1)); + success *= (Math::outside(static_cast(-0.2), limit_min, limit_max) > static_cast(0.9)); + success *= (Math::outside(static_cast(3.2), limit_min, limit_max) > static_cast(0.9)); + + const ScalarT x = static_cast(1.5); + success *= (std::abs(Math::inside(x, limit_min, limit_max) + + Math::outside(x, limit_min, limit_max) + - static_cast(1.0)) + < static_cast(1.0e-12)); + + return success.report(__func__); + } + TestOutcome slew() { TestStatus success = true; @@ -45,30 +114,40 @@ namespace GridKit return success.report(__func__); } - TestOutcome rampsat() + TestOutcome linseg() { TestStatus success = true; - success *= (Math::rampsat(static_cast(-1.0), - static_cast(0.0), - static_cast(2.0), - static_cast(4.0)) + success *= (Math::linseg(static_cast(-1.0), + static_cast(0.0), + static_cast(2.0), + static_cast(4.0)) < static_cast(0.01)); - success *= (Math::rampsat(static_cast(1.0), - static_cast(0.0), - static_cast(2.0), - static_cast(4.0)) + success *= (Math::linseg(static_cast(1.0), + static_cast(0.0), + static_cast(2.0), + static_cast(4.0)) > static_cast(1.99)); - success *= (Math::rampsat(static_cast(1.0), - static_cast(0.0), - static_cast(2.0), - static_cast(4.0)) + success *= (Math::linseg(static_cast(1.0), + static_cast(0.0), + static_cast(2.0), + static_cast(4.0)) < static_cast(2.01)); - success *= (Math::rampsat(static_cast(3.0), - static_cast(0.0), - static_cast(2.0), - static_cast(4.0)) + success *= (Math::linseg(static_cast(3.0), + static_cast(0.0), + static_cast(2.0), + static_cast(4.0)) > static_cast(3.99)); + success *= (Math::linseg(static_cast(1.0), + static_cast(0.0), + static_cast(2.0), + static_cast(-4.0)) + < static_cast(-1.99)); + success *= (Math::linseg(static_cast(1.0), + static_cast(0.0), + static_cast(2.0), + static_cast(-4.0)) + > static_cast(-2.01)); return success.report(__func__); } @@ -105,6 +184,43 @@ namespace GridKit return success.report(__func__); } + TestOutcome minMax() + { + TestStatus success = true; + + const ScalarT high = static_cast(2.0); + const ScalarT low = static_cast(-1.0); + + success *= (Math::max(high, low) > high - static_cast(0.01)); + success *= (Math::max(high, low) < high + static_cast(0.01)); + success *= (Math::max(low, high) > high - static_cast(0.01)); + success *= (Math::max(low, high) < high + static_cast(0.01)); + + success *= (Math::min(high, low) > low - static_cast(0.01)); + success *= (Math::min(high, low) < low + static_cast(0.01)); + success *= (Math::min(low, high) > low - static_cast(0.01)); + success *= (Math::min(low, high) < low + static_cast(0.01)); + + const auto lower_bounded = Math::max(static_cast(-1.0), 0.01); + success *= (lower_bounded > static_cast(0.009)); + success *= (lower_bounded < static_cast(0.011)); + + const ScalarT x = static_cast(0.4); + const ScalarT y = static_cast(-0.7); + success *= (std::abs(Math::min(x, y) + Math::max(x, y) - (x + y)) + < static_cast(1.0e-12)); + + const ScalarT point = static_cast(0.25); + const ScalarT bias = std::log(static_cast(2.0)) / static_cast(240.0); + + success *= (std::abs(Math::max(point, point) - (point + bias)) + < static_cast(1.0e-12)); + success *= (std::abs(Math::min(point, point) - (point - bias)) + < static_cast(1.0e-12)); + + return success.report(__func__); + } + TestOutcome antiWindupIndicator() { TestStatus success = true; @@ -114,19 +230,41 @@ namespace GridKit // Inside the limits the indicator passes dynamics through, regardless // of the sign of f: value is close to 1. - success *= (Math::indicator(limit_min, limit_max, static_cast(1.5), static_cast(0.01)) > static_cast(0.99)); + success *= (Math::indicator(static_cast(1.5), static_cast(0.01), limit_min, limit_max) > static_cast(0.99)); // Above the upper limit with f pushing further out: blocked (≈ 0). - success *= (Math::indicator(limit_min, limit_max, static_cast(3.2), static_cast(0.01)) < static_cast(0.1)); + success *= (Math::indicator(static_cast(3.2), static_cast(0.01), limit_min, limit_max) < static_cast(0.1)); // Above the upper limit but f pulling back in: passed (≈ 1). - success *= (Math::indicator(limit_min, limit_max, static_cast(3.2), static_cast(-0.01)) > static_cast(0.9)); + success *= (Math::indicator(static_cast(3.2), static_cast(-0.01), limit_min, limit_max) > static_cast(0.9)); // Below the lower limit with f pushing further out: blocked (≈ 0). - success *= (Math::indicator(limit_min, limit_max, static_cast(-0.2), static_cast(-0.01)) < static_cast(0.1)); + success *= (Math::indicator(static_cast(-0.2), static_cast(-0.01), limit_min, limit_max) < static_cast(0.1)); // Below the lower limit but f pulling back in: passed (≈ 1). - success *= (Math::indicator(limit_min, limit_max, static_cast(-0.2), static_cast(0.01)) > static_cast(0.9)); + success *= (Math::indicator(static_cast(-0.2), static_cast(0.01), limit_min, limit_max) > static_cast(0.9)); + + return success.report(__func__); + } + + TestOutcome antiWindup() + { + TestStatus success = true; + + const ScalarT limit_min = 0.0; + const ScalarT limit_max = 3.0; + + const ScalarT f_positive = 0.01; + const ScalarT f_negative = -0.01; + + success *= (std::abs(Math::antiwindup(static_cast(1.5), f_positive, limit_min, limit_max) + - Math::indicator(static_cast(1.5), f_positive, limit_min, limit_max) * f_positive) + < static_cast(1.0e-12)); + + success *= (Math::antiwindup(static_cast(3.2), f_positive, limit_min, limit_max) < static_cast(0.001)); + success *= (Math::antiwindup(static_cast(3.2), f_negative, limit_min, limit_max) < static_cast(-0.009)); + success *= (Math::antiwindup(static_cast(-0.2), f_negative, limit_min, limit_max) > static_cast(-0.001)); + success *= (Math::antiwindup(static_cast(-0.2), f_positive, limit_min, limit_max) > static_cast(0.009)); return success.report(__func__); } diff --git a/tests/UnitTests/Math/runSmoothnessIndicatorTests.cpp b/tests/UnitTests/Math/runSmoothnessIndicatorTests.cpp index 6edb891f0..233c36ddd 100644 --- a/tests/UnitTests/Math/runSmoothnessIndicatorTests.cpp +++ b/tests/UnitTests/Math/runSmoothnessIndicatorTests.cpp @@ -7,10 +7,14 @@ int main() GridKit::Testing::SmoothnessIndicatorTests test; result += test.clamp(); + result += test.deadband(); + result += test.limitIndicators(); result += test.slew(); - result += test.rampsat(); + result += test.linseg(); result += test.ramp(); + result += test.minMax(); result += test.antiWindupIndicator(); + result += test.antiWindup(); return result.summary(); } diff --git a/tests/UnitTests/PhasorDynamics/StabilizerIeeestTests.hpp b/tests/UnitTests/PhasorDynamics/StabilizerIeeestTests.hpp index d35d774a6..0c1c77d66 100644 --- a/tests/UnitTests/PhasorDynamics/StabilizerIeeestTests.hpp +++ b/tests/UnitTests/PhasorDynamics/StabilizerIeeestTests.hpp @@ -49,24 +49,24 @@ namespace GridKit { TestStatus success = true; - // Create signal nodes for input (u) and output (Vs) + // Create signal nodes for input (u) and output (Vss) PhasorDynamics::SignalNode u_node; - PhasorDynamics::SignalNode vs_node; + PhasorDynamics::SignalNode vss_node; ScalarT u_value{0.0}; - IdxT u_index = 13; // beyond internal variables - ScalarT vs_value{0.0}; - IdxT vs_index = INVALID_INDEX; + IdxT u_index = 12; // beyond internal variables + ScalarT vss_value{0.0}; + IdxT vss_index = INVALID_INDEX; // Link signal nodes to backing storage u_node.set(&u_value, &u_index); - vs_node.set(&vs_value, &vs_index); + vss_node.set(&vss_value, &vss_index); auto data = makeTestData(); PhasorDynamics::Stabilizer::Ieeest stab(data); - // Wire: stabilizer reads u_node as input, writes vs_node as output + // Wire: stabilizer reads u_node as input, writes vss_node as output stab.getSignals().template attachSignalNode(&u_node); - stab.getSignals().template assignSignalNode(&vs_node); + stab.getSignals().template assignSignalNode(&vss_node); stab.allocate(); success *= (stab.verify() == 0); @@ -85,9 +85,9 @@ namespace GridKit } // Verify output signal is linked and reads the correct value - success *= vs_node.linked(); - success *= (vs_node.getVariableIndex() == 12); - success *= isEqual(vs_node.read(), static_cast(0.0), tol); + success *= vss_node.linked(); + success *= (vss_node.getVariableIndex() == 11); + success *= isEqual(vss_node.read(), static_cast(0.0), tol); return success.report(__func__); } @@ -103,20 +103,20 @@ namespace GridKit TestStatus success = true; PhasorDynamics::SignalNode u_node; - PhasorDynamics::SignalNode vs_node; + PhasorDynamics::SignalNode vss_node; ScalarT u_value{0.5}; - IdxT u_index = 13; - ScalarT vs_value{0.0}; - IdxT vs_index = INVALID_INDEX; + IdxT u_index = 12; + ScalarT vss_value{0.0}; + IdxT vss_index = INVALID_INDEX; u_node.set(&u_value, &u_index); - vs_node.set(&vs_value, &vs_index); + vss_node.set(&vss_value, &vss_index); auto data = makeTestData(); PhasorDynamics::Stabilizer::Ieeest stab(data); stab.getSignals().template attachSignalNode(&u_node); - stab.getSignals().template assignSignalNode(&vs_node); + stab.getSignals().template assignSignalNode(&vss_node); stab.allocate(); stab.initialize(); @@ -129,24 +129,23 @@ namespace GridKit 0.28, // f[1]: -x2_dot + x3 0.37, // f[2]: -x3_dot + x4 1.0975, // f[3]: -x4_dot + (-a0*x1 - a1*x2 - a2*x3 - a3*x4 + u) / a4 - 0.25, // f[4]: -x5_dot + (v4 - x5) / T2 - 0.24, // f[5]: -x6_dot + (v5 - x6) / T4 - -0.01, // f[6]: -x7_dot + (v6 - x7) / T6 + 0.25, // f[4]: -T2*x5_dot - x5 + v4 + 0.24, // f[5]: -T4*x6_dot - x6 + v5 + -0.05, // f[6]: -T6*x7_dot - x7 + v6 -0.42, // f[7]: -v4 + x1 + A5*x2 + A6*x3 - -0.25, // f[8]: -v5 + x5 + (T1/T2)*(v4 - x5) - -0.31, // f[9]: -v6 + x6 + (T3/T4)*(v5 - x6) - 1.15, // f[10]: -v7 + Ks*(T5/T6)*(v6 - x7) + -0.25, // f[8]: -T2*(v5 - x5) + T1*(v4 - x5) + -0.31, // f[9]: -T4*(v6 - x6) + T3*(v5 - x6) + 5.75, // f[10]: -T6*v7 + Ks*T5*(v6 - x7) 0.0, // f[11]: limiter (v7=0.05 within [-0.1, 0.1]) - 0.0, // f[12]: cutout (Vct=0.75 within [0.0, 1.5]) }; - // Looser tolerance for f[11],f[12] — smooth sigmoid approximations + // Looser tolerance for f[11] — Math::clamp is a smooth ramp approximation. const auto loose_tol = static_cast(1.0e-4); auto& residual = stab.getResidual(); for (size_t i = 0; i < res_answer.size(); ++i) { - auto test_tol = (i >= 11) ? loose_tol : static_cast(10 * std::numeric_limits::epsilon()); + auto test_tol = (i == 11) ? loose_tol : static_cast(10 * std::numeric_limits::epsilon()); if (!isEqual(residual[i], res_answer[i], test_tol)) { std::cout << "Incorrect result for residual " << i << ": " @@ -157,7 +156,7 @@ namespace GridKit } // Verify output signal reads the stabilizer output - success *= isEqual(vs_node.read(), static_cast(0.05), loose_tol); + success *= isEqual(vss_node.read(), static_cast(0.05), loose_tol); return success.report(__func__); } @@ -196,18 +195,18 @@ namespace GridKit // Set up signal nodes with DependencyTracking scalar type PhasorDynamics::SignalNode u_node; - PhasorDynamics::SignalNode vs_node; + PhasorDynamics::SignalNode vss_node; DepVar u_value{0.5}; - IdxT u_index = 13; - DepVar vs_value{0.0}; - IdxT vs_index = INVALID_INDEX; + IdxT u_index = 12; + DepVar vss_value{0.0}; + IdxT vss_index = INVALID_INDEX; u_node.set(&u_value, &u_index); - vs_node.set(&vs_value, &vs_index); + vss_node.set(&vss_value, &vss_index); PhasorDynamics::Stabilizer::Ieeest stab(ieeestdata); stab.getSignals().template attachSignalNode(&u_node); - stab.getSignals().template assignSignalNode(&vs_node); + stab.getSignals().template assignSignalNode(&vss_node); stab.allocate(); stab.initialize(); @@ -287,18 +286,18 @@ namespace GridKit PhasorDynamics::Stabilizer::IeeestData ieeestdata) { PhasorDynamics::SignalNode u_node; - PhasorDynamics::SignalNode vs_node; + PhasorDynamics::SignalNode vss_node; ScalarT u_value{0.5}; - IdxT u_index = 13; - ScalarT vs_value{0.0}; - IdxT vs_index = INVALID_INDEX; + IdxT u_index = 12; + ScalarT vss_value{0.0}; + IdxT vss_index = INVALID_INDEX; u_node.set(&u_value, &u_index); - vs_node.set(&vs_value, &vs_index); + vss_node.set(&vss_value, &vss_index); PhasorDynamics::Stabilizer::Ieeest stab(ieeestdata); stab.getSignals().template attachSignalNode(&u_node); - stab.getSignals().template assignSignalNode(&vs_node); + stab.getSignals().template assignSignalNode(&vss_node); stab.allocate(); stab.initialize(); @@ -331,7 +330,7 @@ namespace GridKit PhasorDynamics::Stabilizer::IeeestData data; data.device_class = "stabilizer"; data.disambiguation_string = "ieeest_test"; - data.monitored_variables.insert(PhasorDynamics::Stabilizer::IeeestMonitorableVariables::vs); + data.monitored_variables.insert(PhasorDynamics::Stabilizer::IeeestMonitorableVariables::vss); data.parameters[Params::A1] = 0.1; data.parameters[Params::A2] = 0.2; @@ -349,7 +348,7 @@ namespace GridKit data.parameters[Params::Lsmin] = -0.1; data.parameters[Params::Lsmax] = 0.1; data.parameters[Params::Vcl] = 0.0; - data.parameters[Params::Vcu] = 1.5; + data.parameters[Params::Vcu] = 0.0; data.parameters[Params::Tdelay] = 0.0; return data; @@ -372,8 +371,7 @@ namespace GridKit stab.y()[8] = 0.9; // v5 stab.y()[9] = 1.0; // v6 stab.y()[10] = 0.05; // v7 (within limiter range) - stab.y()[11] = 0.05; // Vss - stab.y()[12] = 0.05; // Vs + stab.y()[11] = 0.05; // Vss (model output) stab.yp()[0] = 0.01; // x1_dot stab.yp()[1] = 0.02; // x2_dot @@ -402,7 +400,6 @@ namespace GridKit stab.y()[9].setValue(1.0); stab.y()[10].setValue(0.05); stab.y()[11].setValue(0.05); - stab.y()[12].setValue(0.05); stab.yp()[0].setValue(0.01); stab.yp()[1].setValue(0.02); From 3c155a641492f53ad2822888cf6a9fd39aab045b Mon Sep 17 00:00:00 2001 From: lukelowry Date: Mon, 18 May 2026 15:58:19 -0500 Subject: [PATCH 06/12] REECA Documentation --- .../PhasorDynamics/Converter/REECA/README.md | 470 ++++++++++++++++++ docs/Figures/PhasorDynamics_REECA_Diagram.png | Bin 0 -> 134602 bytes 2 files changed, 470 insertions(+) create mode 100644 GridKit/Model/PhasorDynamics/Converter/REECA/README.md create mode 100644 docs/Figures/PhasorDynamics_REECA_Diagram.png diff --git a/GridKit/Model/PhasorDynamics/Converter/REECA/README.md b/GridKit/Model/PhasorDynamics/Converter/REECA/README.md new file mode 100644 index 000000000..2b0fdc99a --- /dev/null +++ b/GridKit/Model/PhasorDynamics/Converter/REECA/README.md @@ -0,0 +1,470 @@ +# **Renewable Energy Electrical Control Model (REECA)** + +REECA is a WECC renewable energy electrical control model for inverter-coupled resources. In GridKit it is represented as a signal-control model that computes active- and reactive-current commands. + +Notes: +- Internal electrical quantities and current commands are on model base unless otherwise stated. +- Optional signal inputs default to their documented constant values when omitted. +- Timer-based post-dip reactive-current injection hold and active-current limit hold are not modeled in this version; $T_{\mathrm{hld}}$ and $T_{\mathrm{hld2}}$ must be zero. + +## Block Diagram + +Standard REECA block diagram. + +

+ +## Model Parameters + +Symbol | Units | Description | Typical Value | Note +------------------------------------|----------|---------------------------------------------------------|---------------|------ +$S^{\mathrm{base}}$ | [MVA] | REECA model power base | TBD | Block name: `MVABase` +$s_{\mathrm{pf}}$ | [binary] | Power-factor control flag | TBD | Block name: `PfFlag`; 1 = power-factor control, 0 = Q control +$s_V$ | [binary] | Voltage-control mode flag | TBD | Block name: `VFlag`; 1 = Q control, 0 = voltage control +$s_Q$ | [binary] | Reactive-power control flag | TBD | Block name: `QFlag`; 1 = voltage/Q control, 0 = constant pf or Q control +$s_P$ | [binary] | Active-power reference speed-multiplier flag | TBD | Block name: `Pflag`; 1 = multiply by generator speed +$s_{PQ}$ | [binary] | P/Q priority flag for converter current limit | TBD | Block name: `Pqflag`; 0 = Q priority, 1 = P priority +$T_{\mathrm{rv}}$ | [sec] | Voltage-measurement filter time constant | TBD | Block name: `Trv`; if zero, $V_{\mathrm{meas}}$ is algebraic +$T_{\mathrm{p}}$ | [sec] | Electrical-power measurement filter time constant | TBD | Block name: `Tp`; if zero, $P_{\mathrm{meas}}$ is algebraic +$V_{\mathrm{ref0}}$ | [p.u.] | Outer-loop voltage reference | TBD | Block name: `Vref0`; initialized to terminal voltage if omitted +$V_{\mathrm{dip}}$ | [p.u.] | Low-voltage threshold for reactive-current injection logic | TBD | Block name: `Vdip` +$V_{\mathrm{up}}$ | [p.u.] | High-voltage threshold for reactive-current injection logic | TBD | Block name: `Vup` +$D_{\mathrm{bd1}}$ | [p.u.] | Overvoltage deadband for voltage-error response | TBD | Block name: `dbd1` +$D_{\mathrm{bd2}}$ | [p.u.] | Undervoltage deadband for voltage-error response | TBD | Block name: `dbd2` +$K_{\mathrm{qv}}$ | [p.u.] | Reactive-current injection gain during voltage dip/overvoltage logic | TBD | Block name: `kqv` +$I_{\mathrm{qinj}}^{\min}$ | [p.u.] | Minimum reactive-current injection limit | TBD | Block name: `Iql1` +$I_{\mathrm{qinj}}^{\max}$ | [p.u.] | Maximum reactive-current injection limit | TBD | Block name: `Iqh1` +$I_{\mathrm{qinj}}^{\mathrm{frz}}$ | [p.u.] | Held reactive-current injection value after voltage dip | TBD | Block name: `Iqfrz`; unused when $T_{\mathrm{hld}} = 0$ +$T_{\mathrm{hld}}$ | [sec] | Reactive-current injection hold time after voltage dip clears | TBD | Block name: `Thld`; required to be zero in this version +$Q^{\max}$ | [p.u.] | Maximum reactive-power control limit | TBD | Block name: `Qmax` +$Q^{\min}$ | [p.u.] | Minimum reactive-power control limit | TBD | Block name: `Qmin` +$K_{\mathrm{qp}}$ | [p.u.] | Reactive-power control proportional gain | TBD | Block name: `Kqp` +$K_{\mathrm{qi}}$ | [p.u./s] | Reactive-power control integral gain | TBD | Block name: `Kqi` +$V^{\max}$ | [p.u.] | Maximum voltage-control limit | TBD | Block name: `Vmax` +$V^{\min}$ | [p.u.] | Minimum voltage-control limit | TBD | Block name: `Vmin` +$V_{\mathrm{ref1}}$ | [p.u.] | Inner-loop voltage-control reference/bias | 0 | Block name: `Vref1` +$K_{\mathrm{vp}}$ | [p.u.] | Voltage-control proportional gain | TBD | Block name: `Kvp` +$K_{\mathrm{vi}}$ | [p.u./s] | Voltage-control integral gain | TBD | Block name: `Kvi` +$T_{\mathrm{iq}}$ | [sec] | Reactive-current command lag time constant | TBD | Block name: `Tiq` +$T_{\mathrm{pord}}$ | [sec] | Active-power order filter time constant | TBD | Block name: `Tpord` +$R_P^{\max}$ | [p.u./s] | Positive active-power order ramp-rate limit | TBD | Block name: `dPmax` +$R_P^{\min}$ | [p.u./s] | Negative active-power order ramp-rate limit | TBD | Block name: `dPmin` +$P^{\max}$ | [p.u.] | Maximum active-power order limit | TBD | Block name: `Pmax` +$P^{\min}$ | [p.u.] | Minimum active-power order limit | TBD | Block name: `Pmin` +$I^{\max}$ | [p.u.] | Maximum total converter current | TBD | Block name: `Imax` +$V_{\mathrm{q},1}$ | [p.u.] | VDL1 voltage point 1 | TBD | Block name: `vq1` +$I_{\mathrm{q},1}^{\max}$ | [p.u.] | VDL1 reactive-current limit point 1 | TBD | Block name: `lq1` +$V_{\mathrm{q},2}$ | [p.u.] | VDL1 voltage point 2 | TBD | Block name: `vq2` +$I_{\mathrm{q},2}^{\max}$ | [p.u.] | VDL1 reactive-current limit point 2 | TBD | Block name: `lq2` +$V_{\mathrm{q},3}$ | [p.u.] | VDL1 voltage point 3 | TBD | Block name: `vq3` +$I_{\mathrm{q},3}^{\max}$ | [p.u.] | VDL1 reactive-current limit point 3 | TBD | Block name: `lq3` +$V_{\mathrm{q},4}$ | [p.u.] | VDL1 voltage point 4 | TBD | Block name: `vq4` +$I_{\mathrm{q},4}^{\max}$ | [p.u.] | VDL1 reactive-current limit point 4 | TBD | Block name: `lq4` +$V_{\mathrm{p},1}$ | [p.u.] | VDL2 voltage point 1 | TBD | Block name: `vp1` +$I_{\mathrm{p},1}^{\max}$ | [p.u.] | VDL2 active-current limit point 1 | TBD | Block name: `lp1` +$V_{\mathrm{p},2}$ | [p.u.] | VDL2 voltage point 2 | TBD | Block name: `vp2` +$I_{\mathrm{p},2}^{\max}$ | [p.u.] | VDL2 active-current limit point 2 | TBD | Block name: `lp2` +$V_{\mathrm{p},3}$ | [p.u.] | VDL2 voltage point 3 | TBD | Block name: `vp3` +$I_{\mathrm{p},3}^{\max}$ | [p.u.] | VDL2 active-current limit point 3 | TBD | Block name: `lp3` +$V_{\mathrm{p},4}$ | [p.u.] | VDL2 voltage point 4 | TBD | Block name: `vp4` +$I_{\mathrm{p},4}^{\max}$ | [p.u.] | VDL2 active-current limit point 4 | TBD | Block name: `lp4` +$T_{\mathrm{hld2}}$ | [sec] | Active-current limit hold time after voltage dip clears | TBD | Block name: `Thld2`; required to be zero in this version + +### Parameter Validation + +Implementations should reject invalid REECA parameter sets. If source data preprocessing adjusts active-power ramp-rate or order limits, apply these checks to the effective values used by the equations. + +The required checks are: + +```math +\begin{aligned} + &S^{\mathrm{base}} > 0 \\ + &s_{\mathrm{pf}}, s_V, s_Q, s_P, s_{PQ} \in \{0,1\} \\ + &T_{\mathrm{rv}}, T_{\mathrm{p}} \ge 0 \\ + &0 \le V_{\mathrm{dip}} < V_{\mathrm{up}} \\ + &D_{\mathrm{bd1}} \le 0 \le D_{\mathrm{bd2}} \\ + &I_{\mathrm{qinj}}^{\min} \le I_{\mathrm{qinj}}^{\max} \\ + &T_{\mathrm{hld}} = T_{\mathrm{hld2}} = 0 \\ + &Q^{\min} \le Q^{\max} \\ + &V^{\min} \le V^{\max} \\ + &T_{\mathrm{iq}}, T_{\mathrm{pord}} > 0 \\ + &R_P^{\min} < 0 < R_P^{\max} \\ + &P^{\min} \le P^{\max} \\ + &I^{\max} \ge 0 \\ + &0 \le V_{\mathrm{q},1} < V_{\mathrm{q},2} < V_{\mathrm{q},3} < V_{\mathrm{q},4} \\ + &I_{\mathrm{q},k}^{\max} \ge 0\ \text{for } k=1,\ldots,4 \\ + &0 \le V_{\mathrm{p},1} < V_{\mathrm{p},2} < V_{\mathrm{p},3} < V_{\mathrm{p},4} \\ + &I_{\mathrm{p},k}^{\max} \ge 0\ \text{for } k=1,\ldots,4 +\end{aligned} +``` + +### Model Derived Parameters + +The off-mode flag complements are: + +```math +\begin{aligned} + s_{\mathrm{pf}}^{\mathrm{off}} &= 1 - s_{\mathrm{pf}} \\ + s_V^{\mathrm{off}} &= 1 - s_V \\ + s_Q^{\mathrm{off}} &= 1 - s_Q \\ + s_{PQ}^{\mathrm{off}} &= 1 - s_{PQ} +\end{aligned} +``` + +The VDL functions use GridKit's smooth [Linear Segment](../../../../CommonMath.md#derived-functions) helper and provide flat extrapolation outside the first and fourth voltage points: + +```math +\begin{aligned} + g_q(x) &= + I_{\mathrm{q},1}^{\max} + + \sum_{k=1}^{3} + \text{linseg}\!\left( + x;\, + V_{\mathrm{q},k},\, + V_{\mathrm{q},k+1},\, + I_{\mathrm{q},k+1}^{\max} - I_{\mathrm{q},k}^{\max} + \right) \\ + g_p(x) &= + I_{\mathrm{p},1}^{\max} + + \sum_{k=1}^{3} + \text{linseg}\!\left( + x;\, + V_{\mathrm{p},k},\, + V_{\mathrm{p},k+1},\, + I_{\mathrm{p},k+1}^{\max} - I_{\mathrm{p},k}^{\max} + \right) +\end{aligned} +``` + +## Model Variables + +### Internal Variables + +#### Differential + +Symbol | Units | Description | Note +------------------------|--------|-------------------------------------|------ +$V_{\mathrm{meas}}$ | [p.u.] | Filtered terminal voltage | State 1 in Fig. 1; source label: `Vmeas`; algebraic when $T_{\mathrm{rv}} = 0$ +$P_{\mathrm{meas}}$ | [p.u.] | Filtered electrical power | State 2 in Fig. 1; source label: `Pmeas`; algebraic when $T_{\mathrm{p}} = 0$ +$x_{\mathrm{PIQ}}$ | [p.u.] | Reactive-power PI controller state | State 3 in Fig. 1; source label: `PIQ` +$x_{\mathrm{PIV}}$ | [p.u.] | Voltage PI controller state | State 4 in Fig. 1; source label: `PIV` +$Q_V$ | [p.u.] | Reactive-current command lag state | State 5 in Fig. 1; source label: `Q_V` +$P_{\mathrm{ord}}$ | [p.u.] | Filtered active-power order | State 6 in Fig. 1; source label: `Pord` + +#### Algebraic + +Symbol | Units | Description | Note +--------------------------------|--------|-------------------------------------|------ +$V_T$ | [p.u.] | Terminal voltage magnitude | +$V_{\mathrm{meas}}^{\mathrm{safe}}$ | [p.u.] | Safe filtered terminal voltage for divider blocks | Lower bounded by 0.01 +$s_{\mathrm{dip}}$ | [binary] | Voltage-dip/overvoltage freeze indicator | 1 when outside voltage thresholds +$V_{\mathrm{err}}$ | [p.u.] | Deadbanded voltage error | Defined by CommonMath `deadband` +$I_{\mathrm{qv}}$ | [p.u.] | Reactive-current injection candidate | Converter base +$Q_{\mathrm{ref}}$ | [p.u.] | Selected reactive-power reference | From power-factor or external reactive-power command +$e_Q$ | [p.u.] | Reactive-power control error | Limited $Q_{\mathrm{ref}}$ minus $Q_{\mathrm{gen}}$ +$V_{\mathrm{PIQ}}$ | [p.u.] | Reactive-power control PI output | Limited by $V^{\min}$ and $V^{\max}$ +$e_{\mathrm{PIV}}$ | [p.u.] | Voltage-control PI error | Selected voltage-control signal minus $V_{\mathrm{meas}}$ +$f_{\mathrm{pord}}$ | [p.u./s] | Active-power order derivative before ramp-rate limiting | Feeds $r_{\mathrm{pord}}$ +$r_{\mathrm{pord}}$ | [p.u./s] | Ramp-rate-limited active-power order derivative | Feeds $P_{\mathrm{ord}}$ anti-windup +$I_{\mathrm{q}}^{\mathrm{circ}}$ | [p.u.] | Reactive-current limit from converter current circle | Converter base; nonnegative algebraic branch +$I_{\mathrm{p}}^{\mathrm{circ}}$ | [p.u.] | Active-current limit from converter current circle | Converter base; nonnegative algebraic branch +$I_{\mathrm{q}}^{\max}$ | [p.u.] | Final reactive-current upper limit | Converter base; updated by VDL1 and current-limit logic +$I_{\mathrm{p}}^{\max}$ | [p.u.] | Final active-current upper limit | Converter base; updated by VDL2 and current-limit logic +$I_{\mathrm{qbase}}$ | [p.u.] | Base reactive-current command | Converter base; before $s_Q$ selection and reactive-current injection +$I_{\mathrm{q}}^{\mathrm{raw}}$ | [p.u.] | Raw reactive-current command before final limit | Converter base +$I_{\mathrm{q}}^{\mathrm{cmd}}$ | [p.u.] | Reactive-current command output | Converter base +$I_{\mathrm{p}}^{\mathrm{cmd}}$ | [p.u.] | Active-current command output | Converter base + +### External Variables + +#### Differential + +Symbol | Units | Description | Note +-----------|--------|-------------------------|------ +$\omega$ | [p.u.] | Generator speed deviation | Optional, defaults to zero; source diagram $\omega_g = 1 + \omega$ + +#### Algebraic + +Symbol | Units | Description | Note +-------------------------------------|--------|-----------------------------------|------ +$V_{\mathrm{r}}$ | [p.u.] | Terminal voltage, real component | Owned by bus object +$V_{\mathrm{i}}$ | [p.u.] | Terminal voltage, imaginary component | Owned by bus object +$P_e$ | [p.u.] | Electrical active power | Source label: `Pe` +$Q_{\mathrm{gen}}$ | [p.u.] | Reactive-power feedback | Source label: `Qgen` +$Q_{\mathrm{ext}}$ | [p.u.] | External reactive-power command | Optional, defaults to initialized constant +$\phi_{\mathrm{pf}}^{\mathrm{ref}}$ | [rad] | Power-factor angle reference | Source label: `pfaref`; used through tangent block +$P_{\mathrm{ref}}$ | [p.u.] | External active-power reference | Optional, defaults to initialized constant + +## Model Equations + +For readability, define: + +```math +\begin{aligned} + f_{\mathrm{PIQ}} &= K_{\mathrm{qi}} e_Q \\ + f_{\mathrm{PIV}} &= K_{\mathrm{vi}} e_{\mathrm{PIV}} +\end{aligned} +``` + +### Differential Equations + +The state-equation residuals use compact limiter notation where applicable. The measurement filters are written in descriptor form: if $T_{\mathrm{rv}} = 0$ or $T_{\mathrm{p}} = 0$, the corresponding variable should be tagged algebraic. The $Q_V$ equation also uses $T_{\mathrm{iq}}$ as a derivative coefficient, but $T_{\mathrm{iq}} > 0$ remains required because the freeze multiplier makes the zero-time case structurally different. + +```math +\begin{aligned} + 0 &= -T_{\mathrm{rv}}\dot V_{\mathrm{meas}} - V_{\mathrm{meas}} + V_T \\ + 0 &= -T_{\mathrm{p}}\dot P_{\mathrm{meas}} - P_{\mathrm{meas}} + P_e \\ + 0 &= + -\dot x_{\mathrm{PIQ}} + + (1 - s_{\mathrm{dip}}) + \text{antiwindup}\!\left( + V_{\mathrm{PIQ}}, + f_{\mathrm{PIQ}}, + V^{\min}, + V^{\max} + \right) \\ + 0 &= + -\dot x_{\mathrm{PIV}} + + (1 - s_{\mathrm{dip}}) + \text{antiwindup}\!\left( + I_{\mathrm{qbase}}, + f_{\mathrm{PIV}}, + -I_{\mathrm{q}}^{\max}, + I_{\mathrm{q}}^{\max} + \right) \\ + 0 &= + -T_{\mathrm{iq}}\dot Q_V + - (1 - s_{\mathrm{dip}})Q_V + + (1 - s_{\mathrm{dip}})Q_{\mathrm{ref}}/V_{\mathrm{meas}}^{\mathrm{safe}} \\ + 0 &= + -\dot P_{\mathrm{ord}} + + (1 - s_{\mathrm{dip}}) + \text{antiwindup}\!\left( + P_{\mathrm{ord}}, + r_{\mathrm{pord}}, + P^{\min}, + P^{\max} + \right) +\end{aligned} +``` + +CommonMath defines the [Anti-Windup](../../../../CommonMath.md#anti-windup-indicator) target and smooth approximation. + +### Algebraic Equations + +The algebraic targets use CommonMath helper notation where applicable: + +```math +\begin{aligned} + 0 &= -V_T^2 + V_{\mathrm{r}}^2 + V_{\mathrm{i}}^2 \\ + 0 &= -V_{\mathrm{meas}}^{\mathrm{safe}} + + \text{max}(V_{\mathrm{meas}}, 0.01) \\ + 0 &= -s_{\mathrm{dip}} + + \text{outside}(V_T, V_{\mathrm{dip}}, V_{\mathrm{up}}) \\ + 0 &= -V_{\mathrm{err}} + + \text{deadband}\!\left( + V_{\mathrm{ref0}} - V_{\mathrm{meas}}, + D_{\mathrm{bd1}}, + D_{\mathrm{bd2}} + \right) \\ + 0 &= -I_{\mathrm{qv}} + + \text{clamp}\!\left( + K_{\mathrm{qv}} V_{\mathrm{err}}, + I_{\mathrm{qinj}}^{\min}, + I_{\mathrm{qinj}}^{\max} + \right) \\ + 0 &= -Q_{\mathrm{ref}} + + s_{\mathrm{pf}} P_{\mathrm{meas}}\tan(\phi_{\mathrm{pf}}^{\mathrm{ref}}) + + s_{\mathrm{pf}}^{\mathrm{off}} Q_{\mathrm{ext}} \\ + 0 &= -e_Q + + \text{clamp}\!\left(Q_{\mathrm{ref}}, Q^{\min}, Q^{\max}\right) + - Q_{\mathrm{gen}} \\ + 0 &= -V_{\mathrm{PIQ}} + + \text{clamp}\!\left( + K_{\mathrm{qp}} e_Q + x_{\mathrm{PIQ}}, + V^{\min}, + V^{\max} + \right) \\ + 0 &= -e_{\mathrm{PIV}} + + s_V V_{\mathrm{PIQ}} + + s_V^{\mathrm{off}}(Q_{\mathrm{ref}} + V_{\mathrm{ref1}}) + - V_{\mathrm{meas}} \\ + 0 &= -T_{\mathrm{pord}} f_{\mathrm{pord}} + + (1 + s_P\omega)P_{\mathrm{ref}} + - P_{\mathrm{ord}} \\ + 0 &= -r_{\mathrm{pord}} + + \text{clamp}\!\left( + f_{\mathrm{pord}}, + R_P^{\min}, + R_P^{\max} + \right) \\ + 0 &= -{I_{\mathrm{q}}^{\mathrm{circ}}}^2 + + (I^{\max})^2 - s_{PQ}(I_{\mathrm{p}}^{\mathrm{cmd}})^2 \\ + 0 &= -{I_{\mathrm{p}}^{\mathrm{circ}}}^2 + + (I^{\max})^2 - s_{PQ}^{\mathrm{off}}(I_{\mathrm{q}}^{\mathrm{cmd}})^2 \\ + 0 &= -I_{\mathrm{q}}^{\max} + + \text{min}(g_q(V_{\mathrm{meas}}), I_{\mathrm{q}}^{\mathrm{circ}}) \\ + 0 &= -I_{\mathrm{p}}^{\max} + + \text{min}(g_p(V_{\mathrm{meas}}), I_{\mathrm{p}}^{\mathrm{circ}}) \\ + 0 &= -I_{\mathrm{qbase}} + + \text{clamp}\!\left( + K_{\mathrm{vp}} e_{\mathrm{PIV}} + x_{\mathrm{PIV}}, + -I_{\mathrm{q}}^{\max}, + I_{\mathrm{q}}^{\max} + \right) \\ + 0 &= -I_{\mathrm{q}}^{\mathrm{raw}} + + s_Q I_{\mathrm{qbase}} + s_Q^{\mathrm{off}} Q_V + s_{\mathrm{dip}} I_{\mathrm{qv}} \\ + 0 &= -I_{\mathrm{q}}^{\mathrm{cmd}} + + \text{clamp}\!\left( + I_{\mathrm{q}}^{\mathrm{raw}}, + -I_{\mathrm{q}}^{\max}, + I_{\mathrm{q}}^{\max} + \right) \\ + 0 &= -I_{\mathrm{p}}^{\mathrm{cmd}} + + \text{clamp}\!\left( + P_{\mathrm{ord}}/V_{\mathrm{meas}}^{\mathrm{safe}}, + 0, + I_{\mathrm{p}}^{\max} + \right) +\end{aligned} +``` + +The $V_T$, $I_{\mathrm{q}}^{\mathrm{circ}}$, and $I_{\mathrm{p}}^{\mathrm{circ}}$ variables use nonnegative branches of squared algebraic residuals. This preserves the $s_{PQ}=0$ Q-priority and $s_{PQ}=1$ P-priority current-circle behavior without explicit square roots; a consistent solution should satisfy the nonnegative branch and nonnegative radicands. + +CommonMath defines the helper targets and smooth approximations for [min, max, clamp, deadband, and outside](../../../../CommonMath.md#derived-functions). + +## Initialization + +Initialization is performed by evaluating the steady-state residuals in dependency order. Let subscript $0$ denote initial values and set all internal derivatives to zero. If optional signals are not connected, use steady-state constants: + +```math +\begin{aligned} + V_{T,0} &= \sqrt{V_{\mathrm{r},0}^2 + V_{\mathrm{i},0}^2} \\ + \omega_0 &= 0 \\ + Q_{\mathrm{ext},0} &= Q_{\mathrm{gen},0} \\ + P_{\mathrm{ref},0} &= \dfrac{P_{e,0}}{1+s_P\omega_0} +\end{aligned} +``` + +Connected optional signals use their supplied initial values; if only some are omitted, compute the omitted constants with the connected initial values. Inconsistent supplied commands require a residual solve or initialization rejection. + +If $V_{\mathrm{ref0}}$ is omitted, set $V_{\mathrm{ref0}} = V_{T,0}$. Initialize the measurement variables from the descriptor-form filter residuals: + +```math +\begin{aligned} + V_{\mathrm{meas},0} &= V_{T,0} \\ + P_{\mathrm{meas},0} &= P_{e,0} +\end{aligned} +``` + +When $T_{\mathrm{rv}} = 0$ or $T_{\mathrm{p}} = 0$, the corresponding relation is an algebraic residual rather than a differential-state initial condition. + +Then evaluate the upstream algebraic chain: + +```math +\begin{aligned} + V_{\mathrm{meas},0}^{\mathrm{safe}} &= \text{max}(V_{\mathrm{meas},0}, 0.01) \\ + s_{\mathrm{dip},0} &= \text{outside}(V_{T,0}, V_{\mathrm{dip}}, V_{\mathrm{up}}) \\ + V_{\mathrm{err},0} &= \text{deadband}(V_{\mathrm{ref0}} - V_{\mathrm{meas},0}, D_{\mathrm{bd1}}, D_{\mathrm{bd2}}) \\ + I_{\mathrm{qv},0} &= \text{clamp}(K_{\mathrm{qv}} V_{\mathrm{err},0}, I_{\mathrm{qinj}}^{\min}, I_{\mathrm{qinj}}^{\max}) \\ + Q_{\mathrm{ref},0} &= s_{\mathrm{pf}} P_{\mathrm{meas},0}\tan(\phi_{\mathrm{pf},0}^{\mathrm{ref}}) + s_{\mathrm{pf}}^{\mathrm{off}} Q_{\mathrm{ext},0} \\ + e_{Q,0} &= \text{clamp}(Q_{\mathrm{ref},0}, Q^{\min}, Q^{\max}) - Q_{\mathrm{gen},0} \\ + Q_{V,0} &= \dfrac{Q_{\mathrm{ref},0}}{V_{\mathrm{meas},0}^{\mathrm{safe}}} \\ + P_{\mathrm{ord},0} &= (1+s_P\omega_0)P_{\mathrm{ref},0} +\end{aligned} +``` + +Initialize the reactive-power PI output so its residual and zero-derivative anti-windup condition hold: + +```math +\begin{aligned} + V_{\mathrm{PIQ},0} &= \text{clamp}(K_{\mathrm{qp}} e_{Q,0} + x_{\mathrm{PIQ},0}, V^{\min}, V^{\max}) \\ + e_{\mathrm{PIV},0} &= s_V V_{\mathrm{PIQ},0} + s_V^{\mathrm{off}}(Q_{\mathrm{ref},0} + V_{\mathrm{ref1}}) - V_{\mathrm{meas},0} +\end{aligned} +``` + +For an unsaturated zero-derivative start, require $e_{Q,0}=0$ for $x_{\mathrm{PIQ}}$ and choose or verify $e_{\mathrm{PIV},0}=0$ for $x_{\mathrm{PIV}}$. Then $x_{\mathrm{PIQ},0}=V_{\mathrm{PIQ},0}-K_{\mathrm{qp}}e_{Q,0}$; when $s_V=1$, set $V_{\mathrm{PIQ},0}=V_{\mathrm{meas},0}$, and when $s_V=0$, the supplied $Q_{\mathrm{ref},0}+V_{\mathrm{ref1}}$ must equal $V_{\mathrm{meas},0}$. Saturated initial conditions should be solved against the anti-windup residuals, not forced by this unsaturated formula. + +Finish by evaluating $g_q(V_{\mathrm{meas},0})$, $g_p(V_{\mathrm{meas},0})$, and the current-limit and current-command algebraic residuals in priority order. At the command steps, use the power-flow current targets before final limiting: + +```math +\begin{aligned} + I_{\mathrm{qbase},0}^{\star} &= \dfrac{Q_{\mathrm{gen},0}}{V_{\mathrm{meas},0}^{\mathrm{safe}}} \\ + I_{\mathrm{p},0}^{\star} &= \dfrac{P_{\mathrm{ord},0}}{V_{\mathrm{meas},0}^{\mathrm{safe}}} +\end{aligned} +``` + +For $s_{PQ}=0$, use: + +```math +\begin{aligned} +I_{\mathrm{q},0}^{\mathrm{circ}} +\rightarrow I_{\mathrm{q},0}^{\max} +\rightarrow I_{\mathrm{qbase},0} +\rightarrow I_{\mathrm{q},0}^{\mathrm{raw}} +\rightarrow I_{\mathrm{q},0}^{\mathrm{cmd}} +\rightarrow I_{\mathrm{p},0}^{\mathrm{circ}} +\rightarrow I_{\mathrm{p},0}^{\max} +\rightarrow I_{\mathrm{p},0}^{\mathrm{cmd}} +\end{aligned} +``` + +For $s_{PQ}=1$, use: + +```math +\begin{aligned} +I_{\mathrm{p},0}^{\mathrm{circ}} +\rightarrow I_{\mathrm{p},0}^{\max} +\rightarrow I_{\mathrm{p},0}^{\mathrm{cmd}} +\rightarrow I_{\mathrm{q},0}^{\mathrm{circ}} +\rightarrow I_{\mathrm{q},0}^{\max} +\rightarrow I_{\mathrm{qbase},0} +\rightarrow I_{\mathrm{q},0}^{\mathrm{raw}} +\rightarrow I_{\mathrm{q},0}^{\mathrm{cmd}} +\end{aligned} +``` + +After $I_{\mathrm{q},0}^{\max}$ and $I_{\mathrm{qbase},0}$ are known, initialize the voltage PI state from its output residual; the unsaturated zero-derivative start also requires the $e_{\mathrm{PIV},0}=0$ condition above: + +```math +x_{\mathrm{PIV},0} = I_{\mathrm{qbase},0} - K_{\mathrm{vp}} e_{\mathrm{PIV},0} +``` + +The current-circle variables use the nonnegative branch of the squared algebraic residuals; initialization must reject negative radicands. A standard steady-state initialization assumes $s_{\mathrm{dip},0}=0$. If initialized during voltage-dip or overvoltage logic, $Q_V$, $P_{\mathrm{ord}}$, and the PI histories are not uniquely determined without the unsupported hold-timer histories, so the implementation should solve a saturation-consistent state or reject the start. + +## Model Outputs + +Output | Units | Description | Note +----------------|--------|-------------------------------------|------ +`iqcmd` | [p.u.] | Reactive-current command output | Converter base +`ipcmd` | [p.u.] | Active-current command output | Converter base +`vmeas` | [p.u.] | Filtered terminal voltage | +`pmeas` | [p.u.] | Filtered electrical power | +`piq` | [p.u.] | Reactive-power PI controller state | +`piv` | [p.u.] | Voltage PI controller state | +`qv` | [p.u.] | Reactive-current command lag state | +`pord` | [p.u.] | Filtered active-power order | +`qref` | [p.u.] | Selected reactive-power reference | +`sdip` | [binary] | Voltage-dip/overvoltage freeze indicator | +`iqmax` | [p.u.] | Final reactive-current upper limit | Converter base +`ipmax` | [p.u.] | Final active-current upper limit | Converter base +`iqv` | [p.u.] | Reactive-current injection candidate | Converter base +`vqctrl` | [p.u.] | Reactive-power control PI output | +`iqbase` | [p.u.] | Base reactive-current command | Converter base + +## Outstanding + +Nonzero $T_{\mathrm{hld}}$ and $T_{\mathrm{hld2}}$ require timer/history-state support and are not modeled yet. With the required zero values, $I_{\mathrm{qinj}}^{\mathrm{frz}}$ is unreachable and $I_{\mathrm{p}}^{\max}$ is recalculated from VDL2 and current-circle logic at each residual evaluation instead of held after voltage recovery. + +A future smooth approximation of the held reactive-current path could introduce a continuous gate $h_q$: + +```math +\dot h_q = + \dfrac{1}{T_{\mathrm{rise}}} s_{\mathrm{dip}}(1-h_q) + - \dfrac{1}{T_{\mathrm{hld}}} (1-s_{\mathrm{dip}})h_q +``` + +That approximation is a modeling choice and is not part of the present equations. diff --git a/docs/Figures/PhasorDynamics_REECA_Diagram.png b/docs/Figures/PhasorDynamics_REECA_Diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..509adaa72e57efbe011f5dbae09a462f7abb445e GIT binary patch literal 134602 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
- - + + Figure 1: Exciter IEEET1 model. Figure courtesy of [PowerWorld](https://www.powerworld.com/WebHelp/)
@@ -25,11 +30,11 @@ $K_F$ | [p.u.] | Coefficient for feedback | 0.09 | $T_F$ | [sec] | Time constant for feedback | 1.46 | $V_R^{\min}$ | [p.u.] | Lower limit to voltage regulation | -1 | $V_R^{\max}$ | [p.u.] | Upper limit to voltage regulation | 1 | -$E_1$ | [p.u.] | Saturation Parameter | 2.8 | -$E_2$ | [p.u.] | Saturation Parameter | 3.73 | -$S_{e1}$ | [p.u.] | Saturation Parameter | 0.04 | -$S_{e2}$ | [p.u.] | Saturation Parameter | 0.33 | -$I_{spdlm}$ | [binary] | Speed Limit flag indicator | 0 | +$E_1$ | [p.u.] | Saturation Parameter | 2.8 | +$E_2$ | [p.u.] | Saturation Parameter | 3.73 | +$S_1$ | [p.u.] | Saturation Parameter | 0.04 | +$S_2$ | [p.u.] | Saturation Parameter | 0.33 | +$I_\text{spdlm}$ | [binary] | Speed limit flag indicator | 0 | ### Model Derived Parameters @@ -37,8 +42,8 @@ The relationship of the derived parameters is defined by the following quadratic the expected saturation near the operating region. ``` math \begin{aligned} - S_{e1} &= S_B(E_1-S_A)^2 \\ - S_{e2} &= S_B(E_2-S_A)^2 \\ + S_1 &= S_B(E_1-S_A)^2 \\ + S_2 &= S_B(E_2-S_A)^2 \\ \end{aligned} ``` @@ -47,23 +52,23 @@ Generally, this system has two solutions. The non-extraneous solution is as foll \begin{aligned} C &= \sqrt{ \dfrac - {S_{e2}} - {S_{e1}} - } + {S_2} + {S_1} + } \\ - S_A &= + S_A &= \dfrac {C E_1 - E_2} - {C - 1} + {C - 1} \\ - S_B &= + S_B &= \dfrac - {S_{e1}} + {S_1} {(E_1-S_A)^2} \end{aligned} ``` -## Model Variables +## Model Variables ### Internal Variables @@ -73,8 +78,8 @@ Symbol | Units | Description | Note ----------|--------|-----------------------------------|------- $V_{ts}$ | [p.u.] | Sensed terminal voltage | $V_R$ | [p.u.] | Voltage regulator | -$E_{fd}'$ | [p.u.] | Field-current pre-speed multiplier| -$V_{fx}$ | [p.u.] | Exciter feedback internal state | +$E_{fd}'$ | [p.u.] | Field-current pre-speed multiplier| +$V_{fx}$ | [p.u.] | Exciter feedback internal state | #### Algebraic @@ -86,7 +91,7 @@ $V_{tr}$ | [p.u.] | Terminal Voltage Error | $V_f$ | [p.u.] | Feedback Voltage | $V_E$ | [p.u.] | Excitation control voltage | $E_{fd}$ | [p.u.] | Field winding voltage | -$k_{sat}$ | [p.u.] | Saturation variable | +$k_\text{sat}$ | [p.u.] | Saturation variable | ### External Variables @@ -101,7 +106,7 @@ $\omega$ | [p.u.] | Machine Speed Deviation | Read from a Mac Symbol | Units | Description | Note ----------------|--------|-----------------------------------|------- $E_C$ | [p.u.] | Compensated machine terminal voltage magnitude | -$V_{ref}$ | [p.u.] | Reference terminal voltage | +$V_\text{ref}$ | [p.u.] | Reference terminal voltage | $V_{UEL}$ | [p.u.] | Input from under excitation limiter | $V_{OEL}$ | [p.u.] | Input from over excitation limiter | $V_S$ | [p.u.] | Input from stabilizer controller | @@ -117,73 +122,67 @@ The IEEET1 differential equations, as derived from the model diagram. Define the f = \dfrac{1}{T_A}\left[-V_R + K_A V_{tr}\right] ``` -so that $\dot V_R$ can be written in piecewise form compactly. +so that $\dot V_R$ is the anti-windup limited derivative. ```math \begin{aligned} \dot V_{ts} &= \dfrac{1}{T_R}(E_C-V_{ts}) \\ - \dot V_R &= - \begin{cases} - f - & \text{if } (V_R^{\min} < V_R < V_R^{\max}) & \lor \\ - & \quad (V_R \leq V_R^{\min} \land f>0) & \lor \\ - & \quad(V_R \geq V_R^{\max} \land f<0) \\ - 0 & \text{else } \\ - \end{cases} \\ + \dot V_R &= \operatorname{antiwindup} + \left(V_R, f;\ V_R^{\min}, V_R^{\max}\right) \\ \dot E_{fd}' &= \dfrac{1}{T_E}(V_R-V_E-K_E E_{fd}') \\ \dot V_{fx} &= \dfrac{1}{T_F}V_f \\ \end{aligned} ``` -In simulation the piecewise form above is replaced with a smooth approximation where $\phi$ is GridKit's smooth anti-windup indicator. See [CommonMath: Anti-Windup Indicator](../../../../CommonMath.md#anti-windup-indicator) for its definition, behavior, and design rationale. +CommonMath defines the [Anti-Windup](../../../../CommonMath.md#anti-windup-indicator) target and smooth approximation. ### Algebraic Equations The algebraic equations of the exciter. ```math \begin{aligned} - V_{tr} &= V_{ref} +V_{UEL} + V_{OEL} + V_S - V_f- V_{ts}\\ + V_{tr} &= V_\text{ref} +V_{UEL} + V_{OEL} + V_S - V_f- V_{ts}\\ V_f &= \dfrac{E_{fd}' K_F}{T_F} - V_{fx}\\ - V_E &= k_{sat}\cdot E_{fd}' \\ + V_E &= k_\text{sat}\cdot E_{fd}' \\ E_{fd}&= \begin{cases} - (1+\omega)E_{fd}' & \text{if } I_{spdlm}=1\\ + (1+\omega)E_{fd}' & \text{if } I_\text{spdlm}=1\\ E_{fd}' & \text{else} \\ \end{cases}\\ - k_{sat}&= \begin{cases} + k_\text{sat}&= \begin{cases} S_B(E_{fd}' -S_A)^2 & \text{if } E_{fd}' >S_A\\ 0 & \text{else } \\ \end{cases} \\ \end{aligned} ``` -#### Smooth Piecewise Approximation (Algebraic) +#### Smooth Piecewise Approximation (Algebraic) For the algebraic piecewise functions (non-flags), this implementation is straightforward when the approximation above is used. +Here $q$ is GridKit's [Quadratic Ramp](../../../../CommonMath.md#primitives). ```math \begin{aligned} E_{fd} - &=(1 + \omega I_{spdlm})E_{fd}' \\ - k_{sat} - &=S_B\left[(E_{fd}' -S_A) \cdot \sigma (E_{fd}' -S_A)\right]^2 + &=(1 + \omega I_\text{spdlm})E_{fd}' \\ + k_\text{sat} + &=S_B\, q(E_{fd}' -S_A) \end{aligned} ``` -The approximation approaches an exact solution as the sigmoid steepness increases. ## Initialization -The machine initializes $E_{fd}$ first. IEEET1 reads that value as $E_{fd,0}$, along with any attached $\omega$ and $V_S$, and solves the steady-state algebraic chain so all residuals vanish with $\dot y = 0$. There is no compensation impedance, so $E_C$ is taken as the terminal voltage magnitude. Saturation and the speed-limit flag are included directly; $V_{ref}$ is set to close the $V_{tr}$ equation with the current auxiliary inputs. +The machine initializes $E_{fd}$ first. IEEET1 reads that value as $E_{fd,0}$, along with any attached $\omega$ and $V_S$, and solves the steady-state algebraic chain so all residuals vanish with $\dot y = 0$. There is no compensation impedance, so $E_C$ is taken as the terminal voltage magnitude. Saturation and the speed-limit flag are included directly; $V_\text{ref}$ is set to close the $V_{tr}$ equation with the current auxiliary inputs. ```math \begin{aligned} E_C &= \sqrt{V_r^2 + V_i^2} \\ - E_{fd}' &= \dfrac{E_{fd,0}}{1 + I_{spdlm}\,\omega} \\ - k_{sat} &= S_B\big[(E_{fd}' - S_A)\,\sigma(E_{fd}' - S_A)\big]^2 \\ - V_E &= k_{sat}\, E_{fd}' \\ + E_{fd}' &= \dfrac{E_{fd,0}}{1 + I_\text{spdlm}\,\omega} \\ + k_\text{sat} &= S_B\, q(E_{fd}' - S_A) \\ + V_E &= k_\text{sat}\, E_{fd}' \\ V_R &= K_E\, E_{fd}' + V_E \\ V_{tr} &= \dfrac{V_R}{K_A} \\ V_{fx} &= \dfrac{K_F}{T_F}\, E_{fd}' \\ V_{ts} &= E_C \\ V_f &= 0 \\ - V_{ref} &= E_C + V_{tr} - V_{UEL} - V_{OEL} - V_S + V_\text{ref} &= E_C + V_{tr} - V_{UEL} - V_{OEL} - V_S \end{aligned} ``` @@ -192,4 +191,4 @@ All internal derivatives initialize to zero. The field voltage, $E_{fd}$, is an internal model variable. -The magnetic saturation coefficient $k_{sat}$ is calculated from $E_{fd}$ using the smooth piecewise version above. +The magnetic saturation coefficient $k_\text{sat}$ is calculated from $E_{fd}$ using the smooth piecewise version above. diff --git a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp index 104976d97..836e9c3ff 100644 --- a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp @@ -257,12 +257,11 @@ namespace GridKit ScalarT omega = ws[0]; // The 'pre-limit' derivative of Pv - ScalarT func = (-pv + (pref_ - omega) / R_) / T1_; - ScalarT valv_ind = Math::indicator(pv, func, Pvmin_, Pvmax_); + ScalarT func = (-pv + (pref_ - omega) / R_) / T1_; // Internal Differential Equations f[0] = -ptx_dot + pv - (ptx + T2_ * pv) / T3_; - f[1] = -pv_dot + valv_ind * func; + f[1] = -pv_dot + Math::antiwindup(pv, func, Pvmin_, Pvmax_); // Internal Algebraic Equations f[2] = -pmech + (ptx + T2_ * pv) / T3_ - (Dt_ * omega); From d7bda62225fa5d23c7b446536910a008a1ed6ea7 Mon Sep 17 00:00:00 2001 From: lukelowry Date: Tue, 19 May 2026 18:12:29 -0500 Subject: [PATCH 09/12] Attempt to fix rendering issues. --- .../PhasorDynamics/Converter/REECA/README.md | 83 ++++--------------- 1 file changed, 17 insertions(+), 66 deletions(-) diff --git a/GridKit/Model/PhasorDynamics/Converter/REECA/README.md b/GridKit/Model/PhasorDynamics/Converter/REECA/README.md index 2b0fdc99a..977c419a4 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REECA/README.md +++ b/GridKit/Model/PhasorDynamics/Converter/REECA/README.md @@ -260,75 +260,26 @@ The algebraic targets use CommonMath helper notation where applicable: ```math \begin{aligned} 0 &= -V_T^2 + V_{\mathrm{r}}^2 + V_{\mathrm{i}}^2 \\ - 0 &= -V_{\mathrm{meas}}^{\mathrm{safe}} - + \text{max}(V_{\mathrm{meas}}, 0.01) \\ - 0 &= -s_{\mathrm{dip}} - + \text{outside}(V_T, V_{\mathrm{dip}}, V_{\mathrm{up}}) \\ - 0 &= -V_{\mathrm{err}} - + \text{deadband}\!\left( - V_{\mathrm{ref0}} - V_{\mathrm{meas}}, - D_{\mathrm{bd1}}, - D_{\mathrm{bd2}} - \right) \\ - 0 &= -I_{\mathrm{qv}} - + \text{clamp}\!\left( - K_{\mathrm{qv}} V_{\mathrm{err}}, - I_{\mathrm{qinj}}^{\min}, - I_{\mathrm{qinj}}^{\max} - \right) \\ + 0 &= -V_{\mathrm{meas}}^{\mathrm{safe}} + \max(V_{\mathrm{meas}}, 0.01) \\ + 0 &= -s_{\mathrm{dip}} + \text{outside}(V_T, V_{\mathrm{dip}}, V_{\mathrm{up}}) \\ + 0 &= -V_{\mathrm{err}} + \text{deadband}(V_{\mathrm{ref0}} - V_{\mathrm{meas}}, D_{\mathrm{bd1}}, D_{\mathrm{bd2}}) \\ + 0 &= -I_{\mathrm{qv}} + \text{clamp}(K_{\mathrm{qv}} V_{\mathrm{err}}, I_{\mathrm{qinj}}^{\min}, I_{\mathrm{qinj}}^{\max}) \\ 0 &= -Q_{\mathrm{ref}} + s_{\mathrm{pf}} P_{\mathrm{meas}}\tan(\phi_{\mathrm{pf}}^{\mathrm{ref}}) + s_{\mathrm{pf}}^{\mathrm{off}} Q_{\mathrm{ext}} \\ - 0 &= -e_Q - + \text{clamp}\!\left(Q_{\mathrm{ref}}, Q^{\min}, Q^{\max}\right) - - Q_{\mathrm{gen}} \\ - 0 &= -V_{\mathrm{PIQ}} - + \text{clamp}\!\left( - K_{\mathrm{qp}} e_Q + x_{\mathrm{PIQ}}, - V^{\min}, - V^{\max} - \right) \\ - 0 &= -e_{\mathrm{PIV}} - + s_V V_{\mathrm{PIQ}} - + s_V^{\mathrm{off}}(Q_{\mathrm{ref}} + V_{\mathrm{ref1}}) - - V_{\mathrm{meas}} \\ - 0 &= -T_{\mathrm{pord}} f_{\mathrm{pord}} - + (1 + s_P\omega)P_{\mathrm{ref}} - - P_{\mathrm{ord}} \\ - 0 &= -r_{\mathrm{pord}} - + \text{clamp}\!\left( - f_{\mathrm{pord}}, - R_P^{\min}, - R_P^{\max} - \right) \\ - 0 &= -{I_{\mathrm{q}}^{\mathrm{circ}}}^2 - + (I^{\max})^2 - s_{PQ}(I_{\mathrm{p}}^{\mathrm{cmd}})^2 \\ - 0 &= -{I_{\mathrm{p}}^{\mathrm{circ}}}^2 - + (I^{\max})^2 - s_{PQ}^{\mathrm{off}}(I_{\mathrm{q}}^{\mathrm{cmd}})^2 \\ - 0 &= -I_{\mathrm{q}}^{\max} - + \text{min}(g_q(V_{\mathrm{meas}}), I_{\mathrm{q}}^{\mathrm{circ}}) \\ - 0 &= -I_{\mathrm{p}}^{\max} - + \text{min}(g_p(V_{\mathrm{meas}}), I_{\mathrm{p}}^{\mathrm{circ}}) \\ - 0 &= -I_{\mathrm{qbase}} - + \text{clamp}\!\left( - K_{\mathrm{vp}} e_{\mathrm{PIV}} + x_{\mathrm{PIV}}, - -I_{\mathrm{q}}^{\max}, - I_{\mathrm{q}}^{\max} - \right) \\ - 0 &= -I_{\mathrm{q}}^{\mathrm{raw}} - + s_Q I_{\mathrm{qbase}} + s_Q^{\mathrm{off}} Q_V + s_{\mathrm{dip}} I_{\mathrm{qv}} \\ - 0 &= -I_{\mathrm{q}}^{\mathrm{cmd}} - + \text{clamp}\!\left( - I_{\mathrm{q}}^{\mathrm{raw}}, - -I_{\mathrm{q}}^{\max}, - I_{\mathrm{q}}^{\max} - \right) \\ - 0 &= -I_{\mathrm{p}}^{\mathrm{cmd}} - + \text{clamp}\!\left( - P_{\mathrm{ord}}/V_{\mathrm{meas}}^{\mathrm{safe}}, - 0, - I_{\mathrm{p}}^{\max} - \right) + 0 &= -e_Q + \text{clamp}(Q_{\mathrm{ref}}, Q^{\min}, Q^{\max}) - Q_{\mathrm{gen}} \\ + 0 &= -V_{\mathrm{PIQ}} + \text{clamp}(K_{\mathrm{qp}} e_Q + x_{\mathrm{PIQ}}, V^{\min}, V^{\max}) \\ + 0 &= -e_{\mathrm{PIV}} + s_V V_{\mathrm{PIQ}} + s_V^{\mathrm{off}}(Q_{\mathrm{ref}} + V_{\mathrm{ref1}}) - V_{\mathrm{meas}} \\ + 0 &= -T_{\mathrm{pord}} f_{\mathrm{pord}} + (1 + s_P\omega)P_{\mathrm{ref}} - P_{\mathrm{ord}} \\ + 0 &= -r_{\mathrm{pord}} + \text{clamp}(f_{\mathrm{pord}}, R_P^{\min}, R_P^{\max}) \\ + 0 &= -{I_{\mathrm{q}}^{\mathrm{circ}}}^2 + (I^{\max})^2 - s_{PQ}(I_{\mathrm{p}}^{\mathrm{cmd}})^2 \\ + 0 &= -{I_{\mathrm{p}}^{\mathrm{circ}}}^2 + (I^{\max})^2 - s_{PQ}^{\mathrm{off}}(I_{\mathrm{q}}^{\mathrm{cmd}})^2 \\ + 0 &= -I_{\mathrm{q}}^{\max} + \text{min}(g_q(V_{\mathrm{meas}}), I_{\mathrm{q}}^{\mathrm{circ}}) \\ + 0 &= -I_{\mathrm{p}}^{\max} + \text{min}(g_p(V_{\mathrm{meas}}), I_{\mathrm{p}}^{\mathrm{circ}}) \\ + 0 &= -I_{\mathrm{qbase}} + \text{clamp}(K_{\mathrm{vp}} e_{\mathrm{PIV}} + x_{\mathrm{PIV}}, -I_{\mathrm{q}}^{\max}, I_{\mathrm{q}}^{\max}) \\ + 0 &= -I_{\mathrm{q}}^{\mathrm{raw}} + s_Q I_{\mathrm{qbase}} + s_Q^{\mathrm{off}} Q_V + s_{\mathrm{dip}} I_{\mathrm{qv}} \\ + 0 &= -I_{\mathrm{q}}^{\mathrm{cmd}} + \text{clamp}(I_{\mathrm{q}}^{\mathrm{raw}}, -I_{\mathrm{q}}^{\max}, I_{\mathrm{q}}^{\max}) \\ + 0 &= -I_{\mathrm{p}}^{\mathrm{cmd}} + \text{clamp}(P_{\mathrm{ord}}/V_{\mathrm{meas}}^{\mathrm{safe}}, 0, I_{\mathrm{p}}^{\max}) \end{aligned} ``` From 01d185d56f165b3e2ca26d6ad768697b101b177f Mon Sep 17 00:00:00 2001 From: lukelowry Date: Tue, 19 May 2026 18:43:28 -0500 Subject: [PATCH 10/12] github markdown brace limit - break into groups in REECA --- GridKit/CommonMath.md | 6 +-- .../PhasorDynamics/Converter/REECA/README.md | 47 ++++++++++--------- .../PhasorDynamics/Converter/REGCA/README.md | 36 +++++++------- 3 files changed, 47 insertions(+), 42 deletions(-) diff --git a/GridKit/CommonMath.md b/GridKit/CommonMath.md index 137f28795..a654487a2 100644 --- a/GridKit/CommonMath.md +++ b/GridKit/CommonMath.md @@ -23,8 +23,8 @@ Smooth, autodiff-friendly replacements for piecewise functions used across GridK 1 & x > 0 \end{cases} \\ -\rho(x) &= \max(x,0) \\ -q(x) &= \max(x,0)^2 +\rho(x) &= x\,\sigma(x) \\ +q(x) &= x^2\,\sigma(x) \end{aligned} ``` @@ -38,7 +38,7 @@ q(x) &= x^2\,\sigma(x) \end{aligned} ``` -The scale $\mu=4\cdot f_{\text{sync}}=240$ is chosen so $\sigma$ behaves like a step on inputs of order 1 while keeping derivatives finite. As $\mu \to \infty$, these functions approach their exact targets. +The scale $\mu=4\cdot f_{\text{sync}}=240$ is chosen so $\sigma$ behaves like a step on inputs of order 1 while keeping derivatives finite. As $\mu \to \infty$, these functions approach their exact targets. (*Note*: the implementation of the quadratic ramp `q(x)` could be optimized with Enzyme features down the road). ## Derived Functions diff --git a/GridKit/Model/PhasorDynamics/Converter/REECA/README.md b/GridKit/Model/PhasorDynamics/Converter/REECA/README.md index 977c419a4..6e0d0b83e 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REECA/README.md +++ b/GridKit/Model/PhasorDynamics/Converter/REECA/README.md @@ -259,27 +259,32 @@ The algebraic targets use CommonMath helper notation where applicable: ```math \begin{aligned} - 0 &= -V_T^2 + V_{\mathrm{r}}^2 + V_{\mathrm{i}}^2 \\ - 0 &= -V_{\mathrm{meas}}^{\mathrm{safe}} + \max(V_{\mathrm{meas}}, 0.01) \\ - 0 &= -s_{\mathrm{dip}} + \text{outside}(V_T, V_{\mathrm{dip}}, V_{\mathrm{up}}) \\ - 0 &= -V_{\mathrm{err}} + \text{deadband}(V_{\mathrm{ref0}} - V_{\mathrm{meas}}, D_{\mathrm{bd1}}, D_{\mathrm{bd2}}) \\ - 0 &= -I_{\mathrm{qv}} + \text{clamp}(K_{\mathrm{qv}} V_{\mathrm{err}}, I_{\mathrm{qinj}}^{\min}, I_{\mathrm{qinj}}^{\max}) \\ - 0 &= -Q_{\mathrm{ref}} - + s_{\mathrm{pf}} P_{\mathrm{meas}}\tan(\phi_{\mathrm{pf}}^{\mathrm{ref}}) - + s_{\mathrm{pf}}^{\mathrm{off}} Q_{\mathrm{ext}} \\ - 0 &= -e_Q + \text{clamp}(Q_{\mathrm{ref}}, Q^{\min}, Q^{\max}) - Q_{\mathrm{gen}} \\ - 0 &= -V_{\mathrm{PIQ}} + \text{clamp}(K_{\mathrm{qp}} e_Q + x_{\mathrm{PIQ}}, V^{\min}, V^{\max}) \\ - 0 &= -e_{\mathrm{PIV}} + s_V V_{\mathrm{PIQ}} + s_V^{\mathrm{off}}(Q_{\mathrm{ref}} + V_{\mathrm{ref1}}) - V_{\mathrm{meas}} \\ - 0 &= -T_{\mathrm{pord}} f_{\mathrm{pord}} + (1 + s_P\omega)P_{\mathrm{ref}} - P_{\mathrm{ord}} \\ - 0 &= -r_{\mathrm{pord}} + \text{clamp}(f_{\mathrm{pord}}, R_P^{\min}, R_P^{\max}) \\ - 0 &= -{I_{\mathrm{q}}^{\mathrm{circ}}}^2 + (I^{\max})^2 - s_{PQ}(I_{\mathrm{p}}^{\mathrm{cmd}})^2 \\ - 0 &= -{I_{\mathrm{p}}^{\mathrm{circ}}}^2 + (I^{\max})^2 - s_{PQ}^{\mathrm{off}}(I_{\mathrm{q}}^{\mathrm{cmd}})^2 \\ - 0 &= -I_{\mathrm{q}}^{\max} + \text{min}(g_q(V_{\mathrm{meas}}), I_{\mathrm{q}}^{\mathrm{circ}}) \\ - 0 &= -I_{\mathrm{p}}^{\max} + \text{min}(g_p(V_{\mathrm{meas}}), I_{\mathrm{p}}^{\mathrm{circ}}) \\ - 0 &= -I_{\mathrm{qbase}} + \text{clamp}(K_{\mathrm{vp}} e_{\mathrm{PIV}} + x_{\mathrm{PIV}}, -I_{\mathrm{q}}^{\max}, I_{\mathrm{q}}^{\max}) \\ - 0 &= -I_{\mathrm{q}}^{\mathrm{raw}} + s_Q I_{\mathrm{qbase}} + s_Q^{\mathrm{off}} Q_V + s_{\mathrm{dip}} I_{\mathrm{qv}} \\ - 0 &= -I_{\mathrm{q}}^{\mathrm{cmd}} + \text{clamp}(I_{\mathrm{q}}^{\mathrm{raw}}, -I_{\mathrm{q}}^{\max}, I_{\mathrm{q}}^{\max}) \\ - 0 &= -I_{\mathrm{p}}^{\mathrm{cmd}} + \text{clamp}(P_{\mathrm{ord}}/V_{\mathrm{meas}}^{\mathrm{safe}}, 0, I_{\mathrm{p}}^{\max}) + 0 &= -V_T^2 + V_\mathrm r^2 + V_\mathrm i^2 \\ + 0 &= -V_\mathrm{meas}^\mathrm{safe} + \max(V_\mathrm{meas}, 0.01) \\ + 0 &= -s_\mathrm{dip} + \text{outside}(V_T, V_\mathrm{dip}, V_\mathrm{up}) \\ + 0 &= -V_\mathrm{err} + \text{deadband}(V_\mathrm{ref0} - V_\mathrm{meas}, D_\mathrm{bd1}, D_\mathrm{bd2}) \\ + 0 &= -I_\mathrm{qv} + \text{clamp}(K_\mathrm{qv} V_\mathrm{err}, I_\mathrm{qinj}^{\min}, I_\mathrm{qinj}^{\max}) \\ + 0 &= -Q_\mathrm{ref} + + s_\mathrm{pf} P_\mathrm{meas}\tan(\phi_\mathrm{pf}^\mathrm{ref}) + + s_\mathrm{pf}^\mathrm{off} Q_\mathrm{ext} \\ + 0 &= -e_Q + \text{clamp}(Q_\mathrm{ref}, Q^{\min}, Q^{\max}) - Q_\mathrm{gen} \\ + 0 &= -V_\mathrm{PIQ} + \text{clamp}(K_\mathrm{qp} e_Q + x_\mathrm{PIQ}, V^{\min}, V^{\max}) \\ + 0 &= -e_\mathrm{PIV} + s_V V_\mathrm{PIQ} + s_V^\mathrm{off}(Q_\mathrm{ref} + V_\mathrm{ref1}) - V_\mathrm{meas} \\ + 0 &= -T_\mathrm{pord} f_\mathrm{pord} + (1 + s_P\omega)P_\mathrm{ref} - P_\mathrm{ord} \\ + 0 &= -r_\mathrm{pord} + \text{clamp}(f_\mathrm{pord}, R_P^{\min}, R_P^{\max}) +\end{aligned} +``` + +```math +\begin{aligned} + 0 &= -{I_\mathrm{q}^\mathrm{circ}}^2 + (I^{\max})^2 - s_{PQ}(I_\mathrm{p}^\mathrm{cmd})^2 \\ + 0 &= -{I_\mathrm{p}^\mathrm{circ}}^2 + (I^{\max})^2 - s_{PQ}^\mathrm{off}(I_\mathrm{q}^\mathrm{cmd})^2 \\ + 0 &= -I_\mathrm{q}^{\max} + \text{min}(g_q(V_\mathrm{meas}), I_\mathrm{q}^\mathrm{circ}) \\ + 0 &= -I_\mathrm{p}^{\max} + \text{min}(g_p(V_\mathrm{meas}), I_\mathrm{p}^\mathrm{circ}) \\ + 0 &= -I_\mathrm{qbase} + \text{clamp}(K_\mathrm{vp} e_\mathrm{PIV} + x_\mathrm{PIV}, -I_\mathrm{q}^{\max}, I_\mathrm{q}^{\max}) \\ + 0 &= -I_\mathrm{q}^\mathrm{raw} + s_Q I_\mathrm{qbase} + s_Q^\mathrm{off} Q_V + s_\mathrm{dip} I_\mathrm{qv} \\ + 0 &= -I_\mathrm{q}^\mathrm{cmd} + \text{clamp}(I_\mathrm{q}^\mathrm{raw}, -I_\mathrm{q}^{\max}, I_\mathrm{q}^{\max}) \\ + 0 &= -I_\mathrm{p}^\mathrm{cmd} + \text{clamp}(P_\mathrm{ord}/V_\mathrm{meas}^\mathrm{safe}, 0, I_\mathrm{p}^{\max}) \end{aligned} ``` diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md b/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md index c647cbf14..ea352c520 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md +++ b/GridKit/Model/PhasorDynamics/Converter/REGCA/README.md @@ -255,31 +255,31 @@ steady-state initial values: ```math \begin{aligned} - V_T &= \sqrt{V_{\mathrm{r}}^2 + V_{\mathrm{i}}^2} \\ - I_{\mathrm{r0}} &= \dfrac{P_{\mathrm{0}}V_{\mathrm{r}} + Q_{\mathrm{0}}V_{\mathrm{i}}}{V_T^2} - \dfrac{S^{\mathrm{sys}}}{S^{\mathrm{conv}}} \\ - I_{\mathrm{i0}} &= \dfrac{P_{\mathrm{0}}V_{\mathrm{i}} - Q_{\mathrm{0}}V_{\mathrm{r}}}{V_T^2} - \dfrac{S^{\mathrm{sys}}}{S^{\mathrm{conv}}} \\ + V_T &= \sqrt{V_\mathrm{r}^2 + V_\mathrm{i}^2} \\ + I_\mathrm{r0} &= \dfrac{P_0 V_\mathrm{r} + Q_0 V_\mathrm{i}}{V_T^2} + \dfrac{S^\mathrm{sys}}{S^\mathrm{conv}} \\ + I_\mathrm{i0} &= \dfrac{P_0 V_\mathrm{i} - Q_0 V_\mathrm{r}}{V_T^2} + \dfrac{S^\mathrm{sys}}{S^\mathrm{conv}} \\ V_{M0} &= V_T \\ I_{L0} &= \text{linseg}(V_T;\ V_{L0},\ V_{L1},\ I_{L1}) \\ - I_{\mathrm{p0}} &= \dfrac{I_{\mathrm{r0}}} + I_\mathrm{p0} &= \dfrac{I_\mathrm{r0}} {\text{linseg}(V_T;\ V_{A0},\ V_{A1},\ 1)} \\ - \ell_{\mathrm{p0}} &= -R_{\mathrm{p}}^{\max} - - (M_{\mathrm{p}} - R_{\mathrm{p}}^{\max})\sigma(I_{\mathrm{p0}}) \\ - u_{\mathrm{p0}} &= + \ell_\mathrm{p0} &= -R_\mathrm{p}^{\max} + - (M_\mathrm{p} - R_\mathrm{p}^{\max})\sigma(I_\mathrm{p0}) \\ + u_\mathrm{p0} &= \begin{cases} - M_{\mathrm{p}}(1-\sigma(I_{\mathrm{p0}})) - + R_{\mathrm{p}}^{\max}\sigma(I_{\mathrm{p0}}) - \sigma(I_{L0} - I_{\mathrm{p0}}) + M_\mathrm{p}(1-\sigma(I_\mathrm{p0})) + + R_\mathrm{p}^{\max}\sigma(I_\mathrm{p0}) + \sigma(I_{L0} - I_\mathrm{p0}) & s_L = 1 \\ - M_{\mathrm{p}}(1-\sigma(I_{\mathrm{p0}})) - + R_{\mathrm{p}}^{\max}\sigma(I_{\mathrm{p0}}) + M_\mathrm{p}(1-\sigma(I_\mathrm{p0})) + + R_\mathrm{p}^{\max}\sigma(I_\mathrm{p0}) & s_L = 0 \end{cases} \\ - I_{\mathrm{q0}}^{\mathrm{extra}} &= 0 \\ - I_{\mathrm{q0}} &= -I_{\mathrm{i0}} + I_{\mathrm{q0}}^{\mathrm{extra}} \\ - I_{\mathrm{p0}}^{\mathrm{cmd}} &= I_{\mathrm{p0}} \\ - I_{\mathrm{q0}}^{\mathrm{cmd}} &= I_{\mathrm{q0}} + I_\mathrm{q0}^\mathrm{extra} &= 0 \\ + I_\mathrm{q0} &= -I_\mathrm{i0} + I_\mathrm{q0}^\mathrm{extra} \\ + I_\mathrm{p0}^\mathrm{cmd} &= I_\mathrm{p0} \\ + I_\mathrm{q0}^\mathrm{cmd} &= I_\mathrm{q0} \end{aligned} ``` From 1ae271cb2bb45de5d757f9e65f9b5094303a4238 Mon Sep 17 00:00:00 2001 From: Luke Lowery Date: Wed, 20 May 2026 08:35:33 -0500 Subject: [PATCH 11/12] Update incorrect LaTeX for GH in README.md [skip ci] --- GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md index cab2a062b..9bb2ef5fb 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md @@ -126,7 +126,7 @@ so that $\dot V_R$ is the anti-windup limited derivative. ```math \begin{aligned} \dot V_{ts} &= \dfrac{1}{T_R}(E_C-V_{ts}) \\ - \dot V_R &= \operatorname{antiwindup} + \dot V_R &= \text{antiwindup} \left(V_R, f;\ V_R^{\min}, V_R^{\max}\right) \\ \dot E_{fd}' &= \dfrac{1}{T_E}(V_R-V_E-K_E E_{fd}') \\ \dot V_{fx} &= \dfrac{1}{T_F}V_f \\ From c4387c308d79d964028df0afc7580a51143dba89 Mon Sep 17 00:00:00 2001 From: lukelowry Date: Sat, 23 May 2026 18:01:46 -0500 Subject: [PATCH 12/12] Test readability and arg type clarify --- GridKit/CommonMath.hpp | 20 +- .../Math/SmoothnessIndicatorTests.hpp | 357 ++++++++++-------- 2 files changed, 222 insertions(+), 155 deletions(-) diff --git a/GridKit/CommonMath.hpp b/GridKit/CommonMath.hpp index b2470d587..9bb3a5c3c 100644 --- a/GridKit/CommonMath.hpp +++ b/GridKit/CommonMath.hpp @@ -78,12 +78,18 @@ namespace GridKit * Smooth approximation to max(x, y), composed from the smooth ramp * function. * - * @tparam LeftT - left scalar data type - * @tparam RightT - right scalar data type + * @tparam LeftT - scalar type of x + * @tparam RightT - scalar type of y * * @param[in] x - First input signal * @param[in] y - Second input signal * @return Smooth maximum of x and y + * + * @note The two input types intentionally may differ. Model equations + * often compare a differentiable state or signal with a plain real + * parameter, limit, or literal bound. Keeping both template parameters + * lets the expression promote to the differentiable scalar type without + * forcing callers to cast every parameter. */ template __attribute__((always_inline)) inline auto max( @@ -99,12 +105,18 @@ namespace GridKit * Smooth approximation to min(x, y), composed from the smooth ramp * function. * - * @tparam LeftT - left scalar data type - * @tparam RightT - right scalar data type + * @tparam LeftT - scalar type of x + * @tparam RightT - scalar type of y * * @param[in] x - First input signal * @param[in] y - Second input signal * @return Smooth minimum of x and y + * + * @note The two input types intentionally may differ. Model equations + * often compare a differentiable state or signal with a plain real + * parameter, limit, or literal bound. Keeping both template parameters + * lets the expression promote to the differentiable scalar type without + * forcing callers to cast every parameter. */ template __attribute__((always_inline)) inline auto min( diff --git a/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp b/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp index 336c3afba..41f6d2ca1 100644 --- a/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp +++ b/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp @@ -1,8 +1,12 @@ #pragma once #include +#include +#include +#include #include +#include #include namespace GridKit @@ -12,6 +16,25 @@ namespace GridKit template class SmoothnessIndicatorTests { + private: + using RealT = typename GridKit::ScalarTraits::RealT; + + static constexpr RealT kSmoothTolerance = 1.0e-2; + static constexpr RealT kNearOne = 1.0 - kSmoothTolerance; + static constexpr RealT kRoundoffTolerance = 100.0 * std::numeric_limits::epsilon(); + + static ScalarT scalar(const RealT value) + { + return static_cast(value); + } + + static bool within(const ScalarT value, + const ScalarT expected, + const ScalarT tolerance) + { + return std::abs(value - expected) < tolerance; + } + public: SmoothnessIndicatorTests() = default; ~SmoothnessIndicatorTests() = default; @@ -20,13 +43,14 @@ namespace GridKit { TestStatus success = true; - const ScalarT lower = -0.25; - const ScalarT upper = 0.75; + const ScalarT lower = scalar(-0.25); + const ScalarT upper = scalar(0.75); + const ScalarT tol = scalar(kSmoothTolerance); - success *= (Math::clamp(static_cast(-1.0), lower, upper) < lower + static_cast(0.01)); - success *= (Math::clamp(static_cast(0.4), lower, upper) > lower); - success *= (Math::clamp(static_cast(0.4), lower, upper) < upper); - success *= (Math::clamp(static_cast(1.5), lower, upper) > upper - static_cast(0.01)); + success *= (Math::clamp(scalar(-1.0), lower, upper) < lower + tol); + success *= (Math::clamp(scalar(0.4), lower, upper) > lower); + success *= (Math::clamp(scalar(0.4), lower, upper) < upper); + success *= (Math::clamp(scalar(1.5), lower, upper) > upper - tol); return success.report(__func__); } @@ -35,38 +59,50 @@ namespace GridKit { TestStatus success = true; - const ScalarT lower = -0.05; - const ScalarT upper = 0.10; + const ScalarT lower = scalar(-0.05); + const ScalarT upper = scalar(0.10); + const ScalarT tol = scalar(kSmoothTolerance); - success *= (Math::deadband(static_cast(-1.0), lower, upper) < static_cast(-0.94)); - success *= (Math::deadband(static_cast(-1.0), lower, upper) > static_cast(-0.96)); - success *= (std::abs(Math::deadband(static_cast(0.02), lower, upper)) < static_cast(1.0e-8)); - success *= (Math::deadband(static_cast(1.0), lower, upper) > static_cast(0.89)); - success *= (Math::deadband(static_cast(1.0), lower, upper) < static_cast(0.91)); + const ScalarT below_input = scalar(-1.0); + const ScalarT inside_input = scalar(0.02); + const ScalarT above_input = scalar(1.0); + const ScalarT expected_below = below_input - lower; + const ScalarT expected_above = above_input - upper; + + success *= within(Math::deadband(below_input, lower, upper), expected_below, tol); + success *= (std::abs(Math::deadband(inside_input, lower, upper)) < tol * tol); + success *= within(Math::deadband(above_input, lower, upper), expected_above, tol); const ScalarT lower_breakpoint = Math::deadband(lower, lower, upper); const ScalarT upper_breakpoint = Math::deadband(upper, lower, upper); - success *= (lower_breakpoint < static_cast(0.0)); - success *= (upper_breakpoint > static_cast(0.0)); - success *= (std::abs(lower_breakpoint) < static_cast(0.003)); - success *= (std::abs(upper_breakpoint) < static_cast(0.003)); + success *= (lower_breakpoint < scalar(0.0)); + success *= (upper_breakpoint > scalar(0.0)); + success *= (std::abs(lower_breakpoint) < tol); + success *= (std::abs(upper_breakpoint) < tol); - const ScalarT x = -0.4; + const ScalarT x = scalar(-0.4); success *= (std::abs(Math::deadband(x, lower, upper) - (x - Math::clamp(x, lower, upper))) - < static_cast(1.0e-12)); - - success *= std::isfinite(Math::deadband(static_cast(4.0), lower, upper)); - success *= (Math::deadband(static_cast(4.0), lower, upper) > static_cast(3.89)); - success *= std::isfinite(Math::deadband(static_cast(-4.0), lower, upper)); - success *= (Math::deadband(static_cast(-4.0), lower, upper) < static_cast(-3.94)); - - const ScalarT point = 0.25; - success *= (std::abs(Math::deadband(static_cast(0.75), point, point) - static_cast(0.5)) - < static_cast(1.0e-12)); - success *= (std::abs(Math::deadband(static_cast(-0.25), point, point) + static_cast(0.5)) - < static_cast(1.0e-12)); + < scalar(kRoundoffTolerance)); + + const ScalarT far_above_input = scalar(4.0); + const ScalarT far_below_input = scalar(-4.0); + const ScalarT expected_far_above = far_above_input - upper; + const ScalarT expected_far_below = far_below_input - lower; + + success *= std::isfinite(Math::deadband(far_above_input, lower, upper)); + success *= within(Math::deadband(far_above_input, lower, upper), expected_far_above, tol); + success *= std::isfinite(Math::deadband(far_below_input, lower, upper)); + success *= within(Math::deadband(far_below_input, lower, upper), expected_far_below, tol); + + const ScalarT point = scalar(0.25); + const ScalarT above_point = scalar(0.75); + const ScalarT below_point = scalar(-0.25); + success *= (std::abs(Math::deadband(above_point, point, point) - (above_point - point)) + < scalar(kRoundoffTolerance)); + success *= (std::abs(Math::deadband(below_point, point, point) - (below_point - point)) + < scalar(kRoundoffTolerance)); return success.report(__func__); } @@ -75,27 +111,29 @@ namespace GridKit { TestStatus success = true; - const ScalarT limit_min = 0.0; - const ScalarT limit_max = 3.0; + const ScalarT limit_min = scalar(0.0); + const ScalarT limit_max = scalar(3.0); + const ScalarT near_zero = scalar(kSmoothTolerance); + const ScalarT near_one = scalar(kNearOne); - success *= (Math::above(static_cast(1.0), limit_min) > static_cast(0.99)); - success *= (Math::above(static_cast(-0.2), limit_min) < static_cast(0.1)); - success *= (Math::below(static_cast(1.0), limit_max) > static_cast(0.99)); - success *= (Math::below(static_cast(3.2), limit_max) < static_cast(0.1)); + success *= (Math::above(scalar(1.0), limit_min) > near_one); + success *= (Math::above(scalar(-0.2), limit_min) < near_zero); + success *= (Math::below(scalar(1.0), limit_max) > near_one); + success *= (Math::below(scalar(3.2), limit_max) < near_zero); - success *= (Math::inside(static_cast(1.5), limit_min, limit_max) > static_cast(0.99)); - success *= (Math::inside(static_cast(-0.2), limit_min, limit_max) < static_cast(0.1)); - success *= (Math::inside(static_cast(3.2), limit_min, limit_max) < static_cast(0.1)); + success *= (Math::inside(scalar(1.5), limit_min, limit_max) > near_one); + success *= (Math::inside(scalar(-0.2), limit_min, limit_max) < near_zero); + success *= (Math::inside(scalar(3.2), limit_min, limit_max) < near_zero); - success *= (Math::outside(static_cast(1.5), limit_min, limit_max) < static_cast(0.1)); - success *= (Math::outside(static_cast(-0.2), limit_min, limit_max) > static_cast(0.9)); - success *= (Math::outside(static_cast(3.2), limit_min, limit_max) > static_cast(0.9)); + success *= (Math::outside(scalar(1.5), limit_min, limit_max) < near_zero); + success *= (Math::outside(scalar(-0.2), limit_min, limit_max) > near_one); + success *= (Math::outside(scalar(3.2), limit_min, limit_max) > near_one); - const ScalarT x = static_cast(1.5); + const ScalarT x = scalar(1.5); success *= (std::abs(Math::inside(x, limit_min, limit_max) + Math::outside(x, limit_min, limit_max) - - static_cast(1.0)) - < static_cast(1.0e-12)); + - scalar(1.0)) + < scalar(kRoundoffTolerance)); return success.report(__func__); } @@ -104,12 +142,13 @@ namespace GridKit { TestStatus success = true; - const ScalarT rate = 0.5; + const ScalarT rate = scalar(0.5); + const ScalarT tol = scalar(kSmoothTolerance); - success *= (Math::slew(static_cast(2.0), rate) < static_cast(0.51)); - success *= (Math::slew(static_cast(-2.0), rate) > static_cast(-0.51)); - success *= (Math::slew(static_cast(0.2), rate) > static_cast(0.19)); - success *= (Math::slew(static_cast(-0.2), rate) < static_cast(-0.19)); + success *= within(Math::slew(scalar(2.0), rate), rate, tol); + success *= within(Math::slew(scalar(-2.0), rate), -rate, tol); + success *= within(Math::slew(scalar(0.2), rate), scalar(0.2), tol); + success *= within(Math::slew(scalar(-0.2), rate), scalar(-0.2), tol); return success.report(__func__); } @@ -118,36 +157,22 @@ namespace GridKit { TestStatus success = true; - success *= (Math::linseg(static_cast(-1.0), - static_cast(0.0), - static_cast(2.0), - static_cast(4.0)) - < static_cast(0.01)); - success *= (Math::linseg(static_cast(1.0), - static_cast(0.0), - static_cast(2.0), - static_cast(4.0)) - > static_cast(1.99)); - success *= (Math::linseg(static_cast(1.0), - static_cast(0.0), - static_cast(2.0), - static_cast(4.0)) - < static_cast(2.01)); - success *= (Math::linseg(static_cast(3.0), - static_cast(0.0), - static_cast(2.0), - static_cast(4.0)) - > static_cast(3.99)); - success *= (Math::linseg(static_cast(1.0), - static_cast(0.0), - static_cast(2.0), - static_cast(-4.0)) - < static_cast(-1.99)); - success *= (Math::linseg(static_cast(1.0), - static_cast(0.0), - static_cast(2.0), - static_cast(-4.0)) - > static_cast(-2.01)); + const ScalarT lower = scalar(0.0); + const ScalarT upper = scalar(2.0); + const ScalarT height = scalar(4.0); + const ScalarT tol = scalar(kSmoothTolerance); + + const ScalarT below_input = scalar(-1.0); + const ScalarT midpoint_input = scalar(1.0); + const ScalarT above_input = scalar(3.0); + const ScalarT expected_mid = height * (midpoint_input - lower) / (upper - lower); + const ScalarT negative_height = -height; + const ScalarT expected_mid_neg = negative_height * (midpoint_input - lower) / (upper - lower); + + success *= (Math::linseg(below_input, lower, upper, height) < tol); + success *= within(Math::linseg(midpoint_input, lower, upper, height), expected_mid, tol); + success *= within(Math::linseg(above_input, lower, upper, height), height, tol); + success *= within(Math::linseg(midpoint_input, lower, upper, negative_height), expected_mid_neg, tol); return success.report(__func__); } @@ -156,30 +181,34 @@ namespace GridKit { TestStatus success = true; - const ScalarT tau = static_cast(1.0 / 240.0); - const ScalarT at_zero = tau * std::log(static_cast(2.0)); - - success *= (Math::ramp(static_cast(1.0)) > static_cast(0.99)); - success *= (Math::ramp(static_cast(-1.0)) < static_cast(0.01)); - success *= (std::abs(Math::ramp(static_cast(0.0)) - at_zero) < static_cast(1.0e-12)); - success *= (Math::ramp(static_cast(-0.01)) > static_cast(0.0)); - success *= (Math::ramp(static_cast(0.01)) > Math::ramp(static_cast(0.0))); - success *= std::isfinite(Math::ramp(static_cast(4.0))); - success *= (Math::ramp(static_cast(4.0)) > static_cast(3.99)); - success *= std::isfinite(Math::ramp(static_cast(-4.0))); - success *= (Math::ramp(static_cast(-4.0)) < static_cast(1.0e-12)); - - const ScalarT lower = -0.25; - const ScalarT upper = 0.75; - const ScalarT x = 0.4; - - const ScalarT smooth_clip = lower + Math::ramp(x - lower) - Math::ramp(x - upper); - success *= (smooth_clip > lower); - success *= (smooth_clip < upper); - success *= std::isfinite(Math::clamp(static_cast(4.0), lower, upper)); - success *= (Math::clamp(static_cast(4.0), lower, upper) < upper + static_cast(1.0e-12)); - success *= std::isfinite(Math::clamp(static_cast(-4.0), lower, upper)); - success *= (Math::clamp(static_cast(-4.0), lower, upper) > lower - static_cast(1.0e-12)); + const ScalarT tol = scalar(kSmoothTolerance); + const ScalarT roundoff = scalar(kRoundoffTolerance); + const ScalarT tau = scalar(1.0 / 240.0); + const ScalarT at_zero = tau * std::log(scalar(2.0)); + const ScalarT far_above = scalar(4.0); + const ScalarT far_below = scalar(-4.0); + const ScalarT lower = scalar(-0.25); + const ScalarT upper = scalar(0.75); + const ScalarT x = scalar(0.4); + const ScalarT smooth_clip = lower + Math::ramp(x - lower) + - Math::ramp(x - upper); + + success *= (Math::ramp(scalar(1.0)) > scalar(kNearOne)); + success *= (Math::ramp(scalar(-1.0)) < tol); + success *= (std::abs(Math::ramp(scalar(0.0)) - at_zero) < roundoff); + success *= (Math::ramp(-tol) > scalar(0.0)); + success *= (Math::ramp(tol) > Math::ramp(scalar(0.0))); + success *= std::isfinite(Math::ramp(far_above)); + success *= (Math::ramp(far_above) > far_above - tol); + success *= std::isfinite(Math::ramp(far_below)); + success *= (Math::ramp(far_below) < roundoff); + + success *= (smooth_clip > lower); + success *= (smooth_clip < upper); + success *= std::isfinite(Math::clamp(far_above, lower, upper)); + success *= (Math::clamp(far_above, lower, upper) < upper + roundoff); + success *= std::isfinite(Math::clamp(far_below, lower, upper)); + success *= (Math::clamp(far_below, lower, upper) > lower - roundoff); return success.report(__func__); } @@ -188,35 +217,46 @@ namespace GridKit { TestStatus success = true; - const ScalarT high = static_cast(2.0); - const ScalarT low = static_cast(-1.0); + const ScalarT high = scalar(2.0); + const ScalarT low = scalar(-1.0); + const ScalarT tol = scalar(kSmoothTolerance); + + success *= within(Math::max(high, low), high, tol); + success *= within(Math::max(low, high), high, tol); + + success *= within(Math::min(high, low), low, tol); + success *= within(Math::min(low, high), low, tol); - success *= (Math::max(high, low) > high - static_cast(0.01)); - success *= (Math::max(high, low) < high + static_cast(0.01)); - success *= (Math::max(low, high) > high - static_cast(0.01)); - success *= (Math::max(low, high) < high + static_cast(0.01)); + using Variable = GridKit::DependencyTracking::Variable; - success *= (Math::min(high, low) > low - static_cast(0.01)); - success *= (Math::min(high, low) < low + static_cast(0.01)); - success *= (Math::min(low, high) > low - static_cast(0.01)); - success *= (Math::min(low, high) < low + static_cast(0.01)); + // This mirrors model equations where a differentiable state is + // limited by a plain real parameter. + const RealT parameter_bound = kSmoothTolerance; + const Variable state_below_bound{-1.0, 0}; + const Variable state_above_bound{1.0, 1}; + const auto lower_bounded_state = Math::max(state_below_bound, parameter_bound); + const auto upper_bounded_state = Math::min(state_above_bound, parameter_bound); - const auto lower_bounded = Math::max(static_cast(-1.0), 0.01); - success *= (lower_bounded > static_cast(0.009)); - success *= (lower_bounded < static_cast(0.011)); + static_assert(std::is_same::type, Variable>::value, + "Mixed-type max should keep the differentiable scalar type."); + static_assert(std::is_same::type, Variable>::value, + "Mixed-type min should keep the differentiable scalar type."); - const ScalarT x = static_cast(0.4); - const ScalarT y = static_cast(-0.7); + success *= (std::abs(lower_bounded_state.getValue() - parameter_bound) < kSmoothTolerance); + success *= (std::abs(upper_bounded_state.getValue() - parameter_bound) < kSmoothTolerance); + + const ScalarT x = scalar(0.4); + const ScalarT y = scalar(-0.7); success *= (std::abs(Math::min(x, y) + Math::max(x, y) - (x + y)) - < static_cast(1.0e-12)); + < scalar(kRoundoffTolerance)); - const ScalarT point = static_cast(0.25); - const ScalarT bias = std::log(static_cast(2.0)) / static_cast(240.0); + const ScalarT point = scalar(0.25); + const ScalarT bias = std::log(scalar(2.0)) / scalar(240.0); success *= (std::abs(Math::max(point, point) - (point + bias)) - < static_cast(1.0e-12)); + < scalar(kRoundoffTolerance)); success *= (std::abs(Math::min(point, point) - (point - bias)) - < static_cast(1.0e-12)); + < scalar(kRoundoffTolerance)); return success.report(__func__); } @@ -225,24 +265,31 @@ namespace GridKit { TestStatus success = true; - const ScalarT limit_min = 0.0; - const ScalarT limit_max = 3.0; + const ScalarT limit_min = scalar(0.0); + const ScalarT limit_max = scalar(3.0); + const ScalarT inside = scalar(1.5); + const ScalarT above_limit = scalar(3.2); + const ScalarT below_limit = scalar(-0.2); + const ScalarT f_positive = scalar(0.03); + const ScalarT f_negative = -f_positive; + const ScalarT near_zero = scalar(kSmoothTolerance); + const ScalarT near_one = scalar(kNearOne); - // Inside the limits the indicator passes dynamics through, regardless - // of the sign of f: value is close to 1. - success *= (Math::indicator(static_cast(1.5), static_cast(0.01), limit_min, limit_max) > static_cast(0.99)); + // Inside the limits, both increasing and decreasing dynamics pass. + success *= (Math::indicator(inside, f_positive, limit_min, limit_max) > near_one); + success *= (Math::indicator(inside, f_negative, limit_min, limit_max) > near_one); - // Above the upper limit with f pushing further out: blocked (≈ 0). - success *= (Math::indicator(static_cast(3.2), static_cast(0.01), limit_min, limit_max) < static_cast(0.1)); + // Above the upper limit, increasing dynamics are blocked. + success *= (Math::indicator(above_limit, f_positive, limit_min, limit_max) < near_zero); - // Above the upper limit but f pulling back in: passed (≈ 1). - success *= (Math::indicator(static_cast(3.2), static_cast(-0.01), limit_min, limit_max) > static_cast(0.9)); + // Above the upper limit, decreasing dynamics restore the state. + success *= (Math::indicator(above_limit, f_negative, limit_min, limit_max) > near_one); - // Below the lower limit with f pushing further out: blocked (≈ 0). - success *= (Math::indicator(static_cast(-0.2), static_cast(-0.01), limit_min, limit_max) < static_cast(0.1)); + // Below the lower limit, decreasing dynamics are blocked. + success *= (Math::indicator(below_limit, f_negative, limit_min, limit_max) < near_zero); - // Below the lower limit but f pulling back in: passed (≈ 1). - success *= (Math::indicator(static_cast(-0.2), static_cast(0.01), limit_min, limit_max) > static_cast(0.9)); + // Below the lower limit, increasing dynamics restore the state. + success *= (Math::indicator(below_limit, f_positive, limit_min, limit_max) > near_one); return success.report(__func__); } @@ -251,20 +298,28 @@ namespace GridKit { TestStatus success = true; - const ScalarT limit_min = 0.0; - const ScalarT limit_max = 3.0; - - const ScalarT f_positive = 0.01; - const ScalarT f_negative = -0.01; - - success *= (std::abs(Math::antiwindup(static_cast(1.5), f_positive, limit_min, limit_max) - - Math::indicator(static_cast(1.5), f_positive, limit_min, limit_max) * f_positive) - < static_cast(1.0e-12)); - - success *= (Math::antiwindup(static_cast(3.2), f_positive, limit_min, limit_max) < static_cast(0.001)); - success *= (Math::antiwindup(static_cast(3.2), f_negative, limit_min, limit_max) < static_cast(-0.009)); - success *= (Math::antiwindup(static_cast(-0.2), f_negative, limit_min, limit_max) > static_cast(-0.001)); - success *= (Math::antiwindup(static_cast(-0.2), f_positive, limit_min, limit_max) > static_cast(0.009)); + const ScalarT limit_min = scalar(0.0); + const ScalarT limit_max = scalar(3.0); + const ScalarT inside = scalar(1.5); + const ScalarT above_limit = scalar(3.2); + const ScalarT below_limit = scalar(-0.2); + + const ScalarT f_positive = scalar(0.03); + const ScalarT f_negative = -f_positive; + const ScalarT blocked_tolerance = f_positive * scalar(kSmoothTolerance); + + success *= (std::abs(Math::antiwindup(inside, f_positive, limit_min, limit_max) + - Math::indicator(inside, f_positive, limit_min, limit_max) * f_positive) + < scalar(kRoundoffTolerance)); + + success *= (std::abs(Math::antiwindup(above_limit, f_positive, limit_min, limit_max)) < blocked_tolerance); + success *= within(Math::antiwindup(above_limit, f_negative, limit_min, limit_max), + f_negative, + blocked_tolerance); + success *= (std::abs(Math::antiwindup(below_limit, f_negative, limit_min, limit_max)) < blocked_tolerance); + success *= within(Math::antiwindup(below_limit, f_positive, limit_min, limit_max), + f_positive, + blocked_tolerance); return success.report(__func__); }

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 literal 0 HcmV?d00001 From cfa287d98d61e27ce188f6674967de1f5ee07cf4 Mon Sep 17 00:00:00 2001 From: lukelowry Date: Tue, 19 May 2026 16:17:58 -0500 Subject: [PATCH 07/12] Address formatting issue and improve --- GridKit/CommonMath.hpp | 9 + GridKit/CommonMath.md | 226 +++++++++++------- .../Model/PhasorDynamics/Converter/README.md | 1 + .../PhasorDynamics/Converter/REGCB/README.md | 5 + .../PhasorDynamics/Exciter/IEEET1/README.md | 48 ++-- .../PhasorDynamics/Exciter/SEXS-PTI/README.md | 10 +- .../PhasorDynamics/Governor/Tgov1/README.md | 32 +-- .../Stabilizer/IEEEST/README.md | 6 +- 8 files changed, 204 insertions(+), 133 deletions(-) diff --git a/GridKit/CommonMath.hpp b/GridKit/CommonMath.hpp index f995bf4c9..4426bfa3b 100644 --- a/GridKit/CommonMath.hpp +++ b/GridKit/CommonMath.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -115,6 +116,7 @@ namespace GridKit const LowerT lower, const UpperT upper) { + assert(lower <= upper); return lower + ramp(x - lower) - ramp(x - upper); } @@ -138,6 +140,7 @@ namespace GridKit const RealT lower, const RealT upper) { + assert(lower <= upper); return ramp(x - upper) - ramp(-(x - lower)); } @@ -158,6 +161,7 @@ namespace GridKit const ScalarT f, const RealT rate) { + assert(rate >= ZERO); return clamp(f, -rate, rate); } @@ -184,6 +188,7 @@ namespace GridKit const RealT upper, const RealT height) { + assert(lower < upper); return height / (upper - lower) * (ramp(x - lower) - ramp(x - upper)); } @@ -256,6 +261,7 @@ namespace GridKit const RealT limit_min, const RealT limit_max) { + assert(limit_min <= limit_max); return above(x, limit_min) + below(x, limit_max) - ONE; } @@ -276,6 +282,7 @@ namespace GridKit const RealT limit_min, const RealT limit_max) { + assert(limit_min <= limit_max); return below(x, limit_min) + above(x, limit_max); } @@ -299,6 +306,8 @@ namespace GridKit const RealT limit_min, const RealT limit_max) { + assert(limit_min <= limit_max); + ScalarT above_min = above(x, limit_min); ScalarT below_max = below(x, limit_max); diff --git a/GridKit/CommonMath.md b/GridKit/CommonMath.md index bbfc7180b..45a093ff5 100644 --- a/GridKit/CommonMath.md +++ b/GridKit/CommonMath.md @@ -4,109 +4,165 @@ Smooth, autodiff-friendly replacements for piecewise functions used across GridK ## Primitives -| Name | Exact Target | Smooth Approximation | Description | -|------|--------------|----------------------|-------------| -| `sigmoid` | $H(x)$ | $\sigma(x) = \frac{1}{1+\exp(-\mu x)}$ | Step function | -| `ramp` | $\max(x,0)$ | $\rho(x)=\mu^{-1}\log(1+\exp(\mu x))$ | Smooth one-sided ramp | +### Descriptions -The scale $\mu=240$ is chosen so $\sigma$ behaves like a step on inputs of order 1 while keeping derivatives finite. As $\mu \to \infty$, these functions approach their exact targets. +| Name | Description | Usage | +|------|-------------|-------| +| `sigmoid` | Step function | `IEEET1` | +| `ramp` | Smooth one-sided ramp | `IEEET1`, `REGCA` | -Softplus avoids the negative undershoot of $x\sigma(x)$, with a small positive breakpoint bias: +### Exact Equations ```math -\rho(0)=\frac{\log 2}{\mu}. +\begin{aligned} +\sigma(x) +&= +\begin{cases} +0 & x \le 0 \\ +1 & x > 0 +\end{cases} +\\ +\rho(x) &= \max(x,0) +\end{aligned} ``` -## Derived Functions - -| Name | Exact Target | Smooth Approximation | Description | -|------|--------------|----------------------|-------------| -| `max` | $\begin{cases}x & x>y\\y & x\le y\end{cases}$ | $y+\rho(x-y)$ | Smooth binary maximum | -| `min` | $\begin{cases}x & xu\end{cases}$ | $\ell + \rho(x-\ell) - \rho(x-u)$ | Bounded saturation | -| `deadband` | $\begin{cases}x-\ell & x<\ell\\0 & \ell\le x\le u\\x-u & x>u\end{cases}$ | $\rho(x-u)-\rho(\ell-x)$ | Signed two-sided deadband | -| `slew` | $\begin{cases}-r & f<-r\\f & -r\le f\le r\\r & f>r\end{cases}$ | $-r + \rho(f+r) - \rho(f-r)$ | Symmetric slew-rate limiter | -| `linseg` | $\begin{cases}0 & xb\end{cases}$ | $\frac{h}{b-a}\left[\rho(x-a)-\rho(x-b)\right]$ | Saturated linear segment contribution | -| `above` | $\begin{cases}0 & x\le x_{\min}\\1 & x>x_{\min}\end{cases}$ | $\sigma(x-x_{\min})$ | Above-lower-limit indicator | -| `below` | $\begin{cases}1 & xx_{\max}\\0 & \text{else}\end{cases}$ | $\sigma(x_{\min}-x)+\sigma(x-x_{\max})$ | Outside-band indicator | -| `antiwindup` | $\begin{cases}f & x_{\min}0\\f & x\ge x_{\max}\land f<0\\0 & \text{otherwise}\end{cases}$ | $\phi(x,f)f$ | Anti-windup limited derivative | - -Binary `min` and `max` inherit the ramp breakpoint bias: +### Smooth Equations ```math -\text{max}(x,x)=x+\rho(0), \qquad -\text{min}(x,x)=x-\rho(0). +\begin{aligned} +\sigma(x) &= \dfrac{1}{1+e^{-\mu x}} \\ +\rho(x) &= \dfrac{(\mu x+\lvert\mu x\rvert)/2+\log(1+e^{-\lvert\mu x\rvert})}{\mu} +\end{aligned} ``` -`deadband` is the signed complement of `clamp`, implemented as the difference -of the upper and lower one-sided deadband ramps: +The scale $\mu=4\cdot f_{\text{sync}}=240$ is chosen so $\sigma$ behaves like a step on inputs of order 1 while keeping derivatives finite. As $\mu \to \infty$, these functions approach their exact targets. -```math -\text{deadband}(x;\,\ell,u)=\rho(x-u)-\rho(\ell-x). -``` +## Derived Functions + +### Descriptions -Callers should supply $\ell \le u$. +| Name | Description | Usage | +|------|-------------|-------| +| `max` | Smooth binary maximum | `REECA` | +| `min` | Smooth binary minimum | `REECA` | +| `clamp` | Bounded saturation | `IEEEST` | +| `deadband` | Signed two-sided deadband | `REECA` | +| `slew` | Symmetric slew-rate limiter | - | +| `linseg` | Saturated linear segment contribution | `REGCA`, `REECA` | +| `above` | Above-lower-limit indicator | - | +| `below` | Below-upper-limit indicator | - | +| `inside` | Interior pulse indicator | `IEEEST` | +| `outside` | Outside-band indicator | `REECA` | +| `antiwindup` | Anti-windup limited derivative | `IEEET1`, `TGOV1`, `SEXS-PTI`, `REECA` | -`linseg` is a saturated linear segment contribution, implemented as the -difference of two smooth ramps: +### Exact Equations ```math -\text{linseg}(x;\,a,b,h) -= -\frac{h}{b-a}\left[\rho(x-a)-\rho(x-b)\right]. +\begin{aligned} +\text{max}(x,y) +&= +\begin{cases} +x & x > y \\ +y & x \le y +\end{cases} +\\ +\text{min}(x,y) +&= +\begin{cases} +x & x < y \\ +y & x \ge y +\end{cases} +\\ +\text{clamp}(x;\ell,u) +&= +\begin{cases} +\ell & x < \ell \\ +x & \ell \le x \le u \\ +u & x > u +\end{cases} +\\ +\text{deadband}(x;\ell,u) +&= +\begin{cases} +x-\ell & x < \ell \\ +0 & \ell \le x \le u \\ +x-u & x > u +\end{cases} +\\ +\text{slew}(f;r) +&= +\begin{cases} +-r & f < -r \\ +f & -r \le f \le r \\ +r & f > r +\end{cases} +\\ +\text{linseg}(x;a,b,h) +&= +\begin{cases} +0 & x < a \\ +\dfrac{h}{b-a}(x-a) & a \le x \le b \\ +h & x > b +\end{cases} +\\ +\text{above}(x;\ell) +&= +\begin{cases} +0 & x \le \ell \\ +1 & x > \ell +\end{cases} +\\ +\text{below}(x;u) +&= +\begin{cases} +1 & x < u \\ +0 & x \ge u +\end{cases} +\\ +\text{inside}(x;\ell,u) +&= +\begin{cases} +1 & \ell < x < u \\ +0 & \text{else} +\end{cases} +\\ +\text{outside}(x;\ell,u) +&= +\begin{cases} +1 & x < \ell \lor x > u \\ +0 & \text{else} +\end{cases} +\\ +\text{antiwindup}(x,f;\ell,u) +&= +\begin{cases} +f & \ell < x < u \\ +f & x \le \ell \land f > 0 \\ +f & x \ge u \land f < 0 \\ +0 & \text{otherwise} +\end{cases} +\end{aligned} ``` -Callers should supply $a < b$. The height $h$ may be positive or negative. It -is not a signal-processing window function. +### Smooth Equations -## Anti-Windup Indicator - -For a limited state $x \in [x_{\min}, x_{\max}]$, define -$\phi_L=\text{above}(x,x_{\min})$ and -$\phi_U=\text{below}(x,x_{\max})$. - -GridKit's `indicator` function is the smooth anti-windup gate $\phi(x,f)$, -where + ```math -\phi(x, f) = \phi_L \phi_U + (1 - \phi_U)\,\sigma(-f) + (1 - \phi_L)\,\sigma(f). +\begin{aligned} +\text{max}(x,y) &= y+\rho(x-y) \\ +\text{min}(x,y) &= x-\rho(x-y) \\ +\text{clamp}(x;\ell,u) &= \ell+\rho(x-\ell)-\rho(x-u) \\ +\text{deadband}(x;\ell,u) &= \rho(x-u)-\rho(\ell-x) \\ +\text{slew}(f;r) &= -r+\rho(f+r)-\rho(f-r) \\ +\text{linseg}(x;a,b,h) &= \dfrac{h}{b-a}\left[\rho(x-a)-\rho(x-b)\right] \\ +\text{above}(x;\ell) &= \sigma(x-\ell) \\ +\text{below}(x;u) &= \sigma(u-x) \\ +\text{inside}(x;\ell,u) &= \sigma(x-\ell)+\sigma(u-x)-1 \\ +\text{outside}(x;\ell,u) &= \sigma(\ell-x)+\sigma(x-u) \\ +\phi_L &= \text{above}(x;\ell) \\ +\phi_U &= \text{below}(x;u) \\ +\phi(x,f) &= \phi_L\phi_U+(1-\phi_U)\sigma(-f)+(1-\phi_L)\sigma(f) \\ +\text{antiwindup}(x,f;\ell,u) &= \phi(x,f)f +\end{aligned} ``` - -The first term passes interior dynamics. The second and third terms pass restoring motion from the upper and lower limits, respectively; otherwise, $\phi$ smoothly blocks windup. - -## Model Usage - -Ramp (`Math::ramp`, $\rho$): - -- [IEEET1](Model/PhasorDynamics/Exciter/IEEET1/README.md): smooth magnetic saturation above the saturation knee -- [REGCA](Model/PhasorDynamics/Converter/REGCA/README.md): applies reactive-current and active-current rate-limit corrections - -Binary min/max (`Math::min`, `Math::max`): - -- [REECA](Model/PhasorDynamics/Converter/REECA/README.md): forms the safe measured voltage floor and final current limits - -Linear segment (`Math::linseg`, $\text{linseg}$): - -- [REGCA](Model/PhasorDynamics/Converter/REGCA/README.md): defines the LVPL and LVACM piecewise-linear curves -- [REECA](Model/PhasorDynamics/Converter/REECA/README.md): defines smooth voltage-dependent current-limit interpolation curves - -Deadband (`Math::deadband`): - -- [REECA](Model/PhasorDynamics/Converter/REECA/README.md): smooths the two-sided voltage-error deadband - -Inside indicator (`Math::inside`): - -- [IEEEST](Model/PhasorDynamics/Stabilizer/IEEEST/README.md): forms the smooth output limiter for $v_7$ over $[L_{smin}, L_{smax}]$ - -Outside indicator (`Math::outside`): - -- [REECA](Model/PhasorDynamics/Converter/REECA/README.md): forms the smooth voltage dip/overvoltage indicator for $s_{\mathrm{dip}}$ - -Anti-windup (`Math::antiwindup`, with gate `Math::indicator`): - -- [IEEET1](Model/PhasorDynamics/Exciter/IEEET1/README.md): gates $\dot V_R$ on $V_R \in (V_{rmin}, V_{rmax})$ -- [TGOV1](Model/PhasorDynamics/Governor/Tgov1/README.md): gates $\dot P_v$ on $P_v \in (P_{vmin}, P_{vmax})$ -- [SEXS-PTI](Model/PhasorDynamics/Exciter/SEXS-PTI/README.md): gates $\dot E_{fd}$ on $E_{fd} \in (E_{fd,\min}, E_{fd,\max})$ -- [REECA](Model/PhasorDynamics/Converter/REECA/README.md): gates PI-controller and active-power-order dynamics during output saturation diff --git a/GridKit/Model/PhasorDynamics/Converter/README.md b/GridKit/Model/PhasorDynamics/Converter/README.md index cb5902190..ad38ba19a 100644 --- a/GridKit/Model/PhasorDynamics/Converter/README.md +++ b/GridKit/Model/PhasorDynamics/Converter/README.md @@ -11,3 +11,4 @@ The GridKit converter documentation includes: - Renewable Energy Generator/Converter Model REGCA (See [REGCA](REGCA/README.md)) - Renewable Energy Generator/Converter Model REGCB (See [REGCB](REGCB/README.md)) +- Renewable Energy Electrical Control Model REECA (See [REECA](REECA/README.md)) diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCB/README.md b/GridKit/Model/PhasorDynamics/Converter/REGCB/README.md index 453df3b13..f10fe2218 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REGCB/README.md +++ b/GridKit/Model/PhasorDynamics/Converter/REGCB/README.md @@ -15,6 +15,10 @@ Standard model diagram for the REGCB converter interface. Figure 1: Generator/Converter REGCB model. Figure courtesy of [PowerWorld](https://www.powerworld.com/WebHelp/) +Detailed REGCB parameters, variables, equations, initialization details, and +outputs will be added after validation against the REGCB source standard. + + diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md index ccac7885e..0cb748240 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md @@ -17,14 +17,14 @@ Standard model of the IEEET1 Exciter. Symbol | Units | Description | Typical Value | Note ------------|--------|--------------------------------------|---------| ------ $T_R$ | [sec] | Time constant for voltage sensing | 0 | -$K_a$ | [p.u.] | Coefficient for voltage regulation | 50 | -$T_a$ | [sec] | Time constant for voltage regulation | 0.04 | -$K_e$ | [p.u.] | Coefficient for excitation system | -0.06 | -$T_e$ | [sec] | Time constant for excitation system | 0.6 | -$K_f$ | [p.u.] | Coefficient for feedback | 0.09 | -$T_f$ | [sec] | Time constant for feedback | 1.46 | -$V_{rmin}$ | [p.u.] | Lower limit to voltage regulation | -1 | -$V_{rmax}$ | [p.u.] | Upper limit to voltage regulation | 1 | +$K_A$ | [p.u.] | Coefficient for voltage regulation | 50 | +$T_A$ | [sec] | Time constant for voltage regulation | 0.04 | +$K_E$ | [p.u.] | Coefficient for excitation system | -0.06 | +$T_E$ | [sec] | Time constant for excitation system | 0.6 | +$K_F$ | [p.u.] | Coefficient for feedback | 0.09 | +$T_F$ | [sec] | Time constant for feedback | 1.46 | +$V_R^{\min}$ | [p.u.] | Lower limit to voltage regulation | -1 | +$V_R^{\max}$ | [p.u.] | Upper limit to voltage regulation | 1 | $E_1$ | [p.u.] | Saturation Parameter | 2.8 | $E_2$ | [p.u.] | Saturation Parameter | 3.73 | $S_{e1}$ | [p.u.] | Saturation Parameter | 0.04 | @@ -72,7 +72,7 @@ Generally, this system has two solutions. The non-extraneous solution is as foll Symbol | Units | Description | Note ----------|--------|-----------------------------------|------- $V_{ts}$ | [p.u.] | Sensed terminal voltage | -$V_{R}$ | [p.u.] | Voltage regulator | +$V_R$ | [p.u.] | Voltage regulator | $E_{fd}'$ | [p.u.] | Field-current pre-speed multiplier| $V_{fx}$ | [p.u.] | Exciter feedback internal state | @@ -83,8 +83,8 @@ $V_{fx}$ | [p.u.] | Exciter feedback internal state | Symbol | Units | Description | Note ----------------|--------|-----------------------------------|------- $V_{tr}$ | [p.u.] | Terminal Voltage Error | -$V_{f}$ | [p.u.] | Feedback Voltage | -$V_{E}$ | [p.u.] | Excitation control voltage | +$V_f$ | [p.u.] | Feedback Voltage | +$V_E$ | [p.u.] | Excitation control voltage | $E_{fd}$ | [p.u.] | Field winding voltage | $k_{sat}$ | [p.u.] | Saturation variable | @@ -100,11 +100,11 @@ $\omega$ | [p.u.] | Machine Speed Deviation | Read from a Mac Symbol | Units | Description | Note ----------------|--------|-----------------------------------|------- -$E_{C}$ | [p.u.] | Compensated machine terminal voltage magnitude | +$E_C$ | [p.u.] | Compensated machine terminal voltage magnitude | $V_{ref}$ | [p.u.] | Reference terminal voltage | $V_{UEL}$ | [p.u.] | Input from under excitation limiter | $V_{OEL}$ | [p.u.] | Input from over excitation limiter | -$V_{S}$ | [p.u.] | Input from stabilizer controller | +$V_S$ | [p.u.] | Input from stabilizer controller | ## Model Equations @@ -114,23 +114,23 @@ $V_{S}$ | [p.u.] | Input from stabilizer controller | The IEEET1 differential equations, as derived from the model diagram. Define the pre-limit derivative of $V_R$ ```math -f = \dfrac{1}{T_A}\left[-V_R + K_a V_{tr}\right] +f = \dfrac{1}{T_A}\left[-V_R + K_A V_{tr}\right] ``` so that $\dot V_R$ can be written in piecewise form compactly. ```math \begin{aligned} - \dot{V}_{ts} &= \dfrac{1}{T_R}(E_C-V_{ts}) \\ - \dot{V}_{R} &= + \dot V_{ts} &= \dfrac{1}{T_R}(E_C-V_{ts}) \\ + \dot V_R &= \begin{cases} f - & \text{if } (V_{rmin} < V_R < V_{rmax}) & \lor \\ - & \quad (V_R \leq V_{rmin} \land f>0) & \lor \\ - & \quad(V_R \geq V_{rmax} \land f<0) \\ + & \text{if } (V_R^{\min} < V_R < V_R^{\max}) & \lor \\ + & \quad (V_R \leq V_R^{\min} \land f>0) & \lor \\ + & \quad(V_R \geq V_R^{\max} \land f<0) \\ 0 & \text{else } \\ \end{cases} \\ - \dot{E}_{fd}' &= \dfrac{1}{T_E}(V_R-V_E-K_E E_{fd}') \\ - \dot{V}_{fx} &= \dfrac{1}{T_F}V_f \\ + \dot E_{fd}' &= \dfrac{1}{T_E}(V_R-V_E-K_E E_{fd}') \\ + \dot V_{fx} &= \dfrac{1}{T_F}V_f \\ \end{aligned} ``` @@ -142,8 +142,8 @@ The algebraic equations of the exciter. ```math \begin{aligned} V_{tr} &= V_{ref} +V_{UEL} + V_{OEL} + V_S - V_f- V_{ts}\\ - V_{f} &= \dfrac{E_{fd}' K_F}{T_F} - V_{fx}\\ - V_{E} &= k_{sat}\cdot E_{fd}' \\ + V_f &= \dfrac{E_{fd}' K_F}{T_F} - V_{fx}\\ + V_E &= k_{sat}\cdot E_{fd}' \\ E_{fd}&= \begin{cases} (1+\omega)E_{fd}' & \text{if } I_{spdlm}=1\\ E_{fd}' & \text{else} \\ @@ -179,7 +179,7 @@ The machine initializes $E_{fd}$ first. IEEET1 reads that value as $E_{fd,0}$, a k_{sat} &= S_B\big[(E_{fd}' - S_A)\,\sigma(E_{fd}' - S_A)\big]^2 \\ V_E &= k_{sat}\, E_{fd}' \\ V_R &= K_E\, E_{fd}' + V_E \\ - V_{tr} &= \dfrac{V_R}{K_a} \\ + V_{tr} &= \dfrac{V_R}{K_A} \\ V_{fx} &= \dfrac{K_F}{T_F}\, E_{fd}' \\ V_{ts} &= E_C \\ V_f &= 0 \\ diff --git a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/README.md b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/README.md index 5bdddef7c..5ee75a980 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/README.md +++ b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/README.md @@ -18,8 +18,8 @@ $T_A$ | [sec] | Numerator time constant of lag-lead block | $T_B$ | [sec] | Denominator time constant of lag-lead block | | $T_E$ | [sec] | Exciter field time constant | | $K$ | [p.u.] | Voltage regulator gain | | -$E_{fd,\max}$ | [p.u.] | Maximum excitation output | | -$E_{fd,\min}$ | [p.u.] | Minimum excitation output | | +$E_{fd}^{\max}$ | [p.u.] | Maximum excitation output | | +$E_{fd}^{\min}$ | [p.u.] | Minimum excitation output | | PowerWorld/PSS/E SEXS_PTI data often gives $T_A/T_B$ as a ratio. GridKit stores $T_A$ and $T_B$ separately, so convert ratio-format data with @@ -76,9 +76,9 @@ so that $\dot E_{fd}$ can be written in piecewise form compactly. \dot E_{fd} &= \begin{cases} f - & \text{if } (E_{fd,\min} < E_{fd} < E_{fd,\max}) & \lor \\ - & \quad (E_{fd} \leq E_{fd,\min} \land f > 0) & \lor \\ - & \quad (E_{fd} \geq E_{fd,\max} \land f < 0) \\ + & \text{if } (E_{fd}^{\min} < E_{fd} < E_{fd}^{\max}) & \lor \\ + & \quad (E_{fd} \leq E_{fd}^{\min} \land f > 0) & \lor \\ + & \quad (E_{fd} \geq E_{fd}^{\max} \land f < 0) \\ 0 & \text{else} \end{cases} \end{aligned} diff --git a/GridKit/Model/PhasorDynamics/Governor/Tgov1/README.md b/GridKit/Model/PhasorDynamics/Governor/Tgov1/README.md index d7b778bb1..c51dc72b1 100644 --- a/GridKit/Model/PhasorDynamics/Governor/Tgov1/README.md +++ b/GridKit/Model/PhasorDynamics/Governor/Tgov1/README.md @@ -18,8 +18,8 @@ $R$ | [p.u.] | Droop Constant | 0.05 | $T_1$ | [sec] | Valve Time Delay | 0.5 | $T_2$ | [sec] | Turbine Numerator Time Constant | 2.5 | $T_3$ | [sec] | Turbine Delay | 7.5 | -$P_{vmax}$ | [p.u.] | Max Valve Position | 1 | -$P_{vmin}$ | [p.u.] | Min Valve Position | 0 | +$P_v^{\max}$ | [p.u.] | Max Valve Position | 1 | +$P_v^{\min}$ | [p.u.] | Min Valve Position | 0 | $D_t$ | [p.u.] | Turbine Damping Coefficient | 0 | ## Model Variables @@ -31,12 +31,12 @@ $D_t$ | [p.u.] | Turbine Damping Coefficient | 0 | Symbol | Units | Description | Note ----------|--------|-----------------------------------|------- $P_{tx}$ | [p.u.] | Turbine Power (State 1 in Fig. 1) | -$P_{v}$ | [p.u.] | Valve Position (State 2 in Fig. 1)| +$P_v$ | [p.u.] | Valve Position (State 2 in Fig. 1)| #### Algebraic Symbol | Units | Description | Note ----------------|--------|-----------------------------------|------- -$P_{m}$ | [p.u.] | Mechnical Power to Generator | Read by a Machine Model +$P_m$ | [p.u.] | Mechnical Power to Generator | Read by a Machine Model ### External Variables @@ -62,13 +62,13 @@ f = \dfrac{1}{T_1}\left[-P_v + \dfrac{1}{R}(P_{ref} - \omega)\right] so that $\dot P_v$ can be written in piecewise form compactly. ```math \begin{aligned} - \dot{P}_{tx} &= P_v - \dfrac{1}{T_3}(P_{tx}+T_2P_v) \\ - \dot{P}_{v} &= + \dot P_{tx} &= P_v - \dfrac{1}{T_3}(P_{tx}+T_2P_v) \\ + \dot P_v &= \begin{cases} f - & \text{if } (P_{vmin} < P_v < P_{vmax}) & \lor \\ - & \quad (P_v \leq P_{vmin} \land f>0) & \lor \\ - & \quad(P_v \geq P_{vmax} \land f<0) \\ + & \text{if } (P_v^{\min} < P_v < P_v^{\max}) & \lor \\ + & \quad (P_v \leq P_v^{\min} \land f>0) & \lor \\ + & \quad(P_v \geq P_v^{\max} \land f<0) \\ 0 & \text{else} \end{cases} @@ -79,26 +79,26 @@ so that $\dot P_v$ can be written in piecewise form compactly. The algebraic equation dictating the mechnical power output. ```math \begin{aligned} - P_{m} &= \dfrac{1}{T_3}(P_{tx}+T_2P_v) - D_t \omega \\ + P_m &= \dfrac{1}{T_3}(P_{tx}+T_2P_v) - D_t \omega \\ \end{aligned} ``` In simulation the piecewise form above is replaced with a smooth approximation where $\phi$ is GridKit's smooth anti-windup indicator. See [CommonMath: Anti-Windup Indicator](../../../../CommonMath.md#anti-windup-indicator) for its definition, behavior, and design rationale. ## Initialization -At steady state we assume that $P_v$ is at or within its limits. This implies the initial conditions are a function of $P_{m}$ which is equal to the electric torque. +At steady state we assume that $P_v$ is at or within its limits. This implies the initial conditions are a function of $P_m$ which is equal to the electric torque. ```math \begin{aligned} - P_{tx} &= (T_3-T_2) P_{m}\\ - P_{v} &= P_{m}\\ - \dot{P}_{tx} &=0\\ - \dot{P}_{v} &=0\\ + P_{tx} &= (T_3-T_2) P_m\\ + P_v &= P_m\\ + \dot P_{tx} &=0\\ + \dot P_v &=0\\ \end{aligned} ``` And if the reference power is a constant parameter, we can determine the value by solving the steady state equations. ```math \begin{aligned} - P_{ref} &= R P_{m}\\ + P_{ref} &= R P_m\\ \end{aligned} ``` diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/README.md b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/README.md index 6612b9cd2..d01c45be3 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/README.md +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/README.md @@ -28,8 +28,8 @@ $T_4$ | [s] | Lead–lag 2 denominator time constant | 0.0 $T_5$ | [s] | Washout numerator time constant | 1.65 $T_6$ | [s] | Washout denominator time constant | 1.65 $K_s$ | [p.u.] | Stabilizer gain | 3.0 -$L_{s\min}$ | [p.u.] | Minimum stabilizer output limit | -0.1 -$L_{s\max}$ | [p.u.] | Maximum stabilizer output limit | 0.1 +$L_s^{\min}$ | [p.u.] | Minimum stabilizer output limit | -0.1 +$L_s^{\max}$ | [p.u.] | Maximum stabilizer output limit | 0.1 The IEEE 421.5 IEEEST also defines a cutout window ($V_{cl}$, $V_{cu}$) and an input delay ($T_{delay}$). These parameters are accepted for input-format @@ -102,7 +102,7 @@ $u$ | [p.u.] | Stabilizer input signal 0 &= -T_2(v_5 - x_5) + T_1(v_4 - x_5) \\ 0 &= -T_4(v_6 - x_6) + T_3(v_5 - x_6) \\ 0 &= -T_6 v_7 + K_s T_5(v_6 - x_7) \\ -0 &= -V_{ss} + \operatorname{clamp}(v_7, L_{s\min}, L_{s\max}) +0 &= -V_{ss} + \text{clamp}(v_7, L_s^{\min}, L_s^{\max}) \end{aligned} ``` From c59287daf1442c7f99b4c7c4ffac9fefe163fe9e Mon Sep 17 00:00:00 2001 From: lukelowry Date: Tue, 19 May 2026 17:52:13 -0500 Subject: [PATCH 08/12] qramp for exciter which could eventually have enzyme impl for exact --- GridKit/CommonMath.hpp | 20 ++++ GridKit/CommonMath.md | 9 +- .../Exciter/IEEET1/Ieeet1Impl.hpp | 16 ++-- .../PhasorDynamics/Exciter/IEEET1/README.md | 91 +++++++++---------- .../Governor/Tgov1/Tgov1Impl.hpp | 5 +- 5 files changed, 80 insertions(+), 61 deletions(-) diff --git a/GridKit/CommonMath.hpp b/GridKit/CommonMath.hpp index 4426bfa3b..b2470d587 100644 --- a/GridKit/CommonMath.hpp +++ b/GridKit/CommonMath.hpp @@ -52,6 +52,26 @@ namespace GridKit return (HALF * (z + a) + std::log1p(std::exp(-a))) / MU; } + /** + * @brief Smooth one-sided quadratic ramp + * + * Smooth approximation to max(x, 0)^2 via a sigmoid-gated quadratic. + * Used for IEEE-style quadratic saturation curves. + * + * @note Eventually a enzyme specialization for an exact implementation + * would be nice, since the piecewise definition is C^1 continuous + * + * @tparam ScalarT - scalar data type + * + * @param[in] x - input signal + * @return value of the quadratic ramp + */ + template + __attribute__((always_inline)) inline ScalarT qramp(const ScalarT x) + { + return x * x * sigmoid(x); + } + /** * @brief Smooth binary maximum function * diff --git a/GridKit/CommonMath.md b/GridKit/CommonMath.md index 45a093ff5..137f28795 100644 --- a/GridKit/CommonMath.md +++ b/GridKit/CommonMath.md @@ -9,7 +9,8 @@ Smooth, autodiff-friendly replacements for piecewise functions used across GridK | Name | Description | Usage | |------|-------------|-------| | `sigmoid` | Step function | `IEEET1` | -| `ramp` | Smooth one-sided ramp | `IEEET1`, `REGCA` | +| `ramp` | Smooth one-sided ramp | `REGCA` | +| `qramp` | Exact one-sided quadratic ramp | `IEEET1` | ### Exact Equations @@ -22,7 +23,8 @@ Smooth, autodiff-friendly replacements for piecewise functions used across GridK 1 & x > 0 \end{cases} \\ -\rho(x) &= \max(x,0) +\rho(x) &= \max(x,0) \\ +q(x) &= \max(x,0)^2 \end{aligned} ``` @@ -31,7 +33,8 @@ Smooth, autodiff-friendly replacements for piecewise functions used across GridK ```math \begin{aligned} \sigma(x) &= \dfrac{1}{1+e^{-\mu x}} \\ -\rho(x) &= \dfrac{(\mu x+\lvert\mu x\rvert)/2+\log(1+e^{-\lvert\mu x\rvert})}{\mu} +\rho(x) &= \dfrac{(\mu x+\lvert\mu x\rvert)/2+\log(1+e^{-\lvert\mu x\rvert})}{\mu} \\ +q(x) &= x^2\,\sigma(x) \end{aligned} ``` diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp index 2b310f65b..f535862f0 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp @@ -231,12 +231,11 @@ namespace GridKit ScalarT vimag = bus_->Vi(); ScalarT Ec = std::sqrt(vreal * vreal + vimag * vimag); - ScalarT efdp = efd0 / (ONE + omega * Ispdlim_); - ScalarT efd_sat = (efdp - SA_) * Math::sigmoid(efdp - SA_); - ScalarT ksat = SB_ * efd_sat * efd_sat; - ScalarT ve = ksat * efdp; - ScalarT vr = Ke_ * efdp + ve; - ScalarT vtr = vr / Ka_; + ScalarT efdp = efd0 / (ONE + omega * Ispdlim_); + ScalarT ksat = SB_ * Math::qramp(efdp - SA_); + ScalarT ve = ksat * efdp; + ScalarT vr = Ke_ * efdp + ve; + ScalarT vtr = vr / Ka_; ScalarT vf{0}; ScalarT vfx = (Kf_ / Tf_) * efdp; @@ -339,8 +338,7 @@ namespace GridKit f[6] = -ve + ksat * efdp; f[7] = -efd + efdp + omega * efdp * Ispdlim_; - ScalarT efd_sat = (efdp - SA_) * (Math::sigmoid(efdp - SA_)); - f[8] = -ksat + SB_ * efd_sat * efd_sat; + f[8] = -ksat + SB_ * Math::qramp(efdp - SA_); return 0; } @@ -471,7 +469,7 @@ namespace GridKit monitor_->set(Variable::efd, [this] { return efd_signal_->read(); }); monitor_->set(Variable::ksat, [this] - { return SB_ * (((y_[2] - SA_) * Math::sigmoid(y_[2] - SA_)) * ((y_[2] - SA_) * Math::sigmoid(y_[2] - SA_))); }); + { return SB_ * Math::qramp(y_[2] - SA_); }); } } // namespace Exciter } // namespace PhasorDynamics diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md index 0cb748240..cab2a062b 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/README.md @@ -4,10 +4,15 @@ Standard model of the IEEET1 Exciter. +Notes: +- $E_C$ should be an external signal from the generator or machine, not computed through an exciter-owned `Bus` reference. +- The current implementation uses its `Bus` reference as a proxy for $E_C$. +- This direct coupling affects numerical conditioning; production models typically use a decoupling reactance for the exciter-current path that forms $E_C$. +