diff --git a/CHANGELOG.md b/CHANGELOG.md index 066786e09..0783ca507 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,7 @@ - Added cmake-format hooks, including in pre-commit. - Added off-nominal tap ratio and phase shift support to the PhasorDynamics `Branch` model. - Added portable Vector class to GridKit +- Added `closed` parameter to `Branch` for declaring out-of-service lines in case files. ## v0.1 diff --git a/GridKit/Model/PhasorDynamics/Branch/Branch.hpp b/GridKit/Model/PhasorDynamics/Branch/Branch.hpp index 84149f8a4..7d963bb2f 100644 --- a/GridKit/Model/PhasorDynamics/Branch/Branch.hpp +++ b/GridKit/Model/PhasorDynamics/Branch/Branch.hpp @@ -130,9 +130,6 @@ namespace GridKit void setDerivedParams(); void terminalCurrent1(ScalarT& Ir, ScalarT& Ii); void terminalCurrent2(ScalarT& Ir, ScalarT& Ii); - bool readRealParameter(const ModelDataT& data, - typename ModelDataT::Parameters parameter, - RealT& target); static __attribute__((always_inline)) inline void addAdmittanceContribution(RealT G, RealT B, @@ -201,6 +198,8 @@ namespace GridKit RealT B_{0.0}; RealT tap_{1.0}; RealT phase_{0.0}; + bool closed_{true}; + RealT in_service_factor_{1.0}; IdxT bus1_id_{0}; IdxT bus2_id_{0}; @@ -213,8 +212,6 @@ namespace GridKit RealT g22_{0.0}; RealT b22_{0.0}; - int parameter_error_count_{0}; - /// Variable monitor std::unique_ptr monitor_; }; diff --git a/GridKit/Model/PhasorDynamics/Branch/BranchData.hpp b/GridKit/Model/PhasorDynamics/Branch/BranchData.hpp index 6bfabc5d8..c491603a2 100644 --- a/GridKit/Model/PhasorDynamics/Branch/BranchData.hpp +++ b/GridKit/Model/PhasorDynamics/Branch/BranchData.hpp @@ -21,6 +21,7 @@ namespace GridKit B, ///< Total shunt susceptance tap, ///< Off-nominal tap magnitude on bus1 side phase, ///< Phase shift angle in radians + closed ///< In-service flag (true = closed, default true) }; /// Ports for a branch diff --git a/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp b/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp index 1fe3977f0..686033c52 100644 --- a/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp @@ -8,9 +8,6 @@ */ #include -#include - -#include #include #include @@ -147,7 +144,7 @@ namespace GridKit template int Branch::verify() const { - int ret = parameter_error_count_; + int ret = 0; auto check = [&](bool condition, const char* message) { @@ -310,51 +307,46 @@ namespace GridKit template void Branch::initializeParameters(const ModelDataT& data) { - readRealParameter(data, ModelDataT::Parameters::R, R_); - readRealParameter(data, ModelDataT::Parameters::X, X_); - readRealParameter(data, ModelDataT::Parameters::G, G_); - readRealParameter(data, ModelDataT::Parameters::B, B_); - readRealParameter(data, ModelDataT::Parameters::tap, tap_); - readRealParameter(data, ModelDataT::Parameters::phase, phase_); + using P = typename ModelDataT::Parameters; - if (data.ports.contains(ModelDataT::Ports::bus1)) + if (data.parameters.contains(P::R)) { - bus1_id_ = data.ports.at(ModelDataT::Ports::bus1); + R_ = std::get(data.parameters.at(P::R)); } - - if (data.ports.contains(ModelDataT::Ports::bus2)) + if (data.parameters.contains(P::X)) { - bus2_id_ = data.ports.at(ModelDataT::Ports::bus2); + X_ = std::get(data.parameters.at(P::X)); } - } - - template - bool Branch::readRealParameter(const ModelDataT& data, - typename ModelDataT::Parameters parameter, - RealT& target) - { - if (!data.parameters.contains(parameter)) + if (data.parameters.contains(P::G)) { - return false; + G_ = std::get(data.parameters.at(P::G)); } - - const auto& value = data.parameters.at(parameter); - if (const auto* real_value = std::get_if(&value)) + if (data.parameters.contains(P::B)) { - target = *real_value; - return true; + B_ = std::get(data.parameters.at(P::B)); + } + if (data.parameters.contains(P::tap)) + { + tap_ = std::get(data.parameters.at(P::tap)); + } + if (data.parameters.contains(P::phase)) + { + phase_ = std::get(data.parameters.at(P::phase)); + } + if (data.parameters.contains(P::closed)) + { + closed_ = std::get(data.parameters.at(P::closed)); } - if (const auto* integer_value = std::get_if(&value)) + if (data.ports.contains(ModelDataT::Ports::bus1)) { - target = static_cast(*integer_value); - return true; + bus1_id_ = data.ports.at(ModelDataT::Ports::bus1); } - Log::error() << "Branch: parameter " << magic_enum::enum_name(parameter) - << " must be numeric\n"; - parameter_error_count_ += 1; - return false; + if (data.ports.contains(ModelDataT::Ports::bus2)) + { + bus2_id_ = data.ports.at(ModelDataT::Ports::bus2); + } } template @@ -436,14 +428,15 @@ namespace GridKit template void Branch::setDerivedParams() { - g11_ = RealT{0.0}; - b11_ = RealT{0.0}; - g12_ = RealT{0.0}; - b12_ = RealT{0.0}; - g21_ = RealT{0.0}; - b21_ = RealT{0.0}; - g22_ = RealT{0.0}; - b22_ = RealT{0.0}; + g11_ = RealT{0.0}; + b11_ = RealT{0.0}; + g12_ = RealT{0.0}; + b12_ = RealT{0.0}; + g21_ = RealT{0.0}; + b21_ = RealT{0.0}; + g22_ = RealT{0.0}; + b22_ = RealT{0.0}; + in_service_factor_ = closed_ ? RealT{1.0} : RealT{0.0}; const RealT denom = R_ * R_ + X_ * X_; if (denom == RealT{0.0} || tap_ == RealT{0.0}) @@ -460,17 +453,17 @@ namespace GridKit const RealT g_diag = -(g_br + RealT{0.5} * G_); const RealT b_diag = -(b_br + RealT{0.5} * B_); - g11_ = g_diag * inv_tap * inv_tap; - b11_ = b_diag * inv_tap * inv_tap; + g11_ = in_service_factor_ * g_diag * inv_tap * inv_tap; + b11_ = in_service_factor_ * b_diag * inv_tap * inv_tap; - g12_ = (g_br * cos_ph - b_br * sin_ph) * inv_tap; - b12_ = (b_br * cos_ph + g_br * sin_ph) * inv_tap; + g12_ = in_service_factor_ * (g_br * cos_ph - b_br * sin_ph) * inv_tap; + b12_ = in_service_factor_ * (b_br * cos_ph + g_br * sin_ph) * inv_tap; - g21_ = (g_br * cos_ph + b_br * sin_ph) * inv_tap; - b21_ = (b_br * cos_ph - g_br * sin_ph) * inv_tap; + g21_ = in_service_factor_ * (g_br * cos_ph + b_br * sin_ph) * inv_tap; + b21_ = in_service_factor_ * (b_br * cos_ph - g_br * sin_ph) * inv_tap; - g22_ = g_diag; - b22_ = b_diag; + g22_ = in_service_factor_ * g_diag; + b22_ = in_service_factor_ * b_diag; } } // namespace PhasorDynamics diff --git a/GridKit/Model/PhasorDynamics/Branch/README.md b/GridKit/Model/PhasorDynamics/Branch/README.md index e96c4e3f6..13968f9bb 100644 --- a/GridKit/Model/PhasorDynamics/Branch/README.md +++ b/GridKit/Model/PhasorDynamics/Branch/README.md @@ -10,6 +10,11 @@ Notes: - $G$ and $B$ are total branch shunt values split equally between terminals. - The branch has no solver-owned variables; it contributes current residuals directly to the connected buses. +- `closed=false` is static case-import status. It removes the branch admittance + contribution but does not insert fake admittance; islanded or underconstrained + topology can still make the system singular. +- Sparse automatic differentiation may materialize zero-valued structural + entries for an open branch; the mathematical Jacobian contribution is zero. ## Circuit Diagram @@ -25,14 +30,15 @@ $\theta = 0$. ## Model Parameters -Symbol | Units | Description | Typical Value | Note -------------|---------|--------------------------------------------------|---------------|------ -$R$ | [p.u.] | Branch series resistance | | -$X$ | [p.u.] | Branch series reactance | | -$G$ | [p.u.] | Total branch shunt conductance | 0 | -$B$ | [p.u.] | Total branch shunt susceptance | 0 | -$\tau$ | [p.u.] | Off-nominal tap magnitude on bus-1 side | 1 | Parameter name: `tap` -$\theta$ | [rad] | Phase-shift angle | 0 | Parameter name: `phase` +Symbol | Units | JSON | Description | Typical Value | Note +-----------------------|--------|----------|-----------------------------------------|---------------|------ +$R$ | [p.u.] | `R` | Branch series resistance | | +$X$ | [p.u.] | `X` | Branch series reactance | | +$G$ | [p.u.] | `G` | Total branch shunt conductance | 0 | +$B$ | [p.u.] | `B` | Total branch shunt susceptance | 0 | +$\tau$ | [p.u.] | `tap` | Off-nominal tap magnitude on bus-1 side | 1 | +$\theta$ | [rad] | `phase` | Phase-shift angle | 0 | +$c_{\mathrm{br}}$ | [-] | `closed` | Static branch closed status | `true` | JSON boolean ### Parameter Validation @@ -41,6 +47,7 @@ Invalid Branch parameter sets are rejected by the following checks: ```math \begin{aligned} &R, X, G, B, \tau, \theta \in \mathbb{R}\ \text{and finite} \\ + &c_{\mathrm{br}} \in \{\mathrm{true}, \mathrm{false}\} \\ &R^2 + X^2 > 0 \\ &\tau > 0 \end{aligned} @@ -48,10 +55,15 @@ Invalid Branch parameter sets are rejected by the following checks: ### Model Derived Parameters -The series and shunt admittances are: +The closed-status factor and branch admittances are: ```math \begin{aligned} + s_{\mathrm{br}} &= + \begin{cases} + 1, & c_{\mathrm{br}} = \mathrm{true} \\ + 0, & c_{\mathrm{br}} = \mathrm{false} + \end{cases} \\ Y_{\mathrm{br}} &= \dfrac{1}{R + jX} \\ Y_{\mathrm{sh}} &= G + jB \end{aligned} @@ -88,11 +100,47 @@ The off-nominal transformer transformation uses bus 1 as the tap side: \tau^{-1} & 0 \\ 0 & e^{j\theta} \end{bmatrix} \\ - \mathbf{Y} &= \mathbf{M}^{\dagger}\mathbf{Y}_0\mathbf{M} + \mathbf{Y} &= s_{\mathrm{br}}\mathbf{M}^{\dagger}\mathbf{Y}_0\mathbf{M} \end{aligned} ``` -For the equations below, write each entry as $Y_{mn}=G_{mn}+jB_{mn}$. +For each entry $Y_{mn}=G_{mn}+jB_{mn}$, the real-valued contribution from +terminal $n$ to current at terminal $m$ is: + +```math +\begin{aligned} + \begin{bmatrix} + I_{rm} \\ + I_{im} + \end{bmatrix}_{n} + = + \begin{bmatrix} + G_{mn} & -B_{mn} \\ + B_{mn} & G_{mn} + \end{bmatrix} + \begin{bmatrix} + V_{rn} \\ + V_{in} + \end{bmatrix} +\end{aligned} +``` + +The voltage derivative for the same block is: + +```math +\begin{aligned} + \frac{\partial [I_{rm}, I_{im}]^T} + {\partial [V_{rn}, V_{in}]} + = + \begin{bmatrix} + G_{mn} & -B_{mn} \\ + B_{mn} & G_{mn} + \end{bmatrix} +\end{aligned} +``` + +When `closed=false`, $s_{\mathrm{br}}=0$, so $\mathbf{Y}=0$ and every current +block and voltage derivative block is zero. ## Model Variables @@ -129,24 +177,19 @@ None. ### Algebraic Equations -The branch current relation is $0 = -\mathbf{I} + \mathbf{Y}\mathbf{V}$. - ```math \begin{aligned} - I_{r1} &= G_{11} V_{r1} - B_{11} V_{i1} + 0 &= -I_{r1} + G_{11} V_{r1} - B_{11} V_{i1} + G_{12} V_{r2} - B_{12} V_{i2} \\ - I_{i1} &= B_{11} V_{r1} + G_{11} V_{i1} + 0 &= -I_{i1} + B_{11} V_{r1} + G_{11} V_{i1} + B_{12} V_{r2} + G_{12} V_{i2} \\ - I_{r2} &= G_{21} V_{r1} - B_{21} V_{i1} + 0 &= -I_{r2} + G_{21} V_{r1} - B_{21} V_{i1} + G_{22} V_{r2} - B_{22} V_{i2} \\ - I_{i2} &= B_{21} V_{r1} + G_{21} V_{i1} + 0 &= -I_{i2} + B_{21} V_{r1} + G_{21} V_{i1} + B_{22} V_{r2} + G_{22} V_{i2} \end{aligned} ``` -These current contributions are added to the connected bus residuals with -positive sign because branch current is oriented entering the bus. - ## Initialization The Branch model has no internal state to initialize. During construction or diff --git a/GridKit/Model/PhasorDynamics/ComponentDataJSONParser.hpp b/GridKit/Model/PhasorDynamics/ComponentDataJSONParser.hpp index 90b00de50..7f9914a6a 100644 --- a/GridKit/Model/PhasorDynamics/ComponentDataJSONParser.hpp +++ b/GridKit/Model/PhasorDynamics/ComponentDataJSONParser.hpp @@ -47,14 +47,10 @@ namespace GridKit { c.parameters[key.value()] = raw_parameter.value().template get(); } - else if (raw_parameter.value().is_number_float()) + else if (raw_parameter.value().is_number()) { c.parameters[key.value()] = raw_parameter.value().template get(); } - else if (raw_parameter.value().is_number_integer()) - { - c.parameters[key.value()] = raw_parameter.value().template get(); - } else { Log::error() << "\n\tInvalid initial parameter value type: " diff --git a/GridKit/Model/PhasorDynamics/INPUT_FORMAT.md b/GridKit/Model/PhasorDynamics/INPUT_FORMAT.md index 32df36cdc..1237c643b 100644 --- a/GridKit/Model/PhasorDynamics/INPUT_FORMAT.md +++ b/GridKit/Model/PhasorDynamics/INPUT_FORMAT.md @@ -139,7 +139,7 @@ are specified: Device class | Description | Ports | Initialization parameters | Variables available to monitor ---------------------|------------------------------------------------------|----------------------------------|---------------------------- | ------------------------- - `Branch` | algebraic pi model for a line or off-nominal transformer branch | `bus1`, `bus2` | `R`, `X`, `G`, `B`, `tap`, `phase` | `ir1`, `ii1`, `im1`, `p1`, `q1`, `ir2`, `ii2`, `im2`, `p2`, `q2` + `Branch` | algebraic pi model for a line or off-nominal transformer branch | `bus1`, `bus2` | `R`, `X`, `G`, `B`, `tap`, `phase`, `closed` | `ir1`, `ii1`, `im1`, `p1`, `q1`, `ir2`, `ii2`, `im2`, `p2`, `q2` `Load` | a basic static impedence load model | `bus` | `R`, `X` | `p`, `q` `Genrou` | 6th order machine model | `bus`, `pmech`\*, `speed`\*, `efd`\* | `p0`, `q0`, `H`, `D`, `Ra`, `Tdop`, `Tdopp`, `Tqop`, `Tqopp`, `Xd`, `Xdp`, `Xdpp`, `Xq`, `Xqp`, `Xqpp`, `Xl`, `S10`, `S12`, `mva` | `ir`, `ii`, `p`, `q`, `delta`, `omega`, `speed` `Gensal` | 5th order salient-pole machine model | `bus`, `pmech`\*, `speed`\*, `efd`\* | `p0`, `q0`, `H`, `D`, `Ra`, `Tdop`, `Tdopp`, `Tqopp`, `Xd`, `Xdp`, `Xdpp`, `Xq`, `Xl`, `S10`, `S12`, `mva` | `ir`, `ii`, `p`, `q`, `delta`, `omega`, `speed`, `Eqp`, `psidp`, `psiqpp`, `psidpp`, `vd`, `vq`, `te`, `id`, `iq` @@ -155,9 +155,10 @@ Ports marked with \* are optional and, if missing, will be assumed to be connected to a constant value. This list is subject to change. -For `Branch`, `tap` and `phase` are optional parameters. If omitted, `tap` -defaults to `1.0` and `phase` defaults to `0.0` radians. Bus `bus1` is the tap -side for off-nominal transformer branches. +For `Branch`, `tap`, `phase`, and `closed` are optional parameters. If omitted, +`tap` defaults to `1.0`, `phase` defaults to `0.0` radians, and `closed` +defaults to `true`. `closed` must be a JSON boolean; numeric status values are +rejected. Bus `bus1` is the tap side for off-nominal transformer branches. ## Example File for a 2-Bus System diff --git a/tests/UnitTests/PhasorDynamics/BranchTests.hpp b/tests/UnitTests/PhasorDynamics/BranchTests.hpp index 4ce11312e..e1aa6172f 100644 --- a/tests/UnitTests/PhasorDynamics/BranchTests.hpp +++ b/tests/UnitTests/PhasorDynamics/BranchTests.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -230,6 +231,116 @@ namespace GridKit return success.report(__func__); } + TestOutcome outOfServiceBranch() + { + // Verifies open branches contribute zero residual and DependencyTracking derivatives. + TestStatus success = true; + + RealT R{2.0}; + RealT X{4.0}; + RealT G{0.2}; + RealT B{1.2}; + + DependencyTracking::Variable Vr1{10.0}; + DependencyTracking::Variable Vi1{20.0}; + DependencyTracking::Variable Vr2{30.0}; + DependencyTracking::Variable Vi2{40.0}; + + PhasorDynamics::Bus bus1(Vr1, Vi1); + PhasorDynamics::Bus bus2(Vr2, Vi2); + bus1.allocate(); + bus1.initialize(); + bus1.evaluateResidual(); + bus2.allocate(); + bus2.initialize(); + bus2.evaluateResidual(); + bus1.Vr().setVariableNumber(0); + bus1.Vi().setVariableNumber(1); + bus2.Vr().setVariableNumber(2); + bus2.Vi().setVariableNumber(3); + + PhasorDynamics::BranchData data; + data.parameters[PhasorDynamics::BranchParameters::R] = R; + data.parameters[PhasorDynamics::BranchParameters::X] = X; + data.parameters[PhasorDynamics::BranchParameters::G] = G; + data.parameters[PhasorDynamics::BranchParameters::B] = B; + data.parameters[PhasorDynamics::BranchParameters::closed] = false; + + PhasorDynamics::Branch branch(&bus1, &bus2, data); + branch.allocate(); + branch.evaluateResidual(); + + const RealT zero{0.0}; + std::vector residuals{bus1.Ir(), bus1.Ii(), bus2.Ir(), bus2.Ii()}; + for (const auto& res : residuals) + { + success *= isEqual(res.getValue(), zero); + for (const auto& [var_id, coef] : res.getDependencies()) + { + success *= isEqual(coef, zero); + } + } + + return success.report(__func__); + } + +#ifdef GRIDKIT_ENABLE_ENZYME + TestOutcome outOfServiceEnzymeJacobian() + { + // Verifies open branches contribute zero values through the Enzyme Jacobian path. + TestStatus success = true; + + PhasorDynamics::Bus bus1(10.0, 20.0); + PhasorDynamics::Bus bus2(30.0, 40.0); + bus1.allocate(); + bus1.initialize(); + bus2.allocate(); + bus2.initialize(); + + bus1.setVariableIndex(0, 0); + bus1.setVariableIndex(1, 1); + bus1.setResidualIndex(0, 0); + bus1.setResidualIndex(1, 1); + bus2.setVariableIndex(0, 2); + bus2.setVariableIndex(1, 3); + bus2.setResidualIndex(0, 2); + bus2.setResidualIndex(1, 3); + + PhasorDynamics::BranchData data; + data.parameters[PhasorDynamics::BranchParameters::R] = RealT{2.0}; + data.parameters[PhasorDynamics::BranchParameters::X] = RealT{4.0}; + data.parameters[PhasorDynamics::BranchParameters::G] = RealT{0.2}; + data.parameters[PhasorDynamics::BranchParameters::B] = RealT{1.2}; + data.parameters[PhasorDynamics::BranchParameters::closed] = false; + + PhasorDynamics::Branch branch(&bus1, &bus2, data); + branch.allocate(); + + bus1.evaluateJacobian(); + bus2.evaluateJacobian(); + branch.evaluateJacobian(); + + const RealT zero{0.0}; + auto check_jacobian_values = [&](auto& jacobian) + { + const auto entries = jacobian.getEntries(false); + const auto& [rows, cols, vals] = entries; + (void) rows; + (void) cols; + for (const auto value : vals) + { + success *= isEqual(value, zero); + } + }; + + check_jacobian_values(branch.getJacobian()); + check_jacobian_values(bus1.getJacobian()); + check_jacobian_values(bus2.getJacobian()); + + return success.report(__func__); + } +#endif + TestOutcome accessors() { // Verifies tap and phase-shift residual derivatives. @@ -361,6 +472,30 @@ namespace GridKit PhasorDynamics::Branch negative_tap_branch(&bus1, &bus2, 0.0, 0.1, 0.0, 0.0, -1.0, 0.0); success *= (negative_tap_branch.verify() != 0); + typename PhasorDynamics::Branch::ModelDataT real_closed_data; + real_closed_data.parameters[PhasorDynamics::BranchParameters::R] = RealT{0.0}; + real_closed_data.parameters[PhasorDynamics::BranchParameters::X] = RealT{0.1}; + real_closed_data.parameters[PhasorDynamics::BranchParameters::G] = RealT{0.0}; + real_closed_data.parameters[PhasorDynamics::BranchParameters::B] = RealT{0.0}; + real_closed_data.parameters[PhasorDynamics::BranchParameters::closed] = RealT{1.1}; + success *= throws( + [&]() + { + PhasorDynamics::Branch branch(&bus1, &bus2, real_closed_data); + }); + + typename PhasorDynamics::Branch::ModelDataT integer_closed_data; + integer_closed_data.parameters[PhasorDynamics::BranchParameters::R] = RealT{0.0}; + integer_closed_data.parameters[PhasorDynamics::BranchParameters::X] = RealT{0.1}; + integer_closed_data.parameters[PhasorDynamics::BranchParameters::G] = RealT{0.0}; + integer_closed_data.parameters[PhasorDynamics::BranchParameters::B] = RealT{0.0}; + integer_closed_data.parameters[PhasorDynamics::BranchParameters::closed] = IdxT{1}; + success *= throws( + [&]() + { + PhasorDynamics::Branch branch(&bus1, &bus2, integer_closed_data); + }); + const RealT nan = std::numeric_limits::quiet_NaN(); PhasorDynamics::Branch nonfinite_branch(&bus1, &bus2, nan, 0.1, 0.0, 0.0); success *= (nonfinite_branch.verify() != 0); @@ -370,7 +505,7 @@ namespace GridKit TestOutcome dataConstructorDefaults() { - // Verifies omitted data parameters use tap and phase defaults. + // Verifies omitted data parameters use tap, phase, and closed defaults. TestStatus success = true; const RealT R{2.0}; diff --git a/tests/UnitTests/PhasorDynamics/CMakeLists.txt b/tests/UnitTests/PhasorDynamics/CMakeLists.txt index 932cb13b8..6b006f816 100644 --- a/tests/UnitTests/PhasorDynamics/CMakeLists.txt +++ b/tests/UnitTests/PhasorDynamics/CMakeLists.txt @@ -24,6 +24,9 @@ target_link_libraries( GridKit::phasor_dynamics_bus GridKit::phasor_dynamics_bus_dependency_tracking GridKit::testing) +if(GRIDKIT_ENABLE_ENZYME) + target_compile_definitions(test_phasor_branch PRIVATE GRIDKIT_ENABLE_ENZYME) +endif() add_executable(test_phasor_load runLoadTests.cpp) target_link_libraries( diff --git a/tests/UnitTests/PhasorDynamics/runBranchTests.cpp b/tests/UnitTests/PhasorDynamics/runBranchTests.cpp index c0fe130c8..db8770e85 100644 --- a/tests/UnitTests/PhasorDynamics/runBranchTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runBranchTests.cpp @@ -16,6 +16,10 @@ int main() result += test.offNominalResidual(); result += test.jacobian(); result += test.offNominalJacobian(); + result += test.outOfServiceBranch(); +#ifdef GRIDKIT_ENABLE_ENZYME + result += test.outOfServiceEnzymeJacobian(); +#endif return result.summary(); } diff --git a/tests/UnitTests/Utilities/CaseFormatTests.hpp b/tests/UnitTests/Utilities/CaseFormatTests.hpp index d1c3475ef..2f35333ab 100644 --- a/tests/UnitTests/Utilities/CaseFormatTests.hpp +++ b/tests/UnitTests/Utilities/CaseFormatTests.hpp @@ -61,7 +61,7 @@ namespace GridKit { "number": 2, "class": "infinite_bus", "name": "Bus 2", "init": {"Vr":1.0, "Vi":0.0}, "v_base": 115e3 } ], "devices": [ - { "class": "Branch", "ports": {"bus1":1, "bus2":2}, "id": "1", "params": {"R":0.0, "X":0.1, "G":0.0, "B":0.0, "tap":1.05, "phase":0.1} }, + { "class": "Branch", "ports": {"bus1":1, "bus2":2}, "id": "1", "params": {"R":0, "X":0.1, "G":0, "B":0, "tap":1.05, "phase":0, "closed": false} }, { "class": "Genrou", "ports": {"bus":1}, "id": "1", "params": {"p0":1.0, "q0":0.05013, "H":3.0, "D":0.0, "Ra":0.0, "Tdop":7.0, "Tdopp":0.04, "Tqopp":0.05, "Tqop":0.75, "Xd":2.1, "Xdp":0.2, "Xdpp":0.18, "Xq":0.5, "Xqp": 0.0, "Xqpp":0.18, "Xl":0.15, "S10":0.0, "S12":0.0}, "mon": ["delta", "omega"] }, { "class": "Gensal", "ports": {"bus":1}, "id": "2", "params": {"p0":1.0, "q0":0.05013, "H":3.0, "D":0.0, "Ra":0.0, "Tdop":7.0, "Tdopp":0.04, "Tqopp":0.05, @@ -115,7 +115,8 @@ namespace GridKit success *= std::get(result.branch[0].parameters[BranchParameters::G]) == 0.0; success *= std::get(result.branch[0].parameters[BranchParameters::B]) == 0.0; success *= std::get(result.branch[0].parameters[BranchParameters::tap]) == 1.05; - success *= std::get(result.branch[0].parameters[BranchParameters::phase]) == 0.1; + success *= std::get(result.branch[0].parameters[BranchParameters::phase]) == 0.0; + success *= std::get(result.branch[0].parameters[BranchParameters::closed]) == false; success *= result.branch[0].ports[BranchPorts::bus1] == 1; success *= result.branch[0].ports[BranchPorts::bus2] == 2; success *= result.branch[0].disambiguation_string == "1";