From c1145b9862bc24e3d46f08fc5e147ce1f38e60af Mon Sep 17 00:00:00 2001 From: superwhiskers Date: Mon, 2 Nov 2026 14:44:27 -0500 Subject: [PATCH 1/2] update formatting rules - adjust continuation indentation and bracket alignment - apply formatting fixes across the repository --- .clang-format | 5 +- .../DependencyTracking/VariableOperators.hpp | 42 +- .../Enzyme/D2LDx2.hpp | 124 +- .../AutomaticDifferentiation/Enzyme/DfDwb.hpp | 174 +- .../AutomaticDifferentiation/Enzyme/DfDws.hpp | 90 +- .../AutomaticDifferentiation/Enzyme/DfDx.hpp | 14 +- .../AutomaticDifferentiation/Enzyme/DfDy.hpp | 174 +- .../AutomaticDifferentiation/Enzyme/DfDyp.hpp | 178 +- .../AutomaticDifferentiation/Enzyme/DgDx.hpp | 70 +- .../AutomaticDifferentiation/Enzyme/DhDwb.hpp | 84 +- .../AutomaticDifferentiation/Enzyme/DhDy.hpp | 84 +- .../Enzyme/LowerSparseStorage.hpp | 117 +- .../Enzyme/ModelWrappers.hpp | 86 +- GridKit/CoSim/CoSim.cpp | 124 +- GridKit/CoSim/CoSim.hpp | 26 +- GridKit/CoSim/CoSimInternal.hpp | 19 +- GridKit/CoSim/Message.hpp | 12 +- GridKit/CommonMath.hpp | 69 +- .../LinearAlgebra/SparseMatrix/CooMatrix.cpp | 36 +- .../LinearAlgebra/SparseMatrix/CooMatrix.hpp | 28 +- .../LinearAlgebra/SparseMatrix/CsrMatrix.cpp | 75 +- .../LinearAlgebra/SparseMatrix/CsrMatrix.hpp | 65 +- GridKit/LinearAlgebra/Vector/Vector.cpp | 20 +- GridKit/LinearAlgebra/Vector/Vector.hpp | 34 +- .../LinearAlgebra/Vector/VectorHandler.cpp | 66 +- .../LinearAlgebra/Vector/VectorHandler.hpp | 48 +- .../LinearAlgebra/Vector/VectorHandlerCpu.cpp | 52 +- .../LinearAlgebra/Vector/VectorHandlerCpu.hpp | 16 +- .../Model/OptimalPowerFlow/Branch/Branch.hpp | 14 +- .../OptimalPowerFlow/Branch/BranchImpl.hpp | 16 +- .../Model/OptimalPowerFlow/Bus/BusImpl.hpp | 8 +- GridKit/Model/OptimalPowerFlow/Component.hpp | 75 +- .../OptimalPowerFlow/ComponentEnzyme.hpp | 42 +- .../OptimalPowerFlow/Generator/Generator.hpp | 4 +- .../Generator/GeneratorImpl.hpp | 8 +- GridKit/Model/OptimalPowerFlow/Load/Load.hpp | 8 +- .../Model/OptimalPowerFlow/Load/LoadImpl.hpp | 8 +- .../OptimalPowerFlow/SystemModelImpl.hpp | 32 +- GridKit/Model/ParameterReader.hpp | 19 +- .../Model/PhasorDynamics/Branch/Branch.hpp | 36 +- .../PhasorDynamics/Branch/BranchData.hpp | 16 +- .../PhasorDynamics/Branch/BranchEnzyme.cpp | 120 +- .../PhasorDynamics/Branch/BranchImpl.hpp | 39 +- GridKit/Model/PhasorDynamics/Bus/BusData.hpp | 15 +- .../PhasorDynamics/Bus/BusDataJSONParser.hpp | 11 +- .../BusSignalVoltageOutEnzyme.cpp | 2 +- .../BusSignalVoltageOutImpl.hpp | 23 +- .../Model/PhasorDynamics/ComponentData.hpp | 18 +- .../ComponentDataJSONParser.hpp | 56 +- .../PhasorDynamics/Controller/REECB/Reecb.hpp | 15 +- .../Controller/REECB/ReecbData.hpp | 16 +- .../Controller/REECB/ReecbEnzyme.cpp | 24 +- .../Controller/REECB/ReecbImpl.hpp | 36 +- .../PhasorDynamics/Controller/REPCA/Repca.hpp | 11 +- .../Controller/REPCA/RepcaData.hpp | 16 +- .../Controller/REPCA/RepcaEnzyme.cpp | 24 +- .../Controller/REPCA/RepcaImpl.hpp | 109 +- .../PhasorDynamics/Converter/REGCA/Regca.hpp | 26 +- .../Converter/REGCA/RegcaData.hpp | 16 +- .../Converter/REGCA/RegcaEnzyme.cpp | 149 +- .../Converter/REGCA/RegcaImpl.hpp | 59 +- .../PhasorDynamics/Exciter/ESDC1A/Esdc1a.hpp | 16 +- .../Exciter/ESDC1A/Esdc1aData.hpp | 16 +- .../Exciter/ESDC1A/Esdc1aEnzyme.cpp | 118 +- .../Exciter/ESDC1A/Esdc1aImpl.hpp | 36 +- .../PhasorDynamics/Exciter/IEEET1/Ieeet1.hpp | 7 +- .../Exciter/IEEET1/Ieeet1Data.hpp | 16 +- .../Exciter/IEEET1/Ieeet1Enzyme.cpp | 134 +- .../Exciter/IEEET1/Ieeet1Impl.hpp | 26 +- .../Exciter/SEXS-PTI/SexsPti.hpp | 7 +- .../Exciter/SEXS-PTI/SexsPtiData.hpp | 16 +- .../Exciter/SEXS-PTI/SexsPtiEnzyme.cpp | 134 +- .../Exciter/SEXS-PTI/SexsPtiImpl.hpp | 16 +- .../Governor/GASTPTI/GastPti.hpp | 11 +- .../Governor/GASTPTI/GastPtiData.hpp | 16 +- .../Governor/GASTPTI/GastPtiEnzyme.cpp | 89 +- .../Governor/GASTPTI/GastPtiImpl.hpp | 96 +- .../PhasorDynamics/Governor/HYGOV/Hygov.hpp | 21 +- .../Governor/HYGOV/HygovData.hpp | 16 +- .../Governor/HYGOV/HygovEnzyme.cpp | 89 +- .../Governor/HYGOV/HygovImpl.hpp | 78 +- .../PhasorDynamics/Governor/Tgov1/Tgov1.hpp | 7 +- .../Governor/Tgov1/Tgov1Data.hpp | 16 +- .../Governor/Tgov1/Tgov1Enzyme.cpp | 101 +- .../Governor/Tgov1/Tgov1Impl.hpp | 18 +- .../Model/PhasorDynamics/Load/LoadZ/LoadZ.hpp | 6 +- .../PhasorDynamics/Load/LoadZ/LoadZData.hpp | 16 +- .../PhasorDynamics/Load/LoadZ/LoadZEnzyme.cpp | 90 +- .../PhasorDynamics/Load/LoadZ/LoadZImpl.hpp | 18 +- .../PhasorDynamics/Load/LoadZIP/LoadZIP.hpp | 6 +- .../Load/LoadZIP/LoadZIPData.hpp | 16 +- .../Load/LoadZIP/LoadZIPEnzyme.cpp | 90 +- .../Load/LoadZIP/LoadZIPImpl.hpp | 18 +- GridKit/Model/PhasorDynamics/ModelData.hpp | 46 +- GridKit/Model/PhasorDynamics/PortGroup.hpp | 8 +- .../SignalSource/ConstantSignalSourceData.hpp | 16 +- .../SignalSource/FunctionSignalSourceData.hpp | 16 +- .../Stabilizer/IEEEST/Ieeest.hpp | 11 +- .../Stabilizer/IEEEST/IeeestData.hpp | 16 +- .../Stabilizer/IEEEST/IeeestEnzyme.cpp | 101 +- .../Stabilizer/IEEEST/IeeestImpl.hpp | 14 +- .../SynchronousMachine/GENROU/Genrou.hpp | 6 +- .../SynchronousMachine/GENROU/GenrouData.hpp | 16 +- .../GENROU/GenrouEnzyme.cpp | 160 +- .../SynchronousMachine/GENROU/GenrouImpl.hpp | 24 +- .../SynchronousMachine/GENSAL/Gensal.hpp | 6 +- .../SynchronousMachine/GENSAL/GensalData.hpp | 16 +- .../GENSAL/GensalEnzyme.cpp | 160 +- .../SynchronousMachine/GENSAL/GensalImpl.hpp | 12 +- .../GenClassical/GenClassical.hpp | 6 +- .../GenClassical/GenClassicalData.hpp | 16 +- .../GenClassical/GenClassicalEnzyme.cpp | 160 +- .../GenClassical/GenClassicalImpl.hpp | 26 +- GridKit/Model/PhasorDynamics/SystemModel.hpp | 6 +- .../Model/PhasorDynamics/SystemModelImpl.hpp | 21 +- .../DistributedGenerator.cpp | 134 +- .../DistributedGenerator.hpp | 12 +- GridKit/Model/PowerElectronics/NodeBase.hpp | 8 +- .../Model/PowerElectronics/SystemModel.hpp | 9 +- GridKit/Model/PowerFlow/MatpowerParser.hpp | 56 +- GridKit/Model/VariableMonitor.hpp | 12 +- GridKit/Model/VariableMonitorController.hpp | 13 +- GridKit/Model/VariableMonitorImpl.hpp | 34 +- GridKit/Solver/Dynamic/Ida.cpp | 266 +-- GridKit/Solver/Dynamic/Ida.hpp | 99 +- GridKit/Solver/Dynamic/Native/FixedStep.cpp | 4 +- GridKit/Solver/Dynamic/Rosenbrock.cpp | 68 +- GridKit/Solver/Dynamic/Rosenbrock.hpp | 26 +- GridKit/Solver/Dynamic/RosenbrockTableaus.cpp | 52 +- .../Solver/Optimization/DynamicConstraint.cpp | 142 +- .../Solver/Optimization/DynamicConstraint.hpp | 34 +- .../Solver/Optimization/DynamicObjective.cpp | 142 +- .../Solver/Optimization/DynamicObjective.hpp | 34 +- .../Solver/Optimization/IpoptInterface.cpp | 144 +- .../Solver/Optimization/IpoptInterface.hpp | 86 +- GridKit/Solver/SteadyState/Kinsol.cpp | 42 +- GridKit/Solver/SteadyState/Kinsol.hpp | 16 +- GridKit/Solver/SundialsException.hpp | 3 +- GridKit/Testing/AggregateErrors.hpp | 16 +- GridKit/Testing/CSV.cpp | 10 +- GridKit/Testing/CSV.hpp | 9 +- GridKit/Testing/Testing.hpp | 20 +- GridKit/Utilities/CliArgs/ArgValue.hpp | 7 +- GridKit/Utilities/CliArgs/CliArgs.hpp | 2 +- GridKit/Utilities/CliArgs/CliArgsImpl.hpp | 91 +- GridKit/Utilities/Enum.hpp | 15 +- GridKit/Utilities/FileIO.hpp | 10 +- GridKit/Utilities/Logger/Logger.cpp | 14 +- GridKit/Utilities/String.hpp | 11 +- .../PhasorDynamics/AnalysisUtilities.hpp | 29 +- application/PhasorDynamics/CoSimulation.hpp | 82 +- .../PhasorDynamics/ContingencyAnalysis.cpp | 22 +- application/PhasorDynamics/CoupledClient.hpp | 85 +- application/PhasorDynamics/CoupledServer.hpp | 23 +- .../PhasorDynamics/DynamicSimulation.cpp | 2 +- .../PhasorDynamics/SimulationOptions.hpp | 113 +- .../PhasorDynamics/SimulationRunner.hpp | 56 +- .../DynamicConstrainedOpt.cpp | 8 +- .../GenConstLoad/GenConstLoad.cpp | 6 +- .../GenInfiniteBus/GenInfiniteBus.cpp | 8 +- .../ParameterEstimation.cpp | 8 +- .../ParameterEstimation/lookup_table.hpp | 2 +- .../EconomicDispatch/EconomicDispatch.cpp | 24 +- .../DistributedGeneratorTest/DGTest.cpp | 70 +- .../ExamplesHelper/MicrogridNetwork.hpp | 42 +- .../ExamplesHelper/SystemAssembler.hpp | 6 +- .../PowerElectronics/Microgrid/Microgrid.cpp | 95 +- .../ScaleMicrogrid/SolutionKeys.hpp | 669 ++------ .../MatPowerTesting/MatPowerTesting.hpp | 46 +- .../MatPowerTesting/test_parse_branch_row.cpp | 17 +- .../MatPowerTesting/test_parse_bus_row.cpp | 25 +- .../MatPowerTesting/test_parse_gen_row.cpp | 19 +- .../test_parse_gencost_row.cpp | 15 +- .../MatPowerTesting/test_parse_matpower.cpp | 61 +- .../PhasorDynamics/PDIntegrationTests.hpp | 83 +- .../SystemJacobian/SystemJacobianTests.hpp | 39 +- .../SystemJacobian/runSystemJacobianTests.cpp | 16 +- .../TenGen/Classical/TenGenClassical.cpp | 27 +- .../TenGen/Genrou/TenGenGenrou.cpp | 27 +- .../DependencyTrackingTests.hpp | 10 +- .../Enzyme/EnzymeTests.hpp | 57 +- .../SparseMatrix/SparseCsrTests.hpp | 4 +- .../Vector/VectorHandlerTests.hpp | 7 +- .../Math/SmoothnessIndicatorTests.hpp | 96 +- tests/UnitTests/Network/CoSimTests.hpp | 195 ++- .../OptimalPowerFlow/ComponentTests.hpp | 105 +- .../OptimalPowerFlow/SystemTestData.hpp | 16 +- .../OptimalPowerFlow/SystemTests.hpp | 2 +- .../OptimalPowerFlow/TestHelpers.hpp | 18 +- .../UnitTests/PhasorDynamics/BranchTests.hpp | 46 +- .../BusSignalVoltageOutTests.hpp | 6 +- .../ComponentConnectionTests.hpp | 135 +- .../PhasorDynamics/ControllerReecbTests.hpp | 1428 ++++++++-------- .../PhasorDynamics/ControllerRepcaTests.hpp | 1470 +++++++++-------- .../PhasorDynamics/ConverterRegcaTests.hpp | 173 +- .../PhasorDynamics/ExciterEsdc1aTests.hpp | 610 ++++--- .../PhasorDynamics/ExciterIeeet1Tests.hpp | 8 +- .../PhasorDynamics/ExciterSexsPtiTests.hpp | 5 +- .../PhasorDynamics/GenClassicalTests.hpp | 19 +- .../UnitTests/PhasorDynamics/GenrouTests.hpp | 37 +- .../UnitTests/PhasorDynamics/GensalTests.hpp | 31 +- .../PhasorDynamics/GovernorGastPtiTests.hpp | 762 +++++---- .../PhasorDynamics/GovernorHygovTests.hpp | 1072 ++++++------ .../PhasorDynamics/GovernorTgov1Tests.hpp | 25 +- .../UnitTests/PhasorDynamics/LoadZIPTests.hpp | 17 +- tests/UnitTests/PhasorDynamics/LoadZTests.hpp | 6 +- .../ModelConfigurationTests.hpp | 37 +- .../PhasorDynamics/StabilizerIeeestTests.hpp | 37 +- .../PhasorDynamics/SubsystemModelTests.hpp | 13 +- .../UnitTests/PhasorDynamics/SystemTests.hpp | 43 +- tests/UnitTests/Solver/KinsolTests.hpp | 15 +- tests/UnitTests/Utilities/CaseFormatTests.hpp | 41 +- tests/UnitTests/Utilities/CliArgsTests.hpp | 208 +-- 213 files changed, 8289 insertions(+), 7057 deletions(-) diff --git a/.clang-format b/.clang-format index 2b9360a84f..78a2be4d88 100644 --- a/.clang-format +++ b/.clang-format @@ -4,6 +4,7 @@ BasedOnStyle: Microsoft # Indentation IndentWidth: 2 # 2 spaces per indent +ContinuationIndentWidth: 2 AccessModifierOffset: -2 IndentAccessModifiers: false # Align access modifiers to braces NamespaceIndentation: All # Indent namspace contents @@ -12,7 +13,6 @@ ConstructorInitializerIndentWidth: 2 # Comments which match this regex will be unformatted (and therefore can be longer or have more whitespace than other comments) CommentPragmas: '^\*\*' - # Alignment AlignConsecutiveAssignments: Enabled: true @@ -37,7 +37,8 @@ AlignConsecutiveMacros: AcrossComments: true # Newlines -ColumnLimit: 0 +AlignAfterOpenBracket: BlockIndent # this will need to be replaced w/ clang-format 22 +ColumnLimit: 80 BreakBeforeBraces: Allman # Braces on their own lines SeparateDefinitionBlocks: Always # Separate definitions (functions etc.) with an empty line AlwaysBreakTemplateDeclarations: true # Put template on their own lines diff --git a/GridKit/AutomaticDifferentiation/DependencyTracking/VariableOperators.hpp b/GridKit/AutomaticDifferentiation/DependencyTracking/VariableOperators.hpp index ec786da3dc..6f4c70f62f 100644 --- a/GridKit/AutomaticDifferentiation/DependencyTracking/VariableOperators.hpp +++ b/GridKit/AutomaticDifferentiation/DependencyTracking/VariableOperators.hpp @@ -378,22 +378,32 @@ namespace std return res; \ } -#define IMPL_FUN_2(FUN, DER1, DER2) \ - inline GridKit::DependencyTracking::Variable FUN(const GridKit::DependencyTracking::Variable& x, \ - const GridKit::DependencyTracking::Variable& y) \ - { \ - double val = FUN(x(), y()); \ - double der1 = DER1(x(), y()); \ - double der2 = DER2(x(), y()); \ - GridKit::DependencyTracking::Variable res1(x); /* copy derivatives of x*/ \ - GridKit::DependencyTracking::Variable res2(y); /* copy derivatives of y*/ \ - res1.setValue(val); /* set function value f(x, y) */ \ - res2.setValue(val); /* set function value f(x, y) */ \ - res1.scaleDependencies(der1); /* compute derivatives of f(x, y) with respect to x */ \ - res2.scaleDependencies(der2); /* compute derivatives of f(x, y) with respect to y */ \ - GridKit::DependencyTracking::Variable res(std::move(res1)); /* relocate derivatives w.r.t. x into return */ \ - res.addDependencies(res2); /* add derivatives with respect to y to return */ \ - return res; \ +#define IMPL_FUN_2(FUN, DER1, DER2) \ + inline GridKit::DependencyTracking::Variable FUN( \ + const GridKit::DependencyTracking::Variable& x, \ + const GridKit::DependencyTracking::Variable& y \ + ) \ + { \ + double val = FUN(x(), y()); \ + double der1 = DER1(x(), y()); \ + double der2 = DER2(x(), y()); \ + GridKit::DependencyTracking::Variable res1(x); /* copy derivatives of x*/ \ + GridKit::DependencyTracking::Variable res2(y); /* copy derivatives of y*/ \ + res1.setValue(val); /* set function value f(x, y) */ \ + res2.setValue(val); /* set function value f(x, y) */ \ + res1.scaleDependencies( \ + der1 \ + ); /* compute derivatives of f(x, y) with respect to x */ \ + res2.scaleDependencies( \ + der2 \ + ); /* compute derivatives of f(x, y) with respect to y */ \ + GridKit::DependencyTracking::Variable res( \ + std::move(res1) \ + ); /* relocate derivatives w.r.t. x into return */ \ + res.addDependencies( \ + res2 \ + ); /* add derivatives with respect to y to return */ \ + return res; \ } IMPL_FUN_1(sin, GridKit::DependencyTracking::sin_derivative) diff --git a/GridKit/AutomaticDifferentiation/Enzyme/D2LDx2.hpp b/GridKit/AutomaticDifferentiation/Enzyme/D2LDx2.hpp index 5c434cb157..ccc656fb54 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/D2LDx2.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/D2LDx2.hpp @@ -40,48 +40,56 @@ namespace GridKit * @param[out] nnz - Number of nonzeros */ template - static void eval(const ModelT* model, - const size_t n_var, - const IdxT* variable_indices, - const ScalarT* x, - const RealT sigma, - const RealT* lambda, - IdxT* rows, - IdxT* cols, - ScalarT* vals, - IdxT& nnz) + static void eval( + const ModelT* model, + const size_t n_var, + const IdxT* variable_indices, + const ScalarT* x, + const RealT sigma, + const RealT* lambda, + IdxT* rows, + IdxT* cols, + ScalarT* vals, + IdxT& nnz + ) { std::array gradient{}; for (size_t var_i = 0; var_i < n_var; ++var_i) { // Sparse storage. @see LowerSparseStorage.hpp - ScalarT* seed = __enzyme_todense((void*) ident_load, - (void*) ident_store, - var_i); - ScalarT* dgradient = __enzyme_todense((void*) sparse_load, - (void*) sparse_store, - var_i, - 1.0, // value scaling - variable_indices, - variable_indices, - rows, - cols, - vals, - &nnz); + ScalarT* seed = __enzyme_todense( + (void*) ident_load, + (void*) ident_store, + var_i + ); + ScalarT* dgradient = __enzyme_todense( + (void*) sparse_load, + (void*) sparse_store, + var_i, + 1.0, // value scaling + variable_indices, + variable_indices, + rows, + cols, + vals, + &nnz + ); - __enzyme_fwddiff((void*) lagrangianGradient, - enzyme_const, - model, - enzyme_dup, - x, - seed, - enzyme_dupnoneed, - gradient.data(), - dgradient, - enzyme_const, - sigma, - enzyme_const, - lambda); + __enzyme_fwddiff( + (void*) lagrangianGradient, + enzyme_const, + model, + enzyme_dup, + x, + seed, + enzyme_dupnoneed, + gradient.data(), + dgradient, + enzyme_const, + sigma, + enzyme_const, + lambda + ); } } @@ -90,10 +98,12 @@ namespace GridKit using ConstraintsT = ModelWrapper; template - [[gnu::always_inline]] inline static ScalarT lagrangian(const ModelT* model, - const ScalarT* x, - const RealT sigma, - const RealT* lambda) + [[gnu::always_inline]] inline static ScalarT lagrangian( + const ModelT* model, + const ScalarT* x, + const RealT sigma, + const RealT* lambda + ) { std::array g{}; ConstraintsT::eval(model, x, g.data()); @@ -108,22 +118,26 @@ namespace GridKit /// Add the Lagrangian gradient to `gradient`, whose tangent alone is used template - [[gnu::always_inline]] inline static void lagrangianGradient(const ModelT* model, - const ScalarT* x, - ScalarT* gradient, - const RealT sigma, - const RealT* lambda) + [[gnu::always_inline]] inline static void lagrangianGradient( + const ModelT* model, + const ScalarT* x, + ScalarT* gradient, + const RealT sigma, + const RealT* lambda + ) { - __enzyme_autodiff((void*) lagrangian, - enzyme_const, - model, - enzyme_dup, - x, - gradient, - enzyme_const, - sigma, - enzyme_const, - lambda); + __enzyme_autodiff( + (void*) lagrangian, + enzyme_const, + model, + enzyme_dup, + x, + gradient, + enzyme_const, + sigma, + enzyme_const, + lambda + ); } }; } // namespace Sparse diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DfDwb.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DfDwb.hpp index 73fa06ea74..3ed36480b4 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DfDwb.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DfDwb.hpp @@ -44,53 +44,61 @@ namespace GridKit * @param[out] vals - Values * @param[out] nnz - Number of nonzeros */ - static void eval(ModelT* model, - const size_t n_res, - const size_t n_var, - const IdxT* res_indices, - const IdxT* var_indices, - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - IdxT* rows, - IdxT* cols, - RealT* vals, - IdxT& nnz) + static void eval( + ModelT* model, + const size_t n_res, + const size_t n_var, + const IdxT* res_indices, + const IdxT* var_indices, + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + IdxT* rows, + IdxT* cols, + RealT* vals, + IdxT& nnz + ) { if (n_res > 0 && n_var > 0) { for (size_t var_i = 0; var_i < n_var; ++var_i) { // Sparse storage. @see LowerSparseStorage.hpp - ScalarT* output = __enzyme_todense((void*) ident_load, - (void*) ident_store, - var_i); - ScalarT* d_output = __enzyme_todense((void*) sparse_load, - (void*) sparse_store, - var_i, - 1.0, // value scaling - res_indices, - var_indices, - rows, - cols, - vals, - &nnz); + ScalarT* output = __enzyme_todense( + (void*) ident_load, + (void*) ident_store, + var_i + ); + ScalarT* d_output = __enzyme_todense( + (void*) sparse_load, + (void*) sparse_store, + var_i, + 1.0, // value scaling + res_indices, + var_indices, + rows, + cols, + vals, + &nnz + ); // Core automatic differentiation intrinsic that will be replaced by a derivative // The dummy primal pointer is safe only while residuals never read back their output - __enzyme_fwddiff((void*) ModelWrapper::eval, - enzyme_const, - model, - enzyme_const, - y, - enzyme_const, - yp, - enzyme_dup, - wb, - output, // Seed: column var_i of the identity - enzyme_dupnoneed, - (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) - d_output); // Column var_i of the Jacobian + __enzyme_fwddiff( + (void*) ModelWrapper::eval, + enzyme_const, + model, + enzyme_const, + y, + enzyme_const, + yp, + enzyme_dup, + wb, + output, // Seed: column var_i of the identity + enzyme_dupnoneed, + (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) + d_output + ); // Column var_i of the Jacobian } } } @@ -110,56 +118,64 @@ namespace GridKit * @param[out] vals - Values * @param[out] nnz - Number of nonzeros */ - static void eval(ModelT* model, - const size_t n_res, - const size_t n_var, - const IdxT* res_indices, - const IdxT* var_indices, - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - const ScalarT* ws, - IdxT* rows, - IdxT* cols, - RealT* vals, - IdxT& nnz) + static void eval( + ModelT* model, + const size_t n_res, + const size_t n_var, + const IdxT* res_indices, + const IdxT* var_indices, + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + const ScalarT* ws, + IdxT* rows, + IdxT* cols, + RealT* vals, + IdxT& nnz + ) { if (n_res > 0 && n_var > 0) { for (size_t var_i = 0; var_i < n_var; ++var_i) { // Sparse storage. @see LowerSparseStorage.hpp - ScalarT* output = __enzyme_todense((void*) ident_load, - (void*) ident_store, - var_i); - ScalarT* d_output = __enzyme_todense((void*) sparse_load, - (void*) sparse_store, - var_i, - 1.0, // value scaling - res_indices, - var_indices, - rows, - cols, - vals, - &nnz); + ScalarT* output = __enzyme_todense( + (void*) ident_load, + (void*) ident_store, + var_i + ); + ScalarT* d_output = __enzyme_todense( + (void*) sparse_load, + (void*) sparse_store, + var_i, + 1.0, // value scaling + res_indices, + var_indices, + rows, + cols, + vals, + &nnz + ); // Core automatic differentiation intrinsic that will be replaced by a derivative // The dummy primal pointer is safe only while residuals never read back their output - __enzyme_fwddiff((void*) ModelWrapper::eval, - enzyme_const, - model, - enzyme_const, - y, - enzyme_const, - yp, - enzyme_dup, - wb, - output, // Seed: column var_i of the identity - enzyme_const, - ws, - enzyme_dupnoneed, - (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) - d_output); // Column var_i of the Jacobian + __enzyme_fwddiff( + (void*) ModelWrapper::eval, + enzyme_const, + model, + enzyme_const, + y, + enzyme_const, + yp, + enzyme_dup, + wb, + output, // Seed: column var_i of the identity + enzyme_const, + ws, + enzyme_dupnoneed, + (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) + d_output + ); // Column var_i of the Jacobian } } } diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DfDws.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DfDws.hpp index a3f4cb0345..fac2752a13 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DfDws.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DfDws.hpp @@ -45,56 +45,64 @@ namespace GridKit * @param[out] vals - Values * @param[out] nnz - Number of nonzeros */ - static void eval(ModelT* model, - const size_t n_res, - const size_t n_var, - const IdxT* res_indices, - const IdxT* var_indices, - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - const ScalarT* ws, - IdxT* rows, - IdxT* cols, - RealT* vals, - IdxT& nnz) + static void eval( + ModelT* model, + const size_t n_res, + const size_t n_var, + const IdxT* res_indices, + const IdxT* var_indices, + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + const ScalarT* ws, + IdxT* rows, + IdxT* cols, + RealT* vals, + IdxT& nnz + ) { if (n_res > 0 && n_var > 0) { for (size_t var_i = 0; var_i < n_var; ++var_i) { // Sparse storage. @see LowerSparseStorage.hpp - ScalarT* output = __enzyme_todense((void*) ident_load, - (void*) ident_store, - var_i); - ScalarT* d_output = __enzyme_todense((void*) sparse_load, - (void*) sparse_store, - var_i, - 1.0, // value scaling - res_indices, - var_indices, - rows, - cols, - vals, - &nnz); + ScalarT* output = __enzyme_todense( + (void*) ident_load, + (void*) ident_store, + var_i + ); + ScalarT* d_output = __enzyme_todense( + (void*) sparse_load, + (void*) sparse_store, + var_i, + 1.0, // value scaling + res_indices, + var_indices, + rows, + cols, + vals, + &nnz + ); // Core automatic differentiation intrinsic that will be replaced by a derivative // The dummy primal pointer is safe only while residuals never read back their output - __enzyme_fwddiff((void*) ModelWrapper::eval, - enzyme_const, - model, - enzyme_const, - y, - enzyme_const, - yp, - enzyme_const, - wb, - enzyme_dup, - ws, - output, // Seed: column var_i of the identity - enzyme_dupnoneed, - (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) - d_output); // Column var_i of the Jacobian + __enzyme_fwddiff( + (void*) ModelWrapper::eval, + enzyme_const, + model, + enzyme_const, + y, + enzyme_const, + yp, + enzyme_const, + wb, + enzyme_dup, + ws, + output, // Seed: column var_i of the identity + enzyme_dupnoneed, + (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) + d_output + ); // Column var_i of the Jacobian } } } diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DfDx.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DfDx.hpp index 4d8cbf3eaa..b14dab6fe2 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DfDx.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DfDx.hpp @@ -37,12 +37,14 @@ namespace GridKit std::fill_n(gradient, WrapperT::NUM_INPUTS, 0.0); - __enzyme_autodiff((void*) WrapperT::template eval, - enzyme_const, - model, - enzyme_dup, - x, - gradient); + __enzyme_autodiff( + (void*) WrapperT::template eval, + enzyme_const, + model, + enzyme_dup, + x, + gradient + ); } }; } // namespace Sparse diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DfDy.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DfDy.hpp index 19051d69c0..433f8a6af1 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DfDy.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DfDy.hpp @@ -44,53 +44,61 @@ namespace GridKit * @param[out] vals - Values * @param[out] nnz - Number of nonzeros */ - static void eval(ModelT* model, - const size_t n_res, - const size_t n_var, - const IdxT* res_indices, - const IdxT* var_indices, - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - IdxT* rows, - IdxT* cols, - RealT* vals, - IdxT& nnz) + static void eval( + ModelT* model, + const size_t n_res, + const size_t n_var, + const IdxT* res_indices, + const IdxT* var_indices, + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + IdxT* rows, + IdxT* cols, + RealT* vals, + IdxT& nnz + ) { if (n_res > 0 && n_var > 0) { for (size_t var_i = 0; var_i < n_var; ++var_i) { // Sparse storage. @see LowerSparseStorage.hpp - ScalarT* output = __enzyme_todense((void*) ident_load, - (void*) ident_store, - var_i); - ScalarT* d_output = __enzyme_todense((void*) sparse_load, - (void*) sparse_store, - var_i, - 1.0, // value scaling - res_indices, - var_indices, - rows, - cols, - vals, - &nnz); + ScalarT* output = __enzyme_todense( + (void*) ident_load, + (void*) ident_store, + var_i + ); + ScalarT* d_output = __enzyme_todense( + (void*) sparse_load, + (void*) sparse_store, + var_i, + 1.0, // value scaling + res_indices, + var_indices, + rows, + cols, + vals, + &nnz + ); // Core automatic differentiation intrinsic that will be replaced by a derivative // The dummy primal pointer is safe only while residuals never read back their output - __enzyme_fwddiff((void*) ModelWrapper::eval, - enzyme_const, - model, - enzyme_dup, - y, - output, // Seed: column var_i of the identity - enzyme_const, - yp, - enzyme_const, - wb, - enzyme_dupnoneed, - (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) - d_output); // Column var_i of the Jacobian + __enzyme_fwddiff( + (void*) ModelWrapper::eval, + enzyme_const, + model, + enzyme_dup, + y, + output, // Seed: column var_i of the identity + enzyme_const, + yp, + enzyme_const, + wb, + enzyme_dupnoneed, + (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) + d_output + ); // Column var_i of the Jacobian } } } @@ -110,56 +118,64 @@ namespace GridKit * @param[out] vals - Values * @param[out] nnz - Number of nonzeros */ - static void eval(ModelT* model, - const size_t n_res, - const size_t n_var, - const IdxT* res_indices, - const IdxT* var_indices, - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - const ScalarT* ws, - IdxT* rows, - IdxT* cols, - RealT* vals, - IdxT& nnz) + static void eval( + ModelT* model, + const size_t n_res, + const size_t n_var, + const IdxT* res_indices, + const IdxT* var_indices, + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + const ScalarT* ws, + IdxT* rows, + IdxT* cols, + RealT* vals, + IdxT& nnz + ) { if (n_res > 0 && n_var > 0) { for (size_t var_i = 0; var_i < n_var; ++var_i) { // Sparse storage. @see LowerSparseStorage.hpp - ScalarT* output = __enzyme_todense((void*) ident_load, - (void*) ident_store, - var_i); - ScalarT* d_output = __enzyme_todense((void*) sparse_load, - (void*) sparse_store, - var_i, - 1.0, // value scaling - res_indices, - var_indices, - rows, - cols, - vals, - &nnz); + ScalarT* output = __enzyme_todense( + (void*) ident_load, + (void*) ident_store, + var_i + ); + ScalarT* d_output = __enzyme_todense( + (void*) sparse_load, + (void*) sparse_store, + var_i, + 1.0, // value scaling + res_indices, + var_indices, + rows, + cols, + vals, + &nnz + ); // Core automatic differentiation intrinsic that will be replaced by a derivative // The dummy primal pointer is safe only while residuals never read back their output - __enzyme_fwddiff((void*) ModelWrapper::eval, - enzyme_const, - model, - enzyme_dup, - y, - output, // Seed: column var_i of the identity - enzyme_const, - yp, - enzyme_const, - wb, - enzyme_const, - ws, - enzyme_dupnoneed, - (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) - d_output); // Column var_i of the Jacobian + __enzyme_fwddiff( + (void*) ModelWrapper::eval, + enzyme_const, + model, + enzyme_dup, + y, + output, // Seed: column var_i of the identity + enzyme_const, + yp, + enzyme_const, + wb, + enzyme_const, + ws, + enzyme_dupnoneed, + (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) + d_output + ); // Column var_i of the Jacobian } } } diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DfDyp.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DfDyp.hpp index b7505800fe..56bd56c1e5 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DfDyp.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DfDyp.hpp @@ -45,54 +45,62 @@ namespace GridKit * @param[out] vals - Values * @param[out] nnz - Number of nonzeros */ - static void eval(ModelT* model, - size_t n_res, - size_t n_var, - const IdxT* res_indices, - const IdxT* var_indices, - ScalarT* y, - ScalarT* yp, - ScalarT* wb, - RealT alpha, - IdxT* rows, - IdxT* cols, - RealT* vals, - IdxT& nnz) + static void eval( + ModelT* model, + size_t n_res, + size_t n_var, + const IdxT* res_indices, + const IdxT* var_indices, + ScalarT* y, + ScalarT* yp, + ScalarT* wb, + RealT alpha, + IdxT* rows, + IdxT* cols, + RealT* vals, + IdxT& nnz + ) { if (n_res > 0 && n_var > 0) { for (size_t var_i = 0; var_i < n_var; ++var_i) { // Sparse storage. @see LowerSparseStorage.hpp - ScalarT* output = __enzyme_todense((void*) ident_load, - (void*) ident_store, - var_i); - ScalarT* d_output = __enzyme_todense((void*) sparse_load, - (void*) sparse_store, - var_i, - alpha, // value scaling - res_indices, - var_indices, - rows, - cols, - vals, - &nnz); + ScalarT* output = __enzyme_todense( + (void*) ident_load, + (void*) ident_store, + var_i + ); + ScalarT* d_output = __enzyme_todense( + (void*) sparse_load, + (void*) sparse_store, + var_i, + alpha, // value scaling + res_indices, + var_indices, + rows, + cols, + vals, + &nnz + ); // Core automatic differentiation intrinsic that will be replaced by a derivative // The dummy primal pointer is safe only while residuals never read back their output - __enzyme_fwddiff((void*) ModelWrapper::eval, - enzyme_const, - model, - enzyme_const, - y, - enzyme_dup, - yp, - output, // Seed: column var_i of the identity - enzyme_const, - wb, - enzyme_dupnoneed, - (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) - d_output); // Column var_i of the Jacobian + __enzyme_fwddiff( + (void*) ModelWrapper::eval, + enzyme_const, + model, + enzyme_const, + y, + enzyme_dup, + yp, + output, // Seed: column var_i of the identity + enzyme_const, + wb, + enzyme_dupnoneed, + (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) + d_output + ); // Column var_i of the Jacobian } } } @@ -113,57 +121,65 @@ namespace GridKit * @param[out] vals - Values * @param[out] nnz - Number of nonzeros */ - static void eval(ModelT* model, - size_t n_res, - size_t n_var, - const IdxT* res_indices, - const IdxT* var_indices, - ScalarT* y, - ScalarT* yp, - ScalarT* wb, - ScalarT* ws, - RealT alpha, - IdxT* rows, - IdxT* cols, - RealT* vals, - IdxT& nnz) + static void eval( + ModelT* model, + size_t n_res, + size_t n_var, + const IdxT* res_indices, + const IdxT* var_indices, + ScalarT* y, + ScalarT* yp, + ScalarT* wb, + ScalarT* ws, + RealT alpha, + IdxT* rows, + IdxT* cols, + RealT* vals, + IdxT& nnz + ) { if (n_res > 0 && n_var > 0) { for (size_t var_i = 0; var_i < n_var; ++var_i) { // Sparse storage. @see LowerSparseStorage.hpp - ScalarT* output = __enzyme_todense((void*) ident_load, - (void*) ident_store, - var_i); - ScalarT* d_output = __enzyme_todense((void*) sparse_load, - (void*) sparse_store, - var_i, - alpha, // value scaling - res_indices, - var_indices, - rows, - cols, - vals, - &nnz); + ScalarT* output = __enzyme_todense( + (void*) ident_load, + (void*) ident_store, + var_i + ); + ScalarT* d_output = __enzyme_todense( + (void*) sparse_load, + (void*) sparse_store, + var_i, + alpha, // value scaling + res_indices, + var_indices, + rows, + cols, + vals, + &nnz + ); // Core automatic differentiation intrinsic that will be replaced by a derivative // The dummy primal pointer is safe only while residuals never read back their output - __enzyme_fwddiff((void*) ModelWrapper::eval, - enzyme_const, - model, - enzyme_const, - y, - enzyme_dup, - yp, - output, // Seed: column var_i of the identity - enzyme_const, - wb, - enzyme_const, - ws, - enzyme_dupnoneed, - (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) - d_output); // Column var_i of the Jacobian + __enzyme_fwddiff( + (void*) ModelWrapper::eval, + enzyme_const, + model, + enzyme_const, + y, + enzyme_dup, + yp, + output, // Seed: column var_i of the identity + enzyme_const, + wb, + enzyme_const, + ws, + enzyme_dupnoneed, + (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) + d_output + ); // Column var_i of the Jacobian } } } diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DgDx.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DgDx.hpp index df35b294ae..a9675a87ae 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DgDx.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DgDx.hpp @@ -39,15 +39,17 @@ namespace GridKit * @param[out] nnz - Number of nonzeros */ template - static void eval(const ModelT* model, - const size_t n_var, - const IdxT* row_indices, - const IdxT* col_indices, - const ScalarT* x, - IdxT* rows, - IdxT* cols, - ScalarT* vals, - IdxT& nnz) + static void eval( + const ModelT* model, + const size_t n_var, + const IdxT* row_indices, + const IdxT* col_indices, + const ScalarT* x, + IdxT* rows, + IdxT* cols, + ScalarT* vals, + IdxT& nnz + ) { using WrapperT = ModelWrapper; @@ -55,29 +57,35 @@ namespace GridKit for (size_t var_i = 0; var_i < n_var; ++var_i) { // Sparse storage. @see LowerSparseStorage.hpp - ScalarT* seed = __enzyme_todense((void*) ident_load, - (void*) ident_store, - var_i); - ScalarT* dg = __enzyme_todense((void*) sparse_load, - (void*) sparse_store, - var_i, - 1.0, // value scaling - row_indices, - col_indices, - rows, - cols, - vals, - &nnz); + ScalarT* seed = __enzyme_todense( + (void*) ident_load, + (void*) ident_store, + var_i + ); + ScalarT* dg = __enzyme_todense( + (void*) sparse_load, + (void*) sparse_store, + var_i, + 1.0, // value scaling + row_indices, + col_indices, + rows, + cols, + vals, + &nnz + ); - __enzyme_fwddiff((void*) WrapperT::template eval, - enzyme_const, - model, - enzyme_dup, - x, - seed, - enzyme_dupnoneed, - g.data(), - dg); + __enzyme_fwddiff( + (void*) WrapperT::template eval, + enzyme_const, + model, + enzyme_dup, + x, + seed, + enzyme_dupnoneed, + g.data(), + dg + ); } } }; diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DhDwb.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DhDwb.hpp index 93d5048e75..6a0ff59bf4 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DhDwb.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DhDwb.hpp @@ -44,53 +44,61 @@ namespace GridKit * @param[out] vals - Values * @param[out] nnz - Number of nonzeros */ - static void eval(ModelT* model, - const size_t n_res, - const size_t n_var, - const IdxT* res_indices, - const IdxT* var_indices, - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - IdxT* rows, - IdxT* cols, - RealT* vals, - IdxT& nnz) + static void eval( + ModelT* model, + const size_t n_res, + const size_t n_var, + const IdxT* res_indices, + const IdxT* var_indices, + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + IdxT* rows, + IdxT* cols, + RealT* vals, + IdxT& nnz + ) { if (n_res > 0 && n_var > 0) { for (size_t var_i = 0; var_i < n_var; ++var_i) { // Sparse storage. @see LowerSparseStorage.hpp - ScalarT* output = __enzyme_todense((void*) ident_load, - (void*) ident_store, - var_i); - ScalarT* d_output = __enzyme_todense((void*) sparse_load, - (void*) sparse_store, - var_i, - 1.0, // value scaling - res_indices, - var_indices, - rows, - cols, - vals, - &nnz); + ScalarT* output = __enzyme_todense( + (void*) ident_load, + (void*) ident_store, + var_i + ); + ScalarT* d_output = __enzyme_todense( + (void*) sparse_load, + (void*) sparse_store, + var_i, + 1.0, // value scaling + res_indices, + var_indices, + rows, + cols, + vals, + &nnz + ); // Core automatic differentiation intrinsic that will be replaced by a derivative // The dummy primal pointer is safe only while residuals never read back their output - __enzyme_fwddiff((void*) ModelWrapper::eval, - enzyme_const, - model, - enzyme_const, - y, - enzyme_const, - yp, - enzyme_dup, - wb, - output, // Seed: column var_i of the identity - enzyme_dupnoneed, - (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) - d_output); // Column var_i of the Jacobian + __enzyme_fwddiff( + (void*) ModelWrapper::eval, + enzyme_const, + model, + enzyme_const, + y, + enzyme_const, + yp, + enzyme_dup, + wb, + output, // Seed: column var_i of the identity + enzyme_dupnoneed, + (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) + d_output + ); // Column var_i of the Jacobian } } } diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DhDy.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DhDy.hpp index da7cd2b876..4dadb5f268 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DhDy.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DhDy.hpp @@ -44,53 +44,61 @@ namespace GridKit * @param[out] vals - Values * @param[out] nnz - Number of nonzeros */ - static void eval(ModelT* model, - const size_t n_res, - const size_t n_var, - const IdxT* res_indices, - const IdxT* var_indices, - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - IdxT* rows, - IdxT* cols, - RealT* vals, - IdxT& nnz) + static void eval( + ModelT* model, + const size_t n_res, + const size_t n_var, + const IdxT* res_indices, + const IdxT* var_indices, + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + IdxT* rows, + IdxT* cols, + RealT* vals, + IdxT& nnz + ) { if (n_res > 0 && n_var > 0) { for (size_t var_i = 0; var_i < n_var; ++var_i) { // Sparse storage. @see LowerSparseStorage.hpp - ScalarT* output = __enzyme_todense((void*) ident_load, - (void*) ident_store, - var_i); - ScalarT* d_output = __enzyme_todense((void*) sparse_load, - (void*) sparse_store, - var_i, - 1.0, // value scaling - res_indices, - var_indices, - rows, - cols, - vals, - &nnz); + ScalarT* output = __enzyme_todense( + (void*) ident_load, + (void*) ident_store, + var_i + ); + ScalarT* d_output = __enzyme_todense( + (void*) sparse_load, + (void*) sparse_store, + var_i, + 1.0, // value scaling + res_indices, + var_indices, + rows, + cols, + vals, + &nnz + ); // Core automatic differentiation intrinsic that will be replaced by a derivative // The dummy primal pointer is safe only while residuals never read back their output - __enzyme_fwddiff((void*) ModelWrapper::eval, - enzyme_const, - model, - enzyme_dup, - y, - output, // Seed: column var_i of the identity - enzyme_const, - yp, - enzyme_const, - wb, - enzyme_dupnoneed, - (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) - d_output); // Column var_i of the Jacobian + __enzyme_fwddiff( + (void*) ModelWrapper::eval, + enzyme_const, + model, + enzyme_dup, + y, + output, // Seed: column var_i of the identity + enzyme_const, + yp, + enzyme_const, + wb, + enzyme_dupnoneed, + (ScalarT*) 0x1, // Unneeded primal residual (dummy pointer) + d_output + ); // Column var_i of the Jacobian } } } diff --git a/GridKit/AutomaticDifferentiation/Enzyme/LowerSparseStorage.hpp b/GridKit/AutomaticDifferentiation/Enzyme/LowerSparseStorage.hpp index a49c85e7e4..7f5ea89210 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/LowerSparseStorage.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/LowerSparseStorage.hpp @@ -46,17 +46,19 @@ namespace GridKit * @param[in,out] vals - buffer where val will be stored * @param[in,out] nnz - number of nonzeros */ - [[maybe_unused]] __attribute__((enzyme_sparse_accumulate)) static void inner_store_float_size_t( - size_t row, - size_t col, - float val, - float scaling, - const size_t* row_indices, - const size_t* col_indices, - size_t* rows, - size_t* cols, - float* vals, - size_t& nnz) + [[maybe_unused]] __attribute__((enzyme_sparse_accumulate)) static void + inner_store_float_size_t( + size_t row, + size_t col, + float val, + float scaling, + const size_t* row_indices, + const size_t* col_indices, + size_t* rows, + size_t* cols, + float* vals, + size_t& nnz + ) { const auto row_mapped = row_indices[static_cast(row)]; const auto col_mapped = col_indices[static_cast(col)]; @@ -85,17 +87,19 @@ namespace GridKit * @param[in,out] vals - buffer where val will be stored * @param[in,out] nnz - number of nonzeros */ - [[maybe_unused]] __attribute__((enzyme_sparse_accumulate)) static void inner_store_float_long_int( - long int row, - long int col, - float val, - float scaling, - const long int* row_indices, - const long int* col_indices, - long int* rows, - long int* cols, - float* vals, - long int& nnz) + [[maybe_unused]] __attribute__((enzyme_sparse_accumulate)) static void + inner_store_float_long_int( + long int row, + long int col, + float val, + float scaling, + const long int* row_indices, + const long int* col_indices, + long int* rows, + long int* cols, + float* vals, + long int& nnz + ) { const auto row_mapped = row_indices[static_cast(row)]; const auto col_mapped = col_indices[static_cast(col)]; @@ -124,17 +128,19 @@ namespace GridKit * @param[in,out] vals - buffer where val will be stored * @param[in,out] nnz - number of nonzeros */ - [[maybe_unused]] __attribute__((enzyme_sparse_accumulate)) static void inner_store_double_size_t( - size_t row, - size_t col, - double val, - double scaling, - const size_t* row_indices, - const size_t* col_indices, - size_t* rows, - size_t* cols, - double* vals, - size_t& nnz) + [[maybe_unused]] __attribute__((enzyme_sparse_accumulate)) static void + inner_store_double_size_t( + size_t row, + size_t col, + double val, + double scaling, + const size_t* row_indices, + const size_t* col_indices, + size_t* rows, + size_t* cols, + double* vals, + size_t& nnz + ) { const auto row_mapped = row_indices[static_cast(row)]; const auto col_mapped = col_indices[static_cast(col)]; @@ -163,17 +169,19 @@ namespace GridKit * @param[in,out] vals - buffer where val will be stored * @param[in,out] nnz - number of nonzeros */ - [[maybe_unused]] __attribute__((enzyme_sparse_accumulate)) static void inner_store_double_long_int( - long int row, - long int col, - double val, - double scaling, - const long int* row_indices, - const long int* col_indices, - long int* rows, - long int* cols, - double* vals, - long int& nnz) + [[maybe_unused]] __attribute__((enzyme_sparse_accumulate)) static void + inner_store_double_long_int( + long int row, + long int col, + double val, + double scaling, + const long int* row_indices, + const long int* col_indices, + long int* rows, + long int* cols, + double* vals, + long int& nnz + ) { const auto row_mapped = row_indices[static_cast(row)]; const auto col_mapped = col_indices[static_cast(col)]; @@ -207,16 +215,17 @@ namespace GridKit */ template __attribute__((always_inline)) static void sparse_store( - ScalarT val, - IdxT row, - IdxT col, - ScalarT scaling, - const IdxT* row_indices, - const IdxT* col_indices, - IdxT* rows, - IdxT* cols, - ScalarT* vals, - IdxT* nnz) + ScalarT val, + IdxT row, + IdxT col, + ScalarT scaling, + const IdxT* row_indices, + const IdxT* col_indices, + IdxT* rows, + IdxT* cols, + ScalarT* vals, + IdxT* nnz + ) { if (val == 0.0) return; diff --git a/GridKit/AutomaticDifferentiation/Enzyme/ModelWrappers.hpp b/GridKit/AutomaticDifferentiation/Enzyme/ModelWrappers.hpp index 2638838bbd..6c3a876924 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/ModelWrappers.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/ModelWrappers.hpp @@ -63,11 +63,13 @@ namespace GridKit * @param[in] wb - Bus variables * @param[out] f - Internal residual */ - static void eval(ModelT* model, - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - ScalarT* f) + static void eval( + ModelT* model, + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + ScalarT* f + ) { model->evaluateInternalResidual(y, yp, wb, f); } @@ -90,12 +92,14 @@ namespace GridKit * @param[in] ws - Signal variables * @param[out] f - Internal residual */ - static void eval(ModelT* model, - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - const ScalarT* ws, - ScalarT* f) + static void eval( + ModelT* model, + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + const ScalarT* ws, + ScalarT* f + ) { model->evaluateInternalResidual(y, yp, wb, ws, f); } @@ -117,11 +121,13 @@ namespace GridKit * @param[in] wb - Bus variables * @param[out] h - Bus residual */ - static void eval(ModelT* model, - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - ScalarT* h) + static void eval( + ModelT* model, + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + ScalarT* h + ) { model->evaluateBusResidual(y, yp, wb, h); } @@ -143,11 +149,13 @@ namespace GridKit * @param[in] wb - Bus variables * @param[out] h - Bus residual */ - static void eval(ModelT* model, - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - ScalarT* h) + static void eval( + ModelT* model, + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + ScalarT* h + ) { model->evaluateBusResidual11(y, yp, wb, h); } @@ -169,11 +177,13 @@ namespace GridKit * @param[in] wb - Bus variables * @param[out] h - Bus residual */ - static void eval(ModelT* model, - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - ScalarT* h) + static void eval( + ModelT* model, + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + ScalarT* h + ) { model->evaluateBusResidual12(y, yp, wb, h); } @@ -196,11 +206,13 @@ namespace GridKit * @param[in] wb - Bus variables * @param[out] h - Bus residual */ - static void eval(ModelT* model, - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - ScalarT* h) + static void eval( + ModelT* model, + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + ScalarT* h + ) { model->evaluateBusResidual21(y, yp, wb, h); } @@ -222,11 +234,13 @@ namespace GridKit * @param[in] wb - Bus variables * @param[out] h - Bus residual */ - static void eval(ModelT* model, - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - ScalarT* h) + static void eval( + ModelT* model, + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + ScalarT* h + ) { model->evaluateBusResidual22(y, yp, wb, h); } diff --git a/GridKit/CoSim/CoSim.cpp b/GridKit/CoSim/CoSim.cpp index ee3e097c75..218f91b84a 100644 --- a/GridKit/CoSim/CoSim.cpp +++ b/GridKit/CoSim/CoSim.cpp @@ -102,15 +102,17 @@ namespace GridKit template detail::Channel::Channel( - Disposition disposition, - const std::string& endpoint, - int timeout_ms, - const std::atomic* state) + Disposition disposition, + const std::string& endpoint, + int timeout_ms, + const std::atomic* state + ) : context_(), socket_( - context_, - disposition == Disposition::SERVER ? zmq::socket_type::rep - : zmq::socket_type::req), + context_, + disposition == Disposition::SERVER ? zmq::socket_type::rep + : zmq::socket_type::req + ), timeout_ms_(timeout_ms), state_(state), can_send_(disposition == Disposition::CLIENT) @@ -118,7 +120,8 @@ namespace GridKit if (timeout_ms <= 0 || endpoint.empty()) { throw std::invalid_argument( - "co-simulation requires an endpoint and a positive timeout"); + "co-simulation requires an endpoint and a positive timeout" + ); } // bound socket cleanup @@ -140,7 +143,7 @@ namespace GridKit { if (state_ && state_->load(std::memory_order_relaxed) - == RunState::STOP_REQUESTED) + == RunState::STOP_REQUESTED) { throw Stopped{}; } @@ -148,9 +151,10 @@ namespace GridKit template void detail::Channel::wait( - short events, - const char* operation, - std::chrono::steady_clock::time_point deadline) + short events, + const char* operation, + std::chrono::steady_clock::time_point deadline + ) { using Clock = std::chrono::steady_clock; @@ -158,19 +162,22 @@ namespace GridKit { checkStop(); const auto remaining = - std::chrono::duration_cast( - deadline - Clock::now()); + std::chrono::duration_cast( + deadline - Clock::now() + ); if (remaining.count() <= 0) { throw std::runtime_error( - std::format("Co-simulation {} timed out", operation)); + std::format("Co-simulation {} timed out", operation) + ); } zmq::pollitem_t item{socket_.handle(), 0, events, 0}; try { zmq::poll( - &item, 1, std::min(remaining, std::chrono::milliseconds(25))); + &item, 1, std::min(remaining, std::chrono::milliseconds(25)) + ); } catch (const zmq::error_t& error) { @@ -190,7 +197,8 @@ namespace GridKit template void detail::Channel::send( - const MessageData& message) + const MessageData& message + ) { checkStop(); if (!can_send_) @@ -200,10 +208,11 @@ namespace GridKit validate(message); json wire = { - {"type", typeName(message.type)}, - {"session", message.session}, - {"time", message.time}, - {"signals", message.signals}}; + {"type", typeName(message.type)}, + {"session", message.session}, + {"time", message.time}, + {"signals", message.signals} + }; if (message.type == MessageType::INIT) { @@ -237,7 +246,8 @@ namespace GridKit if (can_send_) { throw std::logic_error( - "Co-simulation socket must send before receiving"); + "Co-simulation socket must send before receiving" + ); } zmq::message_t raw; @@ -280,7 +290,8 @@ namespace GridKit template MessageData detail::Channel::exchange( - const MessageData& request) + const MessageData& request + ) { send(request); auto reply = receive(); @@ -291,13 +302,14 @@ namespace GridKit } const bool final_signals = - request.type == MessageType::STEP && reply.type == MessageType::END; + request.type == MessageType::STEP && reply.type == MessageType::END; if ((!final_signals && reply.type != request.type) || reply.session != request.session || reply.time != request.time) { throw std::runtime_error( - "co-simulation acknowledgement has the wrong type, session or time"); + "co-simulation acknowledgement has the wrong type, session or time" + ); } return reply; @@ -341,7 +353,8 @@ namespace GridKit template void detail::Channel::fail( - const MessageData& message) noexcept + const MessageData& message + ) noexcept { Teardown teardown(*this); @@ -368,7 +381,8 @@ namespace GridKit template void detail::Channel::closePeer( - const MessageMetadata& last) noexcept + const MessageMetadata& last + ) noexcept { Teardown teardown(*this); @@ -401,7 +415,8 @@ namespace GridKit template void detail::Channel::finish( - const MessageData& reply) + const MessageData& reply + ) { send(reply); Teardown teardown(*this); @@ -417,10 +432,11 @@ namespace GridKit template CoSim::CoSim( - const std::string& address, - MessageStepFunction step, - MessageExtractFunction extract, - int timeout_ms) + const std::string& address, + MessageStepFunction step, + MessageExtractFunction extract, + int timeout_ms + ) : address_(address), step_(std::move(step)), extract_(std::move(extract)), @@ -429,22 +445,25 @@ namespace GridKit if (address.empty() || timeout_ms <= 0 || !step_ || !extract_) { throw std::invalid_argument( - "co-simulation requires an endpoint, callbacks and a positive timeout"); + "co-simulation requires an endpoint, callbacks and a positive timeout" + ); } } template CoSim::CoSim( - const std::string& address, - StepFunction step, - ExtractFunction extract, - int timeout_ms) + const std::string& address, + StepFunction step, + ExtractFunction extract, + int timeout_ms + ) : address_(address), timeout_ms_(timeout_ms) { if (address.empty() || timeout_ms <= 0 || !step || !extract) { throw std::invalid_argument( - "co-simulation requires an endpoint, callbacks and a positive timeout"); + "co-simulation requires an endpoint, callbacks and a positive timeout" + ); } step_ = [step = std::move(step)](const auto& message, const auto&) @@ -463,13 +482,15 @@ namespace GridKit { auto expected = detail::RunState::IDLE; if (!state_.compare_exchange_strong( - expected, - detail::RunState::RUNNING, - std::memory_order_acquire, - std::memory_order_relaxed)) + expected, + detail::RunState::RUNNING, + std::memory_order_acquire, + std::memory_order_relaxed + )) { throw std::logic_error( - "attempted to start a co-simulation while it was already running"); + "attempted to start a co-simulation while it was already running" + ); } // ensure the state is reset on scope exit @@ -484,7 +505,8 @@ namespace GridKit } guard{state_}; detail::Channel channel( - disposition, address_, timeout_ms_, &state_); + disposition, address_, timeout_ms_, &state_ + ); MessageMetadata current; struct Completed @@ -503,7 +525,8 @@ namespace GridKit if (message.type == MessageType::FAIL) { throw std::runtime_error( - "co-simulation client failed: " + message.error); + "co-simulation client failed: " + message.error + ); } if (message.type == MessageType::CLOSE) @@ -514,7 +537,7 @@ namespace GridKit return message; }; const MessageExchangeFunction exchange = - [&](const auto& message) + [&](const auto& message) { if constexpr (disposition == Disposition::SERVER) { @@ -532,7 +555,8 @@ namespace GridKit if (peer_finished) { throw std::runtime_error( - "co-simulation peer ended before the callback completed"); + "co-simulation peer ended before the callback completed" + ); } current = message; auto reply = channel.exchange(message); @@ -591,9 +615,9 @@ namespace GridKit { channel.closePeer(last_reply); return state_.load(std::memory_order_relaxed) - == detail::RunState::STOP_REQUESTED - ? RunResult::STOPPED - : RunResult::COMPLETED; + == detail::RunState::STOP_REQUESTED + ? RunResult::STOPPED + : RunResult::COMPLETED; } } } diff --git a/GridKit/CoSim/CoSim.hpp b/GridKit/CoSim/CoSim.hpp index ee025bb1df..83c4eee19a 100644 --- a/GridKit/CoSim/CoSim.hpp +++ b/GridKit/CoSim/CoSim.hpp @@ -30,20 +30,23 @@ namespace GridKit class CoSim { static_assert( - std::atomic::is_always_lock_free, - "lock-free atomics for std::uint8_t are required for co-simulation"); + std::atomic::is_always_lock_free, + "lock-free atomics for std::uint8_t are required for co-simulation" + ); public: CoSim( - const std::string& address, - StepFunction step, - ExtractFunction extract, - int timeout_ms = 30000); + const std::string& address, + StepFunction step, + ExtractFunction extract, + int timeout_ms = 30000 + ); CoSim( - const std::string& address, - MessageStepFunction step, - MessageExtractFunction extract, - int timeout_ms = 30000); + const std::string& address, + MessageStepFunction step, + MessageExtractFunction extract, + int timeout_ms = 30000 + ); CoSim(const CoSim&) = delete; CoSim& operator=(const CoSim&) = delete; @@ -55,7 +58,8 @@ namespace GridKit { auto expected = detail::RunState::RUNNING; state_.compare_exchange_strong( - expected, detail::RunState::STOP_REQUESTED, std::memory_order_relaxed); + expected, detail::RunState::STOP_REQUESTED, std::memory_order_relaxed + ); } /// Check if the co-simulation is running. diff --git a/GridKit/CoSim/CoSimInternal.hpp b/GridKit/CoSim/CoSimInternal.hpp index d19104a506..0ec4275c40 100644 --- a/GridKit/CoSim/CoSimInternal.hpp +++ b/GridKit/CoSim/CoSimInternal.hpp @@ -37,10 +37,11 @@ namespace GridKit { public: Channel( - Disposition disposition, - const std::string& endpoint, - int timeout_ms = 30000, - const std::atomic* state = nullptr); + Disposition disposition, + const std::string& endpoint, + int timeout_ms = 30000, + const std::atomic* state = nullptr + ); Channel(const Channel&) = delete; Channel& operator=(const Channel&) = delete; @@ -52,7 +53,8 @@ namespace GridKit /// Exchange co-simulation messages with the peer. MessageData exchange( - const MessageData& request); + const MessageData& request + ); /// Notify the peer of failure. void fail(const MessageData& message) noexcept; @@ -73,9 +75,10 @@ namespace GridKit /// Wait for a ZeroMQ event. void wait( - short events, - const char* operation, - std::chrono::steady_clock::time_point deadline); + short events, + const char* operation, + std::chrono::steady_clock::time_point deadline + ); /// Check if the simulation has been stopped. void checkStop() const; diff --git a/GridKit/CoSim/Message.hpp b/GridKit/CoSim/Message.hpp index 585e220e2a..5d87d93d3e 100644 --- a/GridKit/CoSim/Message.hpp +++ b/GridKit/CoSim/Message.hpp @@ -81,7 +81,8 @@ namespace GridKit MessageMetadata() = default; MessageMetadata( - MessageType type, std::uint64_t session, double time = 0.0) + MessageType type, std::uint64_t session, double time = 0.0 + ) : type(type), session(session), time(time) { } @@ -117,19 +118,20 @@ namespace GridKit /// server, this is a reply to the current request and the next request. template using MessageExchangeFunction = - std::function(const MessageData&)>; + std::function(const MessageData&)>; /// Apply an incoming message and control simulation continuity. template using MessageStepFunction = std::function&, - const MessageExchangeFunction&)>; + const MessageData&, + const MessageExchangeFunction& + )>; /// Produce the next outgoing message, optionally exchanging intermediate /// messages first. template using MessageExtractFunction = std::function< - MessageData(const MessageExchangeFunction&)>; + MessageData(const MessageExchangeFunction&)>; /// Result of a run. enum class RunResult diff --git a/GridKit/CommonMath.hpp b/GridKit/CommonMath.hpp index 8f9f8c5cf4..71232ea8e6 100644 --- a/GridKit/CommonMath.hpp +++ b/GridKit/CommonMath.hpp @@ -102,8 +102,8 @@ namespace GridKit */ template __attribute__((always_inline)) inline auto max( - const LeftT x, - const RightT y) + const LeftT x, const RightT y + ) { return y + ramp(x - y); } @@ -129,8 +129,8 @@ namespace GridKit */ template __attribute__((always_inline)) inline auto min( - const LeftT x, - const RightT y) + const LeftT x, const RightT y + ) { return x - ramp(x - y); } @@ -153,9 +153,8 @@ namespace GridKit */ template __attribute__((always_inline)) inline auto clamp( - const ScalarT x, - const LowerT lower, - const UpperT upper) + const ScalarT x, const LowerT lower, const UpperT upper + ) { assert(lower <= upper); return lower + ramp(x - lower) - ramp(x - upper); @@ -177,9 +176,8 @@ namespace GridKit */ template __attribute__((always_inline)) inline ScalarT deadband1( - const ScalarT x, - const RealT lower, - const RealT upper) + const ScalarT x, const RealT lower, const RealT upper + ) { assert(lower <= upper); return x * (sigmoid(lower - x) + sigmoid(x - upper)); @@ -201,9 +199,8 @@ namespace GridKit */ template __attribute__((always_inline)) inline ScalarT deadband2( - const ScalarT x, - const RealT lower, - const RealT upper) + const ScalarT x, const RealT lower, const RealT upper + ) { assert(lower <= upper); return ramp(x - upper) - ramp(-(x - lower)); @@ -223,8 +220,8 @@ namespace GridKit */ template __attribute__((always_inline)) inline ScalarT slew( - const ScalarT f, - const RealT rate) + const ScalarT f, const RealT rate + ) { assert(rate >= ZERO); return clamp(f, -rate, rate); @@ -248,10 +245,8 @@ namespace GridKit */ template __attribute__((always_inline)) inline ScalarT linseg( - const ScalarT x, - const RealT lower, - const RealT upper, - const RealT height) + const ScalarT x, const RealT lower, const RealT upper, const RealT height + ) { assert(lower < upper); return height / (upper - lower) * (ramp(x - lower) - ramp(x - upper)); @@ -269,8 +264,8 @@ namespace GridKit */ template __attribute__((always_inline)) inline ScalarT above( - const ScalarT x, - const RealT limit_min) + const ScalarT x, const RealT limit_min + ) { return sigmoid(x - limit_min); } @@ -287,8 +282,8 @@ namespace GridKit */ template __attribute__((always_inline)) inline ScalarT below( - const ScalarT x, - const RealT limit_max) + const ScalarT x, const RealT limit_max + ) { return sigmoid(limit_max - x); } @@ -306,9 +301,8 @@ namespace GridKit */ template __attribute__((always_inline)) inline ScalarT inside( - const ScalarT x, - const RealT limit_min, - const RealT limit_max) + const ScalarT x, const RealT limit_min, const RealT limit_max + ) { assert(limit_min <= limit_max); return above(x, limit_min) + below(x, limit_max) - ONE; @@ -327,9 +321,8 @@ namespace GridKit */ template __attribute__((always_inline)) inline ScalarT outside( - const ScalarT x, - const RealT limit_min, - const RealT limit_max) + const ScalarT x, const RealT limit_min, const RealT limit_max + ) { assert(limit_min <= limit_max); return below(x, limit_min) + above(x, limit_max); @@ -350,10 +343,11 @@ namespace GridKit */ template __attribute__((always_inline)) inline ScalarT indicator( - const ScalarT x, - const ScalarT f, - const RealT limit_min, - const RealT limit_max) + const ScalarT x, + const ScalarT f, + const RealT limit_min, + const RealT limit_max + ) { assert(limit_min <= limit_max); @@ -384,10 +378,11 @@ namespace GridKit */ template __attribute__((always_inline)) inline ScalarT antiwindup( - const ScalarT x, - const ScalarT f, - const RealT limit_min, - const RealT limit_max) + const ScalarT x, + const ScalarT f, + const RealT limit_min, + const RealT limit_max + ) { return indicator(x, f, limit_min, limit_max) * f; } diff --git a/GridKit/LinearAlgebra/SparseMatrix/CooMatrix.cpp b/GridKit/LinearAlgebra/SparseMatrix/CooMatrix.cpp index c6722f8bce..2001ba9a3d 100644 --- a/GridKit/LinearAlgebra/SparseMatrix/CooMatrix.cpp +++ b/GridKit/LinearAlgebra/SparseMatrix/CooMatrix.cpp @@ -27,12 +27,8 @@ namespace GridKit * @param[in] nnz_ - number of non-zeros */ template - CooMatrix::CooMatrix(IdxT n, - IdxT m, - IdxT nnz) - : n_{n}, - m_{m}, - nnz_{nnz} + CooMatrix::CooMatrix(IdxT n, IdxT m, IdxT nnz) + : n_{n}, m_{m}, nnz_{nnz} { setNotUpdated(); @@ -65,14 +61,16 @@ namespace GridKit * @param[in] memspace_dst */ template - CooMatrix::CooMatrix(IdxT n, - IdxT m, - IdxT nnz_, - IdxT** rows, - IdxT** cols, - RealT** vals, - memory::MemorySpace memspace_src, - memory::MemorySpace memspace_dst) + CooMatrix::CooMatrix( + IdxT n, + IdxT m, + IdxT nnz_, + IdxT** rows, + IdxT** cols, + RealT** vals, + memory::MemorySpace memspace_src, + memory::MemorySpace memspace_dst + ) : CooMatrix(n, m, nnz_) { int control = -1; @@ -248,10 +246,12 @@ namespace GridKit * @return 0 if successful, 1 if not. */ template - int CooMatrix::setDataPointers(IdxT* row_data, - IdxT* col_data, - RealT* val_data, - memory::MemorySpace memspace) + int CooMatrix::setDataPointers( + IdxT* row_data, + IdxT* col_data, + RealT* val_data, + memory::MemorySpace memspace + ) { using namespace memory; diff --git a/GridKit/LinearAlgebra/SparseMatrix/CooMatrix.hpp b/GridKit/LinearAlgebra/SparseMatrix/CooMatrix.hpp index 904d063b90..2a66e34cdf 100644 --- a/GridKit/LinearAlgebra/SparseMatrix/CooMatrix.hpp +++ b/GridKit/LinearAlgebra/SparseMatrix/CooMatrix.hpp @@ -19,14 +19,16 @@ namespace GridKit CooMatrix(IdxT n, IdxT m, IdxT nnz); - CooMatrix(IdxT n, - IdxT m, - IdxT nnz, - IdxT** rows, - IdxT** cols, - RealT** vals, - memory::MemorySpace memspace_src = memory::HOST, - memory::MemorySpace memspace_dst = memory::HOST); + CooMatrix( + IdxT n, + IdxT m, + IdxT nnz, + IdxT** rows, + IdxT** cols, + RealT** vals, + memory::MemorySpace memspace_src = memory::HOST, + memory::MemorySpace memspace_dst = memory::HOST + ); ~CooMatrix(); @@ -42,10 +44,12 @@ namespace GridKit IdxT* getColData(memory::MemorySpace memspace = memory::HOST); RealT* getValues(memory::MemorySpace memspace = memory::HOST); - int setDataPointers(IdxT* row_data, - IdxT* col_data, - RealT* val_data, - memory::MemorySpace memspace); + int setDataPointers( + IdxT* row_data, + IdxT* col_data, + RealT* val_data, + memory::MemorySpace memspace + ); int destroyMatrixData(memory::MemorySpace memspace); diff --git a/GridKit/LinearAlgebra/SparseMatrix/CsrMatrix.cpp b/GridKit/LinearAlgebra/SparseMatrix/CsrMatrix.cpp index d97aae3aab..9afdd8d991 100644 --- a/GridKit/LinearAlgebra/SparseMatrix/CsrMatrix.cpp +++ b/GridKit/LinearAlgebra/SparseMatrix/CsrMatrix.cpp @@ -25,12 +25,8 @@ namespace GridKit * @param[in] nnz - number of non-zeros */ template - CsrMatrix::CsrMatrix(IdxT n, - IdxT m, - IdxT nnz) - : n_{n}, - m_{m}, - nnz_{nnz} + CsrMatrix::CsrMatrix(IdxT n, IdxT m, IdxT nnz) + : n_{n}, m_{m}, nnz_{nnz} { setNotUpdated(); @@ -63,14 +59,16 @@ namespace GridKit * @param[in] memspace_dst */ template - CsrMatrix::CsrMatrix(IdxT n, - IdxT m, - IdxT nnz, - IdxT** rows, - IdxT** cols, - RealT** vals, - memory::MemorySpace memspace_src, - memory::MemorySpace memspace_dst) + CsrMatrix::CsrMatrix( + IdxT n, + IdxT m, + IdxT nnz, + IdxT** rows, + IdxT** cols, + RealT** vals, + memory::MemorySpace memspace_src, + memory::MemorySpace memspace_dst + ) : CsrMatrix(n, m, nnz) { int control = -1; @@ -292,10 +290,12 @@ namespace GridKit * @return 0 if successful, 1 if not. */ template - int CsrMatrix::setDataPointers(IdxT* row_data, - IdxT* col_data, - RealT* val_data, - memory::MemorySpace memspace) + int CsrMatrix::setDataPointers( + IdxT* row_data, + IdxT* col_data, + RealT* val_data, + memory::MemorySpace memspace + ) { using namespace memory; @@ -408,9 +408,11 @@ namespace GridKit * @return 0 if successful, -1 if not. */ template - int CsrMatrix::copyValues(const RealT* new_vals, - memory::MemorySpace memspace_in, - memory::MemorySpace memspace_out) + int CsrMatrix::copyValues( + const RealT* new_vals, + memory::MemorySpace memspace_in, + memory::MemorySpace memspace_out + ) { IdxT nnz_current = nnz_; @@ -491,8 +493,9 @@ namespace GridKit * @return 0 if successful, -1 if not. */ template - int CsrMatrix::setValuesPointer(RealT* new_vals, - memory::MemorySpace memspace) + int CsrMatrix::setValuesPointer( + RealT* new_vals, memory::MemorySpace memspace + ) { using namespace memory; setNotUpdated(); @@ -576,11 +579,13 @@ namespace GridKit } template - int CsrMatrix::copyDataFrom(const IdxT* row_data, - const IdxT* col_data, - const RealT* val_data, - memory::MemorySpace memspace_in, - memory::MemorySpace memspace_out) + int CsrMatrix::copyDataFrom( + const IdxT* row_data, + const IdxT* col_data, + const RealT* val_data, + memory::MemorySpace memspace_in, + memory::MemorySpace memspace_out + ) { // four cases (for now) IdxT nnz_current = nnz_; @@ -673,12 +678,14 @@ namespace GridKit } template - int CsrMatrix::copyDataFrom(const IdxT* row_data, - const IdxT* col_data, - const RealT* val_data, - IdxT new_nnz, - memory::MemorySpace memspace_in, - memory::MemorySpace memspace_out) + int CsrMatrix::copyDataFrom( + const IdxT* row_data, + const IdxT* col_data, + const RealT* val_data, + IdxT new_nnz, + memory::MemorySpace memspace_in, + memory::MemorySpace memspace_out + ) { destroyMatrixData(memspace_out); nnz_ = new_nnz; diff --git a/GridKit/LinearAlgebra/SparseMatrix/CsrMatrix.hpp b/GridKit/LinearAlgebra/SparseMatrix/CsrMatrix.hpp index 74029a0da2..72dc630e0e 100644 --- a/GridKit/LinearAlgebra/SparseMatrix/CsrMatrix.hpp +++ b/GridKit/LinearAlgebra/SparseMatrix/CsrMatrix.hpp @@ -19,14 +19,16 @@ namespace GridKit CsrMatrix(IdxT n, IdxT m, IdxT nnz); - CsrMatrix(IdxT n, - IdxT m, - IdxT nnz, - IdxT** rows, - IdxT** cols, - RealT** vals, - memory::MemorySpace memspace_src = memory::HOST, - memory::MemorySpace memspace_dst = memory::HOST); + CsrMatrix( + IdxT n, + IdxT m, + IdxT nnz, + IdxT** rows, + IdxT** cols, + RealT** vals, + memory::MemorySpace memspace_src = memory::HOST, + memory::MemorySpace memspace_dst = memory::HOST + ); ~CsrMatrix(); @@ -42,23 +44,29 @@ namespace GridKit IdxT* getColData(memory::MemorySpace memspace = memory::HOST); RealT* getValues(memory::MemorySpace memspace = memory::HOST); - int copyDataFrom(const IdxT* row_data, - const IdxT* col_data, - const RealT* val_data, - memory::MemorySpace memspace_in, - memory::MemorySpace memspace_out); - int copyDataFrom(const IdxT* row_data, - const IdxT* col_data, - const RealT* val_data, - IdxT new_nnz, - memory::MemorySpace memspace_in, - memory::MemorySpace memspace_out); + int copyDataFrom( + const IdxT* row_data, + const IdxT* col_data, + const RealT* val_data, + memory::MemorySpace memspace_in, + memory::MemorySpace memspace_out + ); + int copyDataFrom( + const IdxT* row_data, + const IdxT* col_data, + const RealT* val_data, + IdxT new_nnz, + memory::MemorySpace memspace_in, + memory::MemorySpace memspace_out + ); int allocateMatrixData(memory::MemorySpace memspace); - int setDataPointers(IdxT* row_data, - IdxT* col_data, - RealT* val_data, - memory::MemorySpace memspace); + int setDataPointers( + IdxT* row_data, + IdxT* col_data, + RealT* val_data, + memory::MemorySpace memspace + ); int destroyMatrixData(memory::MemorySpace memspace); @@ -68,13 +76,14 @@ namespace GridKit // update Values just updates values; it allocates if necessary. // values have the same dimensions between different formats - int copyValues(const RealT* new_vals, - memory::MemorySpace memspace_in, - memory::MemorySpace memspace_out); + int copyValues( + const RealT* new_vals, + memory::MemorySpace memspace_in, + memory::MemorySpace memspace_out + ); // set new values just sets the pointer, use caution. - int setValuesPointer(RealT* new_vals, - memory::MemorySpace memspace); + int setValuesPointer(RealT* new_vals, memory::MemorySpace memspace); private: IdxT n_{0}; ///< number of rows diff --git a/GridKit/LinearAlgebra/Vector/Vector.cpp b/GridKit/LinearAlgebra/Vector/Vector.cpp index ab35e7d5fa..3fda79ab2a 100644 --- a/GridKit/LinearAlgebra/Vector/Vector.cpp +++ b/GridKit/LinearAlgebra/Vector/Vector.cpp @@ -215,9 +215,9 @@ namespace GridKit * @return 0 if successful, 1 otherwise. */ template - int Vector::setData(ScalarT* data, - IdxT size, - memory::MemorySpace memspace) + int Vector::setData( + ScalarT* data, IdxT size, memory::MemorySpace memspace + ) { if (data == nullptr && size != IdxT{}) { @@ -296,9 +296,11 @@ namespace GridKit * @return 0 if successful, 1 otherwise. */ template - int Vector::copyFromExternal(const ScalarT* source, - memory::MemorySpace memspaceSrc, - memory::MemorySpace memspaceDst) + int Vector::copyFromExternal( + const ScalarT* source, + memory::MemorySpace memspaceSrc, + memory::MemorySpace memspaceDst + ) { if (source == nullptr) { @@ -776,8 +778,10 @@ namespace GridKit template int Vector::resize(IdxT new_n_size) { - assert(owns_cpu_data_ && owns_gpu_data_ - && "Cannot resize if vector is not owning the data."); + assert( + owns_cpu_data_ && owns_gpu_data_ + && "Cannot resize if vector is not owning the data." + ); if (h_data_ == nullptr && d_data_ == nullptr) { diff --git a/GridKit/LinearAlgebra/Vector/Vector.hpp b/GridKit/LinearAlgebra/Vector/Vector.hpp index 13ae804662..8ab6ecb75c 100644 --- a/GridKit/LinearAlgebra/Vector/Vector.hpp +++ b/GridKit/LinearAlgebra/Vector/Vector.hpp @@ -79,12 +79,16 @@ namespace GridKit Vector& operator=(const Vector&) = delete; Vector& operator=(Vector&&) = delete; - int copyFromExternal(const ScalarT* source, - memory::MemorySpace memspaceIn = memory::HOST, - memory::MemorySpace memspaceOut = memory::HOST); - int copyFromExternal(const Vector& source, - memory::MemorySpace memspaceIn = memory::HOST, - memory::MemorySpace memspaceOut = memory::HOST); + int copyFromExternal( + const ScalarT* source, + memory::MemorySpace memspaceIn = memory::HOST, + memory::MemorySpace memspaceOut = memory::HOST + ); + int copyFromExternal( + const Vector& source, + memory::MemorySpace memspaceIn = memory::HOST, + memory::MemorySpace memspaceOut = memory::HOST + ); // TODO: in the future, we should consider making the `getData` family of // methods accept the memory space through a template parameter @@ -338,13 +342,17 @@ namespace GridKit int syncData(memory::MemorySpace memspaceOut = memory::HOST); int syncData(IdxT j, memory::MemorySpace memspaceOut = memory::HOST); int resize(IdxT new_n_current); - int copyToExternal(ScalarT* dest, - IdxT i, - memory::MemorySpace memspaceSrc = memory::HOST, - memory::MemorySpace memspaceDst = memory::HOST); - int copyToExternal(ScalarT* dest, - memory::MemorySpace memspaceSrc = memory::HOST, - memory::MemorySpace memspaceDst = memory::HOST); + int copyToExternal( + ScalarT* dest, + IdxT i, + memory::MemorySpace memspaceSrc = memory::HOST, + memory::MemorySpace memspaceDst = memory::HOST + ); + int copyToExternal( + ScalarT* dest, + memory::MemorySpace memspaceSrc = memory::HOST, + memory::MemorySpace memspaceDst = memory::HOST + ); private: [[gnu::always_inline]] diff --git a/GridKit/LinearAlgebra/Vector/VectorHandler.cpp b/GridKit/LinearAlgebra/Vector/VectorHandler.cpp index 008cb709c8..175f2b05fc 100644 --- a/GridKit/LinearAlgebra/Vector/VectorHandler.cpp +++ b/GridKit/LinearAlgebra/Vector/VectorHandler.cpp @@ -87,10 +87,12 @@ namespace GridKit * @param[in] memspace Memory space the operation is computed in (HOST or DEVICE) */ template - void VectorHandler::axpy(const ScalarT alpha, - Vector* x, - Vector* y, - memory::MemorySpace memspace) + void VectorHandler::axpy( + const ScalarT alpha, + Vector* x, + Vector* y, + memory::MemorySpace memspace + ) { switch (memspace) { @@ -124,14 +126,16 @@ namespace GridKit * of columns to use in matrix-vector product. */ template - void VectorHandler::gemv(char transpose, - IdxT k, - const ScalarT alpha, - const ScalarT beta, - Vector* V, - Vector* y, - Vector* x, - memory::MemorySpace memspace) + void VectorHandler::gemv( + char transpose, + IdxT k, + const ScalarT alpha, + const ScalarT beta, + Vector* V, + Vector* y, + Vector* x, + memory::MemorySpace memspace + ) { switch (memspace) { @@ -157,12 +161,14 @@ namespace GridKit * @pre _k_ > 0, _size_ > 0, _size_ = x->getSize() */ template - void VectorHandler::axpyMulti(IdxT size, - Vector* alpha, - IdxT k, - Vector* x, - Vector* y, - memory::MemorySpace memspace) + void VectorHandler::axpyMulti( + IdxT size, + Vector* alpha, + IdxT k, + Vector* x, + Vector* y, + memory::MemorySpace memspace + ) { assert(y->getSize() == x->getSize() && "Sizes of x and y must match!\n"); assert(alpha->getSize() == k && "Size of alpha must match k!\n"); @@ -194,12 +200,14 @@ namespace GridKit * @pre _res_ needs to be allocated to k x 2 size. */ template - void VectorHandler::dot2Multi(IdxT size, - Vector* V, - IdxT k, - Vector* x, - Vector* res, - memory::MemorySpace memspace) + void VectorHandler::dot2Multi( + IdxT size, + Vector* V, + IdxT k, + Vector* x, + Vector* res, + memory::MemorySpace memspace + ) { assert(x->getSize() == V->getSize() && "Sizes of V and x do not match!\n"); assert(res->getSize() == k && "Size of `res` must match k!\n"); @@ -249,10 +257,12 @@ namespace GridKit * @param[in] memspace - Memory space the operation is computed in (HOST or DEVICE) */ template - void VectorHandler::scal(Vector* diag, - Vector* vec, - IdxT diag_offset, - memory::MemorySpace memspace) + void VectorHandler::scal( + Vector* diag, + Vector* vec, + IdxT diag_offset, + memory::MemorySpace memspace + ) { switch (memspace) { diff --git a/GridKit/LinearAlgebra/Vector/VectorHandler.hpp b/GridKit/LinearAlgebra/Vector/VectorHandler.hpp index b718458c20..4be5ec11e2 100644 --- a/GridKit/LinearAlgebra/Vector/VectorHandler.hpp +++ b/GridKit/LinearAlgebra/Vector/VectorHandler.hpp @@ -29,10 +29,12 @@ namespace GridKit ~VectorHandler() = default; // y := alpha * x + y - void axpy(const ScalarT alpha, - Vector* x, - Vector* y, - memory::MemorySpace memspace); + void axpy( + const ScalarT alpha, + Vector* x, + Vector* y, + memory::MemorySpace memspace + ); // Dot product of two vectors ScalarT dot(Vector* x, Vector* y, memory::MemorySpace memspace); @@ -42,26 +44,32 @@ namespace GridKit // Scale vector by diagonal matrix represented as a vector (i.e., vec = diag*vec) void scal(Vector* diag, Vector* vec, memory::MemorySpace memspace); - void scal(Vector* diag, - Vector* vec, - IdxT diag_offset, - memory::MemorySpace memspace); + void scal( + Vector* diag, + Vector* vec, + IdxT diag_offset, + memory::MemorySpace memspace + ); // axpy for multivectors - void axpyMulti(IdxT size, - Vector* alpha, - IdxT k, - Vector* x, - Vector* y, - memory::MemorySpace memspace); + void axpyMulti( + IdxT size, + Vector* alpha, + IdxT k, + Vector* x, + Vector* y, + memory::MemorySpace memspace + ); // Dot product of two vectors with a multivector V - void dot2Multi(IdxT size, - Vector* V, - IdxT k, - Vector* x, - Vector* res, - memory::MemorySpace memspace); + void dot2Multi( + IdxT size, + Vector* V, + IdxT k, + Vector* x, + Vector* res, + memory::MemorySpace memspace + ); // Dense matrix-vector product. void gemv(char transpose, diff --git a/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.cpp b/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.cpp index cf6e12a31d..68826d1a38 100644 --- a/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.cpp +++ b/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.cpp @@ -120,13 +120,15 @@ namespace GridKit * x must equal k. */ template - void VectorHandlerCpu::gemv(char transpose, - IdxT k, - const ScalarT alpha, - const ScalarT beta, - Vector* V, - Vector* y, - Vector* x) + void VectorHandlerCpu::gemv( + char transpose, + IdxT k, + const ScalarT alpha, + const ScalarT beta, + Vector* V, + Vector* y, + Vector* x + ) { // x = beta*x + alpha*V*y OR x = beta*x + alpha*V^Ty const ScalarT* V_data = V->getData(memory::HOST); @@ -139,8 +141,10 @@ namespace GridKit switch (transpose) { case 'T': - assert((V->getSize() == y->getSize()) - && "gemv: Size mismatch! Size of V does not match size of y."); + assert( + (V->getSize() == y->getSize()) + && "gemv: Size mismatch! Size of V does not match size of y." + ); for (i = 0; i < k; ++i) { sum = beta * x_data[i]; @@ -156,8 +160,10 @@ namespace GridKit } break; case 'N': - assert((V->getSize() == x->getSize()) - && "gemv: Size mismatch! Size of V does not match size of x."); + assert( + (V->getSize() == x->getSize()) + && "gemv: Size mismatch! Size of V does not match size of x." + ); for (i = 0; i < n; ++i) { sum = beta * x_data[i]; @@ -190,11 +196,13 @@ namespace GridKit * @pre _k_ > 0, _size_ > 0, _size_ = x->getSize() */ template - void VectorHandlerCpu::axpyMulti(IdxT size, - Vector* alpha, - IdxT k, - Vector* x, - Vector* y) + void VectorHandlerCpu::axpyMulti( + IdxT size, + Vector* alpha, + IdxT k, + Vector* x, + Vector* y + ) { ScalarT* alpha_data = alpha->getData(memory::HOST); ScalarT* y_data = y->getData(memory::HOST); @@ -228,11 +236,13 @@ namespace GridKit * @pre _size_ > 0, _k_ > 0, size = x->getSize(), _res_ needs to be allocated */ template - void VectorHandlerCpu::dot2Multi(IdxT size, - Vector* V, - IdxT k, - Vector* x, - Vector* res) + void VectorHandlerCpu::dot2Multi( + IdxT size, + Vector* V, + IdxT k, + Vector* x, + Vector* res + ) { ScalarT* res_data = res->getData(memory::HOST); const ScalarT* x_data = x->getData(memory::HOST); diff --git a/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.hpp b/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.hpp index 6fd527dbd7..2e9e022668 100644 --- a/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.hpp +++ b/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.hpp @@ -48,13 +48,15 @@ namespace GridKit * if `transpose = T` (yes), `x = beta*x + alpha*V^T*y`, * where `x` is `[k x 1]`, `V` is `[n x k]` and `y` is `[n x 1]`. */ - void gemv(char transpose, - IdxT k, - const ScalarT alpha, - const ScalarT beta, - Vector* V, - Vector* y, - Vector* x); + void gemv( + char transpose, + IdxT k, + const ScalarT alpha, + const ScalarT beta, + Vector* V, + Vector* y, + Vector* x + ); // Scale a vector by a diagonal matrix void scal(Vector* diag, Vector* vec); diff --git a/GridKit/Model/OptimalPowerFlow/Branch/Branch.hpp b/GridKit/Model/OptimalPowerFlow/Branch/Branch.hpp index a7c8b4295d..b0b8b317bd 100644 --- a/GridKit/Model/OptimalPowerFlow/Branch/Branch.hpp +++ b/GridKit/Model/OptimalPowerFlow/Branch/Branch.hpp @@ -61,12 +61,14 @@ namespace GridKit using InternalConstraintsT = BranchInternalConstraints; using ExternalConstraintsT = BranchExternalConstraints; - static constexpr std::array()> NUM_PORT_VARIABLES{ - BusT::NUM_SHARED_VARIABLES, - BusT::NUM_SHARED_VARIABLES}; - static constexpr std::array()> NUM_PORT_CONSTRAINTS{ - BusT::NUM_SHARED_CONSTRAINTS, - BusT::NUM_SHARED_CONSTRAINTS}; + static constexpr std::array()> + NUM_PORT_VARIABLES{ + BusT::NUM_SHARED_VARIABLES, BusT::NUM_SHARED_VARIABLES + }; + static constexpr std::array()> + NUM_PORT_CONSTRAINTS{ + BusT::NUM_SHARED_CONSTRAINTS, BusT::NUM_SHARED_CONSTRAINTS + }; explicit Branch(const ModelDataT& data); diff --git a/GridKit/Model/OptimalPowerFlow/Branch/BranchImpl.hpp b/GridKit/Model/OptimalPowerFlow/Branch/BranchImpl.hpp index dd08a13b44..302910466e 100644 --- a/GridKit/Model/OptimalPowerFlow/Branch/BranchImpl.hpp +++ b/GridKit/Model/OptimalPowerFlow/Branch/BranchImpl.hpp @@ -59,10 +59,10 @@ namespace GridKit } template - [[gnu::always_inline]] void - Branch::internalConstraints([[maybe_unused]] const ScalarT* x, - const ScalarT* external, - ScalarT* g) const + [[gnu::always_inline]] void Branch:: + internalConstraints( + [[maybe_unused]] const ScalarT* x, const ScalarT* external, ScalarT* g + ) const { const auto DP1 = static_cast(BranchExternalConstraints::DP1); const auto DQ1 = static_cast(BranchExternalConstraints::DQ1); @@ -79,10 +79,10 @@ namespace GridKit } template - [[gnu::always_inline]] void - Branch::externalConstraints([[maybe_unused]] const ScalarT* x, - const ScalarT* external, - ScalarT* g) const + [[gnu::always_inline]] void Branch:: + externalConstraints( + [[maybe_unused]] const ScalarT* x, const ScalarT* external, ScalarT* g + ) const { power(external, g); } diff --git a/GridKit/Model/OptimalPowerFlow/Bus/BusImpl.hpp b/GridKit/Model/OptimalPowerFlow/Bus/BusImpl.hpp index 9e22085fd1..c61f40556f 100644 --- a/GridKit/Model/OptimalPowerFlow/Bus/BusImpl.hpp +++ b/GridKit/Model/OptimalPowerFlow/Bus/BusImpl.hpp @@ -76,10 +76,10 @@ namespace GridKit /// Shunt power into the bus, which starts its balance, and the squared voltage magnitude template - [[gnu::always_inline]] void - Bus::internalConstraints(const ScalarT* x, - [[maybe_unused]] const ScalarT* external, - ScalarT* g) const + [[gnu::always_inline]] void Bus:: + internalConstraints( + const ScalarT* x, [[maybe_unused]] const ScalarT* external, ScalarT* g + ) const { const auto VR = static_cast(BusInternalVariables::VR); const auto VI = static_cast(BusInternalVariables::VI); diff --git a/GridKit/Model/OptimalPowerFlow/Component.hpp b/GridKit/Model/OptimalPowerFlow/Component.hpp index 3e6058100d..3264948d6e 100644 --- a/GridKit/Model/OptimalPowerFlow/Component.hpp +++ b/GridKit/Model/OptimalPowerFlow/Component.hpp @@ -42,17 +42,24 @@ namespace GridKit */ template concept ComponentKernels = - std::derived_from> - && std::is_final_v - && Utilities::SizedEnum - && Utilities::SizedEnum - && Utilities::SizedEnum - && Utilities::SizedEnum - && ModelT::NUM_PORT_VARIABLES.size() == ModelT::NUM_PORT_CONSTRAINTS.size() - && std::accumulate(ModelT::NUM_PORT_VARIABLES.begin(), ModelT::NUM_PORT_VARIABLES.end(), std::size_t{0}) - == Utilities::enum_size() - && std::accumulate(ModelT::NUM_PORT_CONSTRAINTS.begin(), ModelT::NUM_PORT_CONSTRAINTS.end(), std::size_t{0}) - == Utilities::enum_size(); + std::derived_from> + && std::is_final_v + && Utilities::SizedEnum + && Utilities::SizedEnum + && Utilities::SizedEnum + && Utilities::SizedEnum + && ModelT::NUM_PORT_VARIABLES.size() + == ModelT::NUM_PORT_CONSTRAINTS.size() + && std::accumulate( + ModelT::NUM_PORT_VARIABLES.begin(), + ModelT::NUM_PORT_VARIABLES.end(), + std::size_t{0} + ) == Utilities::enum_size() + && std::accumulate( + ModelT::NUM_PORT_CONSTRAINTS.begin(), + ModelT::NUM_PORT_CONSTRAINTS.end(), + std::size_t{0} + ) == Utilities::enum_size(); /** * @brief Optimal power flow component, which views its blocks of the @@ -167,23 +174,29 @@ namespace GridKit } /// Objective contribution - virtual ScalarT objective([[maybe_unused]] const ScalarT* x, - [[maybe_unused]] const ScalarT* external) const + virtual ScalarT objective( + [[maybe_unused]] const ScalarT* x, + [[maybe_unused]] const ScalarT* external + ) const { return ScalarT{ZERO}; } /// Contributions `g` to the internal constraints - virtual void internalConstraints([[maybe_unused]] const ScalarT* x, - [[maybe_unused]] const ScalarT* external, - [[maybe_unused]] ScalarT* g) const + virtual void internalConstraints( + [[maybe_unused]] const ScalarT* x, + [[maybe_unused]] const ScalarT* external, + [[maybe_unused]] ScalarT* g + ) const { } /// Contributions `g` to the constraints at each port, in port order - virtual void externalConstraints([[maybe_unused]] const ScalarT* x, - [[maybe_unused]] const ScalarT* external, - [[maybe_unused]] ScalarT* g) const + virtual void externalConstraints( + [[maybe_unused]] const ScalarT* x, + [[maybe_unused]] const ScalarT* external, + [[maybe_unused]] ScalarT* g + ) const { } @@ -243,18 +256,30 @@ namespace GridKit template static constexpr Block internalSize() { - return {static_cast(Utilities::enum_size()), - static_cast(Utilities::enum_size())}; + return { + static_cast( + Utilities::enum_size() + ), + static_cast( + Utilities::enum_size() + ) + }; } /// Internal plus external sizes of `ModelT` template static constexpr Block localSize() { - return {static_cast(Utilities::enum_size() - + Utilities::enum_size()), - static_cast(Utilities::enum_size() - + Utilities::enum_size())}; + return { + static_cast( + Utilities::enum_size() + + Utilities::enum_size() + ), + static_cast( + Utilities::enum_size() + + Utilities::enum_size() + ) + }; } void gather(ScalarT* x) const; diff --git a/GridKit/Model/OptimalPowerFlow/ComponentEnzyme.hpp b/GridKit/Model/OptimalPowerFlow/ComponentEnzyme.hpp index 3c4613eddb..a4eb8451ca 100644 --- a/GridKit/Model/OptimalPowerFlow/ComponentEnzyme.hpp +++ b/GridKit/Model/OptimalPowerFlow/ComponentEnzyme.hpp @@ -48,15 +48,17 @@ namespace GridKit gather(x.data()); jacobian_entries_.nnz = 0; - Enzyme::Sparse::DgDx::eval(&model, - local_x_.getSize(), - constraint_indices_.getData(), - variable_indices_.getData(), - x.data(), - jacobian_entries_.rows.getData(), - jacobian_entries_.cols.getData(), - jacobian_entries_.values.getData(), - jacobian_entries_.nnz); + Enzyme::Sparse::DgDx::eval( + &model, + local_x_.getSize(), + constraint_indices_.getData(), + variable_indices_.getData(), + x.data(), + jacobian_entries_.rows.getData(), + jacobian_entries_.cols.getData(), + jacobian_entries_.values.getData(), + jacobian_entries_.nnz + ); assert(jacobian_entries_.nnz <= jacobian_entries_.values.getSize()); return 0; } @@ -72,16 +74,18 @@ namespace GridKit gatherMultipliers(lambda.data()); hessian_entries_.nnz = 0; - Enzyme::Sparse::D2LDx2::eval(&model, - local_x_.getSize(), - variable_indices_.getData(), - x.data(), - sigma, - lambda.data(), - hessian_entries_.rows.getData(), - hessian_entries_.cols.getData(), - hessian_entries_.values.getData(), - hessian_entries_.nnz); + Enzyme::Sparse::D2LDx2::eval( + &model, + local_x_.getSize(), + variable_indices_.getData(), + x.data(), + sigma, + lambda.data(), + hessian_entries_.rows.getData(), + hessian_entries_.cols.getData(), + hessian_entries_.values.getData(), + hessian_entries_.nnz + ); assert(hessian_entries_.nnz <= hessian_entries_.values.getSize()); keepLowerTriangle(hessian_entries_); diff --git a/GridKit/Model/OptimalPowerFlow/Generator/Generator.hpp b/GridKit/Model/OptimalPowerFlow/Generator/Generator.hpp index 3a1adcd3b8..45ac7fc7b9 100644 --- a/GridKit/Model/OptimalPowerFlow/Generator/Generator.hpp +++ b/GridKit/Model/OptimalPowerFlow/Generator/Generator.hpp @@ -55,8 +55,8 @@ namespace GridKit using ExternalConstraintsT = GeneratorExternalConstraints; static constexpr std::array()> NUM_PORT_VARIABLES{0}; - static constexpr std::array()> NUM_PORT_CONSTRAINTS{ - BusT::NUM_SHARED_CONSTRAINTS}; + static constexpr std::array()> + NUM_PORT_CONSTRAINTS{BusT::NUM_SHARED_CONSTRAINTS}; explicit Generator(const ModelDataT& data); diff --git a/GridKit/Model/OptimalPowerFlow/Generator/GeneratorImpl.hpp b/GridKit/Model/OptimalPowerFlow/Generator/GeneratorImpl.hpp index ff9c7d4752..2ba0cc596d 100644 --- a/GridKit/Model/OptimalPowerFlow/Generator/GeneratorImpl.hpp +++ b/GridKit/Model/OptimalPowerFlow/Generator/GeneratorImpl.hpp @@ -64,10 +64,10 @@ namespace GridKit } template - [[gnu::always_inline]] void - Generator::externalConstraints(const ScalarT* x, - [[maybe_unused]] const ScalarT* external, - ScalarT* g) const + [[gnu::always_inline]] void Generator:: + externalConstraints( + const ScalarT* x, [[maybe_unused]] const ScalarT* external, ScalarT* g + ) const { const auto P = static_cast(GeneratorInternalVariables::P); const auto Q = static_cast(GeneratorInternalVariables::Q); diff --git a/GridKit/Model/OptimalPowerFlow/Load/Load.hpp b/GridKit/Model/OptimalPowerFlow/Load/Load.hpp index d723aa73c4..91d0d1d56b 100644 --- a/GridKit/Model/OptimalPowerFlow/Load/Load.hpp +++ b/GridKit/Model/OptimalPowerFlow/Load/Load.hpp @@ -50,10 +50,10 @@ namespace GridKit using InternalConstraintsT = Utilities::EmptyEnum; using ExternalConstraintsT = LoadExternalConstraints; - static constexpr std::array()> NUM_PORT_VARIABLES{ - BusT::NUM_SHARED_VARIABLES}; - static constexpr std::array()> NUM_PORT_CONSTRAINTS{ - BusT::NUM_SHARED_CONSTRAINTS}; + static constexpr std::array()> + NUM_PORT_VARIABLES{BusT::NUM_SHARED_VARIABLES}; + static constexpr std::array()> + NUM_PORT_CONSTRAINTS{BusT::NUM_SHARED_CONSTRAINTS}; explicit Load(const ModelDataT& data); diff --git a/GridKit/Model/OptimalPowerFlow/Load/LoadImpl.hpp b/GridKit/Model/OptimalPowerFlow/Load/LoadImpl.hpp index 4971f5b12c..27728dce57 100644 --- a/GridKit/Model/OptimalPowerFlow/Load/LoadImpl.hpp +++ b/GridKit/Model/OptimalPowerFlow/Load/LoadImpl.hpp @@ -32,10 +32,10 @@ namespace GridKit /// Power into the bus, the negative of the demand template - [[gnu::always_inline]] void - Load::externalConstraints([[maybe_unused]] const ScalarT* x, - const ScalarT* external, - ScalarT* g) const + [[gnu::always_inline]] void Load:: + externalConstraints( + [[maybe_unused]] const ScalarT* x, const ScalarT* external, ScalarT* g + ) const { const auto VR = static_cast(LoadExternalVariables::VR); const auto VI = static_cast(LoadExternalVariables::VI); diff --git a/GridKit/Model/OptimalPowerFlow/SystemModelImpl.hpp b/GridKit/Model/OptimalPowerFlow/SystemModelImpl.hpp index c0a98a0656..cc09597592 100644 --- a/GridKit/Model/OptimalPowerFlow/SystemModelImpl.hpp +++ b/GridKit/Model/OptimalPowerFlow/SystemModelImpl.hpp @@ -81,8 +81,10 @@ namespace GridKit for (const auto& [number, bus] : buses_) { - checks.check(number != INVALID_INDEX, - std::format("{}: invalid bus number", bus->id())); + checks.check( + number != INVALID_INDEX, + std::format("{}: invalid bus number", bus->id()) + ); } std::set ids; @@ -99,8 +101,14 @@ namespace GridKit const auto& ports = component->ports(); for (IdxT port = 0; port < ports.size(); ++port) { - checks.check(components.contains(ports[port].component), - std::format("{}: port {} must connect to a component in this system", component->id(), port)); + checks.check( + components.contains(ports[port].component), + std::format( + "{}: port {} must connect to a component in this system", + component->id(), + port + ) + ); } } @@ -281,13 +289,25 @@ namespace GridKit if (bus == buses_.end()) { throw std::invalid_argument( - std::format("{}: port '{}' names unknown bus {}", data.id, Utilities::enum_name(port), number->second)); + std::format( + "{}: port '{}' names unknown bus {}", + data.id, + Utilities::enum_name(port), + number->second + ) + ); } if (device->connect(static_cast(port), *bus->second) != 0) { throw std::invalid_argument( - std::format("{}: port '{}' does not fit bus {}", data.id, Utilities::enum_name(port), number->second)); + std::format( + "{}: port '{}' does not fit bus {}", + data.id, + Utilities::enum_name(port), + number->second + ) + ); } } diff --git a/GridKit/Model/ParameterReader.hpp b/GridKit/Model/ParameterReader.hpp index dc97c74eee..3542ff1087 100644 --- a/GridKit/Model/ParameterReader.hpp +++ b/GridKit/Model/ParameterReader.hpp @@ -24,14 +24,12 @@ namespace GridKit { /// Model data container with a map from each parameter to its value template - concept ParameterData = - requires(const T& data) { - typename T::RealT; - typename T::IdxT; - typename T::Parameters; - data.parameters; - } - && Utilities::SizedEnum; + concept ParameterData = requires(const T& data) { + typename T::RealT; + typename T::IdxT; + typename T::Parameters; + data.parameters; + } && Utilities::SizedEnum; /** * @brief Reads typed parameters out of a model data container. @@ -154,7 +152,10 @@ namespace GridKit [[noreturn]] void reject(ParametersT key, std::string_view reason) const { throw std::invalid_argument( - std::format("{}: parameter '{}' {}", model_, magic_enum::enum_name(key), reason)); + std::format( + "{}: parameter '{}' {}", model_, magic_enum::enum_name(key), reason + ) + ); } const ParameterMapT& parameters_; diff --git a/GridKit/Model/PhasorDynamics/Branch/Branch.hpp b/GridKit/Model/PhasorDynamics/Branch/Branch.hpp index f505547e99..194ffdb0af 100644 --- a/GridKit/Model/PhasorDynamics/Branch/Branch.hpp +++ b/GridKit/Model/PhasorDynamics/Branch/Branch.hpp @@ -114,17 +114,19 @@ namespace GridKit void terminalCurrent1(ScalarT& Ir, ScalarT& Ii); void terminalCurrent2(ScalarT& Ir, ScalarT& Ii); - static __attribute__((always_inline)) inline void addAdmittanceContribution(const RealT G, - const RealT B, - const ScalarT Vr, - const ScalarT Vi, - ScalarT& Ir, - ScalarT& Ii); - - static __attribute__((always_inline)) inline void evaluateAdmittanceBlock(const RealT G, - const RealT B, - const ScalarT* wb, - ScalarT* h); + static __attribute__((always_inline)) inline void + addAdmittanceContribution( + const RealT G, + const RealT B, + const ScalarT Vr, + const ScalarT Vi, + ScalarT& Ir, + ScalarT& Ii + ); + + static __attribute__((always_inline)) inline void evaluateAdmittanceBlock( + const RealT G, const RealT B, const ScalarT* wb, ScalarT* h + ); ScalarT& Vr1() { @@ -168,13 +170,17 @@ namespace GridKit public: __attribute__((always_inline)) inline int evaluateBusResidual11( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* + ); __attribute__((always_inline)) inline int evaluateBusResidual12( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* + ); __attribute__((always_inline)) inline int evaluateBusResidual21( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* + ); __attribute__((always_inline)) inline int evaluateBusResidual22( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* + ); private: BusT* bus1_; diff --git a/GridKit/Model/PhasorDynamics/Branch/BranchData.hpp b/GridKit/Model/PhasorDynamics/Branch/BranchData.hpp index f9a2a3556f..3951abbf81 100644 --- a/GridKit/Model/PhasorDynamics/Branch/BranchData.hpp +++ b/GridKit/Model/PhasorDynamics/Branch/BranchData.hpp @@ -78,13 +78,13 @@ namespace GridKit * Integer parameters are of the same type as matrix and vector indices. */ template - using BranchData = - ComponentData; + using BranchData = ComponentData< + real_type, + index_type, + BranchParameters, + BranchBuses, + BranchSignalInputs, + BranchSignalOutputs, + BranchMonitorableVariables>; } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/Branch/BranchEnzyme.cpp b/GridKit/Model/PhasorDynamics/Branch/BranchEnzyme.cpp index 1409b46643..934f1e28d1 100644 --- a/GridKit/Model/PhasorDynamics/Branch/BranchEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Branch/BranchEnzyme.cpp @@ -36,64 +36,80 @@ namespace GridKit nnz_ = 0; // Bus 1 diagonal Jacobian block owned by the bus - GridKit::Enzyme::Sparse::DhDwb, - GridKit::Enzyme::Sparse::MemberFunctions::BusResidual11>::eval(this, - static_cast(bus1_->size()), - static_cast((bus1_->y()).getSize()), - (bus1_->getResidualIndices()).data(), - (bus1_->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - bus1_->y().getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DhDwb< + GridKit::PhasorDynamics::Branch, + GridKit::Enzyme::Sparse::MemberFunctions::BusResidual11>:: + eval( + this, + static_cast(bus1_->size()), + static_cast((bus1_->y()).getSize()), + (bus1_->getResidualIndices()).data(), + (bus1_->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + bus1_->y().getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); // Bus 2 diagonal Jacobian block owned by the bus - GridKit::Enzyme::Sparse::DhDwb, - GridKit::Enzyme::Sparse::MemberFunctions::BusResidual22>::eval(this, - static_cast(bus2_->size()), - static_cast((bus2_->y()).getSize()), - (bus2_->getResidualIndices()).data(), - (bus2_->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - bus2_->y().getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DhDwb< + GridKit::PhasorDynamics::Branch, + GridKit::Enzyme::Sparse::MemberFunctions::BusResidual22>:: + eval( + this, + static_cast(bus2_->size()), + static_cast((bus2_->y()).getSize()), + (bus2_->getResidualIndices()).data(), + (bus2_->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + bus2_->y().getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); // Off-diagonal Jacobian block (Bus2 variables) owned by the branch - GridKit::Enzyme::Sparse::DhDwb, - GridKit::Enzyme::Sparse::MemberFunctions::BusResidual12>::eval(this, - static_cast(bus1_->size()), - static_cast((bus2_->y()).getSize()), - (bus1_->getResidualIndices()).data(), - (bus2_->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - bus2_->y().getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DhDwb< + GridKit::PhasorDynamics::Branch, + GridKit::Enzyme::Sparse::MemberFunctions::BusResidual12>:: + eval( + this, + static_cast(bus1_->size()), + static_cast((bus2_->y()).getSize()), + (bus1_->getResidualIndices()).data(), + (bus2_->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + bus2_->y().getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); // Off-diagonal Jacobian block (Bus1 variables) owned by the branch - GridKit::Enzyme::Sparse::DhDwb, - GridKit::Enzyme::Sparse::MemberFunctions::BusResidual21>::eval(this, - static_cast(bus2_->size()), - static_cast((bus1_->y()).getSize()), - (bus2_->getResidualIndices()).data(), - (bus1_->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - bus1_->y().getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DhDwb< + GridKit::PhasorDynamics::Branch, + GridKit::Enzyme::Sparse::MemberFunctions::BusResidual21>:: + eval( + this, + static_cast(bus2_->size()), + static_cast((bus1_->y()).getSize()), + (bus2_->getResidualIndices()).data(), + (bus1_->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + bus1_->y().getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); this->constructCoo(); diff --git a/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp b/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp index e5d95c87a9..59fdbcacf6 100644 --- a/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp @@ -137,24 +137,25 @@ namespace GridKit } template - __attribute__((always_inline)) inline void Branch::addAdmittanceContribution( + __attribute__((always_inline)) inline void Branch:: + addAdmittanceContribution( const RealT G, const RealT B, const ScalarT Vr, const ScalarT Vi, ScalarT& Ir, - ScalarT& Ii) + ScalarT& Ii + ) { Ir += G * Vr - B * Vi; Ii += B * Vr + G * Vi; } template - __attribute__((always_inline)) inline void Branch::evaluateAdmittanceBlock( - const RealT G, - const RealT B, - const ScalarT* wb, - ScalarT* h) + __attribute__((always_inline)) inline void Branch:: + evaluateAdmittanceBlock( + const RealT G, const RealT B, const ScalarT* wb, ScalarT* h + ) { const ScalarT Vr = wb[0]; const ScalarT Vi = wb[1]; @@ -186,11 +187,13 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Branch::evaluateBusResidual11( + __attribute__((always_inline)) inline int Branch:: + evaluateBusResidual11( [[maybe_unused]] const ScalarT* y, [[maybe_unused]] const ScalarT* yp, const ScalarT* wb, - ScalarT* h) + ScalarT* h + ) { evaluateAdmittanceBlock(g11_, b11_, wb, h); @@ -202,11 +205,13 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Branch::evaluateBusResidual12( + __attribute__((always_inline)) inline int Branch:: + evaluateBusResidual12( [[maybe_unused]] const ScalarT* y, [[maybe_unused]] const ScalarT* yp, const ScalarT* wb, - ScalarT* h) + ScalarT* h + ) { evaluateAdmittanceBlock(g12_, b12_, wb, h); @@ -218,11 +223,13 @@ namespace GridKit * */ template - __attribute__((always_inline)) int Branch::evaluateBusResidual21( + __attribute__((always_inline)) int Branch:: + evaluateBusResidual21( [[maybe_unused]] const ScalarT* y, [[maybe_unused]] const ScalarT* yp, const ScalarT* wb, - ScalarT* h) + ScalarT* h + ) { evaluateAdmittanceBlock(g21_, b21_, wb, h); @@ -234,11 +241,13 @@ namespace GridKit * */ template - __attribute__((always_inline)) int Branch::evaluateBusResidual22( + __attribute__((always_inline)) int Branch:: + evaluateBusResidual22( [[maybe_unused]] const ScalarT* y, [[maybe_unused]] const ScalarT* yp, const ScalarT* wb, - ScalarT* h) + ScalarT* h + ) { evaluateAdmittanceBlock(g22_, b22_, wb, h); diff --git a/GridKit/Model/PhasorDynamics/Bus/BusData.hpp b/GridKit/Model/PhasorDynamics/Bus/BusData.hpp index f4d99ff13a..011d30df37 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusData.hpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusData.hpp @@ -66,13 +66,14 @@ namespace GridKit * Integer parameters are of the same type as matrix and vector indices. */ template - struct BusData : public ComponentData + struct BusData : public ComponentData< + real_type, + index_type, + BusParameters, + Utilities::EmptyEnum, + BusSignalInputs, + BusSignalOutputs, + BusMonitorableVariables> { using RealT = real_type; using IdxT = index_type; diff --git a/GridKit/Model/PhasorDynamics/Bus/BusDataJSONParser.hpp b/GridKit/Model/PhasorDynamics/Bus/BusDataJSONParser.hpp index 8f1ef6c7f5..82d4e73a79 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusDataJSONParser.hpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusDataJSONParser.hpp @@ -34,10 +34,9 @@ namespace GridKit if (!Utilities::isValidIdentifier(bd.name)) { - Log::error() - << "\n\tBus name may contain only ASCII letters, digits, " - "spaces, '_', '.' and '-'." - << error_context.str() << std::endl; + Log::error() << "\n\tBus name may contain only ASCII letters, digits, " + "spaces, '_', '.' and '-'." + << error_context.str() << std::endl; throw std::runtime_error("JSON parser failed"); } @@ -132,7 +131,7 @@ namespace GridKit auto input = Utilities::enum_cast(raw_input.key()); if (input.has_value() && static_cast(input.value()) - < Utilities::enum_size()) + < Utilities::enum_size()) { raw_input.value().get_to(bd.signal_inputs[input.value()]); } @@ -147,7 +146,7 @@ namespace GridKit auto output = Utilities::enum_cast(raw_output.key()); if (output.has_value() && static_cast(output.value()) - < Utilities::enum_size()) + < Utilities::enum_size()) { raw_output.value().get_to(bd.signal_outputs[output.value()]); } diff --git a/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOutEnzyme.cpp b/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOutEnzyme.cpp index f70d4fbdb1..1a077de56f 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOutEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOutEnzyme.cpp @@ -71,7 +71,7 @@ namespace GridKit return; } const IdxT signal_index = - port.linked() ? port.signalVariableIndex() : INVALID_INDEX; + port.linked() ? port.signalVariableIndex() : INVALID_INDEX; J_rows_buffer_[k] = residual_indices_.at(residual); if (signal_index != INVALID_INDEX) { diff --git a/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOutImpl.hpp b/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOutImpl.hpp index d535c654ca..7e58c5a0a7 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOutImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOutImpl.hpp @@ -57,8 +57,8 @@ namespace GridKit monitor_->set(Variable::Vi, [this] { return Vi(); }); monitor_->set( - Variable::Vm, [this] - { return std::sqrt(Vr() * Vr() + Vi() * Vi()); }); + Variable::Vm, [this] { return std::sqrt(Vr() * Vr() + Vi() * Vi()); } + ); monitor_->set(Variable::Va, [this] { return std::atan2(Vi(), Vr()); }); } @@ -144,15 +144,19 @@ namespace GridKit const auto& port = ports_.in.template port(); if (!port.connected()) { - checks.fail(std::format( + checks.fail( + std::format( "{} signal inlet is not connected; a default current is not " "allowed", - name)); + name + ) + ); } else if (!port.linked()) { checks.fail( - std::format("{} signal attached with no linked source", name)); + std::format("{} signal attached with no linked source", name) + ); } }; @@ -161,10 +165,13 @@ namespace GridKit const auto& port = ports_.out.template port(); if (port.connected() && !port.linked()) { - checks.fail(std::format( + checks.fail( + std::format( "{} signal attached but not linked; connect signal ports before " "allocate()", - name)); + name + ) + ); } }; @@ -192,7 +199,7 @@ namespace GridKit if (status && !(ZERO < R * R + X * X)) { Log::error() - << "BusSignalVoltageOut: fault impedance R + jX must be nonzero\n"; + << "BusSignalVoltageOut: fault impedance R + jX must be nonzero\n"; return 1; } diff --git a/GridKit/Model/PhasorDynamics/ComponentData.hpp b/GridKit/Model/PhasorDynamics/ComponentData.hpp index 603d4ad3c4..943b2bf68b 100644 --- a/GridKit/Model/PhasorDynamics/ComponentData.hpp +++ b/GridKit/Model/PhasorDynamics/ComponentData.hpp @@ -17,15 +17,15 @@ namespace GridKit * @tparam real_type Real parameter data type * @tparam index_type Integer parameter data type */ - template - requires std::is_enum_v - && std::is_enum_v + template < + typename real_type, + typename index_type, + typename parameters_enum, + typename buses_enum, + typename signal_inputs_enum, + typename signal_outputs_enum, + typename monitorable_variables_enum> + requires std::is_enum_v && std::is_enum_v && std::is_enum_v && std::is_enum_v && std::is_enum_v diff --git a/GridKit/Model/PhasorDynamics/ComponentDataJSONParser.hpp b/GridKit/Model/PhasorDynamics/ComponentDataJSONParser.hpp index 3ff4a3d119..feef7ca717 100644 --- a/GridKit/Model/PhasorDynamics/ComponentDataJSONParser.hpp +++ b/GridKit/Model/PhasorDynamics/ComponentDataJSONParser.hpp @@ -21,26 +21,28 @@ namespace GridKit using Log = ::GridKit::Utilities::Logger; /// JSON parser function for the `ComponentData` class and descendants - template - requires std::is_enum_v - && std::is_enum_v - && std::is_enum_v - && std::is_enum_v + template < + typename RealT, + typename IdxT, + typename Parameters, + typename Buses, + typename SignalInputs, + typename SignalOutputs, + typename MonitorableVariables> + requires std::is_enum_v && std::is_enum_v + && std::is_enum_v && std::is_enum_v && std::is_enum_v - void from_json(const json& j, - ComponentData& c) + void from_json( + const json& j, + ComponentData< + RealT, + IdxT, + Parameters, + Buses, + SignalInputs, + SignalOutputs, + MonitorableVariables>& c + ) { j.at("class").get_to(c.device_class); @@ -53,10 +55,9 @@ namespace GridKit if (!Utilities::isValidIdentifier(c.disambiguation_string)) { - Log::error() - << "\n\tDevice id may contain only ASCII letters, digits, " - "spaces, '_', '.' and '-'." - << error_context.str() << std::endl; + Log::error() << "\n\tDevice id may contain only ASCII letters, digits, " + "spaces, '_', '.' and '-'." + << error_context.str() << std::endl; throw std::runtime_error("JSON parser failed"); } @@ -110,8 +111,7 @@ namespace GridKit { auto bus = Utilities::enum_cast(raw_port.key()); if (bus.has_value() - && static_cast(bus.value()) - < Utilities::enum_size()) + && static_cast(bus.value()) < Utilities::enum_size()) { raw_port.value().get_to(c.buses[bus.value()]); continue; @@ -120,17 +120,17 @@ namespace GridKit auto signal_input = Utilities::enum_cast(raw_port.key()); if (signal_input.has_value() && static_cast(signal_input.value()) - < Utilities::enum_size()) + < Utilities::enum_size()) { raw_port.value().get_to(c.signal_inputs[signal_input.value()]); continue; } auto signal_output = - Utilities::enum_cast(raw_port.key()); + Utilities::enum_cast(raw_port.key()); if (signal_output.has_value() && static_cast(signal_output.value()) - < Utilities::enum_size()) + < Utilities::enum_size()) { raw_port.value().get_to(c.signal_outputs[signal_output.value()]); continue; diff --git a/GridKit/Model/PhasorDynamics/Controller/REECB/Reecb.hpp b/GridKit/Model/PhasorDynamics/Controller/REECB/Reecb.hpp index 558e4108dd..8560fe1c33 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REECB/Reecb.hpp +++ b/GridKit/Model/PhasorDynamics/Controller/REECB/Reecb.hpp @@ -109,7 +109,7 @@ namespace GridKit public: /// Initialization reconstruction tolerance. static constexpr RealT INITIALIZATION_TOLERANCE = - static_cast(100.0) * std::numeric_limits::epsilon(); + static_cast(100.0) * std::numeric_limits::epsilon(); Reecb(BusT* bus, const ModelDataT& data); ~Reecb(); @@ -133,17 +133,18 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; [[gnu::always_inline]] inline int evaluateInternalResidual( - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - const ScalarT* ws, - ScalarT* f); + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + const ScalarT* ws, + ScalarT* f + ); private: /// Hinge width chosen so closed-circle leakage stays below the /// initialization tolerance [p.u. current squared]. static constexpr RealT CURRENT_CIRCLE_KNEE = - INITIALIZATION_TOLERANCE / Math::MU; + INITIALIZATION_TOLERANCE / Math::MU; struct InitialPoint; diff --git a/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbData.hpp b/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbData.hpp index 9eb4dd6240..494ca3d915 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbData.hpp +++ b/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbData.hpp @@ -95,14 +95,14 @@ namespace GridKit * @see Reecb */ template - using ReecbData = - ComponentData; + using ReecbData = ComponentData< + real_type, + index_type, + ReecbParameters, + ReecbBuses, + ReecbSignalInputs, + ReecbSignalOutputs, + ReecbMonitorableVariables>; } // namespace Controller } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbEnzyme.cpp b/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbEnzyme.cpp index f474aa1766..3ca4cc5059 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbEnzyme.cpp @@ -47,7 +47,8 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy::eval( + GridKit::Enzyme::Sparse::DfDy:: + eval( this, static_cast(f_.getSize()), static_cast(y_.getSize()), @@ -60,9 +61,11 @@ namespace GridKit J_rows_buffer_, J_cols_buffer_, J_vals_buffer_, - nnz_); + nnz_ + ); - GridKit::Enzyme::Sparse::DfDyp::eval( + GridKit::Enzyme::Sparse::DfDyp:: + eval( this, static_cast(f_.getSize()), static_cast(y_.getSize()), @@ -76,9 +79,11 @@ namespace GridKit J_rows_buffer_, J_cols_buffer_, J_vals_buffer_, - nnz_); + nnz_ + ); - GridKit::Enzyme::Sparse::DfDwb::eval( + GridKit::Enzyme::Sparse::DfDwb:: + eval( this, static_cast(f_.getSize()), static_cast(bus_->size()), @@ -91,9 +96,11 @@ namespace GridKit J_rows_buffer_, J_cols_buffer_, J_vals_buffer_, - nnz_); + nnz_ + ); - GridKit::Enzyme::Sparse::DfDws::eval( + GridKit::Enzyme::Sparse::DfDws:: + eval( this, static_cast(f_.getSize()), static_cast(ws_.getSize()), @@ -106,7 +113,8 @@ namespace GridKit J_rows_buffer_, J_cols_buffer_, J_vals_buffer_, - nnz_); + nnz_ + ); this->constructCoo(); return 0; diff --git a/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbImpl.hpp b/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbImpl.hpp index a31190263f..8602cc4530 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbImpl.hpp @@ -35,7 +35,7 @@ namespace GridKit // TODO: this should be fixed. sizing this array based on ordering of // variables seems fragile std::array(ReecbInternalVariables::IQCMD)> - variables{}; + variables{}; std::array()> signals{}; RealT qmin{}; @@ -164,11 +164,14 @@ namespace GridKit { const RealT system_to_component = va_system_base_ / va_component_base_; const RealT component_to_system = va_component_base_ / va_system_base_; - checks.check(std::isfinite(system_to_component) - && system_to_component > ZERO - && std::isfinite(component_to_system) - && component_to_system > ZERO, - "system/component power-base conversion ratios must be finite and positive"); + checks.check( + std::isfinite(system_to_component) + && system_to_component > ZERO + && std::isfinite(component_to_system) + && component_to_system > ZERO, + "system/component power-base conversion ratios must be finite and " + "positive" + ); } checks.check(std::isfinite(Trv_), "Trv must be finite"); @@ -411,7 +414,8 @@ namespace GridKit // Q priority uses Imax directly for reactive current, so include the // smooth-clamp recovery margin carried by iqneed0. const auto current_limit = solveInitialLimit( - std::max({Imax_, high0, low0, iqneed0}), high0, low0); + std::max({Imax_, high0, low0, iqneed0}), high0, low0 + ); if (!current_limit) { Log::error() << "Reecb: adjusted Imax cannot include the initial current commands\n"; @@ -893,13 +897,14 @@ namespace GridKit * @param[out] f Internal residuals. */ template - [[gnu::always_inline]] inline int - Reecb::evaluateInternalResidual( + [[gnu::always_inline]] inline int Reecb:: + evaluateInternalResidual( const ScalarT* y, const ScalarT* yp, const ScalarT* wb, const ScalarT* ws, - ScalarT* f) + ScalarT* f + ) { const auto VMEAS = static_cast(ReecbInternalVariables::VMEAS); const auto PMEAS = static_cast(ReecbInternalVariables::PMEAS); @@ -1084,9 +1089,9 @@ namespace GridKit const ValueT normalizer = absolute + knee; const ValueT scaled_x = absolute / normalizer; const ValueT scaled_knee = knee / normalizer; - const ValueT magnitude = normalizer - * std::sqrt(scaled_x * scaled_x - + scaled_knee * scaled_knee); + const ValueT magnitude = + normalizer + * std::sqrt(scaled_x * scaled_x + scaled_knee * scaled_knee); const ValueT half_sum = HALF * magnitude + HALF * absolute; const ValueT conjugate = QUARTER * knee * (knee / half_sum); @@ -1119,7 +1124,7 @@ namespace GridKit * (scaled_y + std::hypot(scaled_y, ONE)); const RealT square = hinged - QUARTER * CURRENT_CIRCLE_KNEE - * (CURRENT_CIRCLE_KNEE / hinged); + * (CURRENT_CIRCLE_KNEE / hinged); return std::max(ZERO, square); } @@ -1155,7 +1160,8 @@ namespace GridKit */ template auto Reecb::solveInitialLimit( - RealT lower, RealT high, RealT low) -> std::optional + RealT lower, RealT high, RealT low + ) -> std::optional { RealT imax = lower; RealT cap = sqrtramp(circleSquare(imax, high)); diff --git a/GridKit/Model/PhasorDynamics/Controller/REPCA/Repca.hpp b/GridKit/Model/PhasorDynamics/Controller/REPCA/Repca.hpp index 6dfbb41822..00861d8e04 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REPCA/Repca.hpp +++ b/GridKit/Model/PhasorDynamics/Controller/REPCA/Repca.hpp @@ -138,11 +138,12 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; [[gnu::always_inline]] inline int evaluateInternalResidual( - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - const ScalarT* ws, - ScalarT* f); + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + const ScalarT* ws, + ScalarT* f + ); private: /// Smooth asymmetric frequency-droop response. diff --git a/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaData.hpp b/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaData.hpp index 145affd59b..2f6f37d41c 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaData.hpp +++ b/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaData.hpp @@ -101,14 +101,14 @@ namespace GridKit * @see Repca */ template - using RepcaData = - ComponentData; + using RepcaData = ComponentData< + real_type, + index_type, + RepcaParameters, + RepcaBuses, + RepcaSignalInputs, + RepcaSignalOutputs, + RepcaMonitorableVariables>; } // namespace Controller } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaEnzyme.cpp b/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaEnzyme.cpp index b6ee259585..016c73327c 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaEnzyme.cpp @@ -47,7 +47,8 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy::eval( + GridKit::Enzyme::Sparse::DfDy:: + eval( this, static_cast(f_.getSize()), static_cast(y_.getSize()), @@ -60,9 +61,11 @@ namespace GridKit J_rows_buffer_, J_cols_buffer_, J_vals_buffer_, - nnz_); + nnz_ + ); - GridKit::Enzyme::Sparse::DfDyp::eval( + GridKit::Enzyme::Sparse::DfDyp:: + eval( this, static_cast(f_.getSize()), static_cast(y_.getSize()), @@ -76,9 +79,11 @@ namespace GridKit J_rows_buffer_, J_cols_buffer_, J_vals_buffer_, - nnz_); + nnz_ + ); - GridKit::Enzyme::Sparse::DfDwb::eval( + GridKit::Enzyme::Sparse::DfDwb:: + eval( this, static_cast(f_.getSize()), static_cast(bus_->size()), @@ -91,9 +96,11 @@ namespace GridKit J_rows_buffer_, J_cols_buffer_, J_vals_buffer_, - nnz_); + nnz_ + ); - GridKit::Enzyme::Sparse::DfDws::eval( + GridKit::Enzyme::Sparse::DfDws:: + eval( this, static_cast(f_.getSize()), static_cast(ws_.getSize()), @@ -106,7 +113,8 @@ namespace GridKit J_rows_buffer_, J_cols_buffer_, J_vals_buffer_, - nnz_); + nnz_ + ); this->constructCoo(); return 0; diff --git a/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaImpl.hpp b/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaImpl.hpp index e18feb54be..892d3c4a58 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaImpl.hpp @@ -141,33 +141,46 @@ namespace GridKit && va_component_base_ > ZERO; const bool valid_system_base = std::isfinite(va_system_base_) && va_system_base_ > ZERO; - checks.check(valid_component_base, - "mva must define a finite positive component power base"); + checks.check( + valid_component_base, + "mva must define a finite positive component power base" + ); checks.check(valid_system_base, "system power base must be finite and positive"); if (valid_component_base && valid_system_base) { const RealT system_to_component = va_system_base_ / va_component_base_; const RealT component_to_system = va_component_base_ / va_system_base_; - checks.check(std::isfinite(system_to_component) - && system_to_component > ZERO - && std::isfinite(component_to_system) - && component_to_system > ZERO, - "system/component power-base conversion ratios must be finite and positive"); + checks.check( + std::isfinite(system_to_component) + && system_to_component > ZERO + && std::isfinite(component_to_system) + && component_to_system > ZERO, + "system/component power-base conversion ratios must be finite and " + "positive" + ); } checks.check(Kp_ >= ZERO, "Kp must be non-negative"); checks.check(Kpg_ >= ZERO, "Kpg must be non-negative"); - checks.check(dbdlow_ <= ZERO && ZERO <= dbdupper_, - "dbdlow <= 0 <= dbdupper is required"); - checks.check(emin_ <= ZERO && ZERO <= emax_, - "emin <= 0 <= emax is required"); + checks.check( + dbdlow_ <= ZERO && ZERO <= dbdupper_, + "dbdlow <= 0 <= dbdupper is required" + ); + checks.check( + emin_ <= ZERO && ZERO <= emax_, + "emin <= 0 <= emax is required" + ); checks.check(Qmin_ <= Qmax_, "Qmin must be less than or equal to Qmax"); - checks.check(fdbd1_ <= ZERO && ZERO <= fdbd2_, - "fdbd1 <= 0 <= fdbd2 is required"); + checks.check( + fdbd1_ <= ZERO && ZERO <= fdbd2_, + "fdbd1 <= 0 <= fdbd2 is required" + ); checks.check(Ddn_ >= ZERO, "Ddn must be non-negative"); checks.check(Dup_ >= ZERO, "Dup must be non-negative"); - checks.check(femin_ <= ZERO && ZERO <= femax_, - "femin <= 0 <= femax is required"); + checks.check( + femin_ <= ZERO && ZERO <= femax_, + "femin <= 0 <= femax is required" + ); checks.check(Pmin_ <= Pmax_, "Pmin must be less than or equal to Pmax"); auto check_required_signal = [&](const char* name) @@ -272,13 +285,13 @@ namespace GridKit const ScalarT vr = Vr(); const ScalarT vi = Vi(); const ScalarT ir_system = - ports_.in.template port().readSignal(); + ports_.in.template port().readSignal(); const ScalarT ii_system = - ports_.in.template port().readSignal(); + ports_.in.template port().readSignal(); const ScalarT p_system = - ports_.in.template port().readSignal(); + ports_.in.template port().readSignal(); const ScalarT q_system = - ports_.in.template port().readSignal(); + ports_.in.template port().readSignal(); const ScalarT ir = this->toComponentBase(ir_system); const ScalarT ii = this->toComponentBase(ii_system); ScalarT freq = static_cast(ONE); @@ -379,42 +392,19 @@ namespace GridKit const ScalarT pref0_system = p_system + this->toSystemBase(ep0 - pfreq0); const bool candidates_are_finite = - is_finite(qext0_system) - && (!Freqflag_ || is_finite(pext0_system)) - && is_finite(qext0) - && (!Freqflag_ || is_finite(pext0)) - && is_finite(p) - && is_finite(q) - && is_finite(vldc_r) - && is_finite(vldc_i) - && is_finite(v0) - && is_finite(vldc0) - && is_finite(vdroop0) - && is_finite(vctrl0) - && is_finite(vmeas0) - && is_finite(qmeas0) - && is_finite(pmeas0) - && is_finite(sfrz0) - && is_finite(erq0) - && is_finite(erqdb0) - && is_finite(erqlim0) - && is_finite(qpi0) - && is_finite(xqlag0) - && is_finite(qpi_input0) - && is_finite(xqpi0) - && is_finite(ef0) - && is_finite(pfreq0) - && is_finite(ep0) - && is_finite(eplim0) - && is_finite(pref0) - && is_finite(ppi0) - && is_finite(ppi_input0) - && is_finite(xppi0) - && is_finite(pext_output0) - && is_finite(freqref0) - && is_finite(vref0) - && is_finite(qref0_system) - && is_finite(pref0_system); + is_finite(qext0_system) && (!Freqflag_ || is_finite(pext0_system)) + && is_finite(qext0) && (!Freqflag_ || is_finite(pext0)) + && is_finite(p) && is_finite(q) && is_finite(vldc_r) + && is_finite(vldc_i) && is_finite(v0) && is_finite(vldc0) + && is_finite(vdroop0) && is_finite(vctrl0) && is_finite(vmeas0) + && is_finite(qmeas0) && is_finite(pmeas0) && is_finite(sfrz0) + && is_finite(erq0) && is_finite(erqdb0) && is_finite(erqlim0) + && is_finite(qpi0) && is_finite(xqlag0) && is_finite(qpi_input0) + && is_finite(xqpi0) && is_finite(ef0) && is_finite(pfreq0) + && is_finite(ep0) && is_finite(eplim0) && is_finite(pref0) + && is_finite(ppi0) && is_finite(ppi_input0) && is_finite(xppi0) + && is_finite(pext_output0) && is_finite(freqref0) && is_finite(vref0) + && is_finite(qref0_system) && is_finite(pref0_system); if (!candidates_are_finite) { Log::error() << "Repca: derived initial values must be finite\n"; @@ -688,13 +678,14 @@ namespace GridKit * `RepcaInternalVariables` order. */ template - [[gnu::always_inline]] inline int - Repca::evaluateInternalResidual( + [[gnu::always_inline]] inline int Repca:: + evaluateInternalResidual( const ScalarT* y, const ScalarT* yp, const ScalarT* wb, const ScalarT* ws, - ScalarT* f) + ScalarT* f + ) { const auto VMEAS = static_cast(RepcaInternalVariables::VMEAS); const auto QMEAS = static_cast(RepcaInternalVariables::QMEAS); @@ -1093,7 +1084,7 @@ namespace GridKit input = static_cast(result); return std::isfinite(result) && std::abs(Math::deadband2(result, lower, upper) - value) - <= INITIALIZATION_TOLERANCE; + <= INITIALIZATION_TOLERANCE; } /** diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCA/Regca.hpp b/GridKit/Model/PhasorDynamics/Converter/REGCA/Regca.hpp index 67087dda53..9701c87350 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REGCA/Regca.hpp +++ b/GridKit/Model/PhasorDynamics/Converter/REGCA/Regca.hpp @@ -121,10 +121,16 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT* y, const ScalarT* yp, const ScalarT* wb, const ScalarT* ws, ScalarT* f); + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + const ScalarT* ws, + ScalarT* f + ); __attribute__((always_inline)) inline int evaluateBusResidual( - const ScalarT* y, const ScalarT* yp, const ScalarT* wb, ScalarT* h); + const ScalarT* y, const ScalarT* yp, const ScalarT* wb, ScalarT* h + ); private: void initializeParameters(const ModelDataT& data); @@ -146,9 +152,8 @@ namespace GridKit * @todo Move this reusable limiter to CommonMath. */ static __attribute__((always_inline)) inline ScalarT rrpwr( - const ScalarT x, - const ScalarT f, - const RealT rate) + const ScalarT x, const ScalarT f, const RealT rate + ) { assert(rate >= ZERO); @@ -178,17 +183,18 @@ namespace GridKit * @todo Move this one-sided anti-windup helper to CommonMath. */ static __attribute__((always_inline)) inline ScalarT awmax( - const ScalarT x, - const ScalarT f, - const ScalarT xmax, - const ScalarT fmax) + const ScalarT x, + const ScalarT f, + const ScalarT xmax, + const ScalarT fmax + ) { const ScalarT gap_rate = f - fmax; const ScalarT below = Math::sigmoid(xmax - x); return fmax + (below + (ONE - below) * Math::sigmoid(-gap_rate)) - * gap_rate; + * gap_rate; } ScalarT& Vr(); diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaData.hpp b/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaData.hpp index 2034b33618..23e0076053 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaData.hpp +++ b/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaData.hpp @@ -89,14 +89,14 @@ namespace GridKit * @see Regca */ template - using RegcaData = - ComponentData; + using RegcaData = ComponentData< + real_type, + index_type, + RegcaParameters, + RegcaBuses, + RegcaSignalInputs, + RegcaSignalOutputs, + RegcaMonitorableVariables>; } // namespace Converter } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaEnzyme.cpp b/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaEnzyme.cpp index c68327fcd7..355e13a84a 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaEnzyme.cpp @@ -40,80 +40,89 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDy:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDyp::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - alpha_, - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDyp:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + alpha_, + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDwb::eval(this, - static_cast(f_.getSize()), - static_cast(bus_->size()), - (this->getResidualIndices()).data(), - (bus_->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDwb:: + eval( + this, + static_cast(f_.getSize()), + static_cast(bus_->size()), + (this->getResidualIndices()).data(), + (bus_->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDws::eval(this, - static_cast(f_.getSize()), - static_cast(ws_.getSize()), - (this->getResidualIndices()).data(), - ws_indices_.data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDws:: + eval( + this, + static_cast(f_.getSize()), + static_cast(ws_.getSize()), + (this->getResidualIndices()).data(), + ws_indices_.data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DhDy::eval(this, - static_cast(bus_->size()), - static_cast(y_.getSize()), - (bus_->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DhDy::eval( + this, + static_cast(bus_->size()), + static_cast(y_.getSize()), + (bus_->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); this->constructCoo(); return 0; diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaImpl.hpp b/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaImpl.hpp index 7392c8492a..0f2b46aa57 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaImpl.hpp @@ -287,26 +287,42 @@ namespace GridKit if (auto port = ports_.out.template port()) { - port.link(&y[static_cast(RegcaInternalVariables::IR)], - &(this->getVariableIndex(static_cast(RegcaInternalVariables::IR)))); + port.link( + &y[static_cast(RegcaInternalVariables::IR)], + &(this->getVariableIndex( + static_cast(RegcaInternalVariables::IR) + )) + ); } if (auto port = ports_.out.template port()) { - port.link(&y[static_cast(RegcaInternalVariables::II)], - &(this->getVariableIndex(static_cast(RegcaInternalVariables::II)))); + port.link( + &y[static_cast(RegcaInternalVariables::II)], + &(this->getVariableIndex( + static_cast(RegcaInternalVariables::II) + )) + ); } if (auto port = ports_.out.template port()) { - port.link(&y[static_cast(RegcaInternalVariables::PBR)], - &(this->getVariableIndex(static_cast(RegcaInternalVariables::PBR)))); + port.link( + &y[static_cast(RegcaInternalVariables::PBR)], + &(this->getVariableIndex( + static_cast(RegcaInternalVariables::PBR) + )) + ); } if (auto port = ports_.out.template port()) { - port.link(&y[static_cast(RegcaInternalVariables::QBR)], - &(this->getVariableIndex(static_cast(RegcaInternalVariables::QBR)))); + port.link( + &y[static_cast(RegcaInternalVariables::QBR)], + &(this->getVariableIndex( + static_cast(RegcaInternalVariables::QBR) + )) + ); } allocated_ = true; @@ -336,8 +352,10 @@ namespace GridKit checks.check(Rpmax_ >= ZERO, "Rpmax must be non-negative"); checks.check(IL1_ >= ZERO, "IL1 must be non-negative"); checks.check(ZERO <= VL0_ && VL0_ < VL1_, "VL0/VL1 must satisfy 0 <= VL0 < VL1"); - checks.check(ZERO <= VA0_ && VA0_ < VA1_ && VA1_ < Vhvmax_, - "VA0/VA1/Vhvmax must satisfy 0 <= VA0 < VA1 < Vhvmax"); + checks.check( + ZERO <= VA0_ && VA0_ < VA1_ && VA1_ < Vhvmax_, + "VA0/VA1/Vhvmax must satisfy 0 <= VA0 < VA1 < Vhvmax" + ); if (ports_.in.template port()) { @@ -399,14 +417,14 @@ namespace GridKit } if (vt < VA1_) { - Log::error() - << "Regca: terminal voltage magnitude must be at least VA1 at initialization\n"; + Log::error() << "Regca: terminal voltage magnitude must be at least " + "VA1 at initialization\n"; return 1; } if (vt >= Vhvmax_) { - Log::error() - << "Regca: terminal voltage magnitude must be below Vhvmax at initialization\n"; + Log::error() << "Regca: terminal voltage magnitude must be below " + "Vhvmax at initialization\n"; return 1; } @@ -509,13 +527,14 @@ namespace GridKit * @param[out] f Internal residuals. */ template - __attribute__((always_inline)) inline int - Regca::evaluateInternalResidual( + __attribute__((always_inline)) inline int Regca:: + evaluateInternalResidual( const ScalarT* y, const ScalarT* yp, const ScalarT* wb, const ScalarT* ws, - ScalarT* f) + ScalarT* f + ) { const auto VM = static_cast(RegcaInternalVariables::VM); const auto IQ = static_cast(RegcaInternalVariables::IQ); @@ -599,11 +618,13 @@ namespace GridKit * @param[out] h Current injected into the terminal bus. */ template - __attribute__((always_inline)) inline int Regca::evaluateBusResidual( + __attribute__((always_inline)) inline int Regca:: + evaluateBusResidual( const ScalarT* y, [[maybe_unused]] const ScalarT* yp, [[maybe_unused]] const ScalarT* wb, - ScalarT* h) + ScalarT* h + ) { const auto IR = static_cast(RegcaInternalVariables::IR); const auto II = static_cast(RegcaInternalVariables::II); diff --git a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1a.hpp b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1a.hpp index 1941636726..4281b6dc2f 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1a.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1a.hpp @@ -116,11 +116,12 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - const ScalarT* ws, - ScalarT* f); + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + const ScalarT* ws, + ScalarT* f + ); private: void initializeParameters(const ModelDataT& data); @@ -128,9 +129,8 @@ namespace GridKit void setDerivedParameters(); static __attribute__((always_inline)) inline ScalarT awmin( - ScalarT x, - ScalarT f, - RealT xmin); + ScalarT x, ScalarT f, RealT xmin + ); /// Recover the input that the smooth CommonMath ramp maps to a /// requested strictly positive output. diff --git a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aData.hpp b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aData.hpp index 72468a8667..4a87716db4 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aData.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aData.hpp @@ -85,14 +85,14 @@ namespace GridKit * @see Esdc1a */ template - using Esdc1aData = - ComponentData; + using Esdc1aData = ComponentData< + real_type, + index_type, + Esdc1aParameters, + Esdc1aBuses, + Esdc1aSignalInputs, + Esdc1aSignalOutputs, + Esdc1aMonitorableVariables>; } // namespace Exciter } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aEnzyme.cpp b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aEnzyme.cpp index 45c38313bb..b3ae0deaad 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aEnzyme.cpp @@ -45,62 +45,74 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDy:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDyp::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - alpha_, - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDyp:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + alpha_, + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDwb::eval(this, - static_cast(f_.getSize()), - static_cast(bus_->size()), - (this->getResidualIndices()).data(), - (bus_->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDwb:: + eval( + this, + static_cast(f_.getSize()), + static_cast(bus_->size()), + (this->getResidualIndices()).data(), + (bus_->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDws::eval(this, - static_cast(f_.getSize()), - static_cast(ws_.getSize()), - (this->getResidualIndices()).data(), - ws_indices_.data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDws:: + eval( + this, + static_cast(f_.getSize()), + static_cast(ws_.getSize()), + (this->getResidualIndices()).data(), + ws_indices_.data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); this->constructCoo(); return 0; diff --git a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aImpl.hpp b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aImpl.hpp index eebb337cb3..0b6aa18b4c 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aImpl.hpp @@ -139,13 +139,15 @@ namespace GridKit checks.check(Ka_ > ZERO, "Ka must be positive"); checks.check(Vrmin_ <= Vrmax_, "Vrmin must be less than or equal to Vrmax"); - checks.check(UEL_ >= static_cast(0) && UEL_ <= static_cast(3), - "UEL must be 0, 1, 2, or 3"); + checks.check( + UEL_ >= static_cast(0) && UEL_ <= static_cast(3), + "UEL must be 0, 1, 2, or 3" + ); // Model data uses an exact zero to mean "saturation bypassed", so // this is an exact comparison by intent rather than a tolerance test. const bool saturation_disabled = - Se1_ == ZERO && Se2_ == ZERO; + Se1_ == ZERO && Se2_ == ZERO; if (!saturation_disabled) { @@ -171,7 +173,7 @@ namespace GridKit // An attached port must resolve to writable signal storage. The // enumerator is a template argument, so each port names itself once. auto check_attached_signal = - [&](const char* name) + [&](const char* name) { if (ports_.in.template port().connected() && !ports_.in.template port().linked()) @@ -535,11 +537,12 @@ namespace GridKit template __attribute__((always_inline)) inline int Esdc1a::evaluateInternalResidual( - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - const ScalarT* ws, - ScalarT* f) + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + const ScalarT* ws, + ScalarT* f + ) { const auto EFDP = static_cast(Esdc1aInternalVariables::EFDP); const auto VC = static_cast(Esdc1aInternalVariables::VC); @@ -620,11 +623,9 @@ namespace GridKit * @return Anti-windup-limited derivative. */ template - __attribute__((always_inline)) inline scalar_type - Esdc1a::awmin( - const ScalarT x, - const ScalarT f, - const RealT xmin) + __attribute__((always_inline)) inline scalar_type Esdc1a< + scalar_type, + index_type>::awmin(const ScalarT x, const ScalarT f, const RealT xmin) { const ScalarT above = Math::above(x, xmin); @@ -761,12 +762,11 @@ namespace GridKit // the coefficients stay finite; verify() reports inconsistent data. // The disabled test matches the verify() predicate exactly. const bool saturation_disabled = - Se1_ == ZERO && Se2_ == ZERO; + Se1_ == ZERO && Se2_ == ZERO; const bool sat_ordered = (E2_ > E1_ && Se2_ > Se1_) || (E2_ < E1_ && Se2_ < Se1_); const bool saturation_consistent = - E1_ > ZERO && E2_ > ZERO - && Se1_ >= ZERO && Se2_ >= ZERO - && sat_ordered; + E1_ > ZERO && E2_ > ZERO && Se1_ >= ZERO + && Se2_ >= ZERO && sat_ordered; if (saturation_disabled || !saturation_consistent) { SA_ = ZERO; diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1.hpp b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1.hpp index 7d6c2dd3b2..3e1ead22fa 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1.hpp @@ -104,7 +104,12 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, + const ScalarT*, + const ScalarT*, + const ScalarT*, + ScalarT* + ); private: static constexpr RealT TIME_CONSTANT_MINIMUM = static_cast(1.0e-3); diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Data.hpp b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Data.hpp index 1a88441e08..31b4e7920b 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Data.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Data.hpp @@ -77,14 +77,14 @@ namespace GridKit * Integer parameters are of the same type as matrix and vector indices. */ template - using Ieeet1Data = - ComponentData; + using Ieeet1Data = ComponentData< + real_type, + index_type, + Ieeet1Parameters, + Ieeet1Buses, + Ieeet1SignalInputs, + Ieeet1SignalOutputs, + Ieeet1MonitorableVariables>; } // namespace Exciter } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Enzyme.cpp b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Enzyme.cpp index 9272211299..f24b20d97b 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Enzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Enzyme.cpp @@ -38,66 +38,86 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDy< + GridKit::PhasorDynamics::Exciter::Ieeet1, + GridKit::Enzyme::Sparse::MemberFunctions:: + InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDyp, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - alpha_, - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDyp< + GridKit::PhasorDynamics::Exciter::Ieeet1, + GridKit::Enzyme::Sparse::MemberFunctions:: + InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + alpha_, + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDwb, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(bus_->size()), - (this->getResidualIndices()).data(), - (bus_->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - bus_->y().getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDwb< + GridKit::PhasorDynamics::Exciter::Ieeet1, + GridKit::Enzyme::Sparse::MemberFunctions:: + InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(bus_->size()), + (this->getResidualIndices()).data(), + (bus_->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + bus_->y().getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDws, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(ws_.getSize()), - (this->getResidualIndices()).data(), - ws_indices_.data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDws< + GridKit::PhasorDynamics::Exciter::Ieeet1, + GridKit::Enzyme::Sparse::MemberFunctions:: + InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(ws_.getSize()), + (this->getResidualIndices()).data(), + ws_indices_.data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); this->constructCoo(); diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp index d9a9791995..5f741df1ea 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp @@ -125,11 +125,13 @@ namespace GridKit checks.check(Ka_ > ZERO, "Ka must be positive"); checks.check(Vrmin_ <= Vrmax_, "Vrmin must be less than or equal to Vrmax"); - checks.check(Ispdlim_ == ZERO || Ispdlim_ == ONE, - "Ispdlim must be 0 or 1"); + checks.check( + Ispdlim_ == ZERO || Ispdlim_ == ONE, + "Ispdlim must be 0 or 1" + ); const bool saturation_disabled = - Se1_ == ZERO && Se2_ == ZERO; + Se1_ == ZERO && Se2_ == ZERO; if (!saturation_disabled) { @@ -143,7 +145,7 @@ namespace GridKit } auto check_attached_signal = - [&](const char* name) + [&](const char* name) { auto port = ports_.in.template port(); if (port.connected() && !port.linked()) @@ -351,12 +353,14 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Ieeet1::evaluateInternalResidual( - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - const ScalarT* ws, - ScalarT* f) + __attribute__((always_inline)) inline int + Ieeet1::evaluateInternalResidual( + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + const ScalarT* ws, + ScalarT* f + ) { const auto OMEGA = static_cast(Ieeet1ExternalVariables::OMEGA); const auto VREF = static_cast(Ieeet1ExternalVariables::VREF); @@ -576,7 +580,7 @@ namespace GridKit SB_ = ZERO; const bool saturation_disabled = - Se1_ == ZERO && Se2_ == ZERO; + Se1_ == ZERO && Se2_ == ZERO; if (saturation_disabled) { diff --git a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPti.hpp b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPti.hpp index 40550eb55f..f9b1743de7 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPti.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPti.hpp @@ -91,7 +91,12 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, + const ScalarT*, + const ScalarT*, + const ScalarT*, + ScalarT* + ); private: BusT* bus_{nullptr}; diff --git a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiData.hpp b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiData.hpp index c67ec40059..bb1ac68f15 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiData.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiData.hpp @@ -58,14 +58,14 @@ namespace GridKit }; template - using SexsPtiData = - ComponentData; + using SexsPtiData = ComponentData< + real_type, + index_type, + SexsPtiParameters, + SexsPtiBuses, + SexsPtiSignalInputs, + SexsPtiSignalOutputs, + SexsPtiMonitorableVariables>; } // namespace Exciter } // namespace PhasorDynamics diff --git a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiEnzyme.cpp b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiEnzyme.cpp index 1335ab6f2b..0c6a95f9a9 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiEnzyme.cpp @@ -33,66 +33,86 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDy< + GridKit::PhasorDynamics::Exciter::SexsPti, + GridKit::Enzyme::Sparse::MemberFunctions:: + InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDyp, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - alpha_, - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDyp< + GridKit::PhasorDynamics::Exciter::SexsPti, + GridKit::Enzyme::Sparse::MemberFunctions:: + InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + alpha_, + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDwb, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(bus_->size()), - (this->getResidualIndices()).data(), - (bus_->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - bus_->y().getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDwb< + GridKit::PhasorDynamics::Exciter::SexsPti, + GridKit::Enzyme::Sparse::MemberFunctions:: + InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(bus_->size()), + (this->getResidualIndices()).data(), + (bus_->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + bus_->y().getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDws, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(ws_.getSize()), - (this->getResidualIndices()).data(), - ws_indices_.data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDws< + GridKit::PhasorDynamics::Exciter::SexsPti, + GridKit::Enzyme::Sparse::MemberFunctions:: + InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(ws_.getSize()), + (this->getResidualIndices()).data(), + ws_indices_.data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); this->constructCoo(); diff --git a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp index 16e312de30..34f486d033 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp @@ -122,7 +122,7 @@ namespace GridKit } auto check_attached_signal = - [&](const char* name) + [&](const char* name) { auto port = ports_.in.template port(); if (port.connected() && !port.linked()) @@ -245,12 +245,14 @@ namespace GridKit } template - __attribute__((always_inline)) inline int SexsPti::evaluateInternalResidual( - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - const ScalarT* ws, - ScalarT* f) + __attribute__((always_inline)) inline int + SexsPti::evaluateInternalResidual( + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + const ScalarT* ws, + ScalarT* f + ) { const auto VREF = static_cast(SexsPtiExternalVariables::VREF); const auto VS = static_cast(SexsPtiExternalVariables::VS); diff --git a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPti.hpp b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPti.hpp index 4a10113626..7ef810adc5 100644 --- a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPti.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPti.hpp @@ -105,11 +105,12 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; [[gnu::always_inline]] inline int evaluateInternalResidual( - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - const ScalarT* ws, - ScalarT* f); + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + const ScalarT* ws, + ScalarT* f + ); private: bool floorTimeConstant(RealT& value); diff --git a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiData.hpp b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiData.hpp index c068ed98b4..93d5c652bc 100644 --- a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiData.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiData.hpp @@ -72,14 +72,14 @@ namespace GridKit * @see GastPti */ template - using GastPtiData = - ComponentData; + using GastPtiData = ComponentData< + real_type, + index_type, + GastPtiParameters, + GastPtiBuses, + GastPtiSignalInputs, + GastPtiSignalOutputs, + GastPtiMonitorableVariables>; } // namespace Governor } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiEnzyme.cpp b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiEnzyme.cpp index 829812a75c..335e170cba 100644 --- a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiEnzyme.cpp @@ -44,48 +44,57 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - nullptr, - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDy:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + nullptr, + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDyp::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - nullptr, - ws_.getData(), - alpha_, - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDyp:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + nullptr, + ws_.getData(), + alpha_, + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDws::eval(this, - static_cast(f_.getSize()), - static_cast(ws_.getSize()), - (this->getResidualIndices()).data(), - ws_indices_.data(), - y_.getData(), - yp_.getData(), - nullptr, - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDws:: + eval( + this, + static_cast(f_.getSize()), + static_cast(ws_.getSize()), + (this->getResidualIndices()).data(), + ws_indices_.data(), + y_.getData(), + yp_.getData(), + nullptr, + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); this->constructCoo(); return 0; diff --git a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiImpl.hpp b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiImpl.hpp index 3ca2b13c08..bdeadf611a 100644 --- a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiImpl.hpp @@ -103,8 +103,9 @@ namespace GridKit if (auto pmech_port = ports_.out.template port()) { - pmech_port.link(&y[PMECH], - &(this->getVariableIndex(static_cast(PMECH)))); + pmech_port.link( + &y[PMECH], &(this->getVariableIndex(static_cast(PMECH))) + ); } allocated_ = true; @@ -128,10 +129,14 @@ namespace GridKit Model::ConfigurationChecks checks("GastPti"); checks.check(std::isfinite(R_) && R_ > ZERO, "R must be finite and positive"); - checks.check(std::isfinite(At_) && At_ >= ZERO, - "At must be finite and non-negative"); - checks.check(std::isfinite(Kt_) && Kt_ >= ZERO, - "Kt must be finite and non-negative"); + checks.check( + std::isfinite(At_) && At_ >= ZERO, + "At must be finite and non-negative" + ); + checks.check( + std::isfinite(Kt_) && Kt_ >= ZERO, + "Kt must be finite and non-negative" + ); const bool finite_limits = std::isfinite(Vmin_) && std::isfinite(Vmax_); checks.check(finite_limits, "Vmin and Vmax must be finite"); @@ -140,8 +145,10 @@ namespace GridKit checks.check(Vmin_ <= Vmax_, "Vmin must be less than or equal to Vmax"); } - checks.check(std::isfinite(Dturb_) && Dturb_ >= ZERO, - "Dturb must be finite and non-negative"); + checks.check( + std::isfinite(Dturb_) && Dturb_ >= ZERO, + "Dturb must be finite and non-negative" + ); const bool valid_component_base = std::isfinite(va_component_base_) && va_component_base_ > ZERO; const bool valid_system_base = std::isfinite(va_system_base_) @@ -153,19 +160,24 @@ namespace GridKit { const RealT system_to_component = va_system_base_ / va_component_base_; const RealT component_to_system = va_component_base_ / va_system_base_; - checks.check(std::isfinite(system_to_component) - && system_to_component > ZERO - && std::isfinite(component_to_system) - && component_to_system > ZERO, - "system/component power-base conversion ratios must be finite and positive"); + checks.check( + std::isfinite(system_to_component) + && system_to_component > ZERO + && std::isfinite(component_to_system) + && component_to_system > ZERO, + "system/component power-base conversion ratios must be finite and " + "positive" + ); } - checks.check(ports_.out.template port().connected(), - "pmech output must be assigned"); + checks.check( + ports_.out.template port().connected(), + "pmech output must be assigned" + ); // An attached port must resolve to writable signal storage. auto check_attached_signal = - [&](const char* name) -> bool + [&](const char* name) -> bool { auto port = ports_.in.template port(); @@ -183,12 +195,14 @@ namespace GridKit return false; }; - const auto omega_linked = - check_attached_signal - .template operator()("speed"); - const auto pref_linked = - check_attached_signal - .template operator()("pref"); + const auto omega_linked = + check_attached_signal.template operator()( + "speed" + ); + const auto pref_linked = + check_attached_signal.template operator()( + "pref" + ); if (variable_indices_.size() == static_cast(size_)) { @@ -197,14 +211,18 @@ namespace GridKit if (omega_linked) { auto omega = ports_.in.template port(); - checks.check(omega.signalVariableIndex() != pmech_index, - "speed and pmech ports must use distinct signals"); + checks.check( + omega.signalVariableIndex() != pmech_index, + "speed and pmech ports must use distinct signals" + ); } if (pref_linked) { auto pref = ports_.in.template port(); - checks.check(pref.signalVariableIndex() != pmech_index, - "pref and pmech ports must use distinct signals"); + checks.check( + pref.signalVariableIndex() != pmech_index, + "pref and pmech ports must use distinct signals" + ); } if (omega_linked && pref_linked) { @@ -216,8 +234,10 @@ namespace GridKit if (omega_index != INVALID_INDEX || pref_index != INVALID_INDEX) { - checks.check(omega_index != pref_index, - "speed and pref ports must use distinct signals"); + checks.check( + omega_index != pref_index, + "speed and pref ports must use distinct signals" + ); } } } @@ -324,8 +344,8 @@ namespace GridKit const RealT margin = vtemp0 - xflow0; if (!std::isfinite(margin) || margin <= ZERO) { - Log::error() - << "GastPti: active initial temperature-gate margin must be finite and positive\n"; + Log::error() << "GastPti: active initial temperature-gate margin " + "must be finite and positive\n"; return 1; } @@ -347,8 +367,8 @@ namespace GridKit if (!std::isfinite(vload0) || !std::isfinite(vlv0) || !std::isfinite(pref_component0) || !std::isfinite(pref0)) { - Log::error() - << "GastPti: initial selector, load-demand, and reference candidates must be finite\n"; + Log::error() << "GastPti: initial selector, load-demand, and " + "reference candidates must be finite\n"; return 1; } @@ -513,13 +533,14 @@ namespace GridKit * @param[out] f Model-owned residuals in `GastPtiInternalVariables` order. */ template - [[gnu::always_inline]] inline int - GastPti::evaluateInternalResidual( + [[gnu::always_inline]] inline int GastPti:: + evaluateInternalResidual( const ScalarT* y, const ScalarT* yp, const ScalarT* wb, const ScalarT* ws, - ScalarT* f) + ScalarT* f + ) { const auto XVALVE = static_cast(GastPtiInternalVariables::XVALVE); const auto XFLOW = static_cast(GastPtiInternalVariables::XFLOW); @@ -549,8 +570,9 @@ namespace GridKit const ScalarT omega = ws[OMEGA]; const ScalarT pref = this->toComponentBase(ws[PREF]); - const ScalarT valve_target = - Math::antiwindup(xvalve, vlv - xvalve, Vmin_response_, Vmax_response_); + const ScalarT valve_target = Math::antiwindup( + xvalve, vlv - xvalve, Vmin_response_, Vmax_response_ + ); f[XVALVE] = -xvalve_dot + s_valve_ * valve_target / T1_; f[XFLOW] = -xflow_dot + (-xflow + xvalve) / T2_; diff --git a/GridKit/Model/PhasorDynamics/Governor/HYGOV/Hygov.hpp b/GridKit/Model/PhasorDynamics/Governor/HYGOV/Hygov.hpp index e96e38955d..7ad2c09e3e 100644 --- a/GridKit/Model/PhasorDynamics/Governor/HYGOV/Hygov.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/HYGOV/Hygov.hpp @@ -116,11 +116,12 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - const ScalarT* ws, - ScalarT* f); + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + const ScalarT* ws, + ScalarT* f + ); private: void initializeParameters(const ModelDataT& data); @@ -136,11 +137,9 @@ namespace GridKit /// Bisect a bracketed initialization residual to machine rounding. template - static RealT bisectInitialRoot(RealT a, - RealT b, - RealT fa, - RealT fb, - FuncT residual); + static RealT bisectInitialRoot( + RealT a, RealT b, RealT fa, RealT fb, FuncT residual + ); /// Solve the gate at the configured dam head. RealT solveInitialGate(RealT pmech) const; @@ -153,7 +152,7 @@ namespace GridKit /// Accepted seed distance beyond the achievable-power range edge. static constexpr RealT INITIALIZATION_TOLERANCE = - static_cast(100.0) * std::numeric_limits::epsilon(); + static_cast(100.0) * std::numeric_limits::epsilon(); RealT Rperm_{static_cast(0.04)}; RealT Rtemp_{static_cast(0.3)}; diff --git a/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovData.hpp b/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovData.hpp index 9c9d9c1459..e764238978 100644 --- a/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovData.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovData.hpp @@ -94,14 +94,14 @@ namespace GridKit * @see Hygov */ template - using HygovData = - ComponentData; + using HygovData = ComponentData< + real_type, + index_type, + HygovParameters, + HygovBuses, + HygovSignalInputs, + HygovSignalOutputs, + HygovMonitorableVariables>; } // namespace Governor } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovEnzyme.cpp b/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovEnzyme.cpp index acd5f3db68..f3ad7ba720 100644 --- a/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovEnzyme.cpp @@ -32,48 +32,57 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - nullptr, - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDy:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + nullptr, + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDyp::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - nullptr, - ws_.getData(), - alpha_, - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDyp:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + nullptr, + ws_.getData(), + alpha_, + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDws::eval(this, - static_cast(f_.getSize()), - static_cast(ws_.getSize()), - (this->getResidualIndices()).data(), - ws_indices_.data(), - y_.getData(), - yp_.getData(), - nullptr, - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDws:: + eval( + this, + static_cast(f_.getSize()), + static_cast(ws_.getSize()), + (this->getResidualIndices()).data(), + ws_indices_.data(), + y_.getData(), + yp_.getData(), + nullptr, + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); this->constructCoo(); diff --git a/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovImpl.hpp b/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovImpl.hpp index 376ee99b08..f2c83a4cfa 100644 --- a/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovImpl.hpp @@ -126,10 +126,13 @@ namespace GridKit && va_component_base_ > ZERO; const bool valid_system_base = std::isfinite(va_system_base_) && va_system_base_ > ZERO; - checks.check(valid_component_base, - "component power base must be finite and positive"); - checks.check(valid_system_base, - "system power base must be finite and positive"); + checks.check( + valid_component_base, + "component power base must be finite and positive" + ); + checks.check( + valid_system_base, "system power base must be finite and positive" + ); if (valid_component_base && valid_system_base) { const RealT system_to_component = va_system_base_ / va_component_base_; @@ -138,8 +141,11 @@ namespace GridKit && system_to_component > ZERO && std::isfinite(component_to_system) && component_to_system > ZERO; - checks.check(valid_base_ratios, - "system/component power-base conversion ratios must be finite and positive"); + checks.check( + valid_base_ratios, + "system/component power-base conversion ratios must be finite and " + "positive" + ); } checks.check(Rtemp_ > ZERO, "Rtemp must be nonzero"); @@ -186,22 +192,27 @@ namespace GridKit const bool finite_power_range = std::isfinite(minimum_power) && std::isfinite(maximum_power) && std::isfinite(power_range); - checks.check(finite_power_range, - "mechanical-power range must be finite"); + checks.check( + finite_power_range, "mechanical-power range must be finite" + ); if (finite_power_range) { - checks.check(power_range > INITIALIZATION_TOLERANCE, - "mechanical power must rise across [Gv0, Gv5]"); + checks.check( + power_range > INITIALIZATION_TOLERANCE, + "mechanical power must rise across [Gv0, Gv5]" + ); } } - checks.check(ports_.out.template port().connected(), - "pmech output signal must be assigned"); + checks.check( + ports_.out.template port().connected(), + "pmech output signal must be assigned" + ); // An attached port must resolve to readable signal storage. The // enumerator is a template argument, so each port names itself once. auto check_attached_signal = - [&](const char* name) + [&](const char* name) { if (ports_.in.template port().connected() && !ports_.in.template port().linked()) @@ -557,13 +568,14 @@ namespace GridKit * @return int 0 on success. */ template - __attribute__((always_inline)) inline int - Hygov::evaluateInternalResidual( + __attribute__((always_inline)) inline int Hygov:: + evaluateInternalResidual( const ScalarT* y, const ScalarT* yp, [[maybe_unused]] const ScalarT* wb, const ScalarT* ws, - ScalarT* f) + ScalarT* f + ) { const auto XN = static_cast(HygovInternalVariables::XN); const auto XF = static_cast(HygovInternalVariables::XF); @@ -744,16 +756,18 @@ namespace GridKit { return value != ZERO; }; const bool curve_supplied = - std::any_of(Gv_.begin(), Gv_.end(), is_nonzero) - || std::any_of(Pgv_.begin(), Pgv_.end(), is_nonzero); + std::any_of(Gv_.begin(), Gv_.end(), is_nonzero) + || std::any_of(Pgv_.begin(), Pgv_.end(), is_nonzero); if (!curve_supplied) { - Gv_ = {ZERO, - static_cast(0.2), - static_cast(0.4), - static_cast(0.6), - static_cast(0.8), - ONE}; + Gv_ = { + ZERO, + static_cast(0.2), + static_cast(0.4), + static_cast(0.6), + static_cast(0.8), + ONE + }; Pgv_ = Gv_; } @@ -827,9 +841,9 @@ namespace GridKit * @return Steady mechanical power on the component base. */ template - typename Hygov::RealT - Hygov::initialMechanicalPower(RealT gate, - RealT Hdam) const + typename Hygov::RealT Hygov< + scalar_type, + index_type>::initialMechanicalPower(RealT gate, RealT Hdam) const { const RealT pgv = static_cast(gatePower(static_cast(gate))); const RealT q = std::sqrt(Hdam) * pgv; @@ -856,12 +870,10 @@ namespace GridKit */ template template - typename Hygov::RealT - Hygov::bisectInitialRoot(RealT a, - RealT b, - RealT fa, - RealT fb, - FuncT residual) + typename Hygov::RealT Hygov< + scalar_type, + index_type>:: + bisectInitialRoot(RealT a, RealT b, RealT fa, RealT fb, FuncT residual) { while (true) { diff --git a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp index 4b81414574..eb5034f4f0 100644 --- a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp @@ -95,7 +95,12 @@ namespace GridKit public: __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, + const ScalarT*, + const ScalarT*, + const ScalarT*, + ScalarT* + ); private: // Input parameters diff --git a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Data.hpp b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Data.hpp index fe875ad5e9..7497a598ec 100644 --- a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Data.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Data.hpp @@ -77,14 +77,14 @@ namespace GridKit * @tparam index_type Index type (e.g., size_t) */ template - using Tgov1Data = - ComponentData; + using Tgov1Data = ComponentData< + real_type, + index_type, + Tgov1Parameters, + Tgov1Buses, + Tgov1SignalInputs, + Tgov1SignalOutputs, + Tgov1MonitorableVariables>; } // namespace Governor } // namespace PhasorDynamics diff --git a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Enzyme.cpp b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Enzyme.cpp index b8f79fddee..f6141c7c43 100644 --- a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Enzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Enzyme.cpp @@ -37,51 +37,66 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - nullptr, - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDy< + GridKit::PhasorDynamics::Governor::Tgov1, + GridKit::Enzyme::Sparse::MemberFunctions:: + InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + nullptr, + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDyp, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - nullptr, - ws_.getData(), - alpha_, - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDyp< + GridKit::PhasorDynamics::Governor::Tgov1, + GridKit::Enzyme::Sparse::MemberFunctions:: + InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + nullptr, + ws_.getData(), + alpha_, + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDws, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(ws_.getSize()), - (this->getResidualIndices()).data(), - ws_indices_.data(), - y_.getData(), - yp_.getData(), - nullptr, - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDws< + GridKit::PhasorDynamics::Governor::Tgov1, + GridKit::Enzyme::Sparse::MemberFunctions:: + InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(ws_.getSize()), + (this->getResidualIndices()).data(), + ws_indices_.data(), + y_.getData(), + yp_.getData(), + nullptr, + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); this->constructCoo(); diff --git a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp index ec9fa1d805..b7043c714b 100644 --- a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp @@ -32,8 +32,7 @@ namespace GridKit * @param data Data to initialize the model from. */ template - Tgov1::Tgov1( - const ModelDataT& data) + Tgov1::Tgov1(const ModelDataT& data) { initializeParameters(data); @@ -144,7 +143,8 @@ namespace GridKit auto* y = y_.getData(); const auto PM = static_cast(Tgov1InternalVariables::PM); pmech_port.link( - &y[static_cast(PM)], &(this->getVariableIndex(PM))); + &y[static_cast(PM)], &(this->getVariableIndex(PM)) + ); } allocated_ = true; @@ -163,8 +163,10 @@ namespace GridKit checks.check(va_system_base_ > ZERO, "system power base must be positive"); checks.check(R_ != ZERO, "R must be nonzero"); checks.check(Pvmin_ <= Pvmax_, "Pvmin must be less than or equal to Pvmax"); - checks.check(ports_.out.template port().connected(), - "pmech output signal must be assigned"); + checks.check( + ports_.out.template port().connected(), + "pmech output signal must be assigned" + ); auto speed_port = ports_.in.template port(); if (speed_port.connected() && !speed_port.linked()) @@ -279,12 +281,14 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Tgov1::evaluateInternalResidual( + __attribute__((always_inline)) inline int Tgov1:: + evaluateInternalResidual( const ScalarT* y, const ScalarT* yp, [[maybe_unused]] const ScalarT* wb, const ScalarT* ws, - ScalarT* f) + ScalarT* f + ) { const auto PTX = static_cast(Tgov1InternalVariables::PTX); const auto PV = static_cast(Tgov1InternalVariables::PV); diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZ.hpp b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZ.hpp index 5cc2aa7e00..fc352bde83 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZ.hpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZ.hpp @@ -101,9 +101,11 @@ namespace GridKit public: __attribute__((always_inline)) inline int evaluateBusResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* + ); __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* + ); private: BusT* bus_{nullptr}; diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZData.hpp b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZData.hpp index 2e277ebcf7..c1c8d2493f 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZData.hpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZData.hpp @@ -59,13 +59,13 @@ namespace GridKit * Integer parameters are of the same type as matrix and vector indices. */ template - using LoadZData = - ComponentData; + using LoadZData = ComponentData< + real_type, + index_type, + LoadZParameters, + LoadZBuses, + LoadZSignalInputs, + LoadZSignalOutputs, + LoadZMonitorableVariables>; } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZEnzyme.cpp b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZEnzyme.cpp index 0348f9b24a..a20ef95cb6 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZEnzyme.cpp @@ -35,47 +35,59 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidual>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDy< + GridKit::PhasorDynamics::LoadZ, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidual>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDwb, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidual>::eval(this, - static_cast(f_.getSize()), - static_cast(bus_->size()), - (this->getResidualIndices()).data(), - (bus_->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - bus_->y().getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDwb< + GridKit::PhasorDynamics::LoadZ, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidual>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(bus_->size()), + (this->getResidualIndices()).data(), + (bus_->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + bus_->y().getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DhDy, - GridKit::Enzyme::Sparse::MemberFunctions::BusResidual>::eval(this, - static_cast(bus_->size()), - static_cast(y_.getSize()), - (bus_->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DhDy< + GridKit::PhasorDynamics::LoadZ, + GridKit::Enzyme::Sparse::MemberFunctions::BusResidual>:: + eval( + this, + static_cast(bus_->size()), + static_cast(y_.getSize()), + (bus_->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); this->constructCoo(); diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZImpl.hpp b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZImpl.hpp index ef5af5bf2b..fde033b60e 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZImpl.hpp @@ -21,10 +21,8 @@ namespace GridKit * - Number of independent variables = 2 */ template - LoadZ::LoadZ(BusT* bus, - const ModelDataT& data) - : bus_(bus), - monitor_(std::make_unique(data)) + LoadZ::LoadZ(BusT* bus, const ModelDataT& data) + : bus_(bus), monitor_(std::make_unique(data)) { using Parameter = typename ModelDataT::Parameters; @@ -154,11 +152,13 @@ namespace GridKit * */ template - __attribute__((always_inline)) int LoadZ::evaluateBusResidual( + __attribute__((always_inline)) int LoadZ:: + evaluateBusResidual( const ScalarT* y, [[maybe_unused]] const ScalarT* yp, [[maybe_unused]] const ScalarT* wb, - ScalarT* h) + ScalarT* h + ) { const ScalarT Ir = y[0]; const ScalarT Ii = y[1]; @@ -173,11 +173,13 @@ namespace GridKit * */ template - __attribute__((always_inline)) int LoadZ::evaluateInternalResidual( + __attribute__((always_inline)) int LoadZ:: + evaluateInternalResidual( const ScalarT* y, [[maybe_unused]] const ScalarT* yp, const ScalarT* wb, - ScalarT* f) + ScalarT* f + ) { const ScalarT Vr = wb[0]; const ScalarT Vi = wb[1]; diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIP.hpp b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIP.hpp index c427a043d8..9494d569d3 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIP.hpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIP.hpp @@ -114,9 +114,11 @@ namespace GridKit public: __attribute__((always_inline)) inline int evaluateBusResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* + ); __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* + ); private: BusT* bus_{nullptr}; diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPData.hpp b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPData.hpp index b2adb59173..dae58b1fdf 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPData.hpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPData.hpp @@ -59,13 +59,13 @@ namespace GridKit * Integer parameters are of the same type as matrix and vector indices. */ template - using LoadZIPData = - ComponentData; + using LoadZIPData = ComponentData< + real_type, + index_type, + LoadZIPParameters, + LoadZIPBuses, + LoadZIPSignalInputs, + LoadZIPSignalOutputs, + LoadZIPMonitorableVariables>; } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPEnzyme.cpp b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPEnzyme.cpp index a3190886f2..63f93e5a6a 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPEnzyme.cpp @@ -30,47 +30,59 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidual>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDy< + GridKit::PhasorDynamics::LoadZIP, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidual>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDwb, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidual>::eval(this, - static_cast(f_.getSize()), - static_cast(bus_->size()), - (this->getResidualIndices()).data(), - (bus_->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - bus_->y().getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDwb< + GridKit::PhasorDynamics::LoadZIP, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidual>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(bus_->size()), + (this->getResidualIndices()).data(), + (bus_->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + bus_->y().getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DhDy, - GridKit::Enzyme::Sparse::MemberFunctions::BusResidual>::eval(this, - static_cast(bus_->size()), - static_cast(y_.getSize()), - (bus_->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DhDy< + GridKit::PhasorDynamics::LoadZIP, + GridKit::Enzyme::Sparse::MemberFunctions::BusResidual>:: + eval( + this, + static_cast(bus_->size()), + static_cast(y_.getSize()), + (bus_->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); this->constructCoo(); diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPImpl.hpp b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPImpl.hpp index 64f6bb2a6e..c2ee3b16b8 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPImpl.hpp @@ -18,10 +18,8 @@ namespace GridKit * - Number of independent variables = 2 */ template - LoadZIP::LoadZIP(BusT* bus, - const ModelDataT& data) - : bus_(bus), - monitor_(std::make_unique(data)) + LoadZIP::LoadZIP(BusT* bus, const ModelDataT& data) + : bus_(bus), monitor_(std::make_unique(data)) { initializeParameters(data); initializeMonitor(); @@ -168,11 +166,13 @@ namespace GridKit * */ template - __attribute__((always_inline)) int LoadZIP::evaluateBusResidual( + __attribute__((always_inline)) int LoadZIP:: + evaluateBusResidual( const ScalarT* y, [[maybe_unused]] const ScalarT* yp, [[maybe_unused]] const ScalarT* wb, - ScalarT* h) + ScalarT* h + ) { const ScalarT Ir = y[0]; const ScalarT Ii = y[1]; @@ -215,11 +215,13 @@ namespace GridKit * */ template - __attribute__((always_inline)) int LoadZIP::evaluateInternalResidual( + __attribute__((always_inline)) int LoadZIP:: + evaluateInternalResidual( const ScalarT* y, [[maybe_unused]] const ScalarT* yp, const ScalarT* wb, - ScalarT* f) + ScalarT* f + ) { const ScalarT Vr = wb[0]; const ScalarT Vi = wb[1]; diff --git a/GridKit/Model/PhasorDynamics/ModelData.hpp b/GridKit/Model/PhasorDynamics/ModelData.hpp index 43ff4f3c49..67a783f9c5 100644 --- a/GridKit/Model/PhasorDynamics/ModelData.hpp +++ b/GridKit/Model/PhasorDynamics/ModelData.hpp @@ -18,27 +18,29 @@ namespace GridKit /// Concept implemented by component-model data containers. template concept ModelData = - requires { - typename T::RealT; - typename T::IdxT; - typename T::Parameters; - typename T::Buses; - typename T::SignalInputs; - typename T::SignalOutputs; - typename T::MonitorableVariables; - } - && std::derived_from> - && Utilities::SizedEnum - && Utilities::SizedEnum - && Utilities::SizedEnum - && Utilities::SizedEnum - && Utilities::SizedEnum; + requires { + typename T::RealT; + typename T::IdxT; + typename T::Parameters; + typename T::Buses; + typename T::SignalInputs; + typename T::SignalOutputs; + typename T::MonitorableVariables; + } + && std::derived_from< + T, + ComponentData< + typename T::RealT, + typename T::IdxT, + typename T::Parameters, + typename T::Buses, + typename T::SignalInputs, + typename T::SignalOutputs, + typename T::MonitorableVariables>> + && Utilities::SizedEnum + && Utilities::SizedEnum + && Utilities::SizedEnum + && Utilities::SizedEnum + && Utilities::SizedEnum; } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/PortGroup.hpp b/GridKit/Model/PhasorDynamics/PortGroup.hpp index 6dff970384..f36760f3bf 100644 --- a/GridKit/Model/PhasorDynamics/PortGroup.hpp +++ b/GridKit/Model/PhasorDynamics/PortGroup.hpp @@ -18,10 +18,10 @@ namespace GridKit { /// A type deriving from the `Port` class. template - concept PortType = requires { typename T::ScalarT; typename T::IdxT; } - && std::derived_from>; + concept PortType = requires { + typename T::ScalarT; + typename T::IdxT; + } && std::derived_from>; /// Group of ports indexed by their associated signal-variable enum. template diff --git a/GridKit/Model/PhasorDynamics/SignalSource/ConstantSignalSourceData.hpp b/GridKit/Model/PhasorDynamics/SignalSource/ConstantSignalSourceData.hpp index cc945bda6c..0f6481df98 100644 --- a/GridKit/Model/PhasorDynamics/SignalSource/ConstantSignalSourceData.hpp +++ b/GridKit/Model/PhasorDynamics/SignalSource/ConstantSignalSourceData.hpp @@ -35,14 +35,14 @@ namespace GridKit }; template - using ConstantSignalSourceData = - ComponentData; + using ConstantSignalSourceData = ComponentData< + real_type, + index_type, + ConstantSignalSourceParameters, + ConstantSignalSourceBuses, + ConstantSignalSourceSignalInputs, + ConstantSignalSourceSignalOutputs, + ConstantSignalSourceMonitorableVariables>; } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/SignalSource/FunctionSignalSourceData.hpp b/GridKit/Model/PhasorDynamics/SignalSource/FunctionSignalSourceData.hpp index 88bcc53774..82cef7f9ac 100644 --- a/GridKit/Model/PhasorDynamics/SignalSource/FunctionSignalSourceData.hpp +++ b/GridKit/Model/PhasorDynamics/SignalSource/FunctionSignalSourceData.hpp @@ -35,14 +35,14 @@ namespace GridKit }; template - using FunctionSignalSourceData = - ComponentData; + using FunctionSignalSourceData = ComponentData< + real_type, + index_type, + FunctionSignalSourceParameters, + FunctionSignalSourceBuses, + FunctionSignalSourceSignalInputs, + FunctionSignalSourceSignalOutputs, + FunctionSignalSourceMonitorableVariables>; } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp index 476c67f403..20cf7a38f4 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp @@ -97,11 +97,12 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, - const ScalarT*, - const ScalarT*, - const ScalarT*, - ScalarT*); + const ScalarT*, + const ScalarT*, + const ScalarT*, + const ScalarT*, + ScalarT* + ); private: RealT A1_{0}; diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestData.hpp b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestData.hpp index ff2d4ede08..7d4e980cba 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestData.hpp +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestData.hpp @@ -84,14 +84,14 @@ namespace GridKit * @tparam index_type Integer parameter data type */ template - using IeeestData = - ComponentData; + using IeeestData = ComponentData< + real_type, + index_type, + IeeestParameters, + IeeestBuses, + IeeestSignalInputs, + IeeestSignalOutputs, + IeeestMonitorableVariables>; } // namespace Stabilizer } // namespace PhasorDynamics diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestEnzyme.cpp b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestEnzyme.cpp index 4a421a8475..309048f70e 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestEnzyme.cpp @@ -39,51 +39,66 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - nullptr, - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDy< + GridKit::PhasorDynamics::Stabilizer::Ieeest, + GridKit::Enzyme::Sparse::MemberFunctions:: + InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + nullptr, + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDyp, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - nullptr, - ws_.getData(), - alpha_, - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDyp< + GridKit::PhasorDynamics::Stabilizer::Ieeest, + GridKit::Enzyme::Sparse::MemberFunctions:: + InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + nullptr, + ws_.getData(), + alpha_, + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDws, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(ws_.getSize()), - (this->getResidualIndices()).data(), - ws_indices_.data(), - y_.getData(), - yp_.getData(), - nullptr, - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDws< + GridKit::PhasorDynamics::Stabilizer::Ieeest, + GridKit::Enzyme::Sparse::MemberFunctions:: + InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(ws_.getSize()), + (this->getResidualIndices()).data(), + ws_indices_.data(), + y_.getData(), + yp_.getData(), + nullptr, + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); this->constructCoo(); diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp index 78b302ccba..a8b9dadd59 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp @@ -240,12 +240,14 @@ namespace GridKit } template - __attribute__((always_inline)) inline int Ieeest::evaluateInternalResidual( - const ScalarT* y, - const ScalarT* yp, - [[maybe_unused]] const ScalarT* wb, - const ScalarT* ws, - ScalarT* f) + __attribute__((always_inline)) inline int + Ieeest::evaluateInternalResidual( + const ScalarT* y, + const ScalarT* yp, + [[maybe_unused]] const ScalarT* wb, + const ScalarT* ws, + ScalarT* f + ) { ScalarT x1 = y[0]; ScalarT x2 = y[1]; diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/Genrou.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/Genrou.hpp index db51b66ef4..3458c90fd7 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/Genrou.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/Genrou.hpp @@ -138,9 +138,11 @@ namespace GridKit public: __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* + ); __attribute__((always_inline)) inline int evaluateBusResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* + ); private: /* Identification */ diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouData.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouData.hpp index d503f6ee5d..a8b8ef9627 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouData.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouData.hpp @@ -84,13 +84,13 @@ namespace GridKit * Integer parameters are of the same type as matrix and vector indices. */ template - using GenrouData = - ComponentData; + using GenrouData = ComponentData< + real_type, + index_type, + GenrouParameters, + GenrouBuses, + GenrouSignalInputs, + GenrouSignalOutputs, + GenrouMonitorableVariables>; } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouEnzyme.cpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouEnzyme.cpp index b33c98a55d..a11cb9c778 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouEnzyme.cpp @@ -36,80 +36,100 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDy< + GridKit::PhasorDynamics::Genrou, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDyp, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - alpha_, - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDyp< + GridKit::PhasorDynamics::Genrou, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + alpha_, + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDwb, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(bus_->size()), - (this->getResidualIndices()).data(), - (bus_->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDwb< + GridKit::PhasorDynamics::Genrou, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(bus_->size()), + (this->getResidualIndices()).data(), + (bus_->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDws, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(ws_.getSize()), - (this->getResidualIndices()).data(), - ws_indices_.data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDws< + GridKit::PhasorDynamics::Genrou, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(ws_.getSize()), + (this->getResidualIndices()).data(), + ws_indices_.data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DhDy, - GridKit::Enzyme::Sparse::MemberFunctions::BusResidual>::eval(this, - static_cast(bus_->size()), - static_cast(y_.getSize()), - (bus_->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DhDy< + GridKit::PhasorDynamics::Genrou, + GridKit::Enzyme::Sparse::MemberFunctions::BusResidual>:: + eval( + this, + static_cast(bus_->size()), + static_cast(y_.getSize()), + (bus_->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); this->constructCoo(); diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouImpl.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouImpl.hpp index 8cab9793d8..3984de2f6b 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouImpl.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouImpl.hpp @@ -21,10 +21,8 @@ namespace GridKit * @brief Constructor for a GENROU generator model with saturation */ template - Genrou::Genrou(BusT* bus, - const ModelDataT& data) - : bus_(bus), - monitor_(std::make_unique(data)) + Genrou::Genrou(BusT* bus, const ModelDataT& data) + : bus_(bus), monitor_(std::make_unique(data)) { initializeParameters(data); initializeMonitor(); @@ -202,8 +200,10 @@ namespace GridKit const ScalarT ksat_prime = ONE + Xqd_ * ksat; const ScalarT xsat_delta = ksat_prime * Xdpp_ + Xq_ - Xqpp_; - ScalarT delta = std::atan2((vi + Ra_ * ii) * ksat_prime + xsat_delta * ir, - (vr + Ra_ * ir) * ksat_prime - xsat_delta * ii); + ScalarT delta = std::atan2( + (vi + Ra_ * ii) * ksat_prime + xsat_delta * ir, + (vr + Ra_ * ir) * ksat_prime - xsat_delta * ii + ); ScalarT id = ir * std::sin(delta) - ii * std::cos(delta); ScalarT iq = ir * std::cos(delta) + ii * std::sin(delta); ScalarT vq = vr * std::cos(delta) + vi * std::sin(delta) + id * Xqpp_ + iq * Ra_; @@ -309,12 +309,14 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Genrou::evaluateInternalResidual( + __attribute__((always_inline)) inline int Genrou:: + evaluateInternalResidual( const ScalarT* y, const ScalarT* yp, const ScalarT* wb, const ScalarT* ws, - ScalarT* f) + ScalarT* f + ) { /* Read variables */ ScalarT delta = y[0]; @@ -382,11 +384,13 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Genrou::evaluateBusResidual( + __attribute__((always_inline)) inline int Genrou:: + evaluateBusResidual( const ScalarT* y, [[maybe_unused]] const ScalarT* yp, [[maybe_unused]] const ScalarT* wb, - ScalarT* h) + ScalarT* h + ) { ScalarT ir = y[15]; ScalarT ii = y[16]; diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/Gensal.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/Gensal.hpp index a6505e4c8c..73d7fe980f 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/Gensal.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/Gensal.hpp @@ -134,9 +134,11 @@ namespace GridKit public: __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* + ); __attribute__((always_inline)) inline int evaluateBusResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* + ); private: /* Identification */ diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalData.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalData.hpp index 9462915b6d..f8d55827d5 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalData.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalData.hpp @@ -90,13 +90,13 @@ namespace GridKit * Integer parameters are of the same type as matrix and vector indices. */ template - using GensalData = - ComponentData; + using GensalData = ComponentData< + real_type, + index_type, + GensalParameters, + GensalBuses, + GensalSignalInputs, + GensalSignalOutputs, + GensalMonitorableVariables>; } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalEnzyme.cpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalEnzyme.cpp index fc5d581e27..5364df000a 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalEnzyme.cpp @@ -36,80 +36,100 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDy< + GridKit::PhasorDynamics::Gensal, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDyp, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - alpha_, - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDyp< + GridKit::PhasorDynamics::Gensal, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + alpha_, + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDwb, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(bus_->size()), - (this->getResidualIndices()).data(), - (bus_->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDwb< + GridKit::PhasorDynamics::Gensal, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(bus_->size()), + (this->getResidualIndices()).data(), + (bus_->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDws, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(ws_.getSize()), - (this->getResidualIndices()).data(), - ws_indices_.data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDws< + GridKit::PhasorDynamics::Gensal, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(ws_.getSize()), + (this->getResidualIndices()).data(), + ws_indices_.data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DhDy, - GridKit::Enzyme::Sparse::MemberFunctions::BusResidual>::eval(this, - static_cast(bus_->size()), - static_cast(y_.getSize()), - (bus_->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DhDy< + GridKit::PhasorDynamics::Gensal, + GridKit::Enzyme::Sparse::MemberFunctions::BusResidual>:: + eval( + this, + static_cast(bus_->size()), + static_cast(y_.getSize()), + (bus_->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); this->constructCoo(); diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalImpl.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalImpl.hpp index 3fd8dd07a6..26a4c33282 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalImpl.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalImpl.hpp @@ -302,12 +302,14 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Gensal::evaluateInternalResidual( + __attribute__((always_inline)) inline int Gensal:: + evaluateInternalResidual( const ScalarT* y, const ScalarT* yp, const ScalarT* wb, const ScalarT* ws, - ScalarT* f) + ScalarT* f + ) { /* Read variables */ ScalarT delta = y[0]; @@ -368,11 +370,13 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Gensal::evaluateBusResidual( + __attribute__((always_inline)) inline int Gensal:: + evaluateBusResidual( const ScalarT* y, [[maybe_unused]] const ScalarT* yp, [[maybe_unused]] const ScalarT* wb, - ScalarT* h) + ScalarT* h + ) { ScalarT ir = y[12]; ScalarT ii = y[13]; diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassical.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassical.hpp index d1dd37b209..5072030e59 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassical.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassical.hpp @@ -123,9 +123,11 @@ namespace GridKit public: __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* + ); __attribute__((always_inline)) inline int evaluateBusResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* + ); private: /* Identification */ diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalData.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalData.hpp index 8b6e12d723..65b028171a 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalData.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalData.hpp @@ -72,13 +72,13 @@ namespace GridKit * Integer parameters are of the same type as matrix and vector indices. */ template - using GenClassicalData = - ComponentData; + using GenClassicalData = ComponentData< + real_type, + index_type, + GenClassicalParameters, + GenClassicalBuses, + GenClassicalSignalInputs, + GenClassicalSignalOutputs, + GenClassicalMonitorableVariables>; } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalEnzyme.cpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalEnzyme.cpp index 4e522fda48..9ee609017c 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalEnzyme.cpp @@ -36,80 +36,100 @@ namespace GridKit nnz_ = 0; - GridKit::Enzyme::Sparse::DfDy, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDy< + GridKit::PhasorDynamics::GenClassical, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDyp, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - alpha_, - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDyp< + GridKit::PhasorDynamics::GenClassical, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(y_.getSize()), + (this->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + alpha_, + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDwb, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(bus_->size()), - (this->getResidualIndices()).data(), - (bus_->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDwb< + GridKit::PhasorDynamics::GenClassical, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(bus_->size()), + (this->getResidualIndices()).data(), + (bus_->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DfDws, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>::eval(this, - static_cast(f_.getSize()), - static_cast(ws_.getSize()), - (this->getResidualIndices()).data(), - ws_indices_.data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - ws_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DfDws< + GridKit::PhasorDynamics::GenClassical, + GridKit::Enzyme::Sparse::MemberFunctions::InternalResidualWithSignal>:: + eval( + this, + static_cast(f_.getSize()), + static_cast(ws_.getSize()), + (this->getResidualIndices()).data(), + ws_indices_.data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + ws_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); - GridKit::Enzyme::Sparse::DhDy, - GridKit::Enzyme::Sparse::MemberFunctions::BusResidual>::eval(this, - static_cast(bus_->size()), - static_cast(y_.getSize()), - (bus_->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); + GridKit::Enzyme::Sparse::DhDy< + GridKit::PhasorDynamics::GenClassical, + GridKit::Enzyme::Sparse::MemberFunctions::BusResidual>:: + eval( + this, + static_cast(bus_->size()), + static_cast(y_.getSize()), + (bus_->getResidualIndices()).data(), + (this->getVariableIndices()).data(), + y_.getData(), + yp_.getData(), + wb_.getData(), + J_rows_buffer_, + J_cols_buffer_, + J_vals_buffer_, + nnz_ + ); this->constructCoo(); diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalImpl.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalImpl.hpp index 83acd1e46d..523d0bef77 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalImpl.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalImpl.hpp @@ -261,12 +261,14 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int GenClassical::evaluateInternalResidual( - const ScalarT* y, - const ScalarT* yp, - const ScalarT* wb, - const ScalarT* ws, - ScalarT* f) + __attribute__((always_inline)) inline int + GenClassical::evaluateInternalResidual( + const ScalarT* y, + const ScalarT* yp, + const ScalarT* wb, + const ScalarT* ws, + ScalarT* f + ) { // Set variable aliases for better readability. const ScalarT delta = y[0]; @@ -306,11 +308,13 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int GenClassical::evaluateBusResidual( - const ScalarT* y, - [[maybe_unused]] const ScalarT* yp, - [[maybe_unused]] const ScalarT* wb, - ScalarT* h) + __attribute__((always_inline)) inline int + GenClassical::evaluateBusResidual( + const ScalarT* y, + [[maybe_unused]] const ScalarT* yp, + [[maybe_unused]] const ScalarT* wb, + ScalarT* h + ) { const ScalarT ir = y[3]; const ScalarT ii = y[4]; diff --git a/GridKit/Model/PhasorDynamics/SystemModel.hpp b/GridKit/Model/PhasorDynamics/SystemModel.hpp index 7833d82055..d2e38582c2 100644 --- a/GridKit/Model/PhasorDynamics/SystemModel.hpp +++ b/GridKit/Model/PhasorDynamics/SystemModel.hpp @@ -85,8 +85,10 @@ namespace GridKit SystemModel(const SystemModelData& data); - SystemModel(const SystemModelData& data, - const std::vector& external_buses); + SystemModel( + const SystemModelData& data, + const std::vector& external_buses + ); virtual ~SystemModel(); diff --git a/GridKit/Model/PhasorDynamics/SystemModelImpl.hpp b/GridKit/Model/PhasorDynamics/SystemModelImpl.hpp index 85224f88bd..c1141746d2 100644 --- a/GridKit/Model/PhasorDynamics/SystemModelImpl.hpp +++ b/GridKit/Model/PhasorDynamics/SystemModelImpl.hpp @@ -52,8 +52,10 @@ namespace GridKit * use */ template - SystemModel::SystemModel(const SystemModelData& data, - const std::vector& external_buses) + SystemModel::SystemModel( + const SystemModelData& data, + const std::vector& external_buses + ) : SystemModel() { using namespace Governor; @@ -123,9 +125,8 @@ namespace GridKit bus2_index = branchdata.buses.at(BranchBuses::bus2); } - auto* branch = new BranchT(getBus(bus1_index), - getBus(bus2_index), - branchdata); + auto* branch = + new BranchT(getBus(bus1_index), getBus(bus2_index), branchdata); addComponent(branch, branchdata.label()); } @@ -152,8 +153,8 @@ namespace GridKit { bus_index = loadzipdata.buses.at(LoadZIPBuses::bus); } - auto* loadzip = new LoadZIP(getBus(bus_index), - loadzipdata); + auto* loadzip = + new LoadZIP(getBus(bus_index), loadzipdata); addComponent(loadzip, loadzipdata.label()); } @@ -955,8 +956,7 @@ namespace GridKit IdxT gridkit_component_id = static_cast(components_.size()); component->setGridKitComponentID(gridkit_component_id); - component->setSystemBase(this->freq_system_base_, - this->va_system_base_); + component->setSystemBase(this->freq_system_base_, this->va_system_base_); components_.push_back(component); component_labels_.push_back(label); if (!label.empty()) @@ -1008,7 +1008,8 @@ namespace GridKit */ template void SystemModel::setSystemBase( - RealT freq_system_base, RealT va_system_base) + RealT freq_system_base, RealT va_system_base + ) { ComponentT::setSystemBase(freq_system_base, va_system_base); diff --git a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp index 44b471f6de..fa624f26ef 100644 --- a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp +++ b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp @@ -16,11 +16,13 @@ namespace GridKit * Calls default ModelEvaluatorImpl constructor. */ template - DistributedGenerator::DistributedGenerator(IdxT id, - DistributedGeneratorParameters parm, - bool reference_frame, - NodeT* node_ref, - NodeT* node_bus) + DistributedGenerator::DistributedGenerator( + IdxT id, + DistributedGeneratorParameters parm, + bool reference_frame, + NodeT* node_ref, + NodeT* node_bus + ) : wb_(parm.wb_), wc_(parm.wc_), mp_(parm.mp_), @@ -227,8 +229,10 @@ namespace GridKit { rtemp.push_back(1); ctemp.push_back(15); - valtemp.push_back(-std::sin(delta) * static_cast(y_int_[10]) - - std::cos(delta) * static_cast(y_int_[11])); + valtemp.push_back( + -std::sin(delta) * static_cast(y_int_[10]) + - std::cos(delta) * static_cast(y_int_[11]) + ); } this->setJacValues(rtemp, ctemp, valtemp); @@ -240,29 +244,35 @@ namespace GridKit { rtemp.push_back(2); ctemp.push_back(15); - valtemp.push_back(std::cos(delta) * static_cast(y_int_[10]) - - std::sin(delta) * static_cast(y_int_[11])); + valtemp.push_back( + std::cos(delta) * static_cast(y_int_[10]) + - std::sin(delta) * static_cast(y_int_[11]) + ); } this->setJacValues(rtemp, ctemp, valtemp); // r = 3 rtemp.assign(5, 3); ctemp = {3, 11, 12, 13, 14}; - valtemp = {-wc_ - alpha_, - wc_ * static_cast(y_int_[10]), - wc_ * static_cast(y_int_[11]), - wc_ * static_cast(y_int_[8]), - wc_ * static_cast(y_int_[9])}; + valtemp = { + -wc_ - alpha_, + wc_ * static_cast(y_int_[10]), + wc_ * static_cast(y_int_[11]), + wc_ * static_cast(y_int_[8]), + wc_ * static_cast(y_int_[9]) + }; this->setJacValues(rtemp, ctemp, valtemp); // r = 4 rtemp.assign(5, 4); ctemp = {4, 11, 12, 13, 14}; - valtemp = {-wc_ - alpha_, - -wc_ * static_cast(y_int_[11]), - wc_ * static_cast(y_int_[10]), - wc_ * static_cast(y_int_[9]), - -wc_ * static_cast(y_int_[8])}; + valtemp = { + -wc_ - alpha_, + -wc_ * static_cast(y_int_[11]), + wc_ * static_cast(y_int_[10]), + wc_ * static_cast(y_int_[9]), + -wc_ * static_cast(y_int_[8]) + }; this->setJacValues(rtemp, ctemp, valtemp); // r = 5 @@ -292,60 +302,68 @@ namespace GridKit // r = 9 rtemp.assign(9, 9); ctemp = {3, 4, 5, 7, 9, 10, 11, 12, 13}; - valtemp = {-mp_ * static_cast(y_int_[7]), - -(Kpc_ * Kpv_ * nq_) / Lf_, - (Kpc_ * Kiv_) / Lf_, - Kic_ / Lf_, - -(Kpc_ + rLf_) / Lf_ - alpha_, - -mp_ * static_cast(y_int_[0]), - -(Kpc_ * Kpv_ + 1.0) / Lf_, - -(Cf_ * Kpc_ * wb_) / Lf_, - (F_ * Kpc_) / Lf_}; + valtemp = { + -mp_ * static_cast(y_int_[7]), + -(Kpc_ * Kpv_ * nq_) / Lf_, + (Kpc_ * Kiv_) / Lf_, + Kic_ / Lf_, + -(Kpc_ + rLf_) / Lf_ - alpha_, + -mp_ * static_cast(y_int_[0]), + -(Kpc_ * Kpv_ + 1.0) / Lf_, + -(Cf_ * Kpc_ * wb_) / Lf_, + (F_ * Kpc_) / Lf_ + }; this->setJacValues(rtemp, ctemp, valtemp); // r = 10 rtemp.assign(8, 10); ctemp = {3, 6, 8, 9, 10, 11, 12, 14}; - valtemp = {mp_ * static_cast(y_int_[6]), - (Kiv_ * Kpc_) / Lf_, - Kic_ / Lf_, - mp_ * static_cast(y_int_[0]), - -(Kpc_ + rLf_) / Lf_ - alpha_, - (Cf_ * Kpc_ * wb_) / Lf_, - -(Kpc_ * Kpv_ + 1.0) / Lf_, - (F_ * Kpc_) / Lf_}; + valtemp = { + mp_ * static_cast(y_int_[6]), + (Kiv_ * Kpc_) / Lf_, + Kic_ / Lf_, + mp_ * static_cast(y_int_[0]), + -(Kpc_ + rLf_) / Lf_ - alpha_, + (Cf_ * Kpc_ * wb_) / Lf_, + -(Kpc_ * Kpv_ + 1.0) / Lf_, + (F_ * Kpc_) / Lf_ + }; this->setJacValues(rtemp, ctemp, valtemp); // r = 11 rtemp.assign(5, 11); ctemp = {3, 9, 11, 12, 13}; - valtemp = {-mp_ * static_cast(y_int_[9]), - 1.0 / Cf_, - -alpha_, - wb_ - mp_ * static_cast(y_int_[0]), - -1.0 / Cf_}; + valtemp = { + -mp_ * static_cast(y_int_[9]), + 1.0 / Cf_, + -alpha_, + wb_ - mp_ * static_cast(y_int_[0]), + -1.0 / Cf_ + }; this->setJacValues(rtemp, ctemp, valtemp); // r = 12 rtemp.assign(5, 12); ctemp = {3, 10, 11, 12, 14}; - valtemp = {mp_ * static_cast(y_int_[8]), - 1.0 / Cf_, - -wb_ + mp_ * static_cast(y_int_[0]), - -alpha_, - -1.0 / Cf_}; + valtemp = { + mp_ * static_cast(y_int_[8]), + 1.0 / Cf_, + -wb_ + mp_ * static_cast(y_int_[0]), + -alpha_, + -1.0 / Cf_ + }; this->setJacValues(rtemp, ctemp, valtemp); // r = 13 rtemp.assign(6, 13); ctemp = {1, 2, 3, 11, 13, 14}; valtemp = { - (1.0 / Lc_) * -std::cos(delta), - (1.0 / Lc_) * -std::sin(delta), - -mp_ * static_cast(y_int_[11]), - 1.0 / Lc_, - -rLc_ / Lc_ - alpha_, - wb_ - mp_ * static_cast(y_int_[0]), + (1.0 / Lc_) * -std::cos(delta), + (1.0 / Lc_) * -std::sin(delta), + -mp_ * static_cast(y_int_[11]), + 1.0 / Lc_, + -rLc_ / Lc_ - alpha_, + wb_ - mp_ * static_cast(y_int_[0]), }; if (!refframe_) { @@ -359,12 +377,12 @@ namespace GridKit rtemp.assign(6, 14); ctemp = {1, 2, 3, 12, 13, 14}; valtemp = { - (1.0 / Lc_) * std::sin(delta), - (1.0 / Lc_) * -std::cos(delta), - mp_ * static_cast(y_int_[10]), - 1.0 / Lc_, - -wb_ + mp_ * static_cast(y_int_[0]), - -rLc_ / Lc_ - alpha_, + (1.0 / Lc_) * std::sin(delta), + (1.0 / Lc_) * -std::cos(delta), + mp_ * static_cast(y_int_[10]), + 1.0 / Lc_, + -wb_ + mp_ * static_cast(y_int_[0]), + -rLc_ / Lc_ - alpha_, }; if (!refframe_) { diff --git a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp index eb667d67dd..f23217a611 100644 --- a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp +++ b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp @@ -67,11 +67,13 @@ namespace GridKit using Component::n_intern_; public: - DistributedGenerator(IdxT id, - DistributedGeneratorParameters parm, - bool reference_frame, - NodeT* node_ref, - NodeT* node_bus); + DistributedGenerator( + IdxT id, + DistributedGeneratorParameters parm, + bool reference_frame, + NodeT* node_ref, + NodeT* node_bus + ); virtual ~DistributedGenerator(); int initialize(); diff --git a/GridKit/Model/PowerElectronics/NodeBase.hpp b/GridKit/Model/PowerElectronics/NodeBase.hpp index 6e95322f1b..304dbb053c 100644 --- a/GridKit/Model/PowerElectronics/NodeBase.hpp +++ b/GridKit/Model/PowerElectronics/NodeBase.hpp @@ -129,10 +129,10 @@ namespace GridKit ExternalConnection getNodeConnection(size_t local_index) const { return ExternalConnection{ - .y_ = y_ext_[local_index], - .yp_ = yp_ext_[local_index], - .f_ = f_ext_[local_index], - .idx_ = connection_nodes_[local_index], + .y_ = y_ext_[local_index], + .yp_ = yp_ext_[local_index], + .f_ = f_ext_[local_index], + .idx_ = connection_nodes_[local_index], }; } diff --git a/GridKit/Model/PowerElectronics/SystemModel.hpp b/GridKit/Model/PowerElectronics/SystemModel.hpp index 022a118957..48629a4e89 100644 --- a/GridKit/Model/PowerElectronics/SystemModel.hpp +++ b/GridKit/Model/PowerElectronics/SystemModel.hpp @@ -160,10 +160,11 @@ namespace GridKit for (size_t i = 0; i < node->getInternalSize(); i++) { ExternalConnection node_connection{ - .y_ = y_int_ + node_internal_idx, - .yp_ = yp_int_ + node_internal_idx, - .f_ = f_int_ + node_internal_idx, - .idx_ = static_cast(node_internal_idx)}; + .y_ = y_int_ + node_internal_idx, + .yp_ = yp_int_ + node_internal_idx, + .f_ = f_int_ + node_internal_idx, + .idx_ = static_cast(node_internal_idx) + }; node->setExternalConnectionNodes(i, node_connection); node_internal_idx++; diff --git a/GridKit/Model/PowerFlow/MatpowerParser.hpp b/GridKit/Model/PowerFlow/MatpowerParser.hpp index 26c0b79a8e..ef6cf73d57 100644 --- a/GridKit/Model/PowerFlow/MatpowerParser.hpp +++ b/GridKit/Model/PowerFlow/MatpowerParser.hpp @@ -25,12 +25,13 @@ namespace GridKit /// @cond DOXYGEN_INTERNAL static const std::string matlab_syntax_error{ - "Only a subset of Matlab syntax is supported." - "\n\t'=' for assignment must be on the same line as the field, eg " - "`mpc.version = '2'`." - "\n\tOpen brace ('[') must be on the same line as the field for matrix " - "initialization." - "\n\tEach row of a matrix must be terminated by a semicolon."}; + "Only a subset of Matlab syntax is supported." + "\n\t'=' for assignment must be on the same line as the field, eg " + "`mpc.version = '2'`." + "\n\tOpen brace ('[') must be on the same line as the field for matrix " + "initialization." + "\n\tEach row of a matrix must be terminated by a semicolon." + }; /// @endcond @@ -103,19 +104,19 @@ namespace GridKit { logs() << "Parsing MATPOWER bus row\n"; std::stringstream is(row); - is >> br.bus_i // Bus ID - >> br.type // Bus type: 1 = PQ, 2 = PV, 3 = ref, 4 = isolated - >> lr.Pd // Active power demand [MW] - >> lr.Qd // Reactive power demand [MVAr] - >> br.Gs // Shunt conductance (MW demanded at V = 1.0 p.u.) - >> br.Bs // Shunt susceptance (MVAr injected at V = 1.0 p.u.) - >> br.area // Area number (>0) - >> br.Vm // Voltage magnitude (p.u.) - >> br.Va // Voltage phase (deg) - >> br.baseKV // Base voltage [kV] - >> br.zone // Loss zone number (>0) - >> br.Vmax // Maximum voltage magnitude (p.u.) - >> br.Vmin; // Minimum voltage magnitude (p.u.) + is >> br.bus_i // Bus ID + >> br.type // Bus type: 1 = PQ, 2 = PV, 3 = ref, 4 = isolated + >> lr.Pd // Active power demand [MW] + >> lr.Qd // Reactive power demand [MVAr] + >> br.Gs // Shunt conductance (MW demanded at V = 1.0 p.u.) + >> br.Bs // Shunt susceptance (MVAr injected at V = 1.0 p.u.) + >> br.area // Area number (>0) + >> br.Vm // Voltage magnitude (p.u.) + >> br.Va // Voltage phase (deg) + >> br.baseKV // Base voltage [kV] + >> br.zone // Loss zone number (>0) + >> br.Vmax // Maximum voltage magnitude (p.u.) + >> br.Vmin; // Minimum voltage magnitude (p.u.) lr.bus_i = br.bus_i; } @@ -126,9 +127,9 @@ namespace GridKit logs() << "Parsing MATPOWER gen row\n"; std::stringstream is(row); is >> gr.bus >> gr.Pg >> gr.Qg >> gr.Qmax >> gr.Qmin >> gr.Vg >> gr.mBase - >> gr.status >> gr.Pmax >> gr.Pmin >> gr.Pc1 >> gr.Pc2 >> gr.Qc1min - >> gr.Qc1max >> gr.Qc2min >> gr.Qc2max >> gr.ramp_agc >> gr.ramp_10 - >> gr.ramp_30 >> gr.ramp_q >> gr.apf; + >> gr.status >> gr.Pmax >> gr.Pmin >> gr.Pc1 >> gr.Pc2 >> gr.Qc1min + >> gr.Qc1max >> gr.Qc2min >> gr.Qc2max >> gr.ramp_agc >> gr.ramp_10 + >> gr.ramp_30 >> gr.ramp_q >> gr.apf; checkEndOfMatrixRow(is); } @@ -138,8 +139,8 @@ namespace GridKit logs() << "Parsing MATPOWER branch row\n"; std::stringstream is(row); is >> br.fbus >> br.tbus >> br.r >> br.x >> br.b >> br.rateA >> br.rateB - >> br.rateC >> br.ratio >> br.angle >> br.status >> br.angmin - >> br.angmax; + >> br.rateC >> br.ratio >> br.angle >> br.status >> br.angmin + >> br.angmax; checkEndOfMatrixRow(is); } @@ -200,9 +201,10 @@ namespace GridKit readMatPower(mp, ifs); } - template + template < + typename IdxT = int, + typename RealT = double, + std::size_t MaxLineSize = 1028> void readMatPower(SystemModelData& mp, std::istream& is) { using BusDataT = BusData; diff --git a/GridKit/Model/VariableMonitor.hpp b/GridKit/Model/VariableMonitor.hpp index c482ff291c..906ff6522e 100644 --- a/GridKit/Model/VariableMonitor.hpp +++ b/GridKit/Model/VariableMonitor.hpp @@ -35,11 +35,13 @@ namespace GridKit std::array buffer{}; constexpr auto precision = std::numeric_limits::digits10 + 1; - auto [ptr, ec] = std::to_chars(buffer.data(), - buffer.data() + buffer.size(), - value, - std::chars_format::scientific, - precision); + auto [ptr, ec] = std::to_chars( + buffer.data(), + buffer.data() + buffer.size(), + value, + std::chars_format::scientific, + precision + ); if (ec == std::errc{}) { diff --git a/GridKit/Model/VariableMonitorController.hpp b/GridKit/Model/VariableMonitorController.hpp index 512ff8b534..944b3df3ee 100644 --- a/GridKit/Model/VariableMonitorController.hpp +++ b/GridKit/Model/VariableMonitorController.hpp @@ -471,12 +471,13 @@ namespace GridKit }; /// Variant type for all possible sink types - using SinkVariant = std::variant, - Sink, - Sink, - Sink, - Sink, - Sink>; + using SinkVariant = std::variant< + Sink, + Sink, + Sink, + Sink, + Sink, + Sink>; /** * @brief Construct the sink type whose format and layout match the spec diff --git a/GridKit/Model/VariableMonitorImpl.hpp b/GridKit/Model/VariableMonitorImpl.hpp index 3bc94790ae..d05469fb1e 100644 --- a/GridKit/Model/VariableMonitorImpl.hpp +++ b/GridKit/Model/VariableMonitorImpl.hpp @@ -19,10 +19,11 @@ namespace GridKit * @brief Manage printing variables associated with a specific component or * bus */ - template typename eval_type, - template typename model_data_type> + template < + typename scalar_type, + typename index_type, + template typename eval_type, + template typename model_data_type> class VariableMonitor, model_data_type> : public VariableMonitorBase { @@ -53,11 +54,12 @@ namespace GridKit * * @pre id contains only ASCII letters, digits, spaces, '_', '.' and '-'. */ - VariableMonitor(const std::string& device_class, - const std::string& id, - const std::set& variables) - : device_class_(device_class), - id_(id) + VariableMonitor( + const std::string& device_class, + const std::string& id, + const std::set& variables + ) + : device_class_(device_class), id_(id) { std::ranges::copy(variables, std::back_inserter(variables_)); } @@ -68,9 +70,11 @@ namespace GridKit * @param data Expected to be derived from ComponentData */ VariableMonitor(const ObjData& data) - : VariableMonitor(data.device_class, - data.disambiguation_string, - data.monitored_variables) + : VariableMonitor( + data.device_class, + data.disambiguation_string, + data.monitored_variables + ) { } @@ -93,8 +97,10 @@ namespace GridKit void set(VariableEnum v, FuncT f) { using RetT = std::remove_cvref_t>; - static_assert(std::is_floating_point_v || std::is_same_v, - "Monitored variables must be real valued"); + static_assert( + std::is_floating_point_v || std::is_same_v, + "Monitored variables must be real valued" + ); f_[static_cast(enum_integer(v))] = [f] { return static_cast(f()); }; } diff --git a/GridKit/Solver/Dynamic/Ida.cpp b/GridKit/Solver/Dynamic/Ida.cpp index 0a9eaa8873..98958e7aa5 100644 --- a/GridKit/Solver/Dynamic/Ida.cpp +++ b/GridKit/Solver/Dynamic/Ida.cpp @@ -1,4 +1,3 @@ - #include "Ida.hpp" #include @@ -98,13 +97,14 @@ namespace AnalysisManager checkOutput(retval, "IDASetId"); setIDAOptions( - solver_, - time_step_, - rel_tol_, - abs_tol_override_, - max_steps_, - max_order_, - suppress_alg_); + solver_, + time_step_, + rel_tol_, + abs_tol_override_, + max_steps_, + max_order_, + suppress_alg_ + ); // Set up linear solver return this->configureLinearSolver(); @@ -114,7 +114,7 @@ namespace AnalysisManager * @brief Configure the linear solver * * @note This currently uses pre-processor directives to set dense or sparse - * linear solvers + * linear solvers * * @tparam ScalarT * @tparam IdxT @@ -164,7 +164,7 @@ namespace AnalysisManager sunindextype n = static_cast(model_->size()); sunindextype nnz = - static_cast(model_->getCsrJacobian()->getNnz()); + static_cast(model_->getCsrJacobian()->getNnz()); JacobianMat_ = SUNSparseMatrix(n, n, nnz, CSR_MAT, context_); checkAllocation((void*) JacobianMat_, "SUNSparseMatrix"); @@ -198,9 +198,10 @@ namespace AnalysisManager int retval = 0; JacobianMat_ = SUNDenseMatrix( - static_cast(model_->size()), - static_cast(model_->size()), - context_); + static_cast(model_->size()), + static_cast(model_->size()), + context_ + ); checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); @@ -237,7 +238,8 @@ namespace AnalysisManager */ template int Ida::initializeSimulation( - RealT t0, bool findConsistent, bool printMonitor) + RealT t0, bool findConsistent, bool printMonitor + ) { int retval = 0; @@ -288,8 +290,8 @@ namespace AnalysisManager const RealT n_est = (tf - t_init_) / dt; const RealT epsilon = - std::numeric_limits::epsilon() - * std::max({std::abs(t_init_), std::abs(tf), RealT(1.0)}) / dt; + std::numeric_limits::epsilon() + * std::max({std::abs(t_init_), std::abs(tf), RealT(1.0)}) / dt; return static_cast(std::ceil(n_est - epsilon)); } @@ -327,8 +329,8 @@ namespace AnalysisManager return IDA_YA_YDP_INIT; default: GridKit::Utilities::Logger::error() - << "Invalid IDA consistent initial condition type " - << static_cast(consistent_ic_type_) << ".\n"; + << "Invalid IDA consistent initial condition type " + << static_cast(consistent_ic_type_) << ".\n"; throw SundialsException(); } } @@ -342,9 +344,10 @@ namespace AnalysisManager */ template int Ida::runSimulation( - RealT tf, - RealT dt_monitor, - const std::optional step_callback) + RealT tf, + RealT dt_monitor, + const std::optional step_callback + ) { int retval = 0; int nsteps = getStepCount(tf, dt_monitor); @@ -361,12 +364,13 @@ namespace AnalysisManager template int Ida::runSimulationStep( - RealT tf, - RealT dt_monitor, - int step, - int nsteps, - const std::optional callback, - bool printMonitor) + RealT tf, + RealT dt_monitor, + int step, + int nsteps, + const std::optional callback, + bool printMonitor + ) { const RealT tout = getMonitorTime(tf, dt_monitor, step, nsteps); RealT tret; @@ -423,7 +427,8 @@ namespace AnalysisManager // Create and initialize quadratures q_ = N_VNew_Serial( - static_cast(model_->sizeQuadrature()), context_); + static_cast(model_->sizeQuadrature()), context_ + ); checkAllocation((void*) q_, "N_VNew_Serial"); // Set integrand function and allocate quadrature workspace @@ -432,7 +437,8 @@ namespace AnalysisManager // Set tolerances and error control for quadratures setQuadratureTolerance( - solver_, quadrature_rel_tol_, quadrature_abs_tol_override_); + solver_, quadrature_rel_tol_, quadrature_abs_tol_override_ + ); // Include quadrature in error checking retval = IDASetQuadErrCon(solver_, SUNTRUE); @@ -528,7 +534,8 @@ namespace AnalysisManager checkAllocation((void*) ypB_, "N_VClone"); qB_ = N_VNew_Serial( - static_cast(model_->sizeParams()), context_); + static_cast(model_->sizeParams()), context_ + ); checkAllocation((void*) qB_, "N_VNew_Serial"); return 0; @@ -574,17 +581,18 @@ namespace AnalysisManager // IDAInitB must be called after forward simulation run. retval = - IDAInitB(solver_, backwardID_, this->adjointResidual, tf, yyB_, ypB_); + IDAInitB(solver_, backwardID_, this->adjointResidual, tf, yyB_, ypB_); checkOutput(retval, "IDAInitB"); setIDAOptions( - IDAGetAdjIDABmem(solver_, backwardID_), - backward_time_step_, - backward_rel_tol_, - backward_abs_tol_override_, - backward_max_steps_, - backward_max_order_, - backward_suppress_alg_); + IDAGetAdjIDABmem(solver_, backwardID_), + backward_time_step_, + backward_rel_tol_, + backward_abs_tol_override_, + backward_max_steps_, + backward_max_order_, + backward_suppress_alg_ + ); retval = IDASetUserDataB(solver_, backwardID_, model_); checkOutput(retval, "IDASetUserDataB"); @@ -593,9 +601,10 @@ namespace AnalysisManager if (JacobianMatB_ == nullptr) { JacobianMatB_ = SUNDenseMatrix( - static_cast(model_->size()), - static_cast(model_->size()), - context_); + static_cast(model_->size()), + static_cast(model_->size()), + context_ + ); checkAllocation((void*) JacobianMatB_, "SUNDenseMatrix"); } @@ -608,7 +617,8 @@ namespace AnalysisManager // Setup linear solver (only dense supported at this time) retval = IDASetLinearSolverB( - solver_, backwardID_, linearSolverB_, JacobianMatB_); + solver_, backwardID_, linearSolverB_, JacobianMatB_ + ); checkOutput(retval, "IDASetLinearSolverB"); // Also reinitialize quadratures. @@ -616,9 +626,10 @@ namespace AnalysisManager checkOutput(retval, "IDAQuadInitB"); setQuadratureTolerance( - IDAGetAdjIDABmem(solver_, backwardID_), - backward_quadrature_rel_tol_, - backward_quadrature_abs_tol_override_); + IDAGetAdjIDABmem(solver_, backwardID_), + backward_quadrature_rel_tol_, + backward_quadrature_abs_tol_override_ + ); // Include quadratures in error control retval = IDASetQuadErrConB(solver_, backwardID_, SUNTRUE); @@ -642,9 +653,10 @@ namespace AnalysisManager // Create Jacobian matrix JacobianMatB_ = SUNDenseMatrix( - static_cast(model_->size()), - static_cast(model_->size()), - context_); + static_cast(model_->size()), + static_cast(model_->size()), + context_ + ); checkAllocation((void*) JacobianMatB_, "SUNDenseMatrix"); // Create linear solver @@ -653,7 +665,8 @@ namespace AnalysisManager // Attach linear solver to IDA retval = IDASetLinearSolverB( - solver_, backwardID_, linearSolverB_, JacobianMatB_); + solver_, backwardID_, linearSolverB_, JacobianMatB_ + ); checkOutput(retval, "IDASetLinearSolverB"); return retval; @@ -767,10 +780,11 @@ namespace AnalysisManager */ template int Ida::Residual( - RealT tres, N_Vector yy, N_Vector yp, N_Vector rr, void* user_data) + RealT tres, N_Vector yy, N_Vector yp, N_Vector rr, void* user_data + ) { GridKit::Model::Evaluator* model = - static_cast*>(user_data); + static_cast*>(user_data); copyVec(yy, model->y()); copyVec(yp, model->yp()); @@ -792,19 +806,20 @@ namespace AnalysisManager */ template int Ida::Jac( - RealT t, - RealT cj, - N_Vector yy, - N_Vector yp, - N_Vector, - SUNMatrix J, - void* user_data, - N_Vector, - N_Vector, - N_Vector) + RealT t, + RealT cj, + N_Vector yy, + N_Vector yp, + N_Vector, + SUNMatrix J, + void* user_data, + N_Vector, + N_Vector, + N_Vector + ) { GridKit::Model::Evaluator* model = - static_cast*>(user_data); + static_cast*>(user_data); copyVec(yy, model->y()); copyVec(yp, model->yp()); @@ -845,10 +860,11 @@ namespace AnalysisManager */ template int Ida::Integrand( - RealT tt, N_Vector yy, N_Vector yp, N_Vector rhsQ, void* user_data) + RealT tt, N_Vector yy, N_Vector yp, N_Vector rhsQ, void* user_data + ) { GridKit::Model::Evaluator* model = - static_cast*>(user_data); + static_cast*>(user_data); copyVec(yy, model->y()); copyVec(yp, model->yp()); @@ -868,16 +884,17 @@ namespace AnalysisManager */ template int Ida::adjointResidual( - RealT tt, - N_Vector yy, - N_Vector yp, - N_Vector yyB, - N_Vector ypB, - N_Vector rrB, - void* user_data) + RealT tt, + N_Vector yy, + N_Vector yp, + N_Vector yyB, + N_Vector ypB, + N_Vector rrB, + void* user_data + ) { GridKit::Model::Evaluator* model = - static_cast*>(user_data); + static_cast*>(user_data); copyVec(yy, model->y()); copyVec(yp, model->yp()); @@ -899,16 +916,17 @@ namespace AnalysisManager */ template int Ida::adjointIntegrand( - RealT tt, - N_Vector yy, - N_Vector yp, - N_Vector yyB, - N_Vector ypB, - N_Vector rhsQB, - void* user_data) + RealT tt, + N_Vector yy, + N_Vector yp, + N_Vector yyB, + N_Vector ypB, + N_Vector rhsQB, + void* user_data + ) { GridKit::Model::Evaluator* model = - static_cast*>(user_data); + static_cast*>(user_data); copyVec(yy, model->y()); copyVec(yp, model->yp()); @@ -936,8 +954,8 @@ namespace AnalysisManager if (xsize != ysize) { GridKit::Utilities::Logger::error() - << "N_Vector size (" << xsize << ") does not match vector size (" - << y.getSize() << ").\n"; + << "N_Vector size (" << xsize << ") does not match vector size (" + << y.getSize() << ").\n"; throw SundialsException(); } @@ -960,8 +978,8 @@ namespace AnalysisManager if (xsize != ysize) { GridKit::Utilities::Logger::error() - << "vector size (" << x.getSize() - << ") does not match N_Vector size (" << ysize << ").\n"; + << "vector size (" << x.getSize() + << ") does not match N_Vector size (" << ysize << ").\n"; throw SundialsException(); } @@ -983,8 +1001,8 @@ namespace AnalysisManager if (x.size() != ysize) { GridKit::Utilities::Logger::error() - << "std::vector size (" << x.size() - << ") does not match N_Vector size (" << ysize << ").\n"; + << "std::vector size (" << x.size() + << ") does not match N_Vector size (" << ysize << ").\n"; throw SundialsException(); } @@ -1061,7 +1079,7 @@ namespace AnalysisManager num_error_test_fails_ += other.num_error_test_fails_; num_nonlinear_iters_ += other.num_nonlinear_iters_; num_nonlinear_convergence_fails_ += - other.num_nonlinear_convergence_fails_; + other.num_nonlinear_convergence_fails_; return *this; } @@ -1110,23 +1128,25 @@ namespace AnalysisManager sunrealtype dummy2; int retval = IDAGetIntegratorStats( - solver_, - &stats.num_steps_, - &stats.num_residual_evals_, - &stats.num_linear_decompositions_, - &stats.num_error_test_fails_, - &dummy, - &dummy, - &dummy2, - &dummy2, - &dummy2, - &dummy2); + solver_, + &stats.num_steps_, + &stats.num_residual_evals_, + &stats.num_linear_decompositions_, + &stats.num_error_test_fails_, + &dummy, + &dummy, + &dummy2, + &dummy2, + &dummy2, + &dummy2 + ); checkOutput(retval, "IDAGetIntegratorStats"); retval = IDAGetNonlinSolvStats( - solver_, - &stats.num_nonlinear_iters_, - &stats.num_nonlinear_convergence_fails_); + solver_, + &stats.num_nonlinear_iters_, + &stats.num_nonlinear_convergence_fails_ + ); checkOutput(retval, "IDAGetNonlinSolvStats"); return stats; @@ -1144,8 +1164,8 @@ namespace AnalysisManager if (v == NULL) { GridKit::Utilities::Logger::error() - << "Function " << functionName - << " failed -- returned NULL pointer!\n"; + << "Function " << functionName + << " failed -- returned NULL pointer!\n"; throw SundialsException(); } } @@ -1163,8 +1183,8 @@ namespace AnalysisManager { char* msg = IDAGetReturnFlagName(retval); GridKit::Utilities::Logger::error() - << "Function " << functionName << " failed with flag " << msg - << "!\n"; + << "Function " << functionName << " failed with flag " << msg + << "!\n"; std::free(msg); throw SundialsException(); } @@ -1210,7 +1230,8 @@ namespace AnalysisManager */ template void Ida::setTolerance( - ScalarT rel_tol, ScalarT abs_tol_override) + ScalarT rel_tol, ScalarT abs_tol_override + ) { rel_tol_ = rel_tol; abs_tol_override_ = abs_tol_override; @@ -1229,7 +1250,8 @@ namespace AnalysisManager */ template void Ida::setBackwardTolerance( - ScalarT rel_tol, ScalarT abs_tol_override) + ScalarT rel_tol, ScalarT abs_tol_override + ) { backward_rel_tol_ = rel_tol; backward_abs_tol_override_ = abs_tol_override; @@ -1385,13 +1407,14 @@ namespace AnalysisManager */ template void Ida::setIDAOptions( - void* mem, - ScalarT time_step, - ScalarT rel_tol, - ScalarT abs_tol_override, - IdxT max_steps, - int max_order, - bool suppress_alg) + void* mem, + ScalarT time_step, + ScalarT rel_tol, + ScalarT abs_tol_override, + IdxT max_steps, + int max_order, + bool suppress_alg + ) { int retval = 0; retval = IDASetMinStep(mem, time_step); @@ -1401,7 +1424,7 @@ namespace AnalysisManager retval = IDASetMaxNumSteps(mem, static_cast(max_steps)); checkOutput(retval, "IDASetMaxNumSteps"); retval = - IDASetMaxOrd(mem, time_step == 0 ? max_order : std::min(max_order, 2)); + IDASetMaxOrd(mem, time_step == 0 ? max_order : std::min(max_order, 2)); checkOutput(retval, "IDASetMaxOrd"); retval = IDASetSuppressAlg(mem, suppress_alg ? SUNTRUE : SUNFALSE); checkOutput(retval, "IDASetSuppressAlg"); @@ -1432,12 +1455,13 @@ namespace AnalysisManager static constexpr RealT DEFAULT_NONLIN_CONV_COEF_IC = 0.0033; retval = IDASetNonlinConvCoefIC( - mem, DEFAULT_NONLIN_CONV_COEF_IC / FIXED_STEP_TOL_FAC); + mem, DEFAULT_NONLIN_CONV_COEF_IC / FIXED_STEP_TOL_FAC + ); checkOutput(retval, "IDASetNonlinConvCoefIC"); // Scale the IC line-search threshold with the same error weights. const RealT step_tol_ic = - std::pow(std::numeric_limits::epsilon(), 2.0 / 3.0); + std::pow(std::numeric_limits::epsilon(), 2.0 / 3.0); retval = IDASetStepToleranceIC(mem, step_tol_ic / FIXED_STEP_TOL_FAC); checkOutput(retval, "IDASetStepToleranceIC"); } @@ -1458,14 +1482,15 @@ namespace AnalysisManager */ template void Ida::setTolerance( - void* mem, ScalarT rel_tol, ScalarT abs_tol_override, ScalarT tol_fac) + void* mem, ScalarT rel_tol, ScalarT abs_tol_override, ScalarT tol_fac + ) { int retval = 0; if (abs_tol_override > 0) { retval = - IDASStolerances(mem, tol_fac * rel_tol, tol_fac * abs_tol_override); + IDASStolerances(mem, tol_fac * rel_tol, tol_fac * abs_tol_override); checkOutput(retval, "IDASStolerances"); return; } @@ -1498,7 +1523,8 @@ namespace AnalysisManager */ template void Ida::setQuadratureTolerance( - void* mem, ScalarT rel_tol, ScalarT abs_tol_override) + void* mem, ScalarT rel_tol, ScalarT abs_tol_override + ) { int retval = 0; diff --git a/GridKit/Solver/Dynamic/Ida.hpp b/GridKit/Solver/Dynamic/Ida.hpp index 435b642bc0..9c97523fc6 100644 --- a/GridKit/Solver/Dynamic/Ida.hpp +++ b/GridKit/Solver/Dynamic/Ida.hpp @@ -1,4 +1,5 @@ + #pragma once #include @@ -69,21 +70,24 @@ namespace AnalysisManager int configureLinearSolverDense(); int getDefaultInitialCondition(); int initializeSimulation( - RealT t0, bool findConsistent = true, bool printMonitor = true); + RealT t0, bool findConsistent = true, bool printMonitor = true + ); int getStepCount(RealT tf, RealT dt) const; int runSimulation( - RealT tf, - RealT dt_monitor = 0, - std::optional step_callback = {}); + RealT tf, + RealT dt_monitor = 0, + std::optional step_callback = {} + ); int runSimulationStep( - RealT tf, - RealT dt_monitor, - int step, - int nsteps, - std::optional callback = {}, - bool printMonitor = true); + RealT tf, + RealT dt_monitor, + int step, + int nsteps, + std::optional callback = {}, + bool printMonitor = true + ); int deleteSimulation(); int configureQuadrature(); @@ -164,36 +168,39 @@ namespace AnalysisManager static int Residual(RealT t, N_Vector yy, N_Vector yp, N_Vector rr, void* user_data); static int Jac( - RealT t, - RealT cj, - N_Vector yy, - N_Vector yp, - N_Vector resvec, - SUNMatrix J, - void* user_data, - N_Vector tmp1, - N_Vector tmp2, - N_Vector tmp3); + RealT t, + RealT cj, + N_Vector yy, + N_Vector yp, + N_Vector resvec, + SUNMatrix J, + void* user_data, + N_Vector tmp1, + N_Vector tmp2, + N_Vector tmp3 + ); static int Integrand(RealT t, N_Vector yy, N_Vector yp, N_Vector rhsQ, void* user_data); static int adjointResidual( - RealT t, - N_Vector yy, - N_Vector yp, - N_Vector yyB, - N_Vector ypB, - N_Vector rrB, - void* user_data); + RealT t, + N_Vector yy, + N_Vector yp, + N_Vector yyB, + N_Vector ypB, + N_Vector rrB, + void* user_data + ); static int adjointIntegrand( - RealT t, - N_Vector yy, - N_Vector yp, - N_Vector yyB, - N_Vector ypB, - N_Vector rhsQB, - void* user_data); + RealT t, + N_Vector yy, + N_Vector yp, + N_Vector yyB, + N_Vector ypB, + N_Vector rhsQB, + void* user_data + ); RealT getMonitorTime(RealT tf, RealT dt_monitor, int step, int nsteps) const; int getIDAConsistentICType() const; @@ -257,18 +264,20 @@ namespace AnalysisManager static void checkOutput(int retval, const char* functionName); void setIDAOptions( - void* mem, - ScalarT time_step, - ScalarT rel_tol, - ScalarT abs_tol_override, - IdxT max_steps, - int max_order, - bool suppress_alg); + void* mem, + ScalarT time_step, + ScalarT rel_tol, + ScalarT abs_tol_override, + IdxT max_steps, + int max_order, + bool suppress_alg + ); void setTolerance( - void* mem, - ScalarT rel_tol, - ScalarT abs_tol_override, - ScalarT tol_fac = 1); + void* mem, + ScalarT rel_tol, + ScalarT abs_tol_override, + ScalarT tol_fac = 1 + ); void setQuadratureTolerance(void* mem, ScalarT rel_tol, ScalarT abs_tol_override); }; diff --git a/GridKit/Solver/Dynamic/Native/FixedStep.cpp b/GridKit/Solver/Dynamic/Native/FixedStep.cpp index 965627ac0e..ee4a571ba9 100644 --- a/GridKit/Solver/Dynamic/Native/FixedStep.cpp +++ b/GridKit/Solver/Dynamic/Native/FixedStep.cpp @@ -12,8 +12,8 @@ namespace AnalysisManager StepControl FixedStep::nextStep([[maybe_unused]] RealT err, StepControl prev_step, [[maybe_unused]] uint8_t method_order) { return StepControl{ - .accept_ = true, - .step_size_ = prev_step.step_size_, + .accept_ = true, + .step_size_ = prev_step.step_size_, }; } diff --git a/GridKit/Solver/Dynamic/Rosenbrock.cpp b/GridKit/Solver/Dynamic/Rosenbrock.cpp index 15e845b720..2c641bcb82 100644 --- a/GridKit/Solver/Dynamic/Rosenbrock.cpp +++ b/GridKit/Solver/Dynamic/Rosenbrock.cpp @@ -229,12 +229,14 @@ namespace AnalysisManager * @param memspace The memory space that linear algebra operations should be performed in. */ template - Rosenbrock::Rosenbrock(Tableau&& tab, - GridKit::Model::Evaluator* model, - GridKit::LinearAlgebra::LinearSolver& lin_solver, - GridKit::LinearAlgebra::VectorHandler& vector_handler, - const ErrorNorm* err_norm, - GridKit::memory::MemorySpace memspace) + Rosenbrock::Rosenbrock( + Tableau&& tab, + GridKit::Model::Evaluator* model, + GridKit::LinearAlgebra::LinearSolver& lin_solver, + GridKit::LinearAlgebra::VectorHandler& vector_handler, + const ErrorNorm* err_norm, + GridKit::memory::MemorySpace memspace + ) : tab_(std::move(tab)), model_(model), lin_solver_(lin_solver), @@ -402,11 +404,13 @@ namespace AnalysisManager * @return An error code, with 0 as success. */ template - int Rosenbrock::integrate(const std::vector& out_times, - StepController& step_controller, - Parameters params, - std::optional> out_cb, - std::optional> step_cb) + int Rosenbrock::integrate( + const std::vector& out_times, + StepController& step_controller, + Parameters params, + std::optional> out_cb, + std::optional> step_cb + ) { constexpr RealT ONE = GridKit::ONE; constexpr RealT ZERO = GridKit::ZERO; @@ -445,12 +449,14 @@ namespace AnalysisManager err = err_norm_->errorNorm(err_vec, *y_new_, *y_cur_, vector_handler_, memspace_); } - StepControl next_step = step_controller.nextStep(err, - StepControl{ - .accept_ = prev_accept, - .step_size_ = step_size_, - }, - tab_.order_); + StepControl next_step = step_controller.nextStep( + err, + StepControl{ + .accept_ = prev_accept, + .step_size_ = step_size_, + }, + tab_.order_ + ); prev_accept = next_step.accept_; next_step_size = next_step.step_size_; @@ -472,7 +478,8 @@ namespace AnalysisManager stats_.num_steps_++; if (skip_lu_) { - stats_.skip_lu_steps_.push_back(StepInfo{ + stats_.skip_lu_steps_.push_back( + StepInfo{ .sim_time_ = current_time_, .step_size_ = step_size_, .next_step_size_ = next_step_size, @@ -481,7 +488,8 @@ namespace AnalysisManager .skip_lu_ = skip_lu_, .skip_f_ = skip_f_, .accepted_ = prev_accept, - }); + } + ); } stats_.min_step_ = std::min(stats_.min_step_, step_size_); stats_.max_step_ = std::max(stats_.max_step_, step_size_); @@ -495,7 +503,8 @@ namespace AnalysisManager { skip_f_ = true; - stats_.rejections_.push_back(StepInfo{ + stats_.rejections_.push_back( + StepInfo{ .sim_time_ = current_time_, .step_size_ = step_size_, .next_step_size_ = next_step_size, @@ -504,7 +513,8 @@ namespace AnalysisManager .skip_lu_ = skip_lu_, .skip_f_ = skip_f_, .accepted_ = prev_accept, - }); + } + ); } // Check if we can use time delay Jacobians. If we would have increased the step size (but not too much), @@ -529,14 +539,14 @@ namespace AnalysisManager model_->updateTime(current_time_, ZERO); (*step_cb)(StepInfo{ - .sim_time_ = current_time_, - .step_size_ = step_size_, - .next_step_size_ = next_step_size, - .err_est_ = err, - .step_no_ = stats_.num_steps_, - .skip_lu_ = skip_lu_, - .skip_f_ = skip_f_, - .accepted_ = prev_accept, + .sim_time_ = current_time_, + .step_size_ = step_size_, + .next_step_size_ = next_step_size, + .err_est_ = err, + .step_no_ = stats_.num_steps_, + .skip_lu_ = skip_lu_, + .skip_f_ = skip_f_, + .accepted_ = prev_accept, }); } } diff --git a/GridKit/Solver/Dynamic/Rosenbrock.hpp b/GridKit/Solver/Dynamic/Rosenbrock.hpp index 70ece49fcc..d9886f3d50 100644 --- a/GridKit/Solver/Dynamic/Rosenbrock.hpp +++ b/GridKit/Solver/Dynamic/Rosenbrock.hpp @@ -417,12 +417,14 @@ namespace AnalysisManager Stats stats_; public: - Rosenbrock(Tableau&& tab, - GridKit::Model::Evaluator* model, - GridKit::LinearAlgebra::LinearSolver& lin_solver, - GridKit::LinearAlgebra::VectorHandler& vector_handler, - const ErrorNorm* err_norm, - GridKit::memory::MemorySpace memspace = GridKit::memory::HOST); + Rosenbrock( + Tableau&& tab, + GridKit::Model::Evaluator* model, + GridKit::LinearAlgebra::LinearSolver& lin_solver, + GridKit::LinearAlgebra::VectorHandler& vector_handler, + const ErrorNorm* err_norm, + GridKit::memory::MemorySpace memspace = GridKit::memory::HOST + ); [[nodiscard("May fail. Check error code.")]] int allocate(); @@ -431,11 +433,13 @@ namespace AnalysisManager int initializeSimulation(RealT t0); [[nodiscard("May fail. Check error code.")]] - int integrate(const std::vector& out_times, - StepController& step_controller, - Parameters params = {}, - std::optional> out_cb = {}, - std::optional> step_cb = {}); + int integrate( + const std::vector& out_times, + StepController& step_controller, + Parameters params = {}, + std::optional> out_cb = {}, + std::optional> step_cb = {} + ); private: /** diff --git a/GridKit/Solver/Dynamic/RosenbrockTableaus.cpp b/GridKit/Solver/Dynamic/RosenbrockTableaus.cpp index 4fd952bc2e..5c5e1265f6 100644 --- a/GridKit/Solver/Dynamic/RosenbrockTableaus.cpp +++ b/GridKit/Solver/Dynamic/RosenbrockTableaus.cpp @@ -10,19 +10,19 @@ namespace AnalysisManager constexpr size_t num_stages = 1; Tableau re = { - .num_stages_ = num_stages, - .gamma_ = 1.0, - .alpha_sum_ = std::make_unique_for_overwrite(num_stages), - .gamma_sum_ = std::make_unique_for_overwrite(num_stages), - .m_ = std::make_unique_for_overwrite(num_stages), - .e_ = {}, - .A_ = std::make_unique_for_overwrite(num_stages * num_stages), - .C_ = std::make_unique_for_overwrite(num_stages * num_stages), - .H_ = {}, - .order_ = 1, - .is_krylov_ = true, - .is_w_ = false, - .is_dae_ = true, + .num_stages_ = num_stages, + .gamma_ = 1.0, + .alpha_sum_ = std::make_unique_for_overwrite(num_stages), + .gamma_sum_ = std::make_unique_for_overwrite(num_stages), + .m_ = std::make_unique_for_overwrite(num_stages), + .e_ = {}, + .A_ = std::make_unique_for_overwrite(num_stages * num_stages), + .C_ = std::make_unique_for_overwrite(num_stages * num_stages), + .H_ = {}, + .order_ = 1, + .is_krylov_ = true, + .is_w_ = false, + .is_dae_ = true, }; re.alpha_sum_[0] = 0.0; @@ -49,19 +49,19 @@ namespace AnalysisManager constexpr size_t num_stages = 8; Tableau re = { - .num_stages_ = num_stages, - .gamma_ = 0.21193756319429014, - .alpha_sum_ = std::make_unique_for_overwrite(num_stages), - .gamma_sum_ = std::make_unique_for_overwrite(num_stages), - .m_ = std::make_unique_for_overwrite(num_stages), - .e_ = std::make_unique_for_overwrite(num_stages), - .A_ = std::make_unique_for_overwrite(num_stages * num_stages), - .C_ = std::make_unique_for_overwrite(num_stages * num_stages), - .H_ = std::make_unique_for_overwrite(num_stages * 3), - .order_ = 5, - .is_krylov_ = false, - .is_w_ = false, - .is_dae_ = true, + .num_stages_ = num_stages, + .gamma_ = 0.21193756319429014, + .alpha_sum_ = std::make_unique_for_overwrite(num_stages), + .gamma_sum_ = std::make_unique_for_overwrite(num_stages), + .m_ = std::make_unique_for_overwrite(num_stages), + .e_ = std::make_unique_for_overwrite(num_stages), + .A_ = std::make_unique_for_overwrite(num_stages * num_stages), + .C_ = std::make_unique_for_overwrite(num_stages * num_stages), + .H_ = std::make_unique_for_overwrite(num_stages * 3), + .order_ = 5, + .is_krylov_ = false, + .is_w_ = false, + .is_dae_ = true, }; re.alpha_sum_[0] = 0.0; diff --git a/GridKit/Solver/Optimization/DynamicConstraint.cpp b/GridKit/Solver/Optimization/DynamicConstraint.cpp index 8cb0073379..1dbee911c5 100644 --- a/GridKit/Solver/Optimization/DynamicConstraint.cpp +++ b/GridKit/Solver/Optimization/DynamicConstraint.cpp @@ -12,10 +12,12 @@ namespace AnalysisManager { template - DynamicConstraint::DynamicConstraint(Sundials::Ida* integrator, - RealT t_init, - RealT t_final, - RealT dt_monitor) + DynamicConstraint::DynamicConstraint( + Sundials::Ida* integrator, + RealT t_init, + RealT t_final, + RealT dt_monitor + ) : OptimizationSolver(integrator), t_init_(t_init), t_final_(t_final), @@ -55,12 +57,14 @@ namespace AnalysisManager } template - bool DynamicConstraint::get_bounds_info([[maybe_unused]] Index n, - Number* x_l, - Number* x_u, - [[maybe_unused]] Index m, - Number* g_l, - Number* g_u) + bool DynamicConstraint::get_bounds_info( + [[maybe_unused]] Index n, + Number* x_l, + Number* x_u, + [[maybe_unused]] Index m, + Number* g_l, + Number* g_u + ) { // Check if sizes are set correctly assert(n == (Index) (model_->sizeParams() + 1)); @@ -87,15 +91,17 @@ namespace AnalysisManager } template - bool DynamicConstraint::get_starting_point([[maybe_unused]] Index n, - [[maybe_unused]] bool init_x, - Number* x, - [[maybe_unused]] bool init_z, - [[maybe_unused]] Number* z_L, - [[maybe_unused]] Number* z_U, - [[maybe_unused]] Index m, - [[maybe_unused]] bool init_lambda, - [[maybe_unused]] Number* lambda) + bool DynamicConstraint::get_starting_point( + [[maybe_unused]] Index n, + [[maybe_unused]] bool init_x, + Number* x, + [[maybe_unused]] bool init_z, + [[maybe_unused]] Number* z_L, + [[maybe_unused]] Number* z_U, + [[maybe_unused]] Index m, + [[maybe_unused]] bool init_lambda, + [[maybe_unused]] Number* lambda + ) { // Only initial values for x provided. assert(init_x == true); @@ -114,10 +120,12 @@ namespace AnalysisManager } template - bool DynamicConstraint::eval_f([[maybe_unused]] Index n, - const Number* x, - [[maybe_unused]] bool new_x, - Number& obj_value) + bool DynamicConstraint::eval_f( + [[maybe_unused]] Index n, + const Number* x, + [[maybe_unused]] bool new_x, + Number& obj_value + ) { // Set objective to fictitious optimization parameter x[n-1] obj_value = x[model_->sizeParams()]; @@ -126,10 +134,12 @@ namespace AnalysisManager } template - bool DynamicConstraint::eval_grad_f([[maybe_unused]] Index n, - [[maybe_unused]] const Number* x, - [[maybe_unused]] bool new_x, - Number* grad_f) + bool DynamicConstraint::eval_grad_f( + [[maybe_unused]] Index n, + [[maybe_unused]] const Number* x, + [[maybe_unused]] bool new_x, + Number* grad_f + ) { // Objective function equals to the fictitious parameter x[n-1]. // Gradient, then assumes the simple form: @@ -141,11 +151,13 @@ namespace AnalysisManager } template - bool DynamicConstraint::eval_g([[maybe_unused]] Index n, - const Number* x, - [[maybe_unused]] bool new_x, - [[maybe_unused]] Index m, - Number* g) + bool DynamicConstraint::eval_g( + [[maybe_unused]] Index n, + const Number* x, + [[maybe_unused]] bool new_x, + [[maybe_unused]] Index m, + Number* g + ) { // Update optimization parameters auto* param = model_->param().getData(); @@ -174,14 +186,16 @@ namespace AnalysisManager } template - bool DynamicConstraint::eval_jac_g([[maybe_unused]] Index n, - const Number* x, - [[maybe_unused]] bool new_x, - [[maybe_unused]] Index m, - [[maybe_unused]] Index nele_jac, - Index* iRow, - Index* jCol, - Number* values) + bool DynamicConstraint::eval_jac_g( + [[maybe_unused]] Index n, + const Number* x, + [[maybe_unused]] bool new_x, + [[maybe_unused]] Index m, + [[maybe_unused]] Index nele_jac, + Index* iRow, + Index* jCol, + Number* values + ) { // Set Jacobian sparsity pattern ... if (!values) @@ -242,33 +256,37 @@ namespace AnalysisManager } template - bool DynamicConstraint::eval_h([[maybe_unused]] Index n, - [[maybe_unused]] const Number* x, - [[maybe_unused]] bool new_x, - [[maybe_unused]] Number obj_factor, - [[maybe_unused]] Index m, - [[maybe_unused]] const Number* lambda, - [[maybe_unused]] bool new_lambda, - [[maybe_unused]] Index nele_hess, - [[maybe_unused]] Index* iRow, - [[maybe_unused]] Index* jCol, - [[maybe_unused]] Number* values) + bool DynamicConstraint::eval_h( + [[maybe_unused]] Index n, + [[maybe_unused]] const Number* x, + [[maybe_unused]] bool new_x, + [[maybe_unused]] Number obj_factor, + [[maybe_unused]] Index m, + [[maybe_unused]] const Number* lambda, + [[maybe_unused]] bool new_lambda, + [[maybe_unused]] Index nele_hess, + [[maybe_unused]] Index* iRow, + [[maybe_unused]] Index* jCol, + [[maybe_unused]] Number* values + ) { return true; } template - void DynamicConstraint::finalize_solution([[maybe_unused]] SolverReturn status, - [[maybe_unused]] Index n, - [[maybe_unused]] const Number* x, - [[maybe_unused]] const Number* z_L, - [[maybe_unused]] const Number* z_U, - [[maybe_unused]] Index m, - [[maybe_unused]] const Number* g, - [[maybe_unused]] const Number* lambda, - [[maybe_unused]] Number obj_value, - [[maybe_unused]] const IpoptData* ip_data, - [[maybe_unused]] IpoptCalculatedQuantities* ip_cq) + void DynamicConstraint::finalize_solution( + [[maybe_unused]] SolverReturn status, + [[maybe_unused]] Index n, + [[maybe_unused]] const Number* x, + [[maybe_unused]] const Number* z_L, + [[maybe_unused]] const Number* z_U, + [[maybe_unused]] Index m, + [[maybe_unused]] const Number* g, + [[maybe_unused]] const Number* lambda, + [[maybe_unused]] Number obj_value, + [[maybe_unused]] const IpoptData* ip_data, + [[maybe_unused]] IpoptCalculatedQuantities* ip_cq + ) { } diff --git a/GridKit/Solver/Optimization/DynamicConstraint.hpp b/GridKit/Solver/Optimization/DynamicConstraint.hpp index 9a2495f80e..1736200727 100644 --- a/GridKit/Solver/Optimization/DynamicConstraint.hpp +++ b/GridKit/Solver/Optimization/DynamicConstraint.hpp @@ -39,10 +39,12 @@ namespace AnalysisManager using IpoptData = Ipopt::IpoptData; public: - DynamicConstraint(Sundials::Ida* integrator, - RealT t_init, - RealT t_final, - RealT dt_monitor = 0); + DynamicConstraint( + Sundials::Ida* integrator, + RealT t_init, + RealT t_final, + RealT dt_monitor = 0 + ); virtual ~DynamicConstraint(); /// Returns sizes of the model components @@ -70,17 +72,19 @@ namespace AnalysisManager virtual bool eval_h(Index n, const Number* x, bool new_x, Number obj_factor, Index m, const Number* lambda, bool new_lambda, Index nele_hess, Index* iRow, Index* jCol, Number* values); /// Postprocessing of the results (not used here) - virtual void finalize_solution(SolverReturn status, - Index n, - const Number* x, - const Number* z_L, - const Number* z_U, - Index m, - const Number* g, - const Number* lambda, - Number obj_value, - const IpoptData* ip_data, - IpoptCalculatedQuantities* ip_cq); + virtual void finalize_solution( + SolverReturn status, + Index n, + const Number* x, + const Number* z_L, + const Number* z_U, + Index m, + const Number* g, + const Number* lambda, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq + ); private: RealT t_init_; diff --git a/GridKit/Solver/Optimization/DynamicObjective.cpp b/GridKit/Solver/Optimization/DynamicObjective.cpp index a6f27e50a6..1eca727afe 100644 --- a/GridKit/Solver/Optimization/DynamicObjective.cpp +++ b/GridKit/Solver/Optimization/DynamicObjective.cpp @@ -10,10 +10,12 @@ namespace AnalysisManager { template - DynamicObjective::DynamicObjective(Sundials::Ida* integrator, - RealT t_init, - RealT t_final, - RealT dt_monitor) + DynamicObjective::DynamicObjective( + Sundials::Ida* integrator, + RealT t_init, + RealT t_final, + RealT dt_monitor + ) : OptimizationSolver(integrator), t_init_(t_init), t_final_(t_final), @@ -52,12 +54,14 @@ namespace AnalysisManager } template - bool DynamicObjective::get_bounds_info([[maybe_unused]] Index n, - Number* x_l, - Number* x_u, - [[maybe_unused]] Index m, - [[maybe_unused]] Number* g_l, - [[maybe_unused]] Number* g_u) + bool DynamicObjective::get_bounds_info( + [[maybe_unused]] Index n, + Number* x_l, + Number* x_u, + [[maybe_unused]] Index m, + [[maybe_unused]] Number* g_l, + [[maybe_unused]] Number* g_u + ) { // Check if sizes are set correctly assert(n == (Index) model_->sizeParams()); @@ -76,15 +80,17 @@ namespace AnalysisManager } template - bool DynamicObjective::get_starting_point([[maybe_unused]] Index n, - [[maybe_unused]] bool init_x, - Number* x, - [[maybe_unused]] bool init_z, - [[maybe_unused]] Number* z_L, - [[maybe_unused]] Number* z_U, - [[maybe_unused]] Index m, - [[maybe_unused]] bool init_lambda, - [[maybe_unused]] Number* lambda) + bool DynamicObjective::get_starting_point( + [[maybe_unused]] Index n, + [[maybe_unused]] bool init_x, + Number* x, + [[maybe_unused]] bool init_z, + [[maybe_unused]] Number* z_L, + [[maybe_unused]] Number* z_U, + [[maybe_unused]] Index m, + [[maybe_unused]] bool init_lambda, + [[maybe_unused]] Number* lambda + ) { // Only initial values for x provided. assert(init_x == true); @@ -100,10 +106,12 @@ namespace AnalysisManager } template - bool DynamicObjective::eval_f([[maybe_unused]] Index n, - const Number* x, - [[maybe_unused]] bool new_x, - Number& obj_value) + bool DynamicObjective::eval_f( + [[maybe_unused]] Index n, + const Number* x, + [[maybe_unused]] bool new_x, + Number& obj_value + ) { // Update optimization parameters auto* param = model_->param().getData(); @@ -124,10 +132,12 @@ namespace AnalysisManager } template - bool DynamicObjective::eval_grad_f([[maybe_unused]] Index n, - const Number* x, - [[maybe_unused]] bool new_x, - Number* grad_f) + bool DynamicObjective::eval_grad_f( + [[maybe_unused]] Index n, + const Number* x, + [[maybe_unused]] bool new_x, + Number* grad_f + ) { assert(model_->sizeParams() == static_cast(n)); // Update optimization parameters @@ -159,56 +169,64 @@ namespace AnalysisManager } template - bool DynamicObjective::eval_g([[maybe_unused]] Index n, - [[maybe_unused]] const Number* x, - [[maybe_unused]] bool new_x, - [[maybe_unused]] Index m, - [[maybe_unused]] Number* g) + bool DynamicObjective::eval_g( + [[maybe_unused]] Index n, + [[maybe_unused]] const Number* x, + [[maybe_unused]] bool new_x, + [[maybe_unused]] Index m, + [[maybe_unused]] Number* g + ) { return true; } template - bool DynamicObjective::eval_jac_g([[maybe_unused]] Index n, - [[maybe_unused]] const Number* x, - [[maybe_unused]] bool new_x, - [[maybe_unused]] Index m, - [[maybe_unused]] Index nele_jac, - [[maybe_unused]] Index* iRow, - [[maybe_unused]] Index* jCol, - [[maybe_unused]] Number* values) + bool DynamicObjective::eval_jac_g( + [[maybe_unused]] Index n, + [[maybe_unused]] const Number* x, + [[maybe_unused]] bool new_x, + [[maybe_unused]] Index m, + [[maybe_unused]] Index nele_jac, + [[maybe_unused]] Index* iRow, + [[maybe_unused]] Index* jCol, + [[maybe_unused]] Number* values + ) { return true; } template - bool DynamicObjective::eval_h([[maybe_unused]] Index n, - [[maybe_unused]] const Number* x, - [[maybe_unused]] bool new_x, - [[maybe_unused]] Number obj_factor, - [[maybe_unused]] Index m, - [[maybe_unused]] const Number* lambda, - [[maybe_unused]] bool new_lambda, - [[maybe_unused]] Index nele_hess, - [[maybe_unused]] Index* iRow, - [[maybe_unused]] Index* jCol, - [[maybe_unused]] Number* values) + bool DynamicObjective::eval_h( + [[maybe_unused]] Index n, + [[maybe_unused]] const Number* x, + [[maybe_unused]] bool new_x, + [[maybe_unused]] Number obj_factor, + [[maybe_unused]] Index m, + [[maybe_unused]] const Number* lambda, + [[maybe_unused]] bool new_lambda, + [[maybe_unused]] Index nele_hess, + [[maybe_unused]] Index* iRow, + [[maybe_unused]] Index* jCol, + [[maybe_unused]] Number* values + ) { return true; } template - void DynamicObjective::finalize_solution([[maybe_unused]] SolverReturn status, - [[maybe_unused]] Index n, - [[maybe_unused]] const Number* x, - [[maybe_unused]] const Number* z_L, - [[maybe_unused]] const Number* z_U, - [[maybe_unused]] Index m, - [[maybe_unused]] const Number* g, - [[maybe_unused]] const Number* lambda, - [[maybe_unused]] Number obj_value, - [[maybe_unused]] const IpoptData* ip_data, - [[maybe_unused]] IpoptCalculatedQuantities* ip_cq) + void DynamicObjective::finalize_solution( + [[maybe_unused]] SolverReturn status, + [[maybe_unused]] Index n, + [[maybe_unused]] const Number* x, + [[maybe_unused]] const Number* z_L, + [[maybe_unused]] const Number* z_U, + [[maybe_unused]] Index m, + [[maybe_unused]] const Number* g, + [[maybe_unused]] const Number* lambda, + [[maybe_unused]] Number obj_value, + [[maybe_unused]] const IpoptData* ip_data, + [[maybe_unused]] IpoptCalculatedQuantities* ip_cq + ) { } diff --git a/GridKit/Solver/Optimization/DynamicObjective.hpp b/GridKit/Solver/Optimization/DynamicObjective.hpp index 72a5763b0e..1dd0939b1f 100644 --- a/GridKit/Solver/Optimization/DynamicObjective.hpp +++ b/GridKit/Solver/Optimization/DynamicObjective.hpp @@ -35,10 +35,12 @@ namespace AnalysisManager using IpoptData = Ipopt::IpoptData; public: - DynamicObjective(Sundials::Ida* integrator, - RealT t_init, - RealT t_final, - RealT dt_monitor = 0); + DynamicObjective( + Sundials::Ida* integrator, + RealT t_init, + RealT t_final, + RealT dt_monitor = 0 + ); virtual ~DynamicObjective(); /// Returns sizes of the model components @@ -66,17 +68,19 @@ namespace AnalysisManager virtual bool eval_h(Index n, const Number* x, bool new_x, Number obj_factor, Index m, const Number* lambda, bool new_lambda, Index nele_hess, Index* iRow, Index* jCol, Number* values); /// Postprocessing of the results (not used here) - virtual void finalize_solution(SolverReturn status, - Index n, - const Number* x, - const Number* z_L, - const Number* z_U, - Index m, - const Number* g, - const Number* lambda, - Number obj_value, - const IpoptData* ip_data, - IpoptCalculatedQuantities* ip_cq); + virtual void finalize_solution( + SolverReturn status, + Index n, + const Number* x, + const Number* z_L, + const Number* z_U, + Index m, + const Number* g, + const Number* lambda, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq + ); private: RealT t_init_; diff --git a/GridKit/Solver/Optimization/IpoptInterface.cpp b/GridKit/Solver/Optimization/IpoptInterface.cpp index 571f2ea900..f30b6be695 100644 --- a/GridKit/Solver/Optimization/IpoptInterface.cpp +++ b/GridKit/Solver/Optimization/IpoptInterface.cpp @@ -20,11 +20,13 @@ namespace AnalysisManager } template - bool IpoptInterface::get_nlp_info(ipindex& n, - ipindex& m, - ipindex& nnz_jac_g, - ipindex& nnz_h_lag, - IndexStyleEnum& index_style) + bool IpoptInterface::get_nlp_info( + ipindex& n, + ipindex& m, + ipindex& nnz_jac_g, + ipindex& nnz_h_lag, + IndexStyleEnum& index_style + ) { if (model_->getCsrJacobian() == nullptr || model_->getCsrHessian() == nullptr) { @@ -42,12 +44,14 @@ namespace AnalysisManager } template - bool IpoptInterface::get_bounds_info(ipindex n, - ipnumber* x_l, - ipnumber* x_u, - ipindex m, - ipnumber* g_l, - ipnumber* g_u) + bool IpoptInterface::get_bounds_info( + ipindex n, + ipnumber* x_l, + ipnumber* x_u, + ipindex m, + ipnumber* g_l, + ipnumber* g_u + ) { std::copy_n(model_->xLower().getData(), n, x_l); std::copy_n(model_->xUpper().getData(), n, x_u); @@ -58,15 +62,17 @@ namespace AnalysisManager } template - bool IpoptInterface::get_starting_point(ipindex n, - bool init_x, - ipnumber* x, - bool init_z, - [[maybe_unused]] ipnumber* z_L, - [[maybe_unused]] ipnumber* z_U, - [[maybe_unused]] ipindex m, - bool init_lambda, - [[maybe_unused]] ipnumber* lambda) + bool IpoptInterface::get_starting_point( + ipindex n, + bool init_x, + ipnumber* x, + bool init_z, + [[maybe_unused]] ipnumber* z_L, + [[maybe_unused]] ipnumber* z_U, + [[maybe_unused]] ipindex m, + bool init_lambda, + [[maybe_unused]] ipnumber* lambda + ) { // Only the variables have initial values if (!init_x || init_z || init_lambda) @@ -80,10 +86,12 @@ namespace AnalysisManager } template - bool IpoptInterface::eval_f([[maybe_unused]] ipindex n, - const ipnumber* x, - [[maybe_unused]] bool new_x, - ipnumber& obj_value) + bool IpoptInterface::eval_f( + [[maybe_unused]] ipindex n, + const ipnumber* x, + [[maybe_unused]] bool new_x, + ipnumber& obj_value + ) { copyInto(model_->x(), x); if (model_->evaluateObjective() != 0) @@ -97,10 +105,12 @@ namespace AnalysisManager } template - bool IpoptInterface::eval_grad_f(ipindex n, - const ipnumber* x, - [[maybe_unused]] bool new_x, - ipnumber* grad_f) + bool IpoptInterface::eval_grad_f( + ipindex n, + const ipnumber* x, + [[maybe_unused]] bool new_x, + ipnumber* grad_f + ) { copyInto(model_->x(), x); if (model_->evaluateGradient() != 0) @@ -114,11 +124,13 @@ namespace AnalysisManager } template - bool IpoptInterface::eval_g([[maybe_unused]] ipindex n, - const ipnumber* x, - [[maybe_unused]] bool new_x, - ipindex m, - ipnumber* g) + bool IpoptInterface::eval_g( + [[maybe_unused]] ipindex n, + const ipnumber* x, + [[maybe_unused]] bool new_x, + ipindex m, + ipnumber* g + ) { copyInto(model_->x(), x); if (model_->evaluateConstraints() != 0) @@ -132,14 +144,16 @@ namespace AnalysisManager } template - bool IpoptInterface::eval_jac_g([[maybe_unused]] ipindex n, - const ipnumber* x, - [[maybe_unused]] bool new_x, - [[maybe_unused]] ipindex m, - ipindex nele_jac, - ipindex* iRow, - ipindex* jCol, - ipnumber* values) + bool IpoptInterface::eval_jac_g( + [[maybe_unused]] ipindex n, + const ipnumber* x, + [[maybe_unused]] bool new_x, + [[maybe_unused]] ipindex m, + ipindex nele_jac, + ipindex* iRow, + ipindex* jCol, + ipnumber* values + ) { if (values == nullptr) { @@ -159,17 +173,19 @@ namespace AnalysisManager } template - bool IpoptInterface::eval_h([[maybe_unused]] ipindex n, - const ipnumber* x, - [[maybe_unused]] bool new_x, - ipnumber obj_factor, - [[maybe_unused]] ipindex m, - const ipnumber* lambda, - [[maybe_unused]] bool new_lambda, - ipindex nele_hess, - ipindex* iRow, - ipindex* jCol, - ipnumber* values) + bool IpoptInterface::eval_h( + [[maybe_unused]] ipindex n, + const ipnumber* x, + [[maybe_unused]] bool new_x, + ipnumber obj_factor, + [[maybe_unused]] ipindex m, + const ipnumber* lambda, + [[maybe_unused]] bool new_lambda, + ipindex nele_hess, + ipindex* iRow, + ipindex* jCol, + ipnumber* values + ) { if (values == nullptr) { @@ -190,17 +206,19 @@ namespace AnalysisManager } template - void IpoptInterface::finalize_solution([[maybe_unused]] SolverReturn status, - [[maybe_unused]] ipindex n, - const ipnumber* x, - const ipnumber* z_L, - const ipnumber* z_U, - [[maybe_unused]] ipindex m, - [[maybe_unused]] const ipnumber* g, - const ipnumber* lambda, - [[maybe_unused]] ipnumber obj_value, - [[maybe_unused]] const IpoptData* ip_data, - [[maybe_unused]] IpoptCalculatedQuantities* ip_cq) + void IpoptInterface::finalize_solution( + [[maybe_unused]] SolverReturn status, + [[maybe_unused]] ipindex n, + const ipnumber* x, + const ipnumber* z_L, + const ipnumber* z_U, + [[maybe_unused]] ipindex m, + [[maybe_unused]] const ipnumber* g, + const ipnumber* lambda, + [[maybe_unused]] ipnumber obj_value, + [[maybe_unused]] const IpoptData* ip_data, + [[maybe_unused]] IpoptCalculatedQuantities* ip_cq + ) { copyInto(model_->x(), x); copyInto(model_->lambda(), lambda); diff --git a/GridKit/Solver/Optimization/IpoptInterface.hpp b/GridKit/Solver/Optimization/IpoptInterface.hpp index 81c2d8fe8a..8f6bce52ef 100644 --- a/GridKit/Solver/Optimization/IpoptInterface.hpp +++ b/GridKit/Solver/Optimization/IpoptInterface.hpp @@ -49,15 +49,17 @@ namespace AnalysisManager bool get_bounds_info(ipindex n, ipnumber* x_l, ipnumber* x_u, ipindex m, ipnumber* g_l, ipnumber* g_u) override; /// Variables from `x()`, without initial multipliers - bool get_starting_point(ipindex n, - bool init_x, - ipnumber* x, - bool init_z, - ipnumber* z_L, - ipnumber* z_U, - ipindex m, - bool init_lambda, - ipnumber* lambda) override; + bool get_starting_point( + ipindex n, + bool init_x, + ipnumber* x, + bool init_z, + ipnumber* z_L, + ipnumber* z_U, + ipindex m, + bool init_lambda, + ipnumber* lambda + ) override; /// Objective \f$f(x)\f$ bool eval_f(ipindex n, const ipnumber* x, bool new_x, ipnumber& obj_value) override; @@ -69,40 +71,46 @@ namespace AnalysisManager bool eval_g(ipindex n, const ipnumber* x, bool new_x, ipindex m, ipnumber* g) override; /// Constraint Jacobian, or its structure when `values` is null - bool eval_jac_g(ipindex n, - const ipnumber* x, - bool new_x, - ipindex m, - ipindex nele_jac, - ipindex* iRow, - ipindex* jCol, - ipnumber* values) override; + bool eval_jac_g( + ipindex n, + const ipnumber* x, + bool new_x, + ipindex m, + ipindex nele_jac, + ipindex* iRow, + ipindex* jCol, + ipnumber* values + ) override; /// Lower Lagrangian Hessian, or its structure when `values` is null - bool eval_h(ipindex n, - const ipnumber* x, - bool new_x, - ipnumber obj_factor, - ipindex m, - const ipnumber* lambda, - bool new_lambda, - ipindex nele_hess, - ipindex* iRow, - ipindex* jCol, - ipnumber* values) override; + bool eval_h( + ipindex n, + const ipnumber* x, + bool new_x, + ipnumber obj_factor, + ipindex m, + const ipnumber* lambda, + bool new_lambda, + ipindex nele_hess, + ipindex* iRow, + ipindex* jCol, + ipnumber* values + ) override; /// Leave the final point, its multipliers, its objective, and its constraints in the model - void finalize_solution(SolverReturn status, - ipindex n, - const ipnumber* x, - const ipnumber* z_L, - const ipnumber* z_U, - ipindex m, - const ipnumber* g, - const ipnumber* lambda, - ipnumber obj_value, - const IpoptData* ip_data, - IpoptCalculatedQuantities* ip_cq) override; + void finalize_solution( + SolverReturn status, + ipindex n, + const ipnumber* x, + const ipnumber* z_L, + const ipnumber* z_U, + ipindex m, + const ipnumber* g, + const ipnumber* lambda, + ipnumber obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq + ) override; private: /// Copy `values` from Ipopt into a model vector diff --git a/GridKit/Solver/SteadyState/Kinsol.cpp b/GridKit/Solver/SteadyState/Kinsol.cpp index ac018c0577..9b57f2c110 100644 --- a/GridKit/Solver/SteadyState/Kinsol.cpp +++ b/GridKit/Solver/SteadyState/Kinsol.cpp @@ -21,6 +21,7 @@ #include // access to dense SUNMatrix #include +#include namespace AnalysisManager { @@ -32,13 +33,14 @@ namespace AnalysisManager { model_ = model; residual_ = - [model](std::span values, std::span residual) + [model](std::span values, std::span residual) { std::copy(values.begin(), values.end(), model->y().getData()); model->y().setDataUpdated(); const int status = model->evaluateResidual(); std::copy_n( - model->getResidual().getData(), residual.size(), residual.begin()); + model->getResidual().getData(), residual.size(), residual.begin() + ); return status; }; } @@ -109,9 +111,10 @@ namespace AnalysisManager // Set up linear solver JacobianMat_ = SUNDenseMatrix( - static_cast(size_), - static_cast(size_), - context_); + static_cast(size_), + static_cast(size_), + context_ + ); checkAllocation(context_, (void*) JacobianMat_, "SUNDenseMatrix"); linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); @@ -129,7 +132,8 @@ namespace AnalysisManager if (!model_) { throw std::logic_error( - "KINSOL requires an explicit initial guess when used with a callback"); + "KINSOL requires an explicit initial guess when used with a callback" + ); } model_->initialize(); @@ -147,14 +151,15 @@ namespace AnalysisManager } template - int Kinsol::runSimulation(std::span values, - ResidualFunction residual, - bool line_search) + int Kinsol::runSimulation( + std::span values, ResidualFunction residual, bool line_search + ) { if (values.size() != static_cast(size_) || !residual) { throw std::invalid_argument( - "KINSOL requires a matching initial guess and a residual callback"); + "KINSOL requires a matching initial guess and a residual callback" + ); } // ensure the model callback is restored on scope exit @@ -187,7 +192,8 @@ namespace AnalysisManager callback_error_ = nullptr; const int retval = KINSol( - solver_, yy_, line_search ? KIN_LINESEARCH : KIN_NONE, scale_, scale_); + solver_, yy_, line_search ? KIN_LINESEARCH : KIN_NONE, scale_, scale_ + ); if (callback_error_) { std::rethrow_exception(callback_error_); @@ -215,8 +221,9 @@ namespace AnalysisManager try { return self.residual_( - {N_VGetArrayPointer(yy), static_cast(self.size_)}, - {N_VGetArrayPointer(rr), static_cast(self.size_)}); + {N_VGetArrayPointer(yy), static_cast(self.size_)}, + {N_VGetArrayPointer(rr), static_cast(self.size_)} + ); } catch (...) { @@ -283,7 +290,8 @@ namespace AnalysisManager // NOTE: this will only work if called immediately after the function auto errorCode = SUNContext_GetLastError(c); Logger::error() << std::format( - "Function {} failed: {}\n", functionName, SUNGetErrMsg(errorCode)); + "Function {} failed: {}\n", functionName, SUNGetErrMsg(errorCode) + ); throw SundialsException(); } } @@ -294,7 +302,8 @@ namespace AnalysisManager if (retval < 0) { Logger::error() << std::format( - "Function {} failed: {}\n", functionName, SUNGetErrMsg(retval)); + "Function {} failed: {}\n", functionName, SUNGetErrMsg(retval) + ); throw SundialsException(); } } @@ -325,7 +334,8 @@ namespace AnalysisManager void Kinsol::setJacobianUpdateInterval(long int iterations) { checkOutput( - KINSetMaxSetupCalls(solver_, iterations), "KINSetMaxSetupCalls"); + KINSetMaxSetupCalls(solver_, iterations), "KINSetMaxSetupCalls" + ); } // Compiler will prevent building modules with data type incompatible with diff --git a/GridKit/Solver/SteadyState/Kinsol.hpp b/GridKit/Solver/SteadyState/Kinsol.hpp index adfc834cbd..aafad99a77 100644 --- a/GridKit/Solver/SteadyState/Kinsol.hpp +++ b/GridKit/Solver/SteadyState/Kinsol.hpp @@ -34,15 +34,16 @@ namespace AnalysisManager using Logger = ::GridKit::Utilities::Logger; using RealT = typename GridKit::ScalarTraits::RealT; using VectorT = - typename GridKit::Model::Evaluator::VectorT; + typename GridKit::Model::Evaluator::VectorT; static_assert( - std::is_same_v, - "RealT must be the same type as sunrealtype"); + std::is_same_v, + "RealT must be the same type as sunrealtype" + ); public: using ResidualFunction = - std::function, std::span)>; + std::function, std::span)>; Kinsol(GridKit::Model::Evaluator* model); explicit Kinsol(IdxT size); @@ -65,9 +66,10 @@ namespace AnalysisManager /// @param line_search whether or not to use KINSOL's backtracking line /// search int runSimulation( - std::span values, - ResidualFunction residual, - bool line_search = true); + std::span values, + ResidualFunction residual, + bool line_search = true + ); int deleteSimulation(); diff --git a/GridKit/Solver/SundialsException.hpp b/GridKit/Solver/SundialsException.hpp index ca1bb2c007..20727b8e55 100644 --- a/GridKit/Solver/SundialsException.hpp +++ b/GridKit/Solver/SundialsException.hpp @@ -14,7 +14,8 @@ namespace AnalysisManager public: explicit SundialsException( - const char* message = "A SUNDIALS class wrapper failed!\n") + const char* message = "A SUNDIALS class wrapper failed!\n" + ) : message_(message) { } diff --git a/GridKit/Testing/AggregateErrors.hpp b/GridKit/Testing/AggregateErrors.hpp index 3a112fa967..753121391f 100644 --- a/GridKit/Testing/AggregateErrors.hpp +++ b/GridKit/Testing/AggregateErrors.hpp @@ -14,7 +14,7 @@ namespace GridKit { inline constexpr double DEFAULT_ABS_ERROR_THRESHOLD = - std::numeric_limits::epsilon(); + std::numeric_limits::epsilon(); /** * @brief Aggregate norm data for a single variable over time @@ -71,7 +71,8 @@ namespace GridKit * @brief Pretty-print label and values to output stream */ std::ostream& display( - std::ostream& os = std::cout, const std::string& indent = " ") const + std::ostream& os = std::cout, const std::string& indent = " " + ) const { os << indent << label << ":\n" << indent << indent << "max : " @@ -165,8 +166,8 @@ namespace GridKit { template explicit ErrorSetImpl( - const C& labels, - double abs_threshold = DEFAULT_ABS_ERROR_THRESHOLD) + const C& labels, double abs_threshold = DEFAULT_ABS_ERROR_THRESHOLD + ) : ErrorSet(labels), abs_threshold_(abs_threshold), ref_norms_(std::size(labels)) @@ -221,9 +222,10 @@ namespace GridKit template std::unique_ptr makeErrorSet( - ErrorType type, - const C& labels, - double abs_threshold = DEFAULT_ABS_ERROR_THRESHOLD) + ErrorType type, + const C& labels, + double abs_threshold = DEFAULT_ABS_ERROR_THRESHOLD + ) { switch (type) { diff --git a/GridKit/Testing/CSV.cpp b/GridKit/Testing/CSV.cpp index aa161216f9..1ef38265db 100644 --- a/GridKit/Testing/CSV.cpp +++ b/GridKit/Testing/CSV.cpp @@ -35,10 +35,12 @@ namespace GridKit return ifs; } - std::unique_ptr compareCSV(const std::string& f_test, - const std::string& f_ref, - ErrorType error_type, - double abs_threshold) + std::unique_ptr compareCSV( + const std::string& f_test, + const std::string& f_ref, + ErrorType error_type, + double abs_threshold + ) { // Open files and read labels auto ifs_test = checkOpenFile(f_test); diff --git a/GridKit/Testing/CSV.hpp b/GridKit/Testing/CSV.hpp index dadf5c99ac..abf04c1e66 100644 --- a/GridKit/Testing/CSV.hpp +++ b/GridKit/Testing/CSV.hpp @@ -21,10 +21,11 @@ namespace GridKit * @note This assumes a "time" variable is always in the first column. */ std::unique_ptr compareCSV( - const std::string& test_file, - const std::string& reference_file, - ErrorType error_type = ErrorType::RELATIVE, - double abs_threshold = DEFAULT_ABS_ERROR_THRESHOLD); + const std::string& test_file, + const std::string& reference_file, + ErrorType error_type = ErrorType::RELATIVE, + double abs_threshold = DEFAULT_ABS_ERROR_THRESHOLD + ); } // namespace Testing } // namespace GridKit diff --git a/GridKit/Testing/Testing.hpp b/GridKit/Testing/Testing.hpp index ec6a2e0687..f0534a797c 100644 --- a/GridKit/Testing/Testing.hpp +++ b/GridKit/Testing/Testing.hpp @@ -128,9 +128,11 @@ namespace GridKit } template - bool isEqual(const T value, - const T ref, - const T tol = std::numeric_limits::epsilon()) + bool isEqual( + const T value, + const T ref, + const T tol = std::numeric_limits::epsilon() + ) { T error = std::abs(value - ref) / (1.0 + std::abs(ref)); return (error < tol); @@ -148,9 +150,11 @@ namespace GridKit * @return bool - true if the maps are equal; false otherwise */ template - inline bool isEqual(std::map a, - std::map b, - const RealT tol = std::numeric_limits::epsilon()) + inline bool isEqual( + std::map a, + std::map b, + const RealT tol = std::numeric_limits::epsilon() + ) { int fail = 0; @@ -231,8 +235,8 @@ namespace GridKit throws(TFunc func, TArgs&&... args) { return Detail::ThrowsHelper{}( - [&]() - { func(std::forward(args)...); }); + [&]() { func(std::forward(args)...); } + ); } /// True when building a model throws `std::invalid_argument` or the diff --git a/GridKit/Utilities/CliArgs/ArgValue.hpp b/GridKit/Utilities/CliArgs/ArgValue.hpp index cd3274e3c7..532d16cdb4 100644 --- a/GridKit/Utilities/CliArgs/ArgValue.hpp +++ b/GridKit/Utilities/CliArgs/ArgValue.hpp @@ -30,14 +30,15 @@ namespace GridKit */ template static constexpr bool notAnArgValue = - !std::is_same_v, ArgValue>; + !std::is_same_v, ArgValue>; /** * @brief Check that T != std::initializer_list */ template - static constexpr bool notAnArgValueList = - !std::is_same_v, std::initializer_list>; + static constexpr bool notAnArgValueList = !std::is_same_v< + std::remove_reference_t, + std::initializer_list>; /** * @brief Check that T is not an ArgValue or list of ArgValues diff --git a/GridKit/Utilities/CliArgs/CliArgs.hpp b/GridKit/Utilities/CliArgs/CliArgs.hpp index 75610902a1..a732d562eb 100644 --- a/GridKit/Utilities/CliArgs/CliArgs.hpp +++ b/GridKit/Utilities/CliArgs/CliArgs.hpp @@ -43,7 +43,7 @@ namespace GridKit * and the application will exit. * * @note The usage syntax is intended to be similar to - * [ArgParse.jl](https://carlobaldassi.github.io/ArgParse.jl/stable/). + * [ArgParse.jl](https://carlobaldassi.github.io/ArgParse.jl/stable/). * * @note `repeatable = true` allows a named option to occur multiple times. * diff --git a/GridKit/Utilities/CliArgs/CliArgsImpl.hpp b/GridKit/Utilities/CliArgs/CliArgsImpl.hpp index 2de5adb602..9802fa9509 100644 --- a/GridKit/Utilities/CliArgs/CliArgsImpl.hpp +++ b/GridKit/Utilities/CliArgs/CliArgsImpl.hpp @@ -52,7 +52,8 @@ namespace GridKit OptionArgumentPair* findByName(const std::string& name) { return const_cast( - const_cast(this)->findByName(name)); + const_cast(this)->findByName(name) + ); } /// Option lookup via raw (hyphened) name @@ -100,7 +101,8 @@ namespace GridKit inline const std::string& typeString(const Option& opt) { static const std::string labels[] = { - "STRING", "REAL", "INT", "BOOL", "UNSPECIFIED"}; + "STRING", "REAL", "INT", "BOOL", "UNSPECIFIED" + }; return labels[static_cast(opt.type)]; } @@ -147,7 +149,8 @@ namespace GridKit if (!name_map_.try_emplace(name, arg).second) { auto msg = std::format( - "CliArgs: attempted to add duplicate option name: \"{}\"", name); + "CliArgs: attempted to add duplicate option name: \"{}\"", name + ); Log::error() << msg << std::endl; throw std::runtime_error(msg); } @@ -169,8 +172,9 @@ namespace GridKit || arg.option.nargs == 0) { throw std::invalid_argument( - "CliArgs: positional arguments require a bare name and a positive " - "nargs"); + "CliArgs: positional arguments require a bare name and a positive " + "nargs" + ); } mapName(name[0], &arg); positionals_.push_back(&arg); @@ -185,7 +189,8 @@ namespace GridKit if (!notANumber(name[1])) { auto msg = std::format( - "CliArgs: Cannot use number as option name: \"{}\"", name[1]); + "CliArgs: Cannot use number as option name: \"{}\"", name[1] + ); Log::error() << msg << std::endl; throw std::runtime_error(msg); } @@ -213,16 +218,19 @@ namespace GridKit if (!name_map_.count("help") && !name_map_.count("h")) { auto& help = table_.emplace_back( - Option{ - .name = {"--help", "-h"}, - .help = "Print this help message", - .flag = true}); + Option{ + .name = {"--help", "-h"}, + .help = "Print this help message", + .flag = true + } + ); setupArg(help); } } const OptionArgumentPair* CliArgsImpl::findByName( - const std::string& name) const + const std::string& name + ) const { auto ret = name_map_.find(name); if (ret == name_map_.end()) @@ -275,14 +283,16 @@ namespace GridKit if (!arg || arg->option.positional) { Log::error() << std::format( - "CliArgs: unrecognized option \"{}\"\n", token); + "CliArgs: unrecognized option \"{}\"\n", token + ); status = false; continue; } if (!arg->option.repeatable && !arg->values.empty()) { Log::error() << std::format( - "CliArgs: option \"{}\" cannot be repeated\n", arg->option.name[0]); + "CliArgs: option \"{}\" cannot be repeated\n", arg->option.name[0] + ); status = false; } if (arg->option.flag) @@ -306,10 +316,11 @@ namespace GridKit if (count != arg->option.nargs) { Log::error() << std::format( - "CliArgs: option \"{}\" requires {} arguments. {} were given\n", - arg->option.name[0], - arg->option.nargs, - count); + "CliArgs: option \"{}\" requires {} arguments. {} were given\n", + arg->option.name[0], + arg->option.nargs, + count + ); status = false; } continue; @@ -317,14 +328,15 @@ namespace GridKit while (positional < positionals_.size() && positionals_[positional]->values.size() - == positionals_[positional]->option.nargs) + == positionals_[positional]->option.nargs) { ++positional; } if (positional == positionals_.size()) { Log::error() << std::format( - "CliArgs: unexpected argument \"{}\"\n", token); + "CliArgs: unexpected argument \"{}\"\n", token + ); status = false; } else @@ -345,18 +357,20 @@ namespace GridKit if (arg.option.required && arg.values.empty()) { Log::error() << std::format( - "CliArgs: no input was given for the required option \"{}\"\n", - arg.option.name[0]); + "CliArgs: no input was given for the required option \"{}\"\n", + arg.option.name[0] + ); status = false; } else if (arg.option.positional && !arg.values.empty() && arg.values.size() != arg.option.nargs) { Log::error() << std::format( - "CliArgs: argument \"{}\" requires {} values. {} were given\n", - arg.option.name[0], - arg.option.nargs, - arg.values.size()); + "CliArgs: argument \"{}\" requires {} values. {} were given\n", + arg.option.name[0], + arg.option.nargs, + arg.values.size() + ); status = false; } } @@ -436,10 +450,11 @@ namespace GridKit * This function attempts to take care of line breaks well */ void printParagraph( - std::ostream& os, - std::string_view par, - unsigned indent, - unsigned lineLength) + std::ostream& os, + std::string_view par, + unsigned indent, + unsigned lineLength + ) { // Through remainder of this function, 'lineLength' will be the length // available for characters, not including indent. @@ -466,9 +481,9 @@ namespace GridKit } unsigned remaining = - static_cast(std::distance(lineBegin, parEnd)); + static_cast(std::distance(lineBegin, parEnd)); auto lineEnd = - lineBegin + ((remaining < lineLength) ? remaining : lineLength); + lineBegin + ((remaining < lineLength) ? remaining : lineLength); // prevent chopped words // Is lineEnd between two non-space characters? @@ -509,10 +524,11 @@ namespace GridKit * @brief Print the help description of an option as a paragraph */ void printOptionHelp( - std::ostream& os, - const std::string& desc, - unsigned firstColWidth, - unsigned lineLength) + std::ostream& os, + const std::string& desc, + unsigned firstColWidth, + unsigned lineLength + ) { // we need to use one char less per line to work correctly if actual // console has longer lines @@ -542,7 +558,8 @@ namespace GridKit * description [and defaults] */ void printOption( - std::ostream& os, const Option& opt, unsigned firstColWidth) + std::ostream& os, const Option& opt, unsigned firstColWidth + ) { auto c1 = formatFirstColumn(opt); os << c1; @@ -646,7 +663,7 @@ namespace GridKit if (!arg) { auto msg = - std::format("CliArgs: unrecognized option requested: \"{}\"", name); + std::format("CliArgs: unrecognized option requested: \"{}\"", name); Log::error() << msg << '\n'; throw std::runtime_error(msg); } diff --git a/GridKit/Utilities/Enum.hpp b/GridKit/Utilities/Enum.hpp index 034f8a6b90..30a2a7620c 100644 --- a/GridKit/Utilities/Enum.hpp +++ b/GridKit/Utilities/Enum.hpp @@ -41,10 +41,10 @@ namespace GridKit /// An enum with a contiguous sequence of variants, a known maximum value, /// and an underlying type of `std::size_t`. template - concept SizedEnum = std::is_enum_v - && std::is_same_v, - std::size_t> - && is_contiguous_enum(); + concept SizedEnum = + std::is_enum_v + && std::is_same_v, std::size_t> + && is_contiguous_enum(); /// Simplest enum satisfying [`SizedEnum`]. enum class EmptyEnum : std::size_t @@ -68,7 +68,7 @@ namespace GridKit /// Variant of `magic_enum::enum_cast` that permits passing empty enums. template > constexpr auto enum_cast(std::string_view value, BinaryPredicate predicate) - -> std::optional + -> std::optional { if constexpr (magic_enum::enum_count() == 0) { @@ -113,8 +113,9 @@ namespace GridKit constexpr auto enum_values() { return std::views::iota( - std::size_t{0}, - static_cast(magic_enum::enum_count())) + std::size_t{0}, + static_cast(magic_enum::enum_count()) + ) | std::views::transform([](std::size_t i) { return static_cast(i); }); } diff --git a/GridKit/Utilities/FileIO.hpp b/GridKit/Utilities/FileIO.hpp index 9a8d8bb5bd..1001faba27 100644 --- a/GridKit/Utilities/FileIO.hpp +++ b/GridKit/Utilities/FileIO.hpp @@ -35,10 +35,12 @@ namespace GridKit * variables. */ template - void setLookupTable(std::vector>& table, - std::istream& idata, - ScalarT& ti, - ScalarT& tf) + void setLookupTable( + std::vector>& table, + std::istream& idata, + ScalarT& ti, + ScalarT& tf + ) { std::string line; int oldwordcount = -1; diff --git a/GridKit/Utilities/Logger/Logger.cpp b/GridKit/Utilities/Logger/Logger.cpp index 4502f3578b..b6d2d8c03c 100644 --- a/GridKit/Utilities/Logger/Logger.cpp +++ b/GridKit/Utilities/Logger/Logger.cpp @@ -44,7 +44,7 @@ namespace GridKit * * @pre `output_streams_` vector is allocated * @post Verbosity level is set to user supplied value `v` and outputs - * for `output_streams_` are set accordingly. + * for `output_streams_` are set accordingly. */ void Logger::setVerbosity(Verbosity v) { @@ -60,7 +60,7 @@ namespace GridKit * * @pre `output_streams_` vector is allocated * @post Verbosity level is the larger of its previous value and `v`, and - * outputs for `output_streams_` are set accordingly. + * outputs for `output_streams_` are set accordingly. */ void Logger::raiseVerbosity(Verbosity v) { @@ -87,8 +87,8 @@ namespace GridKit * * @pre Vector `output_streams` is allocated and correctly initialized. * @post All streams `output_stream_[i]`, where `i <= verbosity_` are - * directed to stream `logger_`. The rest are sent to null device - * (not printed). + * directed to stream `logger_`. The rest are sent to null device + * (not printed). */ void Logger::updateVerbosity(std::vector& output_streams) { @@ -133,7 +133,7 @@ namespace GridKit { using namespace Colors; *(output_streams_[WARNINGS]) - << "[" << YELLOW << "WARNING" << CLEAR << "] "; + << "[" << YELLOW << "WARNING" << CLEAR << "] "; return *(output_streams_[WARNINGS]); } @@ -155,7 +155,7 @@ namespace GridKit * @brief Returns reference to output stream for all other messages. * * @return Reference to output stream to miscellaneous messages - * in `output_streams_`. + * in `output_streams_`. * * @pre `output_streams_` vector is allocated and correctly initialized. */ @@ -205,7 +205,7 @@ namespace GridKit * * @pre Output file `file_` has been opened. * @post Output file `file_` is closed and active output streams are - * set to default output `std::cout`. + * set to default output `std::cout`. */ void Logger::closeOutputFile() { diff --git a/GridKit/Utilities/String.hpp b/GridKit/Utilities/String.hpp index 6117f57d58..82ad298b30 100644 --- a/GridKit/Utilities/String.hpp +++ b/GridKit/Utilities/String.hpp @@ -14,9 +14,10 @@ namespace GridKit inline bool isValidIdentifier(std::string_view id) { return id.find_first_not_of( - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789 _.-") + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789 _.-" + ) == std::string_view::npos; } @@ -57,7 +58,9 @@ namespace GridKit if (ss.fail() || !ss.eof()) { throw std::runtime_error( - "Failed to parse \""s + str + "\" as value of type \'" + typeid(T).name() + "\'"); + "Failed to parse \""s + str + "\" as value of type \'" + + typeid(T).name() + "\'" + ); } return ret; } diff --git a/application/PhasorDynamics/AnalysisUtilities.hpp b/application/PhasorDynamics/AnalysisUtilities.hpp index e547165266..1ea3855e19 100644 --- a/application/PhasorDynamics/AnalysisUtilities.hpp +++ b/application/PhasorDynamics/AnalysisUtilities.hpp @@ -133,32 +133,33 @@ namespace GridKit if (!std::isfinite(value) || value <= 0.0) { throw std::invalid_argument( - std::string(name) + " must be positive and finite"); + std::string(name) + " must be positive and finite" + ); } return value; }; c.cosim_rel_tol = tolerance("cosim_rel_tol", DEFAULT_COSIM_REL_TOL); c.cosim_step_tol = tolerance("cosim_step_tol", DEFAULT_COSIM_STEP_TOL); c.cosim_function_error = - tolerance("cosim_function_error", DEFAULT_COSIM_FUNCTION_ERROR); + tolerance("cosim_function_error", DEFAULT_COSIM_FUNCTION_ERROR); c.dt_fixed = j.value("dt_fixed", 0.0); c.max_steps = j.value("max_steps", std::size_t{0}); c.max_order = j.value("max_order", 5); c.consistent_ic_type = - AnalysisManager::Sundials::IdaConsistentICType::YA_YDP; + AnalysisManager::Sundials::IdaConsistentICType::YA_YDP; if (j.contains("consistent_ic_type")) { const auto consistent_ic_type_str = - j.at("consistent_ic_type").get(); + j.at("consistent_ic_type").get(); if (consistent_ic_type_str == "y") { c.consistent_ic_type = - AnalysisManager::Sundials::IdaConsistentICType::Y; + AnalysisManager::Sundials::IdaConsistentICType::Y; } else if (consistent_ic_type_str == "ya_ydp") { c.consistent_ic_type = - AnalysisManager::Sundials::IdaConsistentICType::YA_YDP; + AnalysisManager::Sundials::IdaConsistentICType::YA_YDP; } else { @@ -252,7 +253,7 @@ namespace GridKit } c.abs_err_threshold = - j.value("abs_err_threshold", Testing::DEFAULT_ABS_ERROR_THRESHOLD); + j.value("abs_err_threshold", Testing::DEFAULT_ABS_ERROR_THRESHOLD); } /** @@ -348,7 +349,8 @@ namespace GridKit } Testing::TestStatus checkErrors( - const StudyData& study_data, bool print_results = true) + const StudyData& study_data, bool print_results = true + ) { // Generate aggregate errors comparing variable output to reference // solution @@ -360,10 +362,11 @@ namespace GridKit if (!out_file.empty() && !ref_file.empty()) { auto errorSet = Testing::compareCSV( - out_file, - ref_file, - study_data.error_type, - study_data.abs_err_threshold); + out_file, + ref_file, + study_data.error_type, + study_data.abs_err_threshold + ); // Print the errors if (print_results) @@ -378,7 +381,7 @@ namespace GridKit for (std::size_t i = 0; i < study_data.error_tol.size(); ++i) { status *= - errorSet->var_errors[i].max_value < study_data.error_tol[i]; + errorSet->var_errors[i].max_value < study_data.error_tol[i]; } } else diff --git a/application/PhasorDynamics/CoSimulation.hpp b/application/PhasorDynamics/CoSimulation.hpp index edbfa9b776..1949d2db1b 100644 --- a/application/PhasorDynamics/CoSimulation.hpp +++ b/application/PhasorDynamics/CoSimulation.hpp @@ -20,54 +20,62 @@ namespace GridKit namespace PhasorDynamics { inline CoSim::RunResult runCoupledClientStudies( - const SimulationOptions& options, - NextCoupledStudy next, - CompleteCoupledStudy complete, - bool shutdown_peer, - bool print_results = false) + const SimulationOptions& options, + NextCoupledStudy next, + CompleteCoupledStudy complete, + bool shutdown_peer, + bool print_results = false + ) { CoupledClient client( - options, - std::move(next), - std::move(complete), - shutdown_peer, - print_results); + options, + std::move(next), + std::move(complete), + shutdown_peer, + print_results + ); CoSim::CoSim adapter( - options.endpoint, - CoSim::MessageStepFunction( - [&]( - const CoSimulationMessage& reply, - const CoSim::MessageExchangeFunction& exchange) - { return client.handleReply(reply, exchange); }), - CoSim::MessageExtractFunction([&](const auto&) - { return client.extract(); }), - options.timeout_ms); + options.endpoint, + CoSim::MessageStepFunction( + [&]( + const CoSimulationMessage& reply, + const CoSim::MessageExchangeFunction& exchange + ) { return client.handleReply(reply, exchange); } + ), + CoSim::MessageExtractFunction([&](const auto&) + { return client.extract(); }), + options.timeout_ms + ); const auto result = adapter.run(); if (result == CoSim::RunResult::COMPLETED && !client.finished()) { throw std::runtime_error( - "co-simulation peer ended before the study completed"); + "co-simulation peer ended before the study completed" + ); } return result; } inline Testing::TestStatus runCoupledServer( - const StudyData& base, const SimulationOptions& options) + const StudyData& base, const SimulationOptions& options + ) { CoupledServer server(base, options); CoSim::CoSim adapter( - options.endpoint, - CoSim::MessageStepFunction( - [&](const CoSimulationMessage& message, const auto&) - { return server.handleRequest(message); }), - CoSim::MessageExtractFunction([&](const auto&) - { return server.extract(); }), - options.timeout_ms); + options.endpoint, + CoSim::MessageStepFunction( + [&](const CoSimulationMessage& message, const auto&) + { return server.handleRequest(message); } + ), + CoSim::MessageExtractFunction([&](const auto&) + { return server.extract(); }), + options.timeout_ms + ); if (adapter.run() == CoSim::RunResult::STOPPED) { @@ -77,14 +85,16 @@ namespace GridKit if (!server.finished()) { throw std::runtime_error( - "co-simulation peer closed before the study completed"); + "co-simulation peer closed before the study completed" + ); } return server.status(); } inline Testing::TestStatus runCoupledStudy( - const StudyData& data, const SimulationOptions& options) + const StudyData& data, const SimulationOptions& options + ) { if (options.role == "server") { @@ -105,12 +115,12 @@ namespace GridKit }; if (runCoupledClientStudies( - options, - next, - [&](Testing::TestStatus result) - { status *= result; }, - false, - true) + options, + next, + [&](Testing::TestStatus result) { status *= result; }, + false, + true + ) == CoSim::RunResult::STOPPED) { status = false; diff --git a/application/PhasorDynamics/ContingencyAnalysis.cpp b/application/PhasorDynamics/ContingencyAnalysis.cpp index 162583cb6d..93aa6012e6 100644 --- a/application/PhasorDynamics/ContingencyAnalysis.cpp +++ b/application/PhasorDynamics/ContingencyAnalysis.cpp @@ -61,7 +61,8 @@ TestStatus singleFaultStudy(std::size_t fault_id, StudyData study_data) } void runStudySerial( - const StudyData& study_data, std::vector& stat_vec) + const StudyData& study_data, std::vector& stat_vec +) { for (std::size_t i = 0; i < study_data.model_data.bus.size(); ++i) { @@ -72,7 +73,8 @@ void runStudySerial( #ifdef GRIDKIT_ENABLE_THREADS void runStudyAsync( - const StudyData& study_data, std::vector& stat_vec) + const StudyData& study_data, std::vector& stat_vec +) { auto n_faults = study_data.model_data.bus.size(); @@ -81,7 +83,8 @@ void runStudyAsync( for (std::size_t i = 0; i < n_faults; ++i) { futures.emplace_back( - std::async(std::launch::async, singleFaultStudy, i, study_data)); + std::async(std::launch::async, singleFaultStudy, i, study_data) + ); } for (std::size_t i = 0; i < n_faults; ++i) @@ -94,7 +97,8 @@ void runStudyAsync( #ifdef _OPENMP void runStudyOpenMP( - const StudyData& study_data, std::vector& stat_vec) + const StudyData& study_data, std::vector& stat_vec +) { auto n_faults = study_data.model_data.bus.size(); #pragma omp parallel for @@ -147,11 +151,11 @@ int runApplication(int argc, const char* argv[]) return data; }; if (runCoupledClientStudies( - options, - next, - [&](TestStatus result) - { stat_vec[completed++] = result; }, - true) + options, + next, + [&](TestStatus result) { stat_vec[completed++] = result; }, + true + ) == GridKit::CoSim::RunResult::STOPPED) { return 1; diff --git a/application/PhasorDynamics/CoupledClient.hpp b/application/PhasorDynamics/CoupledClient.hpp index 97abfa9c78..912619602c 100644 --- a/application/PhasorDynamics/CoupledClient.hpp +++ b/application/PhasorDynamics/CoupledClient.hpp @@ -31,7 +31,7 @@ namespace GridKit class CoupledClient { using InterfaceSolver = - AnalysisManager::Sundials::Kinsol; + AnalysisManager::Sundials::Kinsol; const SimulationOptions& options_; NextCoupledStudy next_; @@ -57,7 +57,8 @@ namespace GridKit session_++; simulation_ = std::make_unique( - *data_, options_.inputs, options_.outputs); + *data_, options_.inputs, options_.outputs + ); outgoing_ = CoSimulationMessage(CoSim::MessageType::INIT, session_); @@ -88,7 +89,8 @@ namespace GridKit if (time < 0.0 || time > data_->tmax) { throw std::runtime_error( - "peer event time is outside the study interval"); + "peer event time is outside the study interval" + ); } } @@ -118,8 +120,9 @@ namespace GridKit /// Solve $F(inputs) - inputs = 0$ at the current time, holding /// differential states fixed in both partitions. void solveInterface( - const Signals& initial, - const CoSim::MessageExchangeFunction& exchange) + const Signals& initial, + const CoSim::MessageExchangeFunction& exchange + ) { simulation_->setInputs(initial); Signals trial = initial; @@ -133,15 +136,16 @@ namespace GridKit } const auto evaluate = - [&](std::span guess, std::span result) + [&](std::span guess, std::span result) { if (evaluated && std::equal( - guess.begin(), - guess.end(), - trial.begin(), - [](double value, const auto& input) - { return value == input.second; })) + guess.begin(), + guess.end(), + trial.begin(), + [](double value, const auto& input) + { return value == input.second; } + )) { if (result.data() != residual.data()) { @@ -160,14 +164,16 @@ namespace GridKit simulation_->refresh(); auto message = CoSimulationMessage( - CoSim::MessageType::UPDATE, session_, simulation_->time()); + CoSim::MessageType::UPDATE, session_, simulation_->time() + ); message.signals = simulation_->outputs(); const auto reply = exchange(message); if (reply.signals.size() != trial.size()) { throw std::runtime_error( - "Peer signal names do not match the configured inputs"); + "Peer signal names do not match the configured inputs" + ); } i = 0; @@ -190,7 +196,7 @@ namespace GridKit for (std::size_t i = 0; i < values.size(); ++i) { if (std::abs(residual[i]) * scales[i] - / std::max(1.0, std::abs(values[i])) + / std::max(1.0, std::abs(values[i])) >= data_->cosim_rel_tol) { return false; @@ -208,14 +214,15 @@ namespace GridKit if (!interface_solver_) { interface_solver_ = - std::make_unique(values.size()); + std::make_unique(values.size()); interface_solver_->configureSimulation(); interface_solver_->setJacobianUpdateInterval(1); } interface_solver_->setFunctionError(data_->cosim_function_error); interface_solver_->setTolerance( - data_->cosim_rel_tol, data_->cosim_step_tol); + data_->cosim_rel_tol, data_->cosim_step_tol + ); interface_solver_->runSimulation(values, evaluate, false); evaluate(values, residual); @@ -224,25 +231,30 @@ namespace GridKit if (!converged()) { interface_solver_->setTolerance( - std::max( - 0.01 * data_->cosim_rel_tol, - std::numeric_limits::denorm_min()), - data_->cosim_step_tol); + std::max( + 0.01 * data_->cosim_rel_tol, + std::numeric_limits::denorm_min() + ), + data_->cosim_step_tol + ); interface_solver_->runSimulation(values, evaluate, false); evaluate(values, residual); if (!converged()) { throw std::runtime_error( - std::format( - "co-simulation interface did not converge at t={}", - simulation_->time())); + std::format( + "co-simulation interface did not converge at t={}", + simulation_->time() + ) + ); } } } outgoing_ = CoSimulationMessage( - CoSim::MessageType::COMMIT, session_, simulation_->time()); + CoSim::MessageType::COMMIT, session_, simulation_->time() + ); } void advance() @@ -259,12 +271,12 @@ namespace GridKit } const double exchange_time = - static_cast(step_) * options_.interval; + static_cast(step_) * options_.interval; const double target = - std::min(exchange_time, boundaries_.at(boundary_)); + std::min(exchange_time, boundaries_.at(boundary_)); simulation_->advance(target); outgoing_ = - CoSimulationMessage(CoSim::MessageType::STEP, session_, target); + CoSimulationMessage(CoSim::MessageType::STEP, session_, target); outgoing_.signals = simulation_->outputs(); if (sameTime(target, exchange_time)) @@ -275,11 +287,12 @@ namespace GridKit public: CoupledClient( - const SimulationOptions& options, - NextCoupledStudy next, - CompleteCoupledStudy complete, - bool shutdown_peer, - bool print_results) + const SimulationOptions& options, + NextCoupledStudy next, + CompleteCoupledStudy complete, + bool shutdown_peer, + bool print_results + ) : options_(options), next_(std::move(next)), complete_(std::move(complete)), @@ -303,8 +316,9 @@ namespace GridKit } bool handleReply( - const CoSimulationMessage& reply, - const CoSim::MessageExchangeFunction& exchange) + const CoSimulationMessage& reply, + const CoSim::MessageExchangeFunction& exchange + ) { switch (outgoing_.type) { @@ -320,7 +334,8 @@ namespace GridKit if (sameTime(simulation_->time(), data_->tmax)) { outgoing_ = CoSimulationMessage( - CoSim::MessageType::END, session_, data_->tmax); + CoSim::MessageType::END, session_, data_->tmax + ); } else { diff --git a/application/PhasorDynamics/CoupledServer.hpp b/application/PhasorDynamics/CoupledServer.hpp index dfedf6c7dd..9cdb15dcee 100644 --- a/application/PhasorDynamics/CoupledServer.hpp +++ b/application/PhasorDynamics/CoupledServer.hpp @@ -35,7 +35,8 @@ namespace GridKit || !sameTime(message.interval, options_.interval)) { throw std::runtime_error( - "invalid co-simulation initialization or incompatible study timing"); + "invalid co-simulation initialization or incompatible study timing" + ); } session_ = message.session; @@ -47,7 +48,8 @@ namespace GridKit } simulation_ = std::make_unique( - data_, options_.inputs, options_.outputs, &message.signals); + data_, options_.inputs, options_.outputs, &message.signals + ); simulation_->start(); outgoing_.signals = simulation_->outputs(); outgoing_.final_time = data_.tmax; @@ -96,7 +98,7 @@ namespace GridKit bool handleRequest(const CoSimulationMessage& message) { outgoing_ = - CoSimulationMessage(message.type, message.session, message.time); + CoSimulationMessage(message.type, message.session, message.time); if (message.type == CoSim::MessageType::INIT) { beginStudy(message); @@ -108,7 +110,8 @@ namespace GridKit if (simulation_ || message.session != session_) { throw std::runtime_error( - "shutdown requires a completed co-simulation session"); + "shutdown requires a completed co-simulation session" + ); } return false; } @@ -116,7 +119,8 @@ namespace GridKit if (!simulation_ || message.session != session_) { throw std::runtime_error( - "co-simulation message has no matching active session"); + "co-simulation message has no matching active session" + ); } switch (message.type) @@ -124,10 +128,12 @@ namespace GridKit case CoSim::MessageType::STEP: if (message.time - simulation_->time() > options_.interval && !sameTime( - message.time - simulation_->time(), options_.interval)) + message.time - simulation_->time(), options_.interval + )) { throw std::runtime_error( - "co-simulation step exceeds the exchange interval"); + "co-simulation step exceeds the exchange interval" + ); } simulation_->setInputs(message.signals); @@ -139,7 +145,8 @@ namespace GridKit if (!sameTime(message.time, simulation_->time())) { throw std::runtime_error( - "interface update has the wrong simulation time"); + "interface update has the wrong simulation time" + ); } if (message.type == CoSim::MessageType::UPDATE) diff --git a/application/PhasorDynamics/DynamicSimulation.cpp b/application/PhasorDynamics/DynamicSimulation.cpp index a473d5f722..15f64700b2 100644 --- a/application/PhasorDynamics/DynamicSimulation.cpp +++ b/application/PhasorDynamics/DynamicSimulation.cpp @@ -24,7 +24,7 @@ int runApplication(int argc, const char* argv[]) } const auto elapsed = - std::chrono::duration(std::chrono::steady_clock::now() - start); + std::chrono::duration(std::chrono::steady_clock::now() - start); Log::summary() << "Complete in " << elapsed.count() << " seconds\n"; return status.get(); } diff --git a/application/PhasorDynamics/SimulationOptions.hpp b/application/PhasorDynamics/SimulationOptions.hpp index 5e93ce5692..a1a1510501 100644 --- a/application/PhasorDynamics/SimulationOptions.hpp +++ b/application/PhasorDynamics/SimulationOptions.hpp @@ -56,7 +56,8 @@ namespace GridKit || text.find_first_not_of("0123456789") != std::string::npos) { throw std::invalid_argument( - std::format("expected a nonnegative signal ID: {}", text)); + std::format("expected a nonnegative signal ID: {}", text) + ); } const auto value = Utilities::parse(text); @@ -64,7 +65,8 @@ namespace GridKit if (value >= std::numeric_limits::max()) { throw std::invalid_argument( - std::format("signal ID is out of range: {}", text)); + std::format("signal ID is out of range: {}", text) + ); } return value; @@ -72,39 +74,41 @@ namespace GridKit /// Parse command line options to a simulation application. inline SimulationOptions parseSimulationOptions( - int argc, const char* argv[], bool contingency = false) + int argc, const char* argv[], bool contingency = false + ) { using Utilities::ArgType; Utilities::CliArgs args{ - {.name = {"solver_file"}, - .help = "Path to the solver JSON file", - .required = true, - .type = ArgType::String, - .positional = true}, - {.name = {"--cosim-role"}, - .help = "Co-simulation role (client, server)", - .type = ArgType::String}, - {.name = {"--cosim-endpoint"}, - .help = "ZeroMQ endpoint, e.g. tcp://127.0.0.1:8800", - .type = ArgType::String}, - {.name = {"--cosim-dt"}, - .help = "Positive exchange interval in seconds", - .type = ArgType::Real}, - {.name = {"--cosim-input"}, - .help = "Receive JSON key NAME into signal ID: " - "NAME=ID (repeatable)", - .type = ArgType::String, - .repeatable = true}, - {.name = {"--cosim-output"}, - .help = "Send signal ID as JSON key NAME: NAME=ID (repeatable)", - .type = ArgType::String, - .repeatable = true}, - {.name = {"--cosim-timeout-ms"}, - .help = "Send/receive timeout in milliseconds (default: 30000)", - .type = ArgType::Integer}, - {.name = {"--cosim-serve"}, - .help = "Server continues to accept sessions until shutdown", - .flag = true}}; + {.name = {"solver_file"}, + .help = "Path to the solver JSON file", + .required = true, + .type = ArgType::String, + .positional = true}, + {.name = {"--cosim-role"}, + .help = "Co-simulation role (client, server)", + .type = ArgType::String}, + {.name = {"--cosim-endpoint"}, + .help = "ZeroMQ endpoint, e.g. tcp://127.0.0.1:8800", + .type = ArgType::String}, + {.name = {"--cosim-dt"}, + .help = "Positive exchange interval in seconds", + .type = ArgType::Real}, + {.name = {"--cosim-input"}, + .help = "Receive JSON key NAME into signal ID: " + "NAME=ID (repeatable)", + .type = ArgType::String, + .repeatable = true}, + {.name = {"--cosim-output"}, + .help = "Send signal ID as JSON key NAME: NAME=ID (repeatable)", + .type = ArgType::String, + .repeatable = true}, + {.name = {"--cosim-timeout-ms"}, + .help = "Send/receive timeout in milliseconds (default: 30000)", + .type = ArgType::Integer}, + {.name = {"--cosim-serve"}, + .help = "Server continues to accept sessions until shutdown", + .flag = true} + }; args.parseArgs(argc, argv); SimulationOptions options; @@ -124,7 +128,8 @@ namespace GridKit if (!std::isfinite(options.interval) || options.interval <= 0.0) { throw std::invalid_argument( - "co-simulation exchange interval must be positive and finite"); + "co-simulation exchange interval must be positive and finite" + ); } } if (!args["cosim-timeout-ms"].empty()) @@ -146,16 +151,19 @@ namespace GridKit if (equal == std::string::npos || equal == 0) { throw std::invalid_argument( - std::format("signal mapping must be NAME=ID: {}", value)); + std::format("signal mapping must be NAME=ID: {}", value) + ); } if (!mappings - .emplace( - value.substr(0, equal), - parseSignalId(value.substr(equal + 1))) - .second) + .emplace( + value.substr(0, equal), + parseSignalId(value.substr(equal + 1)) + ) + .second) { throw std::invalid_argument( - std::format("duplicate signal name: {}", value)); + std::format("duplicate signal name: {}", value) + ); } } }; @@ -165,32 +173,36 @@ namespace GridKit if (options.solver_file.empty()) { throw std::invalid_argument( - "no solver file provided. use --help for usage"); + "no solver file provided. use --help for usage" + ); } const bool is_cosim = - options.serve || !args["cosim-role"].empty() - || !args["cosim-endpoint"].empty() || !args["cosim-dt"].empty() - || !args["cosim-input"].empty() || !args["cosim-output"].empty() - || !args["cosim-timeout-ms"].empty(); + options.serve || !args["cosim-role"].empty() + || !args["cosim-endpoint"].empty() || !args["cosim-dt"].empty() + || !args["cosim-input"].empty() || !args["cosim-output"].empty() + || !args["cosim-timeout-ms"].empty(); if (is_cosim) { #ifndef GRIDKIT_ENABLE_ZMQ throw std::invalid_argument( - "co-simulation requires a build with GRIDKIT_ENABLE_ZMQ=ON"); + "co-simulation requires a build with GRIDKIT_ENABLE_ZMQ=ON" + ); #endif if ((options.role != "client" && options.role != "server") || options.endpoint.empty() || options.interval <= 0.0 || options.inputs.empty() || options.outputs.empty()) { throw std::invalid_argument( - "co-simulation requires role, endpoint, dt, input and output " - "mappings"); + "co-simulation requires role, endpoint, dt, input and output " + "mappings" + ); } if (contingency && options.role != "client") { throw std::invalid_argument( - "ContingencyAnalysis requires the co-simulation client role. this " - "is a temporary limitation"); + "ContingencyAnalysis requires the co-simulation client role. this " + "is a temporary limitation" + ); } if (options.serve && options.role != "server") { @@ -204,7 +216,8 @@ namespace GridKit if (!ids.insert(id).second) { throw std::invalid_argument( - std::format("signal ID mapped more than once: {}", id)); + std::format("signal ID mapped more than once: {}", id) + ); } } } diff --git a/application/PhasorDynamics/SimulationRunner.hpp b/application/PhasorDynamics/SimulationRunner.hpp index 6d499c40a5..100200b5a3 100644 --- a/application/PhasorDynamics/SimulationRunner.hpp +++ b/application/PhasorDynamics/SimulationRunner.hpp @@ -21,7 +21,7 @@ namespace GridKit using SimulationSystem = SystemModel; using SimulationSolver = - AnalysisManager::Sundials::Ida; + AnalysisManager::Sundials::Ida; using Signals = std::map; using SignalBindings = std::map; @@ -41,7 +41,8 @@ namespace GridKit || !std::isfinite(data.dt_monitor) || data.dt_monitor < 0.0) { throw std::invalid_argument( - "Study requires a positive tmax and a nonnegative monitor interval"); + "Study requires a positive tmax and a nonnegative monitor interval" + ); } double previous = 0.0; @@ -51,7 +52,8 @@ namespace GridKit || event.time > data.tmax) { throw std::invalid_argument( - "Events must be ordered and within the simulation interval"); + "Events must be ordered and within the simulation interval" + ); } previous = event.time; @@ -86,15 +88,17 @@ namespace GridKit if (ret != 0) { throw std::runtime_error( - "Event failed at time " + std::to_string(event.time)); + "Event failed at time " + std::to_string(event.time) + ); } } /// Run a standalone study with event handling and monitoring. inline Testing::TestStatus runStandaloneStudy( - const StudyData& data, - bool consistent_initial = true, - bool print_results = true) + const StudyData& data, + bool consistent_initial = true, + bool print_results = true + ) { validateStudy(data); SimulationSystem sys(data.model_data); @@ -116,7 +120,7 @@ namespace GridKit inline bool sameTime(double a, double b) { return std::abs(a - b) <= 32.0 * std::numeric_limits::epsilon() - * std::max({1.0, std::abs(a), std::abs(b)}); + * std::max({1.0, std::abs(a), std::abs(b)}); } inline void suffixOutputs(StudyData& data, const std::string& suffix) @@ -177,10 +181,11 @@ namespace GridKit public: CoupledSimulation( - const StudyData& data, - const SignalBindings& inputs, - const SignalBindings& outputs, - const Signals* initial_inputs = nullptr) + const StudyData& data, + const SignalBindings& inputs, + const SignalBindings& outputs, + const Signals* initial_inputs = nullptr + ) : data_(data), outputs_(outputs), sys_(data.model_data) { validateStudy(data); @@ -188,8 +193,9 @@ namespace GridKit != AnalysisManager::Sundials::IdaConsistentICType::YA_YDP) { throw std::invalid_argument( - "co-simulation requires consistent_ic_type=ya_ydp to preserve " - "differential states during interface solves"); + "co-simulation requires consistent_ic_type=ya_ydp to preserve " + "differential states during interface solves" + ); } for (const auto& [name, id] : inputs) @@ -198,7 +204,8 @@ namespace GridKit if (signal->assigned() || signal->linked()) { throw std::invalid_argument( - "co-simulation input has a model-owned source: " + name); + "co-simulation input has a model-owned source: " + name + ); } auto& input = inputs_[name]; @@ -212,7 +219,7 @@ namespace GridKit if (found != bus.signal_inputs.end() && found->second == id) { input.value = - component == BusSignalInputs::vr ? bus.Vr0 : bus.Vi0; + component == BusSignalInputs::vr ? bus.Vr0 : bus.Vi0; } } } @@ -229,7 +236,8 @@ namespace GridKit if (!sys_.getSignalNode(id)->linked()) { throw std::invalid_argument( - "co-simulation output has no source: " + name); + "co-simulation output has no source: " + name + ); } } ida_ = std::make_unique(&sys_); @@ -241,7 +249,8 @@ namespace GridKit if (signals.size() != inputs_.size()) { throw std::invalid_argument( - "peer signal names do not match the configured inputs"); + "peer signal names do not match the configured inputs" + ); } for (auto& [name, input] : inputs_) @@ -251,7 +260,8 @@ namespace GridKit if (found == signals.end() || !std::isfinite(found->second)) { throw std::invalid_argument( - "missing or non-finite input signal: " + name); + "missing or non-finite input signal: " + name + ); } input.value = found->second; @@ -317,12 +327,12 @@ namespace GridKit } const double monitor_time = - data_.dt_monitor > 0.0 - ? static_cast(monitor_) * data_.dt_monitor - : data_.tmax; + data_.dt_monitor > 0.0 + ? static_cast(monitor_) * data_.dt_monitor + : data_.tmax; next = std::min(next, monitor_time); const bool print = - sameTime(next, monitor_time) || sameTime(next, data_.tmax); + sameTime(next, monitor_time) || sameTime(next, data_.tmax); const bool at_target = sameTime(next, target); ida_->runSimulationStep(next, 0.0, 1, 1, {}, print && !at_target); pending_monitor_ = print && at_target; diff --git a/examples/Experimental/DynamicConstrainedOpt/DynamicConstrainedOpt.cpp b/examples/Experimental/DynamicConstrainedOpt/DynamicConstrainedOpt.cpp index ccddecf0fc..6abdda4b6b 100644 --- a/examples/Experimental/DynamicConstrainedOpt/DynamicConstrainedOpt.cpp +++ b/examples/Experimental/DynamicConstrainedOpt/DynamicConstrainedOpt.cpp @@ -92,7 +92,9 @@ int main() // Create dynamic objective interface to Ipopt solver Ipopt::SmartPtr ipoptDynamicObjectiveInterface = - new IpoptInterface::DynamicObjective(&idas, t_init, t_final, dt_monitor); + new IpoptInterface::DynamicObjective( + &idas, t_init, t_final, dt_monitor + ); auto* param = model.param().getData(); @@ -123,7 +125,9 @@ int main() // Create dynamic constraint interface to Ipopt solver Ipopt::SmartPtr ipoptDynamicConstraintInterface = - new IpoptInterface::DynamicConstraint(&idas, t_init, t_final, dt_monitor); + new IpoptInterface::DynamicConstraint( + &idas, t_init, t_final, dt_monitor + ); // Initialize problem param[0] = Pm; diff --git a/examples/Experimental/GenConstLoad/GenConstLoad.cpp b/examples/Experimental/GenConstLoad/GenConstLoad.cpp index f7d58e11e7..7ea3d57443 100644 --- a/examples/Experimental/GenConstLoad/GenConstLoad.cpp +++ b/examples/Experimental/GenConstLoad/GenConstLoad.cpp @@ -86,7 +86,9 @@ int main() // Create interface to Ipopt solver Ipopt::SmartPtr ipoptDynamicObjectiveInterface = - new IpoptInterface::DynamicObjective(idas, t_init, t_final, dt_monitor); + new IpoptInterface::DynamicObjective( + idas, t_init, t_final, dt_monitor + ); auto* param = model->param().getData(); @@ -114,7 +116,7 @@ int main() // Compare results of the two optimization methods int retval = - isEqual(ipoptApp->Statistics()->FinalObjective(), 1239.0, 10 * tol) ? 0 : 1; + isEqual(ipoptApp->Statistics()->FinalObjective(), 1239.0, 10 * tol) ? 0 : 1; if (retval != 0) { diff --git a/examples/Experimental/GenInfiniteBus/GenInfiniteBus.cpp b/examples/Experimental/GenInfiniteBus/GenInfiniteBus.cpp index 38e42154f1..0caeef5d28 100644 --- a/examples/Experimental/GenInfiniteBus/GenInfiniteBus.cpp +++ b/examples/Experimental/GenInfiniteBus/GenInfiniteBus.cpp @@ -98,7 +98,9 @@ int main() // Create dynamic objective interface to Ipopt solver Ipopt::SmartPtr ipoptDynamicObjectiveInterface = - new IpoptInterface::DynamicObjective(&idas, t_init, t_final, dt_monitor); + new IpoptInterface::DynamicObjective( + &idas, t_init, t_final, dt_monitor + ); auto* param = model.param().getData(); @@ -124,7 +126,9 @@ int main() // Create dynamic constraint interface to Ipopt solver Ipopt::SmartPtr ipoptDynamicConstraintInterface = - new IpoptInterface::DynamicConstraint(&idas, t_init, t_final, dt_monitor); + new IpoptInterface::DynamicConstraint( + &idas, t_init, t_final, dt_monitor + ); // Store dynamic objective optimization results double* results = new double[model.sizeParams()]; diff --git a/examples/Experimental/ParameterEstimation/ParameterEstimation.cpp b/examples/Experimental/ParameterEstimation/ParameterEstimation.cpp index 86d158e5e0..b7b2ca2fb7 100644 --- a/examples/Experimental/ParameterEstimation/ParameterEstimation.cpp +++ b/examples/Experimental/ParameterEstimation/ParameterEstimation.cpp @@ -107,7 +107,9 @@ int main() // Create dynamic objective interface to Ipopt solver Ipopt::SmartPtr ipoptDynamicObjectiveInterface = - new IpoptInterface::DynamicObjective(&idas, t_init, t_final, dt_monitor); + new IpoptInterface::DynamicObjective( + &idas, t_init, t_final, dt_monitor + ); // Solve the problem status = ipoptApp->OptimizeTNLP(ipoptDynamicObjectiveInterface); @@ -135,7 +137,9 @@ int main() // Create dynamic constraint interface to Ipopt solver Ipopt::SmartPtr ipoptDynamicConstraintInterface = - new IpoptInterface::DynamicConstraint(&idas, t_init, t_final, dt_monitor); + new IpoptInterface::DynamicConstraint( + &idas, t_init, t_final, dt_monitor + ); // Solve the problem status = ipoptApp->OptimizeTNLP(ipoptDynamicConstraintInterface); diff --git a/examples/Experimental/ParameterEstimation/lookup_table.hpp b/examples/Experimental/ParameterEstimation/lookup_table.hpp index 735f1db180..f80332068f 100644 --- a/examples/Experimental/ParameterEstimation/lookup_table.hpp +++ b/examples/Experimental/ParameterEstimation/lookup_table.hpp @@ -1,5 +1,5 @@ std::string lookup_table = - R"( 0 0.092182 0.99596 -0.17574 0.98107 2.7864 0.58172 -1.5217 0.092914 0.4666 -0.18534 -0.49105 -1.3472 + R"( 0 0.092182 0.99596 -0.17574 0.98107 2.7864 0.58172 -1.5217 0.092914 0.4666 -0.18534 -0.49105 -1.3472 0.05 0.032044 0.99785 -0.15175 0.98425 -0.058476 0.52344 -0.80946 0.048601 0.41347 0.063192 0.20608 -3.487 0.1 0.016599 1.0006 -0.1331 0.98738 -0.047843 0.42635 0.22214 0.058264 0.34627 0.061871 0.19728 -0.34913 0.15 0.05483 1.0034 -0.11578 0.99044 -0.036909 0.48633 1.2885 0.052391 0.35895 0.060531 0.29873 2.6589 diff --git a/examples/OptimalPowerFlow/EconomicDispatch/EconomicDispatch.cpp b/examples/OptimalPowerFlow/EconomicDispatch/EconomicDispatch.cpp index 433e5866cb..8ef669f44d 100644 --- a/examples/OptimalPowerFlow/EconomicDispatch/EconomicDispatch.cpp +++ b/examples/OptimalPowerFlow/EconomicDispatch/EconomicDispatch.cpp @@ -24,16 +24,20 @@ int runApplication(int argc, const char* argv[]) { Log::raiseVerbosity(Log::SUMMARY); - CliArgs args{{.name = {"--case-file", "-c"}, .help = "JSON case file", .required = true}, - {.name = {"--reference-cost", "-r"}, .help = "Optimal cost to check [$/h]", .type = ArgType::Real}, - {.name = {"--solver-tolerance"}, - .help = "Ipopt convergence tolerance", - .type = ArgType::Real, - .defaults = 1.0e-6}, - {.name = {"--tolerance", "-t"}, - .help = "Relative tolerance of the cost check", - .type = ArgType::Real, - .defaults = 1.0e-6}}; + CliArgs args{ + {.name = {"--case-file", "-c"}, .help = "JSON case file", .required = true}, + {.name = {"--reference-cost", "-r"}, + .help = "Optimal cost to check [$/h]", + .type = ArgType::Real}, + {.name = {"--solver-tolerance"}, + .help = "Ipopt convergence tolerance", + .type = ArgType::Real, + .defaults = 1.0e-6}, + {.name = {"--tolerance", "-t"}, + .help = "Relative tolerance of the cost check", + .type = ArgType::Real, + .defaults = 1.0e-6} + }; args.parseArgs(argc, argv); OPF::SystemModel model(OPF::parseSystemModelData(args["case-file"]())); diff --git a/examples/PowerElectronics/DistributedGeneratorTest/DGTest.cpp b/examples/PowerElectronics/DistributedGeneratorTest/DGTest.cpp index 7ee73f9de9..6fbcaf9a48 100644 --- a/examples/PowerElectronics/DistributedGeneratorTest/DGTest.cpp +++ b/examples/PowerElectronics/DistributedGeneratorTest/DGTest.cpp @@ -50,22 +50,22 @@ int main(int /* argc */, char const** /* argv */) std::vector t1(16, 0.0); std::vector t2{ - 0.0, - 0.1, - 0.2, - 0.4, - 0.5, - 0.6, - 0.7, - 0.8, - 0.9, - 1.0, - 1.1, - 1.2, - 1.3, - 1.4, - 1.5, - 0.3, + 0.0, + 0.1, + 0.2, + 0.4, + 0.5, + 0.6, + 0.7, + 0.8, + 0.9, + 1.0, + 1.1, + 1.2, + 1.3, + 1.4, + 1.5, + 0.3, }; std::vector res(16, 0.0); @@ -80,31 +80,31 @@ int main(int /* argc */, char const** /* argv */) for (size_t idx : dg.getExternIndices()) { GridKit::PowerElectronics::ExternalConnection connection{ - .y_ = &t2[idx], - .yp_ = &t1[idx], - .f_ = &res[idx], - .idx_ = idx}; + .y_ = &t2[idx], .yp_ = &t1[idx], .f_ = &res[idx], .idx_ = idx + }; dg.setExternalConnectionNodes(idx, connection); } dg.evaluateResidual(); // Generated from matlab code with same parameters and inputs - std::vector true_vec{0, - 8.941907747838389e-01, - 1.846733023014284e+00, - 1.014543000000000e+02, - -1.507680000000000e+01, - 3.787993500000000e+02, - -1.300000000000000e+00, - 2.899095146477517e+02, - 2.939138495559215e+02, - 1.507210571826699e+07, - 1.659799832843673e+07, - -7.591593003913325e+03, - -8.376991073310774e+03, - 3.337988298081817e+03, - 2.684419146397466e+03}; + std::vector true_vec{ + 0, + 8.941907747838389e-01, + 1.846733023014284e+00, + 1.014543000000000e+02, + -1.507680000000000e+01, + 3.787993500000000e+02, + -1.300000000000000e+00, + 2.899095146477517e+02, + 2.939138495559215e+02, + 1.507210571826699e+07, + 1.659799832843673e+07, + -7.591593003913325e+03, + -8.376991073310774e+03, + 3.337988298081817e+03, + 2.684419146397466e+03 + }; std::cout << "Testing the DistributedGenerator model ...\n"; double error_allowed = 10 * std::numeric_limits::epsilon(); diff --git a/examples/PowerElectronics/ExamplesHelper/MicrogridNetwork.hpp b/examples/PowerElectronics/ExamplesHelper/MicrogridNetwork.hpp index efe9f99e23..6d840d0721 100644 --- a/examples/PowerElectronics/ExamplesHelper/MicrogridNetwork.hpp +++ b/examples/PowerElectronics/ExamplesHelper/MicrogridNetwork.hpp @@ -168,22 +168,18 @@ struct ScaleMicrogridNetwork } // Create the reference generator - auto* dg_ref = new DGGenerator(model_id_next++, - DGParam_list[0], - true, - &dg_signal, - &buses[0]); + auto* dg_ref = new DGGenerator( + model_id_next++, DGParam_list[0], true, &dg_signal, &buses[0] + ); generators[0] = dg_ref; // Create the remaining generators. for (IdxT i = 1; i < 2 * N_size; i++) { - auto* dg = new DGGenerator(model_id_next++, - DGParam_list[i], - false, - &dg_signal, - &buses[i]); + auto* dg = new DGGenerator( + model_id_next++, DGParam_list[i], false, &dg_signal, &buses[i] + ); generators[i] = dg; } @@ -191,12 +187,14 @@ struct ScaleMicrogridNetwork // Create transmission lines between consecutive buses. for (IdxT i = 0; i < 2 * N_size - 1; i++) { - auto* line_model = new Line(model_id_next++, - rline_list[i], - Lline_list[i], - &dg_signal, - &buses[i], - &buses[i + 1]); + auto* line_model = new Line( + model_id_next++, + rline_list[i], + Lline_list[i], + &dg_signal, + &buses[i], + &buses[i + 1] + ); lines[i] = line_model; } @@ -204,11 +202,9 @@ struct ScaleMicrogridNetwork // Create loads on every other bus. for (IdxT i = 0; i < N_size; i++) { - auto* load_model = new Load(model_id_next++, - rload_list[i], - Lload_list[i], - &dg_signal, - &buses[2 * i]); + auto* load_model = new Load( + model_id_next++, rload_list[i], Lload_list[i], &dg_signal, &buses[2 * i] + ); loads[2 * i] = load_model; } @@ -216,9 +212,7 @@ struct ScaleMicrogridNetwork // Create and Add all the microgrid Virtual DQ Buses for (IdxT i = 0; i < 2 * N_size; i++) { - auto* virDQbus_model = new BusDQ(model_id_next++, - RN, - &buses[i]); + auto* virDQbus_model = new BusDQ(model_id_next++, RN, &buses[i]); busesDQ[i] = virDQbus_model; } diff --git a/examples/PowerElectronics/ExamplesHelper/SystemAssembler.hpp b/examples/PowerElectronics/ExamplesHelper/SystemAssembler.hpp index e46400a562..8c84da41ff 100644 --- a/examples/PowerElectronics/ExamplesHelper/SystemAssembler.hpp +++ b/examples/PowerElectronics/ExamplesHelper/SystemAssembler.hpp @@ -32,8 +32,10 @@ * does not call GridKit::PowerElectronics::SystemModel::allocate(). */ template -void assembleSystem(ScaleMicrogridNetwork& network, - GridKit::PowerElectronics::SystemModel& sys_model) +void assembleSystem( + ScaleMicrogridNetwork& network, + GridKit::PowerElectronics::SystemModel& sys_model +) { size_t N_size = network.N_size; diff --git a/examples/PowerElectronics/Microgrid/Microgrid.cpp b/examples/PowerElectronics/Microgrid/Microgrid.cpp index 37de3267e7..2963893dc7 100644 --- a/examples/PowerElectronics/Microgrid/Microgrid.cpp +++ b/examples/PowerElectronics/Microgrid/Microgrid.cpp @@ -148,76 +148,31 @@ int main(int /* argc */, char const** /* argv */) // Generated from MATLAB code ODE form with tolerances of 1e-12 std::vector true_vec{ - 2.297543153595780e+04, - 1.275311524125022e+04, - 3.763060183116022e-02, - -2.098153459325261e-02, - 1.848285659119097e-02, - -1.563291404944864e-04, - 6.321941907011718e+01, - -2.942264300846256e+01, - 3.634209302905854e+02, - -2.668928293656362e-06, - 6.321941919221522e+01, - -3.509200178595996e+01, - 2.297580486511343e+04, - 8.742028429066131e+03, - 3.710079564796484e-02, - -1.421122598056797e-02, - 1.874079517807597e-02, - -9.891304812687215e-05, - 6.232933298360234e+01, - -1.796494061423331e+01, - 3.686353885026506e+02, - 3.465673854181523e-05, - 6.232933406188410e+01, - -2.371564475187742e+01, - -7.555954467454730e-03, - 1.727775042678524e+04, - 1.649365247247288e+04, - 3.116555157570849e-02, - -2.985990066758010e-02, - 2.250012115906506e-02, - -2.643873146501096e-04, - 4.861823510250247e+01, - -4.088592755441309e+01, - 3.552597163751238e+02, - -1.496407194199739e-04, - 4.861823504694532e+01, - -4.642797132602495e+01, - -8.273939686941580e-02, - 1.727723725566433e+04, - 9.182386962936238e+03, - 3.024959333190777e-02, - -1.617250828202081e-02, - 2.318056864131751e-02, - -1.295918667730514e-04, - 4.718938244522050e+01, - -1.935782085675469e+01, - 3.662262287803608e+02, - 1.076423957830039e-04, - 4.718938116520511e+01, - -2.507094256286497e+01, - -8.445727984408551e-02, - -1.881248349415025e+01, - 2.114714832305742e+01, - 4.329946674909793e+01, - -3.037887936225145e+00, - -4.487023117352992e+01, - 2.895883729832657e+01, - 8.199613345691378e+01, - -5.623856502948122e+01, - 1.327498499660322e+02, - -8.228065162347022e+01, - 3.119995747945993e+02, - 3.576922945168803e+02, - -5.850795361581618e+00, - 3.641193316268954e+02, - -8.846325267612976e+00, - 3.472146752739036e+02, - -3.272400970143252e+01, - 3.604108939430972e+02, - -3.492842627398574e+01}; + 2.297543153595780e+04, 1.275311524125022e+04, 3.763060183116022e-02, + -2.098153459325261e-02, 1.848285659119097e-02, -1.563291404944864e-04, + 6.321941907011718e+01, -2.942264300846256e+01, 3.634209302905854e+02, + -2.668928293656362e-06, 6.321941919221522e+01, -3.509200178595996e+01, + 2.297580486511343e+04, 8.742028429066131e+03, 3.710079564796484e-02, + -1.421122598056797e-02, 1.874079517807597e-02, -9.891304812687215e-05, + 6.232933298360234e+01, -1.796494061423331e+01, 3.686353885026506e+02, + 3.465673854181523e-05, 6.232933406188410e+01, -2.371564475187742e+01, + -7.555954467454730e-03, 1.727775042678524e+04, 1.649365247247288e+04, + 3.116555157570849e-02, -2.985990066758010e-02, 2.250012115906506e-02, + -2.643873146501096e-04, 4.861823510250247e+01, -4.088592755441309e+01, + 3.552597163751238e+02, -1.496407194199739e-04, 4.861823504694532e+01, + -4.642797132602495e+01, -8.273939686941580e-02, 1.727723725566433e+04, + 9.182386962936238e+03, 3.024959333190777e-02, -1.617250828202081e-02, + 2.318056864131751e-02, -1.295918667730514e-04, 4.718938244522050e+01, + -1.935782085675469e+01, 3.662262287803608e+02, 1.076423957830039e-04, + 4.718938116520511e+01, -2.507094256286497e+01, -8.445727984408551e-02, + -1.881248349415025e+01, 2.114714832305742e+01, 4.329946674909793e+01, + -3.037887936225145e+00, -4.487023117352992e+01, 2.895883729832657e+01, + 8.199613345691378e+01, -5.623856502948122e+01, 1.327498499660322e+02, + -8.228065162347022e+01, 3.119995747945993e+02, 3.576922945168803e+02, + -5.850795361581618e+00, 3.641193316268954e+02, -8.846325267612976e+00, + 3.472146752739036e+02, -3.272400970143252e+01, 3.604108939430972e+02, + -3.492842627398574e+01 + }; std::cout << "Testing Microgrid ...\n"; double error_allowed = 1e-4; diff --git a/examples/PowerElectronics/ScaleMicrogrid/SolutionKeys.hpp b/examples/PowerElectronics/ScaleMicrogrid/SolutionKeys.hpp index 03c7e2b73a..5296fe9710 100644 --- a/examples/PowerElectronics/ScaleMicrogrid/SolutionKeys.hpp +++ b/examples/PowerElectronics/ScaleMicrogrid/SolutionKeys.hpp @@ -31,505 +31,178 @@ constexpr real_type SCALE_MICROGRID_ABS_TOL = 1.0e-8; constexpr index_type SCALE_MICROGRID_MAX_STEPS = 10000; const std::vector answer_key_N2 = { - 22975.4182636905, - 12753.1173017451, - 0.0376305671131306, - -0.0209815421114537, - 0.0184828563235406, - -0.00015632917065729, - 63.2193617412383, - -29.4226556659582, - 363.420924977355, - -3.01001804456668e-06, - 63.2193618667302, - -35.0920143829141, - 22975.8457840701, - 8742.0172166684, - 0.0371009878165673, - -0.0142112776774797, - 0.0187407972932474, - -9.8913852531819e-05, - 62.3296548917654, - -17.9650261562766, - 368.635407345931, - 3.79041261513032e-05, - 62.3296560841534, - -23.7157298601546, - -0.00755583999797958, - 17277.712521392, - 16493.7578328327, - 0.0311645357391787, - -0.0298601153771274, - 0.0225001003469904, - -0.000264388302121386, - 48.6166482764357, - -40.8862612232969, - 355.25957014696, - -0.000167008045114112, - 48.6166481095298, - -46.4283022775928, - -0.0827401584095097, - 17277.2493364959, - 9182.29479881977, - 0.0302503981389185, - -0.0161722538457184, - 0.023180586071601, - -0.000129590157483103, - 47.1906392248137, - -19.3574255862892, - 366.226354188735, - 0.000121054462396047, - 47.19063792117, - -25.0705499054599, - -0.0844566209033113, - -18.8125403122072, - 21.1471334522508, - 43.2997340692497, - -3.03798323340816, - -44.8715356440453, - 28.9585224749495, - 81.99613295014, - -56.2385627562355, - 132.749774614687, - -82.280664729262, - 311.999576042192, - 357.692287974629, - -5.85078929333349, - 364.119335219897, - -8.84631033126304, - 347.214535767435, - -32.7241067379802, - 360.411028950125, - -34.9283280833745}; + 22975.4182636905, 12753.1173017451, 0.0376305671131306, + -0.0209815421114537, 0.0184828563235406, -0.00015632917065729, + 63.2193617412383, -29.4226556659582, 363.420924977355, + -3.01001804456668e-06, 63.2193618667302, -35.0920143829141, + 22975.8457840701, 8742.0172166684, 0.0371009878165673, + -0.0142112776774797, 0.0187407972932474, -9.8913852531819e-05, + 62.3296548917654, -17.9650261562766, 368.635407345931, + 3.79041261513032e-05, 62.3296560841534, -23.7157298601546, + -0.00755583999797958, 17277.712521392, 16493.7578328327, + 0.0311645357391787, -0.0298601153771274, 0.0225001003469904, + -0.000264388302121386, 48.6166482764357, -40.8862612232969, + 355.25957014696, -0.000167008045114112, 48.6166481095298, + -46.4283022775928, -0.0827401584095097, 17277.2493364959, + 9182.29479881977, 0.0302503981389185, -0.0161722538457184, + 0.023180586071601, -0.000129590157483103, 47.1906392248137, + -19.3574255862892, 366.226354188735, 0.000121054462396047, + 47.19063792117, -25.0705499054599, -0.0844566209033113, + -18.8125403122072, 21.1471334522508, 43.2997340692497, + -3.03798323340816, -44.8715356440453, 28.9585224749495, + 81.99613295014, -56.2385627562355, 132.749774614687, + -82.280664729262, 311.999576042192, 357.692287974629, + -5.85078929333349, 364.119335219897, -8.84631033126304, + 347.214535767435, -32.7241067379802, 360.411028950125, + -34.9283280833745 +}; const std::vector answer_key_N4 = { - 27828.3291148094, - 10602.3611530864, - 0.0452452394028709, - -0.0173410584955486, - 0.018686818367312, - -0.000129595027000909, - 76.0120809944985, - -23.2367034227098, - 366.216582730654, - -0.000167782960864797, - 76.0120710728117, - -28.9413214479885, - 27832.0772154743, - 7838.80352597054, - 0.0448129806183038, - -0.0127296381144373, - 0.0188642014642206, - -9.04502393904097e-05, - 75.2859236720964, - -15.4316980534341, - 369.809174828127, - -5.17440472732025e-05, - 75.285919083362, - -21.1922719962368, - -0.0154989336357971, - 20950.1519748442, - 16334.3924580166, - 0.0377787488551238, - -0.0295717781600636, - 0.0225780601074885, - -0.000265567743682681, - 58.9348270364006, - -40.4081583028089, - 355.498460539903, - -8.66167274613643e-05, - 58.9348242715342, - -45.9457664944992, - -0.142596248886844, - 20956.2846481359, - 12345.7855779785, - 0.0371673110634281, - -0.0220171188824754, - 0.0229486760225139, - -0.000191111142238558, - 57.9810673844105, - -28.5265491599081, - 361.481100853144, - 8.24481547667206e-05, - 57.9810719040216, - -34.1573355283559, - -0.164628885385433, - 20978.9206932923, - 17875.6825958711, - 0.0380785081131898, - -0.0325621468970297, - 0.0224354615928625, - -0.000295085318936756, - 59.4025243779293, - -45.1101946009202, - 353.186117339098, - 5.52721744209165e-05, - 59.4025238741703, - -50.6117204294148, - -0.245126576498858, - 20990.6142554844, - 11779.5685373245, - 0.0371243965775962, - -0.0209716906203726, - 0.0230016494389548, - -0.000180846578022512, - 57.9140614794815, - -26.8817831662193, - 362.331254349606, - 0.000209247259473183, - 57.9140782926947, - -32.5257339504705, - -0.253672269778405, - 21004.5418902462, - 16686.981801999, - 0.0379131316203435, - -0.0302602142538338, - 0.0225460339603269, - -0.000272422675391038, - 59.1444740212228, - -41.4902940591195, - 354.969993387113, - 8.14114753778542e-05, - 59.1444846638236, - -47.0195494892644, - -0.288747285297145, - 21005.895228757, - 8274.13913126834, - 0.0366267978764156, - -0.0145584209340773, - 0.0233276948336748, - -0.000117627382397687, - 57.1378568500881, - -16.7923279871216, - 367.58883605301, - 0.000263351556352378, - 57.1378679159653, - -22.518140603782, - -0.285876486857154, - -6.57009481597077, - 28.1053117219546, - 68.341829672125, - 5.75010361666728, - -7.27398138223966, - 42.3413009908014, - 44.2901915856089, - -0.850144510998897, - -26.9214526328474, - 37.7939474726438, - 20.9421230166698, - -8.2155394685309, - -48.4341275019927, - 37.706248875936, - 82.5460878639016, - -57.0458911301263, - 127.388509162578, - -90.4406093871607, - 116.522583626035, - -102.149734009655, - 112.650118587972, - -107.825883544914, - 311.543402422187, - 360.780248808368, - -7.42039816792328, - 365.078323407317, - -13.2331839185884, - 344.46378568747, - -54.5546252592288, - 350.335287885457, - -63.572021962256, - 334.342198258035, - -88.749585714325, - 344.281369936645, - -94.7726681838823, - 332.2248206198, - -103.942854393111, - 347.103721199815, - -107.812479611979}; + 27828.3291148094, 10602.3611530864, 0.0452452394028709, + -0.0173410584955486, 0.018686818367312, -0.000129595027000909, + 76.0120809944985, -23.2367034227098, 366.216582730654, + -0.000167782960864797, 76.0120710728117, -28.9413214479885, + 27832.0772154743, 7838.80352597054, 0.0448129806183038, + -0.0127296381144373, 0.0188642014642206, -9.04502393904097e-05, + 75.2859236720964, -15.4316980534341, 369.809174828127, + -5.17440472732025e-05, 75.285919083362, -21.1922719962368, + -0.0154989336357971, 20950.1519748442, 16334.3924580166, + 0.0377787488551238, -0.0295717781600636, 0.0225780601074885, + -0.000265567743682681, 58.9348270364006, -40.4081583028089, + 355.498460539903, -8.66167274613643e-05, 58.9348242715342, + -45.9457664944992, -0.142596248886844, 20956.2846481359, + 12345.7855779785, 0.0371673110634281, -0.0220171188824754, + 0.0229486760225139, -0.000191111142238558, 57.9810673844105, + -28.5265491599081, 361.481100853144, 8.24481547667206e-05, + 57.9810719040216, -34.1573355283559, -0.164628885385433, + 20978.9206932923, 17875.6825958711, 0.0380785081131898, + -0.0325621468970297, 0.0224354615928625, -0.000295085318936756, + 59.4025243779293, -45.1101946009202, 353.186117339098, + 5.52721744209165e-05, 59.4025238741703, -50.6117204294148, + -0.245126576498858, 20990.6142554844, 11779.5685373245, + 0.0371243965775962, -0.0209716906203726, 0.0230016494389548, + -0.000180846578022512, 57.9140614794815, -26.8817831662193, + 362.331254349606, 0.000209247259473183, 57.9140782926947, + -32.5257339504705, -0.253672269778405, 21004.5418902462, + 16686.981801999, 0.0379131316203435, -0.0302602142538338, + 0.0225460339603269, -0.000272422675391038, 59.1444740212228, + -41.4902940591195, 354.969993387113, 8.14114753778542e-05, + 59.1444846638236, -47.0195494892644, -0.288747285297145, + 21005.895228757, 8274.13913126834, 0.0366267978764156, + -0.0145584209340773, 0.0233276948336748, -0.000117627382397687, + 57.1378568500881, -16.7923279871216, 367.58883605301, + 0.000263351556352378, 57.1378679159653, -22.518140603782, + -0.285876486857154, -6.57009481597077, 28.1053117219546, + 68.341829672125, 5.75010361666728, -7.27398138223966, + 42.3413009908014, 44.2901915856089, -0.850144510998897, + -26.9214526328474, 37.7939474726438, 20.9421230166698, + -8.2155394685309, -48.4341275019927, 37.706248875936, + 82.5460878639016, -57.0458911301263, 127.388509162578, + -90.4406093871607, 116.522583626035, -102.149734009655, + 112.650118587972, -107.825883544914, 311.543402422187, + 360.780248808368, -7.42039816792328, 365.078323407317, + -13.2331839185884, 344.46378568747, -54.5546252592288, + 350.335287885457, -63.572021962256, 334.342198258035, + -88.749585714325, 344.281369936645, -94.7726681838823, + 332.2248206198, -103.942854393111, 347.103721199815, + -107.812479611979 +}; const std::vector answer_key_N8 = { - 29266.6517718661, - 9842.93617289812, - 0.0475360674334622, - -0.0160323945316821, - 0.0187557247105805, - -0.000119821248231538, - 79.8612117213119, - -21.0144010498971, - 367.201497494684, - -0.00135963018489767, - 79.8611351716573, - -26.7318789917162, - 29296.9645459408, - 7415.51099954903, - 0.0471789367393934, - -0.0120180219897291, - 0.0189117902285582, - -8.57914733703415e-05, - 79.2614266664798, - -14.2194852461262, - 370.357116139458, - -0.00065261697325357, - 79.261388452934, - -19.9860446882469, - -0.018074876389402, - 22178.7337755581, - 15750.48869542, - 0.0399575496599213, - -0.028431003000158, - 0.0226540351215628, - -0.000255811047442045, - 62.3338080750298, - -38.6061338491152, - 356.372404460464, - -0.000888421043595241, - 62.3337589017493, - -44.1546192236143, - -0.161178046356866, - 22245.3587939821, - 12476.0312983393, - 0.0395296431152022, - -0.0222832972915751, - 0.0229591349358969, - -0.000195357283522886, - 61.6667253463805, - -28.9363062720176, - 361.284131747149, - 0.000606091049765824, - 61.6667589580497, - -34.5611135316627, - -0.191206982234175, - 22471.354929649, - 17410.9400696732, - 0.0407475331761201, - -0.0316496339533813, - 0.0225047347006168, - -0.000287941144857336, - 63.5662158978541, - -43.6654709736205, - 353.882194971394, - -0.00050508442766251, - 63.5661867600733, - -49.1745383652835, - -0.300475535038271, - 22562.1063953332, - 12532.040739496, - 0.0400730650460856, - -0.0224103188019356, - 0.0229590093469276, - -0.000197040279593967, - 62.5145400797163, - -29.1337602252211, - 361.200953962968, - 0.00123813270414561, - 62.5146115608051, - -34.7565572443792, - -0.321406735230742, - 22822.9625175864, - 17526.9123376124, - 0.0413769691613727, - -0.0318846988884131, - 0.0224996948233429, - -0.000290724959665147, - 64.5480523645119, - -44.0326735095454, - 353.709220392926, - -0.000255137918253834, - 64.548036917491, - -49.5382706457328, - -0.398765881347133, - 22917.4640781459, - 11700.1980576741, - 0.0405370737861658, - -0.0208717910251266, - 0.0230419643488667, - -0.000182321342412399, - 63.2383663569188, - -26.7111380754575, - 362.449323338104, - 0.00143605100750772, - 63.2384503029344, - -32.3525635247183, - -0.409294621792759, - 23175.0870418607, - 17429.0372806116, - 0.0419717095772374, - -0.0317010913432995, - 0.0225145433123769, - -0.000289381352876061, - 65.4757968347883, - -43.7415548084125, - 353.856643943042, - -0.000116590766441278, - 65.4757901489451, - -49.2486679790579, - -0.460038982115987, - 23264.6732405303, - 10919.0360806903, - 0.0409947737541995, - -0.0194331296392293, - 0.0231200668519233, - -0.000168575863901554, - 63.9522672718067, - -24.4455560147541, - 363.621937642842, - 0.00154556746783549, - 63.9523565934322, - -30.1044436917781, - -0.461848591689221, - 23488.6137650364, - 17313.8654584652, - 0.0424952351974662, - -0.0314883547842804, - 0.0225303364455447, - -0.000287714847080755, - 66.2924442955506, - -43.4048501801219, - 354.030311475628, - 0.000169934086992562, - 66.2924545883603, - -48.9139721676174, - -0.491529580804623, - 23557.6136117665, - 10241.0790360359, - 0.0413774884672506, - -0.0181860120867723, - 0.0231877453638413, - -0.000156639599075328, - 64.5492156984859, - -22.4816084883194, - 364.639179755733, - 0.00142420279185394, - 64.5492984953198, - -28.1556597465189, - -0.486548093474613, - 23722.4168131373, - 16958.7765974266, - 0.0428487548646152, - -0.0308090857078185, - 0.0225672437721518, - -0.000281355782039133, - 66.8440182379463, - -42.3350991467661, - 354.562942832682, - 0.000573219240561573, - 66.844044569212, - -47.8519918014414, - -0.499726325044563, - 23769.8747006891, - 9267.5206785042, - 0.0415639300026818, - -0.0164109903099032, - 0.0232814268213158, - -0.000139385907988285, - 64.8399200066663, - -19.6874999818575, - 366.100410278813, - 0.00128332197988872, - 64.8400012051758, - -25.3838027935624, - -0.490219448053285, - 23854.0240861864, - 15160.7060140903, - 0.0427385845553072, - -0.0273659210853948, - 0.0227360281885303, - -0.00024756822257102, - 66.6722121992594, - -36.9193366680176, - 357.260483774461, - 0.000734666517031364, - 66.6722602990682, - -42.4779079553274, - -0.491586583798841, - 23870.5548740189, - 6166.60742794455, - 0.0412253604361869, - -0.0108406830677542, - 0.0235710268609798, - -8.45378382385454e-05, - 64.3117067426907, - -10.9219886629635, - 370.751596332923, - 0.00130490570318174, - 64.3117765573399, - -16.6904284244068, - -0.482907936930927, - -2.9267653635869, - 30.5878043390112, - 75.9238910016987, - 9.17392754248112, - 4.3701560041079, - 48.7765765968327, - 58.3101300775815, - 3.13323809951331, - -6.37573932293514, - 46.1701408549949, - 41.9244199648313, - -6.5432868117422, - -17.3691293511209, - 41.8611610718482, - 27.7383173553277, - -12.9709065074016, - -27.5322418670623, - 38.9032728624808, - 16.2733736528389, - -16.5280348065045, - -36.4800564569504, - 37.0627808819117, - 7.38198504755967, - -17.9899033675727, - -44.0731708800056, - 36.9539474625741, - 1.14781892918688, - -15.9507601441003, - -49.1751072411967, - 44.6278268007059, - 82.7517114852138, - -57.3188928805757, - 125.959171148664, - -93.1822145893453, - 110.816672146529, - -108.811406393296, - 99.5107131550674, - -119.104827911048, - 92.0427992280762, - -125.056967118294, - 88.0811872722293, - -127.985464658329, - 87.1649116220972, - -128.957730829954, - 89.0189233593932, - -129.480383815729, - 311.408200092424, - 361.890500304156, - -7.90450151715305, - 365.594288034004, - -14.6504114199963, - 344.278948204657, - -61.517809887448, - 348.104769580715, - -73.1715704285651, - 329.472137794467, - -107.797643650827, - 335.509251816504, - -117.787067889008, - 317.044841017058, - -139.602945170765, - 325.182412285621, - -147.51178633583, - 307.989533967543, - -158.91998673915, - 318.171184823086, - -165.141414351062, - 302.951769665185, - -168.712626964975, - 315.009688292198, - -173.624287308414, - 302.070219389208, - -171.572667424371, - 315.86470341008, - -175.706947618597, - 306.288884765777, - -170.785573848562, - 322.018589824395, - -176.179397251772}; + 29266.6517718661, 9842.93617289812, 0.0475360674334622, + -0.0160323945316821, 0.0187557247105805, -0.000119821248231538, + 79.8612117213119, -21.0144010498971, 367.201497494684, + -0.00135963018489767, 79.8611351716573, -26.7318789917162, + 29296.9645459408, 7415.51099954903, 0.0471789367393934, + -0.0120180219897291, 0.0189117902285582, -8.57914733703415e-05, + 79.2614266664798, -14.2194852461262, 370.357116139458, + -0.00065261697325357, 79.261388452934, -19.9860446882469, + -0.018074876389402, 22178.7337755581, 15750.48869542, + 0.0399575496599213, -0.028431003000158, 0.0226540351215628, + -0.000255811047442045, 62.3338080750298, -38.6061338491152, + 356.372404460464, -0.000888421043595241, 62.3337589017493, + -44.1546192236143, -0.161178046356866, 22245.3587939821, + 12476.0312983393, 0.0395296431152022, -0.0222832972915751, + 0.0229591349358969, -0.000195357283522886, 61.6667253463805, + -28.9363062720176, 361.284131747149, 0.000606091049765824, + 61.6667589580497, -34.5611135316627, -0.191206982234175, + 22471.354929649, 17410.9400696732, 0.0407475331761201, + -0.0316496339533813, 0.0225047347006168, -0.000287941144857336, + 63.5662158978541, -43.6654709736205, 353.882194971394, + -0.00050508442766251, 63.5661867600733, -49.1745383652835, + -0.300475535038271, 22562.1063953332, 12532.040739496, + 0.0400730650460856, -0.0224103188019356, 0.0229590093469276, + -0.000197040279593967, 62.5145400797163, -29.1337602252211, + 361.200953962968, 0.00123813270414561, 62.5146115608051, + -34.7565572443792, -0.321406735230742, 22822.9625175864, + 17526.9123376124, 0.0413769691613727, -0.0318846988884131, + 0.0224996948233429, -0.000290724959665147, 64.5480523645119, + -44.0326735095454, 353.709220392926, -0.000255137918253834, + 64.548036917491, -49.5382706457328, -0.398765881347133, + 22917.4640781459, 11700.1980576741, 0.0405370737861658, + -0.0208717910251266, 0.0230419643488667, -0.000182321342412399, + 63.2383663569188, -26.7111380754575, 362.449323338104, + 0.00143605100750772, 63.2384503029344, -32.3525635247183, + -0.409294621792759, 23175.0870418607, 17429.0372806116, + 0.0419717095772374, -0.0317010913432995, 0.0225145433123769, + -0.000289381352876061, 65.4757968347883, -43.7415548084125, + 353.856643943042, -0.000116590766441278, 65.4757901489451, + -49.2486679790579, -0.460038982115987, 23264.6732405303, + 10919.0360806903, 0.0409947737541995, -0.0194331296392293, + 0.0231200668519233, -0.000168575863901554, 63.9522672718067, + -24.4455560147541, 363.621937642842, 0.00154556746783549, + 63.9523565934322, -30.1044436917781, -0.461848591689221, + 23488.6137650364, 17313.8654584652, 0.0424952351974662, + -0.0314883547842804, 0.0225303364455447, -0.000287714847080755, + 66.2924442955506, -43.4048501801219, 354.030311475628, + 0.000169934086992562, 66.2924545883603, -48.9139721676174, + -0.491529580804623, 23557.6136117665, 10241.0790360359, + 0.0413774884672506, -0.0181860120867723, 0.0231877453638413, + -0.000156639599075328, 64.5492156984859, -22.4816084883194, + 364.639179755733, 0.00142420279185394, 64.5492984953198, + -28.1556597465189, -0.486548093474613, 23722.4168131373, + 16958.7765974266, 0.0428487548646152, -0.0308090857078185, + 0.0225672437721518, -0.000281355782039133, 66.8440182379463, + -42.3350991467661, 354.562942832682, 0.000573219240561573, + 66.844044569212, -47.8519918014414, -0.499726325044563, + 23769.8747006891, 9267.5206785042, 0.0415639300026818, + -0.0164109903099032, 0.0232814268213158, -0.000139385907988285, + 64.8399200066663, -19.6874999818575, 366.100410278813, + 0.00128332197988872, 64.8400012051758, -25.3838027935624, + -0.490219448053285, 23854.0240861864, 15160.7060140903, + 0.0427385845553072, -0.0273659210853948, 0.0227360281885303, + -0.00024756822257102, 66.6722121992594, -36.9193366680176, + 357.260483774461, 0.000734666517031364, 66.6722602990682, + -42.4779079553274, -0.491586583798841, 23870.5548740189, + 6166.60742794455, 0.0412253604361869, -0.0108406830677542, + 0.0235710268609798, -8.45378382385454e-05, 64.3117067426907, + -10.9219886629635, 370.751596332923, 0.00130490570318174, + 64.3117765573399, -16.6904284244068, -0.482907936930927, + -2.9267653635869, 30.5878043390112, 75.9238910016987, + 9.17392754248112, 4.3701560041079, 48.7765765968327, + 58.3101300775815, 3.13323809951331, -6.37573932293514, + 46.1701408549949, 41.9244199648313, -6.5432868117422, + -17.3691293511209, 41.8611610718482, 27.7383173553277, + -12.9709065074016, -27.5322418670623, 38.9032728624808, + 16.2733736528389, -16.5280348065045, -36.4800564569504, + 37.0627808819117, 7.38198504755967, -17.9899033675727, + -44.0731708800056, 36.9539474625741, 1.14781892918688, + -15.9507601441003, -49.1751072411967, 44.6278268007059, + 82.7517114852138, -57.3188928805757, 125.959171148664, + -93.1822145893453, 110.816672146529, -108.811406393296, + 99.5107131550674, -119.104827911048, 92.0427992280762, + -125.056967118294, 88.0811872722293, -127.985464658329, + 87.1649116220972, -128.957730829954, 89.0189233593932, + -129.480383815729, 311.408200092424, 361.890500304156, + -7.90450151715305, 365.594288034004, -14.6504114199963, + 344.278948204657, -61.517809887448, 348.104769580715, + -73.1715704285651, 329.472137794467, -107.797643650827, + 335.509251816504, -117.787067889008, 317.044841017058, + -139.602945170765, 325.182412285621, -147.51178633583, + 307.989533967543, -158.91998673915, 318.171184823086, + -165.141414351062, 302.951769665185, -168.712626964975, + 315.009688292198, -173.624287308414, 302.070219389208, + -171.572667424371, 315.86470341008, -175.706947618597, + 306.288884765777, -170.785573848562, 322.018589824395, + -176.179397251772 +}; diff --git a/examples/PowerFlow/MatPowerTesting/MatPowerTesting.hpp b/examples/PowerFlow/MatPowerTesting/MatPowerTesting.hpp index 062a32fece..aabaf7fbe5 100644 --- a/examples/PowerFlow/MatPowerTesting/MatPowerTesting.hpp +++ b/examples/PowerFlow/MatPowerTesting/MatPowerTesting.hpp @@ -34,9 +34,11 @@ namespace GridKit { template - inline bool isEqual(PowerFlowData::GenCostData a, - PowerFlowData::GenCostData b, - RealT tol = tol_) + inline bool isEqual( + PowerFlowData::GenCostData a, + PowerFlowData::GenCostData b, + RealT tol = tol_ + ) { (void) tol; // suppress warning int fail = 0; @@ -52,9 +54,11 @@ namespace GridKit } template - inline bool isEqual(PowerFlowData::GenData a, - PowerFlowData::GenData b, - RealT tol = tol_) + inline bool isEqual( + PowerFlowData::GenData a, + PowerFlowData::GenData b, + RealT tol = tol_ + ) { int fail = 0; @@ -88,9 +92,11 @@ namespace GridKit } template - inline bool isEqual(PowerFlowData::BusData a, - PowerFlowData::BusData b, - RealT tol = tol_) + inline bool isEqual( + PowerFlowData::BusData a, + PowerFlowData::BusData b, + RealT tol = tol_ + ) { int fail = 0; @@ -124,9 +130,11 @@ namespace GridKit } template - inline bool isEqual(PowerFlowData::LoadData a, - PowerFlowData::LoadData b, - RealT tol = tol_) + inline bool isEqual( + PowerFlowData::LoadData a, + PowerFlowData::LoadData b, + RealT tol = tol_ + ) { int fail = 0; @@ -144,9 +152,11 @@ namespace GridKit } template - inline bool isEqual(PowerFlowData::BranchData a, - PowerFlowData::BranchData b, - RealT tol = tol_) + inline bool isEqual( + PowerFlowData::BranchData a, + PowerFlowData::BranchData b, + RealT tol = tol_ + ) { int fail = 0; @@ -197,8 +207,10 @@ namespace GridKit } template - inline bool isEqual(PowerFlowData::SystemModelData a, - PowerFlowData::SystemModelData b) + inline bool isEqual( + PowerFlowData::SystemModelData a, + PowerFlowData::SystemModelData b + ) { int fail = 0; diff --git a/examples/PowerFlow/MatPowerTesting/test_parse_branch_row.cpp b/examples/PowerFlow/MatPowerTesting/test_parse_branch_row.cpp index 275a92cb80..dc22558f56 100644 --- a/examples/PowerFlow/MatPowerTesting/test_parse_branch_row.cpp +++ b/examples/PowerFlow/MatPowerTesting/test_parse_branch_row.cpp @@ -16,7 +16,7 @@ namespace using RealT = double; static const std::string matpower_data{ - R"( + R"( %% branch data % fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax @@ -30,7 +30,8 @@ mpc.branch = [ ]; -)"}; +)" + }; } // namespace @@ -38,12 +39,12 @@ int main(int /* argc */, char** /* argv */) { int fail = 0; std::vector> branch_answer{ - {1, 2, 0.00281, 0.0281, 0.00712, 400, 400, 400, 0, 0, 1, -360, 360}, - {1, 4, 0.00304, 0.0304, 0.00658, 0, 0, 0, 0, 0, 1, -360, 360}, - {1, 5, 0.00064, 0.0064, 0.03126, 0, 0, 0, 0, 0, 1, -360, 360}, - {2, 3, 0.00108, 0.0108, 0.01852, 0, 0, 0, 0, 0, 1, -360, 360}, - {3, 4, 0.00297, 0.0297, 0.00674, 0, 0, 0, 0, 0, 1, -360, 360}, - {4, 5, 0.00297, 0.0297, 0.00674, 240, 240, 240, 0, 0, 1, -360, 360}, + {1, 2, 0.00281, 0.0281, 0.00712, 400, 400, 400, 0, 0, 1, -360, 360}, + {1, 4, 0.00304, 0.0304, 0.00658, 0, 0, 0, 0, 0, 1, -360, 360}, + {1, 5, 0.00064, 0.0064, 0.03126, 0, 0, 0, 0, 0, 1, -360, 360}, + {2, 3, 0.00108, 0.0108, 0.01852, 0, 0, 0, 0, 0, 1, -360, 360}, + {3, 4, 0.00297, 0.0297, 0.00674, 0, 0, 0, 0, 0, 1, -360, 360}, + {4, 5, 0.00297, 0.0297, 0.00674, 240, 240, 240, 0, 0, 1, -360, 360}, }; SystemModelData mp; diff --git a/examples/PowerFlow/MatPowerTesting/test_parse_bus_row.cpp b/examples/PowerFlow/MatPowerTesting/test_parse_bus_row.cpp index f7dc3365c9..161e2e35fd 100644 --- a/examples/PowerFlow/MatPowerTesting/test_parse_bus_row.cpp +++ b/examples/PowerFlow/MatPowerTesting/test_parse_bus_row.cpp @@ -16,7 +16,7 @@ namespace using RealT = double; static const std::string matpower_data{ - R"( + R"( %% bus data mpc.bus = [ 1 2 0 0 0 0 1 1 0 230 1 1.1 0.0; @@ -25,7 +25,8 @@ mpc.bus = [ 4 3 400 131.47 0 0 1 1 0 230 1 1.1 0.0; 5 2 0 0 0 0 1 1 0 230 1 1.1 0.9; ]; -)"}; +)" + }; } // namespace @@ -33,19 +34,19 @@ int main(int /* argc */, char** /* argv */) { int fail = 0; std::vector> bus_answer{ - {1, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {2, 1, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {3, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {4, 3, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {5, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.9}, + {1, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {2, 1, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {3, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {4, 3, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {5, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.9}, }; std::vector> load_answer{ - {1, 0, 0}, - {2, 300, 98.61}, - {3, 300, 98.61}, - {4, 400, 131.47}, - {5, 0, 0}, + {1, 0, 0}, + {2, 300, 98.61}, + {3, 300, 98.61}, + {4, 400, 131.47}, + {5, 0, 0}, }; { diff --git a/examples/PowerFlow/MatPowerTesting/test_parse_gen_row.cpp b/examples/PowerFlow/MatPowerTesting/test_parse_gen_row.cpp index 88cf838634..5ffdae788c 100644 --- a/examples/PowerFlow/MatPowerTesting/test_parse_gen_row.cpp +++ b/examples/PowerFlow/MatPowerTesting/test_parse_gen_row.cpp @@ -16,7 +16,7 @@ namespace using RealT = double; static const std::string matpower_data{ - R"( + R"( %% generator data % bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf mpc.gen = [ @@ -27,7 +27,8 @@ mpc.gen = [ 5 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; ]; -)"}; +)" + }; } // namespace @@ -35,11 +36,15 @@ int main(int /* argc */, char** /* argv */) { int fail = 0; std::vector> gen_answer{ - {1, 40, 0, 30, -30, 1, 100, 1, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 170, 0, 127.5, -127.5, 1, 100, 1, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 323.49, 0, 390, -390, 1, 100, 1, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 0, 0, 150, -150, 1, 100, 1, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {5, 466.51, 0, 450, -450, 1, 100, 1, 600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + {1, 40, 0, 30, -30, 1, 100, 1, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 170, 0, 127.5, -127.5, 1, 100, 1, 170, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 323.49, 0, 390, -390, 1, 100, 1, 520, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 0, 150, -150, 1, 100, 1, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {5, 466.51, 0, 450, -450, 1, 100, 1, 600, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }; SystemModelData mp; { diff --git a/examples/PowerFlow/MatPowerTesting/test_parse_gencost_row.cpp b/examples/PowerFlow/MatPowerTesting/test_parse_gencost_row.cpp index 9f7bda2028..fdc68a80eb 100644 --- a/examples/PowerFlow/MatPowerTesting/test_parse_gencost_row.cpp +++ b/examples/PowerFlow/MatPowerTesting/test_parse_gencost_row.cpp @@ -16,7 +16,7 @@ namespace using RealT = double; static const std::string matpower_data{ - R"( + R"( %%----- OPF Data -----%% %% generator cost data @@ -30,7 +30,8 @@ mpc.gencost = [ 2 0 0 3 0 10 0; ]; -)"}; +)" + }; } // namespace @@ -38,11 +39,11 @@ int main(int /* argc */, char** /* argv */) { int fail = 0; std::vector> gencost_answer{ - {2, 0, 0, 3, {0, 14, 0}}, - {2, 0, 0, 3, {0, 15, 0}}, - {2, 0, 0, 3, {0, 30, 0}}, - {2, 0, 0, 3, {0, 40, 0}}, - {2, 0, 0, 3, {0, 10, 0}}, + {2, 0, 0, 3, {0, 14, 0}}, + {2, 0, 0, 3, {0, 15, 0}}, + {2, 0, 0, 3, {0, 30, 0}}, + {2, 0, 0, 3, {0, 40, 0}}, + {2, 0, 0, 3, {0, 10, 0}}, }; SystemModelData mp; diff --git a/examples/PowerFlow/MatPowerTesting/test_parse_matpower.cpp b/examples/PowerFlow/MatPowerTesting/test_parse_matpower.cpp index 659c1cf336..e318f08917 100644 --- a/examples/PowerFlow/MatPowerTesting/test_parse_matpower.cpp +++ b/examples/PowerFlow/MatPowerTesting/test_parse_matpower.cpp @@ -16,7 +16,7 @@ namespace using RealT = double; static const std::string matpower_data{ - R"( + R"( function mpc = case5 %CASE5 Power flow data for modified 5 bus, 5 gen case based on PJM 5-bus system % Please see CASEFORMAT for details on the case file format. @@ -80,7 +80,8 @@ mpc.gencost = [ 2 0 0 3 0 10 0; ]; -)"}; +)" + }; } // namespace @@ -98,39 +99,43 @@ int main(int /* argc */, char** /* argv */) // Create the struct of expected values std::vector branch_answer{ - {1, 2, 0.00281, 0.0281, 0.00712, 400, 400, 400, 0, 0, 1, -360, 360}, - {1, 4, 0.00304, 0.0304, 0.00658, 0, 0, 0, 0, 0, 1, -360, 360}, - {1, 5, 0.00064, 0.0064, 0.03126, 0, 0, 0, 0, 0, 1, -360, 360}, - {2, 3, 0.00108, 0.0108, 0.01852, 0, 0, 0, 0, 0, 1, -360, 360}, - {3, 4, 0.00297, 0.0297, 0.00674, 0, 0, 0, 0, 0, 1, -360, 360}, - {4, 5, 0.00297, 0.0297, 0.00674, 240, 240, 240, 0, 0, 1, -360, 360}, + {1, 2, 0.00281, 0.0281, 0.00712, 400, 400, 400, 0, 0, 1, -360, 360}, + {1, 4, 0.00304, 0.0304, 0.00658, 0, 0, 0, 0, 0, 1, -360, 360}, + {1, 5, 0.00064, 0.0064, 0.03126, 0, 0, 0, 0, 0, 1, -360, 360}, + {2, 3, 0.00108, 0.0108, 0.01852, 0, 0, 0, 0, 0, 1, -360, 360}, + {3, 4, 0.00297, 0.0297, 0.00674, 0, 0, 0, 0, 0, 1, -360, 360}, + {4, 5, 0.00297, 0.0297, 0.00674, 240, 240, 240, 0, 0, 1, -360, 360}, }; std::vector bus_answer{ - {1, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {2, 1, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {3, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {4, 3, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {5, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.9}, + {1, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {2, 1, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {3, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {4, 3, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {5, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.9}, }; std::vector gen_answer{ - {1, 40, 0, 30, -30, 1, 100, 1, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 170, 0, 127.5, -127.5, 1, 100, 1, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 323.49, 0, 390, -390, 1, 100, 1, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 0, 0, 150, -150, 1, 100, 1, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {5, 466.51, 0, 450, -450, 1, 100, 1, 600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + {1, 40, 0, 30, -30, 1, 100, 1, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 170, 0, 127.5, -127.5, 1, 100, 1, 170, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 323.49, 0, 390, -390, 1, 100, 1, 520, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 0, 150, -150, 1, 100, 1, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {5, 466.51, 0, 450, -450, 1, 100, 1, 600, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }; std::vector gencost_answer{ - {2, 0, 0, 3, {0, 14, 0}}, - {2, 0, 0, 3, {0, 15, 0}}, - {2, 0, 0, 3, {0, 30, 0}}, - {2, 0, 0, 3, {0, 40, 0}}, - {2, 0, 0, 3, {0, 10, 0}}, + {2, 0, 0, 3, {0, 14, 0}}, + {2, 0, 0, 3, {0, 15, 0}}, + {2, 0, 0, 3, {0, 30, 0}}, + {2, 0, 0, 3, {0, 40, 0}}, + {2, 0, 0, 3, {0, 10, 0}}, }; std::vector load_answer{ - {1, 0, 0}, - {2, 300, 98.61}, - {3, 300, 98.61}, - {4, 400, 131.47}, - {5, 0, 0}, + {1, 0, 0}, + {2, 300, 98.61}, + {3, 300, 98.61}, + {4, 400, 131.47}, + {5, 0, 0}, }; SystemModelDataT mp_answer; diff --git a/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp b/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp index 828999ed1d..31ca622aad 100644 --- a/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp +++ b/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp @@ -211,11 +211,13 @@ namespace GridKit return success; } - std::unique_ptr runSimulation(SystemModelDataT& system_data, - IdxT fault_bus, - RealT R, - RealT X, - const std::string& ref_file) + std::unique_ptr runSimulation( + SystemModelDataT& system_data, + IdxT fault_bus, + RealT R, + RealT X, + const std::string& ref_file + ) { system_data.monitor_sink.emplace_back(VariableMonitorFormat::CSV, "mon.csv"); @@ -231,8 +233,9 @@ namespace GridKit // Set up simulation AnalysisManager::Sundials::Ida ida(&sys); - ida.setTolerance(static_cast(1.0e-7), - static_cast(1.0e-9)); + ida.setTolerance( + static_cast(1.0e-7), static_cast(1.0e-9) + ); ida.configureSimulation(); // Run for 1s @@ -739,15 +742,17 @@ namespace GridKit bus.Vr0 = ONE; bus.Vi0 = ZERO; - data.signal = {{"Active Current Command", signalId(LoopSignal::IPCMD)}, - {"Reactive Current Command", signalId(LoopSignal::IQCMD)}, - {"Branch Current Real", signalId(LoopSignal::IR)}, - {"Branch Current Imaginary", signalId(LoopSignal::II)}, - {"Branch Active Power", signalId(LoopSignal::PBRANCH)}, - {"Branch Reactive Power", signalId(LoopSignal::QBRANCH)}, - {"Reactive Power Command", signalId(LoopSignal::QEXT)}, - {"Active Power Command", signalId(LoopSignal::PEXT)}, - {"Plant Active Power Reference", signalId(LoopSignal::PLANT_PREF)}}; + data.signal = { + {"Active Current Command", signalId(LoopSignal::IPCMD)}, + {"Reactive Current Command", signalId(LoopSignal::IQCMD)}, + {"Branch Current Real", signalId(LoopSignal::IR)}, + {"Branch Current Imaginary", signalId(LoopSignal::II)}, + {"Branch Active Power", signalId(LoopSignal::PBRANCH)}, + {"Branch Reactive Power", signalId(LoopSignal::QBRANCH)}, + {"Reactive Power Command", signalId(LoopSignal::QEXT)}, + {"Active Power Command", signalId(LoopSignal::PEXT)}, + {"Plant Active Power Reference", signalId(LoopSignal::PLANT_PREF)} + }; auto& converter = data.regca.emplace_back(); converter.buses[RegcaBuses::bus] = RENEWABLE_BUS_ID; @@ -807,7 +812,7 @@ namespace GridKit auto& reference = data.constant_source.emplace_back(); reference.parameters[ConstantSignalSourceParameters::Sr] = INITIAL_ACTIVE_POWER; reference.signal_outputs[ConstantSignalSourceSignalOutputs::sr] = - signalId(LoopSignal::PLANT_PREF); + signalId(LoopSignal::PLANT_PREF); SystemModel system(data); success *= system.allocate() == 0; @@ -831,18 +836,25 @@ namespace GridKit const auto* equilibrium_values = system.y().getData(); const std::vector equilibrium( - equilibrium_values, - equilibrium_values + static_cast(system.y().getSize())); - - success *= isEqual(static_cast(pref_signal->read()), - INITIAL_ACTIVE_POWER, - RECOVERY_TOLERANCE); - success *= isEqual(static_cast(pext_signal->read()), - INITIAL_ACTIVE_POWER, - RECOVERY_TOLERANCE); - success *= isEqual(static_cast(qext_signal->read()), - INITIAL_REACTIVE_POWER, - RECOVERY_TOLERANCE); + equilibrium_values, + equilibrium_values + static_cast(system.y().getSize()) + ); + + success *= isEqual( + static_cast(pref_signal->read()), + INITIAL_ACTIVE_POWER, + RECOVERY_TOLERANCE + ); + success *= isEqual( + static_cast(pext_signal->read()), + INITIAL_ACTIVE_POWER, + RECOVERY_TOLERANCE + ); + success *= isEqual( + static_cast(qext_signal->read()), + INITIAL_REACTIVE_POWER, + RECOVERY_TOLERANCE + ); const RealT pref0 = static_cast(pref_signal->read()); const RealT pext0 = static_cast(pext_signal->read()); @@ -860,9 +872,10 @@ namespace GridKit }; const std::array responses{{ - {"REPCA PEXT", static_cast(pext_signal->read()) - pext0}, - {"REECB IPCMD", static_cast(ipcmd_signal->read()) - ipcmd0}, - {"REGCA PBRANCH", static_cast(pbranch_signal->read()) - pbranch0}, + {"REPCA PEXT", static_cast(pext_signal->read()) - pext0}, + {"REECB IPCMD", static_cast(ipcmd_signal->read()) - ipcmd0}, + {"REGCA PBRANCH", + static_cast(pbranch_signal->read()) - pbranch0}, }}; for (const auto& response : responses) { @@ -876,9 +889,9 @@ namespace GridKit pref_signal->init(pref0); success *= ida.initializeSimulation(PULSE_DURATION) == 0; - success *= ida.runSimulation(PULSE_DURATION + RECOVERY_HORIZON, - OUTPUT_INTERVAL) - == 0; + success *= + ida.runSimulation(PULSE_DURATION + RECOVERY_HORIZON, OUTPUT_INTERVAL) + == 0; const auto* final_values = system.y().getData(); for (size_t entry = 0; entry < equilibrium.size(); ++entry) diff --git a/tests/IntegrationTests/PhasorDynamics/SystemJacobian/SystemJacobianTests.hpp b/tests/IntegrationTests/PhasorDynamics/SystemJacobian/SystemJacobianTests.hpp index 44113f1160..8b11599eb7 100644 --- a/tests/IntegrationTests/PhasorDynamics/SystemJacobian/SystemJacobianTests.hpp +++ b/tests/IntegrationTests/PhasorDynamics/SystemJacobian/SystemJacobianTests.hpp @@ -36,7 +36,7 @@ namespace GridKit using ClockT = std::chrono::steady_clock; using DurationT = std::chrono::duration; using JacobianT = - std::vector; + std::vector; using ModelDataT = PhasorDynamics::SystemModelData; /// Number of timed evaluations after setup and warm-up @@ -99,17 +99,18 @@ namespace GridKit // Jacobian via DependencyTracking JacobianT dependency_tracking_jacobian = - DependencyTrackingJacobian(data); + DependencyTrackingJacobian(data); // Compare DependencyTracking dependencies to Enzyme's success *= - (dependency_tracking_jacobian.size() == enzyme_jacobian.size()); + (dependency_tracking_jacobian.size() == enzyme_jacobian.size()); for (IdxT i = 0; i < dependency_tracking_jacobian.size() && i < enzyme_jacobian.size(); ++i) { success *= (GridKit::Testing::isEqual( - dependency_tracking_jacobian[i], enzyme_jacobian[i], tol)); + dependency_tracking_jacobian[i], enzyme_jacobian[i], tol + )); } } catch (const std::exception& error) @@ -180,16 +181,16 @@ namespace GridKit << "" << std::setw(10) << enzyme_jacobian_[i] << '\n'; output_stream - << std::left << std::setw(static_cast(case_width)) - << case_names_[i] << std::setw(20) << "DependencyTracking" - << std::right << std::setw(7) << sizes_[i] << std::setw(8) - << dependency_tracking_nnz_[i] << std::setw(11) - << dependency_tracking_setup_[i] << std::setw(8) - << dependency_tracking_setup_[i] / enzyme_setup_[i] << std::setw(10) - << dependency_tracking_residual_[i] << std::setw(8) - << dependency_tracking_residual_[i] / enzyme_residual_[i] - << std::setw(10) << dependency_tracking_jacobian_[i] << std::setw(8) - << dependency_tracking_jacobian_[i] / enzyme_jacobian_[i] << '\n'; + << std::left << std::setw(static_cast(case_width)) + << case_names_[i] << std::setw(20) << "DependencyTracking" + << std::right << std::setw(7) << sizes_[i] << std::setw(8) + << dependency_tracking_nnz_[i] << std::setw(11) + << dependency_tracking_setup_[i] << std::setw(8) + << dependency_tracking_setup_[i] / enzyme_setup_[i] << std::setw(10) + << dependency_tracking_residual_[i] << std::setw(8) + << dependency_tracking_residual_[i] / enzyme_residual_[i] + << std::setw(10) << dependency_tracking_jacobian_[i] << std::setw(8) + << dependency_tracking_jacobian_[i] / enzyme_jacobian_[i] << '\n'; } output_stream.flags(flags); @@ -207,8 +208,9 @@ namespace GridKit IdxT index{INVALID_INDEX}; void bind( - PhasorDynamics::SystemModel& system, - const ModelDataT& data) + PhasorDynamics::SystemModel& system, + const ModelDataT& data + ) { for (const auto& bus : data.bus) { @@ -242,7 +244,8 @@ namespace GridKit { ExternalInputs inputs; PhasorDynamics::SystemModel system( - data); + data + ); inputs.bind(system, data); system.updateTime(0.0, 1.0); // Set alpha to 1.0 to verify d/dy' terms @@ -289,7 +292,7 @@ namespace GridKit auto& output_stream = Log::misc(); output_stream - << "Sparse Csr Matrix: System Jacobian with DependencyTracking\n"; + << "Sparse Csr Matrix: System Jacobian with DependencyTracking\n"; system_jacobian->print(output_stream); return GridKit::Testing::MapFromCsr(system_jacobian); diff --git a/tests/IntegrationTests/PhasorDynamics/SystemJacobian/runSystemJacobianTests.cpp b/tests/IntegrationTests/PhasorDynamics/SystemJacobian/runSystemJacobianTests.cpp index 3db2480c4d..3e942684fc 100644 --- a/tests/IntegrationTests/PhasorDynamics/SystemJacobian/runSystemJacobianTests.cpp +++ b/tests/IntegrationTests/PhasorDynamics/SystemJacobian/runSystemJacobianTests.cpp @@ -13,13 +13,15 @@ int main(int argc, const char* argv[]) // Print timings Log::raiseVerbosity(Log::SUMMARY); - GridKit::Utilities::CliArgs args{{.name = {"--cases", "-c"}, - .help = "Case file, or directory searched recursively for *.case.json", - .required = true}, - {.name = {"--evaluations", "-n"}, - .help = "Number of timed evaluations per case", - .type = GridKit::Utilities::ArgType::Integer, - .defaults = 100}}; + GridKit::Utilities::CliArgs args{ + {.name = {"--cases", "-c"}, + .help = "Case file, or directory searched recursively for *.case.json", + .required = true}, + {.name = {"--evaluations", "-n"}, + .help = "Number of timed evaluations per case", + .type = GridKit::Utilities::ArgType::Integer, + .defaults = 100} + }; args.parseArgs(argc, argv); const std::filesystem::path path = args["cases"](); diff --git a/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp b/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp index d27c36e78c..09e0b40be5 100644 --- a/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp +++ b/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp @@ -44,12 +44,14 @@ GridKit::PhasorDynamics::GenClassicalData genData(real_ty } /// Branch data with the given line and transformer parameters -GridKit::PhasorDynamics::BranchData branchData(const real_type R, - const real_type X, - const real_type G, - const real_type B, - const real_type tap = 1.0, - const real_type phase = 0.0) +GridKit::PhasorDynamics::BranchData branchData( + const real_type R, + const real_type X, + const real_type G, + const real_type B, + const real_type tap = 1.0, + const real_type phase = 0.0 +) { using Parameter = GridKit::PhasorDynamics::BranchParameters; @@ -175,9 +177,9 @@ int main() // Output voltage magnitudes on buses for (size_t i = 0; i < 9; ++i) { - out << std::sqrt(yval[2 * i] * yval[2 * i] - + yval[2 * i + 1] * yval[2 * i + 1]) - << ","; + out << std::sqrt( + yval[2 * i] * yval[2 * i] + yval[2 * i + 1] * yval[2 * i + 1] + ) << ","; } // Output generator frequencies @@ -246,9 +248,10 @@ int main() Log::summary() << "Complete in " << (stop - start) / CLOCKS_PER_SEC << " seconds\n"; auto error_set = GridKit::Testing::compareCSV( - "TenGenClassical_results.csv", - "reference/TenGenClassical.ref.csv", - GridKit::Testing::ErrorType::ABSOLUTE); + "TenGenClassical_results.csv", + "reference/TenGenClassical.ref.csv", + GridKit::Testing::ErrorType::ABSOLUTE + ); error_set->display(); success *= error_set->total_error.max_value < 2.6e-4; diff --git a/tests/IntegrationTests/PhasorDynamics/TenGen/Genrou/TenGenGenrou.cpp b/tests/IntegrationTests/PhasorDynamics/TenGen/Genrou/TenGenGenrou.cpp index bdca1ab0ab..685cff6e72 100644 --- a/tests/IntegrationTests/PhasorDynamics/TenGen/Genrou/TenGenGenrou.cpp +++ b/tests/IntegrationTests/PhasorDynamics/TenGen/Genrou/TenGenGenrou.cpp @@ -39,12 +39,14 @@ GridKit::PhasorDynamics::GenrouData genData(real_type p0, } /// Branch data with the given line and transformer parameters -GridKit::PhasorDynamics::BranchData branchData(const real_type R, - const real_type X, - const real_type G, - const real_type B, - const real_type tap = 1.0, - const real_type phase = 0.0) +GridKit::PhasorDynamics::BranchData branchData( + const real_type R, + const real_type X, + const real_type G, + const real_type B, + const real_type tap = 1.0, + const real_type phase = 0.0 +) { using Parameter = GridKit::PhasorDynamics::BranchParameters; @@ -166,9 +168,9 @@ int main() // Output voltage magnitudes on buses for (size_t i = 0; i < 9; ++i) { - out << std::sqrt(yval[2 * i] * yval[2 * i] - + yval[2 * i + 1] * yval[2 * i + 1]) - << ","; + out << std::sqrt( + yval[2 * i] * yval[2 * i] + yval[2 * i + 1] * yval[2 * i + 1] + ) << ","; } // Output generator frequencies @@ -227,9 +229,10 @@ int main() Log::summary() << "Complete in " << (stop - start) / CLOCKS_PER_SEC << " seconds\n"; auto error_set = GridKit::Testing::compareCSV( - "TenGenGenrou_Results.csv", - "reference/TenGenGenrou.ref.csv", - GridKit::Testing::ErrorType::ABSOLUTE); + "TenGenGenrou_Results.csv", + "reference/TenGenGenrou.ref.csv", + GridKit::Testing::ErrorType::ABSOLUTE + ); error_set->display(); success *= error_set->total_error.max_value < 1e-4; diff --git a/tests/UnitTests/AutomaticDifferentiation/DependencyTracking/DependencyTrackingTests.hpp b/tests/UnitTests/AutomaticDifferentiation/DependencyTracking/DependencyTrackingTests.hpp index 4088841133..30f338c386 100644 --- a/tests/UnitTests/AutomaticDifferentiation/DependencyTracking/DependencyTrackingTests.hpp +++ b/tests/UnitTests/AutomaticDifferentiation/DependencyTracking/DependencyTrackingTests.hpp @@ -48,7 +48,7 @@ namespace GridKit // Check dependencies of f[0] (depends on x[0] and x[1]) { const DependencyTracking::Variable::DependencyMap& dependencies = - (f[0]).getDependencies(); + (f[0]).getDependencies(); success *= (dependencies.size() == 2); success *= (dependencies.find(0) != dependencies.end()); @@ -59,7 +59,7 @@ namespace GridKit // Check dependencies of f[2] (depends on x[0], x[1], x[2]) { const DependencyTracking::Variable::DependencyMap& dependencies = - (f[2]).getDependencies(); + (f[2]).getDependencies(); success *= (dependencies.size() == 3); success *= (dependencies.find(0) != dependencies.end()); @@ -72,9 +72,9 @@ namespace GridKit private: template - void residualFunction(std::vector& f, - const std::vector& x, - const std::vector& p) + void residualFunction( + std::vector& f, const std::vector& x, const std::vector& p + ) { const T u = x[0] * x[1]; diff --git a/tests/UnitTests/AutomaticDifferentiation/Enzyme/EnzymeTests.hpp b/tests/UnitTests/AutomaticDifferentiation/Enzyme/EnzymeTests.hpp index 79696db29c..90f75ac21f 100644 --- a/tests/UnitTests/AutomaticDifferentiation/Enzyme/EnzymeTests.hpp +++ b/tests/UnitTests/AutomaticDifferentiation/Enzyme/EnzymeTests.hpp @@ -146,29 +146,35 @@ namespace GridKit size_t current_nnz = 0; for (size_t i = 0; i < N; i++) { - ScalarT* output = __enzyme_todense((void*) ident_load, - (void*) ident_store, - i); - ScalarT* d_output = __enzyme_todense((void*) sparse_load, - (void*) sparse_store, - i, - 1.0, - index_maps, - index_maps, - rows_buffer, - cols_buffer, - vals_buffer, - ¤t_nnz); - - __enzyme_fwddiff((void*) vectorFunction, - enzyme_const, - N, - enzyme_dup, - x, - output, - enzyme_dupnoneed, - (ScalarT*) 0x1, - d_output); + ScalarT* output = __enzyme_todense( + (void*) ident_load, + (void*) ident_store, + i + ); + ScalarT* d_output = __enzyme_todense( + (void*) sparse_load, + (void*) sparse_store, + i, + 1.0, + index_maps, + index_maps, + rows_buffer, + cols_buffer, + vals_buffer, + ¤t_nnz + ); + + __enzyme_fwddiff( + (void*) vectorFunction, + enzyme_const, + N, + enzyme_dup, + x, + output, + enzyme_dupnoneed, + (ScalarT*) 0x1, + d_output + ); } size_t* rows = new size_t[current_nnz]; @@ -216,8 +222,9 @@ namespace GridKit } // @todo move to a common location if this needs to be reused - TestStatus checkVectorFunctionSparseJacobian(SparseMatrix* matrix_1, - SparseMatrix* matrix_2) + TestStatus checkVectorFunctionSparseJacobian( + SparseMatrix* matrix_1, SparseMatrix* matrix_2 + ) { TestStatus success = true; diff --git a/tests/UnitTests/LinearAlgebra/SparseMatrix/SparseCsrTests.hpp b/tests/UnitTests/LinearAlgebra/SparseMatrix/SparseCsrTests.hpp index 0638c46c10..de66bbc5b0 100644 --- a/tests/UnitTests/LinearAlgebra/SparseMatrix/SparseCsrTests.hpp +++ b/tests/UnitTests/LinearAlgebra/SparseMatrix/SparseCsrTests.hpp @@ -42,9 +42,7 @@ namespace GridKit * * @return TestOutcome indicating success or failure of the test */ - TestOutcome constructor(IdxT n, - IdxT m, - IdxT nnz) + TestOutcome constructor(IdxT n, IdxT m, IdxT nnz) { TestStatus success; success = true; diff --git a/tests/UnitTests/LinearAlgebra/Vector/VectorHandlerTests.hpp b/tests/UnitTests/LinearAlgebra/Vector/VectorHandlerTests.hpp index fdb3807d4b..f63de9030c 100644 --- a/tests/UnitTests/LinearAlgebra/Vector/VectorHandlerTests.hpp +++ b/tests/UnitTests/LinearAlgebra/Vector/VectorHandlerTests.hpp @@ -187,8 +187,11 @@ namespace GridKit } IdxT r = K % 2; - ScalarT res = static_cast((std::floor(static_cast(K) / 2.0) + static_cast(r)) * 1.0 - + std::floor(static_cast(K) / 2.0) * (-0.5)); + ScalarT res = static_cast( + (std::floor(static_cast(K) / 2.0) + static_cast(r)) + * 1.0 + + std::floor(static_cast(K) / 2.0) * (-0.5) + ); handler_.axpyMulti(N, &alpha, K, &x, &y, memspace_); status *= verifyAnswer(y, 2.0 - res); diff --git a/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp b/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp index caaae8ebc7..3a4eb512f8 100644 --- a/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp +++ b/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp @@ -26,9 +26,9 @@ namespace GridKit return static_cast(value); } - static bool within(const ScalarT value, - const ScalarT expected, - const ScalarT tolerance) + static bool within( + const ScalarT value, const ScalarT expected, const ScalarT tolerance + ) { return std::abs(value - expected) < tolerance; } @@ -104,9 +104,12 @@ namespace GridKit success *= (std::abs(upper_breakpoint) < tol); const ScalarT x = scalar(-0.4); - success *= (std::abs(Math::deadband2(x, lower, upper) - - (x - Math::clamp(x, lower, upper))) - < scalar(kRoundoffTolerance)); + success *= + (std::abs( + Math::deadband2(x, lower, upper) + - (x - Math::clamp(x, lower, upper)) + ) + < scalar(kRoundoffTolerance)); const ScalarT far_above_input = scalar(4.0); const ScalarT far_below_input = scalar(-4.0); @@ -121,10 +124,16 @@ namespace GridKit const ScalarT point = scalar(0.25); const ScalarT above_point = scalar(0.75); const ScalarT below_point = scalar(-0.25); - success *= (std::abs(Math::deadband2(above_point, point, point) - (above_point - point)) - < scalar(kRoundoffTolerance)); - success *= (std::abs(Math::deadband2(below_point, point, point) - (below_point - point)) - < scalar(kRoundoffTolerance)); + success *= + (std::abs( + Math::deadband2(above_point, point, point) - (above_point - point) + ) + < scalar(kRoundoffTolerance)); + success *= + (std::abs( + Math::deadband2(below_point, point, point) - (below_point - point) + ) + < scalar(kRoundoffTolerance)); return success.report(__func__); } @@ -152,10 +161,12 @@ namespace GridKit success *= (Math::outside(scalar(3.2), limit_min, limit_max) > near_one); const ScalarT x = scalar(1.5); - success *= (std::abs(Math::inside(x, limit_min, limit_max) - + Math::outside(x, limit_min, limit_max) - - scalar(1.0)) - < scalar(kRoundoffTolerance)); + success *= + (std::abs( + Math::inside(x, limit_min, limit_max) + + Math::outside(x, limit_min, limit_max) - scalar(1.0) + ) + < scalar(kRoundoffTolerance)); return success.report(__func__); } @@ -259,26 +270,37 @@ namespace GridKit const auto lower_bounded_state = Math::max(state_below_bound, parameter_bound); const auto upper_bounded_state = Math::min(state_above_bound, parameter_bound); - 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."); + static_assert( + std::is_same< + typename std::decay::type, + Variable>::value, + "Mixed-type max should keep the differentiable scalar type." + ); + static_assert( + std::is_same< + typename std::decay::type, + Variable>::value, + "Mixed-type min should keep the differentiable scalar type." + ); 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)) - < scalar(kRoundoffTolerance)); + success *= + (std::abs(Math::min(x, y) + Math::max(x, y) - (x + y)) + < scalar(kRoundoffTolerance)); const ScalarT point = scalar(0.25); const ScalarT bias = std::log(scalar(2.0)) / scalar(Math::MU); - success *= (std::abs(Math::max(point, point) - (point + bias)) - < scalar(kRoundoffTolerance)); - success *= (std::abs(Math::min(point, point) - (point - bias)) - < scalar(kRoundoffTolerance)); + success *= + (std::abs(Math::max(point, point) - (point + bias)) + < scalar(kRoundoffTolerance)); + success *= + (std::abs(Math::min(point, point) - (point - bias)) + < scalar(kRoundoffTolerance)); return success.report(__func__); } @@ -330,18 +352,26 @@ namespace GridKit 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(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 *= 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); + success *= within( + Math::antiwindup(below_limit, f_positive, limit_min, limit_max), + f_positive, + blocked_tolerance + ); return success.report(__func__); } diff --git a/tests/UnitTests/Network/CoSimTests.hpp b/tests/UnitTests/Network/CoSimTests.hpp index 5487b732b7..7bd8b8af06 100644 --- a/tests/UnitTests/Network/CoSimTests.hpp +++ b/tests/UnitTests/Network/CoSimTests.hpp @@ -33,12 +33,13 @@ namespace GridKit static unsigned serial = 0; const auto timestamp = - std::chrono::steady_clock::now().time_since_epoch().count(); + std::chrono::steady_clock::now().time_since_epoch().count(); const auto name = - std::format("gridkit-unit-{}-{}", timestamp, ++serial); + std::format("gridkit-unit-{}-{}", timestamp, ++serial); return std::format( - "ipc://{}", (std::filesystem::temp_directory_path() / name).string()); + "ipc://{}", (std::filesystem::temp_directory_path() / name).string() + ); } public: @@ -48,46 +49,47 @@ namespace GridKit const auto address = endpoint(); auto server = std::async( - std::launch::async, - [&]() -> auto - { - bool outcome = true; - Channel channel(Disposition::SERVER, address, 5000); + std::launch::async, + [&]() -> auto + { + bool outcome = true; + Channel channel(Disposition::SERVER, address, 5000); - for (std::uint64_t session = 1; session <= 2; session++) - { - auto init = channel.receive(); + for (std::uint64_t session = 1; session <= 2; session++) + { + auto init = channel.receive(); - outcome &= init.type == MessageType::INIT; - outcome &= init.session == session; - outcome &= init.signals.at("voltage real") == 1.03; + outcome &= init.type == MessageType::INIT; + outcome &= init.session == session; + outcome &= init.signals.at("voltage real") == 1.03; - init.signals = {{"current from generator", 2.5}}; - init.event_times = {0.025, 0.035}; - channel.send(init); + init.signals = {{"current from generator", 2.5}}; + init.event_times = {0.025, 0.035}; + channel.send(init); - auto step = channel.receive(); + auto step = channel.receive(); - outcome &= step.time == 0.05; - outcome &= step.type == MessageType::STEP; + outcome &= step.time == 0.05; + outcome &= step.type == MessageType::STEP; - channel.send(step); + channel.send(step); - auto end = channel.receive(); + auto end = channel.receive(); - outcome &= end.type == MessageType::END; + outcome &= end.type == MessageType::END; - channel.send(end); - } + channel.send(end); + } - const auto stop = channel.receive(); + const auto stop = channel.receive(); - outcome &= stop.type == MessageType::SHUTDOWN; + outcome &= stop.type == MessageType::SHUTDOWN; - channel.finish(stop); + channel.finish(stop); - return outcome; - }); + return outcome; + } + ); Channel client(Disposition::CLIENT, address, 5000); @@ -131,46 +133,43 @@ namespace GridKit { const auto address = endpoint(); auto server = std::async( - std::launch::async, - [&] + std::launch::async, + [&] + { + Channel channel(Disposition::SERVER, address, 5000); + auto message = channel.receive(); + + switch (kind) { - Channel channel(Disposition::SERVER, address, 5000); - auto message = channel.receive(); - - switch (kind) - { - case 0: - message.type = MessageType::FAIL; - message.error = "solver failure"; - break; - case 1: - message.session++; - break; - case 2: - message.time = 0.1; - break; - case 3: - message.type = MessageType::END; - break; - } - - channel.finish(message); - }); + case 0: + message.type = MessageType::FAIL; + message.error = "solver failure"; + break; + case 1: + message.session++; + break; + case 2: + message.time = 0.1; + break; + case 3: + message.type = MessageType::END; + break; + } + + channel.finish(message); + } + ); Channel client(Disposition::CLIENT, address, 5000); if (kind == 0) { - outcome *= throws( - [&] - { client.exchange(Message()); }); + outcome *= throws([&] { client.exchange(Message()); }); } else { outcome *= - throws( - [&] - { client.exchange(Message()); }); + throws([&] { client.exchange(Message()); }); client.closePeer(Message()); } @@ -193,34 +192,35 @@ namespace GridKit { const auto address = endpoint(); auto server = std::async( - std::launch::async, - [&]() -> auto + std::launch::async, + [&]() -> auto + { + bool outcome = true; + Channel channel(Disposition::SERVER, address, 5000); + + try { - bool outcome = true; - Channel channel(Disposition::SERVER, address, 5000); - - try - { - channel.receive(); - } - catch (const json::exception& _) - { - } - catch (const std::runtime_error& _) - { - } - catch (...) - { - throw; - } - - Message failure(MessageType::FAIL, 0); - failure.error = "malformed request"; - - channel.finish(failure); - - return outcome; - }); + channel.receive(); + } + catch (const json::exception& _) + { + } + catch (const std::runtime_error& _) + { + } + catch (...) + { + throw; + } + + Message failure(MessageType::FAIL, 0); + failure.error = "malformed request"; + + channel.finish(failure); + + return outcome; + } + ); zmq::context_t context; zmq::socket_t socket(context, zmq::socket_type::req); @@ -229,7 +229,7 @@ namespace GridKit socket.connect(address); outcome *= - socket.send(zmq::buffer(wire), zmq::send_flags::none).has_value(); + socket.send(zmq::buffer(wire), zmq::send_flags::none).has_value(); zmq::message_t reply; @@ -241,13 +241,13 @@ namespace GridKit else { outcome *= - reply.to_string().find("malformed request") != std::string::npos; + reply.to_string().find("malformed request") != std::string::npos; const std::string close = - R"({"type":"close","session":0,"time":0,"signals":{}})"; + R"({"type":"close","session":0,"time":0,"signals":{}})"; outcome *= socket.send(zmq::buffer(close), zmq::send_flags::none) - .has_value(); + .has_value(); socket.set(zmq::sockopt::rcvtimeo, 100); @@ -266,22 +266,19 @@ namespace GridKit Channel client(Disposition::CLIENT, endpoint(), 100); - outcome *= throws( - [&] - { client.exchange(Message()); }); + outcome *= + throws([&] { client.exchange(Message()); }); Message invalid; invalid.signals = {{"bad", std::numeric_limits::infinity()}}; Channel other(Disposition::CLIENT, endpoint(), 100); - outcome *= throws( - [&] - { other.send(invalid); }); + outcome *= throws([&] { other.send(invalid); }); outcome *= throws( - [&] - { Channel invalid_channel(Disposition::CLIENT, endpoint(), 0); }); + [&] { Channel invalid_channel(Disposition::CLIENT, endpoint(), 0); } + ); return outcome.report(__func__); } diff --git a/tests/UnitTests/OptimalPowerFlow/ComponentTests.hpp b/tests/UnitTests/OptimalPowerFlow/ComponentTests.hpp index 1a18008e58..2d709c2cd3 100644 --- a/tests/UnitTests/OptimalPowerFlow/ComponentTests.hpp +++ b/tests/UnitTests/OptimalPowerFlow/ComponentTests.hpp @@ -46,7 +46,7 @@ namespace GridKit public: // Branch Hessian rows reach 5.2 eps, and 8.2 eps on x86-64-v4 with ASan. static constexpr RealT kTol = - static_cast(10.0) * std::numeric_limits::epsilon(); + static_cast(10.0) * std::numeric_limits::epsilon(); /// Power into each bus at V1 = 1 and V2 = j, from the admittances by hand TestOutcome branchPower() @@ -407,14 +407,18 @@ namespace GridKit { return success.report(__func__); } - success *= matches(sum(bus.jacobianEntries()), - EntryMap{{{0, 0}, -TWO * SHUNT_G * vr}, - {{0, 1}, -TWO * SHUNT_G * vi}, - {{1, 0}, TWO * SHUNT_B * vr}, - {{1, 1}, TWO * SHUNT_B * vi}, - {{2, 0}, TWO * vr}, - {{2, 1}, TWO * vi}}, - kTol); + success *= matches( + sum(bus.jacobianEntries()), + EntryMap{ + {{0, 0}, -TWO * SHUNT_G * vr}, + {{0, 1}, -TWO * SHUNT_G * vi}, + {{1, 0}, TWO * SHUNT_B * vr}, + {{1, 1}, TWO * SHUNT_B * vi}, + {{2, 0}, TWO * vr}, + {{2, 1}, TWO * vi} + }, + kTol + ); setMultipliers(system, SHUNT_LAMBDA); success *= bus.evaluateHessian(ONE) == 0; @@ -488,14 +492,18 @@ namespace GridKit return success.report(__func__); } // A bus without a shunt contributes nothing to its balance - success *= matches(sum(bus.jacobianEntries()), - EntryMap{{{0, 0}, ZERO}, - {{0, 1}, ZERO}, - {{1, 0}, ZERO}, - {{1, 1}, ZERO}, - {{2, 0}, TWO * vr}, - {{2, 1}, TWO * vi}}, - kTol); + success *= matches( + sum(bus.jacobianEntries()), + EntryMap{ + {{0, 0}, ZERO}, + {{0, 1}, ZERO}, + {{1, 0}, ZERO}, + {{1, 1}, ZERO}, + {{2, 0}, TWO * vr}, + {{2, 1}, TWO * vi} + }, + kTol + ); setMultipliers(system, BUS_LAMBDA); success *= bus.evaluateHessian(ONE) == 0; @@ -651,8 +659,10 @@ namespace GridKit const RealT u = status(in_service); // Derivative of the demand over each voltage component, divided by that component - const std::array slope{u * (zip.Pi / v + TWO * zip.Pz), - u * (zip.Qi / v + TWO * zip.Qz)}; + const std::array slope{ + u * (zip.Pi / v + TWO * zip.Pz), + u * (zip.Qi / v + TWO * zip.Qz) + }; for (IdxT row = 0; row < slope.size(); ++row) { success *= isEqual(actual.at(row), expected.at(row), kTol); @@ -715,12 +725,13 @@ namespace GridKit data.parameters = {{OPF::LoadParameters::P, IdxT{1}}}; success *= OPF::Load(data).verify().passed(); - for (const auto parameter : {OPF::LoadParameters::P, - OPF::LoadParameters::Q, - OPF::LoadParameters::Pi, - OPF::LoadParameters::Qi, - OPF::LoadParameters::Pz, - OPF::LoadParameters::Qz}) + for (const auto parameter : + {OPF::LoadParameters::P, + OPF::LoadParameters::Q, + OPF::LoadParameters::Pi, + OPF::LoadParameters::Qi, + OPF::LoadParameters::Pz, + OPF::LoadParameters::Qz}) { data.parameters = {{parameter, std::numeric_limits::infinity()}}; success *= configurationRejected([&]() @@ -748,10 +759,12 @@ namespace GridKit }; /// Constant power only, constant current, constant impedance, and all three parts - static constexpr std::array ZIP_PARTS{{{0.0, 0.0, 0.0, 0.0}, - {0.5, -0.2, 0.0, 0.0}, - {0.0, 0.0, 0.3, 0.1}, - {0.4, 0.15, 0.25, -0.05}}}; + static constexpr std::array ZIP_PARTS{ + {{0.0, 0.0, 0.0, 0.0}, + {0.5, -0.2, 0.0, 0.0}, + {0.0, 0.0, 0.3, 0.1}, + {0.4, 0.15, 0.25, -0.05}} + }; static constexpr std::array, 3> ZIP_VOLTAGES{{{1.1, 0.0}, {0.8, -0.6}, {1.15, 0.2}}}; static constexpr std::array LOAD_LAMBDA{0.7, -0.4, 0.0}; @@ -760,13 +773,15 @@ namespace GridKit { OPF::LoadData data; data.id = "zip"; - data.parameters = {{OPF::LoadParameters::P, LOAD_P}, - {OPF::LoadParameters::Q, LOAD_Q}, - {OPF::LoadParameters::Pi, zip.Pi}, - {OPF::LoadParameters::Qi, zip.Qi}, - {OPF::LoadParameters::Pz, zip.Pz}, - {OPF::LoadParameters::Qz, zip.Qz}, - {OPF::LoadParameters::in_service, in_service}}; + data.parameters = { + {OPF::LoadParameters::P, LOAD_P}, + {OPF::LoadParameters::Q, LOAD_Q}, + {OPF::LoadParameters::Pi, zip.Pi}, + {OPF::LoadParameters::Qi, zip.Qi}, + {OPF::LoadParameters::Pz, zip.Pz}, + {OPF::LoadParameters::Qz, zip.Qz}, + {OPF::LoadParameters::in_service, in_service} + }; return data; } @@ -784,8 +799,10 @@ namespace GridKit static std::pair loadWeights(bool in_service, const ZipParts& zip) { const RealT u = status(in_service); - return {-u * (LOAD_LAMBDA[0] * zip.Pi + LOAD_LAMBDA[1] * zip.Qi), - -u * (LOAD_LAMBDA[0] * zip.Pz + LOAD_LAMBDA[1] * zip.Qz)}; + return { + -u * (LOAD_LAMBDA[0] * zip.Pi + LOAD_LAMBDA[1] * zip.Qi), + -u * (LOAD_LAMBDA[0] * zip.Pz + LOAD_LAMBDA[1] * zip.Qz) + }; } template @@ -954,11 +971,13 @@ namespace GridKit * * @param[in] admittance - \f$g_{k1}, b_{k1}, g_{k2}, b_{k2}\f$ */ - static void addPowerHessian(EntryMap& hessian, - IdxT k, - const std::array& admittance, - RealT weight_p, - RealT weight_q) + static void addPowerHessian( + EntryMap& hessian, + IdxT k, + const std::array& admittance, + RealT weight_p, + RealT weight_q + ) { for (IdxT m = 0; m < 2; ++m) { diff --git a/tests/UnitTests/OptimalPowerFlow/SystemTestData.hpp b/tests/UnitTests/OptimalPowerFlow/SystemTestData.hpp index f6bd0f8040..ea8b9a77ec 100644 --- a/tests/UnitTests/OptimalPowerFlow/SystemTestData.hpp +++ b/tests/UnitTests/OptimalPowerFlow/SystemTestData.hpp @@ -66,13 +66,15 @@ namespace GridKit return data; } - static void addBranch(OPF::SystemModelData& data, - const char* id, - IdxT bus1, - IdxT bus2, - RealT r, - RealT x, - RealT b) + static void addBranch( + OPF::SystemModelData& data, + const char* id, + IdxT bus1, + IdxT bus2, + RealT r, + RealT x, + RealT b + ) { auto& branch = data.branch.emplace_back(); branch.id = id; diff --git a/tests/UnitTests/OptimalPowerFlow/SystemTests.hpp b/tests/UnitTests/OptimalPowerFlow/SystemTests.hpp index 9032be21e2..ac2d150845 100644 --- a/tests/UnitTests/OptimalPowerFlow/SystemTests.hpp +++ b/tests/UnitTests/OptimalPowerFlow/SystemTests.hpp @@ -45,7 +45,7 @@ namespace GridKit public: // The Jacobian entries reach 13.4 eps against dependency tracking. static constexpr RealT kTol = - static_cast(32.0) * std::numeric_limits::epsilon(); + static_cast(32.0) * std::numeric_limits::epsilon(); /// Balance equalities and magnitude inequalities at every bus, and flow /// inequalities at every branch, unlimited at the unrated ones diff --git a/tests/UnitTests/OptimalPowerFlow/TestHelpers.hpp b/tests/UnitTests/OptimalPowerFlow/TestHelpers.hpp index 2f976ec29c..af0d9903a1 100644 --- a/tests/UnitTests/OptimalPowerFlow/TestHelpers.hpp +++ b/tests/UnitTests/OptimalPowerFlow/TestHelpers.hpp @@ -75,15 +75,25 @@ namespace GridKit inline auto pattern(const OPF::Component::CooBuffer& entries) { return std::pair{ - std::vector(entries.rows.getData(), entries.rows.getData() + entries.nnz), - std::vector(entries.cols.getData(), entries.cols.getData() + entries.nnz)}; + std::vector( + entries.rows.getData(), entries.rows.getData() + entries.nnz + ), + std::vector( + entries.cols.getData(), entries.cols.getData() + entries.nnz + ) + }; } inline auto pattern(LinearAlgebra::CsrMatrix& matrix) { return std::pair{ - std::vector(matrix.getRowData(), matrix.getRowData() + matrix.getNumRows() + 1), - std::vector(matrix.getColData(), matrix.getColData() + matrix.getNnz())}; + std::vector( + matrix.getRowData(), matrix.getRowData() + matrix.getNumRows() + 1 + ), + std::vector( + matrix.getColData(), matrix.getColData() + matrix.getNnz() + ) + }; } inline bool matches(const EntryMap& actual, const EntryMap& expected, double tolerance) diff --git a/tests/UnitTests/PhasorDynamics/BranchTests.hpp b/tests/UnitTests/PhasorDynamics/BranchTests.hpp index eea0903ac0..838cfcdc04 100644 --- a/tests/UnitTests/PhasorDynamics/BranchTests.hpp +++ b/tests/UnitTests/PhasorDynamics/BranchTests.hpp @@ -38,7 +38,9 @@ namespace GridKit auto* bus2 = new PhasorDynamics::Bus(1.0, 0.1); PhasorDynamics::Component* branch = - new PhasorDynamics::Branch(bus1, bus2, PhasorDynamics::BranchData{}); + new PhasorDynamics::Branch( + bus1, bus2, PhasorDynamics::BranchData{} + ); success *= (branch != nullptr); @@ -386,11 +388,14 @@ namespace GridKit const RealT nan = std::numeric_limits::quiet_NaN(); success *= configurationRejected( - [&]() - { - PhasorDynamics::Branch nonfinite_branch(&bus1, &bus2, branchData(nan, 0.1, 0.0, 0.0)); - return nonfinite_branch.verify(); - }); + [&]() + { + PhasorDynamics::Branch nonfinite_branch( + &bus1, &bus2, branchData(nan, 0.1, 0.0, 0.0) + ); + return nonfinite_branch.verify(); + } + ); Log::setVerbosity(previous_verbosity); return success.report(__func__); @@ -456,12 +461,14 @@ namespace GridKit } private: - static PhasorDynamics::BranchData branchData(const RealT R, - const RealT X, - const RealT G, - const RealT B, - const RealT tap = 1.0, - const RealT phase = 0.0) + static PhasorDynamics::BranchData branchData( + const RealT R, + const RealT X, + const RealT G, + const RealT B, + const RealT tap = 1.0, + const RealT phase = 0.0 + ) { using Parameter = PhasorDynamics::BranchParameters; @@ -475,12 +482,15 @@ namespace GridKit return data; } - std::vector analyticalJacobian(const RealT R, - const RealT X, - const RealT G, - const RealT B, - const RealT tap = 1.0, - const RealT phase = 0.0) + std::vector + analyticalJacobian( + const RealT R, + const RealT X, + const RealT G, + const RealT B, + const RealT tap = 1.0, + const RealT phase = 0.0 + ) { const RealT denom = R * R + X * X; const RealT g = R / denom; diff --git a/tests/UnitTests/PhasorDynamics/BusSignalVoltageOutTests.hpp b/tests/UnitTests/PhasorDynamics/BusSignalVoltageOutTests.hpp index 3a70137a8c..f42bf068b6 100644 --- a/tests/UnitTests/PhasorDynamics/BusSignalVoltageOutTests.hpp +++ b/tests/UnitTests/PhasorDynamics/BusSignalVoltageOutTests.hpp @@ -265,9 +265,11 @@ namespace GridKit success *= isEqual(f[1].getValue(), 2.4); VariableT::DependencyMap expected_f0{ - {6, 0.0}, {8, 0.0}, {ir_var_number, 1.0}}; + {6, 0.0}, {8, 0.0}, {ir_var_number, 1.0} + }; VariableT::DependencyMap expected_f1{ - {6, 0.0}, {8, 0.0}, {ii_var_number, 1.0}}; + {6, 0.0}, {8, 0.0}, {ii_var_number, 1.0} + }; success *= isEqual(f[0].getDependencies(), expected_f0); success *= isEqual(f[1].getDependencies(), expected_f1); diff --git a/tests/UnitTests/PhasorDynamics/ComponentConnectionTests.hpp b/tests/UnitTests/PhasorDynamics/ComponentConnectionTests.hpp index 9015d53c5c..e9794b036e 100644 --- a/tests/UnitTests/PhasorDynamics/ComponentConnectionTests.hpp +++ b/tests/UnitTests/PhasorDynamics/ComponentConnectionTests.hpp @@ -56,8 +56,8 @@ namespace GridKit PhasorDynamics::SystemModel system; PhasorDynamics::BusInfinite bus( - static_cast(1.0), - static_cast(0.0)); + static_cast(1.0), static_cast(0.0) + ); PhasorDynamics::SignalNode efd; PhasorDynamics::Genrou machine(&bus, PhasorDynamics::GenrouData{}); @@ -104,8 +104,8 @@ namespace GridKit PhasorDynamics::SystemModel system; PhasorDynamics::BusInfinite bus( - static_cast(1.0), - static_cast(0.0)); + static_cast(1.0), static_cast(0.0) + ); PhasorDynamics::SignalNode pmech; PhasorDynamics::Genrou machine(&bus, PhasorDynamics::GenrouData{}); @@ -150,8 +150,8 @@ namespace GridKit PhasorDynamics::SystemModel system; PhasorDynamics::BusInfinite bus( - static_cast(1.0), - static_cast(0.0)); + static_cast(1.0), static_cast(0.0) + ); PhasorDynamics::SignalNode efd; PhasorDynamics::GenClassicalData machine_data; @@ -198,8 +198,8 @@ namespace GridKit PhasorDynamics::SystemModel system; PhasorDynamics::BusInfinite bus( - static_cast(1.0), - static_cast(0.0)); + static_cast(1.0), static_cast(0.0) + ); PhasorDynamics::SignalNode pmech; PhasorDynamics::GenClassicalData machine_data; @@ -248,8 +248,8 @@ namespace GridKit PhasorDynamics::SystemModel system; PhasorDynamics::BusInfinite bus( - static_cast(1.0), - static_cast(0.0)); + static_cast(1.0), static_cast(0.0) + ); PhasorDynamics::SignalNode ir; PhasorDynamics::SignalNode ii; PhasorDynamics::SignalNode p; @@ -307,12 +307,16 @@ namespace GridKit const auto* state = plant.y().getData(); - success *= isEqual(state[static_cast(PlantInternal::PMEAS)], - static_cast(0.8), - kTol); - success *= isEqual(state[static_cast(PlantInternal::QMEAS)], - static_cast(0.2), - kTol); + success *= isEqual( + state[static_cast(PlantInternal::PMEAS)], + static_cast(0.8), + kTol + ); + success *= isEqual( + state[static_cast(PlantInternal::QMEAS)], + static_cast(0.2), + kTol + ); const auto* residual = plant.getResidual().getData(); for (IdxT row = 0; row < plant.size(); ++row) @@ -336,8 +340,8 @@ namespace GridKit PhasorDynamics::SystemModel system; PhasorDynamics::BusInfinite bus( - static_cast(1.0), - static_cast(0.0)); + static_cast(1.0), static_cast(0.0) + ); PhasorDynamics::SignalNode ipcmd; PhasorDynamics::SignalNode iqcmd; PhasorDynamics::SignalNode pe; @@ -393,10 +397,16 @@ namespace GridKit success *= ipcmd.linked() && iqcmd.linked() && pe.linked() && qgen.linked(); success *= ipcmd.getVariableIndex() == controller.getVariableIndex( - static_cast(PhasorDynamics::Controller::ReecbInternalVariables::IPCMD)); + static_cast( + PhasorDynamics::Controller::ReecbInternalVariables::IPCMD + ) + ); success *= iqcmd.getVariableIndex() == controller.getVariableIndex( - static_cast(PhasorDynamics::Controller::ReecbInternalVariables::IQCMD)); + static_cast( + PhasorDynamics::Controller::ReecbInternalVariables::IQCMD + ) + ); success *= system.initialize() == 0; success *= system.evaluateResidual() == 0; @@ -433,11 +443,11 @@ namespace GridKit { using namespace PhasorDynamics; - return checkConnection, - GenrouInternalVariables::OMEGA, - GenrouSignalOutputs::speed, - GenrouSignalInputs::pmech>(makeGenrouGastPtiCase(), - __func__); + return checkConnection< + Genrou, + GenrouInternalVariables::OMEGA, + GenrouSignalOutputs::speed, + GenrouSignalInputs::pmech>(makeGenrouGastPtiCase(), __func__); } /// Check production GASTPTI signal wiring to GENSAL. @@ -445,11 +455,11 @@ namespace GridKit { using namespace PhasorDynamics; - return checkConnection, - GensalInternalVariables::OMEGA, - GensalSignalOutputs::speed, - GensalSignalInputs::pmech>(makeGensalGastPtiCase(), - __func__); + return checkConnection< + Gensal, + GensalInternalVariables::OMEGA, + GensalSignalOutputs::speed, + GensalSignalInputs::pmech>(makeGensalGastPtiCase(), __func__); } /// Check production GASTPTI signal wiring to GenClassical. @@ -457,11 +467,13 @@ namespace GridKit { using namespace PhasorDynamics; - return checkConnection, - GenClassicalInternalVariables::OMEGA, - GenClassicalSignalOutputs::speed, - GenClassicalSignalInputs::pmech>(makeGenClassicalGastPtiCase(), - __func__); + return checkConnection< + GenClassical, + GenClassicalInternalVariables::OMEGA, + GenClassicalSignalOutputs::speed, + GenClassicalSignalInputs::pmech>( + makeGenClassicalGastPtiCase(), __func__ + ); } private: @@ -482,11 +494,14 @@ namespace GridKit static constexpr RealT kInitialActivePower = static_cast(0.4); static constexpr RealT kInitialReactivePower = static_cast(0.05); - template - TestOutcome checkConnection(const SystemDataT& data, const char* test_name) + template < + typename MachineT, + auto speed_state_variable, + auto speed_port_variable, + auto pmech_port_variable> + TestOutcome checkConnection( + const SystemDataT& data, const char* test_name + ) { using namespace PhasorDynamics::Governor; @@ -519,11 +534,14 @@ namespace GridKit auto& governor_ports = governor->getPorts(); const bool ports_connected = - machine_ports.out.template port().connected() - && machine_ports.in.template port().connected() - && governor_ports.in.template port().connected() - && governor_ports.in.template port().connected() - && governor_ports.out.template port().connected(); + machine_ports.out.template port().connected() + && machine_ports.in.template port().connected() + && governor_ports.in.template port() + .connected() + && governor_ports.in.template port() + .connected() + && governor_ports.out.template port() + .connected(); success *= ports_connected; if (!ports_connected) { @@ -537,18 +555,21 @@ namespace GridKit success *= speed_index != pmech_index; success *= speed_index == machine->getVariableIndex(static_cast(speed_state_variable)); - success *= speed_index - == governor_ports.in.template port() - .signalVariableIndex(); + success *= + speed_index + == governor_ports.in.template port() + .signalVariableIndex(); success *= pmech_index == machine_ports.in.template port() - .signalVariableIndex(); + .signalVariableIndex(); success *= pmech_index == governor->getVariableIndex( - static_cast(GastPtiInternalVariables::PMECH)); - success *= pref_index - == governor_ports.in.template port() - .signalVariableIndex(); + static_cast(GastPtiInternalVariables::PMECH) + ); + success *= + pref_index + == governor_ports.in.template port() + .signalVariableIndex(); return success.report(test_name); } @@ -567,9 +588,11 @@ namespace GridKit bus.Vr0 = ONE; bus.Vi0 = ZERO; - data.signal = {{"Machine Speed Deviation", kSpeedSignalId}, - {"Mechanical Power", kPmechSignalId}, - {"Active Power Reference", kPrefSignalId}}; + data.signal = { + {"Machine Speed Deviation", kSpeedSignalId}, + {"Mechanical Power", kPmechSignalId}, + {"Active Power Reference", kPrefSignalId} + }; auto& governor = data.gastpti.emplace_back(); governor.signal_inputs[GastPtiSignalInputs::speed] = kSpeedSignalId; diff --git a/tests/UnitTests/PhasorDynamics/ControllerReecbTests.hpp b/tests/UnitTests/PhasorDynamics/ControllerReecbTests.hpp index 1537626e05..a4611187e6 100644 --- a/tests/UnitTests/PhasorDynamics/ControllerReecbTests.hpp +++ b/tests/UnitTests/PhasorDynamics/ControllerReecbTests.hpp @@ -42,7 +42,7 @@ namespace GridKit ~ControllerReecbTests() = default; static constexpr RealT kTol = - static_cast(100.0) * std::numeric_limits::epsilon(); + static_cast(100.0) * std::numeric_limits::epsilon(); /// Validate construction, row layout, defaults, parameters, buses, /// signal links, and the time-constant floor. @@ -61,28 +61,11 @@ namespace GridKit success *= (empty.size() == static_cast(Utilities::enum_size())); const std::array()> row_order{{ - Vars::VMEAS, - Vars::PMEAS, - Vars::XPIQ, - Vars::XPIV, - Vars::QV, - Vars::PORD, - Vars::VT, - Vars::VSAFE, - Vars::SDIP, - Vars::IQV, - Vars::QREF, - Vars::EQ, - Vars::VPIQ, - Vars::EPIV, - Vars::RPORD, - Vars::ILCAP, - Vars::IQMAX, - Vars::IPMAX, - Vars::IQBASE, - Vars::IQRAW, - Vars::IQCMD, - Vars::IPCMD, + Vars::VMEAS, Vars::PMEAS, Vars::XPIQ, Vars::XPIV, Vars::QV, + Vars::PORD, Vars::VT, Vars::VSAFE, Vars::SDIP, Vars::IQV, + Vars::QREF, Vars::EQ, Vars::VPIQ, Vars::EPIV, Vars::RPORD, + Vars::ILCAP, Vars::IQMAX, Vars::IPMAX, Vars::IQBASE, Vars::IQRAW, + Vars::IQCMD, Vars::IPCMD, }}; for (size_t row = 0; row < row_order.size(); ++row) { @@ -96,8 +79,9 @@ namespace GridKit success *= (configured.reecb.initialize() != 0); success *= (configured.reecb.allocate() == 0); success *= (configured.reecb.tagDifferentiable() == 0); - success *= (static_cast(configured.reecb.getResidual().getSize()) - == Utilities::enum_size()); + success *= + (static_cast(configured.reecb.getResidual().getSize()) + == Utilities::enum_size()); for (size_t row = 0; row < Utilities::enum_size(); ++row) { @@ -129,32 +113,13 @@ namespace GridKit const RealT nan = std::numeric_limits::quiet_NaN(); const RealT infinity = std::numeric_limits::infinity(); const std::array real_parameters{{ - Params::mva, - Params::Trv, - Params::Tp, - Params::Vref0, - Params::Vdip, - Params::Vup, - Params::dbd1, - Params::dbd2, - Params::kqv, - Params::Iql1, - Params::Iqh1, - Params::Qmax, - Params::Qmin, - Params::Kqp, - Params::Kqi, - Params::Vmax, - Params::Vmin, - Params::Kvp, - Params::Kvi, - Params::Tiq, - Params::Tpord, - Params::dPmax, - Params::dPmin, - Params::Pmax, - Params::Pmin, - Params::Imax, + Params::mva, Params::Trv, Params::Tp, Params::Vref0, + Params::Vdip, Params::Vup, Params::dbd1, Params::dbd2, + Params::kqv, Params::Iql1, Params::Iqh1, Params::Qmax, + Params::Qmin, Params::Kqp, Params::Kqi, Params::Vmax, + Params::Vmin, Params::Kvp, Params::Kvi, Params::Tiq, + Params::Tpord, Params::dPmax, Params::dPmin, Params::Pmax, + Params::Pmin, Params::Imax, }}; for (const Params parameter : real_parameters) { @@ -177,11 +142,11 @@ namespace GridKit success *= invalidParameterCase(Params::Imax, 0.0); const std::array nonnegative_gains{{ - Params::kqv, - Params::Kqp, - Params::Kqi, - Params::Kvp, - Params::Kvi, + Params::kqv, + Params::Kqp, + Params::Kqi, + Params::Kvp, + Params::Kvi, }}; for (const Params gain : nonnegative_gains) { @@ -189,23 +154,23 @@ namespace GridKit } const std::array flag_parameters{{ - Params::PfFlag, - Params::VFlag, - Params::QFlag, - Params::Pqflag, + Params::PfFlag, + Params::VFlag, + Params::QFlag, + Params::Pqflag, }}; const std::array valid_flag_values{{false, true}}; const std::array invalid_integral_flag_values{{ - static_cast(0), - static_cast(1), - static_cast(2), + static_cast(0), + static_cast(1), + static_cast(2), }}; const std::array invalid_real_flag_values{{ - static_cast(0.0), - static_cast(0.5), - static_cast(1.0), - nan, - infinity, + static_cast(0.0), + static_cast(0.5), + static_cast(1.0), + nan, + infinity, }}; for (const Params flag : flag_parameters) { @@ -253,28 +218,32 @@ namespace GridKit // and saturates the active-power ramp limiter. setState(floored.reecb, {{Vars::VMEAS, 0.5}}); success *= (floored.evaluate() == 0); - success *= residualsMatch(floored.reecb, - {{Vars::VMEAS, 500.0}}, - "floored voltage filter"); - - setState(floored.reecb, - {{Vars::VMEAS, 1.0}, - {Vars::PMEAS, 1.0}, - {Vars::QV, 1.0}, - {Vars::PORD, 1.0}}); + success *= residualsMatch( + floored.reecb, {{Vars::VMEAS, 500.0}}, "floored voltage filter" + ); + + setState( + floored.reecb, + {{Vars::VMEAS, 1.0}, + {Vars::PMEAS, 1.0}, + {Vars::QV, 1.0}, + {Vars::PORD, 1.0}} + ); success *= (floored.evaluate() == 0); - success *= residualsMatch(floored.reecb, - {{Vars::PMEAS, 500.0}, - {Vars::QV, 500.0}, - {Vars::RPORD, 1.0}}, - "floored time constants"); + success *= residualsMatch( + floored.reecb, + {{Vars::PMEAS, 500.0}, {Vars::QV, 500.0}, {Vars::RPORD, 1.0}}, + "floored time constants" + ); // The algebraic slew row supplies the differential order row. setState(floored.reecb, {{Vars::RPORD, 1.0}}); success *= (floored.evaluate() == 0); - success *= residualsMatch(floored.reecb, - {{Vars::PORD, 1.0}, {Vars::RPORD, 0.0}}, - "floored active-power order rate"); + success *= residualsMatch( + floored.reecb, + {{Vars::PORD, 1.0}, {Vars::RPORD, 0.0}}, + "floored active-power order rate" + ); Log::setVerbosity(previous_verbosity); return success.report(__func__); @@ -293,37 +262,30 @@ namespace GridKit success *= fixture.initialize(kInitialIqcmd, kInitialIpcmd); success *= (fixture.evaluate() == 0); - success *= stateMatches(fixture.reecb, - {{Vars::VMEAS, 1.0}, - {Vars::PMEAS, 1.5}, - {Vars::XPIQ, 0.0}, - {Vars::XPIV, 0.0}, - {Vars::QV, 1.5}, - {Vars::PORD, 1.5}, - {Vars::VT, 1.0}, - {Vars::VSAFE, 1.0}, - {Vars::SDIP, 1.0}, - {Vars::IQV, 0.0}, - {Vars::QREF, 1.5}, - {Vars::EQ, 0.0}, - {Vars::VPIQ, 0.5}, - {Vars::EPIV, 0.0}, - {Vars::RPORD, 0.0}, - {Vars::IPMAX, 2.5}, - {Vars::IQBASE, 0.0}, - {Vars::IQRAW, 1.5}, - {Vars::IQCMD, 0.75}, - {Vars::IPCMD, 0.75}}, - "initialization"); - success *= stateMatches(fixture.reecb, - {{Vars::ILCAP, 2.0}}, - "initial current-circle capacity", - kCircleTol); + success *= stateMatches( + fixture.reecb, + {{Vars::VMEAS, 1.0}, {Vars::PMEAS, 1.5}, {Vars::XPIQ, 0.0}, + {Vars::XPIV, 0.0}, {Vars::QV, 1.5}, {Vars::PORD, 1.5}, + {Vars::VT, 1.0}, {Vars::VSAFE, 1.0}, {Vars::SDIP, 1.0}, + {Vars::IQV, 0.0}, {Vars::QREF, 1.5}, {Vars::EQ, 0.0}, + {Vars::VPIQ, 0.5}, {Vars::EPIV, 0.0}, {Vars::RPORD, 0.0}, + {Vars::IPMAX, 2.5}, {Vars::IQBASE, 0.0}, {Vars::IQRAW, 1.5}, + {Vars::IQCMD, 0.75}, {Vars::IPCMD, 0.75}}, + "initialization" + ); + success *= stateMatches( + fixture.reecb, + {{Vars::ILCAP, 2.0}}, + "initial current-circle capacity", + kCircleTol + ); const auto* initial_values = fixture.reecb.y().getData(); - success *= scalarMatches(initial_values[index(Vars::IQMAX)], - initial_values[index(Vars::ILCAP)], - "initial reactive-current limit"); + success *= scalarMatches( + initial_values[index(Vars::IQMAX)], + initial_values[index(Vars::ILCAP)], + "initial reactive-current limit" + ); success *= scalarPreserved(fixture.iqcmd(), kInitialIqcmd, "preserved iqcmd"); success *= scalarPreserved(fixture.ipcmd(), kInitialIpcmd, "preserved ipcmd"); @@ -334,9 +296,11 @@ namespace GridKit success *= scalarMatches(fixture.input(Ext::pref), 0.75, "published pref"); success *= allResidualsWithinInitTolerance(fixture.reecb); - success *= monitorMatches(fixture.reecb, - {{kInitialIqcmd, kInitialIpcmd, 1.0, 1.5}}, - "initialization"); + success *= monitorMatches( + fixture.reecb, + {{kInitialIqcmd, kInitialIpcmd, 1.0, 1.5}}, + "initialization" + ); constexpr RealT absolute_tolerance = 2.5e-7; success *= (fixture.reecb.setAbsoluteTolerance(absolute_tolerance) == 0); @@ -372,7 +336,11 @@ namespace GridKit success *= initializationRejectedAtomically(data, 0.75, -0.1, "negative active-current command"); success *= initializationRejectedAtomically(data, 0.75, std::numeric_limits::infinity(), "nonfinite active-current command"); success *= initializationRejectedAtomically( - data, std::numeric_limits::infinity(), 0.75, "nonfinite reactive-current command"); + data, + std::numeric_limits::infinity(), + 0.75, + "nonfinite reactive-current command" + ); auto pord_above = data; pord_above.parameters[Params::Pmax] = 1.0; @@ -432,8 +400,8 @@ namespace GridKit }; const std::array voltage_limits{{ - {0.3, 0.3, 0.3}, - {1.6, 0.96, 0.8}, + {0.3, 0.3, 0.3}, + {1.6, 0.96, 0.8}, }}; for (const auto& test_case : voltage_limits) { @@ -467,11 +435,23 @@ namespace GridKit success *= (late.evaluate() == 0); success *= residualsMatch(late.reecb, {{Vars::PORD, 0.0}}, "rejected Pmax adjustment"); success *= initializationRejectedAtomically( - power_factor, 0.75, 0.75, "unrepresentable power-factor reference", 1.0e-8, 0.75); + power_factor, + 0.75, + 0.75, + "unrepresentable power-factor reference", + 1.0e-8, + 0.75 + ); success *= initializationRejectedAtomically(data, 0.75, 0.75, "zero terminal voltage", 0.75, 0.75, 0.0); success *= initializationRejectedAtomically( - data, 0.75, 0.75, "nonfinite active-power feedback", std::numeric_limits::infinity(), 0.75); + data, + 0.75, + 0.75, + "nonfinite active-power feedback", + std::numeric_limits::infinity(), + 0.75 + ); // Collapsed limits remain pinned at their initial output or expand to // include it. @@ -571,9 +551,9 @@ namespace GridKit }; const std::array active_cases{{ - {1.0e-6, "near the lower active-current limit"}, - {0.75, "interior active-current command"}, - {1.25 - 1.0e-6, "near the upper active-current limit"}, + {1.0e-6, "near the lower active-current limit"}, + {0.75, "interior active-current command"}, + {1.25 - 1.0e-6, "near the upper active-current limit"}, }}; // The recovered order limits are widened so the reconstruction, not @@ -595,9 +575,9 @@ namespace GridKit Fixture interior(makeData()); success *= interior.initialize(0.0, 0.75); success *= (interior.evaluate() == 0); - success *= stateMatches(interior.reecb, - {{Vars::PORD, 1.5}}, - "interior active-power order"); + success *= stateMatches( + interior.reecb, {{Vars::PORD, 1.5}}, "interior active-power order" + ); // A command whose recovered order lands exactly on the order limit is // admitted rather than rejected. @@ -617,8 +597,8 @@ namespace GridKit }; const std::array asymmetric_slews{{ - {-0.001, 0.1, "narrow negative ramp limit"}, - {-0.1, 0.001, "narrow positive ramp limit"}, + {-0.001, 0.1, "narrow negative ramp limit"}, + {-0.1, 0.001, "narrow positive ramp limit"}, }}; for (const auto& test_case : asymmetric_slews) @@ -631,19 +611,18 @@ namespace GridKit asymmetric.attachAllInputs(); success *= asymmetric.initialize(0.0, 0.75); success *= (asymmetric.evaluate() == 0); - success *= stateMatches(asymmetric.reecb, - {{Vars::PORD, 1.5}}, - test_case.label); + success *= stateMatches( + asymmetric.reecb, {{Vars::PORD, 1.5}}, test_case.label + ); success *= allResidualsWithinInitTolerance(asymmetric.reecb); - success *= scalarMatches(asymmetric.input(Ext::pref), - 0.75, - test_case.label); + success *= + scalarMatches(asymmetric.input(Ext::pref), 0.75, test_case.label); } // The reactive command shares the inverse, at both signs. const std::array reactive_commands{{ - static_cast(1.0 - 1.0e-6), - static_cast(-1.0 + 1.0e-6), + static_cast(1.0 - 1.0e-6), + static_cast(-1.0 + 1.0e-6), }}; for (const RealT iqcmd : reactive_commands) { @@ -664,13 +643,13 @@ namespace GridKit }; const std::array boundary_cases{{ - {true, 0.75, 0.0, 2.5, "zero active-current command"}, - {true, 0.0, 1.25, 0.0, "zero reactive-current capacity"}, - {true, 1.0, 0.75, 2.0, "upper reactive-current command"}, - {true, -1.0, 0.75, 2.0, "lower reactive-current command"}, - {false, 0.75, 1.0, 2.0, "upper active-current command"}, - {false, 1.25, 0.0, 0.0, "zero active-current capacity"}, - {true, 0.75, 1.5, 1.5, "expanded current circle"}, + {true, 0.75, 0.0, 2.5, "zero active-current command"}, + {true, 0.0, 1.25, 0.0, "zero reactive-current capacity"}, + {true, 1.0, 0.75, 2.0, "upper reactive-current command"}, + {true, -1.0, 0.75, 2.0, "lower reactive-current command"}, + {false, 0.75, 1.0, 2.0, "upper active-current command"}, + {false, 1.25, 0.0, 0.0, "zero active-current capacity"}, + {true, 0.75, 1.5, 1.5, "expanded current circle"}, }}; for (const auto& test_case : boundary_cases) { @@ -681,10 +660,12 @@ namespace GridKit success *= (boundary.evaluate() == 0); success *= scalarPreserved(boundary.iqcmd(), test_case.iqcmd, test_case.label); success *= scalarPreserved(boundary.ipcmd(), test_case.ipcmd, test_case.label); - success *= stateMatches(boundary.reecb, - {{Vars::ILCAP, test_case.capacity}}, - test_case.label, - kCircleTol); + success *= stateMatches( + boundary.reecb, + {{Vars::ILCAP, test_case.capacity}}, + test_case.label, + kCircleTol + ); success *= allResidualsWithinInitTolerance(boundary.reecb); } @@ -704,8 +685,8 @@ namespace GridKit capacity_data.parameters[Params::Imax] = 0.1; const std::array, 2> capacity_cases{{ - {1.7, 0.3}, - {1.5, 0.5}, + {1.7, 0.3}, + {1.5, 0.5}, }}; for (const auto& [iqcmd, ipcmd] : capacity_cases) { @@ -720,9 +701,8 @@ namespace GridKit std::cout << "REECB low-priority capacity does not include its initial command\n"; success = false; } - success *= scalarMatches(ilcap, - iqcmd, - "minimal low-priority capacity"); + success *= + scalarMatches(ilcap, iqcmd, "minimal low-priority capacity"); success *= allResidualsWithinInitTolerance(capacity_fixture.reecb); } @@ -755,10 +735,12 @@ namespace GridKit success *= (exhausted.evaluate() == 0); success *= scalarPreserved(exhausted.iqcmd(), 0.0, "exhausted reactive-current capacity"); - success *= stateMatches(exhausted.reecb, - {{Vars::ILCAP, 0.0}}, - "injection does not expand current circle", - kCircleTol); + success *= stateMatches( + exhausted.reecb, + {{Vars::ILCAP, 0.0}}, + "injection does not expand current circle", + kCircleTol + ); success *= allResidualsWithinInitTolerance(exhausted.reecb); Log::setVerbosity(previous_verbosity); @@ -778,33 +760,24 @@ namespace GridKit success *= (fixture.evaluate() == 0); const RealT ideal_circle_leg = circleLeg(1.76); - const std::array()> expected_residuals{{ - {Vars::VMEAS, 0.99}, - {Vars::PMEAS, 0.145}, - {Vars::XPIQ, 0.21}, - {Vars::XPIV, 0.13}, - {Vars::QV, -0.05}, - {Vars::PORD, 0.26}, - {Vars::VT, -0.03}, - {Vars::VSAFE, 0.0}, - {Vars::SDIP, 0.0}, - {Vars::IQV, 0.0}, - {Vars::QREF, 0.0}, - {Vars::EQ, 0.0}, - {Vars::VPIQ, 0.0}, - {Vars::EPIV, 0.0}, - {Vars::RPORD, 0.0}, - {Vars::ILCAP, ideal_circle_leg - 1.20}, - {Vars::IQMAX, 0.0}, - {Vars::IPMAX, 0.0}, - {Vars::IQBASE, 0.0}, - {Vars::IQRAW, 0.0}, - {Vars::IQCMD, 0.19}, - {Vars::IPCMD, 0.05}, - }}; + const std::array()> + expected_residuals{{ + {Vars::VMEAS, 0.99}, {Vars::PMEAS, 0.145}, + {Vars::XPIQ, 0.21}, {Vars::XPIV, 0.13}, + {Vars::QV, -0.05}, {Vars::PORD, 0.26}, + {Vars::VT, -0.03}, {Vars::VSAFE, 0.0}, + {Vars::SDIP, 0.0}, {Vars::IQV, 0.0}, + {Vars::QREF, 0.0}, {Vars::EQ, 0.0}, + {Vars::VPIQ, 0.0}, {Vars::EPIV, 0.0}, + {Vars::RPORD, 0.0}, {Vars::ILCAP, ideal_circle_leg - 1.20}, + {Vars::IQMAX, 0.0}, {Vars::IPMAX, 0.0}, + {Vars::IQBASE, 0.0}, {Vars::IQRAW, 0.0}, + {Vars::IQCMD, 0.19}, {Vars::IPCMD, 0.05}, + }}; - success *= (static_cast(fixture.reecb.getResidual().getSize()) - == expected_residuals.size()); + success *= + (static_cast(fixture.reecb.getResidual().getSize()) + == expected_residuals.size()); for (size_t row = 0; row < expected_residuals.size(); ++row) { if (index(expected_residuals[row].variable) != row) @@ -823,12 +796,14 @@ namespace GridKit tolerance = kCircleTol; } - success *= variableMatches(residuals[index(variable)], - expected, - "residual", - variable, - "hand-computable state", - tolerance); + success *= variableMatches( + residuals[index(variable)], + expected, + "residual", + variable, + "hand-computable state", + tolerance + ); } return success.report(__func__); @@ -885,10 +860,12 @@ namespace GridKit success *= allResidualsWithinInitTolerance(fixture.reecb); success *= scalarPreserved(fixture.iqcmd(), 0.75, "selector iqcmd"); success *= scalarPreserved(fixture.ipcmd(), 0.75, "selector ipcmd"); - success *= stateMatches(fixture.reecb, - {{Vars::ILCAP, 2.0}}, - "selector ILCAP", - kCircleTol); + success *= stateMatches( + fixture.reecb, + {{Vars::ILCAP, 2.0}}, + "selector ILCAP", + kCircleTol + ); // Exactly one reactive path carries the operating point. const auto* y = fixture.reecb.y().getData(); @@ -963,22 +940,24 @@ namespace GridKit // voltage error without power-base conversion. fixture.input(Ext::qext) = 1.2; success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::EPIV, 0.2}}, - "unconverted voltage reference"); + success *= residualsMatch( + fixture.reecb, {{Vars::EPIV, 0.2}}, "unconverted voltage reference" + ); // A reference beyond Vmax is limited. fixture.input(Ext::qext) = 2.0; success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::EPIV, 0.5}}, - "limited voltage reference"); + success *= residualsMatch( + fixture.reecb, {{Vars::EPIV, 0.5}}, "limited voltage reference" + ); setState(fixture.reecb, {{Vars::EPIV, 0.2}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::XPIV, 0.1}}, - "unconverted voltage-reference rate"); + success *= residualsMatch( + fixture.reecb, + {{Vars::XPIV, 0.1}}, + "unconverted voltage-reference rate" + ); } { @@ -993,15 +972,17 @@ namespace GridKit // converted value drives the current-command lag. fixture.input(Ext::qext) = 0.85; success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::QREF, 0.2}}, - "converted reactive reference"); + success *= residualsMatch( + fixture.reecb, {{Vars::QREF, 0.2}}, "converted reactive reference" + ); setState(fixture.reecb, {{Vars::QREF, 1.7}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::QV, 10.0}}, - "converted reactive-reference rate"); + success *= residualsMatch( + fixture.reecb, + {{Vars::QV, 10.0}}, + "converted reactive-reference rate" + ); } return success.report(__func__); @@ -1025,9 +1006,9 @@ namespace GridKit setControlState(fixture.reecb); setState(fixture.reecb, {{Vars::QV, 0.1}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::QREF, 0.8}}, - "constant-reactive reference"); + success *= residualsMatch( + fixture.reecb, {{Vars::QREF, 0.8}}, "constant-reactive reference" + ); setState(fixture.reecb, {{Vars::QREF, 0.8}}); success *= (fixture.evaluate() == 0); @@ -1035,9 +1016,11 @@ namespace GridKit setState(fixture.reecb, {{Vars::VT, 0.0}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::SDIP, -1.0}}, - "constant-reactive voltage gate"); + success *= residualsMatch( + fixture.reecb, + {{Vars::SDIP, -1.0}}, + "constant-reactive voltage gate" + ); setState(fixture.reecb, {{Vars::SDIP, 0.0}}); success *= (fixture.evaluate() == 0); @@ -1058,27 +1041,31 @@ namespace GridKit setControlState(fixture.reecb); setState(fixture.reecb, {{Vars::XPIQ, 0.82}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::QREF, 0.2}}, - "cascaded reactive-power reference"); + success *= residualsMatch( + fixture.reecb, + {{Vars::QREF, 0.2}}, + "cascaded reactive-power reference" + ); setState(fixture.reecb, {{Vars::QREF, 0.2}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::EQ, 0.3}}, - "cascaded reactive-power error"); + success *= residualsMatch( + fixture.reecb, {{Vars::EQ, 0.3}}, "cascaded reactive-power error" + ); setState(fixture.reecb, {{Vars::EQ, 0.3}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::XPIQ, 0.12}, {Vars::QV, 0.0}}, - "reactive-power integral rate"); + success *= residualsMatch( + fixture.reecb, + {{Vars::XPIQ, 0.12}, {Vars::QV, 0.0}}, + "reactive-power integral rate" + ); setState(fixture.reecb, {{Vars::VT, 0.0}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::SDIP, -1.0}}, - "reactive-power voltage gate"); + success *= residualsMatch( + fixture.reecb, {{Vars::SDIP, -1.0}}, "reactive-power voltage gate" + ); setState(fixture.reecb, {{Vars::SDIP, 0.0}}); success *= (fixture.evaluate() == 0); @@ -1097,21 +1084,23 @@ namespace GridKit success *= fixture.prepare(0.0, 0.2); setControlState(fixture.reecb); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::EPIV, 0.05}}, - "direct-voltage error"); + success *= residualsMatch( + fixture.reecb, {{Vars::EPIV, 0.05}}, "direct-voltage error" + ); setState(fixture.reecb, {{Vars::EPIV, 0.05}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::XPIQ, 0.0}, {Vars::XPIV, 0.025}}, - "voltage-control integral rate"); + success *= residualsMatch( + fixture.reecb, + {{Vars::XPIQ, 0.0}, {Vars::XPIV, 0.025}}, + "voltage-control integral rate" + ); setState(fixture.reecb, {{Vars::VT, 2.0}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::SDIP, -1.0}}, - "voltage-control voltage gate"); + success *= residualsMatch( + fixture.reecb, {{Vars::SDIP, -1.0}}, "voltage-control voltage gate" + ); setState(fixture.reecb, {{Vars::SDIP, 0.0}}); success *= (fixture.evaluate() == 0); @@ -1134,9 +1123,9 @@ namespace GridKit }; const std::array reference_cases{{ - {-0.6, -0.7, -0.28}, - {0.05, 0.1, 0.04}, - {0.6, 0.8, 0.32}, + {-0.6, -0.7, -0.28}, + {0.05, 0.1, 0.04}, + {0.6, 0.8, 0.32}, }}; for (const auto& test_case : reference_cases) { @@ -1145,18 +1134,24 @@ namespace GridKit fixture.input(Ext::qext) = test_case.input; success *= fixture.prepare(0.0, 0.2); setControlState(fixture.reecb); - setState(fixture.reecb, - {{Vars::XPIQ, 1.0}, {Vars::QREF, 2.0 * test_case.input}}); + setState( + fixture.reecb, + {{Vars::XPIQ, 1.0}, {Vars::QREF, 2.0 * test_case.input}} + ); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::EQ, test_case.limited_error}}, - "reactive-power reference limit"); + success *= residualsMatch( + fixture.reecb, + {{Vars::EQ, test_case.limited_error}}, + "reactive-power reference limit" + ); setState(fixture.reecb, {{Vars::EQ, test_case.limited_error}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::XPIQ, test_case.expected_rate}}, - "reactive-power limited-error rate"); + success *= residualsMatch( + fixture.reecb, + {{Vars::XPIQ, test_case.expected_rate}}, + "reactive-power limited-error rate" + ); } } @@ -1172,11 +1167,11 @@ namespace GridKit data.parameters[Params::Qmax] = 3.0; const std::array antiwindup_cases{{ - {2.2, 1.0, 0.0}, - {2.2, -1.0, -0.8}, - {-0.2, -1.0, 0.0}, - {-0.2, 1.0, 0.8}, - {1.0, 1.0, 0.8}, + {2.2, 1.0, 0.0}, + {2.2, -1.0, -0.8}, + {-0.2, -1.0, 0.0}, + {-0.2, 1.0, 0.8}, + {1.0, 1.0, 0.8}, }}; for (const auto& test_case : antiwindup_cases) { @@ -1185,14 +1180,18 @@ namespace GridKit fixture.input(Ext::qext) = test_case.reference; success *= fixture.prepare(0.0, 0.2); setControlState(fixture.reecb); - setState(fixture.reecb, - {{Vars::XPIQ, test_case.state}, - {Vars::QREF, 2.0 * test_case.reference}, - {Vars::EQ, 2.0 * test_case.reference}}); + setState( + fixture.reecb, + {{Vars::XPIQ, test_case.state}, + {Vars::QREF, 2.0 * test_case.reference}, + {Vars::EQ, 2.0 * test_case.reference}} + ); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::XPIQ, test_case.expected}}, - "reactive-power antiwindup"); + success *= residualsMatch( + fixture.reecb, + {{Vars::XPIQ, test_case.expected}}, + "reactive-power antiwindup" + ); } } @@ -1207,11 +1206,11 @@ namespace GridKit data.parameters[Params::Kvi] = 1.0; const std::array antiwindup_cases{{ - {1.0, 1.6, 0.0}, - {1.0, 0.4, -0.6}, - {-1.0, 0.4, 0.0}, - {-1.0, 1.6, 0.6}, - {0.0, 1.6, 0.6}, + {1.0, 1.6, 0.0}, + {1.0, 0.4, -0.6}, + {-1.0, 0.4, 0.0}, + {-1.0, 1.6, 0.6}, + {0.0, 1.6, 0.6}, }}; for (const auto& test_case : antiwindup_cases) { @@ -1220,15 +1219,19 @@ namespace GridKit fixture.input(Ext::qext) = test_case.reference; success *= fixture.prepare(0.0, 0.2); setControlState(fixture.reecb); - setState(fixture.reecb, - {{Vars::XPIV, test_case.state}, - {Vars::EPIV, test_case.reference - 1.0}, - {Vars::ILCAP, 0.5}, - {Vars::IQMAX, 0.5}}); + setState( + fixture.reecb, + {{Vars::XPIV, test_case.state}, + {Vars::EPIV, test_case.reference - 1.0}, + {Vars::ILCAP, 0.5}, + {Vars::IQMAX, 0.5}} + ); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::XPIV, test_case.expected}}, - "voltage-control antiwindup"); + success *= residualsMatch( + fixture.reecb, + {{Vars::XPIV, test_case.expected}}, + "voltage-control antiwindup" + ); } } @@ -1245,40 +1248,48 @@ namespace GridKit data.parameters[Params::Vref0] = 3.0; const std::array injection_cases{{ - {5.5, -1.2}, - {4.2, -0.6}, - {3.0, 0.0}, - {1.8, 0.6}, - {0.4, 1.5}, + {5.5, -1.2}, + {4.2, -0.6}, + {3.0, 0.0}, + {1.8, 0.6}, + {0.4, 1.5}, }}; for (const auto& test_case : injection_cases) { Fixture fixture(data); success *= fixture.prepare(0.0, 0.2); setControlState(fixture.reecb); - setState(fixture.reecb, - {{Vars::VMEAS, test_case.input}, - {Vars::IQV, 0.0}, - {Vars::IQRAW, 0.0}, - {Vars::IQCMD, 0.0}, - {Vars::ILCAP, 3.0}, - {Vars::IQMAX, 3.0}}); + setState( + fixture.reecb, + {{Vars::VMEAS, test_case.input}, + {Vars::IQV, 0.0}, + {Vars::IQRAW, 0.0}, + {Vars::IQCMD, 0.0}, + {Vars::ILCAP, 3.0}, + {Vars::IQMAX, 3.0}} + ); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::IQV, test_case.expected}}, - "reactive-current injection curve"); + success *= residualsMatch( + fixture.reecb, + {{Vars::IQV, test_case.expected}}, + "reactive-current injection curve" + ); setState(fixture.reecb, {{Vars::IQV, test_case.expected}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::IQRAW, test_case.expected}}, - "reactive-current injection sum"); + success *= residualsMatch( + fixture.reecb, + {{Vars::IQRAW, test_case.expected}}, + "reactive-current injection sum" + ); setState(fixture.reecb, {{Vars::IQRAW, test_case.expected}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::IQCMD, test_case.expected}}, - "reactive-current injection command"); + success *= residualsMatch( + fixture.reecb, + {{Vars::IQCMD, test_case.expected}}, + "reactive-current injection command" + ); } } @@ -1296,15 +1307,17 @@ namespace GridKit setControlState(fixture.reecb); setState(fixture.reecb, {{Vars::PMEAS, 0.6}, {Vars::QV, 0.1}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::QREF, 0.3}}, - "power-factor reactive reference"); + success *= residualsMatch( + fixture.reecb, + {{Vars::QREF, 0.3}}, + "power-factor reactive reference" + ); setState(fixture.reecb, {{Vars::QREF, 0.3}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::QV, 0.4}}, - "power-factor reference"); + success *= residualsMatch( + fixture.reecb, {{Vars::QV, 0.4}}, "power-factor reference" + ); } return success.report(__func__); @@ -1319,9 +1332,9 @@ namespace GridKit { // The ramp-rate limiter bounds the active-power order rate. const std::array rate_cases{{ - {-1.0, -0.5}, - {0.2, 0.2}, - {1.0, 0.6}, + {-1.0, -0.5}, + {0.2, 0.2}, + {1.0, 0.6}, }}; for (const auto& test_case : rate_cases) { @@ -1331,15 +1344,19 @@ namespace GridKit success *= fixture.prepare(0.0, 0.2); setControlState(fixture.reecb); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::RPORD, test_case.expected}}, - "active-power ramp limit"); + success *= residualsMatch( + fixture.reecb, + {{Vars::RPORD, test_case.expected}}, + "active-power ramp limit" + ); setState(fixture.reecb, {{Vars::RPORD, test_case.expected}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::PORD, test_case.expected}}, - "active-power order rate"); + success *= residualsMatch( + fixture.reecb, + {{Vars::PORD, test_case.expected}}, + "active-power order rate" + ); } } @@ -1355,10 +1372,10 @@ namespace GridKit }; const std::array rate_cases{{ - {-0.001, 0.1, -0.002, -0.001}, - {-0.001, 0.1, 0.05, 0.05}, - {-0.1, 0.001, -0.05, -0.05}, - {-0.1, 0.001, 0.002, 0.001}, + {-0.001, 0.1, -0.002, -0.001}, + {-0.001, 0.1, 0.05, 0.05}, + {-0.1, 0.001, -0.05, -0.05}, + {-0.1, 0.001, 0.002, 0.001}, }}; for (const auto& test_case : rate_cases) @@ -1373,24 +1390,28 @@ namespace GridKit success *= fixture.prepare(0.0, 0.2); setControlState(fixture.reecb); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::RPORD, test_case.expected}}, - "asymmetric active-power ramp limit"); + success *= residualsMatch( + fixture.reecb, + {{Vars::RPORD, test_case.expected}}, + "asymmetric active-power ramp limit" + ); setState(fixture.reecb, {{Vars::RPORD, test_case.expected}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::PORD, test_case.expected}}, - "asymmetric active-power order rate"); + success *= residualsMatch( + fixture.reecb, + {{Vars::PORD, test_case.expected}}, + "asymmetric active-power order rate" + ); } } { // The voltage band gates the active-power order outside it. const std::array gate_cases{{ - {0.0, 0.0}, - {1.0, 0.2}, - {2.0, 0.0}, + {0.0, 0.0}, + {1.0, 0.2}, + {2.0, 0.0}, }}; for (const auto& test_case : gate_cases) { @@ -1402,15 +1423,19 @@ namespace GridKit setState(fixture.reecb, {{Vars::VT, test_case.input}}); success *= (fixture.evaluate() == 0); const RealT gate = test_case.expected / static_cast(0.2); - success *= residualsMatch(fixture.reecb, - {{Vars::SDIP, gate - 1.0}}, - "active-power voltage gate"); + success *= residualsMatch( + fixture.reecb, + {{Vars::SDIP, gate - 1.0}}, + "active-power voltage gate" + ); setState(fixture.reecb, {{Vars::SDIP, gate}, {Vars::RPORD, 0.2}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::PORD, test_case.expected}}, - "gated active-power order rate"); + success *= residualsMatch( + fixture.reecb, + {{Vars::PORD, test_case.expected}}, + "gated active-power order rate" + ); } } @@ -1418,11 +1443,11 @@ namespace GridKit // Saturated probes sit beyond their limit by a margin, so a blocked // gate contributes nothing and an admitted gate passes the full rate. const std::array antiwindup_cases{{ - {2.0, 1.0, 0.0}, - {2.0, -1.0, -0.5}, - {-0.4, -1.0, 0.0}, - {-0.4, 1.0, 0.6}, - {0.5, 1.0, 0.6}, + {2.0, 1.0, 0.0}, + {2.0, -1.0, -0.5}, + {-0.4, -1.0, 0.0}, + {-0.4, 1.0, 0.6}, + {0.5, 1.0, 0.6}, }}; for (const auto& test_case : antiwindup_cases) { @@ -1436,39 +1461,47 @@ namespace GridKit { limited_rate = -0.5; } - setState(fixture.reecb, - {{Vars::PORD, test_case.state}, {Vars::RPORD, limited_rate}}); + setState( + fixture.reecb, + {{Vars::PORD, test_case.state}, {Vars::RPORD, limited_rate}} + ); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::PORD, test_case.expected}}, - "active-power antiwindup"); + success *= residualsMatch( + fixture.reecb, + {{Vars::PORD, test_case.expected}}, + "active-power antiwindup" + ); } } { // P priority leaves the reactive command on the residual capacity. const std::array reactive_limit_cases{{ - {-3.0, -2.0}, - {-1.0, -1.0}, - {0.0, 0.0}, - {1.0, 1.0}, - {3.0, 2.0}, + {-3.0, -2.0}, + {-1.0, -1.0}, + {0.0, 0.0}, + {1.0, 1.0}, + {3.0, 2.0}, }}; for (const auto& test_case : reactive_limit_cases) { Fixture fixture(makeData()); success *= fixture.prepare(0.0, 0.2); setControlState(fixture.reecb); - setState(fixture.reecb, - {{Vars::ILCAP, 2.0}, - {Vars::IQMAX, 2.0}, - {Vars::IQRAW, test_case.input}, - {Vars::IQCMD, 0.0}, - {Vars::QV, test_case.input}}); + setState( + fixture.reecb, + {{Vars::ILCAP, 2.0}, + {Vars::IQMAX, 2.0}, + {Vars::IQRAW, test_case.input}, + {Vars::IQCMD, 0.0}, + {Vars::QV, test_case.input}} + ); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::IQCMD, test_case.expected}}, - "reactive-command limit"); + success *= residualsMatch( + fixture.reecb, + {{Vars::IQCMD, test_case.expected}}, + "reactive-command limit" + ); } } @@ -1479,25 +1512,29 @@ namespace GridKit data.parameters[Params::Pqflag] = false; const std::array active_limit_cases{{ - {-1.0, 0.0}, - {0.6, 0.6}, - {1.0, 1.0}, - {3.0, 2.0}, + {-1.0, 0.0}, + {0.6, 0.6}, + {1.0, 1.0}, + {3.0, 2.0}, }}; for (const auto& test_case : active_limit_cases) { Fixture fixture(data); success *= fixture.prepare(0.2, 0.0); setControlState(fixture.reecb); - setState(fixture.reecb, - {{Vars::ILCAP, 2.0}, - {Vars::IPMAX, 2.0}, - {Vars::IPCMD, 0.0}, - {Vars::PORD, test_case.input}}); + setState( + fixture.reecb, + {{Vars::ILCAP, 2.0}, + {Vars::IPMAX, 2.0}, + {Vars::IPCMD, 0.0}, + {Vars::PORD, test_case.input}} + ); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::IPCMD, test_case.expected}}, - "active-command limit"); + success *= residualsMatch( + fixture.reecb, + {{Vars::IPCMD, test_case.expected}}, + "active-command limit" + ); } } @@ -1505,8 +1542,8 @@ namespace GridKit // The priority selector chooses which command consumes the circle. const RealT capacity_state = 1.20; const std::array, 2> priority_cases{{ - {true, 1.76}, - {false, 2.00}, + {true, 1.76}, + {false, 2.00}, }}; for (const auto& [p_priority, square] : priority_cases) { @@ -1523,10 +1560,12 @@ namespace GridKit { label = "P-priority current circle"; } - success *= residualsMatch(fixture.reecb, - {{Vars::ILCAP, circleLeg(square) - capacity_state}}, - label, - kCircleTol); + success *= residualsMatch( + fixture.reecb, + {{Vars::ILCAP, circleLeg(square) - capacity_state}}, + label, + kCircleTol + ); } } @@ -1553,14 +1592,16 @@ namespace GridKit iqcmd = maximum; ipcmd = limit; } - setState(fixture.reecb, - {{Vars::ILCAP, 0.0}, - {Vars::IQCMD, iqcmd}, - {Vars::IPCMD, ipcmd}}); + setState( + fixture.reecb, + {{Vars::ILCAP, 0.0}, {Vars::IQCMD, iqcmd}, {Vars::IPCMD, ipcmd}} + ); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::ILCAP, 0.0}}, - "finite selected current circle"); + success *= residualsMatch( + fixture.reecb, + {{Vars::ILCAP, 0.0}}, + "finite selected current circle" + ); success *= allResidualsFinite(fixture.reecb); } @@ -1574,10 +1615,12 @@ namespace GridKit setControlState(open.reecb); setState(open.reecb, {{Vars::ILCAP, 0.0}, {Vars::IPCMD, 0.0}}); success *= (open.evaluate() == 0); - success *= residualsMatch(open.reecb, - {{Vars::ILCAP, open_limit}}, - "finite open current circle", - kCircleTol); + success *= residualsMatch( + open.reecb, + {{Vars::ILCAP, open_limit}}, + "finite open current circle", + kCircleTol + ); success *= allResidualsFinite(open.reecb); } @@ -1594,9 +1637,9 @@ namespace GridKit }; const std::array circle_cases{{ - {0.25, 0.75}, - {0.5, 0.0}, - {0.75, -1.25}, + {0.25, 0.75}, + {0.5, 0.0}, + {0.75, -1.25}, }}; for (const auto& test_case : circle_cases) { @@ -1605,18 +1648,22 @@ namespace GridKit Fixture fixture(data); success *= fixture.prepare(0.0, test_case.ipcmd); setControlState(fixture.reecb); - setState(fixture.reecb, - {{Vars::ILCAP, 0.0}, - {Vars::IQMAX, 0.0}, - {Vars::IQRAW, 0.0}, - {Vars::IPCMD, test_case.ipcmd}, - {Vars::IQCMD, 0.0}, - {Vars::QV, 1.0}}); + setState( + fixture.reecb, + {{Vars::ILCAP, 0.0}, + {Vars::IQMAX, 0.0}, + {Vars::IQRAW, 0.0}, + {Vars::IPCMD, test_case.ipcmd}, + {Vars::IQCMD, 0.0}, + {Vars::QV, 1.0}} + ); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::ILCAP, ideal_capacity}}, - "off-axis capacity", - kCircleTol); + success *= residualsMatch( + fixture.reecb, + {{Vars::ILCAP, ideal_capacity}}, + "off-axis capacity", + kCircleTol + ); const RealT capacity = fixture.reecb.getResidual().getData()[index(Vars::ILCAP)]; if (!std::isfinite(capacity) || capacity < ZERO) @@ -1627,16 +1674,21 @@ namespace GridKit setState(fixture.reecb, {{Vars::ILCAP, capacity}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::IQMAX, capacity}}, - "reactive-current capacity"); - - setState(fixture.reecb, - {{Vars::IQMAX, capacity}, {Vars::IQRAW, 1.0}}); + success *= residualsMatch( + fixture.reecb, + {{Vars::IQMAX, capacity}}, + "reactive-current capacity" + ); + + setState( + fixture.reecb, {{Vars::IQMAX, capacity}, {Vars::IQRAW, 1.0}} + ); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, - {{Vars::IQCMD, capacity}}, - "capacity magnitude bound"); + success *= residualsMatch( + fixture.reecb, + {{Vars::IQCMD, capacity}}, + "capacity magnitude bound" + ); success *= allResidualsFinite(fixture.reecb); } } @@ -1661,11 +1713,23 @@ namespace GridKit }; const std::array control_modes{{ - {"reactive-power reference with Q priority", false, false, false, false}, - {"power-factor reference with P priority", true, false, false, true}, - {"direct-voltage control with Q priority", false, false, true, false}, - {"cascaded reactive-power control with P priority", false, true, true, true}, - {"cascaded power-factor control with Q priority", true, true, true, false}, + {"reactive-power reference with Q priority", + false, + false, + false, + false}, + {"power-factor reference with P priority", true, false, false, true}, + {"direct-voltage control with Q priority", false, false, true, false}, + {"cascaded reactive-power control with P priority", + false, + true, + true, + true}, + {"cascaded power-factor control with Q priority", + true, + true, + true, + false}, }}; for (const auto& mode : control_modes) { @@ -1683,9 +1747,10 @@ namespace GridKit Log::setVerbosity(Log::Verbosity::NONE); } success *= jacobiansMatch( - dependencyTrackingJacobian(data, kNonunitAlpha, success), - enzymeJacobian(data, kNonunitAlpha, success), - mode.label); + dependencyTrackingJacobian(data, kNonunitAlpha, success), + enzymeJacobian(data, kNonunitAlpha, success), + mode.label + ); Log::setVerbosity(previous_verbosity); } @@ -1698,39 +1763,47 @@ namespace GridKit }; const std::array current_circle_probes{{ - {"open current circle", true, 2.5, 2.0}, - {"closing current circle", true, 0.41, 0.05}, - {"closed current circle", true, 0.4, 0.0}, - {"over-driven current circle", true, 0.2, 0.0}, - {"over-driven current circle on the reactive axis", false, 0.1, 0.0}, + {"open current circle", true, 2.5, 2.0}, + {"closing current circle", true, 0.41, 0.05}, + {"closed current circle", true, 0.4, 0.0}, + {"over-driven current circle", true, 0.2, 0.0}, + {"over-driven current circle on the reactive axis", false, 0.1, 0.0}, }}; for (const auto& probe : current_circle_probes) { auto data = makeJacobianData(); data.parameters[Params::Pqflag] = probe.p_priority; data.parameters[Params::Imax] = probe.imax; - success *= jacobiansMatch( - dependencyTrackingJacobian( - data, kNonunitAlpha, success, probe.capacity), - enzymeJacobian(data, kNonunitAlpha, success, probe.capacity), - probe.label); + success *= jacobiansMatch( + dependencyTrackingJacobian( + data, kNonunitAlpha, success, probe.capacity + ), + enzymeJacobian(data, kNonunitAlpha, success, probe.capacity), + probe.label + ); } auto transition_data = makeJacobianData(); transition_data.parameters[Params::Pqflag] = true; transition_data.parameters[Params::Imax] = 0.4; - success *= jacobiansMatch( - dependencyTrackingJacobian( - transition_data, kNonunitAlpha, success, 0.1, 0.2, 0.1), - enzymeJacobian( - transition_data, kNonunitAlpha, success, 0.1, 0.2, 0.1), - "open current-circle transition"); + success *= jacobiansMatch( + dependencyTrackingJacobian( + transition_data, kNonunitAlpha, success, 0.1, 0.2, 0.1 + ), + enzymeJacobian( + transition_data, kNonunitAlpha, success, 0.1, 0.2, 0.1 + ), + "open current-circle transition" + ); success *= jacobiansMatch( - dependencyTrackingJacobian( - transition_data, kNonunitAlpha, success, 0.1, 0.2, 0.3), - enzymeJacobian( - transition_data, kNonunitAlpha, success, 0.1, 0.2, 0.3), - "over-driven current-circle transition"); + dependencyTrackingJacobian( + transition_data, kNonunitAlpha, success, 0.1, 0.2, 0.3 + ), + enzymeJacobian( + transition_data, kNonunitAlpha, success, 0.1, 0.2, 0.3 + ), + "over-driven current-circle transition" + ); struct NonlinearProbe { @@ -1743,20 +1816,24 @@ namespace GridKit // The component base selects the active-order slew branch. Explicit // voltage-error states select either side of the moving current band. const std::array nonlinear_probes{{ - {"upper active-order slew", 25.0, 2.0, 0.2}, - {"lower active-order slew", 100.0, 2.0, 0.2}, - {"below voltage-PI moving band", 50.0, 0.5, -1.0}, - {"above voltage-PI moving band", 50.0, 0.5, 1.0}, + {"upper active-order slew", 25.0, 2.0, 0.2}, + {"lower active-order slew", 100.0, 2.0, 0.2}, + {"below voltage-PI moving band", 50.0, 0.5, -1.0}, + {"above voltage-PI moving band", 50.0, 0.5, 1.0}, }}; for (const auto& probe : nonlinear_probes) { auto data = makeJacobianData(); data.parameters[Params::mva] = probe.mva; - success *= jacobiansMatch( - dependencyTrackingJacobian( - data, kNonunitAlpha, success, probe.capacity, probe.epiv), - enzymeJacobian(data, kNonunitAlpha, success, probe.capacity, probe.epiv), - probe.label); + success *= jacobiansMatch( + dependencyTrackingJacobian( + data, kNonunitAlpha, success, probe.capacity, probe.epiv + ), + enzymeJacobian( + data, kNonunitAlpha, success, probe.capacity, probe.epiv + ), + probe.label + ); } auto injection_data = makeJacobianData(); @@ -1767,10 +1844,11 @@ namespace GridKit injection_data.parameters[Params::Iql1] = -1.2; injection_data.parameters[Params::Iqh1] = 1.5; injection_data.parameters[Params::Vref0] = 2.2; - success *= jacobiansMatch( - dependencyTrackingJacobian(injection_data, kNonunitAlpha, success), - enzymeJacobian(injection_data, kNonunitAlpha, success), - "voltage-error current injection"); + success *= jacobiansMatch( + dependencyTrackingJacobian(injection_data, kNonunitAlpha, success), + enzymeJacobian(injection_data, kNonunitAlpha, success), + "voltage-error current injection" + ); return success.report(__func__); } @@ -1830,11 +1908,13 @@ namespace GridKit bool commands_assigned_{true}; public: - explicit Fixture(const Data& data, - RealT vr = 1.0, - RealT vi = 0.0, - RealT system_va_base = kSystemBaseVa, - bool assign_commands = true) + explicit Fixture( + const Data& data, + RealT vr = 1.0, + RealT vi = 0.0, + RealT system_va_base = kSystemBaseVa, + bool assign_commands = true + ) : commands_assigned_(assign_commands), bus(static_cast(vr), static_cast(vi)), reecb(&bus, data) @@ -1959,7 +2039,7 @@ namespace GridKit /// MU-aware tolerance for ideal current-circle comparisons. static constexpr RealT kCircleTol = - std::max(ONE / (Math::MU * Math::MU), kTol); + std::max(ONE / (Math::MU * Math::MU), kTol); static constexpr size_t kBusVrColumn = Utilities::enum_size(); @@ -2126,36 +2206,26 @@ namespace GridKit template void setResidualState(PhasorDynamics::Controller::Reecb& reecb) const { - setState(reecb, - {{Vars::VMEAS, 0.80}, - {Vars::PMEAS, 0.55}, - {Vars::XPIQ, 0.64}, - {Vars::XPIV, -0.05}, - {Vars::QV, 0.30}, - {Vars::PORD, 0.60}, - {Vars::VT, 1.00}, - {Vars::VSAFE, 0.80}, - {Vars::SDIP, 1.00}, - {Vars::IQV, 0.50}, - {Vars::QREF, 0.40}, - {Vars::EQ, 0.60}, - {Vars::VPIQ, 1.00}, - {Vars::EPIV, 0.20}, - {Vars::RPORD, 0.20}, - {Vars::ILCAP, 1.20}, - {Vars::IQMAX, 1.20}, - {Vars::IPMAX, 1.50}, - {Vars::IQBASE, 0.19}, - {Vars::IQRAW, 0.69}, - {Vars::IQCMD, 0.25}, - {Vars::IPCMD, 0.35}}); - setDerivative(reecb, - {{Vars::VMEAS, 0.01}, - {Vars::PMEAS, -0.02}, - {Vars::XPIQ, 0.03}, - {Vars::XPIV, -0.03}, - {Vars::QV, 0.05}, - {Vars::PORD, -0.06}}); + setState( + reecb, + {{Vars::VMEAS, 0.80}, {Vars::PMEAS, 0.55}, {Vars::XPIQ, 0.64}, + {Vars::XPIV, -0.05}, {Vars::QV, 0.30}, {Vars::PORD, 0.60}, + {Vars::VT, 1.00}, {Vars::VSAFE, 0.80}, {Vars::SDIP, 1.00}, + {Vars::IQV, 0.50}, {Vars::QREF, 0.40}, {Vars::EQ, 0.60}, + {Vars::VPIQ, 1.00}, {Vars::EPIV, 0.20}, {Vars::RPORD, 0.20}, + {Vars::ILCAP, 1.20}, {Vars::IQMAX, 1.20}, {Vars::IPMAX, 1.50}, + {Vars::IQBASE, 0.19}, {Vars::IQRAW, 0.69}, {Vars::IQCMD, 0.25}, + {Vars::IPCMD, 0.35}} + ); + setDerivative( + reecb, + {{Vars::VMEAS, 0.01}, + {Vars::PMEAS, -0.02}, + {Vars::XPIQ, 0.03}, + {Vars::XPIV, -0.03}, + {Vars::QV, 0.05}, + {Vars::PORD, -0.06}} + ); } /// A neutral driven state for the control probes: unit voltage, cleared @@ -2164,39 +2234,28 @@ namespace GridKit void setControlState(PhasorDynamics::Controller::Reecb& reecb) const { reecb.yp().setToConst(static_cast(ZERO)); - setState(reecb, - {{Vars::VMEAS, 1.0}, - {Vars::PMEAS, 0.6}, - {Vars::XPIQ, 0.0}, - {Vars::XPIV, 0.0}, - {Vars::QV, 0.0}, - {Vars::PORD, 0.5}, - {Vars::VT, 1.0}, - {Vars::VSAFE, 1.0}, - {Vars::SDIP, 1.0}, - {Vars::IQV, 0.0}, - {Vars::QREF, 0.0}, - {Vars::EQ, 0.0}, - {Vars::VPIQ, 0.0}, - {Vars::EPIV, 0.0}, - {Vars::RPORD, 0.0}, - {Vars::ILCAP, 1.4}, - {Vars::IQMAX, 1.4}, - {Vars::IPMAX, 1.5}, - {Vars::IQBASE, 0.0}, - {Vars::IQRAW, 0.0}, - {Vars::IQCMD, 0.1}, - {Vars::IPCMD, 0.2}}); + setState( + reecb, {{Vars::VMEAS, 1.0}, {Vars::PMEAS, 0.6}, {Vars::XPIQ, 0.0}, + {Vars::XPIV, 0.0}, {Vars::QV, 0.0}, {Vars::PORD, 0.5}, + {Vars::VT, 1.0}, {Vars::VSAFE, 1.0}, {Vars::SDIP, 1.0}, + {Vars::IQV, 0.0}, {Vars::QREF, 0.0}, {Vars::EQ, 0.0}, + {Vars::VPIQ, 0.0}, {Vars::EPIV, 0.0}, {Vars::RPORD, 0.0}, + {Vars::ILCAP, 1.4}, {Vars::IQMAX, 1.4}, {Vars::IPMAX, 1.5}, + {Vars::IQBASE, 0.0}, {Vars::IQRAW, 0.0}, {Vars::IQCMD, 0.1}, + {Vars::IPCMD, 0.2}} + ); reecb.yp().setDataUpdated(); } /// Populate every differential and algebraic variable for a Jacobian /// probe. The optional states place selected smooth branches explicitly. template - void setJacobianState(Fixture& fixture, - RealT capacity, - RealT epiv = static_cast(0.2), - RealT ipcmd = static_cast(0.2)) const + void setJacobianState( + Fixture& fixture, + RealT capacity, + RealT epiv = static_cast(0.2), + RealT ipcmd = static_cast(0.2) + ) const { fixture.input(Ext::pe) = static_cast(0.25); fixture.input(Ext::qgen) = static_cast(0.5); @@ -2205,29 +2264,19 @@ namespace GridKit fixture.input(Ext::pref) = static_cast(0.25); fixture.reecb.yp().setToConst(static_cast(ZERO)); - setState(fixture.reecb, - {{Vars::VMEAS, 1.0}, - {Vars::PMEAS, 0.5}, - {Vars::XPIQ, 1.6}, - {Vars::XPIV, 0.0}, - {Vars::QV, 0.0}, - {Vars::PORD, 0.5}, - {Vars::VT, 1.0}, - {Vars::VSAFE, 1.0}, - {Vars::SDIP, 1.0}, - {Vars::IQV, 0.0}, - {Vars::QREF, 0.0}, - {Vars::EQ, 0.5}, - {Vars::VPIQ, 1.0}, - {Vars::EPIV, epiv}, - {Vars::RPORD, 0.05}, - {Vars::ILCAP, capacity}, - {Vars::IQMAX, capacity}, - {Vars::IPMAX, capacity}, - {Vars::IQBASE, 0.2}, - {Vars::IQRAW, 0.2}, - {Vars::IQCMD, 0.1}, - {Vars::IPCMD, ipcmd}}); + setState( + fixture.reecb, {{Vars::VMEAS, 1.0}, {Vars::PMEAS, 0.5}, + {Vars::XPIQ, 1.6}, {Vars::XPIV, 0.0}, + {Vars::QV, 0.0}, {Vars::PORD, 0.5}, + {Vars::VT, 1.0}, {Vars::VSAFE, 1.0}, + {Vars::SDIP, 1.0}, {Vars::IQV, 0.0}, + {Vars::QREF, 0.0}, {Vars::EQ, 0.5}, + {Vars::VPIQ, 1.0}, {Vars::EPIV, epiv}, + {Vars::RPORD, 0.05}, {Vars::ILCAP, capacity}, + {Vars::IQMAX, capacity}, {Vars::IPMAX, capacity}, + {Vars::IQBASE, 0.2}, {Vars::IQRAW, 0.2}, + {Vars::IQCMD, 0.1}, {Vars::IPCMD, ipcmd}} + ); fixture.reecb.yp().setDataUpdated(); } @@ -2252,32 +2301,40 @@ namespace GridKit { success = false; } - if (!vectorsMatch(implicit_defaults.reecb.y(), - explicit_defaults.reecb.y(), - "documented-default state")) + if (!vectorsMatch( + implicit_defaults.reecb.y(), + explicit_defaults.reecb.y(), + "documented-default state" + )) { success = false; } - if (!vectorsMatch(implicit_defaults.reecb.yp(), - explicit_defaults.reecb.yp(), - "documented-default derivative")) + if (!vectorsMatch( + implicit_defaults.reecb.yp(), + explicit_defaults.reecb.yp(), + "documented-default derivative" + )) { success = false; } - if (!vectorsMatch(implicit_defaults.reecb.getResidual(), - explicit_defaults.reecb.getResidual(), - "documented-default residual")) + if (!vectorsMatch( + implicit_defaults.reecb.getResidual(), + explicit_defaults.reecb.getResidual(), + "documented-default residual" + )) { success = false; } for (auto variable : Utilities::enum_values()) { const auto port = static_cast(variable); - if (!rowMatches(implicit_defaults.input(variable), - explicit_defaults.input(variable), - "documented-default signal", - port, - "")) + if (!rowMatches( + implicit_defaults.input(variable), + explicit_defaults.input(variable), + "documented-default signal", + port, + "" + )) { success = false; } @@ -2291,9 +2348,11 @@ namespace GridKit { success = false; } - if (!vectorsMatch(implicit_defaults.reecb.getResidual(), - explicit_defaults.reecb.getResidual(), - "documented-default dynamic residual")) + if (!vectorsMatch( + implicit_defaults.reecb.getResidual(), + explicit_defaults.reecb.getResidual(), + "documented-default dynamic residual" + )) { success = false; } @@ -2306,11 +2365,12 @@ namespace GridKit auto data = makeData(); data.parameters[parameter] = value; return configurationRejected( - [&]() - { - Fixture fixture(data); - return fixture.reecb.verify(); - }); + [&]() + { + Fixture fixture(data); + return fixture.reecb.verify(); + } + ); } template @@ -2338,13 +2398,15 @@ namespace GridKit fixture.reecb.yp().setDataUpdated(); } - bool initializationRejectedAtomically(const Data& data, - RealT iqcmd, - RealT ipcmd, - const char* label, - RealT pe = 0.6, - RealT qgen = 0.6, - RealT voltage = 1.0) const + bool initializationRejectedAtomically( + const Data& data, + RealT iqcmd, + RealT ipcmd, + const char* label, + RealT pe = 0.6, + RealT qgen = 0.6, + RealT voltage = 1.0 + ) const { Fixture fixture(data, voltage); fixture.attachAllInputs(77.0); @@ -2397,10 +2459,12 @@ namespace GridKit for (auto variable : Utilities::enum_values()) { const auto port = static_cast(variable); - if (!valueUnchanged(fixture.input(variable), - inputs_before[port], - "external signal", - port)) + if (!valueUnchanged( + fixture.input(variable), + inputs_before[port], + "external signal", + port + )) { success = false; } @@ -2409,8 +2473,10 @@ namespace GridKit } template - void setState(PhasorDynamics::Controller::Reecb& reecb, - std::initializer_list values) const + void setState( + PhasorDynamics::Controller::Reecb& reecb, + std::initializer_list values + ) const { auto* y = reecb.y().getData(); for (const auto& [variable, value] : values) @@ -2421,8 +2487,10 @@ namespace GridKit } template - void setDerivative(PhasorDynamics::Controller::Reecb& reecb, - std::initializer_list values) const + void setDerivative( + PhasorDynamics::Controller::Reecb& reecb, + std::initializer_list values + ) const { auto* yp = reecb.yp().getData(); for (const auto& [variable, value] : values) @@ -2434,39 +2502,24 @@ namespace GridKit static const char* variableName(Vars variable) { - static constexpr std::array()> names{{ - "VMEAS", - "PMEAS", - "XPIQ", - "XPIV", - "QV", - "PORD", - "VT", - "VSAFE", - "SDIP", - "IQV", - "QREF", - "EQ", - "VPIQ", - "EPIV", - "RPORD", - "ILCAP", - "IQMAX", - "IPMAX", - "IQBASE", - "IQRAW", - "IQCMD", - "IPCMD", - }}; + static constexpr std::array()> + names{{ + "VMEAS", "PMEAS", "XPIQ", "XPIV", "QV", "PORD", + "VT", "VSAFE", "SDIP", "IQV", "QREF", "EQ", + "VPIQ", "EPIV", "RPORD", "ILCAP", "IQMAX", "IPMAX", + "IQBASE", "IQRAW", "IQCMD", "IPCMD", + }}; return names[index(variable)]; } - static bool variableMatches(RealT actual, - RealT expected, - const char* what, - Vars variable, - const char* context, - RealT tolerance = kTol) + static bool variableMatches( + RealT actual, + RealT expected, + const char* what, + Vars variable, + const char* context, + RealT tolerance = kTol + ) { if (isEqual(actual, expected, tolerance)) { @@ -2483,12 +2536,14 @@ namespace GridKit return false; } - static bool rowMatches(RealT actual, - RealT expected, - const char* what, - size_t row, - const char* context, - RealT tolerance = kTol) + static bool rowMatches( + RealT actual, + RealT expected, + const char* what, + size_t row, + const char* context, + RealT tolerance = kTol + ) { if (isEqual(actual, expected, tolerance)) { @@ -2505,10 +2560,9 @@ namespace GridKit return false; } - bool scalarMatches(RealT actual, - RealT expected, - const char* label, - RealT tolerance = kTol) const + bool scalarMatches( + RealT actual, RealT expected, const char* label, RealT tolerance = kTol + ) const { if (isEqual(actual, expected, tolerance)) { @@ -2543,10 +2597,9 @@ namespace GridKit return false; } - static bool valueUnchanged(RealT actual, - RealT expected, - const char* what, - size_t row) + static bool valueUnchanged( + RealT actual, RealT expected, const char* what, size_t row + ) { if (preserved(actual, expected)) { @@ -2559,22 +2612,26 @@ namespace GridKit } template - bool rowsMatch(const VectorT& vector, - const ValuesT& values, - const char* what, - const char* context, - RealT tolerance = kTol) const + bool rowsMatch( + const VectorT& vector, + const ValuesT& values, + const char* what, + const char* context, + RealT tolerance = kTol + ) const { bool success = true; const auto* vector_values = vector.getData(); for (const auto& [variable, expected] : values) { - if (!variableMatches(static_cast(vector_values[index(variable)]), - expected, - what, - variable, - context, - tolerance)) + if (!variableMatches( + static_cast(vector_values[index(variable)]), + expected, + what, + variable, + context, + tolerance + )) { success = false; } @@ -2582,36 +2639,44 @@ namespace GridKit return success; } - bool residualsMatch(const ReecbT& reecb, - std::initializer_list values, - const char* context = "", - RealT tolerance = kTol) const + bool residualsMatch( + const ReecbT& reecb, + std::initializer_list values, + const char* context = "", + RealT tolerance = kTol + ) const { return rowsMatch(reecb.getResidual(), values, "residual", context, tolerance); } template - bool residualsMatch(const ReecbT& reecb, - const std::array& values, - const char* context = "", - RealT tolerance = kTol) const + bool residualsMatch( + const ReecbT& reecb, + const std::array& values, + const char* context = "", + RealT tolerance = kTol + ) const { return rowsMatch(reecb.getResidual(), values, "residual", context, tolerance); } - bool stateMatches(const ReecbT& reecb, - std::initializer_list values, - const char* context = "", - RealT tolerance = kTol) const + bool stateMatches( + const ReecbT& reecb, + std::initializer_list values, + const char* context = "", + RealT tolerance = kTol + ) const { return rowsMatch(reecb.y(), values, "state", context, tolerance); } template - bool stateMatches(const ReecbT& reecb, - const std::array& values, - const char* context = "", - RealT tolerance = kTol) const + bool stateMatches( + const ReecbT& reecb, + const std::array& values, + const char* context = "", + RealT tolerance = kTol + ) const { return rowsMatch(reecb.y(), values, "state", context, tolerance); } @@ -2624,12 +2689,14 @@ namespace GridKit for (size_t row = 0; row < Utilities::enum_size(); ++row) { const auto variable = static_cast(row); - if (!variableMatches(f[row], - 0.0, - "residual", - variable, - "at rest", - ReecbT::INITIALIZATION_TOLERANCE)) + if (!variableMatches( + f[row], + 0.0, + "residual", + variable, + "at rest", + ReecbT::INITIALIZATION_TOLERANCE + )) { success = false; } @@ -2657,9 +2724,11 @@ namespace GridKit return success; } - bool monitorMatches(const ReecbT& reecb, - const std::array& expected, - const char* context) const + bool monitorMatches( + const ReecbT& reecb, + const std::array& expected, + const char* context + ) const { RealT time = 0.0; Model::VariableMonitorController monitor(time); @@ -2709,9 +2778,11 @@ namespace GridKit } template - bool vectorUnchanged(const VectorT& vector, - const std::vector& snapshot, - const char* what) const + bool vectorUnchanged( + const VectorT& vector, + const std::vector& snapshot, + const char* what + ) const { bool success = true; const auto* values = vector.getData(); @@ -2726,9 +2797,9 @@ namespace GridKit } template - bool vectorsMatch(const LeftVectorT& left, - const RightVectorT& right, - const char* what) const + bool vectorsMatch( + const LeftVectorT& left, const RightVectorT& right, const char* what + ) const { if (left.getSize() != right.getSize()) { @@ -2740,11 +2811,13 @@ namespace GridKit const auto* right_values = right.getData(); for (size_t row = 0; row < static_cast(left.getSize()); ++row) { - if (!rowMatches(static_cast(left_values[row]), - static_cast(right_values[row]), - what, - row, - "")) + if (!rowMatches( + static_cast(left_values[row]), + static_cast(right_values[row]), + what, + row, + "" + )) { success = false; } @@ -2779,12 +2852,14 @@ namespace GridKit } std::vector - dependencyTrackingJacobian(const Data& data, - RealT alpha, - TestStatus& success, - RealT capacity = 2.0, - RealT epiv = static_cast(0.2), - RealT ipcmd = static_cast(0.2)) const + dependencyTrackingJacobian( + const Data& data, + RealT alpha, + TestStatus& success, + RealT capacity = 2.0, + RealT epiv = static_cast(0.2), + RealT ipcmd = static_cast(0.2) + ) const { using DepVar = DependencyTracking::Variable; @@ -2801,13 +2876,14 @@ namespace GridKit } #ifdef GRIDKIT_ENABLE_ENZYME - std::vector - enzymeJacobian(const Data& data, - RealT alpha, - TestStatus& success, - RealT capacity = 2.0, - RealT epiv = static_cast(0.2), - RealT ipcmd = static_cast(0.2)) const + std::vector enzymeJacobian( + const Data& data, + RealT alpha, + TestStatus& success, + RealT capacity = 2.0, + RealT epiv = static_cast(0.2), + RealT ipcmd = static_cast(0.2) + ) const { Fixture fixture(data, kStateVr, kStateVi); fixture.attachAllInputs(); @@ -2829,9 +2905,11 @@ namespace GridKit } bool jacobiansMatch( - const std::vector& dependency, - const std::vector& enzyme, - const char* probe) const + const std::vector& + dependency, + const std::vector& enzyme, + const char* probe + ) const { if (dependency.size() != enzyme.size()) { diff --git a/tests/UnitTests/PhasorDynamics/ControllerRepcaTests.hpp b/tests/UnitTests/PhasorDynamics/ControllerRepcaTests.hpp index f2db717bba..00f0c25754 100644 --- a/tests/UnitTests/PhasorDynamics/ControllerRepcaTests.hpp +++ b/tests/UnitTests/PhasorDynamics/ControllerRepcaTests.hpp @@ -40,7 +40,7 @@ namespace GridKit ~ControllerRepcaTests() = default; static constexpr RealT kTol = - static_cast(100.0) * std::numeric_limits::epsilon(); + static_cast(100.0) * std::numeric_limits::epsilon(); /// Validate construction, defaults, parameters, signals, and time floors. TestOutcome validation() @@ -111,34 +111,13 @@ namespace GridKit const RealT nan = std::numeric_limits::quiet_NaN(); const RealT infinity = std::numeric_limits::infinity(); const std::array real_parameters{{ - Params::mva, - Params::Tfltr, - Params::Vfrz, - Params::Rc, - Params::Xc, - Params::Kc, - Params::dbdlow, - Params::dbdupper, - Params::emax, - Params::emin, - Params::Kp, - Params::Ki, - Params::Qmax, - Params::Qmin, - Params::Tft, - Params::Tfv, - Params::Tp, - Params::fdbd1, - Params::fdbd2, - Params::Ddn, - Params::Dup, - Params::femax, - Params::femin, - Params::Kpg, - Params::Kig, - Params::Pmax, - Params::Pmin, - Params::Tlag, + Params::mva, Params::Tfltr, Params::Vfrz, Params::Rc, + Params::Xc, Params::Kc, Params::dbdlow, Params::dbdupper, + Params::emax, Params::emin, Params::Kp, Params::Ki, + Params::Qmax, Params::Qmin, Params::Tft, Params::Tfv, + Params::Tp, Params::fdbd1, Params::fdbd2, Params::Ddn, + Params::Dup, Params::femax, Params::femin, Params::Kpg, + Params::Kig, Params::Pmax, Params::Pmin, Params::Tlag, }}; for (const Params parameter : real_parameters) { @@ -156,31 +135,30 @@ namespace GridKit { auto tiny_base_data = makeData(); tiny_base_data.parameters[Params::mva] = std::numeric_limits::min(); - Fixture overflowing_base_ratio(tiny_base_data, - 1.0, - 0.0, - std::numeric_limits::max()); + Fixture overflowing_base_ratio( + tiny_base_data, 1.0, 0.0, std::numeric_limits::max() + ); overflowing_base_ratio.attachAllInputs(); success *= (!overflowing_base_ratio.repca.verify().passed()); } const std::array flag_parameters{{ - Params::VcompFlag, - Params::RefFlag, - Params::Freqflag, + Params::VcompFlag, + Params::RefFlag, + Params::Freqflag, }}; const std::array valid_flag_values{{false, true}}; const std::array invalid_integral_flag_values{{ - static_cast(0), - static_cast(1), - static_cast(2), + static_cast(0), + static_cast(1), + static_cast(2), }}; const std::array invalid_real_flag_values{{ - static_cast(0.0), - static_cast(0.5), - static_cast(1.0), - nan, - infinity, + static_cast(0.0), + static_cast(0.5), + static_cast(1.0), + nan, + infinity, }}; for (const Params flag : flag_parameters) { @@ -238,14 +216,14 @@ namespace GridKit floored.repca.y().setDataUpdated(); success *= (floored.repca.evaluateResidual() == 0); const std::array floored_residuals{{ - {Vars::VMEAS, 1.0}, - {Vars::QMEAS, 2.0}, - {Vars::PMEAS, 3.0}, - {Vars::PREF, 4.0}, + {Vars::VMEAS, 1.0}, + {Vars::QMEAS, 2.0}, + {Vars::PMEAS, 3.0}, + {Vars::PREF, 4.0}, }}; - success *= residualsMatch(floored.repca, - floored_residuals, - "floored time constants"); + success *= residualsMatch( + floored.repca, floored_residuals, "floored time constants" + ); Log::setVerbosity(previous_verbosity); return success.report(__func__); @@ -263,7 +241,8 @@ namespace GridKit success *= (fixture.repca.tagDifferentiable() == 0); success *= (fixture.repca.evaluateResidual() == 0); - const std::array()> initial_state{{ + const std::array()> + initial_state{{ {Vars::VMEAS, 0.984002032518226}, {Vars::QMEAS, 0.2}, {Vars::XQPI, 0.5}, @@ -286,7 +265,7 @@ namespace GridKit {Vars::EPLIM, 0.0}, {Vars::PPI, 0.9}, {Vars::PEXT, 0.45}, - }}; + }}; success *= stateMatches(fixture.repca, initial_state, "initialization"); success *= scalarPreserved(fixture.input(Ext::ir), 0.2, "preserved ir"); @@ -318,18 +297,17 @@ namespace GridKit const auto* tolerances = fixture.repca.absoluteTolerance().getData(); for (size_t row = 0; row < Utilities::enum_size(); ++row) { - success *= valueUnchanged(tolerances[row], - absolute_tolerance, - "absolute tolerance", - row); + success *= valueUnchanged( + tolerances[row], absolute_tolerance, "absolute tolerance", row + ); } const std::array initial_monitors{{ - 0.25, - 0.45, - 0.984002032518226, - 0.2, - 0.8, + 0.25, + 0.45, + 0.984002032518226, + 0.2, + 0.8, }}; success *= monitorMatches(fixture.repca, initial_monitors, "initialization"); @@ -364,25 +342,23 @@ namespace GridKit success *= (fallback.repca.evaluateResidual() == 0); success *= allResidualsWithinInitTolerance(fallback.repca); - Fixture outputless(makeInitializationData(), - 0.8, - 0.6, - 100.0e6, - false); + Fixture outputless( + makeInitializationData(), 0.8, 0.6, 100.0e6, false + ); outputless.attachAllInputs(); setInitializationInputs(outputless); success *= outputless.initialize(0.25, 0.45); success *= (outputless.repca.evaluateResidual() == 0); const std::array outputless_state{{ - {Vars::QEXT, 0.25}, - {Vars::PEXT, 0.45}, + {Vars::QEXT, 0.25}, + {Vars::PEXT, 0.45}, }}; - success *= stateMatches(outputless.repca, - outputless_state, - "unassigned command outputs"); - success *= monitorMatches(outputless.repca, - initial_monitors, - "unassigned command outputs"); + success *= stateMatches( + outputless.repca, outputless_state, "unassigned command outputs" + ); + success *= monitorMatches( + outputless.repca, initial_monitors, "unassigned command outputs" + ); success *= allResidualsWithinInitTolerance(outputless.repca); struct FlagCase @@ -397,14 +373,62 @@ namespace GridKit }; const std::array flag_cases{{ - {"droop/reactive-reference/disabled-frequency", false, false, false, 1.08, 0.8, 0.0}, - {"droop/reactive-reference/enabled-frequency", false, false, true, 1.08, 0.9, 0.45}, - {"droop/voltage-reference/disabled-frequency", false, true, false, 1.08, 0.8, 0.0}, - {"droop/voltage-reference/enabled-frequency", false, true, true, 1.08, 0.9, 0.45}, - {"line-drop/reactive-reference/disabled-frequency", true, false, false, 0.984002032518226, 0.8, 0.0}, - {"line-drop/reactive-reference/enabled-frequency", true, false, true, 0.984002032518226, 0.9, 0.45}, - {"line-drop/voltage-reference/disabled-frequency", true, true, false, 0.984002032518226, 0.8, 0.0}, - {"line-drop/voltage-reference/enabled-frequency", true, true, true, 0.984002032518226, 0.9, 0.45}, + {"droop/reactive-reference/disabled-frequency", + false, + false, + false, + 1.08, + 0.8, + 0.0}, + {"droop/reactive-reference/enabled-frequency", + false, + false, + true, + 1.08, + 0.9, + 0.45}, + {"droop/voltage-reference/disabled-frequency", + false, + true, + false, + 1.08, + 0.8, + 0.0}, + {"droop/voltage-reference/enabled-frequency", + false, + true, + true, + 1.08, + 0.9, + 0.45}, + {"line-drop/reactive-reference/disabled-frequency", + true, + false, + false, + 0.984002032518226, + 0.8, + 0.0}, + {"line-drop/reactive-reference/enabled-frequency", + true, + false, + true, + 0.984002032518226, + 0.9, + 0.45}, + {"line-drop/voltage-reference/disabled-frequency", + true, + true, + false, + 0.984002032518226, + 0.8, + 0.0}, + {"line-drop/voltage-reference/enabled-frequency", + true, + true, + true, + 0.984002032518226, + 0.9, + 0.45}, }}; for (const auto& test_case : flag_cases) { @@ -420,15 +444,14 @@ namespace GridKit success *= (scenario.repca.evaluateResidual() == 0); const std::array expected_state{{ - {Vars::VMEAS, test_case.voltage}, - {Vars::VCTRL, test_case.voltage}, - {Vars::PREF, test_case.pref}, - {Vars::PPI, test_case.pref}, - {Vars::PEXT, test_case.pext}, + {Vars::VMEAS, test_case.voltage}, + {Vars::VCTRL, test_case.voltage}, + {Vars::PREF, test_case.pref}, + {Vars::PPI, test_case.pref}, + {Vars::PEXT, test_case.pext}, }}; - success *= stateMatches(scenario.repca, - expected_state, - test_case.label); + success *= + stateMatches(scenario.repca, expected_state, test_case.label); success *= scalarMatches(scenario.qext(), 0.25, test_case.label); success *= scalarMatches(scenario.pext(), test_case.pext, test_case.label); success *= allResidualsWithinInitTolerance(scenario.repca); @@ -459,46 +482,49 @@ namespace GridKit const RealT nan = std::numeric_limits::quiet_NaN(); const RealT infinity = std::numeric_limits::infinity(); const std::array rejection_cases{{ - {"nonfinite qext", infinity, 0.45}, - {"nonfinite pext", 0.25, infinity}, - {"nan qext", nan, 0.45}, - {"nan pext", 0.25, nan}, + {"nonfinite qext", infinity, 0.45}, + {"nonfinite pext", 0.25, infinity}, + {"nan qext", nan, 0.45}, + {"nan pext", 0.25, nan}, }}; for (const auto& test_case : rejection_cases) { - success *= initializationRejectedAtomically(data, - test_case.qext, - test_case.pext, - test_case.label); + success *= initializationRejectedAtomically( + data, test_case.qext, test_case.pext, test_case.label + ); } const std::array required_ports{{ - Ext::ir, - Ext::ii, - Ext::p, - Ext::q, - Ext::freq, + Ext::ir, + Ext::ii, + Ext::p, + Ext::q, + Ext::freq, }}; const std::array nonfinite_values{{infinity, -infinity, nan}}; for (const Ext port : required_ports) { for (const RealT value : nonfinite_values) { - success *= initializationRejectedAtomically(data, - 0.25, - 0.45, - "nonfinite required signal", - NonfiniteTarget::INPUT, - 0.8, - 0.6, - port, - value); + success *= initializationRejectedAtomically( + data, + 0.25, + 0.45, + "nonfinite required signal", + NonfiniteTarget::INPUT, + 0.8, + 0.6, + port, + value + ); } } - success *= initializationRejectedAtomically(data, - 0.25, - 0.45, - "nonfinite bus voltage", - NonfiniteTarget::BUS_VOLTAGE); + success *= initializationRejectedAtomically( + data, + 0.25, + 0.45, + "nonfinite bus voltage", + NonfiniteTarget::BUS_VOLTAGE + ); auto collapsed_data = data; @@ -513,12 +539,12 @@ namespace GridKit const std::array voltage_reference_values{{false, true}}; const std::array, 2> voltage_cases{{ - {0.8, 0.6}, - {0.2, 0.0}, + {0.8, 0.6}, + {0.2, 0.0}, }}; const std::array asymmetric_reactive_state{{ - {Vars::ERQDB, -0.1}, - {Vars::ERQLIM, 0.0}, + {Vars::ERQDB, -0.1}, + {Vars::ERQLIM, 0.0}, }}; for (const bool voltage_reference : voltage_reference_values) { @@ -526,16 +552,18 @@ namespace GridKit data.parameters[Params::RefFlag] = voltage_reference; for (const auto& voltage : voltage_cases) { - Fixture asymmetric_reactive(data, - voltage.first, - voltage.second); + Fixture asymmetric_reactive( + data, voltage.first, voltage.second + ); asymmetric_reactive.attachAllInputs(); setInitializationInputs(asymmetric_reactive); success *= asymmetric_reactive.initialize(0.25, 0.45); success *= (asymmetric_reactive.repca.evaluateResidual() == 0); - success *= stateMatches(asymmetric_reactive.repca, - asymmetric_reactive_state, - "asymmetric reactive initialization"); + success *= stateMatches( + asymmetric_reactive.repca, + asymmetric_reactive_state, + "asymmetric reactive initialization" + ); success *= allResidualsWithinInitTolerance(asymmetric_reactive.repca); } } @@ -562,19 +590,25 @@ namespace GridKit success *= asymmetric_active.initialize(0.25, 0.45); success *= (asymmetric_active.repca.evaluateResidual() == 0); const std::array lower_active_state{{ - {Vars::EF, 0.0}, - {Vars::EP, -0.1}, - {Vars::EPLIM, 0.0}, + {Vars::EF, 0.0}, + {Vars::EP, -0.1}, + {Vars::EPLIM, 0.0}, }}; - success *= stateMatches(asymmetric_active.repca, - lower_active_state, - "lower active-error boundary"); - success *= scalarMatches(asymmetric_active.input(Ext::freqref), - 0.995, - "asymmetric frequency reference"); - success *= scalarMatches(asymmetric_active.input(Ext::pref), - 0.35, - "lower-bound plant reference"); + success *= stateMatches( + asymmetric_active.repca, + lower_active_state, + "lower active-error boundary" + ); + success *= scalarMatches( + asymmetric_active.input(Ext::freqref), + 0.995, + "asymmetric frequency reference" + ); + success *= scalarMatches( + asymmetric_active.input(Ext::pref), + 0.35, + "lower-bound plant reference" + ); success *= allResidualsWithinInitTolerance(asymmetric_active.repca); } @@ -588,28 +622,36 @@ namespace GridKit success *= asymmetric_active.initialize(0.25, 0.45); success *= (asymmetric_active.repca.evaluateResidual() == 0); const std::array upper_active_state{{ - {Vars::EF, 0.0}, - {Vars::EP, 0.1}, - {Vars::EPLIM, 0.0}, + {Vars::EF, 0.0}, + {Vars::EP, 0.1}, + {Vars::EPLIM, 0.0}, }}; - success *= stateMatches(asymmetric_active.repca, - upper_active_state, - "upper active-error boundary"); - success *= scalarMatches(asymmetric_active.input(Ext::freqref), - 0.985, - "asymmetric frequency reference"); - success *= scalarMatches(asymmetric_active.input(Ext::pref), - 0.45, - "upper-bound plant reference"); + success *= stateMatches( + asymmetric_active.repca, + upper_active_state, + "upper active-error boundary" + ); + success *= scalarMatches( + asymmetric_active.input(Ext::freqref), + 0.985, + "asymmetric frequency reference" + ); + success *= scalarMatches( + asymmetric_active.input(Ext::pref), + 0.45, + "upper-bound plant reference" + ); success *= allResidualsWithinInitTolerance(asymmetric_active.repca); } auto overflow_data = makeInitializationData(); overflow_data.parameters[Params::Rc] = std::numeric_limits::max(); - success *= initializationRejectedAtomically(overflow_data, - 0.25, - 0.45, - "nonfinite derived initialization candidate"); + success *= initializationRejectedAtomically( + overflow_data, + 0.25, + 0.45, + "nonfinite derived initialization candidate" + ); // An invalid configuration is rejected before any state is written. { @@ -641,18 +683,20 @@ namespace GridKit success *= qmax_pmin_boundary.initialize(0.75, 0.0); success *= (qmax_pmin_boundary.repca.evaluateResidual() == 0); const std::array qmax_pmin_state{{ - {Vars::QPI, 1.5}, - {Vars::XQLAG, 1.5}, - {Vars::XQPI, 1.6}, - {Vars::QEXT, 0.75}, - {Vars::PREF, 0.0}, - {Vars::PPI, 0.0}, - {Vars::XPPI, -0.1}, - {Vars::PEXT, 0.0}, + {Vars::QPI, 1.5}, + {Vars::XQLAG, 1.5}, + {Vars::XQPI, 1.6}, + {Vars::QEXT, 0.75}, + {Vars::PREF, 0.0}, + {Vars::PPI, 0.0}, + {Vars::XPPI, -0.1}, + {Vars::PEXT, 0.0}, }}; - success *= stateMatches(qmax_pmin_boundary.repca, - qmax_pmin_state, - "Qmax/Pmin command boundary"); + success *= stateMatches( + qmax_pmin_boundary.repca, + qmax_pmin_state, + "Qmax/Pmin command boundary" + ); } { @@ -662,18 +706,20 @@ namespace GridKit success *= qmin_pmax_boundary.initialize(-0.4, 1.0); success *= (qmin_pmax_boundary.repca.evaluateResidual() == 0); const std::array qmin_pmax_state{{ - {Vars::QPI, -0.8}, - {Vars::XQLAG, -0.8}, - {Vars::XQPI, -0.9}, - {Vars::QEXT, -0.4}, - {Vars::PREF, 2.0}, - {Vars::PPI, 2.0}, - {Vars::XPPI, 2.1}, - {Vars::PEXT, 1.0}, + {Vars::QPI, -0.8}, + {Vars::XQLAG, -0.8}, + {Vars::XQPI, -0.9}, + {Vars::QEXT, -0.4}, + {Vars::PREF, 2.0}, + {Vars::PPI, 2.0}, + {Vars::XPPI, 2.1}, + {Vars::PEXT, 1.0}, }}; - success *= stateMatches(qmin_pmax_boundary.repca, - qmin_pmax_state, - "Qmin/Pmax command boundary"); + success *= stateMatches( + qmin_pmax_boundary.repca, + qmin_pmax_state, + "Qmin/Pmax command boundary" + ); } { @@ -683,18 +729,18 @@ namespace GridKit success *= collapsed_limits.initialize(0.25, 0.45); success *= (collapsed_limits.repca.evaluateResidual() == 0); const std::array collapsed_state{{ - {Vars::XQPI, 0.5}, - {Vars::XQLAG, 0.5}, - {Vars::QPI, 0.5}, - {Vars::QEXT, 0.25}, - {Vars::XPPI, 0.9}, - {Vars::PREF, 0.9}, - {Vars::PPI, 0.9}, - {Vars::PEXT, 0.45}, + {Vars::XQPI, 0.5}, + {Vars::XQLAG, 0.5}, + {Vars::QPI, 0.5}, + {Vars::QEXT, 0.25}, + {Vars::XPPI, 0.9}, + {Vars::PREF, 0.9}, + {Vars::PPI, 0.9}, + {Vars::PEXT, 0.45}, }}; - success *= stateMatches(collapsed_limits.repca, - collapsed_state, - "collapsed Q/P limits"); + success *= stateMatches( + collapsed_limits.repca, collapsed_state, "collapsed Q/P limits" + ); success *= allResidualsWithinInitTolerance(collapsed_limits.repca); } @@ -708,10 +754,10 @@ namespace GridKit }; const std::array limit_cases{{ - {"adjusted Qmin", -0.5, 0.45, Vars::QPI, -1.0}, - {"adjusted Qmax", 0.9, 0.45, Vars::QPI, 1.8}, - {"adjusted Pmin", 0.25, -0.1, Vars::PPI, -0.2}, - {"adjusted Pmax", 0.25, 1.1, Vars::PPI, 2.2}, + {"adjusted Qmin", -0.5, 0.45, Vars::QPI, -1.0}, + {"adjusted Qmax", 0.9, 0.45, Vars::QPI, 1.8}, + {"adjusted Pmin", 0.25, -0.1, Vars::PPI, -0.2}, + {"adjusted Pmax", 0.25, 1.1, Vars::PPI, 2.2}, }}; for (const auto& test_case : limit_cases) @@ -720,9 +766,11 @@ namespace GridKit adjusted.attachAllInputs(); setInitializationInputs(adjusted); success *= adjusted.initialize(test_case.qext, test_case.pext); - success *= stateMatches(adjusted.repca, - {{test_case.output, test_case.expected}}, - test_case.label); + success *= stateMatches( + adjusted.repca, + {{test_case.output, test_case.expected}}, + test_case.label + ); success *= (adjusted.repca.evaluateResidual() == 0); success *= allResidualsWithinInitTolerance(adjusted.repca); } @@ -736,21 +784,24 @@ namespace GridKit disabled_frequency.attachAllInputs(); setInitializationInputs(disabled_frequency); success *= disabled_frequency.initialize(0.25, 0.45); - success *= stateMatches(disabled_frequency.repca, - {{Vars::PREF, 0.8}, - {Vars::PPI, 0.8}, - {Vars::PEXT, 0.0}}, - "measured-power limit"); + success *= stateMatches( + disabled_frequency.repca, + {{Vars::PREF, 0.8}, {Vars::PPI, 0.8}, {Vars::PEXT, 0.0}}, + "measured-power limit" + ); success *= (disabled_frequency.repca.evaluateResidual() == 0); success *= allResidualsWithinInitTolerance(disabled_frequency.repca); - setState(disabled_frequency.repca, - {{Vars::XPPI, 0.6}, {Vars::PPI, 0.77}}); + setState( + disabled_frequency.repca, {{Vars::XPPI, 0.6}, {Vars::PPI, 0.77}} + ); setDerivative(disabled_frequency.repca, {{Vars::XPPI, 0.0}}); success *= (disabled_frequency.repca.evaluateResidual() == 0); - success *= residualsMatch(disabled_frequency.repca, - {{Vars::XPPI, 0.18}}, - "measured-power limit"); + success *= residualsMatch( + disabled_frequency.repca, + {{Vars::XPPI, 0.18}}, + "measured-power limit" + ); } { @@ -759,29 +810,37 @@ namespace GridKit setInitializationInputs(adjusted); success *= adjusted.initialize(1.0, 1.25); - setState(adjusted.repca, - {{Vars::QPI, 1.75}, - {Vars::XQPI, 1.55}, - {Vars::SFRZ, 1.0}, - {Vars::PPI, 2.25}, - {Vars::XPPI, 2.08}}); + setState( + adjusted.repca, + {{Vars::QPI, 1.75}, + {Vars::XQPI, 1.55}, + {Vars::SFRZ, 1.0}, + {Vars::PPI, 2.25}, + {Vars::XPPI, 2.08}} + ); setDerivative(adjusted.repca, {{Vars::XQPI, 0.0}, {Vars::XPPI, 0.0}}); success *= (adjusted.repca.evaluateResidual() == 0); - success *= residualsMatch(adjusted.repca, - {{Vars::XQPI, 0.3}, {Vars::XPPI, 0.18}}, - "adjusted antiwindup limits"); - - setState(adjusted.repca, - {{Vars::QPI, 0.0}, - {Vars::ERQLIM, 0.0}, - {Vars::XQPI, 1.75}, - {Vars::PPI, 0.0}, - {Vars::EPLIM, 0.0}, - {Vars::XPPI, 2.25}}); + success *= residualsMatch( + adjusted.repca, + {{Vars::XQPI, 0.3}, {Vars::XPPI, 0.18}}, + "adjusted antiwindup limits" + ); + + setState( + adjusted.repca, + {{Vars::QPI, 0.0}, + {Vars::ERQLIM, 0.0}, + {Vars::XQPI, 1.75}, + {Vars::PPI, 0.0}, + {Vars::EPLIM, 0.0}, + {Vars::XPPI, 2.25}} + ); success *= (adjusted.repca.evaluateResidual() == 0); - success *= residualsMatch(adjusted.repca, - {{Vars::QPI, 1.75}, {Vars::PPI, 2.25}}, - "adjusted command limits"); + success *= residualsMatch( + adjusted.repca, + {{Vars::QPI, 1.75}, {Vars::PPI, 2.25}}, + "adjusted command limits" + ); } Log::setVerbosity(previous_verbosity); @@ -801,33 +860,24 @@ namespace GridKit setAnswerKeyState(fixture.repca); success *= (fixture.repca.evaluateResidual() == 0); - const std::array()> expected_residuals{{ - {Vars::VMEAS, 0.4}, - {Vars::QMEAS, 0.45}, - {Vars::XQPI, -0.225}, - {Vars::XQLAG, 0.46}, - {Vars::PMEAS, 0.5}, - {Vars::XPPI, -69.0 / 170.0}, - {Vars::PREF, 0.4}, - {Vars::V, -1.28}, - {Vars::VLDC, 0.028}, - {Vars::VDROOP, 0.1}, - {Vars::VCTRL, 0.05}, - {Vars::SFRZ, 0.5}, - {Vars::ERQ, -0.63}, - {Vars::ERQDB, 0.75}, - {Vars::ERQLIM, 0.025}, - {Vars::QPI, -0.05}, - {Vars::QEXT, -1.345}, - {Vars::EF, -0.015}, - {Vars::EP, -0.4}, - {Vars::EPLIM, 1.1}, - {Vars::PPI, 0.1}, - {Vars::PEXT, 0.05}, - }}; + const std::array()> + expected_residuals{{ + {Vars::VMEAS, 0.4}, {Vars::QMEAS, 0.45}, + {Vars::XQPI, -0.225}, {Vars::XQLAG, 0.46}, + {Vars::PMEAS, 0.5}, {Vars::XPPI, -69.0 / 170.0}, + {Vars::PREF, 0.4}, {Vars::V, -1.28}, + {Vars::VLDC, 0.028}, {Vars::VDROOP, 0.1}, + {Vars::VCTRL, 0.05}, {Vars::SFRZ, 0.5}, + {Vars::ERQ, -0.63}, {Vars::ERQDB, 0.75}, + {Vars::ERQLIM, 0.025}, {Vars::QPI, -0.05}, + {Vars::QEXT, -1.345}, {Vars::EF, -0.015}, + {Vars::EP, -0.4}, {Vars::EPLIM, 1.1}, + {Vars::PPI, 0.1}, {Vars::PEXT, 0.05}, + }}; - success *= (static_cast(fixture.repca.getResidual().getSize()) - == expected_residuals.size()); + success *= + (static_cast(fixture.repca.getResidual().getSize()) + == expected_residuals.size()); const auto* residual = fixture.repca.getResidual().getData(); for (size_t row = 0; row < expected_residuals.size(); ++row) { @@ -838,9 +888,11 @@ namespace GridKit << variableName(variable) << '\n'; success = false; } - success *= scalarMatches(residual[index(variable)], - expected_residuals[row].value, - variableName(variable)); + success *= scalarMatches( + residual[index(variable)], + expected_residuals[row].value, + variableName(variable) + ); } return success.report(__func__); @@ -861,10 +913,10 @@ namespace GridKit }; const std::array flag_cases{{ - {"droop/reactive-reference", false, false, 0.08, 0.30}, - {"droop/voltage-reference", false, true, 0.08, 0.10}, - {"line-drop/reactive-reference", true, false, -0.08, 0.30}, - {"line-drop/voltage-reference", true, true, -0.08, 0.10}, + {"droop/reactive-reference", false, false, 0.08, 0.30}, + {"droop/voltage-reference", false, true, 0.08, 0.10}, + {"line-drop/reactive-reference", true, false, -0.08, 0.30}, + {"line-drop/voltage-reference", true, true, -0.08, 0.10}, }}; for (const auto& test_case : flag_cases) { @@ -879,22 +931,23 @@ namespace GridKit fixture.input(Ext::qref) = 0.20; success *= fixture.prepare(0.0, 0.0); - setState(fixture.repca, - {{Vars::VMEAS, 0.95}, - {Vars::QMEAS, 0.10}, - {Vars::VLDC, 0.92}, - {Vars::VDROOP, 1.08}, - {Vars::VCTRL, 1.0}, - {Vars::ERQ, 0.0}}); + setState( + fixture.repca, + {{Vars::VMEAS, 0.95}, + {Vars::QMEAS, 0.10}, + {Vars::VLDC, 0.92}, + {Vars::VDROOP, 1.08}, + {Vars::VCTRL, 1.0}, + {Vars::ERQ, 0.0}} + ); success *= (fixture.repca.evaluateResidual() == 0); const std::array expected_residuals{{ - {Vars::VCTRL, test_case.vctrl}, - {Vars::ERQ, test_case.erq}, + {Vars::VCTRL, test_case.vctrl}, + {Vars::ERQ, test_case.erq}, }}; - success *= residualsMatch(fixture.repca, - expected_residuals, - test_case.label); + success *= + residualsMatch(fixture.repca, expected_residuals, test_case.label); } Fixture fixture(makeResidualData()); @@ -914,103 +967,115 @@ namespace GridKit success *= freeze.prepare(0.0, 0.0); const std::array freeze_cases{{ - {0.0, 0.0}, - {1.6, 1.0}, + {0.0, 0.0}, + {1.6, 1.0}, }}; for (const auto& test_case : freeze_cases) { setState(freeze.repca, {{Vars::V, test_case.input}, {Vars::SFRZ, 0.0}}); success *= (freeze.repca.evaluateResidual() == 0); - success *= residualsMatch(freeze.repca, - {{Vars::SFRZ, test_case.expected}}, - "freeze gate"); + success *= residualsMatch( + freeze.repca, {{Vars::SFRZ, test_case.expected}}, "freeze gate" + ); } } // The interior probe sits at the midpoint of the band, where the // smooth deadband cancels exactly. const std::array deadband_cases{{ - {-0.82, -0.8}, - {0.005, 0.0}, - {0.83, 0.8}, + {-0.82, -0.8}, + {0.005, 0.0}, + {0.83, 0.8}, }}; for (const auto& test_case : deadband_cases) { setState(fixture.repca, {{Vars::ERQ, test_case.input}, {Vars::ERQDB, 0.0}}); success *= (fixture.repca.evaluateResidual() == 0); - success *= residualsMatch(fixture.repca, - {{Vars::ERQDB, test_case.expected}}, - "reactive-power deadband"); + success *= residualsMatch( + fixture.repca, + {{Vars::ERQDB, test_case.expected}}, + "reactive-power deadband" + ); } const std::array error_limit_cases{{ - {-1.5, -0.7}, - {0.05, 0.05}, - {1.6, 0.8}, + {-1.5, -0.7}, + {0.05, 0.05}, + {1.6, 0.8}, }}; for (const auto& test_case : error_limit_cases) { setState(fixture.repca, {{Vars::ERQDB, test_case.input}, {Vars::ERQLIM, 0.0}}); success *= (fixture.repca.evaluateResidual() == 0); - success *= residualsMatch(fixture.repca, - {{Vars::ERQLIM, test_case.expected}}, - "reactive-power error limit"); + success *= residualsMatch( + fixture.repca, + {{Vars::ERQLIM, test_case.expected}}, + "reactive-power error limit" + ); } const std::array command_limit_cases{{ - {-1.6, -0.8}, - {0.05, 0.05}, - {1.7, 0.9}, + {-1.6, -0.8}, + {0.05, 0.05}, + {1.7, 0.9}, }}; for (const auto& test_case : command_limit_cases) { - setState(fixture.repca, - {{Vars::XQPI, test_case.input}, - {Vars::ERQLIM, 0.0}, - {Vars::QPI, 0.0}}); + setState( + fixture.repca, + {{Vars::XQPI, test_case.input}, + {Vars::ERQLIM, 0.0}, + {Vars::QPI, 0.0}} + ); success *= (fixture.repca.evaluateResidual() == 0); - success *= residualsMatch(fixture.repca, - {{Vars::QPI, test_case.expected}}, - "reactive-power command limit"); + success *= residualsMatch( + fixture.repca, + {{Vars::QPI, test_case.expected}}, + "reactive-power command limit" + ); } // The limited command feeds back to the PI state; a state beyond a // limit holds under outward error and returns under restoring error. const std::array antiwindup_cases{{ - {0.35, 0.3, -0.25, 0.9}, - {-0.25, -0.3, 0.35, -0.9}, - {0.9, 0.4, 0.4, 0.75}, - {0.9, 0.4, 1.4, 0.0}, - {0.2, -0.6, 1.4, -1.05}, - {-0.8, -0.4, -1.3, 0.0}, + {0.35, 0.3, -0.25, 0.9}, + {-0.25, -0.3, 0.35, -0.9}, + {0.9, 0.4, 0.4, 0.75}, + {0.9, 0.4, 1.4, 0.0}, + {0.2, -0.6, 1.4, -1.05}, + {-0.8, -0.4, -1.3, 0.0}, }}; for (const auto& test_case : antiwindup_cases) { - setState(fixture.repca, - {{Vars::QPI, test_case.output}, - {Vars::ERQLIM, test_case.error}, - {Vars::XQPI, test_case.state}, - {Vars::SFRZ, 1.0}}); + setState( + fixture.repca, + {{Vars::QPI, test_case.output}, + {Vars::ERQLIM, test_case.error}, + {Vars::XQPI, test_case.state}, + {Vars::SFRZ, 1.0}} + ); setDerivative(fixture.repca, {{Vars::XQPI, 0.0}}); success *= (fixture.repca.evaluateResidual() == 0); - success *= residualsMatch(fixture.repca, - {{Vars::XQPI, test_case.expected}, {Vars::QPI, 0.0}}, - "reactive-power antiwindup"); + success *= residualsMatch( + fixture.repca, + {{Vars::XQPI, test_case.expected}, {Vars::QPI, 0.0}}, + "reactive-power antiwindup" + ); } - setState(fixture.repca, - {{Vars::XQLAG, 0.14}, - {Vars::QPI, 0.27}, - {Vars::QEXT, 0.20}}); + setState( + fixture.repca, + {{Vars::XQLAG, 0.14}, {Vars::QPI, 0.27}, {Vars::QEXT, 0.20}} + ); setDerivative(fixture.repca, {{Vars::XQLAG, -0.04}}); success *= (fixture.repca.evaluateResidual() == 0); const std::array lead_lag_residuals{{ - {Vars::XQLAG, 0.092}, - {Vars::QEXT, -0.624}, + {Vars::XQLAG, 0.092}, + {Vars::QEXT, -0.624}, }}; - success *= residualsMatch(fixture.repca, - lead_lag_residuals, - "reactive-command lead-lag"); + success *= residualsMatch( + fixture.repca, lead_lag_residuals, "reactive-command lead-lag" + ); // A state beyond the upper limit holds under outward error, so the // row depends on the limited command but not on the state. @@ -1019,27 +1084,35 @@ namespace GridKit blocked.attachAllInputs(); setAnswerKeyInputs(blocked); success *= blocked.prepare(0.0, 0.0); - setState(blocked.repca, - {{Vars::QPI, 0.9}, {Vars::XQPI, 1.4}, {Vars::ERQLIM, 0.4}, {Vars::SFRZ, 1.0}}); + setState( + blocked.repca, + {{Vars::QPI, 0.9}, + {Vars::XQPI, 1.4}, + {Vars::ERQLIM, 0.4}, + {Vars::SFRZ, 1.0}} + ); setDerivative(blocked.repca, {{Vars::XQPI, 0.0}}); numberVariables(blocked); blocked.repca.updateTime(0.0, 1.0); success *= (blocked.repca.evaluateResidual() == 0); const DependencyTracking::Variable::DependencyMap expected{ - {2 * index(Vars::XQPI) + 1, -1.0}, // @todo Remove these - {2 * index(Vars::SFRZ), 0.0}, // @todo Remove these - {2 * index(Vars::ERQLIM), 0.0}, // @todo Remove these - {2 * index(Vars::QPI), 1.5}, // @todo Remove these - {2 * index(Vars::XQPI), 0.0}, // @todo Remove these + {2 * index(Vars::XQPI) + 1, -1.0}, // @todo Remove these + {2 * index(Vars::SFRZ), 0.0}, // @todo Remove these + {2 * index(Vars::ERQLIM), 0.0}, // @todo Remove these + {2 * index(Vars::QPI), 1.5}, // @todo Remove these + {2 * index(Vars::XQPI), 0.0}, // @todo Remove these }; success *= jacobianRowMatches( - blocked.repca.getResidual().getData()[index(Vars::XQPI)].getDependencies(), - expected, - index(Vars::XQPI), - "blocked reactive-power antiwindup", - kTol); + blocked.repca.getResidual() + .getData()[index(Vars::XQPI)] + .getDependencies(), + expected, + index(Vars::XQPI), + "blocked reactive-power antiwindup", + kTol + ); } return success.report(__func__); @@ -1058,8 +1131,8 @@ namespace GridKit }; const std::array flag_cases{{ - {"disabled frequency control", false, -0.6}, - {"enabled frequency control", true, 0.2}, + {"disabled frequency control", false, -0.6}, + {"enabled frequency control", true, 0.2}, }}; for (const auto& test_case : flag_cases) { @@ -1071,9 +1144,9 @@ namespace GridKit success *= fixture.prepare(0.0, 0.0); setState(fixture.repca, {{Vars::PREF, 0.8}, {Vars::PEXT, 0.3}}); success *= (fixture.repca.evaluateResidual() == 0); - success *= residualsMatch(fixture.repca, - {{Vars::PEXT, test_case.pext}}, - test_case.label); + success *= residualsMatch( + fixture.repca, {{Vars::PEXT, test_case.pext}}, test_case.label + ); } Fixture fixture(makeResidualData()); @@ -1084,9 +1157,9 @@ namespace GridKit // The interior probe sits at the midpoint of the band, where the // smooth deadband cancels exactly. const std::array frequency_deadband_cases{{ - {-0.81, -0.8}, - {0.0025, 0.0}, - {0.815, 0.8}, + {-0.81, -0.8}, + {0.0025, 0.0}, + {0.815, 0.8}, }}; for (const auto& test_case : frequency_deadband_cases) { @@ -1094,89 +1167,101 @@ namespace GridKit fixture.input(Ext::freqref) = 1.0 + test_case.input; setState(fixture.repca, {{Vars::EF, 0.0}}); success *= (fixture.repca.evaluateResidual() == 0); - success *= residualsMatch(fixture.repca, - {{Vars::EF, test_case.expected}}, - "frequency deadband"); + success *= residualsMatch( + fixture.repca, + {{Vars::EF, test_case.expected}}, + "frequency deadband" + ); } const std::array droop_cases{{ - {-0.9, -1.8}, - {0.0, 0.0}, - {0.9, 0.9}, + {-0.9, -1.8}, + {0.0, 0.0}, + {0.9, 0.9}, }}; fixture.input(Ext::pref) = 0.2; for (const auto& test_case : droop_cases) { - setState(fixture.repca, - {{Vars::EF, test_case.input}, - {Vars::EP, 0.0}, - {Vars::PMEAS, 0.4}}); + setState( + fixture.repca, + {{Vars::EF, test_case.input}, {Vars::EP, 0.0}, {Vars::PMEAS, 0.4}} + ); success *= (fixture.repca.evaluateResidual() == 0); - success *= residualsMatch(fixture.repca, - {{Vars::EP, test_case.expected}}, - "frequency droop"); + success *= residualsMatch( + fixture.repca, {{Vars::EP, test_case.expected}}, "frequency droop" + ); } const std::array error_limit_cases{{ - {-1.3, -0.5}, - {0.05, 0.05}, - {1.4, 0.6}, + {-1.3, -0.5}, + {0.05, 0.05}, + {1.4, 0.6}, }}; for (const auto& test_case : error_limit_cases) { setState(fixture.repca, {{Vars::EP, test_case.input}, {Vars::EPLIM, 0.0}}); success *= (fixture.repca.evaluateResidual() == 0); - success *= residualsMatch(fixture.repca, - {{Vars::EPLIM, test_case.expected}}, - "active-power error limit"); + success *= residualsMatch( + fixture.repca, + {{Vars::EPLIM, test_case.expected}}, + "active-power error limit" + ); } const std::array command_limit_cases{{ - {-0.8, 0.0}, - {1.0, 1.0}, - {2.8, 2.0}, + {-0.8, 0.0}, + {1.0, 1.0}, + {2.8, 2.0}, }}; for (const auto& test_case : command_limit_cases) { - setState(fixture.repca, - {{Vars::XPPI, test_case.input}, - {Vars::EPLIM, 0.0}, - {Vars::PPI, 0.0}}); + setState( + fixture.repca, + {{Vars::XPPI, test_case.input}, + {Vars::EPLIM, 0.0}, + {Vars::PPI, 0.0}} + ); success *= (fixture.repca.evaluateResidual() == 0); - success *= residualsMatch(fixture.repca, - {{Vars::PPI, test_case.expected}}, - "active-power command limit"); + success *= residualsMatch( + fixture.repca, + {{Vars::PPI, test_case.expected}}, + "active-power command limit" + ); } // The limited command feeds back to the PI state; a state beyond a // limit holds under outward error and returns under restoring error. const std::array antiwindup_cases{{ - {1.45, 0.5, 0.6, 0.9}, - {0.6, -0.5, 1.45, -0.9}, - {2.0, 1.0, 1.15, 0.9}, - {2.0, 0.5, 2.5, 0.0}, - {1.15, -1.0, 2.85, -0.9}, - {0.0, -0.5, -0.5, 0.0}, + {1.45, 0.5, 0.6, 0.9}, + {0.6, -0.5, 1.45, -0.9}, + {2.0, 1.0, 1.15, 0.9}, + {2.0, 0.5, 2.5, 0.0}, + {1.15, -1.0, 2.85, -0.9}, + {0.0, -0.5, -0.5, 0.0}, }}; for (const auto& test_case : antiwindup_cases) { - setState(fixture.repca, - {{Vars::PPI, test_case.output}, - {Vars::XPPI, test_case.state}, - {Vars::EPLIM, test_case.error}}); + setState( + fixture.repca, + {{Vars::PPI, test_case.output}, + {Vars::XPPI, test_case.state}, + {Vars::EPLIM, test_case.error}} + ); setDerivative(fixture.repca, {{Vars::XPPI, 0.0}}); success *= (fixture.repca.evaluateResidual() == 0); - success *= residualsMatch(fixture.repca, - {{Vars::XPPI, test_case.expected}, {Vars::PPI, 0.0}}, - "active-power antiwindup"); + success *= residualsMatch( + fixture.repca, + {{Vars::XPPI, test_case.expected}, {Vars::PPI, 0.0}}, + "active-power antiwindup" + ); } setState(fixture.repca, {{Vars::PPI, 0.66}, {Vars::PREF, 0.60}}); setDerivative(fixture.repca, {{Vars::PREF, 0.05}}); success *= (fixture.repca.evaluateResidual() == 0); - success *= residualsMatch(fixture.repca, - {{Vars::PREF, 0.07}}, - "active-power command lag"); + success *= residualsMatch( + fixture.repca, {{Vars::PREF, 0.07}}, "active-power command lag" + ); return success.report(__func__); } @@ -1191,27 +1276,29 @@ namespace GridKit setAnswerKeyInputs(fixture); success *= fixture.prepare(0.0, 0.0); setAnswerKeyState(fixture.repca); - setDerivative(fixture.repca, - {{Vars::VMEAS, 0.2}, - {Vars::QMEAS, -0.1}, - {Vars::XQPI, 0.4}, - {Vars::XQLAG, -0.3}, - {Vars::PMEAS, 0.6}, - {Vars::XPPI, -0.5}, - {Vars::PREF, 0.8}}); + setDerivative( + fixture.repca, + {{Vars::VMEAS, 0.2}, + {Vars::QMEAS, -0.1}, + {Vars::XQPI, 0.4}, + {Vars::XQLAG, -0.3}, + {Vars::PMEAS, 0.6}, + {Vars::XPPI, -0.5}, + {Vars::PREF, 0.8}} + ); success *= (fixture.repca.evaluateResidual() == 0); const std::array expected_residuals{{ - {Vars::VMEAS, 0.3}, - {Vars::QMEAS, 0.35}, - {Vars::XQPI, -0.325}, - {Vars::XQLAG, 0.36}, - {Vars::PMEAS, 0.4}, - {Vars::XPPI, -43.0 / 85.0}, - {Vars::PREF, 0.3}, + {Vars::VMEAS, 0.3}, + {Vars::QMEAS, 0.35}, + {Vars::XQPI, -0.325}, + {Vars::XQLAG, 0.36}, + {Vars::PMEAS, 0.4}, + {Vars::XPPI, -43.0 / 85.0}, + {Vars::PREF, 0.3}, }}; - success *= residualsMatch(fixture.repca, - expected_residuals, - "explicit derivatives"); + success *= residualsMatch( + fixture.repca, expected_residuals, "explicit derivatives" + ); return success.report(__func__); } @@ -1226,28 +1313,31 @@ namespace GridKit const auto data = makeResidualData(); const auto dependency = dependencyTrackingJacobian(data, success); - success *= jacobianMatches(dependency, - expectedJacobian(), - "dependency tracking", - kTol); + success *= jacobianMatches( + dependency, expectedJacobian(), "dependency tracking", kTol + ); auto all_flags_off_data = data; all_flags_off_data.parameters[Params::VcompFlag] = false; all_flags_off_data.parameters[Params::RefFlag] = false; all_flags_off_data.parameters[Params::Freqflag] = false; const auto all_flags_off = - dependencyTrackingJacobian(all_flags_off_data, success); - success *= jacobianMatches(all_flags_off, - expectedJacobianAllFlagsOff(), - "all-flags-off dependency tracking", - kTol); + dependencyTrackingJacobian(all_flags_off_data, success); + success *= jacobianMatches( + all_flags_off, + expectedJacobianAllFlagsOff(), + "all-flags-off dependency tracking", + kTol + ); const auto nonunit_alpha_dependency = - dependencyTrackingJacobian(data, success, kNonunitAlpha); - success *= jacobianMatches(nonunit_alpha_dependency, - expectedJacobianNonunitAlpha(), - "non-unit-alpha dependency tracking", - kTol); + dependencyTrackingJacobian(data, success, kNonunitAlpha); + success *= jacobianMatches( + nonunit_alpha_dependency, + expectedJacobianNonunitAlpha(), + "non-unit-alpha dependency tracking", + kTol + ); return success.report(__func__); } @@ -1261,26 +1351,30 @@ namespace GridKit const auto data = makeResidualData(); - success *= jacobianMatches(enzymeJacobian(data, success), - dependencyTrackingJacobian(data, success), - "Enzyme versus dependency tracking", - kTol); + success *= jacobianMatches( + enzymeJacobian(data, success), + dependencyTrackingJacobian(data, success), + "Enzyme versus dependency tracking", + kTol + ); auto all_flags_off_data = data; all_flags_off_data.parameters[Params::VcompFlag] = false; all_flags_off_data.parameters[Params::RefFlag] = false; all_flags_off_data.parameters[Params::Freqflag] = false; - success *= jacobianMatches( - enzymeJacobian(all_flags_off_data, success), - dependencyTrackingJacobian(all_flags_off_data, success), - "all-flags-off Enzyme versus dependency tracking", - kTol); + success *= jacobianMatches( + enzymeJacobian(all_flags_off_data, success), + dependencyTrackingJacobian(all_flags_off_data, success), + "all-flags-off Enzyme versus dependency tracking", + kTol + ); success *= jacobianMatches( - enzymeJacobian(data, success, kNonunitAlpha), - dependencyTrackingJacobian(data, success, kNonunitAlpha), - "non-unit-alpha Enzyme versus dependency tracking", - kTol); + enzymeJacobian(data, success, kNonunitAlpha), + dependencyTrackingJacobian(data, success, kNonunitAlpha), + "non-unit-alpha Enzyme versus dependency tracking", + kTol + ); return success.report(__func__); } @@ -1346,13 +1440,14 @@ namespace GridKit PhasorDynamics::SignalNode pext_node_; public: - explicit Fixture(const Data& data, - RealT vr = 1.0, - RealT vi = 0.0, - RealT system_va_base = 100.0e6, - bool assign_command_outputs = true) - : bus(static_cast(vr), static_cast(vi)), - repca(&bus, data) + explicit Fixture( + const Data& data, + RealT vr = 1.0, + RealT vi = 0.0, + RealT system_va_base = 100.0e6, + bool assign_command_outputs = true + ) + : bus(static_cast(vr), static_cast(vi)), repca(&bus, data) { repca.setSystemBase(60.0, system_va_base); if (assign_command_outputs) @@ -1382,8 +1477,9 @@ namespace GridKit repca.getPorts().in.template port().connect(&input_nodes_[index(Ext::q)]); } - void attachAllInputs(RealT initial_value = 0.0, - bool attach_frequency = true) + void attachAllInputs( + RealT initial_value = 0.0, bool attach_frequency = true + ) { attachRequiredInputs(initial_value); @@ -1609,37 +1705,27 @@ namespace GridKit // Every smooth-transition argument keeps a saturation margin, and // every clamp that must pass its input through sits at the midpoint // of its limits or well inside them, so each row carries its ideal value. - setState(repca, - {{Vars::VMEAS, 0.85}, - {Vars::QMEAS, 0.45}, - {Vars::XQPI, 0.0}, - {Vars::XQLAG, -0.05}, - {Vars::PMEAS, 0.3}, - {Vars::XPPI, 1.85}, - {Vars::PREF, 0.35}, - {Vars::V, 1.5}, - {Vars::VLDC, 1.0}, - {Vars::VDROOP, 1.6}, - {Vars::VCTRL, 0.95}, - {Vars::SFRZ, 0.5}, - {Vars::ERQ, 0.83}, - {Vars::ERQDB, 0.05}, - {Vars::ERQLIM, 0.025}, - {Vars::QPI, 0.1}, - {Vars::QEXT, 0.25}, - {Vars::EF, 0.8}, - {Vars::EP, 2.0}, - {Vars::EPLIM, -0.5}, - {Vars::PPI, 0.9}, - {Vars::PEXT, 0.15}}); - setDerivative(repca, - {{Vars::VMEAS, 0.1}, - {Vars::QMEAS, -0.2}, - {Vars::XQPI, 0.3}, - {Vars::XQLAG, -0.4}, - {Vars::PMEAS, 0.5}, - {Vars::XPPI, -0.6}, - {Vars::PREF, 0.7}}); + setState( + repca, + {{Vars::VMEAS, 0.85}, {Vars::QMEAS, 0.45}, {Vars::XQPI, 0.0}, + {Vars::XQLAG, -0.05}, {Vars::PMEAS, 0.3}, {Vars::XPPI, 1.85}, + {Vars::PREF, 0.35}, {Vars::V, 1.5}, {Vars::VLDC, 1.0}, + {Vars::VDROOP, 1.6}, {Vars::VCTRL, 0.95}, {Vars::SFRZ, 0.5}, + {Vars::ERQ, 0.83}, {Vars::ERQDB, 0.05}, {Vars::ERQLIM, 0.025}, + {Vars::QPI, 0.1}, {Vars::QEXT, 0.25}, {Vars::EF, 0.8}, + {Vars::EP, 2.0}, {Vars::EPLIM, -0.5}, {Vars::PPI, 0.9}, + {Vars::PEXT, 0.15}} + ); + setDerivative( + repca, + {{Vars::VMEAS, 0.1}, + {Vars::QMEAS, -0.2}, + {Vars::XQPI, 0.3}, + {Vars::XQLAG, -0.4}, + {Vars::PMEAS, 0.5}, + {Vars::XPPI, -0.6}, + {Vars::PREF, 0.7}} + ); } bool defaultsMatchDocumentedValues() const @@ -1672,21 +1758,27 @@ namespace GridKit { success = false; } - if (!vectorsMatch(implicit_defaults.repca.y(), - explicit_defaults.repca.y(), - "documented-default state")) + if (!vectorsMatch( + implicit_defaults.repca.y(), + explicit_defaults.repca.y(), + "documented-default state" + )) { success = false; } - if (!vectorsMatch(implicit_defaults.repca.yp(), - explicit_defaults.repca.yp(), - "documented-default derivative")) + if (!vectorsMatch( + implicit_defaults.repca.yp(), + explicit_defaults.repca.yp(), + "documented-default derivative" + )) { success = false; } - if (!vectorsMatch(implicit_defaults.repca.getResidual(), - explicit_defaults.repca.getResidual(), - "documented-default residual")) + if (!vectorsMatch( + implicit_defaults.repca.getResidual(), + explicit_defaults.repca.getResidual(), + "documented-default residual" + )) { success = false; } @@ -1694,11 +1786,13 @@ namespace GridKit { const auto port = static_cast(variant); const auto variable = static_cast(port); - if (!rowMatches(implicit_defaults.input(variable), - explicit_defaults.input(variable), - "documented-default signal", - port, - "")) + if (!rowMatches( + implicit_defaults.input(variable), + explicit_defaults.input(variable), + "documented-default signal", + port, + "" + )) { success = false; } @@ -1716,9 +1810,11 @@ namespace GridKit { success = false; } - if (!vectorsMatch(implicit_defaults.repca.getResidual(), - explicit_defaults.repca.getResidual(), - "documented-default dynamic residual")) + if (!vectorsMatch( + implicit_defaults.repca.getResidual(), + explicit_defaults.repca.getResidual(), + "documented-default dynamic residual" + )) { success = false; } @@ -1731,12 +1827,13 @@ namespace GridKit auto data = makeData(); data.parameters[parameter] = value; return configurationRejected( - [&]() - { - Fixture fixture(data); - fixture.attachAllInputs(); - return fixture.repca.verify(); - }); + [&]() + { + Fixture fixture(data); + fixture.attachAllInputs(); + return fixture.repca.verify(); + } + ); } template @@ -1764,16 +1861,17 @@ namespace GridKit fixture.repca.yp().setDataUpdated(); } - bool initializationRejectedAtomically(const Data& data, - RealT qext, - RealT pext, - const char* label, - NonfiniteTarget target = NonfiniteTarget::NONE, - RealT initial_vr = 0.8, - RealT initial_vi = 0.6, - Ext poisoned_port = Ext::freq, - RealT poison_value = - std::numeric_limits::infinity()) const + bool initializationRejectedAtomically( + const Data& data, + RealT qext, + RealT pext, + const char* label, + NonfiniteTarget target = NonfiniteTarget::NONE, + RealT initial_vr = 0.8, + RealT initial_vi = 0.6, + Ext poisoned_port = Ext::freq, + RealT poison_value = std::numeric_limits::infinity() + ) const { Fixture fixture(data, initial_vr, initial_vi); fixture.attachAllInputs(77.0); @@ -1835,10 +1933,12 @@ namespace GridKit for (auto variant : Utilities::enum_values()) { const auto port = static_cast(variant); - if (!valueUnchanged(fixture.input(static_cast(port)), - inputs_before[port], - "external signal", - port)) + if (!valueUnchanged( + fixture.input(static_cast(port)), + inputs_before[port], + "external signal", + port + )) { success = false; } @@ -1847,8 +1947,10 @@ namespace GridKit } template - void setState(PhasorDynamics::Controller::Repca& repca, - std::initializer_list values) const + void setState( + PhasorDynamics::Controller::Repca& repca, + std::initializer_list values + ) const { auto* y = repca.y().getData(); for (const auto& [variable, value] : values) @@ -1859,8 +1961,10 @@ namespace GridKit } template - void setDerivative(PhasorDynamics::Controller::Repca& repca, - std::initializer_list values) const + void setDerivative( + PhasorDynamics::Controller::Repca& repca, + std::initializer_list values + ) const { auto* yp = repca.yp().getData(); for (const auto& [variable, value] : values) @@ -1872,39 +1976,24 @@ namespace GridKit static const char* variableName(Vars variable) { - static constexpr std::array()> names{{ - "VMEAS", - "QMEAS", - "XQPI", - "XQLAG", - "PMEAS", - "XPPI", - "PREF", - "V", - "VLDC", - "VDROOP", - "VCTRL", - "SFRZ", - "ERQ", - "ERQDB", - "ERQLIM", - "QPI", - "QEXT", - "EF", - "EP", - "EPLIM", - "PPI", - "PEXT", - }}; + static constexpr std::array()> + names{{ + "VMEAS", "QMEAS", "XQPI", "XQLAG", "PMEAS", "XPPI", + "PREF", "V", "VLDC", "VDROOP", "VCTRL", "SFRZ", + "ERQ", "ERQDB", "ERQLIM", "QPI", "QEXT", "EF", + "EP", "EPLIM", "PPI", "PEXT", + }}; return names[index(variable)]; } - static bool variableMatches(RealT actual, - RealT expected, - const char* what, - Vars variable, - const char* context, - RealT tolerance = kTol) + static bool variableMatches( + RealT actual, + RealT expected, + const char* what, + Vars variable, + const char* context, + RealT tolerance = kTol + ) { if (isEqual(actual, expected, tolerance)) { @@ -1921,12 +2010,14 @@ namespace GridKit return false; } - static bool rowMatches(RealT actual, - RealT expected, - const char* what, - size_t row, - const char* context, - RealT tolerance = kTol) + static bool rowMatches( + RealT actual, + RealT expected, + const char* what, + size_t row, + const char* context, + RealT tolerance = kTol + ) { if (isEqual(actual, expected, tolerance)) { @@ -1942,10 +2033,9 @@ namespace GridKit return false; } - bool scalarMatches(RealT actual, - RealT expected, - const char* label, - RealT tolerance = kTol) const + bool scalarMatches( + RealT actual, RealT expected, const char* label, RealT tolerance = kTol + ) const { if (isEqual(actual, expected, tolerance)) { @@ -1956,9 +2046,11 @@ namespace GridKit return false; } - bool monitorMatches(const RepcaT& repca, - const std::array& expected, - const char* context) const + bool monitorMatches( + const RepcaT& repca, + const std::array& expected, + const char* context + ) const { RealT time = 0.0; Model::VariableMonitorController monitor(time); @@ -1974,10 +2066,10 @@ namespace GridKit std::getline(output, header); std::getline(output, values_line); - bool success = - header == "t,Repca_repca_test_qext,Repca_repca_test_pext," - "Repca_repca_test_vmeas,Repca_repca_test_qmeas," - "Repca_repca_test_pmeas"; + bool success = header + == "t,Repca_repca_test_qext,Repca_repca_test_pext," + "Repca_repca_test_vmeas,Repca_repca_test_qmeas," + "Repca_repca_test_pmeas"; const auto values = Tokenizer(values_line, ',')(); if (values.size() != expected.size() + 1) @@ -1989,11 +2081,7 @@ namespace GridKit for (size_t i = 0; i < expected.size(); ++i) { - if (!rowMatches(values[i + 1], - expected[i], - "monitor", - i, - context)) + if (!rowMatches(values[i + 1], expected[i], "monitor", i, context)) { success = false; } @@ -2023,10 +2111,9 @@ namespace GridKit return false; } - static bool valueUnchanged(RealT actual, - RealT expected, - const char* what, - size_t index) + static bool valueUnchanged( + RealT actual, RealT expected, const char* what, size_t index + ) { if (preserved(actual, expected)) { @@ -2039,10 +2126,12 @@ namespace GridKit } template - bool rowsMatch(const VectorT& vector, - const ValuesT& values, - const char* what, - const char* context) const + bool rowsMatch( + const VectorT& vector, + const ValuesT& values, + const char* what, + const char* context + ) const { bool success = true; const auto* vector_values = vector.getData(); @@ -2050,11 +2139,13 @@ namespace GridKit { const size_t row = index(variable); - if (!variableMatches(static_cast(vector_values[row]), - expected, - what, - variable, - context)) + if (!variableMatches( + static_cast(vector_values[row]), + expected, + what, + variable, + context + )) { success = false; } @@ -2062,32 +2153,40 @@ namespace GridKit return success; } - bool residualsMatch(const RepcaT& repca, - std::initializer_list values, - const char* context = "") const + bool residualsMatch( + const RepcaT& repca, + std::initializer_list values, + const char* context = "" + ) const { return rowsMatch(repca.getResidual(), values, "residual", context); } template - bool residualsMatch(const RepcaT& repca, - const std::array& values, - const char* context = "") const + bool residualsMatch( + const RepcaT& repca, + const std::array& values, + const char* context = "" + ) const { return rowsMatch(repca.getResidual(), values, "residual", context); } - bool stateMatches(const RepcaT& repca, - std::initializer_list values, - const char* context = "") const + bool stateMatches( + const RepcaT& repca, + std::initializer_list values, + const char* context = "" + ) const { return rowsMatch(repca.y(), values, "state", context); } template - bool stateMatches(const RepcaT& repca, - const std::array& values, - const char* context = "") const + bool stateMatches( + const RepcaT& repca, + const std::array& values, + const char* context = "" + ) const { return rowsMatch(repca.y(), values, "state", context); } @@ -2100,12 +2199,14 @@ namespace GridKit for (size_t row = 0; row < Utilities::enum_size(); ++row) { const auto variable = static_cast(row); - if (!variableMatches(f[row], - 0.0, - "residual", - variable, - "at rest", - RepcaT::INITIALIZATION_TOLERANCE)) + if (!variableMatches( + f[row], + 0.0, + "residual", + variable, + "at rest", + RepcaT::INITIALIZATION_TOLERANCE + )) { success = false; } @@ -2130,18 +2231,19 @@ namespace GridKit } template - bool vectorUnchanged(const VectorT& vector, - const std::vector& snapshot, - const char* what) const + bool vectorUnchanged( + const VectorT& vector, + const std::vector& snapshot, + const char* what + ) const { bool success = true; const auto* values = vector.getData(); for (size_t row = 0; row < snapshot.size(); ++row) { - if (!valueUnchanged(static_cast(values[row]), - snapshot[row], - what, - row)) + if (!valueUnchanged( + static_cast(values[row]), snapshot[row], what, row + )) { success = false; } @@ -2150,9 +2252,9 @@ namespace GridKit } template - bool vectorsMatch(const LeftVectorT& left, - const RightVectorT& right, - const char* what) const + bool vectorsMatch( + const LeftVectorT& left, const RightVectorT& right, const char* what + ) const { if (left.getSize() != right.getSize()) { @@ -2164,11 +2266,13 @@ namespace GridKit const auto* right_values = right.getData(); for (size_t row = 0; row < static_cast(left.getSize()); ++row) { - if (!rowMatches(static_cast(left_values[row]), - static_cast(right_values[row]), - what, - row, - "")) + if (!rowMatches( + static_cast(left_values[row]), + static_cast(right_values[row]), + what, + row, + "" + )) { success = false; } @@ -2179,48 +2283,56 @@ namespace GridKit std::vector expectedJacobian() const { return { - {{index(Vars::VMEAS), -6.0}, {index(Vars::VCTRL), 5.0}}, - {{index(Vars::QMEAS), -6.0}, {externalColumn(index(Ext::q)), 10.0}}, - {{index(Vars::XQPI), -1.75}, - {index(Vars::SFRZ), 0.15}, - {index(Vars::ERQLIM), 0.0}, - {index(Vars::QPI), 0.75}}, - {{index(Vars::XQLAG), -1.4}, {index(Vars::QPI), 0.4}}, - {{index(Vars::PMEAS), -3.5}, {externalColumn(index(Ext::p)), 5.0}}, - {{index(Vars::XPPI), -35.0 / 17.0}, - {index(Vars::EPLIM), 0.0}, - {index(Vars::PPI), 18.0 / 17.0}}, - {{index(Vars::PREF), -3.0}, {index(Vars::PPI), 2.0}}, - {{index(Vars::V), -3.0}, {kBusVrColumn, 1.8}, {kBusViColumn, 0.8}}, - {{index(Vars::VLDC), -2.0}, - {kBusVrColumn, 1.96}, - {kBusViColumn, 0.52}, - {externalColumn(index(Ext::ir)), -0.1096}, - {externalColumn(index(Ext::ii)), 0.0968}}, - {{index(Vars::V), 1.0}, {index(Vars::VDROOP), -1.0}, {externalColumn(index(Ext::q)), 0.8}}, - {{index(Vars::VLDC), 1.0}, - {index(Vars::VDROOP), 0.0}, - {index(Vars::VCTRL), -1.0}}, - {{index(Vars::V), 0.0}, {index(Vars::SFRZ), -1.0}}, - {{index(Vars::VMEAS), -1.0}, - {index(Vars::QMEAS), 0.0}, - {index(Vars::ERQ), -1.0}, - {externalColumn(index(Ext::vref)), 1.0}, - {externalColumn(index(Ext::qref)), 0.0}}, - {{index(Vars::ERQ), 1.0}, {index(Vars::ERQDB), -1.0}}, - {{index(Vars::ERQDB), 1.0}, {index(Vars::ERQLIM), -1.0}}, - {{index(Vars::XQPI), 1.0}, {index(Vars::ERQLIM), 2.0}, {index(Vars::QPI), -1.0}}, - {{index(Vars::XQLAG), 2.3}, {index(Vars::QPI), 0.2}, {index(Vars::QEXT), -5.0}}, - {{index(Vars::EF), -1.0}, - {externalColumn(index(Ext::freq)), -1.0}, - {externalColumn(index(Ext::freqref)), 1.0}}, - {{index(Vars::PMEAS), -1.0}, - {index(Vars::EF), 1.0}, - {index(Vars::EP), -1.0}, - {externalColumn(index(Ext::pref)), 2.0}}, - {{index(Vars::EP), 0.0}, {index(Vars::EPLIM), -1.0}}, - {{index(Vars::XPPI), 1.0}, {index(Vars::EPLIM), 1.7}, {index(Vars::PPI), -1.0}}, - {{index(Vars::PREF), 1.0}, {index(Vars::PEXT), -2.0}}, + {{index(Vars::VMEAS), -6.0}, {index(Vars::VCTRL), 5.0}}, + {{index(Vars::QMEAS), -6.0}, {externalColumn(index(Ext::q)), 10.0}}, + {{index(Vars::XQPI), -1.75}, + {index(Vars::SFRZ), 0.15}, + {index(Vars::ERQLIM), 0.0}, + {index(Vars::QPI), 0.75}}, + {{index(Vars::XQLAG), -1.4}, {index(Vars::QPI), 0.4}}, + {{index(Vars::PMEAS), -3.5}, {externalColumn(index(Ext::p)), 5.0}}, + {{index(Vars::XPPI), -35.0 / 17.0}, + {index(Vars::EPLIM), 0.0}, + {index(Vars::PPI), 18.0 / 17.0}}, + {{index(Vars::PREF), -3.0}, {index(Vars::PPI), 2.0}}, + {{index(Vars::V), -3.0}, {kBusVrColumn, 1.8}, {kBusViColumn, 0.8}}, + {{index(Vars::VLDC), -2.0}, + {kBusVrColumn, 1.96}, + {kBusViColumn, 0.52}, + {externalColumn(index(Ext::ir)), -0.1096}, + {externalColumn(index(Ext::ii)), 0.0968}}, + {{index(Vars::V), 1.0}, + {index(Vars::VDROOP), -1.0}, + {externalColumn(index(Ext::q)), 0.8}}, + {{index(Vars::VLDC), 1.0}, + {index(Vars::VDROOP), 0.0}, + {index(Vars::VCTRL), -1.0}}, + {{index(Vars::V), 0.0}, {index(Vars::SFRZ), -1.0}}, + {{index(Vars::VMEAS), -1.0}, + {index(Vars::QMEAS), 0.0}, + {index(Vars::ERQ), -1.0}, + {externalColumn(index(Ext::vref)), 1.0}, + {externalColumn(index(Ext::qref)), 0.0}}, + {{index(Vars::ERQ), 1.0}, {index(Vars::ERQDB), -1.0}}, + {{index(Vars::ERQDB), 1.0}, {index(Vars::ERQLIM), -1.0}}, + {{index(Vars::XQPI), 1.0}, + {index(Vars::ERQLIM), 2.0}, + {index(Vars::QPI), -1.0}}, + {{index(Vars::XQLAG), 2.3}, + {index(Vars::QPI), 0.2}, + {index(Vars::QEXT), -5.0}}, + {{index(Vars::EF), -1.0}, + {externalColumn(index(Ext::freq)), -1.0}, + {externalColumn(index(Ext::freqref)), 1.0}}, + {{index(Vars::PMEAS), -1.0}, + {index(Vars::EF), 1.0}, + {index(Vars::EP), -1.0}, + {externalColumn(index(Ext::pref)), 2.0}}, + {{index(Vars::EP), 0.0}, {index(Vars::EPLIM), -1.0}}, + {{index(Vars::XPPI), 1.0}, + {index(Vars::EPLIM), 1.7}, + {index(Vars::PPI), -1.0}}, + {{index(Vars::PREF), 1.0}, {index(Vars::PEXT), -2.0}}, }; } @@ -2228,20 +2340,20 @@ namespace GridKit { auto expected = expectedJacobian(); expected[index(Vars::VCTRL)] = { - {index(Vars::VLDC), 0.0}, - {index(Vars::VDROOP), 1.0}, - {index(Vars::VCTRL), -1.0}, + {index(Vars::VLDC), 0.0}, + {index(Vars::VDROOP), 1.0}, + {index(Vars::VCTRL), -1.0}, }; expected[index(Vars::ERQ)] = { - {index(Vars::VMEAS), 0.0}, - {index(Vars::QMEAS), -1.0}, - {index(Vars::ERQ), -1.0}, - {externalColumn(index(Ext::vref)), 0.0}, - {externalColumn(index(Ext::qref)), 2.0}, + {index(Vars::VMEAS), 0.0}, + {index(Vars::QMEAS), -1.0}, + {index(Vars::ERQ), -1.0}, + {externalColumn(index(Ext::vref)), 0.0}, + {externalColumn(index(Ext::qref)), 2.0}, }; expected[index(Vars::PEXT)] = { - {index(Vars::PREF), 0.0}, - {index(Vars::PEXT), -2.0}, + {index(Vars::PREF), 0.0}, + {index(Vars::PEXT), -2.0}, }; return expected; } @@ -2260,11 +2372,12 @@ namespace GridKit } bool jacobianRowMatches( - const DependencyTracking::Variable::DependencyMap& actual, - const DependencyTracking::Variable::DependencyMap& expected, - size_t row, - const char* source, - RealT tolerance) const + const DependencyTracking::Variable::DependencyMap& actual, + const DependencyTracking::Variable::DependencyMap& expected, + size_t row, + const char* source, + RealT tolerance + ) const { if (isEqual(actual, expected, tolerance)) { @@ -2277,10 +2390,12 @@ namespace GridKit } bool jacobianMatches( - const std::vector& actual, - const std::vector& expected, - const char* source, - RealT tolerance) const + const std::vector& actual, + const std::vector& + expected, + const char* source, + RealT tolerance + ) const { if (actual.size() != expected.size()) { @@ -2325,10 +2440,10 @@ namespace GridKit fixture.bus.y().setDataUpdated(); } - std::vector dependencyTrackingJacobian( - const Data& data, - TestStatus& success, - RealT alpha = 1.0) const + std::vector + dependencyTrackingJacobian( + const Data& data, TestStatus& success, RealT alpha = 1.0 + ) const { using DepVar = DependencyTracking::Variable; @@ -2347,9 +2462,8 @@ namespace GridKit #ifdef GRIDKIT_ENABLE_ENZYME std::vector enzymeJacobian( - const Data& data, - TestStatus& success, - RealT alpha = 1.0) const + const Data& data, TestStatus& success, RealT alpha = 1.0 + ) const { Fixture fixture(data, kStateVr, kStateVi); fixture.attachAllInputs(); diff --git a/tests/UnitTests/PhasorDynamics/ConverterRegcaTests.hpp b/tests/UnitTests/PhasorDynamics/ConverterRegcaTests.hpp index aef52a7707..0d385419f2 100644 --- a/tests/UnitTests/PhasorDynamics/ConverterRegcaTests.hpp +++ b/tests/UnitTests/PhasorDynamics/ConverterRegcaTests.hpp @@ -37,9 +37,9 @@ namespace GridKit ~ConverterRegcaTests() = default; static constexpr ScalarT kTol = - static_cast(100.0) * std::numeric_limits::epsilon(); + static_cast(100.0) * std::numeric_limits::epsilon(); static constexpr RealT kSmoothTol = - std::max(ONE / (Math::MU * Math::MU), kTol); + std::max(ONE / (Math::MU * Math::MU), kTol); /// Construction, the monitor, and every verify() error class: missing /// and invalid parameters, a null bus, and an unlinked command port. @@ -67,11 +67,14 @@ namespace GridKit bad_switch.parameters[Params::sL] = static_cast(2); success *= configurationRejected( - [&]() - { - PhasorDynamics::Converter::Regca bad_switch_model(&bus, bad_switch); - return bad_switch_model.verify(); - }); + [&]() + { + PhasorDynamics::Converter::Regca bad_switch_model( + &bus, bad_switch + ); + return bad_switch_model.verify(); + } + ); success *= invalidParameterCase(bus, Params::mva, 0.0); success *= invalidParameterCase(bus, Params::IL1, -0.1); @@ -201,9 +204,9 @@ namespace GridKit }; const std::array rejected{{ - {"terminal voltage below VA1", HALF * kVa1}, - {"terminal voltage at Vhvmax", kHvrcmVoltageLimit}, - {"zero terminal voltage", 0.0}, + {"terminal voltage below VA1", HALF * kVa1}, + {"terminal voltage at Vhvmax", kHvrcmVoltageLimit}, + {"zero terminal voltage", 0.0}, }}; for (const auto& test_case : rejected) @@ -351,16 +354,16 @@ namespace GridKit // The LVACM and LVPL states use the midpoint of their breakpoint // interval, where linseg is exactly one half for every MU. const std::array expected{{ - {Vars::VM, "VM", -0.01}, - {Vars::IQ, "IQ", 1.52}, - {Vars::IP, "IP", -0.03}, - {Vars::VT, "VT", 0.5425}, - {Vars::IR, "IR", -0.2875}, - {Vars::II, "II", 0.1265}, - {Vars::IQEXTRA, "IQEXTRA", -0.03}, - {Vars::IL, "IL", 0.35}, - {Vars::PBR, "PBR", 0.0}, - {Vars::QBR, "QBR", 0.0}, + {Vars::VM, "VM", -0.01}, + {Vars::IQ, "IQ", 1.52}, + {Vars::IP, "IP", -0.03}, + {Vars::VT, "VT", 0.5425}, + {Vars::IR, "IR", -0.2875}, + {Vars::II, "II", 0.1265}, + {Vars::IQEXTRA, "IQEXTRA", -0.03}, + {Vars::IL, "IL", 0.35}, + {Vars::PBR, "PBR", 0.0}, + {Vars::QBR, "QBR", 0.0}, }}; const auto& residual = fixture.regca.getResidual(); @@ -402,12 +405,12 @@ namespace GridKit }; const std::array cases{{ - {"negative outward rate", -0.5, -1.5, -0.7}, - {"negative restoring rate", -0.5, 0.5, 5.0}, - {"zero negative rate", 0.0, -0.5, -0.7}, - {"zero positive rate", 0.0, 0.5, 0.7}, - {"positive restoring rate", 0.5, -0.5, -5.0}, - {"positive outward rate", 0.5, 1.5, 0.7}, + {"negative outward rate", -0.5, -1.5, -0.7}, + {"negative restoring rate", -0.5, 0.5, 5.0}, + {"zero negative rate", 0.0, -0.5, -0.7}, + {"zero positive rate", 0.0, 0.5, 0.7}, + {"positive restoring rate", 0.5, -0.5, -5.0}, + {"positive outward rate", 0.5, 1.5, 0.7}, }}; auto* y = fixture.regca.y().getData(); @@ -420,9 +423,9 @@ namespace GridKit success *= (fixture.evaluate() == 0); const auto* f = fixture.regca.getResidual().getData(); - success *= scalarMatches(f[index(Vars::IP)], - test_case.expected_rate, - test_case.label); + success *= scalarMatches( + f[index(Vars::IP)], test_case.expected_rate, test_case.label + ); } } @@ -437,9 +440,9 @@ namespace GridKit // Above the LVPL ceiling, outward motion is blocked and restoring // motion passes. Bypassing LVPL leaves the same outward drive intact. const std::array cases{{ - {"outward rate blocked by LVPL", true, 0.7, 0.0}, - {"restoring rate passes LVPL", true, 0.5, -0.5}, - {"outward rate with LVPL bypassed", false, 0.7, 0.5}, + {"outward rate blocked by LVPL", true, 0.7, 0.0}, + {"restoring rate passes LVPL", true, 0.5, -0.5}, + {"outward rate with LVPL bypassed", false, 0.7, 0.5}, }}; for (const auto& test_case : cases) @@ -463,9 +466,9 @@ namespace GridKit success *= (fixture.evaluate() == 0); const auto* f = fixture.regca.getResidual().getData(); - success *= scalarMatches(f[index(Vars::IP)], - test_case.expected_rate, - test_case.label); + success *= scalarMatches( + f[index(Vars::IP)], test_case.expected_rate, test_case.label + ); } // The moving-ceiling rule: with VM inside the active LVPL segment and @@ -488,9 +491,9 @@ namespace GridKit success *= (fixture.evaluate() == 0); const auto* f = fixture.regca.getResidual().getData(); - success *= scalarMatches(f[index(Vars::IP)], - -1.925, - "falling ceiling drags Ip"); + success *= scalarMatches( + f[index(Vars::IP)], -1.925, "falling ceiling drags Ip" + ); } // Above the upper breakpoint the ceiling releases: outward motion @@ -509,9 +512,9 @@ namespace GridKit success *= (fixture.evaluate() == 0); const auto* f = fixture.regca.getResidual().getData(); - success *= scalarMatches(f[index(Vars::IP)], - 0.7, - "released ceiling above the breakpoint"); + success *= scalarMatches( + f[index(Vars::IP)], 0.7, "released ceiling above the breakpoint" + ); } return success.report(__func__); @@ -535,10 +538,10 @@ namespace GridKit // The unlimited rate is (command - Q0) / Tg with Tg = 0.2. const std::array cases{{ - {"upper recovery limit binds", 0.2, 0.4, 0.5}, - {"lower recovery limit binds", -0.2, -0.4, -0.6}, - {"zero Q0 leaves rising rates unrestricted", 0.0, 0.4, 2.0}, - {"zero Q0 leaves falling rates unrestricted", 0.0, -0.4, -2.0}, + {"upper recovery limit binds", 0.2, 0.4, 0.5}, + {"lower recovery limit binds", -0.2, -0.4, -0.6}, + {"zero Q0 leaves rising rates unrestricted", 0.0, 0.4, 2.0}, + {"zero Q0 leaves falling rates unrestricted", 0.0, -0.4, -2.0}, }}; for (const auto& test_case : cases) @@ -580,10 +583,14 @@ namespace GridKit const auto* y = fixture.regca.y().getData(); const RealT extra_current = y[index(Vars::IQEXTRA)]; - success *= scalarMatches( - extra_current, hvrcmTransition(), "IQEXTRA at initialization"); + success *= scalarMatches( + extra_current, hvrcmTransition(), "IQEXTRA at initialization" + ); success *= scalarMatches( - y[index(Vars::IQ)] - y[index(Vars::IQEXTRA)], 0.1 / terminal_voltage, "IQ preserves Q0 after HVRCM compensation"); + y[index(Vars::IQ)] - y[index(Vars::IQEXTRA)], + 0.1 / terminal_voltage, + "IQ preserves Q0 after HVRCM compensation" + ); success *= scalarMatches(y[index(Vars::QBR)], 0.1, "QBR"); } @@ -646,12 +653,13 @@ namespace GridKit success *= (fixture.evaluate() == 0); - const auto& dependencies = - fixture.regca.getResidual().getData()[index(Vars::IQEXTRA)].getDependencies(); + const auto& dependencies = fixture.regca.getResidual() + .getData()[index(Vars::IQEXTRA)] + .getDependencies(); const DepVar::DependencyMap expected{{ - {2 * index(Vars::VT), 0.5}, // @todo remove these - {2 * index(Vars::IQEXTRA), -0.5}, // @todo remove these + {2 * index(Vars::VT), 0.5}, // @todo remove these + {2 * index(Vars::IQEXTRA), -0.5}, // @todo remove these }}; success *= isEqual(dependencies, expected, kTol); } @@ -668,9 +676,9 @@ namespace GridKit const RealT transition_current = 1.0 / Math::MU; const std::array currents{{ - -transition_current, - 0.0, - transition_current, + -transition_current, + 0.0, + transition_current, }}; for (const bool lvpl_enabled : {false, true}) @@ -681,17 +689,18 @@ namespace GridKit for (const RealT current : currents) { const auto dependency_tracking_jacobian = - dependencyTrackingJacobian(data, current, success); + dependencyTrackingJacobian(data, current, success); const auto enzyme_jacobian = enzymeJacobian(data, current, success); - const auto nrows = std::min(dependency_tracking_jacobian.size(), - enzyme_jacobian.size()); + const auto nrows = std::min( + dependency_tracking_jacobian.size(), enzyme_jacobian.size() + ); for (size_t i = 0; i < nrows; ++i) { - if (!isEqual(dependency_tracking_jacobian[i], - enzyme_jacobian[i], - kTol)) + if (!isEqual( + dependency_tracking_jacobian[i], enzyme_jacobian[i], kTol + )) { std::cout << "Jacobian row " << i << " mismatch between dependency tracking and Enzyme" @@ -815,8 +824,8 @@ namespace GridKit /// Offset whose smooth-ramp tail decays by one significand width. static constexpr RealT kHvrcmOffset = - static_cast(std::numeric_limits::digits) - * std::numbers::ln2_v / Math::MU; + static_cast(std::numeric_limits::digits) + * std::numbers::ln2_v / Math::MU; static constexpr RealT hvrcmTransition() { @@ -942,11 +951,12 @@ namespace GridKit auto data = makeData(); data.parameters[param] = value; return configurationRejected( - [&]() - { - PhasorDynamics::Converter::Regca model(&bus, data); - return model.verify(); - }); + [&]() + { + PhasorDynamics::Converter::Regca model(&bus, data); + return model.verify(); + } + ); } bool allResidualsZero(PhasorDynamics::Converter::Regca& regca) const @@ -970,10 +980,12 @@ namespace GridKit return success; } - bool scalarMatches(ScalarT actual, - ScalarT expected, - const char* label, - RealT tolerance = kTol) const + bool scalarMatches( + ScalarT actual, + ScalarT expected, + const char* label, + RealT tolerance = kTol + ) const { if (isEqual(actual, expected, tolerance)) { @@ -991,8 +1003,8 @@ namespace GridKit /// transition points, where the Jacobian has the richest structure. template void setJacobianState( - PhasorDynamics::Converter::Regca& regca, - RealT current) + PhasorDynamics::Converter::Regca& regca, RealT current + ) { setResidualState(regca); auto* y = regca.y().getData(); @@ -1003,10 +1015,10 @@ namespace GridKit regca.y().setDataUpdated(); } - std::vector dependencyTrackingJacobian( - const Data& data, - RealT current, - TestStatus& success) + std::vector + dependencyTrackingJacobian( + const Data& data, RealT current, TestStatus& success + ) { using DepVar = DependencyTracking::Variable; @@ -1028,9 +1040,8 @@ namespace GridKit } std::vector enzymeJacobian( - const Data& data, - RealT current, - TestStatus& success) + const Data& data, RealT current, TestStatus& success + ) { Fixture fixture(data, kStateVr, kStateVi); fixture.attachIpcmd(kStateIpcmd); diff --git a/tests/UnitTests/PhasorDynamics/ExciterEsdc1aTests.hpp b/tests/UnitTests/PhasorDynamics/ExciterEsdc1aTests.hpp index fa0c04014c..cede683730 100644 --- a/tests/UnitTests/PhasorDynamics/ExciterEsdc1aTests.hpp +++ b/tests/UnitTests/PhasorDynamics/ExciterEsdc1aTests.hpp @@ -41,7 +41,7 @@ namespace GridKit // Rows that divide by a time constant amplify by 1/T; the // worst here is VR, which recovers Ka*(Vr/Ka) through 1/Ta at 31 eps. static constexpr RealT kTol = - static_cast(100.0) * std::numeric_limits::epsilon(); + static_cast(100.0) * std::numeric_limits::epsilon(); /// Construction and every verify() error class, including parameter /// types, parameter relationships, bus ownership, and signal linkage. @@ -91,21 +91,22 @@ namespace GridKit success *= invalidParameterCase(Params::Se2, 0.08); success *= invalidParameterCase(Params::E1, -1.0); - for (const Params parameter : {Params::Tr, - Params::Ka, - Params::Ta, - Params::Tb, - Params::Tc, - Params::Vrmax, - Params::Vrmin, - Params::Ke, - Params::Te, - Params::Kf, - Params::Tf1, - Params::E1, - Params::Se1, - Params::E2, - Params::Se2}) + for (const Params parameter : + {Params::Tr, + Params::Ka, + Params::Ta, + Params::Tb, + Params::Tc, + Params::Vrmax, + Params::Vrmin, + Params::Ke, + Params::Te, + Params::Kf, + Params::Tf1, + Params::E1, + Params::Se1, + Params::E2, + Params::Se2}) { success *= invalidParameterCase(parameter, std::numeric_limits::quiet_NaN()); success *= invalidParameterCase(parameter, std::numeric_limits::infinity()); @@ -335,52 +336,62 @@ namespace GridKit speed_data.parameters[Params::exclim] = false; speed_data.parameters[Params::Vrmin] = -100.0; speed_data.parameters[Params::Vrmax] = 100.0; - success *= initializationRejectedAtomically(speed_data, - 1.2, - {{External::speed, -1.0}, - {External::vref, 77.0}, - {External::vs, 77.0}, - {External::vuel, -77.0}}, - "zero speed multiplier"); - success *= initializationRejectedAtomically(speed_data, - 1.2, - {{External::speed, -1.1}, - {External::vref, 77.0}, - {External::vs, 77.0}, - {External::vuel, -77.0}}, - "negative speed multiplier"); + success *= initializationRejectedAtomically( + speed_data, + 1.2, + {{External::speed, -1.0}, + {External::vref, 77.0}, + {External::vs, 77.0}, + {External::vuel, -77.0}}, + "zero speed multiplier" + ); + success *= initializationRejectedAtomically( + speed_data, + 1.2, + {{External::speed, -1.1}, + {External::vref, 77.0}, + {External::vs, 77.0}, + {External::vuel, -77.0}}, + "negative speed multiplier" + ); // The enabled exciter lower limit rejects a negative field-voltage // state before initialization writes any storage. - success *= initializationRejectedAtomically(makeData(), - -0.2, - {{External::speed, 0.0}, - {External::vref, 77.0}, - {External::vs, 77.0}, - {External::vuel, -0.5}}, - "field-voltage state below zero limit"); + success *= initializationRejectedAtomically( + makeData(), + -0.2, + {{External::speed, 0.0}, + {External::vref, 77.0}, + {External::vs, 77.0}, + {External::vuel, -0.5}}, + "field-voltage state below zero limit" + ); // The seeded field voltage maps to a regulator output above Vrmax. auto limit_data = makeData(); limit_data.parameters[Params::Vrmax] = 0.05; limit_data.parameters[Params::Vrmin] = -0.05; - success *= initializationRejectedAtomically(limit_data, - 1.2, - {{External::speed, 0.0}, - {External::vref, 77.0}, - {External::vs, 77.0}, - {External::vuel, -77.0}}, - "regulator output outside limits"); + success *= initializationRejectedAtomically( + limit_data, + 1.2, + {{External::speed, 0.0}, + {External::vref, 77.0}, + {External::vs, 77.0}, + {External::vuel, -77.0}}, + "regulator output outside limits" + ); // A UEL input above the gate operating point holds the high-value // gate active, which the smooth gate cannot represent at rest. - success *= initializationRejectedAtomically(makeData(), - 1.2, - {{External::speed, 0.0}, - {External::vref, 77.0}, - {External::vs, 77.0}, - {External::vuel, 0.5}}, - "active high-value gate"); + success *= initializationRejectedAtomically( + makeData(), + 1.2, + {{External::speed, 0.0}, + {External::vref, 77.0}, + {External::vs, 77.0}, + {External::vuel, 0.5}}, + "active high-value gate" + ); // A non-finite field-voltage seed is rejected before any signal is // published. @@ -391,42 +402,46 @@ namespace GridKit success *= scalarMatches(nonfinite.input(External::vref), 77.0, "rejected vref preservation"); success *= initializationRejectedAtomically( - speed_data, - 1.2, - {{External::speed, std::numeric_limits::infinity()}, - {External::vref, 77.0}, - {External::vs, 0.0}, - {External::vuel, -77.0}}, - "non-finite speed input"); + speed_data, + 1.2, + {{External::speed, std::numeric_limits::infinity()}, + {External::vref, 77.0}, + {External::vs, 0.0}, + {External::vuel, -77.0}}, + "non-finite speed input" + ); success *= initializationRejectedAtomically( - makeData(), - 1.2, - {{External::speed, 0.0}, - {External::vref, 77.0}, - {External::vs, std::numeric_limits::infinity()}, - {External::vuel, -0.5}}, - "non-finite stabilizer input"); + makeData(), + 1.2, + {{External::speed, 0.0}, + {External::vref, 77.0}, + {External::vs, std::numeric_limits::infinity()}, + {External::vuel, -0.5}}, + "non-finite stabilizer input" + ); success *= initializationRejectedAtomically( - makeData(), - 1.2, - {{External::speed, 0.0}, - {External::vref, 77.0}, - {External::vs, 0.0}, - {External::vuel, -std::numeric_limits::infinity()}}, - "non-finite UEL input"); + makeData(), + 1.2, + {{External::speed, 0.0}, + {External::vref, 77.0}, + {External::vs, 0.0}, + {External::vuel, -std::numeric_limits::infinity()}}, + "non-finite UEL input" + ); success *= initializationRejectedAtomically( - makeData(), - 1.2, - {{External::speed, 0.0}, - {External::vref, 77.0}, - {External::vs, 0.0}, - {External::vuel, -0.5}}, - "zero terminal voltage", - 0.0, - 0.0); + makeData(), + 1.2, + {{External::speed, 0.0}, + {External::vref, 77.0}, + {External::vs, 0.0}, + {External::vuel, -0.5}}, + "zero terminal voltage", + 0.0, + 0.0 + ); // An invalid configuration is rejected before any state is written. auto invalid_data = makeData(); @@ -472,10 +487,12 @@ namespace GridKit success *= speed_fixture.initialize(1.2); success *= (speed_fixture.evaluate() == 0); success *= allResidualsZero(speed_fixture.esdc1a); - success *= scalarMatches( - speed_fixture.esdc1a.y().getData()[static_cast(Internal::EFDP)], - 2.4, - "rescaled EFDP"); + success *= scalarMatches( + speed_fixture.esdc1a.y() + .getData()[static_cast(Internal::EFDP)], + 2.4, + "rescaled EFDP" + ); // The gate stays representable arbitrarily close to its operating // point: the ramp inverse seeds a 0.003 margin exactly. @@ -511,7 +528,8 @@ namespace GridKit setAnswerKeyState(fixture.esdc1a); success *= (fixture.evaluate() == 0); - const std::array()> expected{{ + const std::array()> + expected{{ {Internal::EFDP, 0.04}, {Internal::VC, 0.27}, {Internal::VR, 0.97}, @@ -523,7 +541,7 @@ namespace GridKit {Internal::SE, 0.16}, {Internal::VFE, 0.14}, {Internal::EFD, 1.32}, - }}; + }}; success *= (static_cast(fixture.esdc1a.getResidual().getSize()) == expected.size()); success *= residualsMatch(fixture.esdc1a, expected); @@ -553,18 +571,27 @@ namespace GridKit setState(fixture.esdc1a, {{Internal::VR, 0.6}, {Internal::VFE, 0.2}, {Internal::VF, 0.1}}); setDerivative(fixture.esdc1a, {{Internal::EFDP, 0.1}, {Internal::VF, 0.05}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.esdc1a, - {{Internal::EFDP, 0.7}, {Internal::VF, -19.0 / 140.0}}, - "field-voltage and feedback drive"); + success *= residualsMatch( + fixture.esdc1a, + {{Internal::EFDP, 0.7}, {Internal::VF, -19.0 / 140.0}}, + "field-voltage and feedback drive" + ); // Feedback decays when the field voltage is held at its lower limit. - setState(fixture.esdc1a, - {{Internal::EFDP, -0.2}, {Internal::VR, -0.1}, {Internal::VFE, 0.0}, {Internal::VF, -0.14}}); + setState( + fixture.esdc1a, + {{Internal::EFDP, -0.2}, + {Internal::VR, -0.1}, + {Internal::VFE, 0.0}, + {Internal::VF, -0.14}} + ); setDerivative(fixture.esdc1a, {{Internal::EFDP, 0.0}, {Internal::VF, 0.2}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.esdc1a, - {{Internal::EFDP, 0.0}, {Internal::VF, 0.0}}, - "feedback at the field-voltage limit"); + success *= residualsMatch( + fixture.esdc1a, + {{Internal::EFDP, 0.0}, {Internal::VF, 0.0}}, + "feedback at the field-voltage limit" + ); // Summing junction: UEL < 2 excludes the UEL input from the error. Fixture summing(makeData()); @@ -587,16 +614,20 @@ namespace GridKit junction.input(External::vref) = 1.1; junction.input(External::vs) = 0.05; junction.input(External::vuel) = 0.2; - setState(junction.esdc1a, - {{Internal::VC, 0.9}, - {Internal::VF, 0.02}, - {Internal::EV, 0.1}, - {Internal::VLL, 0.5}, - {Internal::VHV, 0.2}}); + setState( + junction.esdc1a, + {{Internal::VC, 0.9}, + {Internal::VF, 0.02}, + {Internal::EV, 0.1}, + {Internal::VLL, 0.5}, + {Internal::VHV, 0.2}} + ); success *= (junction.evaluate() == 0); - success *= residualsMatch(junction.esdc1a, - {{Internal::EV, 0.33}, {Internal::VHV, 0.3}}, - "summing-junction UEL routing"); + success *= residualsMatch( + junction.esdc1a, + {{Internal::EV, 0.33}, {Internal::VHV, 0.3}}, + "summing-junction UEL routing" + ); // An active lead-lag pair advances the error and relaxes its state. auto lead_lag_data = makeData(); @@ -607,9 +638,11 @@ namespace GridKit setState(lead_lag.esdc1a, {{Internal::XLL, 0.4}, {Internal::EV, 0.7}, {Internal::VLL, 0.5}}); setDerivative(lead_lag.esdc1a, {{Internal::XLL, 0.0}}); success *= (lead_lag.evaluate() == 0); - success *= residualsMatch(lead_lag.esdc1a, - {{Internal::XLL, 0.6}, {Internal::VLL, 0.02}}, - "lead-lag"); + success *= residualsMatch( + lead_lag.esdc1a, + {{Internal::XLL, 0.6}, {Internal::VLL, 0.02}}, + "lead-lag" + ); // The regulator anti-windup blocks outward rates at both limits and // admits restoring rates. @@ -622,10 +655,10 @@ namespace GridKit }; const std::array antiwindup_cases{{ - {"Vrmax blocks an outward regulator rate", 1.5, 0.05, 0.0}, - {"Vrmax admits a restoring regulator rate", 1.5, 0.025, -5.0}, - {"Vrmin blocks an outward regulator rate", -1.5, -0.05, 0.0}, - {"Vrmin admits a restoring regulator rate", -1.5, -0.025, 5.0}, + {"Vrmax blocks an outward regulator rate", 1.5, 0.05, 0.0}, + {"Vrmax admits a restoring regulator rate", 1.5, 0.025, -5.0}, + {"Vrmin blocks an outward regulator rate", -1.5, -0.05, 0.0}, + {"Vrmin admits a restoring regulator rate", -1.5, -0.025, 5.0}, }}; for (const auto& test_case : antiwindup_cases) @@ -633,9 +666,11 @@ namespace GridKit setState(fixture.esdc1a, {{Internal::VR, test_case.vr}, {Internal::VHV, test_case.vhv}}); setDerivative(fixture.esdc1a, {{Internal::VR, 0.0}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.esdc1a, - {{Internal::VR, test_case.expected}}, - test_case.label); + success *= residualsMatch( + fixture.esdc1a, + {{Internal::VR, test_case.expected}}, + test_case.label + ); } return success.report(__func__); @@ -657,8 +692,8 @@ namespace GridKit }; const std::array gate_cases{{ - {"gate selects the lead-lag branch", -0.5, 0.3}, - {"gate selects the UEL branch", 0.8, 0.6}, + {"gate selects the lead-lag branch", -0.5, 0.3}, + {"gate selects the UEL branch", 0.8, 0.6}, }}; Fixture gate(makeData()); @@ -684,8 +719,8 @@ namespace GridKit }; const std::array saturation_order_cases{{ - {"ascending saturation points", 2.0, 0.125, 4.0, 0.5625}, - {"descending saturation points", 4.0, 0.5625, 2.0, 0.125}, + {"ascending saturation points", 2.0, 0.125, 4.0, 0.5625}, + {"descending saturation points", 4.0, 0.5625, 2.0, 0.125}, }}; struct SaturationEvaluation @@ -707,21 +742,24 @@ namespace GridKit success *= saturation.initialize(1.2); const std::array evaluations{{ - {test_case.e1, 0.0, test_case.e1 * test_case.se1}, - {test_case.e2, 0.0, test_case.e2 * test_case.se2}, - {3.0, 0.25, 0.75}, - {1.0, 0.05, -0.05}, + {test_case.e1, 0.0, test_case.e1 * test_case.se1}, + {test_case.e2, 0.0, test_case.e2 * test_case.se2}, + {3.0, 0.25, 0.75}, + {1.0, 0.05, -0.05}, }}; for (const auto& evaluation : evaluations) { - setState(saturation.esdc1a, - {{Internal::EFDP, evaluation.efdp}, - {Internal::SE, evaluation.se}}); + setState( + saturation.esdc1a, + {{Internal::EFDP, evaluation.efdp}, {Internal::SE, evaluation.se}} + ); success *= (saturation.evaluate() == 0); - success *= residualsMatch(saturation.esdc1a, - {{Internal::SE, evaluation.expected}}, - test_case.label); + success *= residualsMatch( + saturation.esdc1a, + {{Internal::SE, evaluation.expected}}, + test_case.label + ); } } @@ -747,11 +785,31 @@ namespace GridKit }; const std::array field_limit_cases{{ - {"below zero blocks an outward field-voltage rate", true, -0.2, -0.1, 0.0}, - {"zero retains the smooth lower-limit transition", true, 0.0, -0.1, -0.1}, - {"above zero admits a downward field-voltage rate", true, 0.2, -0.1, -0.2}, - {"below zero admits a restoring field-voltage rate", true, -0.2, 0.1, 0.2}, - {"disabled lower limit admits an outward rate", false, -0.2, -0.1, -0.2}, + {"below zero blocks an outward field-voltage rate", + true, + -0.2, + -0.1, + 0.0}, + {"zero retains the smooth lower-limit transition", + true, + 0.0, + -0.1, + -0.1}, + {"above zero admits a downward field-voltage rate", + true, + 0.2, + -0.1, + -0.2}, + {"below zero admits a restoring field-voltage rate", + true, + -0.2, + 0.1, + 0.2}, + {"disabled lower limit admits an outward rate", + false, + -0.2, + -0.1, + -0.2}, }}; for (const auto& test_case : field_limit_cases) @@ -761,15 +819,19 @@ namespace GridKit Fixture limit(data); limit.attachAllInputs(); success *= limit.initialize(1.2); - setState(limit.esdc1a, - {{Internal::EFDP, test_case.efdp}, - {Internal::VR, test_case.vr}, - {Internal::VFE, 0.0}}); + setState( + limit.esdc1a, + {{Internal::EFDP, test_case.efdp}, + {Internal::VR, test_case.vr}, + {Internal::VFE, 0.0}} + ); setDerivative(limit.esdc1a, {{Internal::EFDP, 0.0}}); success *= (limit.evaluate() == 0); - success *= residualsMatch(limit.esdc1a, - {{Internal::EFDP, test_case.expected}}, - test_case.label); + success *= residualsMatch( + limit.esdc1a, + {{Internal::EFDP, test_case.expected}}, + test_case.label + ); } // The lower-limit selector does not alter the algebraic exciter @@ -786,13 +848,17 @@ namespace GridKit feedback.attachAllInputs(); feedback.input(External::vuel) = -0.5; success *= feedback.initialize(1.2); - setState(feedback.esdc1a, - {{Internal::EFDP, 1.0}, {Internal::SE, 0.0}, {Internal::VFE, 0.0}}); + setState( + feedback.esdc1a, + {{Internal::EFDP, 1.0}, {Internal::SE, 0.0}, {Internal::VFE, 0.0}} + ); success *= (feedback.evaluate() == 0); - success *= residualsMatch(feedback.esdc1a, - {{Internal::VFE, -0.2}}, - enabled ? "feedback with lower limit enabled" - : "feedback with lower limit disabled"); + success *= residualsMatch( + feedback.esdc1a, + {{Internal::VFE, -0.2}}, + enabled ? "feedback with lower limit enabled" + : "feedback with lower limit disabled" + ); } // At the lower-limit transition, pin the assembled alpha = 1 @@ -803,28 +869,36 @@ namespace GridKit Fixture transition(makeData()); transition.attachAllInputs(); success *= transition.initialize(1.2); - setState(transition.esdc1a, - {{Internal::EFDP, 0.0}, {Internal::VR, -0.1}, {Internal::VFE, 0.0}}); + setState( + transition.esdc1a, + {{Internal::EFDP, 0.0}, {Internal::VR, -0.1}, {Internal::VFE, 0.0}} + ); setDerivative(transition.esdc1a, {{Internal::EFDP, 0.0}}); numberVariables(transition); success *= (transition.evaluate() == 0); const auto& dependencies = - transition.esdc1a.getResidual().getData()[static_cast(Internal::EFDP)].getDependencies(); + transition.esdc1a.getResidual() + .getData()[static_cast(Internal::EFDP)] + .getDependencies(); const DepVar::DependencyMap expected{{ - {2 * static_cast(Internal::EFDP), -12.0}, // @todo Remove these - {2 * static_cast(Internal::EFDP) + 1, -1.0}, // @todo Remove these - {2 * static_cast(Internal::VR), 1.0}, // @todo Remove these - {2 * static_cast(Internal::VFE), -1.0}, // @todo Remove these + {2 * static_cast(Internal::EFDP), + -12.0}, // @todo Remove these + {2 * static_cast(Internal::EFDP) + 1, + -1.0}, // @todo Remove these + {2 * static_cast(Internal::VR), 1.0}, // @todo Remove these + {2 * static_cast(Internal::VFE), + -1.0}, // @todo Remove these }}; success *= isEqual(dependencies, expected, kTol); } // The speed multiplier scales the published field voltage only when // enabled. - for (const auto& [enabled, expected] : std::array, 2>{{ - {false, 0.0}, - {true, 0.06}, + for (const auto& [enabled, expected] : + std::array, 2>{{ + {false, 0.0}, + {true, 0.06}, }}) { auto data = makeData(); @@ -835,10 +909,11 @@ namespace GridKit speed.input(External::speed) = 0.05; setState(speed.esdc1a, {{Internal::EFDP, 1.2}, {Internal::EFD, 1.2}}); success *= (speed.evaluate() == 0); - success *= residualsMatch(speed.esdc1a, - {{Internal::EFD, expected}}, - enabled ? "speed multiplier enabled" - : "speed multiplier disabled"); + success *= residualsMatch( + speed.esdc1a, + {{Internal::EFD, expected}}, + enabled ? "speed multiplier enabled" : "speed multiplier disabled" + ); } return success.report(__func__); @@ -896,9 +971,10 @@ namespace GridKit private: std::array()> input_values_{}; std::array()> input_indices_{}; - std::array, - Utilities::enum_size()> - input_nodes_{}; + std::array< + PhasorDynamics::SignalNode, + Utilities::enum_size()> + input_nodes_{}; PhasorDynamics::SignalNode efd_node_; @@ -927,13 +1003,17 @@ namespace GridKit } esdc1a.getPorts().in.template port().connect( - &input_nodes_[static_cast(External::speed)]); + &input_nodes_[static_cast(External::speed)] + ); esdc1a.getPorts().in.template port().connect( - &input_nodes_[static_cast(External::vref)]); + &input_nodes_[static_cast(External::vref)] + ); esdc1a.getPorts().in.template port().connect( - &input_nodes_[static_cast(External::vs)]); + &input_nodes_[static_cast(External::vs)] + ); esdc1a.getPorts().in.template port().connect( - &input_nodes_[static_cast(External::vuel)]); + &input_nodes_[static_cast(External::vuel)] + ); } /// Seed the assigned field-voltage node. @@ -1111,24 +1191,28 @@ namespace GridKit template void setAnswerKeyState(PhasorDynamics::Exciter::Esdc1a& esdc1a) const { - setState(esdc1a, - {{Internal::EFDP, 2.4}, - {Internal::VC, 0.95}, - {Internal::VR, 0.45}, - {Internal::VF, 0.04}, - {Internal::XLL, 0.30}, - {Internal::EV, 0.36}, - {Internal::VLL, 0.33}, - {Internal::VHV, 0.03}, - {Internal::SE, 0.08}, - {Internal::VFE, 0.42}, - {Internal::EFD, 1.2}}); - setDerivative(esdc1a, - {{Internal::EFDP, 0.01}, - {Internal::VC, -0.02}, - {Internal::VR, 0.03}, - {Internal::VF, -0.02}, - {Internal::XLL, 0.05}}); + setState( + esdc1a, + {{Internal::EFDP, 2.4}, + {Internal::VC, 0.95}, + {Internal::VR, 0.45}, + {Internal::VF, 0.04}, + {Internal::XLL, 0.30}, + {Internal::EV, 0.36}, + {Internal::VLL, 0.33}, + {Internal::VHV, 0.03}, + {Internal::SE, 0.08}, + {Internal::VFE, 0.42}, + {Internal::EFD, 1.2}} + ); + setDerivative( + esdc1a, + {{Internal::EFDP, 0.01}, + {Internal::VC, -0.02}, + {Internal::VR, 0.03}, + {Internal::VF, -0.02}, + {Internal::XLL, 0.05}} + ); } /// Omitting every parameter must give exactly the model built from the @@ -1156,21 +1240,27 @@ namespace GridKit { success = false; } - if (!vectorUnchanged(implicit_defaults.esdc1a.y(), - copyVector(explicit_defaults.esdc1a.y()), - "documented-default state")) + if (!vectorUnchanged( + implicit_defaults.esdc1a.y(), + copyVector(explicit_defaults.esdc1a.y()), + "documented-default state" + )) { success = false; } - if (!vectorUnchanged(implicit_defaults.esdc1a.yp(), - copyVector(explicit_defaults.esdc1a.yp()), - "documented-default derivative")) + if (!vectorUnchanged( + implicit_defaults.esdc1a.yp(), + copyVector(explicit_defaults.esdc1a.yp()), + "documented-default derivative" + )) { success = false; } - if (!vectorUnchanged(implicit_defaults.esdc1a.getResidual(), - copyVector(explicit_defaults.esdc1a.getResidual()), - "documented-default residual")) + if (!vectorUnchanged( + implicit_defaults.esdc1a.getResidual(), + copyVector(explicit_defaults.esdc1a.getResidual()), + "documented-default residual" + )) { success = false; } @@ -1187,9 +1277,11 @@ namespace GridKit { success = false; } - if (!vectorUnchanged(implicit_defaults.esdc1a.getResidual(), - copyVector(explicit_defaults.esdc1a.getResidual()), - "documented-default dynamic residual")) + if (!vectorUnchanged( + implicit_defaults.esdc1a.getResidual(), + copyVector(explicit_defaults.esdc1a.getResidual()), + "documented-default dynamic residual" + )) { success = false; } @@ -1202,11 +1294,12 @@ namespace GridKit auto data = makeData(); data.parameters[parameter] = value; return configurationRejected( - [&]() - { - Fixture fixture(data); - return fixture.esdc1a.verify(); - }); + [&]() + { + Fixture fixture(data); + return fixture.esdc1a.verify(); + } + ); } template @@ -1222,15 +1315,18 @@ namespace GridKit std::vector copyVector(const VectorT& vector) const { const auto* values = vector.getData(); - return std::vector(values, - values + static_cast(vector.getSize())); + return std::vector( + values, values + static_cast(vector.getSize()) + ); } /// Every row of a vector still holds its snapshot value. template - bool vectorUnchanged(const VectorT& vector, - const std::vector& snapshot, - const char* what) const + bool vectorUnchanged( + const VectorT& vector, + const std::vector& snapshot, + const char* what + ) const { bool success = true; const auto* values = vector.getData(); @@ -1246,10 +1342,9 @@ namespace GridKit /// An initialization input retains exactly the value supplied by its /// owner, including signed infinities and NaN. - bool scalarPreserved(RealT actual, - RealT expected, - const char* what, - size_t row) const + bool scalarPreserved( + RealT actual, RealT expected, const char* what, size_t row + ) const { bool ret = actual == expected; if (std::isnan(expected)) @@ -1281,12 +1376,14 @@ namespace GridKit fixture.esdc1a.yp().setDataUpdated(); } - bool initializationRejectedAtomically(const Data& data, - RealT efd_seed, - const ExternalRows& inputs, - const char* label, - RealT vr = 0.8, - RealT vi = 0.6) const + bool initializationRejectedAtomically( + const Data& data, + RealT efd_seed, + const ExternalRows& inputs, + const char* label, + RealT vr = 0.8, + RealT vi = 0.6 + ) const { Fixture fixture(data, vr, vi); fixture.attachAllInputs(); @@ -1316,10 +1413,12 @@ namespace GridKit } for (const auto& [port, value] : inputs) { - if (!scalarPreserved(static_cast(fixture.input(port)), - value, - "external input", - static_cast(port))) + if (!scalarPreserved( + static_cast(fixture.input(port)), + value, + "external input", + static_cast(port) + )) { success = false; } @@ -1338,8 +1437,10 @@ namespace GridKit /// Write state rows and publish the update, folding in the /// setDataUpdated() that a hand-written write block has to remember. template - void setState(PhasorDynamics::Exciter::Esdc1a& esdc1a, - const InternalRows& rows) const + void setState( + PhasorDynamics::Exciter::Esdc1a& esdc1a, + const InternalRows& rows + ) const { auto* y = esdc1a.y().getData(); for (const auto& [variable, value] : rows) @@ -1351,8 +1452,10 @@ namespace GridKit /// setState() for the derivative vector. template - void setDerivative(PhasorDynamics::Exciter::Esdc1a& esdc1a, - const InternalRows& rows) const + void setDerivative( + PhasorDynamics::Exciter::Esdc1a& esdc1a, + const InternalRows& rows + ) const { auto* yp = esdc1a.yp().getData(); for (const auto& [variable, value] : rows) @@ -1365,11 +1468,13 @@ namespace GridKit /// Compare one vector row against its expected value. Every row check /// in this suite reports through here, so failures share one format. /// Rows are named by their canonical internal-variable enumeration. - static bool rowMatches(RealT actual, - RealT expected, - const char* what, - size_t row, - const char* context) + static bool rowMatches( + RealT actual, + RealT expected, + const char* what, + size_t row, + const char* context + ) { if (isEqual(actual, expected, kTol)) { @@ -1383,10 +1488,12 @@ namespace GridKit /// Check selected rows of a model vector against expected values. template - bool rowsMatch(const VectorT& vector, - const RowsT& rows, - const char* what, - const char* context) const + bool rowsMatch( + const VectorT& vector, + const RowsT& rows, + const char* what, + const char* context + ) const { bool success = true; const auto* values = vector.getData(); @@ -1401,17 +1508,21 @@ namespace GridKit return success; } - bool residualsMatch(const Esdc1aT& esdc1a, - const InternalRows& rows, - const char* context = "") const + bool residualsMatch( + const Esdc1aT& esdc1a, + const InternalRows& rows, + const char* context = "" + ) const { return rowsMatch(esdc1a.getResidual(), rows, "residual", context); } template - bool residualsMatch(const Esdc1aT& esdc1a, - const std::array& rows, - const char* context = "") const + bool residualsMatch( + const Esdc1aT& esdc1a, + const std::array& rows, + const char* context = "" + ) const { return rowsMatch(esdc1a.getResidual(), rows, "residual", context); } @@ -1437,10 +1548,12 @@ namespace GridKit return success; } - bool scalarMatches(ScalarT actual, - ScalarT expected, - const char* label, - ScalarT tolerance = kTol) const + bool scalarMatches( + ScalarT actual, + ScalarT expected, + const char* label, + ScalarT tolerance = kTol + ) const { if (isEqual(actual, expected, tolerance)) { @@ -1479,9 +1592,8 @@ namespace GridKit } #ifdef GRIDKIT_ENABLE_ENZYME - std::vector dependencyTrackingJacobian( - const Data& data, - TestStatus& success) const + std::vector + dependencyTrackingJacobian(const Data& data, TestStatus& success) const { using DepVar = DependencyTracking::Variable; @@ -1500,8 +1612,8 @@ namespace GridKit } std::vector enzymeJacobian( - const Data& data, - TestStatus& success) const + const Data& data, TestStatus& success + ) const { Fixture fixture(data, kStateVr, kStateVi); fixture.attachAllInputs(); diff --git a/tests/UnitTests/PhasorDynamics/ExciterIeeet1Tests.hpp b/tests/UnitTests/PhasorDynamics/ExciterIeeet1Tests.hpp index 757b2dcf92..05cc50660b 100644 --- a/tests/UnitTests/PhasorDynamics/ExciterIeeet1Tests.hpp +++ b/tests/UnitTests/PhasorDynamics/ExciterIeeet1Tests.hpp @@ -29,7 +29,7 @@ namespace GridKit ~ExciterIeeet1Tests() = default; static constexpr RealT kTol = - static_cast(4.0) * std::numeric_limits::epsilon(); + static_cast(4.0) * std::numeric_limits::epsilon(); TestOutcome constructor() { @@ -248,9 +248,9 @@ namespace GridKit const auto* f = exciter.getResidual().getData(); // vref absorbs both limiter inputs; later changes enter with unit gain. - success *= isEqual(vref_node.read(), - y[0] + y[4] + y[5] - vuel_value - voel_value, - kTol); + success *= isEqual( + vref_node.read(), y[0] + y[4] + y[5] - vuel_value - voel_value, kTol + ); success *= isEqual(f[4], static_cast(0.0), kTol); vuel_value = -0.3; diff --git a/tests/UnitTests/PhasorDynamics/ExciterSexsPtiTests.hpp b/tests/UnitTests/PhasorDynamics/ExciterSexsPtiTests.hpp index 9898a0f9c0..3fc1d561ae 100644 --- a/tests/UnitTests/PhasorDynamics/ExciterSexsPtiTests.hpp +++ b/tests/UnitTests/PhasorDynamics/ExciterSexsPtiTests.hpp @@ -385,9 +385,8 @@ namespace GridKit system.y().setDataUpdated(); success *= (system.evaluateResidual() == 0); const auto* f = system.getResidual().getData(); - success *= isEqual(f[consumer_vtr_residual], - static_cast(0.75), - kTol); + success *= + isEqual(f[consumer_vtr_residual], static_cast(0.75), kTol); return success.report(__func__); } diff --git a/tests/UnitTests/PhasorDynamics/GenClassicalTests.hpp b/tests/UnitTests/PhasorDynamics/GenClassicalTests.hpp index a089cf1ccb..0f417d42ec 100644 --- a/tests/UnitTests/PhasorDynamics/GenClassicalTests.hpp +++ b/tests/UnitTests/PhasorDynamics/GenClassicalTests.hpp @@ -66,7 +66,7 @@ namespace GridKit auto data = makeGenClassicalData(); PhasorDynamics::Component* machine = - new PhasorDynamics::GenClassical(bus, data); + new PhasorDynamics::GenClassical(bus, data); success *= (machine != nullptr); @@ -97,11 +97,11 @@ namespace GridKit data.parameters[Parameter::Xdp] = RealT{2.3}; const std::vector var_answer = { - 3.0 * std::numbers::pi_v / 4.0, // delta - 0.0, // omega - 3.5, // Te - 1.0, // Ir - 2.0, // Ii + 3.0 * std::numbers::pi_v / 4.0, // delta + 0.0, // omega + 3.5, // Te + 1.0, // Ir + 2.0, // Ii }; PhasorDynamics::Bus bus(1.0, 1.0); @@ -381,12 +381,7 @@ namespace GridKit gen.getPorts().in.template port().connect(&pmech); gen.getPorts().in.template port().connect(&efd); - const std::vector res_answer = { - 0.0, - -0.5, - -6.0, - 2.0, - -6.0}; + const std::vector res_answer = {0.0, -0.5, -6.0, 2.0, -6.0}; bus.allocate(); bus.initialize(); diff --git a/tests/UnitTests/PhasorDynamics/GenrouTests.hpp b/tests/UnitTests/PhasorDynamics/GenrouTests.hpp index 9c4530565d..c001b5a63f 100644 --- a/tests/UnitTests/PhasorDynamics/GenrouTests.hpp +++ b/tests/UnitTests/PhasorDynamics/GenrouTests.hpp @@ -70,7 +70,7 @@ namespace GridKit auto* bus = new PhasorDynamics::Bus(1.0, 0.0); PhasorDynamics::Component* machine = - new PhasorDynamics::Genrou(bus, GenrouDataT{}); + new PhasorDynamics::Genrou(bus, GenrouDataT{}); success *= (machine != nullptr); @@ -227,23 +227,24 @@ namespace GridKit // Answer key is available only in double precision. // Therefore, only double precision tests are done at this time. const std::vector res_answer = { - -2.0 * std::numbers::pi_v * 60.0, - -static_cast(10.) / static_cast(9.), - -static_cast(223.) / static_cast(525.), - -54.75, - -9.6, - static_cast(892.) / static_cast(375.), - 0.21, - -0.07, - -0.19223748416156686, - 2.0, - 1.4, - 0.31, - 2.211, - 0.85, - 1.2, - -static_cast(13.) / static_cast(130.), - -static_cast(143.) / static_cast(52.)}; + -2.0 * std::numbers::pi_v * 60.0, + -static_cast(10.) / static_cast(9.), + -static_cast(223.) / static_cast(525.), + -54.75, + -9.6, + static_cast(892.) / static_cast(375.), + 0.21, + -0.07, + -0.19223748416156686, + 2.0, + 1.4, + 0.31, + 2.211, + 0.85, + 1.2, + -static_cast(13.) / static_cast(130.), + -static_cast(143.) / static_cast(52.) + }; bus.allocate(); bus.initialize(); diff --git a/tests/UnitTests/PhasorDynamics/GensalTests.hpp b/tests/UnitTests/PhasorDynamics/GensalTests.hpp index 80c0b43dd7..bd0a408758 100644 --- a/tests/UnitTests/PhasorDynamics/GensalTests.hpp +++ b/tests/UnitTests/PhasorDynamics/GensalTests.hpp @@ -66,7 +66,7 @@ namespace GridKit auto data = makeGensalData(); PhasorDynamics::Component* machine = - new PhasorDynamics::Gensal(bus, data); + new PhasorDynamics::Gensal(bus, data); success *= (machine != nullptr); @@ -267,20 +267,21 @@ namespace GridKit PhasorDynamics::Gensal gen(&bus, data); const std::vector res_answer = { - 0.0, - 0.0, - 2.2083333333333335, - -1.028125, - 0.65, - 0.0, - 0.2, - -1.1, - -1.4, - 1.8125, - 0.5, - 0.25, - 2.95, - -1.25}; + 0.0, + 0.0, + 2.2083333333333335, + -1.028125, + 0.65, + 0.0, + 0.2, + -1.1, + -1.4, + 1.8125, + 0.5, + 0.25, + 2.95, + -1.25 + }; bus.allocate(); bus.initialize(); diff --git a/tests/UnitTests/PhasorDynamics/GovernorGastPtiTests.hpp b/tests/UnitTests/PhasorDynamics/GovernorGastPtiTests.hpp index 131a6d1469..6f5508e7c0 100644 --- a/tests/UnitTests/PhasorDynamics/GovernorGastPtiTests.hpp +++ b/tests/UnitTests/PhasorDynamics/GovernorGastPtiTests.hpp @@ -41,7 +41,7 @@ namespace GridKit // Smooth gates, base conversion, and time-constant scaling accumulate a // few floating-point operations beyond one machine epsilon. static constexpr RealT kTol = - static_cast(10.0) * std::numeric_limits::epsilon(); + static_cast(10.0) * std::numeric_limits::epsilon(); /// Construction, parameter types and domains, lifecycle, and signal linkage. TestOutcome validation() @@ -101,16 +101,16 @@ namespace GridKit success *= invalidParameterCase(Params::Trate, -1.0); const std::array real_parameters{{ - Params::R, - Params::T1, - Params::T2, - Params::T3, - Params::At, - Params::Kt, - Params::Vmax, - Params::Vmin, - Params::Dturb, - Params::Trate, + Params::R, + Params::T1, + Params::T2, + Params::T3, + Params::At, + Params::Kt, + Params::Vmax, + Params::Vmin, + Params::Dturb, + Params::Trate, }}; for (const Params parameter : real_parameters) { @@ -120,10 +120,12 @@ namespace GridKit // A finite serialized rating that overflows its MW-to-VA conversion is // still an invalid component base. - success *= invalidParameterCase(Params::Trate, - std::numeric_limits::max()); - success *= invalidParameterCase(Params::Trate, - std::numeric_limits::denorm_min()); + success *= invalidParameterCase( + Params::Trate, std::numeric_limits::max() + ); + success *= invalidParameterCase( + Params::Trate, std::numeric_limits::denorm_min() + ); // Equal configured limits are valid; reversed limits are not. auto equal = makeData(); @@ -147,18 +149,20 @@ namespace GridKit integer_real.parameters[Params::Trate] = static_cast(50); Fixture integer_fixture(integer_real); success *= integer_fixture.initialize(0.4); - success *= stateMatches(integer_fixture.gastpti, - {{Internal::XFLOW, 0.8}}, - "integer-valued component base"); + success *= stateMatches( + integer_fixture.gastpti, + {{Internal::XFLOW, 0.8}}, + "integer-valued component base" + ); success *= invalidParameterCase(Params::T1, true); const std::array invalid_system_bases{{ - -100.0e6, - ZERO, - std::numeric_limits::denorm_min(), - std::numeric_limits::quiet_NaN(), - std::numeric_limits::infinity(), + -100.0e6, + ZERO, + std::numeric_limits::denorm_min(), + std::numeric_limits::quiet_NaN(), + std::numeric_limits::infinity(), }}; for (const RealT system_base : invalid_system_bases) { @@ -181,10 +185,10 @@ namespace GridKit }; const std::array time_constant_cases{{ - {0.0, 1.0}, - {0.0005, 1.0}, - {0.001, 1.0}, - {0.002, 0.5}, + {0.0, 1.0}, + {0.0005, 1.0}, + {0.001, 1.0}, + {0.002, 0.5}, }}; for (const auto& test_case : time_constant_cases) { @@ -195,18 +199,21 @@ namespace GridKit Fixture time_fixture(time_data); success *= time_fixture.initialize(0.4); - setState(time_fixture.gastpti, - {{Internal::XVALVE, 0.401}, - {Internal::XFLOW, 0.4}, - {Internal::XTEMP, 0.399}, - {Internal::VLV, 0.402}}); + setState( + time_fixture.gastpti, + {{Internal::XVALVE, 0.401}, + {Internal::XFLOW, 0.4}, + {Internal::XTEMP, 0.399}, + {Internal::VLV, 0.402}} + ); success *= (time_fixture.evaluate() == 0); success *= residualsMatch( - time_fixture.gastpti, - {{Internal::XVALVE, test_case.expected_residual}, - {Internal::XFLOW, test_case.expected_residual}, - {Internal::XTEMP, test_case.expected_residual}}, - "in-place time-constant floor boundary"); + time_fixture.gastpti, + {{Internal::XVALVE, test_case.expected_residual}, + {Internal::XFLOW, test_case.expected_residual}, + {Internal::XTEMP, test_case.expected_residual}}, + "in-place time-constant floor boundary" + ); } Log::setVerbosity(previous_verbosity); @@ -238,9 +245,9 @@ namespace GridKit success *= scalarMatches(y[index(Internal::VLV)], 0.8, "VLV at the fuel flow"); success *= scalarPreserved(fixture.pmech(), 0.4, "preserved pmech seed"); - success *= scalarPreserved(fixture.input(index(External::speed)), - 0.0, - "preserved omega input"); + success *= scalarPreserved( + fixture.input(index(External::speed)), 0.0, "preserved omega input" + ); success *= scalarMatches(fixture.input(index(External::pref)), 0.4, "published pref"); RealT time = 0.0; @@ -294,16 +301,20 @@ namespace GridKit // base ratio. fixture.input(index(External::pref)) = 0.5; // the published 0.4 plus a 0.1 step success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.gastpti, - {{Internal::VLOAD, 0.01}}, - "reference step on the component base"); + success *= residualsMatch( + fixture.gastpti, + {{Internal::VLOAD, 0.01}}, + "reference step on the component base" + ); // GridKit deliberately leaves references above At uncapped. fixture.input(index(External::pref)) = 1.1; // 2.2 on component base; At = 2.0 success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.gastpti, - {{Internal::VLOAD, 0.07}}, - "uncapped reference above At"); + success *= residualsMatch( + fixture.gastpti, + {{Internal::VLOAD, 0.07}}, + "uncapped reference above At" + ); // Unattached ports fall back to the reference latched by // initialize(), so the same steady state holds without a controller. @@ -332,25 +343,33 @@ namespace GridKit speed_fixture.attachAllInputs(); speed_fixture.input(index(External::speed)) = omega; success *= speed_fixture.initialize(initial_pmech); - success *= stateMatches(speed_fixture.gastpti, - {{Internal::XVALVE, xflow}, - {Internal::XFLOW, xflow}, - {Internal::XTEMP, xflow}, - {Internal::VTEMP, vtemp}, - {Internal::VLV, xflow}}, - "signed nonzero-speed initialization"); - success *= scalarPreserved(speed_fixture.pmech(), - initial_pmech, - "signed-speed pmech preservation"); - success *= scalarPreserved(speed_fixture.input(index(External::speed)), - omega, - "signed-speed input preservation"); + success *= stateMatches( + speed_fixture.gastpti, + {{Internal::XVALVE, xflow}, + {Internal::XFLOW, xflow}, + {Internal::XTEMP, xflow}, + {Internal::VTEMP, vtemp}, + {Internal::VLV, xflow}}, + "signed nonzero-speed initialization" + ); + success *= scalarPreserved( + speed_fixture.pmech(), + initial_pmech, + "signed-speed pmech preservation" + ); + success *= scalarPreserved( + speed_fixture.input(index(External::speed)), + omega, + "signed-speed input preservation" + ); const auto* speed_y = speed_fixture.gastpti.y().getData(); const RealT vload = static_cast(speed_y[index(Internal::VLOAD)]); const RealT pref = component_to_system * (vload + omega / droop); - success *= scalarMatches(speed_fixture.input(index(External::pref)), - pref, - "signed-speed pref publication"); + success *= scalarMatches( + speed_fixture.input(index(External::pref)), + pref, + "signed-speed pref publication" + ); success *= (speed_fixture.evaluate() == 0); success *= allResidualsZero(speed_fixture.gastpti); } @@ -379,16 +398,17 @@ namespace GridKit // makeResidualData() halves the power base, so a 0.4 seed is a 0.8 // component-base fuel flow. const std::array rejected{{ - {"temperature-gate margin at equality", 0.8, 0.4}, - {"temperature-gate margin negative", 0.0, 0.4}, + {"temperature-gate margin at equality", 0.8, 0.4}, + {"temperature-gate margin negative", 0.0, 0.4}, }}; for (const auto& test_case : rejected) { auto data = makeResidualData(); data.parameters[Params::At] = test_case.at; - success *= initializationRejectedAtomically( - data, test_case.pmech, test_case.label); + success *= initializationRejectedAtomically( + data, test_case.pmech, test_case.label + ); } // An invalid configuration is rejected before any state is written. @@ -409,62 +429,70 @@ namespace GridKit success *= vectorUnchanged(invalid_fixture.gastpti.yp(), invalid_yp, "derivative"); const std::array nonfinite_values{{ - std::numeric_limits::quiet_NaN(), - std::numeric_limits::infinity(), - -std::numeric_limits::infinity(), + std::numeric_limits::quiet_NaN(), + std::numeric_limits::infinity(), + -std::numeric_limits::infinity(), }}; for (const RealT pmech : nonfinite_values) { success *= initializationRejectedAtomically( - makeResidualData(), pmech, "non-finite pmech seed"); + makeResidualData(), pmech, "non-finite pmech seed" + ); } for (const RealT omega : nonfinite_values) { success *= initializationRejectedAtomically( - makeResidualData(), 0.4, "non-finite speed seed", omega); + makeResidualData(), 0.4, "non-finite speed seed", omega + ); } // Each case starts from finite parameters and finite seeds, then // overflows a different initialization candidate. None may commit. auto power_candidate = makeResidualData(); - success *= initializationRejectedAtomically( - power_candidate, - std::numeric_limits::max(), - "non-finite component-base power candidate"); + success *= initializationRejectedAtomically( + power_candidate, + std::numeric_limits::max(), + "non-finite component-base power candidate" + ); auto flow_candidate = makeResidualData(); flow_candidate.parameters[Params::Dturb] = std::numeric_limits::max(); - success *= initializationRejectedAtomically( - flow_candidate, 0.4, "non-finite fuel-flow candidate", 2.0); + success *= initializationRejectedAtomically( + flow_candidate, 0.4, "non-finite fuel-flow candidate", 2.0 + ); auto temperature_candidate = makeResidualData(); temperature_candidate.parameters[Params::At] = std::numeric_limits::max(); - success *= initializationRejectedAtomically( - temperature_candidate, 0.4, "non-finite temperature candidate"); + success *= initializationRejectedAtomically( + temperature_candidate, 0.4, "non-finite temperature candidate" + ); auto reference_candidate = makeResidualData(); reference_candidate.parameters[Params::R] = std::numeric_limits::denorm_min(); reference_candidate.parameters[Params::Dturb] = ZERO; - success *= initializationRejectedAtomically( - reference_candidate, - 0.4, - "non-finite reference candidate", - std::numeric_limits::max()); + success *= initializationRejectedAtomically( + reference_candidate, + 0.4, + "non-finite reference candidate", + std::numeric_limits::max() + ); // Normal response expands its effective bounds to an over-rated initial // flow and remains exactly at rest. Fixture over_rated(makeResidualData()); over_rated.attachAllInputs(); success *= over_rated.initialize(0.6); // fuel flow 1.2 above Vmax = 1.1 - success *= stateMatches(over_rated.gastpti, - {{Internal::XVALVE, 1.2}, - {Internal::XFLOW, 1.2}, - {Internal::VLV, 1.2}}, - "over-rated dispatch"); - success *= scalarPreserved(over_rated.pmech(), - 0.6, - "preserved over-rated pmech seed"); + success *= stateMatches( + over_rated.gastpti, + {{Internal::XVALVE, 1.2}, + {Internal::XFLOW, 1.2}, + {Internal::VLV, 1.2}}, + "over-rated dispatch" + ); + success *= scalarPreserved( + over_rated.pmech(), 0.6, "preserved over-rated pmech seed" + ); success *= (over_rated.evaluate() == 0); success *= allResidualsZero(over_rated.gastpti); @@ -491,22 +519,28 @@ namespace GridKit } success *= vectorUnchanged(reinitialize.gastpti.y(), y_before, "reinitialized state"); success *= vectorUnchanged(reinitialize.gastpti.yp(), yp_before, "reinitialized derivative"); - success *= scalarPreserved(reinitialize.input(index(External::pref)), - pref_before, - "reinitialized pref"); + success *= scalarPreserved( + reinitialize.input(index(External::pref)), + pref_before, + "reinitialized pref" + ); reinitialize.seedPmech(over_rated_pmech); const RealT upper_boundary = y_before[index(Internal::XVALVE)]; - setState(reinitialize.gastpti, - {{Internal::XVALVE, upper_boundary}, - {Internal::VLV, upper_boundary + boundary_command}}); + setState( + reinitialize.gastpti, + {{Internal::XVALVE, upper_boundary}, + {Internal::VLV, upper_boundary + boundary_command}} + ); setDerivative(reinitialize.gastpti, {{Internal::XVALVE, 0.0}}); success *= (reinitialize.evaluate() == 0); const RealT expected_boundary_response = - boundary_weight * boundary_command / valve_time_constant; - success *= residualsMatch(reinitialize.gastpti, - {{Internal::XVALVE, expected_boundary_response}}, - "failed reinitialization preserves effective limits"); + boundary_weight * boundary_command / valve_time_constant; + success *= residualsMatch( + reinitialize.gastpti, + {{Internal::XVALVE, expected_boundary_response}}, + "failed reinitialization preserves effective limits" + ); struct EqualLimitTemperatureCase { @@ -515,10 +549,11 @@ namespace GridKit RealT vtemp; }; - const std::array equal_limit_temperature_cases{{ + const std::array + equal_limit_temperature_cases{{ {"equal valve limits at the temperature limit", 0.8, 0.8}, {"equal valve limits above the temperature limit", 0.0, -0.32}, - }}; + }}; for (const auto& test_case : equal_limit_temperature_cases) { auto equal_limit_data = makeResidualData(); @@ -529,14 +564,16 @@ namespace GridKit Fixture equal_limits(equal_limit_data); equal_limits.attachAllInputs(); success *= equal_limits.initialize(0.4); - success *= stateMatches(equal_limits.gastpti, - {{Internal::XVALVE, 0.8}, - {Internal::XFLOW, 0.8}, - {Internal::XTEMP, 0.8}, - {Internal::VLOAD, 0.8}, - {Internal::VTEMP, test_case.vtemp}, - {Internal::PMECH, 0.4}}, - test_case.label); + success *= stateMatches( + equal_limits.gastpti, + {{Internal::XVALVE, 0.8}, + {Internal::XFLOW, 0.8}, + {Internal::XTEMP, 0.8}, + {Internal::VLOAD, 0.8}, + {Internal::VTEMP, test_case.vtemp}, + {Internal::PMECH, 0.4}}, + test_case.label + ); success *= (equal_limits.evaluate() == 0); success *= allResidualsZero(equal_limits.gastpti); } @@ -555,9 +592,11 @@ namespace GridKit Fixture zero_seed(makeResidualData()); zero_seed.attachAllInputs(); success *= zero_seed.initialize(0.0); - success *= stateMatches(zero_seed.gastpti, - {{Internal::XFLOW, 0.0}, {Internal::VTEMP, 2.52}}, - "zero seed"); + success *= stateMatches( + zero_seed.gastpti, + {{Internal::XFLOW, 0.0}, {Internal::VTEMP, 2.52}}, + "zero seed" + ); success *= (zero_seed.evaluate() == 0); success *= allResidualsZero(zero_seed.gastpti); @@ -566,11 +605,13 @@ namespace GridKit Fixture negative_seed(negative_data); negative_seed.attachAllInputs(); success *= negative_seed.initialize(-0.1); - success *= stateMatches(negative_seed.gastpti, - {{Internal::XFLOW, -0.2}, - {Internal::VLOAD, -0.2}, - {Internal::PMECH, -0.1}}, - "negative finite dispatch"); + success *= stateMatches( + negative_seed.gastpti, + {{Internal::XFLOW, -0.2}, + {Internal::VLOAD, -0.2}, + {Internal::PMECH, -0.1}}, + "negative finite dispatch" + ); success *= (negative_seed.evaluate() == 0); success *= allResidualsZero(negative_seed.gastpti); @@ -594,15 +635,17 @@ namespace GridKit auto data = makeResidualData(); data.parameters[Params::Kt] = temperature_gain; data.parameters[Params::At] = - initial_flow + temperature_margin / (ONE + temperature_gain); + initial_flow + temperature_margin / (ONE + temperature_gain); Fixture fixture(data); fixture.attachAllInputs(); success *= fixture.initialize(initial_pmech); - success *= stateMatches(fixture.gastpti, - {{Internal::VTEMP, initial_flow + temperature_margin}, - {Internal::VLV, initial_flow}}, - "near-gate initialization"); + success *= stateMatches( + fixture.gastpti, + {{Internal::VTEMP, initial_flow + temperature_margin}, + {Internal::VLV, initial_flow}}, + "near-gate initialization" + ); const auto* y = fixture.gastpti.y().getData(); const RealT vload = static_cast(y[index(Internal::VLOAD)]); @@ -624,10 +667,11 @@ namespace GridKit Fixture large_margin(large_margin_data); large_margin.attachAllInputs(); success *= large_margin.initialize(0.4); - success *= stateMatches(large_margin.gastpti, - {{Internal::VLOAD, 0.8}, - {Internal::VLV, 0.8}}, - "large finite temperature margin"); + success *= stateMatches( + large_margin.gastpti, + {{Internal::VLOAD, 0.8}, {Internal::VLV, 0.8}}, + "large finite temperature margin" + ); success *= (large_margin.evaluate() == 0); success *= allResidualsZero(large_margin.gastpti); @@ -649,7 +693,8 @@ namespace GridKit success *= (fixture.evaluate() == 0); // The state is chosen so every documented equation has a readable answer. - const std::array()> expected{{ + const std::array()> + expected{{ {Internal::XVALVE, 0.19}, {Internal::XFLOW, 0.22}, {Internal::XTEMP, 0.07}, @@ -657,7 +702,7 @@ namespace GridKit {Internal::VTEMP, 1.0}, {Internal::VLV, 0.15}, {Internal::PMECH, -0.1424}, - }}; + }}; success *= (static_cast(fixture.gastpti.getResidual().getSize()) == expected.size()); success *= residualsMatch(fixture.gastpti, expected); @@ -680,23 +725,28 @@ namespace GridKit }; const std::array antiwindup_cases{{ - {"Vmax blocks an outward valve rate", 1.6, 1.85, 0.0}, - {"Vmin blocks an outward valve rate", -0.45, -0.7, 0.0}, - {"Vmax admits a restoring valve rate", 1.6, 1.25, -1.0}, - {"Vmin admits a restoring valve rate", -0.45, -0.1, 1.0}, + {"Vmax blocks an outward valve rate", 1.6, 1.85, 0.0}, + {"Vmin blocks an outward valve rate", -0.45, -0.7, 0.0}, + {"Vmax admits a restoring valve rate", 1.6, 1.25, -1.0}, + {"Vmin admits a restoring valve rate", -0.45, -0.1, 1.0}, }}; for (const auto& test_case : antiwindup_cases) { Fixture antiwindup(makeResidualData()); antiwindup.attachAllInputs(); success *= antiwindup.initialize(0.4); - setState(antiwindup.gastpti, - {{Internal::XVALVE, test_case.xvalve}, {Internal::VLV, test_case.vlv}}); + setState( + antiwindup.gastpti, + {{Internal::XVALVE, test_case.xvalve}, + {Internal::VLV, test_case.vlv}} + ); setDerivative(antiwindup.gastpti, {{Internal::XVALVE, 0.0}}); success *= (antiwindup.evaluate() == 0); - success *= residualsMatch(antiwindup.gastpti, - {{Internal::XVALVE, test_case.expected}}, - test_case.label); + success *= residualsMatch( + antiwindup.gastpti, + {{Internal::XVALVE, test_case.expected}}, + test_case.label + ); } // A speed deviation enters the droop and turbine-damping rows. @@ -705,10 +755,11 @@ namespace GridKit success *= speed_step.initialize(0.4); speed_step.input(index(External::speed)) = 0.05; success *= (speed_step.evaluate() == 0); - success *= residualsMatch(speed_step.gastpti, - {{Internal::VLOAD, -0.05}, - {Internal::PMECH, -0.006}}, - "speed deviation in the droop and damping rows"); + success *= residualsMatch( + speed_step.gastpti, + {{Internal::VLOAD, -0.05}, {Internal::PMECH, -0.006}}, + "speed deviation in the droop and damping rows" + ); // Normal response expands both sides of the configured interval to // admit the initialized flow. The derived boundary must be used thereafter. @@ -728,8 +779,10 @@ namespace GridKit }; const std::array effective_boundary_cases{{ - {"adjusted upper response boundary", over_rated_pmech, command_magnitude}, - {"adjusted lower response boundary", ZERO, -command_magnitude}, + {"adjusted upper response boundary", + over_rated_pmech, + command_magnitude}, + {"adjusted lower response boundary", ZERO, -command_magnitude}, }}; const auto previous_verbosity = Log::verbosity(); // Suppress expected response-limit adjustment warnings from these cases. @@ -742,19 +795,21 @@ namespace GridKit success *= response.initialize(test_case.pmech); const RealT boundary = static_cast( - response.gastpti.y().getData()[index(Internal::XVALVE)]); - setState(response.gastpti, - {{Internal::XVALVE, boundary}, - {Internal::VLV, boundary + test_case.command}}); - setDerivative(response.gastpti, - {{Internal::XVALVE, ZERO}}); + response.gastpti.y().getData()[index(Internal::XVALVE)] + ); + setState( + response.gastpti, + {{Internal::XVALVE, boundary}, + {Internal::VLV, boundary + test_case.command}} + ); + setDerivative(response.gastpti, {{Internal::XVALVE, ZERO}}); success *= (response.evaluate() == 0); const RealT expected = - boundary_weight * test_case.command / valve_time_constant; - success *= residualsMatch(response.gastpti, - {{Internal::XVALVE, expected}}, - test_case.label); + boundary_weight * test_case.command / valve_time_constant; + success *= residualsMatch( + response.gastpti, {{Internal::XVALVE, expected}}, test_case.label + ); } Log::setVerbosity(previous_verbosity); @@ -777,60 +832,66 @@ namespace GridKit }; const std::array gate_cases{{ - {"the load demand wins the LV gate", 0.3, 1.5}, - {"the temperature demand wins the LV gate", 1.5, 0.3}, - {"equal demands split the smooth LV gate", 0.9, 0.9}, + {"the load demand wins the LV gate", 0.3, 1.5}, + {"the temperature demand wins the LV gate", 1.5, 0.3}, + {"equal demands split the smooth LV gate", 0.9, 0.9}, }}; for (const auto& test_case : gate_cases) { Fixture gate(makeResidualData()); gate.attachAllInputs(); success *= gate.initialize(0.4); - setState(gate.gastpti, - {{Internal::VLOAD, test_case.vload}, - {Internal::VTEMP, test_case.vtemp}, - {Internal::VLV, 0.0}}); + setState( + gate.gastpti, + {{Internal::VLOAD, test_case.vload}, + {Internal::VTEMP, test_case.vtemp}, + {Internal::VLV, 0.0}} + ); success *= (gate.evaluate() == 0); const RealT expected = - static_cast(Math::min(test_case.vload, test_case.vtemp)); - success *= residualsMatch(gate.gastpti, - {{Internal::VLV, expected}}, - test_case.label); + static_cast(Math::min(test_case.vload, test_case.vtemp)); + success *= residualsMatch( + gate.gastpti, {{Internal::VLV, expected}}, test_case.label + ); } // The exhaust-temperature feedback drives the temperature demand. Fixture feedback(makeResidualData()); feedback.attachAllInputs(); success *= feedback.initialize(0.4); - setState(feedback.gastpti, - {{Internal::XTEMP, 0.9}, {Internal::VTEMP, 1.1}}); + setState( + feedback.gastpti, {{Internal::XTEMP, 0.9}, {Internal::VTEMP, 1.1}} + ); success *= (feedback.evaluate() == 0); - success *= residualsMatch(feedback.gastpti, - {{Internal::VTEMP, 1.06}}, - "temperature feedback"); + success *= residualsMatch( + feedback.gastpti, {{Internal::VTEMP, 1.06}}, "temperature feedback" + ); // At equality, the smooth low-value selector splits its sensitivity // evenly between the two demand signals. Fixture selector(makeResidualData()); selector.attachAllInputs(); success *= selector.initialize(0.4); - setState(selector.gastpti, - {{Internal::VLOAD, 0.9}, - {Internal::VTEMP, 0.9}, - {Internal::VLV, 0.7}}); + setState( + selector.gastpti, + {{Internal::VLOAD, 0.9}, {Internal::VTEMP, 0.9}, {Internal::VLV, 0.7}} + ); numberVariables(selector); success *= (selector.evaluate() == 0); const DependencyTracking::Variable::DependencyMap expected{ - {2 * index(Internal::VLOAD), 0.5}, // @todo Remove these - {2 * index(Internal::VTEMP), 0.5}, // @todo Remove these - {2 * index(Internal::VLV), -1.0}, // @todo Remove these + {2 * index(Internal::VLOAD), 0.5}, // @todo Remove these + {2 * index(Internal::VTEMP), 0.5}, // @todo Remove these + {2 * index(Internal::VLV), -1.0}, // @todo Remove these }; success *= jacobianRowMatches( - selector.gastpti.getResidual().getData()[index(Internal::VLV)].getDependencies(), - expected, - index(Internal::VLV), - "selector equality"); + selector.gastpti.getResidual() + .getData()[index(Internal::VLV)] + .getDependencies(), + expected, + index(Internal::VLV), + "selector equality" + ); return success.report(__func__); } @@ -849,42 +910,53 @@ namespace GridKit const auto data = makeResidualData(); - const auto compare = [&](const Data& case_data, - RealT pmech, - const char* context, - std::initializer_list overrides) + const auto compare = [&]( + const Data& case_data, + RealT pmech, + const char* context, + std::initializer_list overrides + ) { const auto dependency_jacobian = - dependencyTrackingJacobian(case_data, pmech, success, overrides); + dependencyTrackingJacobian(case_data, pmech, success, overrides); const auto enzyme_jacobian = - enzymeJacobian(case_data, pmech, success, overrides); + enzymeJacobian(case_data, pmech, success, overrides); - success *= jacobianMatches(enzyme_jacobian, - dependency_jacobian, - context, - kTol); + success *= jacobianMatches( + enzyme_jacobian, dependency_jacobian, context, kTol + ); }; - compare(data, - initial_pmech, - "load-limited Enzyme versus dependency tracking", - {}); - compare(data, - initial_pmech, - "temperature-limited Enzyme versus dependency tracking", - {{Internal::VLOAD, 1.5}, {Internal::VTEMP, 0.3}}); - compare(data, - initial_pmech, - "equal-selector Enzyme versus dependency tracking", - {{Internal::VLOAD, 0.9}, {Internal::VTEMP, 0.9}}); - compare(data, - initial_pmech, - "blocked-response Enzyme versus dependency tracking", - {{Internal::XVALVE, 1.6}, {Internal::VLV, 1.85}}); - compare(data, - initial_pmech, - "restoring-response Enzyme versus dependency tracking", - {{Internal::XVALVE, 1.6}, {Internal::VLV, 1.35}}); + compare( + data, + initial_pmech, + "load-limited Enzyme versus dependency tracking", + {} + ); + compare( + data, + initial_pmech, + "temperature-limited Enzyme versus dependency tracking", + {{Internal::VLOAD, 1.5}, {Internal::VTEMP, 0.3}} + ); + compare( + data, + initial_pmech, + "equal-selector Enzyme versus dependency tracking", + {{Internal::VLOAD, 0.9}, {Internal::VTEMP, 0.9}} + ); + compare( + data, + initial_pmech, + "blocked-response Enzyme versus dependency tracking", + {{Internal::XVALVE, 1.6}, {Internal::VLV, 1.85}} + ); + compare( + data, + initial_pmech, + "restoring-response Enzyme versus dependency tracking", + {{Internal::XVALVE, 1.6}, {Internal::VLV, 1.35}} + ); const auto adjusted_verbosity = Log::verbosity(); // Suppress the expected response-limit adjustment warning for this case. @@ -895,12 +967,15 @@ namespace GridKit success *= adjusted.initialize(over_rated_pmech); const RealT adjusted_boundary = static_cast( - adjusted.gastpti.y().getData()[index(Internal::XVALVE)]); - compare(data, - over_rated_pmech, - "adjusted-boundary Enzyme versus dependency tracking", - {{Internal::XVALVE, adjusted_boundary}, - {Internal::VLV, adjusted_boundary + boundary_command}}); + adjusted.gastpti.y().getData()[index(Internal::XVALVE)] + ); + compare( + data, + over_rated_pmech, + "adjusted-boundary Enzyme versus dependency tracking", + {{Internal::XVALVE, adjusted_boundary}, + {Internal::VLV, adjusted_boundary + boundary_command}} + ); Log::setVerbosity(adjusted_verbosity); auto collapsed_data = data; @@ -914,19 +989,23 @@ namespace GridKit Fixture collapsed(collapsed_data); collapsed.attachAllInputs(); success *= collapsed.initialize(initial_pmech); - compare(collapsed_data, - initial_pmech, - "collapsed Enzyme versus dependency tracking", - {}); + compare( + collapsed_data, + initial_pmech, + "collapsed Enzyme versus dependency tracking", + {} + ); collapsed.input(index(External::speed)) = ZERO; collapsed.input(index(External::pref)) = ZERO; collapsed.seedPmech(over_rated_pmech); success *= (collapsed.gastpti.initialize() == 0); - compare(collapsed_data, - over_rated_pmech, - "reinitialized Enzyme versus dependency tracking", - {}); + compare( + collapsed_data, + over_rated_pmech, + "reinitialized Enzyme versus dependency tracking", + {} + ); Log::setVerbosity(collapsed_verbosity); return success.report(__func__); @@ -998,9 +1077,11 @@ namespace GridKit } gastpti.getPorts().in.template port().connect( - &input_nodes_[index(External::speed)]); + &input_nodes_[index(External::speed)] + ); gastpti.getPorts().in.template port().connect( - &input_nodes_[index(External::pref)]); + &input_nodes_[index(External::pref)] + ); } /// Seed the assigned mechanical-power node on the system base. @@ -1146,18 +1227,22 @@ namespace GridKit template void setAnswerKeyState(PhasorDynamics::Governor::GastPti& gastpti) const { - setState(gastpti, - {{Internal::XVALVE, 0.61}, - {Internal::XFLOW, 0.52}, - {Internal::XTEMP, 0.3}, - {Internal::VLOAD, 0.83}, - {Internal::VTEMP, 1.4}, - {Internal::VLV, 0.68}, - {Internal::PMECH, 0.33}}); - setDerivative(gastpti, - {{Internal::XVALVE, 0.01}, - {Internal::XFLOW, -0.02}, - {Internal::XTEMP, 0.03}}); + setState( + gastpti, + {{Internal::XVALVE, 0.61}, + {Internal::XFLOW, 0.52}, + {Internal::XTEMP, 0.3}, + {Internal::VLOAD, 0.83}, + {Internal::VTEMP, 1.4}, + {Internal::VLV, 0.68}, + {Internal::PMECH, 0.33}} + ); + setDerivative( + gastpti, + {{Internal::XVALVE, 0.01}, + {Internal::XFLOW, -0.02}, + {Internal::XTEMP, 0.03}} + ); } /// Omitting every optional parameter must give exactly the model built @@ -1185,21 +1270,27 @@ namespace GridKit { success = false; } - if (!vectorUnchanged(implicit_defaults.gastpti.y(), - copyVector(explicit_defaults.gastpti.y()), - "documented-default state")) + if (!vectorUnchanged( + implicit_defaults.gastpti.y(), + copyVector(explicit_defaults.gastpti.y()), + "documented-default state" + )) { success = false; } - if (!vectorUnchanged(implicit_defaults.gastpti.yp(), - copyVector(explicit_defaults.gastpti.yp()), - "documented-default derivative")) + if (!vectorUnchanged( + implicit_defaults.gastpti.yp(), + copyVector(explicit_defaults.gastpti.yp()), + "documented-default derivative" + )) { success = false; } - if (!vectorUnchanged(implicit_defaults.gastpti.getResidual(), - copyVector(explicit_defaults.gastpti.getResidual()), - "documented-default residual")) + if (!vectorUnchanged( + implicit_defaults.gastpti.getResidual(), + copyVector(explicit_defaults.gastpti.getResidual()), + "documented-default residual" + )) { success = false; } @@ -1216,9 +1307,11 @@ namespace GridKit { success = false; } - if (!vectorUnchanged(implicit_defaults.gastpti.getResidual(), - copyVector(explicit_defaults.gastpti.getResidual()), - "documented-default dynamic residual")) + if (!vectorUnchanged( + implicit_defaults.gastpti.getResidual(), + copyVector(explicit_defaults.gastpti.getResidual()), + "documented-default dynamic residual" + )) { success = false; } @@ -1312,15 +1405,18 @@ namespace GridKit std::vector copyVector(const VectorT& vector) const { const auto* values = vector.getData(); - return std::vector(values, - values + static_cast(vector.getSize())); + return std::vector( + values, values + static_cast(vector.getSize()) + ); } /// Every row of a vector still holds its snapshot value. template - bool vectorUnchanged(const VectorT& vector, - const std::vector& snapshot, - const char* what) const + bool vectorUnchanged( + const VectorT& vector, + const std::vector& snapshot, + const char* what + ) const { bool success = true; const auto* values = vector.getData(); @@ -1354,10 +1450,12 @@ namespace GridKit fixture.gastpti.yp().setDataUpdated(); } - bool initializationRejectedAtomically(const Data& data, - RealT pmech, - const char* label, - RealT omega = ZERO) const + bool initializationRejectedAtomically( + const Data& data, + RealT pmech, + const char* label, + RealT omega = ZERO + ) const { Fixture fixture(data); fixture.attachAllInputs(); @@ -1379,21 +1477,25 @@ namespace GridKit success = false; } - if (!scalarPreserved(fixture.pmech(), - pmech, - "rejected pmech seed preservation")) + if (!scalarPreserved( + fixture.pmech(), pmech, "rejected pmech seed preservation" + )) { success = false; } - if (!scalarPreserved(fixture.input(index(External::speed)), - omega, - "rejected omega preservation")) + if (!scalarPreserved( + fixture.input(index(External::speed)), + omega, + "rejected omega preservation" + )) { success = false; } - if (!scalarPreserved(fixture.input(index(External::pref)), - 77.0, - "rejected pref preservation")) + if (!scalarPreserved( + fixture.input(index(External::pref)), + 77.0, + "rejected pref preservation" + )) { success = false; } @@ -1411,8 +1513,10 @@ namespace GridKit /// Write state rows and publish the update, folding in the /// setDataUpdated() that a hand-written write block has to remember. template - void setState(PhasorDynamics::Governor::GastPti& gastpti, - std::initializer_list values) const + void setState( + PhasorDynamics::Governor::GastPti& gastpti, + std::initializer_list values + ) const { auto* y = gastpti.y().getData(); for (const auto& [variable, value] : values) @@ -1424,8 +1528,10 @@ namespace GridKit /// setState() for the derivative vector. template - void setDerivative(PhasorDynamics::Governor::GastPti& gastpti, - std::initializer_list values) const + void setDerivative( + PhasorDynamics::Governor::GastPti& gastpti, + std::initializer_list values + ) const { auto* yp = gastpti.yp().getData(); for (const auto& [variable, value] : values) @@ -1438,11 +1544,13 @@ namespace GridKit /// Compare one vector row against its expected value. Every row check /// in this suite reports through here, so failures share one format. /// Variables are named by the canonical enum used by the expectation. - static bool rowMatches(RealT actual, - RealT expected, - const char* what, - size_t row, - const char* context) + static bool rowMatches( + RealT actual, + RealT expected, + const char* what, + size_t row, + const char* context + ) { if (isEqual(actual, expected, kTol)) { @@ -1457,10 +1565,12 @@ namespace GridKit /// Check selected rows of a model vector against expected values. template - bool rowsMatch(const VectorT& vector, - const ValuesT& values, - const char* what, - const char* context) const + bool rowsMatch( + const VectorT& vector, + const ValuesT& values, + const char* what, + const char* context + ) const { bool success = true; const auto* vector_values = vector.getData(); @@ -1475,32 +1585,40 @@ namespace GridKit return success; } - bool residualsMatch(const GastPtiT& gastpti, - std::initializer_list values, - const char* context = "") const + bool residualsMatch( + const GastPtiT& gastpti, + std::initializer_list values, + const char* context = "" + ) const { return rowsMatch(gastpti.getResidual(), values, "residual", context); } template - bool residualsMatch(const GastPtiT& gastpti, - const std::array& values, - const char* context = "") const + bool residualsMatch( + const GastPtiT& gastpti, + const std::array& values, + const char* context = "" + ) const { return rowsMatch(gastpti.getResidual(), values, "residual", context); } - bool stateMatches(const GastPtiT& gastpti, - std::initializer_list values, - const char* context = "") const + bool stateMatches( + const GastPtiT& gastpti, + std::initializer_list values, + const char* context = "" + ) const { return rowsMatch(gastpti.y(), values, "state", context); } template - bool stateMatches(const GastPtiT& gastpti, - const std::array& values, - const char* context = "") const + bool stateMatches( + const GastPtiT& gastpti, + const std::array& values, + const char* context = "" + ) const { return rowsMatch(gastpti.y(), values, "state", context); } @@ -1526,10 +1644,12 @@ namespace GridKit return success; } - bool scalarMatches(ScalarT actual, - ScalarT expected, - const char* label, - ScalarT tolerance = kTol) const + bool scalarMatches( + ScalarT actual, + ScalarT expected, + const char* label, + ScalarT tolerance = kTol + ) const { if (isEqual(actual, expected, tolerance)) { @@ -1567,11 +1687,12 @@ namespace GridKit } bool jacobianRowMatches( - const DependencyTracking::Variable::DependencyMap& actual, - const DependencyTracking::Variable::DependencyMap& expected, - size_t row, - const char* context, - RealT tolerance = kTol) const + const DependencyTracking::Variable::DependencyMap& actual, + const DependencyTracking::Variable::DependencyMap& expected, + size_t row, + const char* context, + RealT tolerance = kTol + ) const { if (isEqual(actual, expected, tolerance)) { @@ -1584,10 +1705,12 @@ namespace GridKit } bool jacobianMatches( - const std::vector& actual, - const std::vector& expected, - const char* context, - RealT tolerance = kTol) const + const std::vector& actual, + const std::vector& + expected, + const char* context, + RealT tolerance = kTol + ) const { if (actual.size() != expected.size()) { @@ -1629,11 +1752,13 @@ namespace GridKit fixture.gastpti.yp().setDataUpdated(); } - std::vector dependencyTrackingJacobian( - const Data& data, - RealT pmech, - TestStatus& success, - std::initializer_list overrides) const + std::vector + dependencyTrackingJacobian( + const Data& data, + RealT pmech, + TestStatus& success, + std::initializer_list overrides + ) const { using DepVar = DependencyTracking::Variable; @@ -1653,10 +1778,11 @@ namespace GridKit #ifdef GRIDKIT_ENABLE_ENZYME std::vector enzymeJacobian( - const Data& data, - RealT pmech, - TestStatus& success, - std::initializer_list overrides) const + const Data& data, + RealT pmech, + TestStatus& success, + std::initializer_list overrides + ) const { Fixture fixture(data); fixture.attachAllInputs(); diff --git a/tests/UnitTests/PhasorDynamics/GovernorHygovTests.hpp b/tests/UnitTests/PhasorDynamics/GovernorHygovTests.hpp index 6e59d5a7ae..3736d2948b 100644 --- a/tests/UnitTests/PhasorDynamics/GovernorHygovTests.hpp +++ b/tests/UnitTests/PhasorDynamics/GovernorHygovTests.hpp @@ -40,7 +40,7 @@ namespace GridKit ~GovernorHygovTests() = default; static constexpr RealT kTol = - static_cast(100.0) * std::numeric_limits::epsilon(); + static_cast(100.0) * std::numeric_limits::epsilon(); /// Construction and every verify() error class, including parameter /// types and finiteness, parameter relationships, power bases, curve @@ -78,36 +78,14 @@ namespace GridKit const RealT infinity = std::numeric_limits::infinity(); const std::array real_parameters{{ - Params::Trate, - Params::Rperm, - Params::Rtemp, - Params::Tr, - Params::Tf, - Params::Tg, - Params::Velm, - Params::Gmax, - Params::Gmin, - Params::Tw, - Params::At, - Params::Dturb, - Params::Qnl, - Params::Tn, - Params::Tnp, - Params::db1, - Params::db2, - Params::Hdam, - Params::Gv0, - Params::Gv1, - Params::Gv2, - Params::Gv3, - Params::Gv4, - Params::Gv5, - Params::Pgv0, - Params::Pgv1, - Params::Pgv2, - Params::Pgv3, - Params::Pgv4, - Params::Pgv5, + Params::Trate, Params::Rperm, Params::Rtemp, Params::Tr, + Params::Tf, Params::Tg, Params::Velm, Params::Gmax, + Params::Gmin, Params::Tw, Params::At, Params::Dturb, + Params::Qnl, Params::Tn, Params::Tnp, Params::db1, + Params::db2, Params::Hdam, Params::Gv0, Params::Gv1, + Params::Gv2, Params::Gv3, Params::Gv4, Params::Gv5, + Params::Pgv0, Params::Pgv1, Params::Pgv2, Params::Pgv3, + Params::Pgv4, Params::Pgv5, }}; const std::array nonfinite_values{{nan, infinity, -infinity}}; @@ -116,11 +94,14 @@ namespace GridKit for (const RealT value : nonfinite_values) { success *= configurationRejected( - [&]() - { - Fixture invalid_fixture(makeData(), {{parameter, value}}); - return invalid_fixture.hygov.verify(); - }); + [&]() + { + Fixture invalid_fixture( + makeData(), {{parameter, value}} + ); + return invalid_fixture.hygov.verify(); + } + ); } } @@ -129,59 +110,55 @@ namespace GridKit PhasorDynamics::Governor::Hygov unassigned(makeData()); success *= (!unassigned.verify().passed()); - const std::array, 19> invalid_parameter_values{{ - {Params::Trate, 0.0}, - {Params::Trate, -1.0}, - {Params::Rtemp, 0.0}, - {Params::Tr, -0.1}, - {Params::Tf, -0.1}, - {Params::Tg, -0.1}, - {Params::Tw, -0.1}, - {Params::Tn, -0.1}, - {Params::Tnp, -0.1}, - {Params::Velm, -0.1}, - {Params::Gmin, 1.1}, - {Params::At, 0.0}, - {Params::Dturb, -0.1}, - {Params::db1, -0.1}, - {Params::Hdam, 0.0}, - {Params::Gv2, 0.1}, - {Params::Pgv2, 0.1}, - {Params::Gmin, -0.05}, + const std::array, 19> invalid_parameter_values{ + { + {Params::Trate, 0.0}, {Params::Trate, -1.0}, {Params::Rtemp, 0.0}, + {Params::Tr, -0.1}, {Params::Tf, -0.1}, {Params::Tg, -0.1}, + {Params::Tw, -0.1}, {Params::Tn, -0.1}, {Params::Tnp, -0.1}, + {Params::Velm, -0.1}, {Params::Gmin, 1.1}, {Params::At, 0.0}, + {Params::Dturb, -0.1}, {Params::db1, -0.1}, {Params::Hdam, 0.0}, + {Params::Gv2, 0.1}, {Params::Pgv2, 0.1}, {Params::Gmin, -0.05}, {Params::Gmax, 1.05}, - }}; + } + }; for (const auto& [parameter, value] : invalid_parameter_values) { success *= configurationRejected( - [&]() - { - Fixture invalid_fixture(makeData(), {{parameter, value}}); - return invalid_fixture.hygov.verify(); - }); + [&]() + { + Fixture invalid_fixture( + makeData(), {{parameter, value}} + ); + return invalid_fixture.hygov.verify(); + } + ); } // A curve with no rise cannot yield a unique gate. - Fixture flat_curve(makeData(), - {{Params::Pgv1, 0.0}, - {Params::Pgv2, 0.0}, - {Params::Pgv3, 0.0}, - {Params::Pgv4, 0.0}, - {Params::Pgv5, 0.0}}); + Fixture flat_curve( + makeData(), + {{Params::Pgv1, 0.0}, + {Params::Pgv2, 0.0}, + {Params::Pgv3, 0.0}, + {Params::Pgv4, 0.0}, + {Params::Pgv5, 0.0}} + ); success *= (!flat_curve.hygov.verify().passed()); // A curve that rises only outside the configured response limits is // valid because initialization may expand those limits. Fixture flat_configured_range( - makeData(), - {{Params::Gmin, 0.0}, - {Params::Gmax, 0.2}, - {Params::Pgv0, 0.5}, - {Params::Pgv1, 0.5}, - {Params::Pgv2, 0.5}, - {Params::Pgv3, 0.5}, - {Params::Pgv4, 0.5}, - {Params::Pgv5, 1.0}}); + makeData(), + {{Params::Gmin, 0.0}, + {Params::Gmax, 0.2}, + {Params::Pgv0, 0.5}, + {Params::Pgv1, 0.5}, + {Params::Pgv2, 0.5}, + {Params::Pgv3, 0.5}, + {Params::Pgv4, 0.5}, + {Params::Pgv5, 1.0}} + ); success *= (flat_configured_range.hygov.verify().passed()); // A requested backlash is accepted, warns, and remains inactive. @@ -199,29 +176,30 @@ namespace GridKit bad_numeric_type.parameters[Params::Trate] = true; success *= configurationRejected( - [&]() - { - Fixture bad_numeric_model(bad_numeric_type); - return bad_numeric_model.hygov.verify(); - }); + [&]() + { + Fixture bad_numeric_model(bad_numeric_type); + return bad_numeric_model.hygov.verify(); + } + ); Fixture overflowing_component_base( - makeData(), - {{Params::Trate, std::numeric_limits::max()}}); + makeData(), {{Params::Trate, std::numeric_limits::max()}} + ); success *= (!overflowing_component_base.hygov.verify().passed()); Fixture overflowing_base_ratio( - makeData(), - {{Params::Trate, std::numeric_limits::min()}}); + makeData(), {{Params::Trate, std::numeric_limits::min()}} + ); success *= (!overflowing_base_ratio.hygov.verify().passed()); const std::array invalid_system_bases{{ - 0.0, - -1.0, - nan, - infinity, - -infinity, - std::numeric_limits::min(), + 0.0, + -1.0, + nan, + infinity, + -infinity, + std::numeric_limits::min(), }}; for (const RealT system_base : invalid_system_bases) @@ -236,12 +214,14 @@ namespace GridKit // All five zero time constants use the documented numerical floor and // still admit a consistent steady-state initialization. - Fixture floors(makeData(), - {{Params::Tr, 0.0}, - {Params::Tf, 0.0}, - {Params::Tg, 0.0}, - {Params::Tw, 0.0}, - {Params::Tnp, 0.0}}); + Fixture floors( + makeData(), + {{Params::Tr, 0.0}, + {Params::Tf, 0.0}, + {Params::Tg, 0.0}, + {Params::Tw, 0.0}, + {Params::Tnp, 0.0}} + ); success *= floors.initialize(0.4); success *= (floors.evaluate() == 0); success *= allResidualsZero(floors.hygov); @@ -267,16 +247,20 @@ namespace GridKit const auto* y = fixture.hygov.y().getData(); success *= scalarMatches(y[static_cast(Internal::XF)], 0.0, "XF at rest"); - success *= scalarMatches(y[static_cast(Internal::C)], - 0.9000000000001573, - "C on component base"); - success *= scalarMatches(y[static_cast(Internal::G)], - 0.9000000000001573, - "G on component base"); + success *= scalarMatches( + y[static_cast(Internal::C)], + 0.9000000000001573, + "C on component base" + ); + success *= scalarMatches( + y[static_cast(Internal::G)], + 0.9000000000001573, + "G on component base" + ); success *= scalarMatches(y[static_cast(Internal::Q)], 0.9, "Q on component base"); - success *= scalarMatches(y[static_cast(Internal::PGV)], - 0.9, - "PGV on component base"); + success *= scalarMatches( + y[static_cast(Internal::PGV)], 0.9, "PGV on component base" + ); success *= scalarMatches(y[static_cast(Internal::H)], 1.0, "H at the dam head"); success *= scalarMatches(fixture.pmech(), 0.4, "preserved pmech value"); @@ -335,9 +319,11 @@ namespace GridKit // the base ratio. fixture.input(External::pref) = 0.1025; // the published 0.0025 plus a 0.1 step success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.hygov, - {{Internal::EF, 0.2}}, - "reference step on the component base"); + success *= residualsMatch( + fixture.hygov, + {{Internal::EF, 0.2}}, + "reference step on the component base" + ); // Unattached ports fall back to the references latched by // initialize(), so the same steady state holds without a controller. @@ -362,46 +348,55 @@ namespace GridKit Log::setVerbosity(Log::Verbosity::NONE); success *= initializationRejectedAtomically( - makeResidualData(), - -0.3, - {{External::speed, 0.0}, {External::pref, 77.0}, {External::paux, 0.02}}, - "mechanical power below the gate curve"); + makeResidualData(), + -0.3, + {{External::speed, 0.0}, + {External::pref, 77.0}, + {External::paux, 0.02}}, + "mechanical power below the gate curve" + ); const auto no_finite_head = withParameters( - makeData(), - {{Params::Pgv0, -1.0}, - {Params::Pgv1, -0.8}, - {Params::Pgv2, -0.6}, - {Params::Pgv3, -0.4}, - {Params::Pgv4, -0.2}, - {Params::Pgv5, 0.0}}); + makeData(), + {{Params::Pgv0, -1.0}, + {Params::Pgv1, -0.8}, + {Params::Pgv2, -0.6}, + {Params::Pgv3, -0.4}, + {Params::Pgv4, -0.2}, + {Params::Pgv5, 0.0}} + ); success *= initializationRejectedAtomically( - no_finite_head, - 0.0, - {{External::speed, 0.0}, {External::pref, 77.0}, {External::paux, 0.02}}, - "no finite effective Hdam"); + no_finite_head, + 0.0, + {{External::speed, 0.0}, + {External::pref, 77.0}, + {External::paux, 0.02}}, + "no finite effective Hdam" + ); // 4.5 MW on the system base is 2.5 pu on a 1.8 MW turbine base. Fixture effective_fixture( - makeData(), - {{Params::Trate, 1.8}, - {Params::At, 1.25}, - {Params::Qnl, 0.07}, - {Params::Gmax, 0.5}}); + makeData(), + {{Params::Trate, 1.8}, + {Params::At, 1.25}, + {Params::Qnl, 0.07}, + {Params::Gmax, 0.5}} + ); effective_fixture.attachAllInputs(); success *= effective_fixture.initialize(0.045); success *= stateMatches( - effective_fixture.hygov, - {{Internal::C, 1.0}, - {Internal::G, 1.0}, - {Internal::Q, 1.2812656647316965}, - {Internal::PGV, 0.9971118867476669}, - {Internal::H, 1.6511654364800423}}, - "effective dam head"); + effective_fixture.hygov, + {{Internal::C, 1.0}, + {Internal::G, 1.0}, + {Internal::Q, 1.2812656647316965}, + {Internal::PGV, 0.9971118867476669}, + {Internal::H, 1.6511654364800423}}, + "effective dam head" + ); success *= scalarMatches(effective_fixture.pmech(), 0.045, "preserved pmech value"); - success *= scalarMatches(effective_fixture.input(External::pref), - 0.0009, - "published pref"); + success *= scalarMatches( + effective_fixture.input(External::pref), 0.0009, "published pref" + ); success *= (effective_fixture.evaluate() == 0); success *= allResidualsZero(effective_fixture.hygov); @@ -414,43 +409,50 @@ namespace GridKit }; const std::array response_limit_cases{{ - {"expanded upper response limit", Params::Gmax, 0.5, 0.1}, - {"expanded lower response limit", Params::Gmin, 0.7, -0.1}, + {"expanded upper response limit", Params::Gmax, 0.5, 0.1}, + {"expanded lower response limit", Params::Gmin, 0.7, -0.1}, }}; for (const auto& test_case : response_limit_cases) { - Fixture fixture(makeResidualData(), - {{test_case.limit_parameter, test_case.limit}}); + Fixture fixture( + makeResidualData(), {{test_case.limit_parameter, test_case.limit}} + ); success *= fixture.initialize(0.4); const RealT gate = static_cast( - fixture.hygov.y().getData()[static_cast(Internal::C)]); + fixture.hygov.y().getData()[static_cast(Internal::C)] + ); const bool gate_is_outside = test_case.rate > 0.0 - ? gate > test_case.limit - : gate < test_case.limit; + ? gate > test_case.limit + : gate < test_case.limit; if (!gate_is_outside) { std::cout << test_case.label << " did not initialize outside the configured limit\n"; success = false; } - success *= stateMatches(fixture.hygov, - {{Internal::G, gate}, {Internal::H, 1.2}}, - test_case.label); + success *= stateMatches( + fixture.hygov, + {{Internal::G, gate}, {Internal::H, 1.2}}, + test_case.label + ); success *= (fixture.evaluate() == 0); success *= allResidualsZero(fixture.hygov); // The effective response bound admits an outward rate between the // configured limit and initialized gate. - setState(fixture.hygov, - {{Internal::C, 0.5 * (test_case.limit + gate)}, - {Internal::RC, test_case.rate}}); + setState( + fixture.hygov, + {{Internal::C, 0.5 * (test_case.limit + gate)}, + {Internal::RC, test_case.rate}} + ); setDerivative(fixture.hygov, {{Internal::C, 0.0}}); success *= (fixture.evaluate() == 0); - const RealT response_rate = static_cast( - fixture.hygov.getResidual().getData()[static_cast(Internal::C)]); - const bool rate_is_admitted = test_case.rate > 0.0 - ? response_rate > 0.9 * test_case.rate - : response_rate < 0.9 * test_case.rate; + const RealT response_rate = + static_cast(fixture.hygov.getResidual() + .getData()[static_cast(Internal::C)]); + const bool rate_is_admitted = + test_case.rate > 0.0 ? response_rate > 0.9 * test_case.rate + : response_rate < 0.9 * test_case.rate; if (!rate_is_admitted) { std::cout << test_case.label << " did not admit the outward desired-gate rate\n"; @@ -466,19 +468,21 @@ namespace GridKit success *= (effective_fixture.hygov.initialize() != 0); success *= vectorUnchanged(effective_fixture.hygov.y(), effective_y, "state"); success *= vectorUnchanged(effective_fixture.hygov.yp(), effective_yp, "derivative"); - success *= scalarMatches(effective_fixture.input(External::pref), - 0.0009, - "preserved pref"); + success *= scalarMatches( + effective_fixture.input(External::pref), 0.0009, "preserved pref" + ); effective_fixture.input(External::speed) = 0.0; success *= (effective_fixture.evaluate() == 0); success *= allResidualsZero(effective_fixture.hygov); - setState(effective_fixture.hygov, - {{Internal::C, 0.75}, {Internal::RC, 0.2}}); + setState( + effective_fixture.hygov, {{Internal::C, 0.75}, {Internal::RC, 0.2}} + ); setDerivative(effective_fixture.hygov, {{Internal::C, 0.0}}); success *= (effective_fixture.evaluate() == 0); - const RealT preserved_rate = static_cast( - effective_fixture.hygov.getResidual().getData()[static_cast(Internal::C)]); + const RealT preserved_rate = + static_cast(effective_fixture.hygov.getResidual() + .getData()[static_cast(Internal::C)]); if (!(preserved_rate > 0.19)) { std::cout << "failed initialization did not preserve effective Gmax\n"; @@ -489,29 +493,36 @@ namespace GridKit // and Hdam. effective_fixture.setPmech(0.009); success *= (effective_fixture.hygov.initialize() == 0); - success *= stateMatches(effective_fixture.hygov, - {{Internal::H, 1.0}}, - "configured dam head after reinitialization"); + success *= stateMatches( + effective_fixture.hygov, + {{Internal::H, 1.0}}, + "configured dam head after reinitialization" + ); success *= (effective_fixture.evaluate() == 0); success *= allResidualsZero(effective_fixture.hygov); - setState(effective_fixture.hygov, - {{Internal::C, 0.75}, {Internal::RC, 0.2}}); + setState( + effective_fixture.hygov, {{Internal::C, 0.75}, {Internal::RC, 0.2}} + ); setDerivative(effective_fixture.hygov, {{Internal::C, 0.0}}); success *= (effective_fixture.evaluate() == 0); success *= scalarMatches( - static_cast(effective_fixture.hygov.getResidual().getData()[static_cast(Internal::C)]), - 0.0, - "configured Gmax after reinitialization"); + static_cast(effective_fixture.hygov.getResidual() + .getData()[static_cast(Internal::C)]), + 0.0, + "configured Gmax after reinitialization" + ); // Initialization supports only a zero speed deviation; a moving // machine would need a multi-root gate search. - success *= initializationRejectedAtomically(makeResidualData(), - 0.4, - {{External::speed, 0.03}, - {External::pref, 77.0}, - {External::paux, 0.02}}, - "nonzero initial speed deviation"); + success *= initializationRejectedAtomically( + makeResidualData(), + 0.4, + {{External::speed, 0.03}, + {External::pref, 77.0}, + {External::paux, 0.02}}, + "nonzero initial speed deviation" + ); // An invalid configuration is rejected before any state is written. Fixture invalid_fixture(makeResidualData(), {{Params::Rtemp, 0.0}}); @@ -532,9 +543,11 @@ namespace GridKit Fixture zero_power_fixture(makeData()); success *= zero_power_fixture.initialize(0.0); success *= stateMatches( - zero_power_fixture.hygov, - {{Internal::C, 0.09999999999984271}, {Internal::G, 0.09999999999984271}}, - "zero mechanical power"); + zero_power_fixture.hygov, + {{Internal::C, 0.09999999999984271}, + {Internal::G, 0.09999999999984271}}, + "zero mechanical power" + ); success *= (zero_power_fixture.evaluate() == 0); success *= allResidualsZero(zero_power_fixture.hygov); @@ -547,22 +560,27 @@ namespace GridKit Fixture lower_edge(makeData()); success *= lower_edge.initialize(p_min - 0.5 * kTol); - success *= stateMatches(lower_edge.hygov, - {{Internal::C, 0.0}, {Internal::G, 0.0}}, - "half the tolerance below the achievable minimum"); - success *= scalarMatches(lower_edge.pmech(), - p_min - 0.5 * kTol, - "clipped pmech value"); + success *= stateMatches( + lower_edge.hygov, + {{Internal::C, 0.0}, {Internal::G, 0.0}}, + "half the tolerance below the achievable minimum" + ); + success *= scalarMatches( + lower_edge.pmech(), p_min - 0.5 * kTol, "clipped pmech value" + ); success *= (lower_edge.evaluate() == 0); success *= allResidualsZero(lower_edge.hygov); Fixture effective_edge(makeData()); success *= effective_edge.initialize(p_max + 0.5 * kTol); - success *= stateMatches(effective_edge.hygov, - {{Internal::C, 1.0}, {Internal::G, 1.0}}, - "half the tolerance beyond the achievable maximum"); - const RealT effective_edge_head = static_cast( - effective_edge.hygov.y().getData()[static_cast(Internal::H)]); + success *= stateMatches( + effective_edge.hygov, + {{Internal::C, 1.0}, {Internal::G, 1.0}}, + "half the tolerance beyond the achievable maximum" + ); + const RealT effective_edge_head = static_cast( + effective_edge.hygov.y().getData()[static_cast(Internal::H)] + ); if (!(effective_edge_head > 1.0)) { std::cout << "effective head was not raised above configured Hdam\n"; @@ -572,10 +590,13 @@ namespace GridKit success *= allResidualsZero(effective_edge.hygov); success *= initializationRejectedAtomically( - makeData(), - p_min - 2.0 * kTol, - {{External::speed, 0.0}, {External::pref, 77.0}, {External::paux, 0.02}}, - "twice the tolerance below the achievable minimum"); + makeData(), + p_min - 2.0 * kTol, + {{External::speed, 0.0}, + {External::pref, 77.0}, + {External::paux, 0.02}}, + "twice the tolerance below the achievable minimum" + ); const RealT nan = std::numeric_limits::quiet_NaN(); const RealT infinity = std::numeric_limits::infinity(); @@ -587,18 +608,22 @@ namespace GridKit for (const RealT value : nonfinite_inputs) { - success *= initializationRejectedAtomically(makeData(), - 0.4, - {{External::speed, value}, - {External::pref, 77.0}, - {External::paux, 0.02}}, - "non-finite speed input"); - success *= initializationRejectedAtomically(makeData(), - 0.4, - {{External::speed, 0.0}, - {External::pref, 77.0}, - {External::paux, value}}, - "non-finite auxiliary-power input"); + success *= initializationRejectedAtomically( + makeData(), + 0.4, + {{External::speed, value}, + {External::pref, 77.0}, + {External::paux, 0.02}}, + "non-finite speed input" + ); + success *= initializationRejectedAtomically( + makeData(), + 0.4, + {{External::speed, 0.0}, + {External::pref, 77.0}, + {External::paux, value}}, + "non-finite auxiliary-power input" + ); // A non-finite seed lands in the aliased pmech state itself, so the // poisoned-state comparison cannot express its preservation. The @@ -609,15 +634,18 @@ namespace GridKit pmech_fixture.input(External::paux) = 0.02; success *= pmech_fixture.prepare(value); success *= (pmech_fixture.hygov.initialize() != 0); - success *= scalarPreserved( - static_cast(pmech_fixture.input(External::pref)), - 77.0, - "external input", - static_cast(External::pref)); - success *= scalarPreserved(static_cast(pmech_fixture.input(External::paux)), - 0.02, - "external input", - static_cast(External::paux)); + success *= scalarPreserved( + static_cast(pmech_fixture.input(External::pref)), + 77.0, + "external input", + static_cast(External::pref) + ); + success *= scalarPreserved( + static_cast(pmech_fixture.input(External::paux)), + 0.02, + "external input", + static_cast(External::paux) + ); } Log::setVerbosity(previous_verbosity); @@ -643,11 +671,11 @@ namespace GridKit }; const std::array exactness_cases{{ - {"gate inside the Gv1 knee", 0.0556, 0.1982318164100278}, - {"gate inside the Gv2 knee", 0.2509, 0.4003865335541374}, - {"gate mid-segment", 0.4, 0.5719050089028755}, - {"gate inside the Gv3 knee", 0.4244, 0.6007061471851347}, - {"gate inside the Gv4 knee", 0.5617, 0.8006094230811988}, + {"gate inside the Gv1 knee", 0.0556, 0.1982318164100278}, + {"gate inside the Gv2 knee", 0.2509, 0.4003865335541374}, + {"gate mid-segment", 0.4, 0.5719050089028755}, + {"gate inside the Gv3 knee", 0.4244, 0.6007061471851347}, + {"gate inside the Gv4 knee", 0.5617, 0.8006094230811988}, }}; for (const auto& seed : exactness_cases) @@ -675,7 +703,8 @@ namespace GridKit setAnswerKeyState(fixture.hygov); success *= (fixture.evaluate() == 0); - const std::array()> expected{{ + const std::array()> + expected{{ {Internal::XN, -0.07785714285714286}, {Internal::XF, -0.7300000000000001}, {Internal::C, 0.06}, @@ -688,7 +717,7 @@ namespace GridKit {Internal::PGV, -0.04600000003160343}, {Internal::H, -0.033299999999999885}, {Internal::PMECH, -0.012679999999999934}, - }}; + }}; success *= (static_cast(fixture.hygov.getResidual().getSize()) == expected.size()); success *= residualsMatch(fixture.hygov, expected, "answer key"); @@ -705,64 +734,64 @@ namespace GridKit // Exercise both sides and the interior of the type-1 +/-0.01 deadband. const std::array deadband_cases{{ - {"speed deadband below the band", - {{External::speed, -0.05}}, - {{Internal::OMEGADB, 0.0}}, - {}, - {{Internal::OMEGADB, -0.049996641662021946}}}, - {"speed deadband inside the band", - {{External::speed, 0.004}}, - {{Internal::OMEGADB, 0.0}}, - {}, - {{Internal::OMEGADB, 0.0009004582873718001}}}, - {"speed deadband above the band", - {{External::speed, 0.05}}, - {{Internal::OMEGADB, 0.0}}, - {}, - {{Internal::OMEGADB, 0.049996641662021946}}}, + {"speed deadband below the band", + {{External::speed, -0.05}}, + {{Internal::OMEGADB, 0.0}}, + {}, + {{Internal::OMEGADB, -0.049996641662021946}}}, + {"speed deadband inside the band", + {{External::speed, 0.004}}, + {{Internal::OMEGADB, 0.0}}, + {}, + {{Internal::OMEGADB, 0.0009004582873718001}}}, + {"speed deadband above the band", + {{External::speed, 0.05}}, + {{Internal::OMEGADB, 0.0}}, + {}, + {{Internal::OMEGADB, 0.049996641662021946}}}, }}; success *= runResidualCases(data, 0.4, deadband_cases); const std::array gate_velocity_cases{{ - {"gate velocity below the rate limit", - {}, - {{Internal::FC, -0.6}, {Internal::RC, 0.0}}, - {}, - {{Internal::RC, -0.15}}}, - {"gate velocity inside the rate limit", - {}, - {{Internal::FC, 0.05}, {Internal::RC, 0.0}}, - {}, - {{Internal::RC, 0.04999999999984272}}}, - {"gate velocity above the rate limit", - {}, - {{Internal::FC, 0.6}, {Internal::RC, 0.0}}, - {}, - {{Internal::RC, 0.15000000000000002}}}, + {"gate velocity below the rate limit", + {}, + {{Internal::FC, -0.6}, {Internal::RC, 0.0}}, + {}, + {{Internal::RC, -0.15}}}, + {"gate velocity inside the rate limit", + {}, + {{Internal::FC, 0.05}, {Internal::RC, 0.0}}, + {}, + {{Internal::RC, 0.04999999999984272}}}, + {"gate velocity above the rate limit", + {}, + {{Internal::FC, 0.6}, {Internal::RC, 0.0}}, + {}, + {{Internal::RC, 0.15000000000000002}}}, }}; success *= runResidualCases(data, 0.4, gate_velocity_cases); const std::array gate_antiwindup_cases{{ - {"Gmax blocks an outward desired-gate rate", - {}, - {{Internal::C, 1.2}, {Internal::RC, 0.2}}, - {{Internal::C, 0.0}}, - {{Internal::C, 0.0}}}, - {"Gmin blocks an outward desired-gate rate", - {}, - {{Internal::C, -0.2}, {Internal::RC, -0.2}}, - {{Internal::C, 0.0}}, - {{Internal::C, 0.0}}}, - {"Gmax admits a restoring desired-gate rate", - {}, - {{Internal::C, 1.2}, {Internal::RC, -0.2}}, - {{Internal::C, 0.0}}, - {{Internal::C, -0.2}}}, - {"Gmin admits a restoring desired-gate rate", - {}, - {{Internal::C, -0.2}, {Internal::RC, 0.2}}, - {{Internal::C, 0.0}}, - {{Internal::C, 0.2}}}, + {"Gmax blocks an outward desired-gate rate", + {}, + {{Internal::C, 1.2}, {Internal::RC, 0.2}}, + {{Internal::C, 0.0}}, + {{Internal::C, 0.0}}}, + {"Gmin blocks an outward desired-gate rate", + {}, + {{Internal::C, -0.2}, {Internal::RC, -0.2}}, + {{Internal::C, 0.0}}, + {{Internal::C, 0.0}}}, + {"Gmax admits a restoring desired-gate rate", + {}, + {{Internal::C, 1.2}, {Internal::RC, -0.2}}, + {{Internal::C, 0.0}}, + {{Internal::C, -0.2}}}, + {"Gmin admits a restoring desired-gate rate", + {}, + {{Internal::C, -0.2}, {Internal::RC, 0.2}}, + {{Internal::C, 0.0}}, + {{Internal::C, 0.2}}}, }}; success *= runResidualCases(data, 0.4, gate_antiwindup_cases); @@ -780,11 +809,14 @@ namespace GridKit success *= (blocked.evaluate() == 0); const auto& dependencies = - blocked.hygov.getResidual().getData()[static_cast(Internal::C)].getDependencies(); + blocked.hygov.getResidual() + .getData()[static_cast(Internal::C)] + .getDependencies(); const DepVar::DependencyMap expected{{ - {2 * static_cast(Internal::C), 0.0}, // @todo Remove these - {2 * static_cast(Internal::C) + 1, -1.0}, // @todo Remove these - {2 * static_cast(Internal::RC), 0.0}, // @todo Remove these + {2 * static_cast(Internal::C), 0.0}, // @todo Remove these + {2 * static_cast(Internal::C) + 1, + -1.0}, // @todo Remove these + {2 * static_cast(Internal::RC), 0.0}, // @todo Remove these }}; success *= isEqual(dependencies, expected, kTol); } @@ -800,50 +832,51 @@ namespace GridKit const auto data = makeResidualData(); const std::array gate_power_cases{{ - {"gate-power curve segment 1", - {}, - {{Internal::G, 0.1}, {Internal::PGV, 0.0}}, - {}, - {{Internal::PGV, 0.07500000000021236}}}, - {"gate-power curve segment 2", - {}, - {{Internal::G, 0.3}, {Internal::PGV, 0.0}}, - {}, - {{Internal::PGV, 0.28500000000007075}}}, - {"gate-power curve segment 3", - {}, - {{Internal::G, 0.5}, {Internal::PGV, 0.0}}, - {}, - {{Internal::PGV, 0.5399999999999371}}}, - {"gate-power curve segment 4", - {}, - {{Internal::G, 0.7}, {Internal::PGV, 0.0}}, - {}, - {{Internal::PGV, 0.7549999999999292}}}, - {"gate-power curve segment 5", - {}, - {{Internal::G, 0.9}, {Internal::PGV, 0.0}}, - {}, - {{Internal::PGV, 0.9249999999998506}}}, + {"gate-power curve segment 1", + {}, + {{Internal::G, 0.1}, {Internal::PGV, 0.0}}, + {}, + {{Internal::PGV, 0.07500000000021236}}}, + {"gate-power curve segment 2", + {}, + {{Internal::G, 0.3}, {Internal::PGV, 0.0}}, + {}, + {{Internal::PGV, 0.28500000000007075}}}, + {"gate-power curve segment 3", + {}, + {{Internal::G, 0.5}, {Internal::PGV, 0.0}}, + {}, + {{Internal::PGV, 0.5399999999999371}}}, + {"gate-power curve segment 4", + {}, + {{Internal::G, 0.7}, {Internal::PGV, 0.0}}, + {}, + {{Internal::PGV, 0.7549999999999292}}}, + {"gate-power curve segment 5", + {}, + {{Internal::G, 0.9}, {Internal::PGV, 0.0}}, + {}, + {{Internal::PGV, 0.9249999999998506}}}, }}; success *= runResidualCases(data, 0.4, gate_power_cases); // A head away from the dam head drives the flow and head rows, and // turbine damping scales with speed deviation and gate. const std::array turbine_cases{{ - {"water column", - {}, - {{Internal::Q, 0.61}, {Internal::H, 0.9}, {Internal::PGV, 0.55}}, - {{Internal::Q, 0.05}}, - {{Internal::Q, 0.18076923076923068}, {Internal::H, -0.09984999999999994}}}, - {"turbine damping", - {{External::speed, 0.05}}, - {{Internal::G, 0.6}, - {Internal::Q, 0.7}, - {Internal::H, 1.1}, - {Internal::PMECH, 0.5}}, - {}, - {{Internal::PMECH, -0.2677999999999999}}}, + {"water column", + {}, + {{Internal::Q, 0.61}, {Internal::H, 0.9}, {Internal::PGV, 0.55}}, + {{Internal::Q, 0.05}}, + {{Internal::Q, 0.18076923076923068}, + {Internal::H, -0.09984999999999994}}}, + {"turbine damping", + {{External::speed, 0.05}}, + {{Internal::G, 0.6}, + {Internal::Q, 0.7}, + {Internal::H, 1.1}, + {Internal::PMECH, 0.5}}, + {}, + {{Internal::PMECH, -0.2677999999999999}}}, }}; success *= runResidualCases(data, 0.4, turbine_cases); @@ -851,12 +884,16 @@ namespace GridKit curve_fixture.attachAllInputs(); success *= curve_fixture.initialize(0.33761676); success *= stateMatches( - curve_fixture.hygov, - {{Internal::C, 0.5000001394783365}, {Internal::G, 0.5000001394783365}}, - "nonidentity curve inversion"); - success *= scalarMatches(curve_fixture.input(External::pref), - 0.015000004184348527, - "nonidentity-curve published pref"); + curve_fixture.hygov, + {{Internal::C, 0.5000001394783365}, + {Internal::G, 0.5000001394783365}}, + "nonidentity curve inversion" + ); + success *= scalarMatches( + curve_fixture.input(External::pref), + 0.015000004184348527, + "nonidentity-curve published pref" + ); success *= scalarMatches(curve_fixture.pmech(), 0.33761676, "preserved pmech value"); success *= (curve_fixture.evaluate() == 0); success *= allResidualsZero(curve_fixture.hygov); @@ -868,12 +905,13 @@ namespace GridKit const RealT flat_gate_maximum = static_cast(0.6); const RealT plateau_power = static_cast(0.5); const RealT plateau_pmech = static_cast(0.4); - Fixture flat_fixture(makeData(), - {{Params::Pgv2, plateau_power}, - {Params::Pgv3, plateau_power}}); + Fixture flat_fixture( + makeData(), + {{Params::Pgv2, plateau_power}, {Params::Pgv3, plateau_power}} + ); success *= flat_fixture.initialize(plateau_pmech); const RealT flat_gate = - flat_fixture.hygov.y().getData()[static_cast(Internal::G)]; + flat_fixture.hygov.y().getData()[static_cast(Internal::G)]; if (flat_gate < flat_gate_minimum || flat_gate > flat_gate_maximum) { std::cout << "flat-segment plateau gate " @@ -918,7 +956,11 @@ namespace GridKit // Guard the required PGV/G dependency even if both paths agree. success *= jacobianContains( - dependency_jacobian, Internal::PGV, Internal::G, "dependency-tracking"); + dependency_jacobian, + Internal::PGV, + Internal::G, + "dependency-tracking" + ); success *= jacobianContains(enzyme_jacobian, Internal::PGV, Internal::G, "Enzyme"); } @@ -940,8 +982,21 @@ namespace GridKit using ExternalRows = std::vector; /// Failure-report names for the internal rows, ordered as `Internal`. - static constexpr std::array()> kRowNames{ - {"XN", "XF", "C", "G", "Q", "OMEGADB", "EF", "FC", "RC", "PGV", "H", "PMECH"}}; + static constexpr std::array()> + kRowNames{ + {"XN", + "XF", + "C", + "G", + "Q", + "OMEGADB", + "EF", + "FC", + "RC", + "PGV", + "H", + "PMECH"} + }; struct ResidualCase { @@ -952,8 +1007,9 @@ namespace GridKit InternalRows expected; }; - static Data withParameters(Data data, - std::initializer_list> overrides) + static Data withParameters( + Data data, std::initializer_list> overrides + ) { for (const auto& [parameter, value] : overrides) { @@ -972,16 +1028,19 @@ namespace GridKit private: std::array()> input_values_{}; std::array()> input_indices_{}; - std::array, - Utilities::enum_size()> - input_nodes_{}; + std::array< + PhasorDynamics::SignalNode, + Utilities::enum_size()> + input_nodes_{}; PhasorDynamics::SignalNode pmech_node_; public: - explicit Fixture(const Data& data, - std::initializer_list> overrides = {}, - RealT system_va_base = 100.0e6) + explicit Fixture( + const Data& data, + std::initializer_list> overrides = {}, + RealT system_va_base = 100.0e6 + ) : hygov(withParameters(data, overrides)) { hygov.setSystemBase(60.0, system_va_base); @@ -1002,12 +1061,15 @@ namespace GridKit input_nodes_[port].link(&input_values_[port], &input_indices_[port]); } - hygov.getPorts().in.template port().connect( - &input_nodes_[static_cast(External::speed)]); + hygov.getPorts() + .in.template port() + .connect(&input_nodes_[static_cast(External::speed)]); hygov.getPorts().in.template port().connect( - &input_nodes_[static_cast(External::pref)]); + &input_nodes_[static_cast(External::pref)] + ); hygov.getPorts().in.template port().connect( - &input_nodes_[static_cast(External::paux)]); + &input_nodes_[static_cast(External::paux)] + ); } /// Set the assigned mechanical-power node on the system base. @@ -1087,99 +1149,52 @@ namespace GridKit { // These are the documented defaults. The all-zero source curve // selects the identity curve, spelled out here point by point. - return withParameters(makeMinimalData(), - {{Params::Rperm, 0.04}, - {Params::Rtemp, 0.3}, - {Params::Tr, 5.0}, - {Params::Tf, 0.05}, - {Params::Tg, 0.5}, - {Params::Velm, 0.2}, - {Params::Gmax, 1.0}, - {Params::Gmin, 0.0}, - {Params::Tw, 1.0}, - {Params::At, 1.2}, - {Params::Dturb, 0.5}, - {Params::Qnl, 0.05}, - {Params::Tn, 0.0}, - {Params::Tnp, 0.0}, - {Params::db1, 0.0}, - {Params::db2, 0.0}, - {Params::Hdam, 1.0}, - {Params::Gv0, 0.0}, - {Params::Gv1, 0.2}, - {Params::Gv2, 0.4}, - {Params::Gv3, 0.6}, - {Params::Gv4, 0.8}, - {Params::Gv5, 1.0}, - {Params::Pgv0, 0.0}, - {Params::Pgv1, 0.2}, - {Params::Pgv2, 0.4}, - {Params::Pgv3, 0.6}, - {Params::Pgv4, 0.8}, - {Params::Pgv5, 1.0}}); + return withParameters( + makeMinimalData(), + {{Params::Rperm, 0.04}, {Params::Rtemp, 0.3}, {Params::Tr, 5.0}, + {Params::Tf, 0.05}, {Params::Tg, 0.5}, {Params::Velm, 0.2}, + {Params::Gmax, 1.0}, {Params::Gmin, 0.0}, {Params::Tw, 1.0}, + {Params::At, 1.2}, {Params::Dturb, 0.5}, {Params::Qnl, 0.05}, + {Params::Tn, 0.0}, {Params::Tnp, 0.0}, {Params::db1, 0.0}, + {Params::db2, 0.0}, {Params::Hdam, 1.0}, {Params::Gv0, 0.0}, + {Params::Gv1, 0.2}, {Params::Gv2, 0.4}, {Params::Gv3, 0.6}, + {Params::Gv4, 0.8}, {Params::Gv5, 1.0}, {Params::Pgv0, 0.0}, + {Params::Pgv1, 0.2}, {Params::Pgv2, 0.4}, {Params::Pgv3, 0.6}, + {Params::Pgv4, 0.8}, {Params::Pgv5, 1.0}} + ); } Data makeData() const { // The documented typical values with the floored time constants // raised above the floor, so routine fixtures log no warnings. - return withParameters(makeMinimalData(), - {{Params::Trate, 100.0}, - {Params::Rperm, 0.05}, - {Params::Rtemp, 0.4}, - {Params::Tr, 5.0}, - {Params::Tf, 0.2}, - {Params::Tg, 0.5}, - {Params::Velm, 0.5}, - {Params::Gmax, 1.0}, - {Params::Gmin, 0.0}, - {Params::Tw, 1.0}, - {Params::At, 1.0}, - {Params::Dturb, 0.0}, - {Params::Qnl, 0.1}, - {Params::Tn, 0.0}, - {Params::Tnp, 1.0}, - {Params::db1, 0.0}, - {Params::db2, 0.0}, - {Params::Hdam, 1.0}, - {Params::Gv0, 0.0}, - {Params::Gv1, 0.2}, - {Params::Gv2, 0.4}, - {Params::Gv3, 0.6}, - {Params::Gv4, 0.8}, - {Params::Gv5, 1.0}, - {Params::Pgv0, 0.0}, - {Params::Pgv1, 0.2}, - {Params::Pgv2, 0.4}, - {Params::Pgv3, 0.6}, - {Params::Pgv4, 0.8}, - {Params::Pgv5, 1.0}}); + return withParameters( + makeMinimalData(), + {{Params::Trate, 100.0}, {Params::Rperm, 0.05}, {Params::Rtemp, 0.4}, + {Params::Tr, 5.0}, {Params::Tf, 0.2}, {Params::Tg, 0.5}, + {Params::Velm, 0.5}, {Params::Gmax, 1.0}, {Params::Gmin, 0.0}, + {Params::Tw, 1.0}, {Params::At, 1.0}, {Params::Dturb, 0.0}, + {Params::Qnl, 0.1}, {Params::Tn, 0.0}, {Params::Tnp, 1.0}, + {Params::db1, 0.0}, {Params::db2, 0.0}, {Params::Hdam, 1.0}, + {Params::Gv0, 0.0}, {Params::Gv1, 0.2}, {Params::Gv2, 0.4}, + {Params::Gv3, 0.6}, {Params::Gv4, 0.8}, {Params::Gv5, 1.0}, + {Params::Pgv0, 0.0}, {Params::Pgv1, 0.2}, {Params::Pgv2, 0.4}, + {Params::Pgv3, 0.6}, {Params::Pgv4, 0.8}, {Params::Pgv5, 1.0}} + ); } Data makeResidualData() const { - return withParameters(makeData(), - {{Params::Trate, 50.0}, - {Params::Rperm, 0.06}, - {Params::Rtemp, 0.4}, - {Params::Tr, 4.0}, - {Params::Tf, 0.2}, - {Params::Tg, 0.6}, - {Params::Velm, 0.15}, - {Params::Gmax, 0.95}, - {Params::Gmin, 0.05}, - {Params::Tw, 1.3}, - {Params::At, 1.1}, - {Params::Dturb, 0.6}, - {Params::Qnl, 0.08}, - {Params::Tn, 0.7}, - {Params::Tnp, 1.4}, - {Params::db1, 0.01}, - {Params::Hdam, 1.2}, - {Params::Pgv1, 0.15}, - {Params::Pgv2, 0.42}, - {Params::Pgv3, 0.66}, - {Params::Pgv4, 0.85}}); + return withParameters( + makeData(), + {{Params::Trate, 50.0}, {Params::Rperm, 0.06}, {Params::Rtemp, 0.4}, + {Params::Tr, 4.0}, {Params::Tf, 0.2}, {Params::Tg, 0.6}, + {Params::Velm, 0.15}, {Params::Gmax, 0.95}, {Params::Gmin, 0.05}, + {Params::Tw, 1.3}, {Params::At, 1.1}, {Params::Dturb, 0.6}, + {Params::Qnl, 0.08}, {Params::Tn, 0.7}, {Params::Tnp, 1.4}, + {Params::db1, 0.01}, {Params::Hdam, 1.2}, {Params::Pgv1, 0.15}, + {Params::Pgv2, 0.42}, {Params::Pgv3, 0.66}, {Params::Pgv4, 0.85}} + ); } template @@ -1195,25 +1210,29 @@ namespace GridKit template void setAnswerKeyState(PhasorDynamics::Governor::Hygov& hygov) const { - setState(hygov, - {{Internal::XN, 0.11}, - {Internal::XF, 0.23}, - {Internal::C, 0.52}, - {Internal::G, 0.47}, - {Internal::Q, 0.61}, - {Internal::OMEGADB, 0.015}, - {Internal::EF, 0.08}, - {Internal::FC, 0.12}, - {Internal::RC, 0.09}, - {Internal::PGV, 0.55}, - {Internal::H, 1.12}, - {Internal::PMECH, 0.33}}); - setDerivative(hygov, - {{Internal::XN, 0.01}, - {Internal::XF, -0.02}, - {Internal::C, 0.03}, - {Internal::G, -0.04}, - {Internal::Q, 0.05}}); + setState( + hygov, + {{Internal::XN, 0.11}, + {Internal::XF, 0.23}, + {Internal::C, 0.52}, + {Internal::G, 0.47}, + {Internal::Q, 0.61}, + {Internal::OMEGADB, 0.015}, + {Internal::EF, 0.08}, + {Internal::FC, 0.12}, + {Internal::RC, 0.09}, + {Internal::PGV, 0.55}, + {Internal::H, 1.12}, + {Internal::PMECH, 0.33}} + ); + setDerivative( + hygov, + {{Internal::XN, 0.01}, + {Internal::XF, -0.02}, + {Internal::C, 0.03}, + {Internal::G, -0.04}, + {Internal::Q, 0.05}} + ); } /// Omitting every optional parameter must give exactly the model built @@ -1241,21 +1260,27 @@ namespace GridKit { success = false; } - if (!vectorUnchanged(implicit_defaults.hygov.y(), - copyVector(explicit_defaults.hygov.y()), - "documented-default state")) + if (!vectorUnchanged( + implicit_defaults.hygov.y(), + copyVector(explicit_defaults.hygov.y()), + "documented-default state" + )) { success = false; } - if (!vectorUnchanged(implicit_defaults.hygov.yp(), - copyVector(explicit_defaults.hygov.yp()), - "documented-default derivative")) + if (!vectorUnchanged( + implicit_defaults.hygov.yp(), + copyVector(explicit_defaults.hygov.yp()), + "documented-default derivative" + )) { success = false; } - if (!vectorUnchanged(implicit_defaults.hygov.getResidual(), - copyVector(explicit_defaults.hygov.getResidual()), - "documented-default residual")) + if (!vectorUnchanged( + implicit_defaults.hygov.getResidual(), + copyVector(explicit_defaults.hygov.getResidual()), + "documented-default residual" + )) { success = false; } @@ -1272,9 +1297,11 @@ namespace GridKit { success = false; } - if (!vectorUnchanged(implicit_defaults.hygov.getResidual(), - copyVector(explicit_defaults.hygov.getResidual()), - "documented-default dynamic residual")) + if (!vectorUnchanged( + implicit_defaults.hygov.getResidual(), + copyVector(explicit_defaults.hygov.getResidual()), + "documented-default dynamic residual" + )) { success = false; } @@ -1294,14 +1321,17 @@ namespace GridKit std::vector copyVector(const VectorT& vector) const { const auto* values = vector.getData(); - return std::vector(values, - values + static_cast(vector.getSize())); + return std::vector( + values, values + static_cast(vector.getSize()) + ); } template - bool vectorUnchanged(const VectorT& vector, - const std::vector& snapshot, - const char* what) const + bool vectorUnchanged( + const VectorT& vector, + const std::vector& snapshot, + const char* what + ) const { bool success = true; const auto* values = vector.getData(); @@ -1317,10 +1347,9 @@ namespace GridKit /// An initialization input retains exactly the value supplied by its /// owner, including signed infinities and NaN. - bool scalarPreserved(RealT actual, - RealT expected, - const char* what, - size_t row) const + bool scalarPreserved( + RealT actual, RealT expected, const char* what, size_t row + ) const { bool ret = actual == expected; if (std::isnan(expected)) @@ -1354,10 +1383,12 @@ namespace GridKit /// Initialization must fail and leave the poisoned state, the seeded /// pmech value, and every supplied input untouched. - bool initializationRejectedAtomically(const Data& data, - RealT pmech, - const ExternalRows& inputs, - const char* label) const + bool initializationRejectedAtomically( + const Data& data, + RealT pmech, + const ExternalRows& inputs, + const char* label + ) const { Fixture fixture(data); fixture.attachAllInputs(); @@ -1387,10 +1418,12 @@ namespace GridKit } for (const auto& [port, value] : inputs) { - if (!scalarPreserved(static_cast(fixture.input(port)), - value, - "external input", - static_cast(port))) + if (!scalarPreserved( + static_cast(fixture.input(port)), + value, + "external input", + static_cast(port) + )) { success = false; } @@ -1409,8 +1442,10 @@ namespace GridKit /// Write state rows and publish the update, folding in the /// setDataUpdated() that a hand-written write block has to remember. template - void setState(PhasorDynamics::Governor::Hygov& hygov, - const InternalRows& rows) const + void setState( + PhasorDynamics::Governor::Hygov& hygov, + const InternalRows& rows + ) const { auto* y = hygov.y().getData(); for (const auto& [variable, value] : rows) @@ -1421,8 +1456,10 @@ namespace GridKit } template - void setDerivative(PhasorDynamics::Governor::Hygov& hygov, - const InternalRows& rows) const + void setDerivative( + PhasorDynamics::Governor::Hygov& hygov, + const InternalRows& rows + ) const { auto* yp = hygov.yp().getData(); for (const auto& [variable, value] : rows) @@ -1434,9 +1471,11 @@ namespace GridKit /// Evaluate each scenario on a fresh fixture to prevent state leakage. template - bool runResidualCases(const Data& data, - RealT pmech, - const std::array& cases) const + bool runResidualCases( + const Data& data, + RealT pmech, + const std::array& cases + ) const { bool success = true; for (const auto& test_case : cases) @@ -1467,11 +1506,13 @@ namespace GridKit } /// Compare one named row and report mismatches consistently. - bool rowMatches(RealT actual, - RealT expected, - const char* what, - size_t row, - const char* context) const + bool rowMatches( + RealT actual, + RealT expected, + const char* what, + size_t row, + const char* context + ) const { if (isEqual(actual, expected, kTol)) { @@ -1493,10 +1534,12 @@ namespace GridKit } template - bool rowsMatch(const VectorT& vector, - const RowsT& rows, - const char* what, - const char* context) const + bool rowsMatch( + const VectorT& vector, + const RowsT& rows, + const char* what, + const char* context + ) const { bool success = true; const auto* values = vector.getData(); @@ -1511,24 +1554,26 @@ namespace GridKit return success; } - bool residualsMatch(const HygovT& hygov, - const InternalRows& rows, - const char* context = "") const + bool residualsMatch( + const HygovT& hygov, const InternalRows& rows, const char* context = "" + ) const { return rowsMatch(hygov.getResidual(), rows, "residual", context); } template - bool residualsMatch(const HygovT& hygov, - const std::array& rows, - const char* context = "") const + bool residualsMatch( + const HygovT& hygov, + const std::array& rows, + const char* context = "" + ) const { return rowsMatch(hygov.getResidual(), rows, "residual", context); } - bool stateMatches(const HygovT& hygov, - const InternalRows& rows, - const char* context = "") const + bool stateMatches( + const HygovT& hygov, const InternalRows& rows, const char* context = "" + ) const { return rowsMatch(hygov.y(), rows, "state", context); } @@ -1554,10 +1599,12 @@ namespace GridKit return success; } - bool scalarMatches(ScalarT actual, - ScalarT expected, - const char* label, - ScalarT tolerance = kTol) const + bool scalarMatches( + ScalarT actual, + ScalarT expected, + const char* label, + ScalarT tolerance = kTol + ) const { if (isEqual(actual, expected, tolerance)) { @@ -1592,10 +1639,12 @@ namespace GridKit #ifdef GRIDKIT_ENABLE_ENZYME template - bool jacobianContains(const JacobianRowsT& rows, - Internal row_variable, - Internal column_variable, - const char* what) const + bool jacobianContains( + const JacobianRowsT& rows, + Internal row_variable, + Internal column_variable, + const char* what + ) const { const auto row = static_cast(row_variable); const auto column = static_cast(column_variable); @@ -1608,10 +1657,10 @@ namespace GridKit return false; } - std::vector dependencyTrackingJacobian( - const Data& data, - RealT gate, - TestStatus& success) const + std::vector + dependencyTrackingJacobian( + const Data& data, RealT gate, TestStatus& success + ) const { using DepVar = DependencyTracking::Variable; @@ -1630,9 +1679,8 @@ namespace GridKit } std::vector enzymeJacobian( - const Data& data, - RealT gate, - TestStatus& success) const + const Data& data, RealT gate, TestStatus& success + ) const { Fixture fixture(data); fixture.attachAllInputs(); diff --git a/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp b/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp index 0fce7d31f8..42744a2dcb 100644 --- a/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp +++ b/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp @@ -40,7 +40,9 @@ namespace GridKit PhasorDynamics::Bus bus(1.0, 0.0); PhasorDynamics::Governor::Tgov1* gov = - new PhasorDynamics::Governor::Tgov1(PhasorDynamics::Governor::Tgov1Data{}); + new PhasorDynamics::Governor::Tgov1( + PhasorDynamics::Governor::Tgov1Data{} + ); success *= (gov != nullptr); @@ -105,9 +107,11 @@ namespace GridKit gov.getPorts().in.template port().connect(&omega); // Test answer keys - const std::vector res_answer = {static_cast(2.0) / static_cast(15.0), - -2.0, - static_cast(1.0) / static_cast(3.0)}; + const std::vector res_answer = { + static_cast(2.0) / static_cast(15.0), + -2.0, + static_cast(1.0) / static_cast(3.0) + }; bus.allocate(); gen.allocate(); @@ -303,9 +307,11 @@ namespace GridKit } private: - std::vector DependencyTrackingJacobian( - PhasorDynamics::BusData busdata, - PhasorDynamics::GenrouData gendata) + std::vector + DependencyTrackingJacobian( + PhasorDynamics::BusData busdata, + PhasorDynamics::GenrouData gendata + ) { PhasorDynamics::Bus bus(busdata); PhasorDynamics::SignalNode pmech; @@ -344,8 +350,9 @@ namespace GridKit } std::vector EnzymeJacobian( - PhasorDynamics::BusData busdata, - PhasorDynamics::GenrouData gendata) + PhasorDynamics::BusData busdata, + PhasorDynamics::GenrouData gendata + ) { PhasorDynamics::Bus bus(busdata); PhasorDynamics::SignalNode pmech; diff --git a/tests/UnitTests/PhasorDynamics/LoadZIPTests.hpp b/tests/UnitTests/PhasorDynamics/LoadZIPTests.hpp index fcf33dce7f..8edfcd759b 100644 --- a/tests/UnitTests/PhasorDynamics/LoadZIPTests.hpp +++ b/tests/UnitTests/PhasorDynamics/LoadZIPTests.hpp @@ -37,7 +37,7 @@ namespace GridKit auto* bus = new PhasorDynamics::Bus(1.0, 0.0); PhasorDynamics::Component* load = - new PhasorDynamics::LoadZIP(bus, DataT{}); + new PhasorDynamics::LoadZIP(bus, DataT{}); success *= (load != nullptr); @@ -215,8 +215,13 @@ namespace GridKit } private: - std::vector DependencyTrackingJacobian( - const RealT Pnom, const RealT Qnom, const RealT alphaI, const RealT alphaP) + std::vector + DependencyTrackingJacobian( + const RealT Pnom, + const RealT Qnom, + const RealT alphaI, + const RealT alphaP + ) { DependencyTracking::Variable Vr{0.3}; DependencyTracking::Variable Vi{0.4}; @@ -250,7 +255,11 @@ namespace GridKit } std::vector EnzymeJacobian( - const RealT Pnom, const RealT Qnom, const RealT alphaI, const RealT alphaP) + const RealT Pnom, + const RealT Qnom, + const RealT alphaI, + const RealT alphaP + ) { ScalarT Vr{0.3}; ScalarT Vi{0.4}; diff --git a/tests/UnitTests/PhasorDynamics/LoadZTests.hpp b/tests/UnitTests/PhasorDynamics/LoadZTests.hpp index 8ad661f043..8f5811670b 100644 --- a/tests/UnitTests/PhasorDynamics/LoadZTests.hpp +++ b/tests/UnitTests/PhasorDynamics/LoadZTests.hpp @@ -38,7 +38,7 @@ namespace GridKit auto* bus = new PhasorDynamics::Bus(1.0, 0.0); PhasorDynamics::Component* load = - new PhasorDynamics::LoadZ(bus, DataT{}); + new PhasorDynamics::LoadZ(bus, DataT{}); success *= (load != nullptr); @@ -249,8 +249,8 @@ namespace GridKit return data; } - std::vector analyticalJacobian(const RealT R, - const RealT X) + std::vector + analyticalJacobian(const RealT R, const RealT X) { const RealT b = -X / (R * R + X * X); const RealT g = R / (R * R + X * X); diff --git a/tests/UnitTests/PhasorDynamics/ModelConfigurationTests.hpp b/tests/UnitTests/PhasorDynamics/ModelConfigurationTests.hpp index 91e0f4c698..7d5d11b61b 100644 --- a/tests/UnitTests/PhasorDynamics/ModelConfigurationTests.hpp +++ b/tests/UnitTests/PhasorDynamics/ModelConfigurationTests.hpp @@ -38,13 +38,14 @@ namespace GridKit { private: using Params = ReaderTestParameters; - using DataT = PhasorDynamics::ComponentData; + using DataT = PhasorDynamics::ComponentData< + RealT, + IdxT, + Params, + Utilities::EmptyEnum, + Utilities::EmptyEnum, + Utilities::EmptyEnum, + Utilities::EmptyEnum>; public: /// Omitted parameters return no value, integers widen to reals, and @@ -54,16 +55,18 @@ namespace GridKit TestStatus success = true; DataT data; - data.parameters = {{Params::integer, static_cast(2)}, - {Params::real, static_cast(0.5)}, - {Params::zero, ZERO}, - {Params::negative, -ONE}, - {Params::infinite, std::numeric_limits::infinity()}, - {Params::not_a_number, std::numeric_limits::quiet_NaN()}, - {Params::integer_flag, static_cast(1)}, - {Params::false_flag, false}, - {Params::true_flag, true}, - {Params::text, std::string("2")}}; + data.parameters = { + {Params::integer, static_cast(2)}, + {Params::real, static_cast(0.5)}, + {Params::zero, ZERO}, + {Params::negative, -ONE}, + {Params::infinite, std::numeric_limits::infinity()}, + {Params::not_a_number, std::numeric_limits::quiet_NaN()}, + {Params::integer_flag, static_cast(1)}, + {Params::false_flag, false}, + {Params::true_flag, true}, + {Params::text, std::string("2")} + }; const Model::ParameterReader reader(data, "Test"); diff --git a/tests/UnitTests/PhasorDynamics/StabilizerIeeestTests.hpp b/tests/UnitTests/PhasorDynamics/StabilizerIeeestTests.hpp index b0e6c2c7e6..8e684e2557 100644 --- a/tests/UnitTests/PhasorDynamics/StabilizerIeeestTests.hpp +++ b/tests/UnitTests/PhasorDynamics/StabilizerIeeestTests.hpp @@ -133,18 +133,18 @@ namespace GridKit // Hand-computed answer key (see plan for full derivation) const std::vector res_answer = { - 0.19, // f[0]: -x1_dot + x2 - 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]: -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]: -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.19, // f[0]: -x1_dot + x2 + 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]: -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]: -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]) }; // Looser tolerance for f[11] — Math::clamp is a smooth ramp approximation. @@ -181,10 +181,10 @@ namespace GridKit auto data = makeTestData(); std::vector - dependency_tracking_jacobian = DependencyTrackingJacobian(data); + dependency_tracking_jacobian = DependencyTrackingJacobian(data); std::vector - enzyme_jacobian = EnzymeJacobian(data); + enzyme_jacobian = EnzymeJacobian(data); // Compare DependencyTracking dependencies to Enzyme's auto tol = 10 * std::numeric_limits::epsilon(); @@ -197,8 +197,10 @@ namespace GridKit } private: - std::vector DependencyTrackingJacobian( - PhasorDynamics::Stabilizer::IeeestData ieeestdata) + std::vector + DependencyTrackingJacobian( + PhasorDynamics::Stabilizer::IeeestData ieeestdata + ) { using DepVar = DependencyTracking::Variable; @@ -239,7 +241,8 @@ namespace GridKit } std::vector EnzymeJacobian( - PhasorDynamics::Stabilizer::IeeestData ieeestdata) + PhasorDynamics::Stabilizer::IeeestData ieeestdata + ) { PhasorDynamics::SignalNode u_node; PhasorDynamics::SignalNode vss_node; diff --git a/tests/UnitTests/PhasorDynamics/SubsystemModelTests.hpp b/tests/UnitTests/PhasorDynamics/SubsystemModelTests.hpp index 4aee9499de..a32e098ebb 100644 --- a/tests/UnitTests/PhasorDynamics/SubsystemModelTests.hpp +++ b/tests/UnitTests/PhasorDynamics/SubsystemModelTests.hpp @@ -179,10 +179,12 @@ namespace GridKit // Device uses a signal of its parent const json signal_r = {{"signal_id", 1}, {"name", "sr"}}; const json signal_i = {{"signal_id", 2}, {"name", "si"}}; - const json source = {{"class", "ConstantSignalSource"}, - {"ports", {{"sr", 1}, {"si", 2}}}, - {"id", "1"}, - {"params", json::object()}}; + const json source = { + {"class", "ConstantSignalSource"}, + {"ports", {{"sr", 1}, {"si", 2}}}, + {"id", "1"}, + {"params", json::object()} + }; input = hierarchical; input["signals"] = json::array({signal_r, signal_i}); input["subsystems"][0]["devices"].push_back(source); @@ -312,7 +314,8 @@ namespace GridKit auto* c = b->getSubsystem(0); PhasorDynamics::SystemModel top_dt( - readJson("SubsystemHierarchical.json").template get()); + readJson("SubsystemHierarchical.json").template get() + ); for (auto* system : {&flat, &top}) { diff --git a/tests/UnitTests/PhasorDynamics/SystemTests.hpp b/tests/UnitTests/PhasorDynamics/SystemTests.hpp index a5d67d422b..434aa7fb48 100644 --- a/tests/UnitTests/PhasorDynamics/SystemTests.hpp +++ b/tests/UnitTests/PhasorDynamics/SystemTests.hpp @@ -38,12 +38,14 @@ namespace GridKit using ComponentT = PhasorDynamics::Component; using RealT = typename ComponentT::RealT; - static PhasorDynamics::BranchData branchData(const RealT R, - const RealT X, - const RealT G, - const RealT B, - const RealT tap = 1.0, - const RealT phase = 0.0) + static PhasorDynamics::BranchData branchData( + const RealT R, + const RealT X, + const RealT G, + const RealT B, + const RealT tap = 1.0, + const RealT phase = 0.0 + ) { using Parameter = PhasorDynamics::BranchParameters; @@ -398,11 +400,13 @@ namespace GridKit auto rebind = [&](auto& model, IdxT offset) { - return model.bind(system.y(), - system.yp(), - system.getResidual(), - system.absoluteTolerance(), - offset); + return model.bind( + system.y(), + system.yp(), + system.getResidual(), + system.absoluteTolerance(), + offset + ); }; // Rebinding the same slices is a no-op. @@ -437,9 +441,7 @@ namespace GridKit // Suppress the expected signal-configuration error below. // Use EVERYTHING to inspect the diagnostic. Log::setVerbosity(Log::Verbosity::NONE); - status *= throws( - [&]() - { sys.allocate(); }); + status *= throws([&]() { sys.allocate(); }); Log::setVerbosity(previous_verbosity); return status.report(__func__); @@ -462,9 +464,7 @@ namespace GridKit // Suppress the expected child-allocation error below. // Use EVERYTHING to inspect the diagnostic. Log::setVerbosity(Log::Verbosity::NONE); - status *= throws( - [&]() - { system.allocate(); }); + status *= throws([&]() { system.allocate(); }); Log::setVerbosity(previous_verbosity); return status.report(__func__); @@ -548,8 +548,10 @@ namespace GridKit } private: - std::vector DependencyTrackingJacobian( - PhasorDynamics::SystemModelData data) + std::vector + DependencyTrackingJacobian( + PhasorDynamics::SystemModelData data + ) { // Create an empty system model PhasorDynamics::SystemModel system(data); @@ -570,7 +572,8 @@ namespace GridKit } std::vector EnzymeJacobian( - PhasorDynamics::SystemModelData data) + PhasorDynamics::SystemModelData data + ) { // Create an empty system model PhasorDynamics::SystemModel system(data); diff --git a/tests/UnitTests/Solver/KinsolTests.hpp b/tests/UnitTests/Solver/KinsolTests.hpp index 28fc212e92..c1f7dda0a4 100644 --- a/tests/UnitTests/Solver/KinsolTests.hpp +++ b/tests/UnitTests/Solver/KinsolTests.hpp @@ -84,13 +84,14 @@ namespace GridKit outcome *= isEqual(values[1], 3.0); solver.runSimulation( - values, - [](auto x, auto f) - { - f[0] = x[0] - 7.0; - f[1] = x[1] + 1.0; - return 0; - }); + values, + [](auto x, auto f) + { + f[0] = x[0] - 7.0; + f[1] = x[1] + 1.0; + return 0; + } + ); outcome *= isEqual(values[0], 7.0); outcome *= isEqual(values[1], -1.0); diff --git a/tests/UnitTests/Utilities/CaseFormatTests.hpp b/tests/UnitTests/Utilities/CaseFormatTests.hpp index d5d974a6e9..8cbae39ba5 100644 --- a/tests/UnitTests/Utilities/CaseFormatTests.hpp +++ b/tests/UnitTests/Utilities/CaseFormatTests.hpp @@ -58,10 +58,12 @@ namespace GridKit json input = case_input; if (hierarchical) { - input["subsystems"] = json::array({{{"id", "area"}, - {"level", 1}, - {"buses", input["buses"]}, - {"devices", input["devices"]}}}); + input["subsystems"] = json::array( + {{{"id", "area"}, + {"level", 1}, + {"buses", input["buses"]}, + {"devices", input["devices"]}}} + ); input["buses"] = json::array(); input["devices"] = json::array(); } @@ -125,7 +127,7 @@ namespace GridKit using ReecbData = Controller::ReecbData; const char data[] = - R"({ + R"({ "header": { "format_version": 0.2, "format_revision": 0, @@ -265,13 +267,17 @@ namespace GridKit success *= result.reecb[0].buses[ReecbData::Buses::bus] == 1; success *= result.reecb[0].disambiguation_string == "REE1"; success *= result.reecb[0].monitored_variables.contains( - ReecbData::MonitorableVariables::iqcmd); + ReecbData::MonitorableVariables::iqcmd + ); success *= result.reecb[0].monitored_variables.contains( - ReecbData::MonitorableVariables::ipcmd); + ReecbData::MonitorableVariables::ipcmd + ); success *= result.reecb[0].monitored_variables.contains( - ReecbData::MonitorableVariables::vmeas); + ReecbData::MonitorableVariables::vmeas + ); success *= result.reecb[0].monitored_variables.contains( - ReecbData::MonitorableVariables::pmeas); + ReecbData::MonitorableVariables::pmeas + ); return success.report(__func__); } @@ -287,7 +293,7 @@ namespace GridKit using RepcaData = Controller::RepcaData; const char data[] = - R"({ + R"({ "header": { "format_version": 0.2, "format_revision": 0, @@ -555,7 +561,8 @@ namespace GridKit success *= result.hygov[0].monitored_variables.contains(HygovData::MonitorableVariables::pmech); success *= result.hygov[0].monitored_variables.contains(HygovData::MonitorableVariables::filter); success *= result.hygov[0].monitored_variables.contains( - HygovData::MonitorableVariables::desiredgate); + HygovData::MonitorableVariables::desiredgate + ); success *= result.hygov[0].monitored_variables.contains(HygovData::MonitorableVariables::gate); success *= result.hygov[0].monitored_variables.contains(HygovData::MonitorableVariables::flow); success *= result.hygov[0].monitored_variables.contains(HygovData::MonitorableVariables::head); @@ -681,13 +688,17 @@ namespace GridKit success *= result.reecb[0].signal_outputs[ReecbData::SignalOutputs::ipcmd] == 28; success *= result.reecb[0].disambiguation_string == "EC1"; success *= result.reecb[0].monitored_variables.contains( - ReecbData::MonitorableVariables::iqcmd); + ReecbData::MonitorableVariables::iqcmd + ); success *= result.reecb[0].monitored_variables.contains( - ReecbData::MonitorableVariables::ipcmd); + ReecbData::MonitorableVariables::ipcmd + ); success *= result.reecb[0].monitored_variables.contains( - ReecbData::MonitorableVariables::vmeas); + ReecbData::MonitorableVariables::vmeas + ); success *= result.reecb[0].monitored_variables.contains( - ReecbData::MonitorableVariables::pmeas); + ReecbData::MonitorableVariables::pmeas + ); return success.report(__func__); } diff --git a/tests/UnitTests/Utilities/CliArgsTests.hpp b/tests/UnitTests/Utilities/CliArgsTests.hpp index 87d5abbddd..1cf6ec2b72 100644 --- a/tests/UnitTests/Utilities/CliArgsTests.hpp +++ b/tests/UnitTests/Utilities/CliArgsTests.hpp @@ -40,20 +40,21 @@ namespace GridKit TestStatus status{true}; CliArgs args{ - {.name = {"--opt1"}, .help = "an option with an argument"}, + {.name = {"--opt1"}, .help = "an option with an argument"}, - {.name = {"--opt2", "-o"}, - .help = "An option with an argument and a short-hand", - .type = ArgType::Integer, - .defaults = 0}, + {.name = {"--opt2", "-o"}, + .help = "An option with an argument and a short-hand", + .type = ArgType::Integer, + .defaults = 0}, - {.name = {"--opt3"}, - .help = "An option with two arguments", - .nargs = 2}, + {.name = {"--opt3"}, + .help = "An option with two arguments", + .nargs = 2}, - {.name = {"--flag1", "-f"}, - .help = "A flag option (no argument)", - .flag = true}}; + {.name = {"--flag1", "-f"}, + .help = "A flag option (no argument)", + .flag = true} + }; status *= args["opt1"].empty(); status *= !args["opt2"].empty(); @@ -68,14 +69,17 @@ namespace GridKit Log::misc() << "Expect error because options cannot be duplicated\n"; Log::setVerbosity(previous_verbosity); status *= throws( - [&]() - { CliArgs args{{.name = {"--opt1"}}, {.name = {"--opt1", "-o"}}}; }); + [&]() + { CliArgs args{{.name = {"--opt1"}}, {.name = {"--opt1", "-o"}}}; } + ); status *= throws( - [&]() - { - CliArgs args{ - {.name = {"--opt1", "-o"}}, {.name = {"--opt2", "-o"}}}; - }); + [&]() + { + CliArgs args{ + {.name = {"--opt1", "-o"}}, {.name = {"--opt2", "-o"}} + }; + } + ); return status.report(__func__); } @@ -88,34 +92,36 @@ namespace GridKit using namespace GridKit::Utilities; CliArgs args{ - {.name = {"--file"}, .required = true}, + {.name = {"--file"}, .required = true}, - {.name = {"--twoargs"}, .nargs = 2}, + {.name = {"--twoargs"}, .nargs = 2}, - {.name = {"--size", "-N"}, .type = ArgType::Integer}, + {.name = {"--size", "-N"}, .type = ArgType::Integer}, - {.name = {"--tol", "-t"}, .type = ArgType::Real}, + {.name = {"--tol", "-t"}, .type = ArgType::Real}, - {.name = {"--params", "-p"}, - .type = ArgType::Real, - .nargs = 3, - .defaults = {0, 0, 0}}}; + {.name = {"--params", "-p"}, + .type = ArgType::Real, + .nargs = 3, + .defaults = {0, 0, 0}} + }; CommandLine cl{ - "phony", - "--file", - "fake.txt", - "--twoargs", - "arg1", - "arg2", - "-N", - "16", - "-t", - "0.01", - "--params", - "0.025", - "-1.14", - "-21"}; + "phony", + "--file", + "fake.txt", + "--twoargs", + "arg1", + "arg2", + "-N", + "16", + "-t", + "0.01", + "--params", + "0.025", + "-1.14", + "-21" + }; args.parseArgs(cl.argc, cl.argv); @@ -143,7 +149,7 @@ namespace GridKit status *= isEqual(y, -1.14); status *= isEqual(z, -21.0); status *= - args.get("params") == args["params"].as(); + args.get("params") == args["params"].as(); const auto previous_verbosity = Log::verbosity(); Log::setVerbosity(Log::Verbosity::EVERYTHING); @@ -160,27 +166,29 @@ namespace GridKit { using namespace GridKit::Utilities; CliArgs args{ - {.name = {"solver_file"}, .required = true, .positional = true}, - {.name = {"--item", "-i"}, .repeatable = true}, - {.name = {"--pair"}, - .nargs = 2, - .defaults = {0, 0}, - .repeatable = true}, - {.name = {"--flag", "-f"}, .flag = true}}; + {.name = {"solver_file"}, .required = true, .positional = true}, + {.name = {"--item", "-i"}, .repeatable = true}, + {.name = {"--pair"}, + .nargs = 2, + .defaults = {0, 0}, + .repeatable = true}, + {.name = {"--flag", "-f"}, .flag = true} + }; CommandLine cl{ - "app", - "-f", - "--item", - "friendly name=1", - "study with spaces.solver.json", - "--pair", - "-1", - "2", - "-i", - "other=2", - "--pair", - "3", - "4"}; + "app", + "-f", + "--item", + "friendly name=1", + "study with spaces.solver.json", + "--pair", + "-1", + "2", + "-i", + "other=2", + "--pair", + "3", + "4" + }; args.parseArgs(cl.argc, cl.argv); @@ -205,9 +213,10 @@ namespace GridKit status *= args["pair"].as() == std::array{0, 0}; CliArgs positionals{ - {.name = {"first"}, .positional = true}, - {.name = {"second"}, .nargs = 2, .positional = true}, - {.name = {"--flag"}, .flag = true}}; + {.name = {"first"}, .positional = true}, + {.name = {"second"}, .nargs = 2, .positional = true}, + {.name = {"--flag"}, .flag = true} + }; CommandLine multiple{"app", "one", "--flag", "two", "three"}; positionals.parseArgs(multiple.argc, multiple.argv); status *= positionals.get("first") == "one"; @@ -222,40 +231,47 @@ namespace GridKit const auto argsAreBad = [&](auto&& cl) { CliArgs args{ - {.name = {"solver_file"}, .required = true, .positional = true}, - {.name = {"--one"}}, - {.name = {"--item"}, .nargs = 2, .repeatable = true}, - {.name = {"--flag"}, .flag = true}}; + {.name = {"solver_file"}, .required = true, .positional = true}, + {.name = {"--one"}}, + {.name = {"--item"}, .nargs = 2, .repeatable = true}, + {.name = {"--flag"}, .flag = true} + }; return throws( - [&]() - { args.parseArgs(cl.argc, cl.argv); }); + [&]() { args.parseArgs(cl.argc, cl.argv); } + ); }; TestStatus status{true}; status *= argsAreBad(CommandLine{"app"}); status *= argsAreBad(CommandLine{"app", "a.solver.json", "b.solver.json"}); status *= argsAreBad(CommandLine{"app", "--solver-file", "a.solver.json"}); - status *= - argsAreBad(CommandLine{"app", "a.solver.json", "--one", "1", "--one", "2"}); status *= argsAreBad( - CommandLine{"app", "a.solver.json", "--item", "1", "--item", "2", "3"}); + CommandLine{"app", "a.solver.json", "--one", "1", "--one", "2"} + ); status *= argsAreBad( - CommandLine{"app", "a.solver.json", "--item", "1", "2", "--item", "3"}); + CommandLine{"app", "a.solver.json", "--item", "1", "--item", "2", "3"} + ); + status *= argsAreBad( + CommandLine{"app", "a.solver.json", "--item", "1", "2", "--item", "3"} + ); status *= argsAreBad(CommandLine{"app", "a.solver.json", "--item", "--flag"}); status *= argsAreBad(CommandLine{"app", "a.solver.json", "--flag", "--flag"}); status *= throws( - [] - { - CliArgs args{{.name = {"pair"}, .nargs = 2, .positional = true}}; - - CommandLine cl{"app", "one"}; - args.parseArgs(cl.argc, cl.argv); - }); + [] + { + CliArgs args{{.name = {"pair"}, .nargs = 2, .positional = true}}; + + CommandLine cl{"app", "one"}; + args.parseArgs(cl.argc, cl.argv); + } + ); status *= throws( - [] - { - CliArgs args{ - {.name = {"file"}, .positional = true, .repeatable = true}}; - }); + [] + { + CliArgs args{ + {.name = {"file"}, .positional = true, .repeatable = true} + }; + } + ); return status.report(__func__); } @@ -272,15 +288,16 @@ namespace GridKit auto argsAreBad = [&](auto&& cl) { CliArgs args{ - {.name = {"--opt1"}, .required = true}, + {.name = {"--opt1"}, .required = true}, - {.name = {"--opt2", "-o"}, .nargs = 2}, + {.name = {"--opt2", "-o"}, .nargs = 2}, - {.name = {"--flag1", "-f"}, .flag = true}}; + {.name = {"--flag1", "-f"}, .flag = true} + }; return throws( - [&]() - { args.parseArgs(cl.argc, cl.argv); }); + [&]() { args.parseArgs(cl.argc, cl.argv); } + ); }; const auto previous_verbosity = Log::verbosity(); @@ -297,10 +314,11 @@ namespace GridKit // incorrect number of values for an option Log::misc() << "Expect error because 1 < 2\n"; status *= - argsAreBad(CommandLine{"app", "--opt1", "val", "--opt2", "6"}); + argsAreBad(CommandLine{"app", "--opt1", "val", "--opt2", "6"}); Log::misc() << "Expect error because 3 > 2\n"; status *= argsAreBad( - CommandLine{"app", "--opt1", "val", "--opt2", "6", "7", "8"}); + CommandLine{"app", "--opt1", "val", "--opt2", "6", "7", "8"} + ); // passing a value to a flag option Log::misc() << "Expect error because flag options don't take args\n"; @@ -308,8 +326,8 @@ namespace GridKit Log::misc() << "Expect error because option name can't be a number\n"; status *= throws( - [] - { CliArgs args{{.name = {"--one", "-1"}}}; }); + [] { CliArgs args{{.name = {"--one", "-1"}}}; } + ); Log::setVerbosity(previous_verbosity); return status.report(__func__); From 2810da6d8c2986c9f712d629bbc94617cdb67714 Mon Sep 17 00:00:00 2001 From: superwhiskers Date: Tue, 3 Nov 2026 20:55:07 +0000 Subject: [PATCH 2/2] Apply pre-commit fixes --- .../DependencyTracking/Variable.hpp | 12 +- .../DependencyTracking/VariableOperators.hpp | 38 +- .../Enzyme/D2LDx2.hpp | 8 +- .../AutomaticDifferentiation/Enzyme/DfDwb.hpp | 17 +- .../AutomaticDifferentiation/Enzyme/DfDws.hpp | 12 +- .../AutomaticDifferentiation/Enzyme/DfDy.hpp | 26 +- .../AutomaticDifferentiation/Enzyme/DfDyp.hpp | 26 +- .../AutomaticDifferentiation/Enzyme/DgDx.hpp | 3 +- .../AutomaticDifferentiation/Enzyme/DhDwb.hpp | 12 +- .../AutomaticDifferentiation/Enzyme/DhDy.hpp | 12 +- .../Enzyme/LowerSparseStorage.hpp | 90 +- .../Enzyme/ModelWrappers.hpp | 95 +- GridKit/CoSim/CoSim.cpp | 6 +- GridKit/CoSim/Message.hpp | 6 +- GridKit/CommonMath.hpp | 33 +- GridKit/LinearAlgebra/Solver/LinearSolver.hpp | 42 +- .../Solver/ResolveSystemSolver.cpp | 57 +- .../Solver/ResolveSystemSolver.hpp | 16 +- .../LinearAlgebra/SparseMatrix/CooMatrix.cpp | 70 +- .../LinearAlgebra/SparseMatrix/CsrMatrix.cpp | 111 +- GridKit/LinearAlgebra/Vector/Vector.cpp | 163 ++- GridKit/LinearAlgebra/Vector/Vector.hpp | 43 +- .../LinearAlgebra/Vector/VectorHandler.cpp | 155 +- .../LinearAlgebra/Vector/VectorHandler.hpp | 58 +- .../LinearAlgebra/Vector/VectorHandlerCpu.cpp | 73 +- .../LinearAlgebra/Vector/VectorHandlerCpu.hpp | 38 +- GridKit/MemoryUtilities/MemoryUtils.hpp | 3 +- GridKit/MemoryUtilities/cpu/CpuMemory.hpp | 33 +- GridKit/Model/Evaluator.hpp | 40 +- GridKit/Model/EvaluatorTraits.hpp | 4 +- .../Model/OptimalPowerFlow/Branch/Branch.hpp | 17 +- .../OptimalPowerFlow/Branch/BranchData.hpp | 25 +- .../Branch/BranchDependencyTracking.cpp | 9 +- .../OptimalPowerFlow/Branch/BranchImpl.hpp | 16 +- GridKit/Model/OptimalPowerFlow/Bus/Bus.hpp | 16 +- .../Bus/BusDependencyTracking.cpp | 9 +- .../Model/OptimalPowerFlow/Bus/BusImpl.hpp | 11 +- GridKit/Model/OptimalPowerFlow/Component.hpp | 18 +- .../Model/OptimalPowerFlow/ComponentData.hpp | 17 +- .../OptimalPowerFlow/ComponentEnzyme.hpp | 14 +- .../Model/OptimalPowerFlow/ComponentImpl.hpp | 62 +- .../OptimalPowerFlow/Generator/Generator.hpp | 14 +- .../Generator/GeneratorData.hpp | 3 +- .../Generator/GeneratorDependencyTracking.cpp | 9 +- .../Generator/GeneratorImpl.hpp | 11 +- GridKit/Model/OptimalPowerFlow/Load/Load.hpp | 4 +- .../Model/OptimalPowerFlow/Load/LoadData.hpp | 3 +- .../Load/LoadDependencyTracking.cpp | 9 +- .../Model/OptimalPowerFlow/Load/LoadImpl.hpp | 9 +- .../Model/OptimalPowerFlow/SystemModel.hpp | 21 +- .../OptimalPowerFlow/SystemModelData.cpp | 4 +- .../OptimalPowerFlow/SystemModelData.hpp | 4 +- .../SystemModelDataJSONParser.hpp | 36 +- .../SystemModelDependencyTracking.cpp | 24 +- .../OptimalPowerFlow/SystemModelEnzyme.cpp | 35 +- .../OptimalPowerFlow/SystemModelImpl.hpp | 116 +- GridKit/Model/OptimizationEvaluator.hpp | 3 +- GridKit/Model/ParameterReader.hpp | 15 +- .../Model/PhasorDynamics/Branch/Branch.hpp | 23 +- .../PhasorDynamics/Branch/BranchData.hpp | 48 +- .../PhasorDynamics/Branch/BranchEnzyme.cpp | 4 +- .../PhasorDynamics/Branch/BranchImpl.hpp | 196 ++- GridKit/Model/PhasorDynamics/Bus/Bus.hpp | 7 +- GridKit/Model/PhasorDynamics/Bus/BusData.hpp | 6 +- .../PhasorDynamics/Bus/BusDataJSONParser.hpp | 31 +- .../Model/PhasorDynamics/Bus/BusEnzyme.cpp | 7 +- .../Model/PhasorDynamics/Bus/BusFactory.hpp | 11 +- GridKit/Model/PhasorDynamics/Bus/BusImpl.hpp | 30 +- .../PhasorDynamics/Bus/BusInfiniteImpl.hpp | 27 +- .../BusSignalVoltageIn/BusSignalVoltageIn.hpp | 11 +- .../BusSignalVoltageInImpl.hpp | 47 +- .../BusSignalVoltageOut.cpp | 3 +- .../BusSignalVoltageOut.hpp | 4 +- .../BusSignalVoltageOutImpl.hpp | 63 +- GridKit/Model/PhasorDynamics/BusBase.hpp | 39 +- GridKit/Model/PhasorDynamics/Component.hpp | 93 +- .../Model/PhasorDynamics/ComponentData.hpp | 6 +- .../ComponentDataJSONParser.hpp | 28 +- .../PhasorDynamics/Controller/REECB/Reecb.cpp | 3 +- .../PhasorDynamics/Controller/REECB/Reecb.hpp | 103 +- .../Controller/REECB/ReecbData.hpp | 120 +- .../REECB/ReecbDependencyTracking.cpp | 3 +- .../Controller/REECB/ReecbEnzyme.cpp | 8 +- .../Controller/REECB/ReecbImpl.hpp | 466 ++++-- .../PhasorDynamics/Controller/REPCA/Repca.cpp | 3 +- .../PhasorDynamics/Controller/REPCA/Repca.hpp | 107 +- .../Controller/REPCA/RepcaData.hpp | 127 +- .../Controller/REPCA/RepcaEnzyme.cpp | 8 +- .../Controller/REPCA/RepcaImpl.hpp | 364 +++-- .../PhasorDynamics/Converter/REGCA/Regca.cpp | 3 +- .../PhasorDynamics/Converter/REGCA/Regca.hpp | 27 +- .../Converter/REGCA/RegcaData.hpp | 8 +- .../Converter/REGCA/RegcaEnzyme.cpp | 9 +- .../Converter/REGCA/RegcaImpl.hpp | 197 +-- .../PhasorDynamics/Exciter/ESDC1A/Esdc1a.cpp | 3 +- .../PhasorDynamics/Exciter/ESDC1A/Esdc1a.hpp | 20 +- .../Exciter/ESDC1A/Esdc1aData.hpp | 18 +- .../Exciter/ESDC1A/Esdc1aEnzyme.cpp | 14 +- .../Exciter/ESDC1A/Esdc1aImpl.hpp | 222 ++- .../PhasorDynamics/Exciter/IEEET1/Ieeet1.hpp | 20 +- .../Exciter/IEEET1/Ieeet1Enzyme.cpp | 14 +- .../Exciter/IEEET1/Ieeet1Impl.hpp | 142 +- .../Exciter/SEXS-PTI/SexsPti.hpp | 12 +- .../Exciter/SEXS-PTI/SexsPtiEnzyme.cpp | 14 +- .../Exciter/SEXS-PTI/SexsPtiImpl.hpp | 83 +- .../Governor/GASTPTI/GastPti.cpp | 3 +- .../Governor/GASTPTI/GastPti.hpp | 29 +- .../Governor/GASTPTI/GastPtiData.hpp | 47 +- .../Governor/GASTPTI/GastPtiEnzyme.cpp | 5 +- .../Governor/GASTPTI/GastPtiImpl.hpp | 215 ++- .../PhasorDynamics/Governor/HYGOV/Hygov.hpp | 18 +- .../Governor/HYGOV/HygovData.hpp | 36 +- .../Governor/HYGOV/HygovEnzyme.cpp | 5 +- .../Governor/HYGOV/HygovImpl.hpp | 337 +++-- .../PhasorDynamics/Governor/Tgov1/Tgov1.hpp | 14 +- .../Governor/Tgov1/Tgov1Data.hpp | 3 +- .../Governor/Tgov1/Tgov1Enzyme.cpp | 5 +- .../Governor/Tgov1/Tgov1Impl.hpp | 66 +- .../Model/PhasorDynamics/Load/LoadZ/LoadZ.hpp | 10 +- .../PhasorDynamics/Load/LoadZ/LoadZData.hpp | 4 +- .../PhasorDynamics/Load/LoadZ/LoadZEnzyme.cpp | 4 +- .../PhasorDynamics/Load/LoadZ/LoadZImpl.hpp | 15 +- .../PhasorDynamics/Load/LoadZIP/LoadZIP.hpp | 10 +- .../Load/LoadZIP/LoadZIPData.hpp | 4 +- .../Load/LoadZIP/LoadZIPEnzyme.cpp | 4 +- .../Load/LoadZIP/LoadZIPImpl.hpp | 43 +- .../SignalNode/SignalNodeDataJSONParser.hpp | 3 +- .../SignalSource/ConstantSignalSourceImpl.hpp | 19 +- .../SignalSource/FunctionSignalSource.hpp | 3 +- .../SignalSource/FunctionSignalSourceImpl.hpp | 34 +- .../Stabilizer/IEEEST/Ieeest.hpp | 15 +- .../Stabilizer/IEEEST/IeeestData.hpp | 37 +- .../IEEEST/IeeestDependencyTracking.cpp | 3 +- .../Stabilizer/IEEEST/IeeestEnzyme.cpp | 5 +- .../Stabilizer/IEEEST/IeeestImpl.hpp | 75 +- .../SynchronousMachine/GENROU/Genrou.hpp | 16 +- .../SynchronousMachine/GENROU/GenrouData.hpp | 4 +- .../GENROU/GenrouEnzyme.cpp | 13 +- .../SynchronousMachine/GENROU/GenrouImpl.hpp | 100 +- .../SynchronousMachine/GENSAL/Gensal.hpp | 16 +- .../SynchronousMachine/GENSAL/GensalData.hpp | 9 +- .../GENSAL/GensalEnzyme.cpp | 13 +- .../SynchronousMachine/GENSAL/GensalImpl.hpp | 121 +- .../GenClassical/GenClassical.hpp | 12 +- .../GenClassical/GenClassicalData.hpp | 9 +- .../GenClassical/GenClassicalEnzyme.cpp | 13 +- .../GenClassical/GenClassicalImpl.hpp | 111 +- GridKit/Model/PhasorDynamics/SystemModel.hpp | 27 +- .../Model/PhasorDynamics/SystemModelData.cpp | 4 +- .../Model/PhasorDynamics/SystemModelData.hpp | 56 +- .../SystemModelDataJSONParser.hpp | 20 +- .../SystemModelDependencyTracking.cpp | 6 +- .../PhasorDynamics/SystemModelEnzyme.cpp | 46 +- .../Model/PhasorDynamics/SystemModelImpl.hpp | 174 ++- GridKit/Model/PowerElectronics/Bus/Bus.hpp | 3 +- .../PowerElectronics/Bus/GroundedBus.hpp | 7 +- .../PowerElectronics/Bus/MicrogridBus.hpp | 3 +- .../Model/PowerElectronics/Bus/SignalNode.hpp | 3 +- .../PowerElectronics/Capacitor/Capacitor.cpp | 7 +- GridKit/Model/PowerElectronics/Component.hpp | 258 ++-- .../DistributedGenerator.cpp | 116 +- .../PowerElectronics/ExternalConnection.hpp | 13 +- .../InductionMotor/InductionMotor.cpp | 50 +- .../InductionMotor/InductionMotor.hpp | 11 +- .../PowerElectronics/Inductor/Inductor.cpp | 4 +- .../LinearTransformer/LinearTransformer.cpp | 16 +- .../LinearTransformer/LinearTransformer.hpp | 4 +- .../MicrogridBusDQ/MicrogridBusDQ.cpp | 18 +- .../MicrogridLine/MicrogridLine.cpp | 41 +- .../MicrogridLine/MicrogridLine.hpp | 4 +- .../MicrogridLoad/MicrogridLoad.cpp | 33 +- .../MicrogridLoad/MicrogridLoad.hpp | 4 +- GridKit/Model/PowerElectronics/Node.hpp | 10 +- GridKit/Model/PowerElectronics/NodeBase.hpp | 35 +- .../PowerElectronics/Resistor/Resistor.cpp | 7 +- .../SynchronousMachine/SynchronousMachine.cpp | 47 +- .../SynchronousMachine/SynchronousMachine.hpp | 17 +- .../Model/PowerElectronics/SystemModel.hpp | 86 +- .../TransmissionLine/TransmissionLine.cpp | 74 +- .../TransmissionLine/TransmissionLine.hpp | 3 +- .../VoltageSource/VoltageSource.cpp | 4 +- GridKit/Model/PowerFlow/Branch/Branch.cpp | 23 +- GridKit/Model/PowerFlow/Bus/BaseBus.hpp | 3 +- GridKit/Model/PowerFlow/Bus/BusFactory.hpp | 3 +- GridKit/Model/PowerFlow/Bus/BusPQ.cpp | 3 +- GridKit/Model/PowerFlow/Bus/BusPV.cpp | 3 +- GridKit/Model/PowerFlow/Bus/BusSlack.cpp | 16 +- .../PowerFlow/Generator/GeneratorFactory.hpp | 7 +- .../Model/PowerFlow/Generator/GeneratorPQ.cpp | 4 +- .../PowerFlow/Generator/GeneratorSlack.cpp | 3 +- .../Model/PowerFlow/Generator2/Generator2.cpp | 28 +- .../Model/PowerFlow/Generator4/Generator4.cpp | 85 +- .../Generator4Governor/Generator4Governor.cpp | 210 ++- .../Generator4Param/Generator4Param.cpp | 175 ++- .../Generator4Param/Generator4Param.hpp | 4 +- GridKit/Model/PowerFlow/Load/Load.cpp | 10 +- GridKit/Model/PowerFlow/MatpowerParser.hpp | 18 +- GridKit/Model/PowerFlow/MiniGrid/MiniGrid.cpp | 15 +- .../Model/PowerFlow/ModelEvaluatorImpl.hpp | 5 +- GridKit/Model/PowerFlow/PowerFlowData.hpp | 73 +- GridKit/Model/PowerFlow/SystemModel.hpp | 9 +- .../Model/PowerFlow/SystemModelPowerFlow.hpp | 23 +- GridKit/Model/VariableMonitor.hpp | 6 +- GridKit/Model/VariableMonitorController.hpp | 70 +- GridKit/Model/VariableMonitorImpl.hpp | 7 +- GridKit/Solver/Dynamic/Ida.cpp | 16 +- GridKit/Solver/Dynamic/Ida.hpp | 27 +- .../Solver/Dynamic/Native/AdaptiveStep.cpp | 19 +- .../Solver/Dynamic/Native/AdaptiveStep.hpp | 31 +- GridKit/Solver/Dynamic/Native/ErrorNorm.hpp | 32 +- GridKit/Solver/Dynamic/Native/FixedStep.cpp | 9 +- GridKit/Solver/Dynamic/Native/FixedStep.hpp | 14 +- GridKit/Solver/Dynamic/Native/InfNorm.cpp | 77 +- GridKit/Solver/Dynamic/Native/InfNorm.hpp | 30 +- GridKit/Solver/Dynamic/Native/StepControl.hpp | 8 +- .../Solver/Dynamic/Native/StepController.hpp | 26 +- GridKit/Solver/Dynamic/Rosenbrock.cpp | 676 +++++---- GridKit/Solver/Dynamic/Rosenbrock.hpp | 239 ++-- GridKit/Solver/Dynamic/RosenbrockTableaus.cpp | 9 +- .../Solver/Optimization/DynamicConstraint.cpp | 27 +- .../Solver/Optimization/DynamicConstraint.hpp | 64 +- .../Solver/Optimization/DynamicObjective.cpp | 11 +- .../Solver/Optimization/DynamicObjective.hpp | 64 +- .../Solver/Optimization/IpoptInterface.cpp | 14 +- .../Solver/Optimization/IpoptInterface.hpp | 31 +- GridKit/Solver/SteadyState/Kinsol.cpp | 20 +- GridKit/Solver/SteadyState/Kinsol.hpp | 4 +- GridKit/Testing/AggregateErrors.hpp | 11 +- GridKit/Testing/CSV.cpp | 4 +- GridKit/Testing/CommandLine.hpp | 3 +- GridKit/Testing/OutputAtTime.hpp | 10 +- GridKit/Testing/Testing.cpp | 32 +- GridKit/Testing/Testing.hpp | 33 +- GridKit/Utilities/CliArgs/ArgValue.hpp | 3 +- GridKit/Utilities/CliArgs/ArgVector.hpp | 6 +- GridKit/Utilities/CliArgs/CliArgsImpl.hpp | 31 +- GridKit/Utilities/MapFromCsr.hpp | 8 +- GridKit/Utilities/String.hpp | 26 +- .../PhasorDynamics/AnalysisUtilities.hpp | 19 +- application/PhasorDynamics/CoupledClient.hpp | 10 +- .../AdjointSensitivity/AdjointSensitivity.cpp | 3 +- .../DynamicConstrainedOpt.cpp | 7 +- .../GenConstLoad/GenConstLoad.cpp | 19 +- .../GenInfiniteBus/GenInfiniteBus.cpp | 7 +- .../ParameterEstimation.cpp | 7 +- .../EconomicDispatch/EconomicDispatch.cpp | 17 +- .../DistributedGeneratorTest/DGTest.cpp | 7 +- .../ExamplesHelper/MicrogridNetwork.hpp | 25 +- .../PowerElectronics/Microgrid/Microgrid.cpp | 30 +- .../PowerElectronics/RLCircuit/RLCircuit.cpp | 12 +- .../ScaleMicrogrid/ScaleMicrogrid.cpp | 26 +- .../ScaleMicrogridArbitrary.cpp | 9 +- .../ScaleMicrogrid/SolutionKeys.hpp | 5 +- examples/PowerFlow/Grid3Bus/Grid3BusSys.cpp | 92 +- .../MatPowerTesting/MatPowerTesting.hpp | 17 +- .../PhasorDynamics/PDIntegrationTests.hpp | 340 +++-- .../SystemJacobian/runSystemJacobianTests.cpp | 10 +- .../TenGen/Classical/TenGenClassical.cpp | 55 +- .../TenGen/Genrou/TenGenGenrou.cpp | 48 +- .../Enzyme/EnzymeTests.hpp | 21 +- .../SparseMatrix/SparseCooTests.hpp | 7 +- .../SparseMatrix/SparseCsrTests.hpp | 38 +- .../SparseMatrix/runSparseCooTests.cpp | 6 +- .../SparseMatrix/runSparseCsrTests.cpp | 6 +- .../Vector/VectorHandlerTests.hpp | 60 +- .../LinearAlgebra/Vector/VectorTests.hpp | 57 +- .../Math/SmoothnessIndicatorTests.hpp | 186 ++- .../OptimalPowerFlow/ComponentTests.hpp | 377 +++-- .../OptimalPowerFlow/CoupledComponent.hpp | 24 +- .../UnitTests/OptimalPowerFlow/IpoptTests.hpp | 53 +- .../OptimalPowerFlow/SystemTestData.hpp | 27 +- .../OptimalPowerFlow/SystemTests.hpp | 263 ++-- .../OptimalPowerFlow/TestHelpers.hpp | 37 +- .../UnitTests/PhasorDynamics/BranchTests.hpp | 151 +- .../BusSignalVoltageInTests.hpp | 9 +- tests/UnitTests/PhasorDynamics/BusTests.hpp | 22 +- .../ComponentConnectionTests.hpp | 403 ++++-- .../PhasorDynamics/ControllerReecbTests.hpp | 465 ++++-- .../PhasorDynamics/ControllerRepcaTests.hpp | 304 ++-- .../PhasorDynamics/ConverterRegcaTests.hpp | 186 ++- .../PhasorDynamics/ExciterEsdc1aTests.hpp | 295 ++-- .../PhasorDynamics/ExciterIeeet1Tests.hpp | 91 +- .../PhasorDynamics/ExciterSexsPtiTests.hpp | 125 +- .../PhasorDynamics/GenClassicalTests.hpp | 61 +- .../UnitTests/PhasorDynamics/GenrouTests.hpp | 51 +- .../UnitTests/PhasorDynamics/GensalTests.hpp | 38 +- .../PhasorDynamics/GovernorGastPtiTests.hpp | 351 +++-- .../PhasorDynamics/GovernorHygovTests.hpp | 276 ++-- .../PhasorDynamics/GovernorTgov1Tests.hpp | 128 +- .../UnitTests/PhasorDynamics/LoadZIPTests.hpp | 73 +- tests/UnitTests/PhasorDynamics/LoadZTests.hpp | 40 +- .../ModelConfigurationTests.hpp | 54 +- .../PhasorDynamics/StabilizerIeeestTests.hpp | 91 +- .../PhasorDynamics/SubsystemModelTests.hpp | 60 +- .../SystemSingleComponentTests.hpp | 134 +- .../UnitTests/PhasorDynamics/SystemTests.hpp | 118 +- .../runSystemSingleComponentTests.cpp | 4 +- .../PowerElectronics/ComponentCloneTests.hpp | 29 +- tests/UnitTests/Solver/Dynamic/IdaTests.hpp | 46 +- .../Solver/Dynamic/RosenbrockTests.hpp | 127 +- .../Solver/Dynamic/runRosenbrockTests.cpp | 7 +- tests/UnitTests/Solver/KinsolTests.hpp | 3 +- tests/UnitTests/Utilities/CaseFormatTests.hpp | 1264 +++++++++++++---- tests/UnitTests/Utilities/CliArgsTests.hpp | 15 +- tests/UnitTests/Utilities/LoggerTests.hpp | 10 +- 305 files changed, 11050 insertions(+), 5683 deletions(-) diff --git a/GridKit/AutomaticDifferentiation/DependencyTracking/Variable.hpp b/GridKit/AutomaticDifferentiation/DependencyTracking/Variable.hpp index 5d90ce0a20..94ba4580d2 100644 --- a/GridKit/AutomaticDifferentiation/DependencyTracking/Variable.hpp +++ b/GridKit/AutomaticDifferentiation/DependencyTracking/Variable.hpp @@ -36,9 +36,7 @@ namespace GridKit @brief Default constructor. */ Variable() - : value_(0.0), - variable_number_(INVALID_VAR_NUMBER), - is_fixed_(false) + : value_(0.0), variable_number_(INVALID_VAR_NUMBER), is_fixed_(false) { } @@ -46,9 +44,7 @@ namespace GridKit @brief Constructor which initializes the value. */ explicit Variable(double value) - : value_(value), - variable_number_(INVALID_VAR_NUMBER), - is_fixed_(false) + : value_(value), variable_number_(INVALID_VAR_NUMBER), is_fixed_(false) { } @@ -58,9 +54,7 @@ namespace GridKit */ Variable(double value, size_t variable_number) - : value_(value), - variable_number_(variable_number), - is_fixed_(false) + : value_(value), variable_number_(variable_number), is_fixed_(false) { dependencies_[variable_number_] = 1.0; } diff --git a/GridKit/AutomaticDifferentiation/DependencyTracking/VariableOperators.hpp b/GridKit/AutomaticDifferentiation/DependencyTracking/VariableOperators.hpp index 6f4c70f62f..8e468477d1 100644 --- a/GridKit/AutomaticDifferentiation/DependencyTracking/VariableOperators.hpp +++ b/GridKit/AutomaticDifferentiation/DependencyTracking/VariableOperators.hpp @@ -367,15 +367,17 @@ namespace GridKit namespace std { -#define IMPL_FUN_1(FUN, DER) \ - inline GridKit::DependencyTracking::Variable FUN(const GridKit::DependencyTracking::Variable& x) \ - { \ - double val = FUN(x()); \ - double der = DER(x()); \ - GridKit::DependencyTracking::Variable res(x); /* copy derivatives of x*/ \ - res.setValue(val); /* set function value f(x) */ \ - res.scaleDependencies(der); /* compute derivatives of f(x) */ \ - return res; \ +#define IMPL_FUN_1(FUN, DER) \ + inline GridKit::DependencyTracking::Variable FUN( \ + const GridKit::DependencyTracking::Variable& x \ + ) \ + { \ + double val = FUN(x()); \ + double der = DER(x()); \ + GridKit::DependencyTracking::Variable res(x); /* copy derivatives of x*/ \ + res.setValue(val); /* set function value f(x) */ \ + res.scaleDependencies(der); /* compute derivatives of f(x) */ \ + return res; \ } #define IMPL_FUN_2(FUN, DER1, DER2) \ @@ -391,17 +393,13 @@ namespace std GridKit::DependencyTracking::Variable res2(y); /* copy derivatives of y*/ \ res1.setValue(val); /* set function value f(x, y) */ \ res2.setValue(val); /* set function value f(x, y) */ \ - res1.scaleDependencies( \ - der1 \ + res1.scaleDependencies(der1 \ ); /* compute derivatives of f(x, y) with respect to x */ \ - res2.scaleDependencies( \ - der2 \ + res2.scaleDependencies(der2 \ ); /* compute derivatives of f(x, y) with respect to y */ \ - GridKit::DependencyTracking::Variable res( \ - std::move(res1) \ + GridKit::DependencyTracking::Variable res(std::move(res1) \ ); /* relocate derivatives w.r.t. x into return */ \ - res.addDependencies( \ - res2 \ + res.addDependencies(res2 \ ); /* add derivatives with respect to y to return */ \ return res; \ } @@ -422,7 +420,11 @@ namespace std IMPL_FUN_1(sqrt, GridKit::DependencyTracking::sqrt_derivative) IMPL_FUN_1(abs, GridKit::DependencyTracking::abs_derivative) - IMPL_FUN_2(atan2, GridKit::DependencyTracking::atan2_derivative1, GridKit::DependencyTracking::atan2_derivative2) + IMPL_FUN_2( + atan2, + GridKit::DependencyTracking::atan2_derivative1, + GridKit::DependencyTracking::atan2_derivative2 + ) #undef IMPL_FUN_1 #undef IMPL_FUN_2 diff --git a/GridKit/AutomaticDifferentiation/Enzyme/D2LDx2.hpp b/GridKit/AutomaticDifferentiation/Enzyme/D2LDx2.hpp index ccc656fb54..6eb7b157cc 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/D2LDx2.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/D2LDx2.hpp @@ -19,8 +19,9 @@ namespace GridKit namespace Sparse { /** - * @brief Enzyme sparse Hessian of \f$L = \sigma f + \lambda^T g\f$, by one - * forward sweep per local variable over the reverse gradient of \f$L\f$ + * @brief Enzyme sparse Hessian of \f$L = \sigma f + \lambda^T g\f$, by + * one forward sweep per local variable over the reverse gradient of + * \f$L\f$ * * @tparam ModelT - optimization component model */ @@ -116,7 +117,8 @@ namespace GridKit return value; } - /// Add the Lagrangian gradient to `gradient`, whose tangent alone is used + /// Add the Lagrangian gradient to `gradient`, whose tangent alone is + /// used template [[gnu::always_inline]] inline static void lagrangianGradient( const ModelT* model, diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DfDwb.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DfDwb.hpp index 3ed36480b4..27c5d5d173 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DfDwb.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DfDwb.hpp @@ -26,9 +26,10 @@ namespace GridKit template struct DfDwb { - using ScalarT = typename GridKit::Model::EvaluatorTraits::ScalarT; - using IdxT = typename GridKit::Model::EvaluatorTraits::IdxT; - using RealT = typename GridKit::Model::EvaluatorTraits::RealT; + using ScalarT = + typename GridKit::Model::EvaluatorTraits::ScalarT; + using IdxT = typename GridKit::Model::EvaluatorTraits::IdxT; + using RealT = typename GridKit::Model::EvaluatorTraits::RealT; /** * @param[in] model - Pointer to the model to be differentiated @@ -82,8 +83,9 @@ namespace GridKit &nnz ); - // Core automatic differentiation intrinsic that will be replaced by a derivative - // The dummy primal pointer is safe only while residuals never read back their output + // Core automatic differentiation intrinsic that will be replaced + // by a derivative The dummy primal pointer is safe only while + // residuals never read back their output __enzyme_fwddiff( (void*) ModelWrapper::eval, enzyme_const, @@ -157,8 +159,9 @@ namespace GridKit &nnz ); - // Core automatic differentiation intrinsic that will be replaced by a derivative - // The dummy primal pointer is safe only while residuals never read back their output + // Core automatic differentiation intrinsic that will be replaced + // by a derivative The dummy primal pointer is safe only while + // residuals never read back their output __enzyme_fwddiff( (void*) ModelWrapper::eval, enzyme_const, diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DfDws.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DfDws.hpp index fac2752a13..7ec8ea49b7 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DfDws.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DfDws.hpp @@ -26,9 +26,10 @@ namespace GridKit template struct DfDws { - using ScalarT = typename GridKit::Model::EvaluatorTraits::ScalarT; - using IdxT = typename GridKit::Model::EvaluatorTraits::IdxT; - using RealT = typename GridKit::Model::EvaluatorTraits::RealT; + using ScalarT = + typename GridKit::Model::EvaluatorTraits::ScalarT; + using IdxT = typename GridKit::Model::EvaluatorTraits::IdxT; + using RealT = typename GridKit::Model::EvaluatorTraits::RealT; /** * @param[in] model - Pointer to the model to be differentiated @@ -84,8 +85,9 @@ namespace GridKit &nnz ); - // Core automatic differentiation intrinsic that will be replaced by a derivative - // The dummy primal pointer is safe only while residuals never read back their output + // Core automatic differentiation intrinsic that will be replaced + // by a derivative The dummy primal pointer is safe only while + // residuals never read back their output __enzyme_fwddiff( (void*) ModelWrapper::eval, enzyme_const, diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DfDy.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DfDy.hpp index 433f8a6af1..2bd6ca41df 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DfDy.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DfDy.hpp @@ -18,7 +18,8 @@ namespace GridKit namespace Sparse { /** - * @brief Enzyme automatic differentiation Jacobian evaluator: Internal Jacobian, df/dy + * @brief Enzyme automatic differentiation Jacobian evaluator: Internal + * Jacobian, df/dy * * @tparam ModelT - model type * @tparam MemberFunctions - member function parameter key @@ -26,9 +27,10 @@ namespace GridKit template struct DfDy { - using ScalarT = typename GridKit::Model::EvaluatorTraits::ScalarT; - using IdxT = typename GridKit::Model::EvaluatorTraits::IdxT; - using RealT = typename GridKit::Model::EvaluatorTraits::RealT; + using ScalarT = + typename GridKit::Model::EvaluatorTraits::ScalarT; + using IdxT = typename GridKit::Model::EvaluatorTraits::IdxT; + using RealT = typename GridKit::Model::EvaluatorTraits::RealT; /** * @param[in] model - Pointer to the model to be differentiated @@ -82,8 +84,9 @@ namespace GridKit &nnz ); - // Core automatic differentiation intrinsic that will be replaced by a derivative - // The dummy primal pointer is safe only while residuals never read back their output + // Core automatic differentiation intrinsic that will be replaced + // by a derivative The dummy primal pointer is safe only while + // residuals never read back their output __enzyme_fwddiff( (void*) ModelWrapper::eval, enzyme_const, @@ -107,8 +110,10 @@ namespace GridKit * @param[in] model - Pointer to the model to be differentiated * @param[in] n_res - Number of residual functions * @param[in] n_var - Number of independent variables - * @param[in] res_indices - Map from local residual indices to global indices - * @param[in] var_indices - Map from local variable indices to global indices + * @param[in] res_indices - Map from local residual indices to global + * indices + * @param[in] var_indices - Map from local variable indices to global + * indices * @param[in] y - Internal variables * @param[in] yp - Internal variable derivatives * @param[in] wb - Bus variables @@ -157,8 +162,9 @@ namespace GridKit &nnz ); - // Core automatic differentiation intrinsic that will be replaced by a derivative - // The dummy primal pointer is safe only while residuals never read back their output + // Core automatic differentiation intrinsic that will be replaced + // by a derivative The dummy primal pointer is safe only while + // residuals never read back their output __enzyme_fwddiff( (void*) ModelWrapper::eval, enzyme_const, diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DfDyp.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DfDyp.hpp index 56bd56c1e5..e831a365c8 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DfDyp.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DfDyp.hpp @@ -18,7 +18,8 @@ namespace GridKit namespace Sparse { /** - * @brief Enzyme automatic differentiation Jacobian evaluator: Internal Jacobian, alpha*df/dyp + * @brief Enzyme automatic differentiation Jacobian evaluator: Internal + * Jacobian, alpha*df/dyp * * @tparam ModelT - model type * @tparam MemberFunctions - member function parameter key @@ -26,9 +27,10 @@ namespace GridKit template struct DfDyp { - using ScalarT = typename GridKit::Model::EvaluatorTraits::ScalarT; - using IdxT = typename GridKit::Model::EvaluatorTraits::IdxT; - using RealT = typename GridKit::Model::EvaluatorTraits::RealT; + using ScalarT = + typename GridKit::Model::EvaluatorTraits::ScalarT; + using IdxT = typename GridKit::Model::EvaluatorTraits::IdxT; + using RealT = typename GridKit::Model::EvaluatorTraits::RealT; /** * @param[in] model - Pointer to the model to be differentiated @@ -84,8 +86,9 @@ namespace GridKit &nnz ); - // Core automatic differentiation intrinsic that will be replaced by a derivative - // The dummy primal pointer is safe only while residuals never read back their output + // Core automatic differentiation intrinsic that will be replaced + // by a derivative The dummy primal pointer is safe only while + // residuals never read back their output __enzyme_fwddiff( (void*) ModelWrapper::eval, enzyme_const, @@ -109,8 +112,10 @@ namespace GridKit * @param[in] model - Pointer to the model to be differentiated * @param[in] n_res - Number of residual functions * @param[in] n_var - Number of independent variables - * @param[in] res_indices - Map from local residual indices to global indices - * @param[in] var_indices - Map from local variable indices to global indices + * @param[in] res_indices - Map from local residual indices to global + * indices + * @param[in] var_indices - Map from local variable indices to global + * indices * @param[in] y - Internal variables * @param[in] yp - Internal variable derivatives * @param[in] wb - Bus variables @@ -161,8 +166,9 @@ namespace GridKit &nnz ); - // Core automatic differentiation intrinsic that will be replaced by a derivative - // The dummy primal pointer is safe only while residuals never read back their output + // Core automatic differentiation intrinsic that will be replaced + // by a derivative The dummy primal pointer is safe only while + // residuals never read back their output __enzyme_fwddiff( (void*) ModelWrapper::eval, enzyme_const, diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DgDx.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DgDx.hpp index a9675a87ae..379843dc25 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DgDx.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DgDx.hpp @@ -30,7 +30,8 @@ namespace GridKit /** * @param[in] model - Pointer to the model to be differentiated * @param[in] n_var - Number of local variables - * @param[in] row_indices - Global row of each local constraint contribution + * @param[in] row_indices - Global row of each local constraint + * contribution * @param[in] col_indices - Global column of each local variable * @param[in] x - Local variables * @param[out] rows - Row indices diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DhDwb.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DhDwb.hpp index 6a0ff59bf4..208a971c55 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DhDwb.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DhDwb.hpp @@ -26,9 +26,10 @@ namespace GridKit template struct DhDwb { - using ScalarT = typename GridKit::Model::EvaluatorTraits::ScalarT; - using IdxT = typename GridKit::Model::EvaluatorTraits::IdxT; - using RealT = typename GridKit::Model::EvaluatorTraits::RealT; + using ScalarT = + typename GridKit::Model::EvaluatorTraits::ScalarT; + using IdxT = typename GridKit::Model::EvaluatorTraits::IdxT; + using RealT = typename GridKit::Model::EvaluatorTraits::RealT; /** * @param[in] model - Pointer to the model to be differentiated @@ -82,8 +83,9 @@ namespace GridKit &nnz ); - // Core automatic differentiation intrinsic that will be replaced by a derivative - // The dummy primal pointer is safe only while residuals never read back their output + // Core automatic differentiation intrinsic that will be replaced + // by a derivative The dummy primal pointer is safe only while + // residuals never read back their output __enzyme_fwddiff( (void*) ModelWrapper::eval, enzyme_const, diff --git a/GridKit/AutomaticDifferentiation/Enzyme/DhDy.hpp b/GridKit/AutomaticDifferentiation/Enzyme/DhDy.hpp index 4dadb5f268..6fd8e962f5 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/DhDy.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/DhDy.hpp @@ -26,9 +26,10 @@ namespace GridKit template struct DhDy { - using ScalarT = typename GridKit::Model::EvaluatorTraits::ScalarT; - using IdxT = typename GridKit::Model::EvaluatorTraits::IdxT; - using RealT = typename GridKit::Model::EvaluatorTraits::RealT; + using ScalarT = + typename GridKit::Model::EvaluatorTraits::ScalarT; + using IdxT = typename GridKit::Model::EvaluatorTraits::IdxT; + using RealT = typename GridKit::Model::EvaluatorTraits::RealT; /** * @param[in] model - Pointer to the model to be differentiated @@ -82,8 +83,9 @@ namespace GridKit &nnz ); - // Core automatic differentiation intrinsic that will be replaced by a derivative - // The dummy primal pointer is safe only while residuals never read back their output + // Core automatic differentiation intrinsic that will be replaced + // by a derivative The dummy primal pointer is safe only while + // residuals never read back their output __enzyme_fwddiff( (void*) ModelWrapper::eval, enzyme_const, diff --git a/GridKit/AutomaticDifferentiation/Enzyme/LowerSparseStorage.hpp b/GridKit/AutomaticDifferentiation/Enzyme/LowerSparseStorage.hpp index 7f5ea89210..21b4d3ca9b 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/LowerSparseStorage.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/LowerSparseStorage.hpp @@ -1,7 +1,8 @@ /** * @file LowerSparseStorage.hpp * - * @details This file contains functions used by Enzyme to store sparse Jacobians. + * @details This file contains functions used by Enzyme to store sparse + * Jacobians. * * @author Nicholson Koukpaizan (koukpaizannk@ornl.gov) * @@ -22,8 +23,9 @@ namespace GridKit /** * @brief Enzyme todense template * - * @details This is used by Enzyme's auto sparsity analysis. It internally maps dense storage - * to sparse ones (where structural zeros are not kept). + * @details This is used by Enzyme's auto sparsity analysis. It internally + * maps dense storage to sparse ones (where structural zeros are not + * kept). * * @tparam T - return type */ @@ -33,7 +35,8 @@ namespace GridKit /** * @brief Enzyme sparse accumulation for float and size_t * - * @note __attribute__((enzyme_sparse_accumulate)) does not support templates yet + * @note __attribute__((enzyme_sparse_accumulate)) does not support + * templates yet * * @param[in] row - row to be stored * @param[in] col - column to be stored @@ -74,7 +77,8 @@ namespace GridKit /** * @brief Enzyme sparse accumulation for float and long int * - * @note __attribute__((enzyme_sparse_accumulate)) does not support templates yet + * @note __attribute__((enzyme_sparse_accumulate)) does not support + * templates yet * * @param[in] row - row to be stored * @param[in] col - column to be stored @@ -115,7 +119,8 @@ namespace GridKit /** * @brief Enzyme sparse accumulation for double and size_t * - * @note __attribute__((enzyme_sparse_accumulate)) does not support templates yet + * @note __attribute__((enzyme_sparse_accumulate)) does not support + * templates yet * * @param[in] row - row to be stored * @param[in] col - column to be stored @@ -156,7 +161,8 @@ namespace GridKit /** * @brief Enzyme sparse accumulation for double and long int * - * @note __attribute__((enzyme_sparse_accumulate)) does not support templates yet + * @note __attribute__((enzyme_sparse_accumulate)) does not support + * templates yet * * @param[in] row - row to be stored * @param[in] col - column to be stored @@ -197,7 +203,8 @@ namespace GridKit /** * @brief Enzyme sparse store * - * @details This takes in a row, column and value and stores them in buffers + * @details This takes in a row, column and value and stores them in + * buffers * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type @@ -232,20 +239,66 @@ namespace GridKit row /= sizeof(ScalarT); - // this template nightmare is because __attribute__((enzyme_sparse_accumulate)) does not support templates yet + // this template nightmare is because + // __attribute__((enzyme_sparse_accumulate)) does not support templates + // yet if constexpr (std::is_same::value) { if constexpr (std::is_same::value) - inner_store_float_size_t(row, col, val, scaling, row_indices, col_indices, rows, cols, vals, *nnz); + inner_store_float_size_t( + row, + col, + val, + scaling, + row_indices, + col_indices, + rows, + cols, + vals, + *nnz + ); else - inner_store_double_size_t(row, col, val, scaling, row_indices, col_indices, rows, cols, vals, *nnz); + inner_store_double_size_t( + row, + col, + val, + scaling, + row_indices, + col_indices, + rows, + cols, + vals, + *nnz + ); } else if constexpr (std::is_same::value) { if constexpr (std::is_same::value) - inner_store_float_long_int(row, col, val, scaling, row_indices, col_indices, rows, cols, vals, *nnz); + inner_store_float_long_int( + row, + col, + val, + scaling, + row_indices, + col_indices, + rows, + cols, + vals, + *nnz + ); else - inner_store_double_long_int(row, col, val, scaling, row_indices, col_indices, rows, cols, vals, *nnz); + inner_store_double_long_int( + row, + col, + val, + scaling, + row_indices, + col_indices, + rows, + cols, + vals, + *nnz + ); } else { @@ -262,7 +315,8 @@ namespace GridKit * @tparam IdxT - matrix index data type */ template - [[gnu::always_inline]] static ScalarT sparse_load(IdxT, IdxT, ScalarT, const IdxT*, const IdxT*, IdxT*, IdxT*, ScalarT*, IdxT*) + [[gnu::always_inline]] static ScalarT + sparse_load(IdxT, IdxT, ScalarT, const IdxT*, const IdxT*, IdxT*, IdxT*, ScalarT*, IdxT*) { return 0.0; } @@ -274,7 +328,9 @@ namespace GridKit * @tparam IdxT - matrix index data type */ template - __attribute__((always_inline)) static void ident_store(ScalarT, IdxT, IdxT) + __attribute__((always_inline)) static void ident_store( + ScalarT, IdxT, IdxT + ) { assert(0 && "should never store"); } @@ -286,7 +342,9 @@ namespace GridKit * @tparam IdxT - matrix index data type */ template - __attribute__((always_inline)) static ScalarT ident_load(IdxT row, IdxT col) + __attribute__((always_inline)) static ScalarT ident_load( + IdxT row, IdxT col + ) { row /= sizeof(ScalarT); return (ScalarT) (row == col); diff --git a/GridKit/AutomaticDifferentiation/Enzyme/ModelWrappers.hpp b/GridKit/AutomaticDifferentiation/Enzyme/ModelWrappers.hpp index 6c3a876924..79d22b174d 100644 --- a/GridKit/AutomaticDifferentiation/Enzyme/ModelWrappers.hpp +++ b/GridKit/AutomaticDifferentiation/Enzyme/ModelWrappers.hpp @@ -27,16 +27,22 @@ namespace GridKit InternalResidual, InternalResidualWithSignal, BusResidual, - BusResidual11, //< Special case for branches that are connected to two buses - BusResidual12, //< Special case for branches that are connected to two buses - BusResidual21, //< Special case for branches that are connected to two buses - BusResidual22, //< Special case for branches that are connected to two buses + BusResidual11, //< Special case for branches that are connected to two + //buses + BusResidual12, //< Special case for branches that are connected to two + //buses + BusResidual21, //< Special case for branches that are connected to two + //buses + BusResidual22, //< Special case for branches that are connected to two + //buses Objective, //< Optimization objective - Constraints //< Optimization internal constraints and contributions at the ports + Constraints //< Optimization internal constraints and contributions at + //the ports }; /** - * @brief Template definition for wrapper around residual methods inside model classes + * @brief Template definition for wrapper around residual methods inside + * model classes * * @tparam ModelT - model type * @tparam MemberFunctions - member function parameter key @@ -48,13 +54,15 @@ namespace GridKit }; /** - * @brief Residual wrapper partial template specialization for InternalResidual + * @brief Residual wrapper partial template specialization for + * InternalResidual * */ template struct ModelWrapper { - using ScalarT = typename GridKit::Model::EvaluatorTraits::ScalarT; + using ScalarT = + typename GridKit::Model::EvaluatorTraits::ScalarT; /** * @param[in] model - Pointer to the model to be differentiated @@ -76,13 +84,15 @@ namespace GridKit }; /** - * @brief Residual wrapper partial template specialization for InternalResidualWithSignal + * @brief Residual wrapper partial template specialization for + * InternalResidualWithSignal * */ template struct ModelWrapper { - using ScalarT = typename GridKit::Model::EvaluatorTraits::ScalarT; + using ScalarT = + typename GridKit::Model::EvaluatorTraits::ScalarT; /** * @param[in] model - Pointer to the model to be differentiated @@ -112,7 +122,8 @@ namespace GridKit template struct ModelWrapper { - using ScalarT = typename GridKit::Model::EvaluatorTraits::ScalarT; + using ScalarT = + typename GridKit::Model::EvaluatorTraits::ScalarT; /** * @param[in] model - Pointer to the model to be differentiated @@ -134,13 +145,15 @@ namespace GridKit }; /** - * @brief Residual wrapper partial template specialization for BusResidual11 (branch member function) + * @brief Residual wrapper partial template specialization for + * BusResidual11 (branch member function) * */ template struct ModelWrapper { - using ScalarT = typename GridKit::Model::EvaluatorTraits::ScalarT; + using ScalarT = + typename GridKit::Model::EvaluatorTraits::ScalarT; /** * @param[in] model - Pointer to the model to be differentiated @@ -162,13 +175,15 @@ namespace GridKit }; /** - * @brief Residual wrapper partial template specialization for BusResidual12 (branch member function) + * @brief Residual wrapper partial template specialization for + * BusResidual12 (branch member function) * */ template struct ModelWrapper { - using ScalarT = typename GridKit::Model::EvaluatorTraits::ScalarT; + using ScalarT = + typename GridKit::Model::EvaluatorTraits::ScalarT; /** * @param[in] model - Pointer to the model to be differentiated @@ -190,17 +205,20 @@ namespace GridKit }; /** - * @brief Residual wrapper partial template specialization for BusResidual21 (branch member function) + * @brief Residual wrapper partial template specialization for + * BusResidual21 (branch member function) * */ template struct ModelWrapper { - using ScalarT = typename GridKit::Model::EvaluatorTraits::ScalarT; + using ScalarT = + typename GridKit::Model::EvaluatorTraits::ScalarT; /** * @param[in] model - Pointer to the model to be differentiated - __enzyme_fwddiff((void*) ModelWrapper::eval, + __enzyme_fwddiff((void*) ModelWrapper::eval, * @param[in] y - Internal variables * @param[in] yp - Internal variable derivatives * @param[in] wb - Bus variables @@ -219,13 +237,15 @@ namespace GridKit }; /** - * @brief Residual wrapper partial template specialization for BusResidual22 (branch member function) + * @brief Residual wrapper partial template specialization for + * BusResidual22 (branch member function) * */ template struct ModelWrapper { - using ScalarT = typename GridKit::Model::EvaluatorTraits::ScalarT; + using ScalarT = + typename GridKit::Model::EvaluatorTraits::ScalarT; /** * @param[in] model - Pointer to the model to be differentiated @@ -247,16 +267,20 @@ namespace GridKit }; /** - * @brief Wrapper partial template specialization for an optimization objective + * @brief Wrapper partial template specialization for an optimization + * objective */ template struct ModelWrapper { /// Number of internal variables - static constexpr std::size_t NUM_INTERNAL_INPUTS = Utilities::enum_size(); + static constexpr std::size_t NUM_INTERNAL_INPUTS = + Utilities::enum_size(); /// Number of local variables - static constexpr std::size_t NUM_INPUTS = NUM_INTERNAL_INPUTS + Utilities::enum_size(); + static constexpr std::size_t NUM_INPUTS = + NUM_INTERNAL_INPUTS + + Utilities::enum_size(); /** * @param[in] model - Pointer to the model to be differentiated @@ -264,26 +288,33 @@ namespace GridKit * @return Objective contribution */ template - [[gnu::always_inline]] inline static ScalarT eval(const ModelT* model, const ScalarT* x) + [[gnu::always_inline]] inline static ScalarT eval( + const ModelT* model, const ScalarT* x + ) { return model->objective(x, x + NUM_INTERNAL_INPUTS); } }; /** - * @brief Wrapper partial template specialization for optimization constraints + * @brief Wrapper partial template specialization for optimization + * constraints */ template struct ModelWrapper { /// Number of internal variables - static constexpr std::size_t NUM_INTERNAL_INPUTS = Utilities::enum_size(); + static constexpr std::size_t NUM_INTERNAL_INPUTS = + Utilities::enum_size(); /// Number of internal constraints - static constexpr std::size_t NUM_INTERNAL_OUTPUTS = Utilities::enum_size(); + static constexpr std::size_t NUM_INTERNAL_OUTPUTS = + Utilities::enum_size(); /// Number of local constraint contributions - static constexpr std::size_t NUM_OUTPUTS = NUM_INTERNAL_OUTPUTS + Utilities::enum_size(); + static constexpr std::size_t NUM_OUTPUTS = + NUM_INTERNAL_OUTPUTS + + Utilities::enum_size(); /** * @param[in] model - Pointer to the model to be differentiated @@ -291,10 +322,14 @@ namespace GridKit * @param[out] g - Local constraint contributions */ template - [[gnu::always_inline]] inline static void eval(const ModelT* model, const ScalarT* x, ScalarT* g) + [[gnu::always_inline]] inline static void eval( + const ModelT* model, const ScalarT* x, ScalarT* g + ) { model->internalConstraints(x, x + NUM_INTERNAL_INPUTS, g); - model->externalConstraints(x, x + NUM_INTERNAL_INPUTS, g + NUM_INTERNAL_OUTPUTS); + model->externalConstraints( + x, x + NUM_INTERNAL_INPUTS, g + NUM_INTERNAL_OUTPUTS + ); } }; } // namespace Sparse diff --git a/GridKit/CoSim/CoSim.cpp b/GridKit/CoSim/CoSim.cpp index 218f91b84a..f8138eed50 100644 --- a/GridKit/CoSim/CoSim.cpp +++ b/GridKit/CoSim/CoSim.cpp @@ -245,8 +245,7 @@ namespace GridKit if (can_send_) { - throw std::logic_error( - "Co-simulation socket must send before receiving" + throw std::logic_error("Co-simulation socket must send before receiving" ); } @@ -380,8 +379,7 @@ namespace GridKit } template - void detail::Channel::closePeer( - const MessageMetadata& last + void detail::Channel::closePeer(const MessageMetadata& last ) noexcept { Teardown teardown(*this); diff --git a/GridKit/CoSim/Message.hpp b/GridKit/CoSim/Message.hpp index 5d87d93d3e..d1a03ff202 100644 --- a/GridKit/CoSim/Message.hpp +++ b/GridKit/CoSim/Message.hpp @@ -122,10 +122,8 @@ namespace GridKit /// Apply an incoming message and control simulation continuity. template - using MessageStepFunction = std::function&, - const MessageExchangeFunction& - )>; + using MessageStepFunction = std::function< + bool(const MessageData&, const MessageExchangeFunction&)>; /// Produce the next outgoing message, optionally exchanging intermediate /// messages first. diff --git a/GridKit/CommonMath.hpp b/GridKit/CommonMath.hpp index 71232ea8e6..3b0b4ab7bc 100644 --- a/GridKit/CommonMath.hpp +++ b/GridKit/CommonMath.hpp @@ -37,7 +37,8 @@ namespace GridKit __attribute__((always_inline)) inline ScalarT sigmoid(const ScalarT x) { using RealT = typename GridKit::ScalarTraits::RealT; - return HALF * (ONE + std::tanh(HALF * MU * x)); + return HALF + * (ONE + std::tanh(HALF * MU * x)); } /** @@ -167,7 +168,8 @@ namespace GridKit * passes the input through unchanged outside the band. * * @tparam ScalarT - scalar data type - * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * @tparam RealT - Real data type (see + * GridKit::ScalarTraits::RealT) * * @param[in] x - Input signal * @param[in] lower - Lower breakpoint @@ -190,7 +192,8 @@ namespace GridKit * smooth ramp function. * * @tparam ScalarT - scalar data type - * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * @tparam RealT - Real data type (see + * GridKit::ScalarTraits::RealT) * * @param[in] x - Input signal * @param[in] lower - Lower breakpoint @@ -212,7 +215,8 @@ namespace GridKit * Smooth approximation to min(max(f, -rate), rate). * * @tparam ScalarT - scalar data type - * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * @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 @@ -235,7 +239,8 @@ namespace GridKit * 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) + * @tparam RealT - Real data type (see + * GridKit::ScalarTraits::RealT) * * @param[in] x - Input signal * @param[in] lower - Lower breakpoint @@ -256,7 +261,8 @@ namespace GridKit * @brief Smooth above-limit indicator * * @tparam ScalarT - Scalar data type - * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * @tparam RealT - Real data type (see + * GridKit::ScalarTraits::RealT) * * @param[in] x - State variable * @param[in] limit_min - Minimum limit @@ -274,7 +280,8 @@ namespace GridKit * @brief Smooth below-limit indicator * * @tparam ScalarT - Scalar data type - * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * @tparam RealT - Real data type (see + * GridKit::ScalarTraits::RealT) * * @param[in] x - State variable * @param[in] limit_max - Maximum limit @@ -292,7 +299,8 @@ namespace GridKit * @brief Smooth inside-limits indicator * * @tparam ScalarT - Scalar data type - * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * @tparam RealT - Real data type (see + * GridKit::ScalarTraits::RealT) * * @param[in] x - State variable * @param[in] limit_min - Minimum limit @@ -312,7 +320,8 @@ namespace GridKit * @brief Smooth outside-limits indicator * * @tparam ScalarT - Scalar data type - * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * @tparam RealT - Real data type (see + * GridKit::ScalarTraits::RealT) * * @param[in] x - State variable * @param[in] limit_min - Minimum limit @@ -332,7 +341,8 @@ namespace GridKit * @brief Smooth anti-windup indicator for a limited state variable * * @tparam ScalarT - Scalar data type - * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * @tparam RealT - Real data type (see + * GridKit::ScalarTraits::RealT) * * @param[in] x - State variable * @param[in] f - Pre-limit derivative of the state variable @@ -368,7 +378,8 @@ namespace GridKit * and blocks motion that would push further into saturation. * * @tparam ScalarT - Scalar data type - * @tparam RealT - Real data type (see GridKit::ScalarTraits::RealT) + * @tparam RealT - Real data type (see + * GridKit::ScalarTraits::RealT) * * @param[in] x - Limited state or limited output signal * @param[in] f - Pre-limit derivative diff --git a/GridKit/LinearAlgebra/Solver/LinearSolver.hpp b/GridKit/LinearAlgebra/Solver/LinearSolver.hpp index 4edb16740f..cd980fc631 100644 --- a/GridKit/LinearAlgebra/Solver/LinearSolver.hpp +++ b/GridKit/LinearAlgebra/Solver/LinearSolver.hpp @@ -11,8 +11,10 @@ namespace GridKit { /** - * @brief Interface for linear solvers used by GridKit integrators, including - * \ref AnalysisManager::NativeDynamicSolver::Rosenbrock "Rosenbrock". + * @brief Interface for linear solvers used by GridKit integrators, + * including + * \ref AnalysisManager::NativeDynamicSolver::Rosenbrock + * "Rosenbrock". * */ template @@ -22,35 +24,47 @@ namespace GridKit using RealT = GridKit::ScalarTraits::RealT; /** - * @brief Configure the solver by analyzing the given matrix. The sparsity pattern of the given matrix must be set, and future calls - * to other methods will use this sparsity pattern, as well as the data pointer of the given matrix. + * @brief Configure the solver by analyzing the given matrix. The sparsity + * pattern of the given matrix must be set, and future calls to other + * methods will use this sparsity pattern, as well as the data pointer of + * the given matrix. * * @param matrix The matrix to configure the solver with. * @return int An error code, or 0 if none. */ - virtual int configureSolver(GridKit::LinearAlgebra::CsrMatrix& matrix) = 0; + virtual int configureSolver( + GridKit::LinearAlgebra::CsrMatrix& matrix + ) = 0; /** * @brief Setup the solver with matrix data. * - * @param reuse_factors If true, factors from a previous call to `setupSolver()` are reused. - * @pre \ref configureSolver() must be called first and every time the sparsity pattern of the matrix changes. - * @pre If `reuse_factors` is true, then `setupSolver` must have been called once before with the same sparsity pattern. + * @param reuse_factors If true, factors from a previous call to + * `setupSolver()` are reused. + * @pre \ref configureSolver() must be called first and every time the + * sparsity pattern of the matrix changes. + * @pre If `reuse_factors` is true, then `setupSolver` must have been + * called once before with the same sparsity pattern. * @return int An error code, or 0 if none. */ - virtual int setupSolver(bool reuse_factors = false) = 0; + virtual int setupSolver(bool reuse_factors = false) = 0; /** * @brief Perform a linear solve using the configured matrix. * * @param rhs The right-hand-side vector (input). No data is changed. * @param lhs The left-hand-side vector (output). - * @pre \ref setupSolver must be called first and every time the data of the matrix changes. + * @pre \ref setupSolver must be called first and every time the data of + * the matrix changes. * @return int An error code, or 0 if none. * - * @todo The data of the `rhs` parameter doesn't change, but we can't mark as constant because ReSolve currently requires - * a non-`const` pointer for vectors, even if it will only read from that vector. In the future this might change, so this - * can be updated to be `const`. + * @todo The data of the `rhs` parameter doesn't change, but we can't mark + * as constant because ReSolve currently requires a non-`const` pointer + * for vectors, even if it will only read from that vector. In the future + * this might change, so this can be updated to be `const`. */ - virtual int solve(GridKit::LinearAlgebra::Vector& rhs, GridKit::LinearAlgebra::Vector& lhs) = 0; + virtual int solve( + GridKit::LinearAlgebra::Vector& rhs, + GridKit::LinearAlgebra::Vector& lhs + ) = 0; }; } // namespace LinearAlgebra } // namespace GridKit diff --git a/GridKit/LinearAlgebra/Solver/ResolveSystemSolver.cpp b/GridKit/LinearAlgebra/Solver/ResolveSystemSolver.cpp index 4d67971479..b437f3fe63 100644 --- a/GridKit/LinearAlgebra/Solver/ResolveSystemSolver.cpp +++ b/GridKit/LinearAlgebra/Solver/ResolveSystemSolver.cpp @@ -8,10 +8,13 @@ namespace GridKit namespace LinearAlgebra { /** - * @brief Helper function to convert GridKit `MemorySpace` into ReSolve `MemorySpace`. + * @brief Helper function to convert GridKit `MemorySpace` into ReSolve + * `MemorySpace`. * */ - ReSolve::memory::MemorySpace memorySpaceAsResolve(memory::MemorySpace memspace) + ReSolve::memory::MemorySpace memorySpaceAsResolve( + memory::MemorySpace memspace + ) { switch (memspace) { @@ -25,24 +28,37 @@ namespace GridKit } template - ResolveSystemSolver::ResolveSystemSolver(ReSolve::SystemSolver& lin_solver, GridKit::memory::MemorySpace memspace) + ResolveSystemSolver::ResolveSystemSolver( + ReSolve::SystemSolver& lin_solver, GridKit::memory::MemorySpace memspace + ) : lin_solver_(lin_solver), memspace_(memorySpaceAsResolve(memspace)) { } /** - * @brief Creates a new ReSolve matrix with the dimensions of the given matrix, then sets its data pointers to those of the given matrix. - * Sets up the linear solver to use this new ReSolve matrix. + * @brief Creates a new ReSolve matrix with the dimensions of the given + * matrix, then sets its data pointers to those of the given matrix. Sets up + * the linear solver to use this new ReSolve matrix. * - * @todo Right now preconditioning doesn't work. There should be a ReSolve PR soon for this. + * @todo Right now preconditioning doesn't work. There should be a ReSolve + * PR soon for this. * */ template - int ResolveSystemSolver::configureSolver(GridKit::LinearAlgebra::CsrMatrix& matrix) + int ResolveSystemSolver::configureSolver( + GridKit::LinearAlgebra::CsrMatrix& matrix + ) { - matrix_ = std::make_unique(matrix.getNumRows(), matrix.getNumColumns(), matrix.getNnz()); - - if (int err = matrix_->setDataPointers(matrix.getRowData(), matrix.getColData(), matrix.getValues(), memspace_)) + matrix_ = std::make_unique( + matrix.getNumRows(), matrix.getNumColumns(), matrix.getNnz() + ); + + if (int err = matrix_->setDataPointers( + matrix.getRowData(), + matrix.getColData(), + matrix.getValues(), + memspace_ + )) return err; if (int err = lin_solver_.setMatrix(matrix_.get())) @@ -51,9 +67,11 @@ namespace GridKit if (int err = lin_solver_.analyze()) return err; - // TODO: This function needs to be called to properly use a preconditioner in ReSolve (if there is any), but currently will error - // if there is no preconditioner configured. Once we can detect if a preconditioner is configured, we can restore this functionality. - // Also, we will always want to use *right* preconditioning. + // TODO: This function needs to be called to properly use a preconditioner + // in ReSolve (if there is any), but currently will error if there is no + // preconditioner configured. Once we can detect if a preconditioner is + // configured, we can restore this functionality. Also, we will always + // want to use *right* preconditioning. // BUBBLE_FAIL(lin_solver_.preconditionerSetup("right")); return 0; @@ -77,13 +95,18 @@ namespace GridKit } /** - * @brief Perform the solver by creating two new ReSolve vectors and setting their data to point to their GridKit counterparts. - * Then ask ReSolve to perform the solve. Since the matrix should be pointing at the correct GridKit buffers and the vectors - * as well, this solve should correctly fill `lhs`'s data buffer. + * @brief Perform the solver by creating two new ReSolve vectors and setting + * their data to point to their GridKit counterparts. Then ask ReSolve to + * perform the solve. Since the matrix should be pointing at the correct + * GridKit buffers and the vectors as well, this solve should correctly fill + * `lhs`'s data buffer. * */ template - int ResolveSystemSolver::solve(GridKit::LinearAlgebra::Vector& rhs, GridKit::LinearAlgebra::Vector& lhs) + int ResolveSystemSolver::solve( + GridKit::LinearAlgebra::Vector& rhs, + GridKit::LinearAlgebra::Vector& lhs + ) { ReSolve::vector::Vector resolve_rhs(rhs.getSize()); ReSolve::vector::Vector resolve_lhs(lhs.getSize()); diff --git a/GridKit/LinearAlgebra/Solver/ResolveSystemSolver.hpp b/GridKit/LinearAlgebra/Solver/ResolveSystemSolver.hpp index 9ca55ef19d..351ab57f10 100644 --- a/GridKit/LinearAlgebra/Solver/ResolveSystemSolver.hpp +++ b/GridKit/LinearAlgebra/Solver/ResolveSystemSolver.hpp @@ -18,15 +18,23 @@ namespace GridKit public: using RealT = LinearSolver::RealT; - ResolveSystemSolver(ReSolve::SystemSolver& lin_solver, GridKit::memory::MemorySpace memspace = GridKit::memory::HOST); + ResolveSystemSolver( + ReSolve::SystemSolver& lin_solver, + GridKit::memory::MemorySpace memspace = GridKit::memory::HOST + ); - int configureSolver(GridKit::LinearAlgebra::CsrMatrix& matrix) final; + int configureSolver(GridKit::LinearAlgebra::CsrMatrix& matrix + ) final; int setupSolver(bool reuse_factors = false) final; - int solve(GridKit::LinearAlgebra::Vector& rhs, GridKit::LinearAlgebra::Vector& lhs) final; + int solve( + GridKit::LinearAlgebra::Vector& rhs, + GridKit::LinearAlgebra::Vector& lhs + ) final; private: /** - * @brief The ReSolve matrix used for the linear solve. Its data pointers should just point to a \ref GridKit::LinearAlgebra::CsrMatrix. + * @brief The ReSolve matrix used for the linear solve. Its data pointers + * should just point to a \ref GridKit::LinearAlgebra::CsrMatrix. * */ std::unique_ptr matrix_; diff --git a/GridKit/LinearAlgebra/SparseMatrix/CooMatrix.cpp b/GridKit/LinearAlgebra/SparseMatrix/CooMatrix.cpp index 2001ba9a3d..11ac510a59 100644 --- a/GridKit/LinearAlgebra/SparseMatrix/CooMatrix.cpp +++ b/GridKit/LinearAlgebra/SparseMatrix/CooMatrix.cpp @@ -262,14 +262,16 @@ namespace GridKit case HOST: if (owns_cpu_sparsity_pattern_ && (h_row_data_ || h_col_data_)) { - Log::warning() << "Trying to set matrix host data, but the data already set! " - << "Ignoring setDataPointers function call.\n"; + Log::warning( + ) << "Trying to set matrix host data, but the data already set! " + << "Ignoring setDataPointers function call.\n"; return 1; } if (owns_cpu_values_ && h_val_data_) { - Log::warning() << "Trying to set matrix host values, but the values already set! " - << "Ignoring setValuesPointer function call.\n"; + Log::warning( + ) << "Trying to set matrix host values, but the values already set! " + << "Ignoring setValuesPointer function call.\n"; return 1; } h_row_data_ = row_data; @@ -282,13 +284,15 @@ namespace GridKit case DEVICE: if (owns_gpu_sparsity_pattern_ && (d_row_data_ || d_col_data_)) { - Log::warning() << "Trying to set matrix host data, but the data already set! " - << "Ignoring setDataPointers function call.\n"; + Log::warning( + ) << "Trying to set matrix host data, but the data already set! " + << "Ignoring setDataPointers function call.\n"; return 1; } if (owns_gpu_values_ && d_val_data_) { - Log::warning() << "Trying to set matrix device values, but the values already set! " + Log::warning() << "Trying to set matrix device values, but the " + "values already set! " << "Ignoring setValuesPointer function call.\n"; return 1; } @@ -364,7 +368,8 @@ namespace GridKit { if (!h_data_updated_) { - Log::error() << "CooMatrix::getCsrRowData requires up-to-date host data, but host is out of date!\n"; + Log::error() << "CooMatrix::getCsrRowData requires up-to-date host " + "data, but host is out of date!\n"; assert(h_data_updated_); return nullptr; } @@ -377,9 +382,16 @@ namespace GridKit } // Sort by (row, col) - std::sort(map_to_sorted_, map_to_sorted_ + nnz_, [this](IdxT a, IdxT b) - { if (h_row_data_[a] != h_row_data_[b]) return h_row_data_[a] < h_row_data_[b]; - return h_col_data_[a] < h_col_data_[b]; }); + std::sort( + map_to_sorted_, + map_to_sorted_ + nnz_, + [this](IdxT a, IdxT b) + { + if (h_row_data_[a] != h_row_data_[b]) + return h_row_data_[a] < h_row_data_[b]; + return h_col_data_[a] < h_col_data_[b]; + } + ); IdxT* row_data_tmp = new IdxT[static_cast(nnz_)]; IdxT* col_data_tmp = new IdxT[static_cast(nnz_)]; @@ -417,7 +429,8 @@ namespace GridKit IdxT w = 0; for (IdxT i = 1; i < nnz_; i++) { - if (h_row_data_[i] == h_row_data_[w] && h_col_data_[i] == h_col_data_[w]) + if (h_row_data_[i] == h_row_data_[w] + && h_col_data_[i] == h_col_data_[w]) { h_val_data_[w] += h_val_data_[i]; map_to_dedup_[i] = w; @@ -510,8 +523,8 @@ namespace GridKit * @param memspace - memory space to be synced up (HOST or DEVICE) * @return int - 0 if successful, error code otherwise * - * @pre The memory space other than `memspace` must be up-to-date. Otherwise, - * this function will return an error. + * @pre The memory space other than `memspace` must be up-to-date. + * Otherwise, this function will return an error. * * @see CooMatrix::setUpdated */ @@ -524,17 +537,22 @@ namespace GridKit { case HOST: // check if we need to copy or not - assert(((h_row_data_ == nullptr) == (h_col_data_ == nullptr)) && "In CooMatrix::syncData one of host row or column data is null!\n"); + assert( + ((h_row_data_ == nullptr) == (h_col_data_ == nullptr)) + && "In CooMatrix::syncData one of host row or column data is null!\n" + ); if (h_data_updated_) { - Log::warning() << "CooMatrix::syncData is trying to sync host, but host already up to date!\n"; + Log::warning() << "CooMatrix::syncData is trying to sync host, but " + "host already up to date!\n"; assert(!h_data_updated_); return 1; } if (!d_data_updated_) { - Log::error() << "CooMatrix::syncData is trying to sync host with device, but device is out of date! " + Log::error() << "CooMatrix::syncData is trying to sync host with " + "device, but device is out of date! " << "See CooMatrix::syncData documentation.\n"; assert(d_data_updated_); } @@ -555,17 +573,23 @@ namespace GridKit h_data_updated_ = true; return 0; case DEVICE: - assert(((d_row_data_ == nullptr) == (d_col_data_ == nullptr)) && "In CooMatrix::syncData one of device row or column data is null!\n"); + assert( + ((d_row_data_ == nullptr) == (d_col_data_ == nullptr)) + && "In CooMatrix::syncData one of device row or column data is " + "null!\n" + ); if (d_data_updated_) { - Log::warning() << "CooMatrix::syncData is trying to sync device, but device already up to date!\n"; + Log::warning() << "CooMatrix::syncData is trying to sync device, but " + "device already up to date!\n"; assert(!d_data_updated_); return 1; } if (!h_data_updated_) { - Log::error() << "CooMatrix::syncData is trying to sync device with host, but host is out of date! " + Log::error() << "CooMatrix::syncData is trying to sync device with " + "host, but host is out of date! " << "See CooMatrix::syncData documentation.\n"; assert(h_data_updated_); } @@ -598,12 +622,12 @@ namespace GridKit template void CooMatrix::print(std::ostream& out, IdxT indexing_base) { - out << std::scientific << std::setprecision(std::numeric_limits::digits10); + out << std::scientific + << std::setprecision(std::numeric_limits::digits10); for (IdxT i = 0; i < nnz_; ++i) { out << h_row_data_[i] + indexing_base << " " - << h_col_data_[i] + indexing_base << " " - << h_val_data_[i] << "\n"; + << h_col_data_[i] + indexing_base << " " << h_val_data_[i] << "\n"; } } diff --git a/GridKit/LinearAlgebra/SparseMatrix/CsrMatrix.cpp b/GridKit/LinearAlgebra/SparseMatrix/CsrMatrix.cpp index 9afdd8d991..9ebc25b735 100644 --- a/GridKit/LinearAlgebra/SparseMatrix/CsrMatrix.cpp +++ b/GridKit/LinearAlgebra/SparseMatrix/CsrMatrix.cpp @@ -245,14 +245,14 @@ namespace GridKit * * @return 0 if successful, -1 if not. * - * The method sets the boolean flag indicating that the `memspace` is updated. - * It automatically sets the other data mirror to non-updated. You would - * use this function if you update matrix data by accessing its raw pointers. - * In such case, the matrix has no way of knowing which data is most recent, so - * you have to tell it. + * The method sets the boolean flag indicating that the `memspace` is + * updated. It automatically sets the other data mirror to non-updated. You + * would use this function if you update matrix data by accessing its raw + * pointers. In such case, the matrix has no way of knowing which data is + * most recent, so you have to tell it. * - * @warning This is an expert-level function. Use only if you know what you are - * doing. + * @warning This is an expert-level function. Use only if you know what you + * are doing. * * @note If you want to set both DEVICE and HOST memory to the same value * use syncData function. @@ -306,14 +306,16 @@ namespace GridKit case HOST: if (owns_cpu_sparsity_pattern_ && (h_row_data_ || h_col_data_)) { - Log::warning() << "Trying to set matrix host data, but the data already set! " - << "Ignoring setDataPointers function call.\n"; + Log::warning( + ) << "Trying to set matrix host data, but the data already set! " + << "Ignoring setDataPointers function call.\n"; return 1; } if (owns_cpu_values_ && h_val_data_) { - Log::warning() << "Trying to set matrix host values, but the values already set! " - << "Ignoring setValuesPointer function call.\n"; + Log::warning( + ) << "Trying to set matrix host values, but the values already set! " + << "Ignoring setValuesPointer function call.\n"; return 1; } h_row_data_ = row_data; @@ -326,13 +328,15 @@ namespace GridKit case DEVICE: if (owns_gpu_sparsity_pattern_ && (d_row_data_ || d_col_data_)) { - Log::warning() << "Trying to set matrix host data, but the data already set! " - << "Ignoring setDataPointers function call.\n"; + Log::warning( + ) << "Trying to set matrix host data, but the data already set! " + << "Ignoring setDataPointers function call.\n"; return 1; } if (owns_gpu_values_ && d_val_data_) { - Log::warning() << "Trying to set matrix device values, but the values already set! " + Log::warning() << "Trying to set matrix device values, but the " + "values already set! " << "Ignoring setValuesPointer function call.\n"; return 1; } @@ -396,14 +400,17 @@ namespace GridKit } /** - * @brief update matrix values using the _new_values_ provided either as HOST or as DEVICE array. + * @brief update matrix values using the _new_values_ provided either as + * HOST or as DEVICE array. * - * This function will copy the data (not just assign a pointer) and allocate if needed. - * It also sets ownership and update flags. + * This function will copy the data (not just assign a pointer) and allocate + * if needed. It also sets ownership and update flags. * - * @param[in] new_vals - pointer to new values data (array of real numbers) + * @param[in] new_vals - pointer to new values data (array of real + * numbers) * @param[in] memspace_in - memory space (HOST or DEVICE) of _new_vals_ - * @param[in] memspace_out - memory space (HOST or DEVICE) of matrix values to be updated. + * @param[in] memspace_out - memory space (HOST or DEVICE) of matrix values + * to be updated. * * @return 0 if successful, -1 if not. */ @@ -505,8 +512,9 @@ namespace GridKit case HOST: if (owns_cpu_values_ && h_val_data_) { - Log::warning() << "Trying to set matrix host values, but the values already set! " - << "Ignoring setValuesPointer function call.\n"; + Log::warning( + ) << "Trying to set matrix host values, but the values already set! " + << "Ignoring setValuesPointer function call.\n"; return 1; } h_val_data_ = new_vals; @@ -516,7 +524,8 @@ namespace GridKit case DEVICE: if (owns_gpu_values_ && d_val_data_) { - Log::warning() << "Trying to set matrix device values, but the values already set! " + Log::warning() << "Trying to set matrix device values, but the " + "values already set! " << "Ignoring setValuesPointer function call.\n"; return 1; } @@ -603,7 +612,8 @@ namespace GridKit { control = 2; } - if (((memspace_in == memory::DEVICE)) && ((memspace_out == memory::DEVICE))) + if (((memspace_in == memory::DEVICE)) + && ((memspace_out == memory::DEVICE))) { control = 3; } @@ -611,12 +621,16 @@ namespace GridKit if (memspace_out == memory::HOST) { // check if cpu data allocated - assert(((h_row_data_ == nullptr) == (h_col_data_ == nullptr)) && "In CsrMatrix::copyDataFrom one of host row or column data is null!\n"); + assert( + ((h_row_data_ == nullptr) == (h_col_data_ == nullptr)) + && "In CsrMatrix::copyDataFrom one of host row or column data is " + "null!\n" + ); if ((h_row_data_ == nullptr) && (h_col_data_ == nullptr)) { - h_row_data_ = new IdxT[static_cast(n_ + 1)]; - h_col_data_ = new IdxT[static_cast(nnz_current)]; + h_row_data_ = new IdxT[static_cast(n_ + 1)]; + h_col_data_ = new IdxT[static_cast(nnz_current)]; owns_cpu_sparsity_pattern_ = true; } if (h_val_data_ == nullptr) @@ -629,7 +643,11 @@ namespace GridKit if (memspace_out == memory::DEVICE) { // check if cuda data allocated - assert(((d_row_data_ == nullptr) == (d_col_data_ == nullptr)) && "In CsrMatrix::copyDataFrom one of device row or column data is null!\n"); + assert( + ((d_row_data_ == nullptr) == (d_col_data_ == nullptr)) + && "In CsrMatrix::copyDataFrom one of device row or column data is " + "null!\n" + ); if ((d_row_data_ == nullptr) && (d_col_data_ == nullptr)) { @@ -689,7 +707,9 @@ namespace GridKit { destroyMatrixData(memspace_out); nnz_ = new_nnz; - return copyDataFrom(row_data, col_data, val_data, memspace_in, memspace_out); + return copyDataFrom( + row_data, col_data, val_data, memspace_in, memspace_out + ); } template @@ -729,8 +749,8 @@ namespace GridKit * @param memspace - memory space to be synced up (HOST or DEVICE) * @return int - 0 if successful, error code otherwise * - * @pre The memory space other than `memspace` must be up-to-date. Otherwise, - * this function will return an error. + * @pre The memory space other than `memspace` must be up-to-date. + * Otherwise, this function will return an error. * * @see CsrMatrix::setUpdated */ @@ -743,17 +763,22 @@ namespace GridKit { case HOST: // check if we need to copy or not - assert(((h_row_data_ == nullptr) == (h_col_data_ == nullptr)) && "In CsrMatrix::syncData one of host row or column data is null!\n"); + assert( + ((h_row_data_ == nullptr) == (h_col_data_ == nullptr)) + && "In CsrMatrix::syncData one of host row or column data is null!\n" + ); if (h_data_updated_) { - Log::warning() << "CsrMatrix::syncData is trying to sync host, but host already up to date!\n"; + Log::warning() << "CsrMatrix::syncData is trying to sync host, but " + "host already up to date!\n"; assert(!h_data_updated_); return 1; } if (!d_data_updated_) { - Log::error() << "CsrMatrix::syncData is trying to sync host with device, but device is out of date! " + Log::error() << "CsrMatrix::syncData is trying to sync host with " + "device, but device is out of date! " << "See CsrMatrix::syncData documentation.\n"; assert(d_data_updated_); } @@ -774,17 +799,23 @@ namespace GridKit h_data_updated_ = true; return 0; case DEVICE: - assert(((d_row_data_ == nullptr) == (d_col_data_ == nullptr)) && "In CsrMatrix::syncData one of device row or column data is null!\n"); + assert( + ((d_row_data_ == nullptr) == (d_col_data_ == nullptr)) + && "In CsrMatrix::syncData one of device row or column data is " + "null!\n" + ); if (d_data_updated_) { - Log::warning() << "CsrMatrix::syncData is trying to sync device, but device already up to date!\n"; + Log::warning() << "CsrMatrix::syncData is trying to sync device, but " + "device already up to date!\n"; assert(!d_data_updated_); return 1; } if (!h_data_updated_) { - Log::error() << "CsrMatrix::syncData is trying to sync device with host, but host is out of date! " + Log::error() << "CsrMatrix::syncData is trying to sync device with " + "host, but host is out of date! " << "See CsrMatrix::syncData documentation.\n"; assert(h_data_updated_); } @@ -817,14 +848,14 @@ namespace GridKit template void CsrMatrix::print(std::ostream& out, IdxT indexing_base) { - out << std::scientific << std::setprecision(std::numeric_limits::digits10); + out << std::scientific + << std::setprecision(std::numeric_limits::digits10); for (IdxT i = 0; i < n_; ++i) { for (IdxT j = h_row_data_[i]; j < h_row_data_[i + 1]; ++j) { - out << i + indexing_base << " " - << h_col_data_[j] + indexing_base << " " - << h_val_data_[j] << "\n"; + out << i + indexing_base << " " << h_col_data_[j] + indexing_base + << " " << h_val_data_[j] << "\n"; } } } diff --git a/GridKit/LinearAlgebra/Vector/Vector.cpp b/GridKit/LinearAlgebra/Vector/Vector.cpp index 3fda79ab2a..3ab59c2d31 100644 --- a/GridKit/LinearAlgebra/Vector/Vector.cpp +++ b/GridKit/LinearAlgebra/Vector/Vector.cpp @@ -17,20 +17,24 @@ namespace GridKit [[gnu::cold, gnu::noinline]] void logHostUnsyncFailure() { - Log::error() << "Vector::getData - host data is stale. Perhaps you need to call syncData?\n"; + Log::error() << "Vector::getData - host data is stale. Perhaps you " + "need to call syncData?\n"; } [[gnu::cold, gnu::noinline]] void logDeviceUnsyncFailure() { - Log::error() << "Vector::getData - host device is stale. Perhaps you need to call syncData?\n"; + Log::error() << "Vector::getData - host device is stale. Perhaps you " + "need to call syncData?\n"; } template [[gnu::cold, gnu::noinline]] void logBoundsCheckFailure(IdxT j, IdxT k) { - Log::error() << "Vector::getData - vector index " << j << " out of range, multivector has only " << k << " vectors\n"; + Log::error() << "Vector::getData - vector index " << j + << " out of range, multivector has only " << k + << " vectors\n"; } template void logBoundsCheckFailure(long int, long int); @@ -74,9 +78,7 @@ namespace GridKit */ template Vector::Vector(IdxT n, IdxT k) - : n_capacity_(n), - k_(k), - n_size_(n) + : n_capacity_(n), k_(k), n_size_(n) { if (k <= 1) { @@ -169,7 +171,9 @@ namespace GridKit * you are doing. */ template - int Vector::setData(ScalarT* data, memory::MemorySpace memspace) + int Vector::setData( + ScalarT* data, memory::MemorySpace memspace + ) { using namespace memory; @@ -178,7 +182,8 @@ namespace GridKit case HOST: if (h_data_) { - Log::error() << "Vector::setData - host data already exists, ignoring call\n"; + Log::error( + ) << "Vector::setData - host data already exists, ignoring call\n"; return 1; } h_data_ = data; @@ -189,7 +194,8 @@ namespace GridKit case DEVICE: if (d_data_) { - Log::error() << "Vector::setData - device data already exists, ignoring call\n"; + Log::error( + ) << "Vector::setData - device data already exists, ignoring call\n"; return 1; } d_data_ = data; @@ -221,7 +227,8 @@ namespace GridKit { if (data == nullptr && size != IdxT{}) { - Log::error() << "Vector::setData - nonzero vector cannot use null data\n"; + Log::error( + ) << "Vector::setData - nonzero vector cannot use null data\n"; return 1; } @@ -236,7 +243,8 @@ namespace GridKit } if (d_data_ != nullptr && size != n_size_) { - Log::error() << "Vector::setData - size conflicts with existing device data\n"; + Log::error( + ) << "Vector::setData - size conflicts with existing device data\n"; return 1; } h_data_ = data; @@ -247,12 +255,14 @@ namespace GridKit case DEVICE: if (d_data_ != nullptr && owns_gpu_data_) { - Log::error() << "Vector::setData - cannot replace owned device data\n"; + Log::error( + ) << "Vector::setData - cannot replace owned device data\n"; return 1; } if (h_data_ != nullptr && size != n_size_) { - Log::error() << "Vector::setData - size conflicts with existing host data\n"; + Log::error( + ) << "Vector::setData - size conflicts with existing host data\n"; return 1; } d_data_ = data; @@ -274,10 +284,15 @@ namespace GridKit * @param[in] memspaceSrc - Memory space of the data source (HOST or DEVICE) * @param[in] memspaceDst - Memory space to copy data to (HOST or DEVICE) * - * @pre Size of _source_ is greater than or equal to the current vector size. + * @pre Size of _source_ is greater than or equal to the current vector + * size. */ template - int Vector::copyFromExternal(const Vector& source, memory::MemorySpace memspaceSrc, memory::MemorySpace memspaceDst) + int Vector::copyFromExternal( + const Vector& source, + memory::MemorySpace memspaceSrc, + memory::MemorySpace memspaceDst + ) { const ScalarT* source_data = source.getData(memspaceSrc); return copyFromExternal(source_data, memspaceSrc, memspaceDst); @@ -290,7 +305,8 @@ namespace GridKit * this function. * * @param[in] source - Array to copy from - * @param[in] memspaceSrc - Memory space of the source array (HOST or DEVICE) + * @param[in] memspaceSrc - Memory space of the source array (HOST or + * DEVICE) * @param[in] memspaceDst - Memory space to copy data to (HOST or DEVICE) * * @return 0 if successful, 1 otherwise. @@ -304,7 +320,8 @@ namespace GridKit { if (source == nullptr) { - Log::error() << "Vector::copyFromExternal - source data is null or stale\n"; + Log::error( + ) << "Vector::copyFromExternal - source data is null or stale\n"; return 1; } @@ -313,14 +330,16 @@ namespace GridKit case memory::HOST: if (h_data_ == nullptr) { - Log::error() << "Vector::copyFromExternal - host destination not allocated\n"; + Log::error( + ) << "Vector::copyFromExternal - host destination not allocated\n"; return 1; } break; case memory::DEVICE: if (d_data_ == nullptr) { - Log::error() << "Vector::copyFromExternal - device destination not allocated\n"; + Log::error( + ) << "Vector::copyFromExternal - device destination not allocated\n"; return 1; } break; @@ -396,13 +415,15 @@ namespace GridKit { if (getDeviceUpdated(i) != all_gpu_updated) { - Log::error() << "Vector::syncData - inconsistent update state across device columns.\n" + Log::error() << "Vector::syncData - inconsistent update state across " + "device columns.\n" << "Use syncData(j, memspace) for individual vectors\n"; return 1; } if (getHostUpdated(i) != all_cpu_updated) { - Log::error() << "Vector::syncData - inconsistent update state across host columns.\n" + Log::error() << "Vector::syncData - inconsistent update state across " + "host columns.\n" << "Use syncData(j, memspace) for individual vectors\n"; return 1; } @@ -418,7 +439,8 @@ namespace GridKit } if (!all_cpu_updated) { - Log::error() << "Vector::syncData - host data is stale, cannot sync to device\n"; + Log::error( + ) << "Vector::syncData - host data is stale, cannot sync to device\n"; return 1; } if (d_data_ == nullptr) @@ -437,7 +459,8 @@ namespace GridKit } if (!all_gpu_updated) { - Log::error() << "Vector::syncData - device data is stale, cannot sync to host\n"; + Log::error( + ) << "Vector::syncData - device data is stale, cannot sync to host\n"; return 1; } if (h_data_ == nullptr) @@ -492,7 +515,8 @@ namespace GridKit } if (!getHostUpdated(j)) { - Log::error() << "Vector::syncData - host data is stale, cannot sync to device\n"; + Log::error( + ) << "Vector::syncData - host data is stale, cannot sync to device\n"; return 1; } if (d_data_ == nullptr) @@ -500,7 +524,9 @@ namespace GridKit Log::error() << "Vector::syncData - device data not allocated\n"; return 1; } - mem_.copyArrayHostToDevice(&d_data_[j * n_size_], &h_data_[j * n_size_], n_size_); + mem_.copyArrayHostToDevice( + &d_data_[j * n_size_], &h_data_[j * n_size_], n_size_ + ); setDeviceUpdated(j, true); break; case HOST: // gpu -> cpu @@ -511,7 +537,8 @@ namespace GridKit } if (!getDeviceUpdated(j)) { - Log::error() << "Vector::syncData - device data is stale, cannot sync to host\n"; + Log::error( + ) << "Vector::syncData - device data is stale, cannot sync to host\n"; return 1; } if (h_data_ == nullptr) @@ -519,7 +546,9 @@ namespace GridKit Log::error() << "Vector::syncData - host data not allocated\n"; return 1; } - mem_.copyArrayDeviceToHost(&h_data_[j * n_size_], &d_data_[j * n_size_], n_size_); + mem_.copyArrayDeviceToHost( + &h_data_[j * n_size_], &d_data_[j * n_size_], n_size_ + ); setHostUpdated(j, true); break; default: @@ -587,7 +616,8 @@ namespace GridKit * * In case of multivectors, the entire multivector is set to zero. * - * @param[in] memspace - Memory space of the data to be zeroed (HOST or DEVICE) + * @param[in] memspace - Memory space of the data to be zeroed (HOST or + * DEVICE) * */ template @@ -624,7 +654,8 @@ namespace GridKit * @brief set the data of a single vector in a multivector to zero. * * @param[in] j - Index of a vector in the multivector - * @param[in] memspace - Memory space of the data to be zeroed (HOST or DEVICE) + * @param[in] memspace - Memory space of the data to be zeroed (HOST or + * DEVICE) * * @pre `j` < `k_`, i.e., `j` is smaller than the number of vectors. */ @@ -678,7 +709,9 @@ namespace GridKit * */ template - int Vector::setToConst(ScalarT C, memory::MemorySpace memspace) + int Vector::setToConst( + ScalarT C, memory::MemorySpace memspace + ) { using namespace memory; switch (memspace) @@ -708,7 +741,8 @@ namespace GridKit } /** - * @brief set the data of a single vector in a multivector to a given constant. + * @brief set the data of a single vector in a multivector to a given + * constant. * * @param[in] j - Index of a vector in the multivector * @param[in] C - Constant value to set @@ -717,7 +751,9 @@ namespace GridKit * @pre `j` < `k_`, i.e., `j` is smaller than the number of vectors. */ template - int Vector::setToConst(IdxT j, ScalarT C, memory::MemorySpace memspace) + int Vector::setToConst( + IdxT j, ScalarT C, memory::MemorySpace memspace + ) { using namespace memory; @@ -810,7 +846,9 @@ namespace GridKit ScalarT* new_data = nullptr; mem_.allocateArrayOnHost(&new_data, new_n_size * k_); for (IdxT j = 0; j < k_; ++j) - mem_.copyArrayHostToHost(&new_data[j * new_n_size], &h_data_[j * old_n_size], old_n_size); + mem_.copyArrayHostToHost( + &new_data[j * new_n_size], &h_data_[j * old_n_size], old_n_size + ); mem_.deleteOnHost(h_data_); h_data_ = new_data; } @@ -820,7 +858,9 @@ namespace GridKit ScalarT* new_data = nullptr; mem_.allocateArrayOnDevice(&new_data, new_n_size * k_); for (IdxT j = 0; j < k_; ++j) - mem_.copyArrayDeviceToDevice(&new_data[j * new_n_size], &d_data_[j * old_n_size], old_n_size); + mem_.copyArrayDeviceToDevice( + &new_data[j * new_n_size], &d_data_[j * old_n_size], old_n_size + ); mem_.deleteOnDevice(d_data_); d_data_ = new_data; } @@ -831,14 +871,17 @@ namespace GridKit } /** - * @brief Copy HOST or DEVICE data of a single vector in a multivector to _dest_. + * @brief Copy HOST or DEVICE data of a single vector in a multivector to + * _dest_. * * Supports cross-space copies, e.g. vector _i_ from HOST to DEVICE. * * @param[out] dest - Destination array * @param[in] i - Index of a vector in the multivector - * @param[in] memspaceSrc - Memory space of the source data (HOST or DEVICE) - * @param[in] memspaceDst - Memory space of the destination (HOST or DEVICE) + * @param[in] memspaceSrc - Memory space of the source data (HOST or + * DEVICE) + * @param[in] memspaceDst - Memory space of the destination (HOST or + * DEVICE) * * @return 0 if successful, 1 otherwise. * @@ -847,24 +890,33 @@ namespace GridKit * @post All elements of vector _i_ are copied to _dest_. */ template - int Vector::copyToExternal(ScalarT* dest, IdxT i, memory::MemorySpace memspaceSrc, memory::MemorySpace memspaceDst) + int Vector::copyToExternal( + ScalarT* dest, + IdxT i, + memory::MemorySpace memspaceSrc, + memory::MemorySpace memspaceDst + ) { using namespace memory; if (i >= k_) { Log::error() << "Vector::copyToExternal - vector index " << i - << " out of range, multivector has only " << k_ << " vectors\n"; + << " out of range, multivector has only " << k_ + << " vectors\n"; return 1; } if (dest == nullptr) { - Log::error() << "Vector::copyToExternal - destination pointer for vector " << i << " is null\n"; + Log::error( + ) << "Vector::copyToExternal - destination pointer for vector " + << i << " is null\n"; return 1; } ScalarT* data = getData(i, memspaceSrc); if (data == nullptr) { - Log::error() << "Vector::copyToExternal - source data for vector " << i << " is null or stale\n"; + Log::error() << "Vector::copyToExternal - source data for vector " << i + << " is null or stale\n"; return 1; } switch (memspaceSrc) @@ -898,34 +950,45 @@ namespace GridKit /** * @brief copy HOST or DEVICE data of multivector to _dest_. * - * This function allows to copy data between different memory spaces in one call. - * For example, you can copy data of multivector from HOST to DEVICE, or from DEVICE to HOST. + * This function allows to copy data between different memory spaces in one + * call. For example, you can copy data of multivector from HOST to DEVICE, + * or from DEVICE to HOST. * * @param[out] dest - Pointer to the memory to which data is copied - * @param[in] memspaceSrc - Memory space (HOST or DEVICE) of the data to be copied - * @param[in] memspaceDst - Memory space (HOST or DEVICE) to which data is copied + * @param[in] memspaceSrc - Memory space (HOST or DEVICE) of the data to + * be copied + * @param[in] memspaceDst - Memory space (HOST or DEVICE) to which data is + * copied * * @return 0 if successful, 1 otherwise. * - * @pre _dest_ is allocated, and the size of _dest_ is at least _n_ * _k_ (total length of all vectors in the multivector). + * @pre _dest_ is allocated, and the size of _dest_ is at least _n_ * _k_ + * (total length of all vectors in the multivector). * @pre _dest_ is allocated in memspaceOutDst memory space. - * @post All elements of all vectors in multivector are copied to the array _dest_. + * @post All elements of all vectors in multivector are copied to the array + * _dest_. */ template - int Vector::copyToExternal(ScalarT* dest, memory::MemorySpace memspaceSrc, memory::MemorySpace memspaceDst) + int Vector::copyToExternal( + ScalarT* dest, + memory::MemorySpace memspaceSrc, + memory::MemorySpace memspaceDst + ) { using namespace memory; ScalarT* data = this->getData(memspaceSrc); // Check that the source data is not null and up to date if (data == nullptr) { - Log::error() << "Vector::copyToExternal - source data is null or stale\n"; + Log::error( + ) << "Vector::copyToExternal - source data is null or stale\n"; return 1; } // Check that the destination memory space is allocated if (dest == nullptr) { - Log::error() << "Vector::copyToExternal - destination pointer is null\n"; + Log::error( + ) << "Vector::copyToExternal - destination pointer is null\n"; return 1; } switch (memspaceSrc) diff --git a/GridKit/LinearAlgebra/Vector/Vector.hpp b/GridKit/LinearAlgebra/Vector/Vector.hpp index 8ab6ecb75c..a983357d7b 100644 --- a/GridKit/LinearAlgebra/Vector/Vector.hpp +++ b/GridKit/LinearAlgebra/Vector/Vector.hpp @@ -50,9 +50,9 @@ namespace GridKit * - Multivectors are stored in one array, organized column-wise. A vector * is a multivector of size 1. * - There is a mirroring memory approach: the class has DEVICE and HOST - * data pointers. If needed, only one (or none) can be used or allocated. - * Unless triggered directly or by other function, the data is NOT - * automatically updated between HOST and DEVICE. + * data pointers. If needed, only one (or none) can be used or + * allocated. Unless triggered directly or by other function, the data is + * NOT automatically updated between HOST and DEVICE. * - Constructor DOES NOT allocate memory. This has to be done separately. * - You can get (and set) "raw" data easily, if needed. * - There is memory ownership utility - vector can own memory (separate @@ -65,8 +65,7 @@ namespace GridKit class Vector { public: - Vector() - : Vector(0) + Vector() : Vector(0) { } @@ -100,8 +99,8 @@ namespace GridKit * * @param[in] memspace - Memory space of the pointer (HOST or DEVICE) * - * @return pointer to the vector data (HOST or DEVICE). In case of multivectors, - * vectors are stored column-wise. + * @return pointer to the vector data (HOST or DEVICE). In case of + * multivectors, vectors are stored column-wise. * * @note This function gives you access to the pointer, not to a copy. * If you change the values using the pointer, the vector values will @@ -136,7 +135,8 @@ namespace GridKit } /** - * @brief Get a pointer to HOST or DEVICE data of a vector in a multivector. + * @brief Get a pointer to HOST or DEVICE data of a vector in a + * multivector. * * @param[in] j - Index of a vector in multivector * @param[in] memspace - Memory space of the pointer (HOST or DEVICE) @@ -187,8 +187,8 @@ namespace GridKit * * @param[in] memspace - Memory space of the pointer (HOST or DEVICE) * - * @return pointer to the vector data (HOST or DEVICE). In case of multivectors, - * vectors are stored column-wise. + * @return pointer to the vector data (HOST or DEVICE). In case of + * multivectors, vectors are stored column-wise. */ [[gnu::always_inline]] const ScalarT* getData(memory::MemorySpace memspace = memory::HOST) const @@ -218,7 +218,8 @@ namespace GridKit } /** - * @brief Get a const pointer to HOST or DEVICE data of a vector in a multivector. + * @brief Get a const pointer to HOST or DEVICE data of a vector in a + * multivector. * * @param[in] j - Index of a vector in multivector * @param[in] memspace - Memory space of the pointer (HOST or DEVICE) @@ -228,7 +229,9 @@ namespace GridKit * @pre `j` < `k_`, i.e., `j` is smaller than the number of vectors. */ [[gnu::always_inline]] - const ScalarT* getData(IdxT j, memory::MemorySpace memspace = memory::HOST) const + const ScalarT* getData( + IdxT j, memory::MemorySpace memspace = memory::HOST + ) const { using memory::DEVICE; using memory::HOST; @@ -268,8 +271,8 @@ namespace GridKit * @brief Set the flag to indicate that the data (HOST or DEVICE) has been * updated. * - * Use this function if you update vector elements by accessing the raw data - * pointer. + * Use this function if you update vector elements by accessing the raw + * data pointer. * * @param[in] memspace - Memory space (HOST or DEVICE) * @@ -298,8 +301,8 @@ namespace GridKit * @brief Set the flag to indicate that the data (HOST or DEVICE) for * vector `j` in the multivector has been updated. * - * Use this function if you update vector elements by accessing the raw data - * pointer. + * Use this function if you update vector elements by accessing the raw + * data pointer. * * @param[in] j - Index of a vector in multivector * @param[in] memspace - Memory space (HOST or DEVICE) @@ -333,12 +336,16 @@ namespace GridKit } int setData(ScalarT* data, memory::MemorySpace memspace = memory::HOST); - int setData(ScalarT* data, IdxT size, memory::MemorySpace memspace = memory::HOST); + int setData( + ScalarT* data, IdxT size, memory::MemorySpace memspace = memory::HOST + ); int allocate(memory::MemorySpace memspace = memory::HOST); int setToZero(memory::MemorySpace memspace = memory::HOST); int setToZero(IdxT i, memory::MemorySpace memspace = memory::HOST); int setToConst(ScalarT C, memory::MemorySpace memspace = memory::HOST); - int setToConst(IdxT i, ScalarT C, memory::MemorySpace memspace = memory::HOST); + int setToConst( + IdxT i, ScalarT C, memory::MemorySpace memspace = memory::HOST + ); int syncData(memory::MemorySpace memspaceOut = memory::HOST); int syncData(IdxT j, memory::MemorySpace memspaceOut = memory::HOST); int resize(IdxT new_n_current); diff --git a/GridKit/LinearAlgebra/Vector/VectorHandler.cpp b/GridKit/LinearAlgebra/Vector/VectorHandler.cpp index 175f2b05fc..3f506251bc 100644 --- a/GridKit/LinearAlgebra/Vector/VectorHandler.cpp +++ b/GridKit/LinearAlgebra/Vector/VectorHandler.cpp @@ -17,33 +17,45 @@ namespace GridKit * * @param[in] x The first vector * @param[in] y The second vector - * @param[in] memspace Memory space the operation is computed in (HOST or DEVICE) + * @param[in] memspace Memory space the operation is computed in (HOST or + * DEVICE) * * @return dot product of _x_ and _y_ */ template - ScalarT VectorHandler::dot(Vector* x, Vector* y, memory::MemorySpace memspace) + ScalarT VectorHandler::dot( + Vector* x, + Vector* y, + memory::MemorySpace memspace + ) { switch (memspace) { case memory::HOST: return cpuImpl_.dot(x, y); case memory::DEVICE: - Log::error() << "VectorHandler::dot - DEVICE memory space not yet supported\n"; + Log::error( + ) << "VectorHandler::dot - DEVICE memory space not yet supported\n"; return static_cast(NAN); } return static_cast(NAN); } /** - * @brief scale a vector by a constant i.e, x = alpha*x where alpha is a constant + * @brief scale a vector by a constant i.e, x = alpha*x where alpha is a + * constant * * @param[in] alpha The constant * @param[in,out] x The vector - * @param[in] memspace Memory space the operation is computed in (HOST or DEVICE) + * @param[in] memspace Memory space the operation is computed in (HOST or + * DEVICE) */ template - void VectorHandler::scal(const ScalarT alpha, Vector* x, memory::MemorySpace memspace) + void VectorHandler::scal( + const ScalarT alpha, + Vector* x, + memory::MemorySpace memspace + ) { switch (memspace) { @@ -51,28 +63,34 @@ namespace GridKit cpuImpl_.scal(alpha, x); break; case memory::DEVICE: - Log::error() << "VectorHandler::scal - DEVICE memory space not yet supported\n"; + Log::error( + ) << "VectorHandler::scal - DEVICE memory space not yet supported\n"; break; } } /** - * @brief compute infinity norm of a vector (i.e., find an entry with largest absolute value) + * @brief compute infinity norm of a vector (i.e., find an entry with + * largest absolute value) * * @param[in] x The vector - * @param[in] memspace Memory space the operation is computed in (HOST or DEVICE) + * @param[in] memspace Memory space the operation is computed in (HOST or + * DEVICE) * * @return infinity norm of _x_ */ template - ScalarT VectorHandler::amax(Vector* x, memory::MemorySpace memspace) + ScalarT VectorHandler::amax( + Vector* x, memory::MemorySpace memspace + ) { switch (memspace) { case memory::HOST: return cpuImpl_.amax(x); case memory::DEVICE: - Log::error() << "VectorHandler::amax - DEVICE memory space not yet supported\n"; + Log::error( + ) << "VectorHandler::amax - DEVICE memory space not yet supported\n"; return static_cast(NAN); } return static_cast(NAN); @@ -84,7 +102,8 @@ namespace GridKit * @param[in] alpha The constant * @param[in] x The first vector * @param[in,out] y The second vector (result is returned in y) - * @param[in] memspace Memory space the operation is computed in (HOST or DEVICE) + * @param[in] memspace Memory space the operation is computed in (HOST or + * DEVICE) */ template void VectorHandler::axpy( @@ -100,7 +119,8 @@ namespace GridKit cpuImpl_.axpy(alpha, x, y); break; case memory::DEVICE: - Log::error() << "VectorHandler::axpy - DEVICE memory space not yet supported\n"; + Log::error( + ) << "VectorHandler::axpy - DEVICE memory space not yet supported\n"; break; } } @@ -114,13 +134,16 @@ namespace GridKit * where `x` is `[k x 1]`, `V` is `[n x k]` and `y` is `[n x 1]`. * * @param[in] transpose - yes (T) or no (N) - * @param[in] k - Number of columns in (non-transposed) matrix to use + * @param[in] k - Number of columns in (non-transposed) matrix to + * use * @param[in] alpha - Constant scalar * @param[in] beta - Constant scalar - * @param[in] V - Multivector containing the matrix, organized columnwise + * @param[in] V - Multivector containing the matrix, organized + * columnwise * @param[in] y - Vector, k x 1 if N and n x 1 if T * @param[in,out] x - Vector, n x 1 if N and k x 1 if T - * @param[in] memspace - Memory space the operation is computed in (HOST or DEVICE) + * @param[in] memspace - Memory space the operation is computed in (HOST or + * DEVICE) * * @note Parameter k is not the total number of columns in V but the number * of columns to use in matrix-vector product. @@ -143,7 +166,8 @@ namespace GridKit cpuImpl_.gemv(transpose, k, alpha, beta, V, y, x); break; case memory::DEVICE: - Log::error() << "VectorHandler::gemv - DEVICE memory space not yet supported\n"; + Log::error( + ) << "VectorHandler::gemv - DEVICE memory space not yet supported\n"; break; } } @@ -155,8 +179,10 @@ namespace GridKit * @param[in] alpha vector size k x 1 * @param[in] k number of vectors in the multivector x * @param[in] x (multi)vector [size x k] - * @param[in,out] y vector size size x 1 (this is where the result is stored) - * @param[in] memspace Memory space the operation is computed in (HOST or DEVICE) + * @param[in,out] y vector size size x 1 (this is where the result is + * stored) + * @param[in] memspace Memory space the operation is computed in (HOST or + * DEVICE) * * @pre _k_ > 0, _size_ > 0, _size_ = x->getSize() */ @@ -179,7 +205,8 @@ namespace GridKit cpuImpl_.axpyMulti(size, alpha, k, x, y); break; case memory::DEVICE: - Log::error() << "VectorHandler::axpyMulti - DEVICE memory space not yet supported\n"; + Log::error() << "VectorHandler::axpyMulti - DEVICE memory space not " + "yet supported\n"; break; } } @@ -187,14 +214,16 @@ namespace GridKit /** * @brief Multivector dot product, i.e V^T x * - * Computes V^T x with k vectors from multivector V. Result is stored in `res`. + * Computes V^T x with k vectors from multivector V. Result is stored in + * `res`. * * @param[in] size - Number of elements in a single vector in V * @param[in] V - Multivector; k vectors of size n x 1 each * @param[in] k - Number of vectors in V to use * @param[in] x - Multivector; 2 vectors of size n x 1 each * @param[out] res - Multivector; 2 vectors size k x 1 each - * @param[in] memspace - Memory space the operation is computed in (HOST or DEVICE) + * @param[in] memspace - Memory space the operation is computed in (HOST or + * DEVICE) * * @pre _size_ > 0, _k_ > 0, size = x->getSize(). * @pre _res_ needs to be allocated to k x 2 size. @@ -209,7 +238,9 @@ namespace GridKit memory::MemorySpace memspace ) { - assert(x->getSize() == V->getSize() && "Sizes of V and x do not match!\n"); + assert( + x->getSize() == V->getSize() && "Sizes of V and x do not match!\n" + ); assert(res->getSize() == k && "Size of `res` must match k!\n"); switch (memspace) @@ -218,7 +249,8 @@ namespace GridKit cpuImpl_.dot2Multi(size, V, k, x, res); break; case memory::DEVICE: - Log::error() << "VectorHandler::dot2Multi - DEVICE memory space not yet supported\n"; + Log::error() << "VectorHandler::dot2Multi - DEVICE memory space not " + "yet supported\n"; break; } } @@ -228,14 +260,22 @@ namespace GridKit * * @param[in] diag - vector representing the diagonal matrix * @param[in,out] vec - vector to be scaled - * @param[in] memspace - Memory space the operation is computed in (HOST or DEVICE) + * @param[in] memspace - Memory space the operation is computed in (HOST or + * DEVICE) * * @pre The diagonal vector must be of the same size as the vector. */ template - void VectorHandler::scal(Vector* diag, Vector* vec, memory::MemorySpace memspace) + void VectorHandler::scal( + Vector* diag, + Vector* vec, + memory::MemorySpace memspace + ) { - assert(diag->getSize() == vec->getSize() && "Diagonal vector must be of the same size as the vector."); + assert( + diag->getSize() == vec->getSize() + && "Diagonal vector must be of the same size as the vector." + ); switch (memspace) { @@ -243,18 +283,22 @@ namespace GridKit cpuImpl_.scal(diag, vec); break; case memory::DEVICE: - Log::error() << "VectorHandler::scal - DEVICE memory space not yet supported\n"; + Log::error( + ) << "VectorHandler::scal - DEVICE memory space not yet supported\n"; break; } } /** - * @brief Scale a vector by a diagonal matrix represented by a contiguous subvector of an input vector + * @brief Scale a vector by a diagonal matrix represented by a contiguous + * subvector of an input vector * * @param[in] diag - vector representing the diagonal matrix * @param[in,out] vec - vector to be scaled - * @param[in] diag_offset - the index of diag where the diagonal matrix begins (inclusive) - * @param[in] memspace - Memory space the operation is computed in (HOST or DEVICE) + * @param[in] diag_offset - the index of diag where the diagonal matrix + * begins (inclusive) + * @param[in] memspace - Memory space the operation is computed in (HOST or + * DEVICE) */ template void VectorHandler::scal( @@ -270,7 +314,8 @@ namespace GridKit cpuImpl_.scal(diag, vec, diag_offset); break; case memory::DEVICE: - Log::error() << "VectorHandler::scal - DEVICE memory space not yet supported\n"; + Log::error( + ) << "VectorHandler::scal - DEVICE memory space not yet supported\n"; break; } } @@ -280,23 +325,32 @@ namespace GridKit * * @param[in] diag - diagonal matrix stored in a vector object * @param[in,out] vec - vector to be divided - * @param[in] memspace - Memory space the operation is computed in (HOST or DEVICE) + * @param[in] memspace - Memory space the operation is computed in (HOST or + * DEVICE) * * @pre The two vectors must be the same size * * @return 0 if successful, 1 otherwise */ template - int VectorHandler::diagSolve(Vector* diag, Vector* vec, memory::MemorySpace memspace) + int VectorHandler::diagSolve( + Vector* diag, + Vector* vec, + memory::MemorySpace memspace + ) { - assert(diag->getSize() == vec->getSize() && "Diagonal vector must be of the same size as the vector."); + assert( + diag->getSize() == vec->getSize() + && "Diagonal vector must be of the same size as the vector." + ); switch (memspace) { case memory::HOST: return cpuImpl_.diagSolve(diag, vec); case memory::DEVICE: - Log::error() << "VectorHandler::diagSolve - DEVICE memory space not yet supported\n"; + Log::error() << "VectorHandler::diagSolve - DEVICE memory space not " + "yet supported\n"; return 1; } return 1; @@ -308,24 +362,33 @@ namespace GridKit * @param[in] x - The first vector * @param[in] y - The second vector * @param[out] out - The output vector - * @param[in] memspace - Memory space the operation is computed in (HOST or DEVICE) + * @param[in] memspace - Memory space the operation is computed in (HOST or + * DEVICE) * * @pre The two vectors must be the same size * * @return 0 if successful, 1 otherwise */ template - int VectorHandler::max(Vector* x, Vector* y, Vector* out, memory::MemorySpace memspace) + int VectorHandler::max( + Vector* x, + Vector* y, + Vector* out, + memory::MemorySpace memspace + ) { assert(x->getSize() == y->getSize() && "Vectors must be the same size."); - assert(x->getSize() == out->getSize() && "Vectors must be the same size."); + assert( + x->getSize() == out->getSize() && "Vectors must be the same size." + ); switch (memspace) { case memory::HOST: return cpuImpl_.max(x, y, out); case memory::DEVICE: - GridKit::LinearAlgebra::Log::error() << "VectorHandler::max - DEVICE memory space not yet supported\n"; + GridKit::LinearAlgebra::Log::error() + << "VectorHandler::max - DEVICE memory space not yet supported\n"; return 1; } return 1; @@ -336,12 +399,17 @@ namespace GridKit * * @param[in] in - Input vector * @param[out] out - Output vector - * @param[in] memspace - Memory space the operation is computed in (HOST or DEVICE) + * @param[in] memspace - Memory space the operation is computed in (HOST or + * DEVICE) * * @return 0 if successful, 1 otherwise */ template - int VectorHandler::abs(Vector* in, Vector* out, memory::MemorySpace memspace) + int VectorHandler::abs( + Vector* in, + Vector* out, + memory::MemorySpace memspace + ) { assert(in->getSize() == out->getSize() && "Vector sizes do not match!\n"); @@ -350,7 +418,8 @@ namespace GridKit case memory::HOST: return cpuImpl_.abs(in, out); case memory::DEVICE: - GridKit::LinearAlgebra::Log::error() << "VectorHandler::abs - DEVICE memory space not yet supported\n"; + GridKit::LinearAlgebra::Log::error() + << "VectorHandler::abs - DEVICE memory space not yet supported\n"; return 1; } return 1; diff --git a/GridKit/LinearAlgebra/Vector/VectorHandler.hpp b/GridKit/LinearAlgebra/Vector/VectorHandler.hpp index 4be5ec11e2..5f6c08cd96 100644 --- a/GridKit/LinearAlgebra/Vector/VectorHandler.hpp +++ b/GridKit/LinearAlgebra/Vector/VectorHandler.hpp @@ -37,13 +37,26 @@ namespace GridKit ); // Dot product of two vectors - ScalarT dot(Vector* x, Vector* y, memory::MemorySpace memspace); + ScalarT dot( + Vector* x, + Vector* y, + memory::MemorySpace memspace + ); // Scale vector by scalar - void scal(const ScalarT alpha, Vector* x, memory::MemorySpace memspace); + void scal( + const ScalarT alpha, + Vector* x, + memory::MemorySpace memspace + ); - // Scale vector by diagonal matrix represented as a vector (i.e., vec = diag*vec) - void scal(Vector* diag, Vector* vec, memory::MemorySpace memspace); + // Scale vector by diagonal matrix represented as a vector (i.e., vec = + // diag*vec) + void scal( + Vector* diag, + Vector* vec, + memory::MemorySpace memspace + ); void scal( Vector* diag, Vector* vec, @@ -72,18 +85,33 @@ namespace GridKit ); // Dense matrix-vector product. - void gemv(char transpose, - IdxT k, // number of vectors from multivector V to use - const ScalarT alpha, - const ScalarT beta, - Vector* V, - Vector* y, - Vector* x, - memory::MemorySpace memspace); + void gemv( + char transpose, + IdxT k, // number of vectors from multivector V to use + const ScalarT alpha, + const ScalarT beta, + Vector* V, + Vector* y, + Vector* x, + memory::MemorySpace memspace + ); - int diagSolve(Vector* diag, Vector* vec, memory::MemorySpace memspace); - int max(Vector* x, Vector* y, Vector* out, memory::MemorySpace memspace); - int abs(Vector* in, Vector* out, memory::MemorySpace memspace); + int diagSolve( + Vector* diag, + Vector* vec, + memory::MemorySpace memspace + ); + int max( + Vector* x, + Vector* y, + Vector* out, + memory::MemorySpace memspace + ); + int abs( + Vector* in, + Vector* out, + memory::MemorySpace memspace + ); // Vector infinity norm ScalarT amax(Vector* x, memory::MemorySpace memspace); diff --git a/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.cpp b/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.cpp index 68826d1a38..e53170dfdf 100644 --- a/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.cpp +++ b/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.cpp @@ -21,7 +21,9 @@ namespace GridKit * @return dot product of _x_ and _y_ */ template - ScalarT VectorHandlerCpu::dot(Vector* x, Vector* y) + ScalarT VectorHandlerCpu::dot( + Vector* x, Vector* y + ) { const ScalarT* x_data = x->getData(memory::HOST); const ScalarT* y_data = y->getData(memory::HOST); @@ -39,13 +41,16 @@ namespace GridKit } /** - * @brief scale a vector by a constant i.e, x = alpha*x where alpha is a constant + * @brief scale a vector by a constant i.e, x = alpha*x where alpha is a + * constant * * @param[in] alpha The constant * @param[in,out] x The vector */ template - void VectorHandlerCpu::scal(const ScalarT alpha, Vector* x) + void VectorHandlerCpu::scal( + const ScalarT alpha, Vector* x + ) { ScalarT* x_data = x->getData(memory::HOST); @@ -57,7 +62,8 @@ namespace GridKit } /** - * @brief compute infinity norm of a vector (i.e., find an entry with largest absolute value) + * @brief compute infinity norm of a vector (i.e., find an entry with + * largest absolute value) * * @param[in] x vector * @@ -89,7 +95,9 @@ namespace GridKit * @param[in,out] y The second vector (result is returned in y) */ template - void VectorHandlerCpu::axpy(const ScalarT alpha, Vector* x, Vector* y) + void VectorHandlerCpu::axpy( + const ScalarT alpha, Vector* x, Vector* y + ) { ScalarT* x_data = x->getData(memory::HOST); ScalarT* y_data = y->getData(memory::HOST); @@ -101,8 +109,8 @@ namespace GridKit } /** - * @brief gemv computes matrix-vector product where the matrix and vectors are dense. - * i.e., x = beta*x + alpha*V*y + * @brief gemv computes matrix-vector product where the matrix and vectors + * are dense. i.e., x = beta*x + alpha*V*y * * @param[in] transpose - transposed = 'T' or not 'N' * @param[in] k Number of columns in (non-transposed) matrix to use @@ -180,7 +188,8 @@ namespace GridKit break; default: Log::error() << "Unrecognized transpose option " << transpose - << " in gemv. Valid options are 'N' (not transposed) and 'T' (transposed).\n"; + << " in gemv. Valid options are 'N' (not transposed) and " + "'T' (transposed).\n"; } // switch x->setDataUpdated(memory::HOST); } @@ -191,7 +200,8 @@ namespace GridKit * @param[in] size number of elements in y * @param[in] alpha vector size k x 1 * @param[in] x (multi)vector size size x k - * @param[in,out] y vector size size x 1 (this is where the result is stored) + * @param[in,out] y vector size size x 1 (this is where the result is + * stored) * * @pre _k_ > 0, _size_ > 0, _size_ = x->getSize() */ @@ -223,17 +233,20 @@ namespace GridKit } /** - * @brief mass (bulk) dot product i.e, V^T x, where V is n x k dense multivector (a dense - * multivector consisting of k vectors size n) and x is k x 2 dense multivector (a multivector - * consisting of two vectors size n each) + * @brief mass (bulk) dot product i.e, V^T x, where V is n x k dense + * multivector (a dense multivector consisting of k vectors size n) and x is + * k x 2 dense multivector (a multivector consisting of two vectors size n + * each) * * @param[in] size Number of elements in a single vector in V * @param[in] V Multivector; k vectors size n x 1 each * @param[in] k Number of vectors in V * @param[in] x Multivector; 2 vectors size n x 1 each - * @param[out] res Multivector; 2 vectors size k x 1 each (result is returned in res) + * @param[out] res Multivector; 2 vectors size k x 1 each (result is + * returned in res) * - * @pre _size_ > 0, _k_ > 0, size = x->getSize(), _res_ needs to be allocated + * @pre _size_ > 0, _k_ > 0, size = x->getSize(), _res_ needs to be + * allocated */ template void VectorHandlerCpu::dot2Multi( @@ -280,7 +293,9 @@ namespace GridKit * @param[in,out] vec Vector to be scaled */ template - void VectorHandlerCpu::scal(Vector* diag, Vector* vec) + void VectorHandlerCpu::scal( + Vector* diag, Vector* vec + ) { const ScalarT* diag_data = diag->getData(memory::HOST); ScalarT* vec_data = vec->getData(memory::HOST); @@ -294,14 +309,18 @@ namespace GridKit } /** - * @brief Scale a vector by a diagonal matrix represented by a contiguous subvector of diag + * @brief Scale a vector by a diagonal matrix represented by a contiguous + * subvector of diag * * @param[in] diag Diagonal vector * @param[in,out] vec Vector to be scaled - * @param[in] diag_offset - the index of diag where the diagonal matrix begins + * @param[in] diag_offset - the index of diag where the diagonal matrix + * begins */ template - void VectorHandlerCpu::scal(Vector* diag, Vector* vec, IdxT diag_offset) + void VectorHandlerCpu::scal( + Vector* diag, Vector* vec, IdxT diag_offset + ) { const ScalarT* diag_data = &diag->getData(memory::HOST)[diag_offset]; ScalarT* vec_data = vec->getData(memory::HOST); @@ -328,7 +347,9 @@ namespace GridKit * @return 0 if successful, 1 otherwise */ template - int VectorHandlerCpu::diagSolve(Vector* diag, Vector* vec) + int VectorHandlerCpu::diagSolve( + Vector* diag, Vector* vec + ) { ScalarT* diag_data = diag->getData(memory::HOST); ScalarT* vec_data = vec->getData(memory::HOST); @@ -344,8 +365,8 @@ namespace GridKit /** * @brief Take the element-wise max of two vectors. - * Each element of the output will be the maximum value of the corresponding elements in the - * input vectors. + * Each element of the output will be the maximum value of the corresponding + * elements in the input vectors. * * @param[in] x - First input vector * @param[in] y - Second input vector @@ -356,7 +377,11 @@ namespace GridKit * @return 0 if successful, 1 otherwise */ template - int VectorHandlerCpu::max(Vector* x, Vector* y, Vector* out) + int VectorHandlerCpu::max( + Vector* x, + Vector* y, + Vector* out + ) { const ScalarT* x_data = x->getData(memory::HOST); const ScalarT* y_data = y->getData(memory::HOST); @@ -380,7 +405,9 @@ namespace GridKit * @return 0 if successful, 1 otherwise */ template - int VectorHandlerCpu::abs(Vector* in, Vector* out) + int VectorHandlerCpu::abs( + Vector* in, Vector* out + ) { const ScalarT* in_data = in->getData(memory::HOST); ScalarT* out_data = out->getData(memory::HOST); diff --git a/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.hpp b/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.hpp index 2e9e022668..d5a7562c00 100644 --- a/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.hpp +++ b/GridKit/LinearAlgebra/Vector/VectorHandlerCpu.hpp @@ -25,7 +25,9 @@ namespace GridKit ~VectorHandlerCpu() = default; // y = alpha * x + y - void axpy(const ScalarT alpha, Vector* x, Vector* y); + void axpy( + const ScalarT alpha, Vector* x, Vector* y + ); // dot: x \cdot y ScalarT dot(Vector* x, Vector* y); @@ -36,11 +38,25 @@ namespace GridKit // vector infinity norm ScalarT amax(Vector* x); - // mass axpy: y = y - x*alpha, where x is [n x k] and alpha is [k x 1]; x is stored columnwise - void axpyMulti(IdxT size, Vector* alpha, IdxT k, Vector* x, Vector* y); + // mass axpy: y = y - x*alpha, where x is [n x k] and alpha is [k x 1]; x + // is stored columnwise + void axpyMulti( + IdxT size, + Vector* alpha, + IdxT k, + Vector* x, + Vector* y + ); - // mass dot: V^T x, where V is [n x k] and x is [k x 2], everything is stored and returned columnwise - void dot2Multi(IdxT size, Vector* V, IdxT k, Vector* x, Vector* res); + // mass dot: V^T x, where V is [n x k] and x is [k x 2], everything is + // stored and returned columnwise + void dot2Multi( + IdxT size, + Vector* V, + IdxT k, + Vector* x, + Vector* res + ); /** gemv: * if `transpose = N` (no), `x = beta*x + alpha*V*y`, @@ -60,13 +76,21 @@ namespace GridKit // Scale a vector by a diagonal matrix void scal(Vector* diag, Vector* vec); - void scal(Vector* diag, Vector* vec, IdxT diag_offset); + void scal( + Vector* diag, + Vector* vec, + IdxT diag_offset + ); // Divide the elements of a vector by the elements of another vector int diagSolve(Vector* diag, Vector* vec); // Compute element-wise max of two vectors - int max(Vector* x, Vector* y, Vector* out); + int max( + Vector* x, + Vector* y, + Vector* out + ); // Compute element-wise absolute value of a vector int abs(Vector* in, Vector* out); diff --git a/GridKit/MemoryUtilities/MemoryUtils.hpp b/GridKit/MemoryUtilities/MemoryUtils.hpp index 4e6c7bf305..0c0836ea3b 100644 --- a/GridKit/MemoryUtilities/MemoryUtils.hpp +++ b/GridKit/MemoryUtilities/MemoryUtils.hpp @@ -152,7 +152,8 @@ namespace GridKit #ifdef GridKit_ENABLE_GPU -// Check if GPU support is enabled in GridKit and set appropriate device memory manager. +// Check if GPU support is enabled in GridKit and set appropriate device memory +// manager. #if defined GridKit_ENABLE_CUDA #include #elif defined GridKit_ENABLE_HIP diff --git a/GridKit/MemoryUtilities/cpu/CpuMemory.hpp b/GridKit/MemoryUtilities/cpu/CpuMemory.hpp index b47c5e767d..8548de19c0 100644 --- a/GridKit/MemoryUtilities/cpu/CpuMemory.hpp +++ b/GridKit/MemoryUtilities/cpu/CpuMemory.hpp @@ -44,7 +44,8 @@ namespace GridKit */ static int deleteOnDevice(void* /* v */) { - Log::error() << "Trying to delete on a GPU device, but GPU support not available.\n"; + Log::error() << "Trying to delete on a GPU device, but GPU support not " + "available.\n"; return -1; } @@ -59,7 +60,8 @@ namespace GridKit template static int allocateArrayOnDevice(T** /* v */, I /* n */) { - Log::error() << "Trying to allocate on a GPU device, but GPU support not available.\n"; + Log::error() << "Trying to allocate on a GPU device, but GPU support " + "not available.\n"; return -1; } @@ -74,7 +76,8 @@ namespace GridKit template static int allocateBufferOnDevice(T** /* v */, I /* n */) { - Log::error() << "Trying to allocate on a GPU device, but GPU support not available.\n"; + Log::error() << "Trying to allocate on a GPU device, but GPU support " + "not available.\n"; return -1; } @@ -89,7 +92,8 @@ namespace GridKit template static int setZeroArrayOnDevice(T* /* v */, I /* n */) { - Log::error() << "Trying to initialize array on a GPU device, but GPU support not available.\n"; + Log::error() << "Trying to initialize array on a GPU device, but GPU " + "support not available.\n"; return -1; } @@ -104,7 +108,8 @@ namespace GridKit template static int setArrayToConstOnDevice(T* /* v */, T /* c */, I /* n */) { - Log::error() << "Trying to initialize array on a GPU device, but GPU support not available.\n"; + Log::error() << "Trying to initialize array on a GPU device, but GPU " + "support not available.\n"; return -1; } @@ -117,9 +122,11 @@ namespace GridKit * @return Always return failure! */ template - static int copyArrayDeviceToHost(T* /* dst */, const T* /* src */, I /* n */) + static int + copyArrayDeviceToHost(T* /* dst */, const T* /* src */, I /* n */) { - Log::error() << "Trying to copy from a GPU device, but GPU support not available.\n"; + Log::error() << "Trying to copy from a GPU device, but GPU support not " + "available.\n"; return -1; } @@ -132,16 +139,20 @@ namespace GridKit * @return Always return failure! */ template - static int copyArrayDeviceToDevice(T* /* dst */, const T* /* src */, I /* n */) + static int + copyArrayDeviceToDevice(T* /* dst */, const T* /* src */, I /* n */) { - Log::error() << "Trying to copy to a GPU device, but GPU support not available.\n"; + Log::error( + ) << "Trying to copy to a GPU device, but GPU support not available.\n"; return -1; } template - static int copyArrayHostToDevice(T* /* dst */, const T* /* src */, I /* n */) + static int + copyArrayHostToDevice(T* /* dst */, const T* /* src */, I /* n */) { - Log::error() << "Trying to copy to a GPU device, but GPU support not available.\n"; + Log::error( + ) << "Trying to copy to a GPU device, but GPU support not available.\n"; return -1; } }; // struct Cpu diff --git a/GridKit/Model/Evaluator.hpp b/GridKit/Model/Evaluator.hpp index 11d88c1e29..d1c2c686c2 100644 --- a/GridKit/Model/Evaluator.hpp +++ b/GridKit/Model/Evaluator.hpp @@ -39,17 +39,19 @@ namespace GridKit /** * @brief Allocate all internal memory used by the model. * - * @post Changing the model by changing its internal topology (i.e. \ref size(), \ref nnz(), sparsity pattern - * in \ref getCsrJacobian(), etc.) may invalidate the model until `allocate()` is called again. Calling any - * function that requires `allocate()` to be called in between modifying the model and reallocating may invoke - * undefined behaviour. + * @post Changing the model by changing its internal topology (i.e. \ref + * size(), \ref nnz(), sparsity pattern in \ref getCsrJacobian(), etc.) + * may invalidate the model until `allocate()` is called again. Calling + * any function that requires `allocate()` to be called in between + * modifying the model and reallocating may invoke undefined behaviour. */ virtual int allocate() = 0; virtual int initialize() = 0; /** * @brief Fill the \ref tag() vector with proper indicators. * - * @note For some models, this may be a no-op, and the vector returned by \ref tag() will still be empty. + * @note For some models, this may be a no-op, and the vector returned by + * \ref tag() will still be empty. * * @pre \ref allocate() must have been called. */ @@ -69,11 +71,14 @@ namespace GridKit /** * @brief Evaluate the model's residual function. * - * For models which can be appropriately modeled in semi-explicit form, this will evaluate + * For models which can be appropriately modeled in semi-explicit form, + * this will evaluate * \f[F(t, y, \dot{y}) = f(t,y) - M \dot{y},\f] - * where \f(M\f) is the mass matrix. For models which can be modeled in Hessenberg form, - * \f(M\f) should be a simple indicator function for if the variable is differential - * (if \f(\dot{y}\f) appears in its equation). This indicator should be given by \ref tag(). + * where \f(M\f) is the mass matrix. For models which can be modeled in + * Hessenberg form, + * \f(M\f) should be a simple indicator function for if the variable is + * differential (if \f(\dot{y}\f) appears in its equation). This indicator + * should be given by \ref tag(). */ virtual int evaluateResidual() = 0; virtual int evaluateJacobian() = 0; @@ -89,8 +94,9 @@ namespace GridKit /** * @brief How many non-zero elements are in this model's Jacobian. * - * This knowledge may be needed to allocate the buffers for the model's Jacobian, so it - * it should not depend on \ref allocate() having been called. + * This knowledge may be needed to allocate the buffers for the model's + * Jacobian, so it it should not depend on \ref allocate() having been + * called. * * @see getCsrJacobian() */ @@ -144,7 +150,8 @@ namespace GridKit } /** - * @brief Is the Jacobian defined. Used in IDA to determine whether DQ is used or not + * @brief Is the Jacobian defined. Used in IDA to determine whether DQ is + * used or not * * @return true * @return false @@ -179,10 +186,13 @@ namespace GridKit virtual const VectorT& yp() const = 0; /** - * @brief An indicator for which variables in the model are differential (true) or algebraic (false). + * @brief An indicator for which variables in the model are differential + * (true) or algebraic (false). * - * This information may be required for certain integrator features (such as the \ref AnalysisManager::NativeDynamicSolver::Rosenbrock - * integrator), but is not required to be set. A reference to an empty vector may be returned. + * This information may be required for certain integrator features (such + * as the \ref AnalysisManager::NativeDynamicSolver::Rosenbrock + * integrator), but is not required to be set. A reference to an empty + * vector may be returned. * * @pre \ref tagDifferentiable() must have been called. */ diff --git a/GridKit/Model/EvaluatorTraits.hpp b/GridKit/Model/EvaluatorTraits.hpp index 727e2b8135..fe23ccd7ca 100644 --- a/GridKit/Model/EvaluatorTraits.hpp +++ b/GridKit/Model/EvaluatorTraits.hpp @@ -28,7 +28,9 @@ namespace GridKit { private: template - static Evaluator probe(const Evaluator&); + static Evaluator probe(const Evaluator< + scalar_type, + index_type>&); public: using EvaluatorT = decltype(probe(std::declval())); diff --git a/GridKit/Model/OptimalPowerFlow/Branch/Branch.hpp b/GridKit/Model/OptimalPowerFlow/Branch/Branch.hpp index b0b8b317bd..2b3087b3ce 100644 --- a/GridKit/Model/OptimalPowerFlow/Branch/Branch.hpp +++ b/GridKit/Model/OptimalPowerFlow/Branch/Branch.hpp @@ -32,7 +32,8 @@ namespace GridKit S2, ///< \f$P_2^2 + Q_2^2\f$ Squared apparent power at bus 2 [p.u.] }; - /// External constraint contributions of a `Branch`, the power into the buses at its ports + /// External constraint contributions of a `Branch`, the power into the + /// buses at its ports enum class BranchExternalConstraints : size_t { DP1, ///< \f$\Delta P_1^\mathrm{bus}\f$ Active power into bus 1 [p.u.] @@ -41,7 +42,8 @@ namespace GridKit DQ2, ///< \f$\Delta Q_2^\mathrm{bus}\f$ Reactive power into bus 2 [p.u.] }; - /// Line or off-nominal transformer between two buses, with power positive into the buses + /// Line or off-nominal transformer between two buses, with power positive + /// into the buses template class Branch final : public Component { @@ -80,14 +82,19 @@ namespace GridKit int evaluateJacobian() override; int evaluateHessian(RealT sigma) override; - [[gnu::always_inline]] void internalConstraints(const ScalarT* x, const ScalarT* external, ScalarT* g) const override; - [[gnu::always_inline]] void externalConstraints(const ScalarT* x, const ScalarT* external, ScalarT* g) const override; + [[gnu::always_inline]] void internalConstraints( + const ScalarT* x, const ScalarT* external, ScalarT* g + ) const override; + [[gnu::always_inline]] void externalConstraints( + const ScalarT* x, const ScalarT* external, ScalarT* g + ) const override; private: void initializeParameters(const ModelDataT& data); void setDerivedParameters(); - [[gnu::always_inline]] void power(const ScalarT* external, ScalarT* s) const; + [[gnu::always_inline]] void power(const ScalarT* external, ScalarT* s) + const; RealT R_{ZERO}; RealT X_{ZERO}; diff --git a/GridKit/Model/OptimalPowerFlow/Branch/BranchData.hpp b/GridKit/Model/OptimalPowerFlow/Branch/BranchData.hpp index 93d06fdef9..ac1ff499ed 100644 --- a/GridKit/Model/OptimalPowerFlow/Branch/BranchData.hpp +++ b/GridKit/Model/OptimalPowerFlow/Branch/BranchData.hpp @@ -16,15 +16,19 @@ namespace GridKit /// Parameters for a branch enum class BranchParameters : size_t { - R, ///< \f$R\f$ Series resistance [p.u.] - X, ///< \f$X\f$ Series reactance [p.u.] - G, ///< \f$G\f$ Total line shunt conductance, split between the ports [p.u.] - B, ///< \f$B\f$ Total line shunt susceptance, split between the ports [p.u.] - Gmag, ///< \f$G_\mathrm{mag}\f$ Magnetizing shunt conductance at bus 1 [p.u.] - Bmag, ///< \f$B_\mathrm{mag}\f$ Magnetizing shunt susceptance at bus 1 [p.u.] - tap, ///< \f$\tau\f$ Off-nominal tap magnitude on the bus-1 side [p.u.] - phase, ///< \f$\theta\f$ Phase-shift angle [rad] - Smax, ///< \f$S^{\max}\f$ Apparent power limit at each port [p.u.] + R, ///< \f$R\f$ Series resistance [p.u.] + X, ///< \f$X\f$ Series reactance [p.u.] + G, ///< \f$G\f$ Total line shunt conductance, split between the ports + ///< [p.u.] + B, ///< \f$B\f$ Total line shunt susceptance, split between the ports + ///< [p.u.] + Gmag, ///< \f$G_\mathrm{mag}\f$ Magnetizing shunt conductance at bus 1 + ///< [p.u.] + Bmag, ///< \f$B_\mathrm{mag}\f$ Magnetizing shunt susceptance at bus 1 + ///< [p.u.] + tap, ///< \f$\tau\f$ Off-nominal tap magnitude on the bus-1 side [p.u.] + phase, ///< \f$\theta\f$ Phase-shift angle [rad] + Smax, ///< \f$S^{\max}\f$ Apparent power limit at each port [p.u.] in_service, ///< \f$u\f$ Service status }; @@ -37,6 +41,7 @@ namespace GridKit /// Data of a `Branch` template - using BranchData = ComponentData; + using BranchData = + ComponentData; } // namespace OptimalPowerFlow } // namespace GridKit diff --git a/GridKit/Model/OptimalPowerFlow/Branch/BranchDependencyTracking.cpp b/GridKit/Model/OptimalPowerFlow/Branch/BranchDependencyTracking.cpp index f4146f0a4f..7082671df1 100644 --- a/GridKit/Model/OptimalPowerFlow/Branch/BranchDependencyTracking.cpp +++ b/GridKit/Model/OptimalPowerFlow/Branch/BranchDependencyTracking.cpp @@ -1,7 +1,8 @@ /** * @file BranchDependencyTracking.cpp - * @brief Optimal power flow branch instantiation for `DependencyTracking::Variable`. - * Its derivatives come from the system model dependencies. + * @brief Optimal power flow branch instantiation for + * `DependencyTracking::Variable`. Its derivatives come from the system model + * dependencies. */ #include @@ -25,7 +26,9 @@ namespace GridKit } template - int Branch::evaluateHessian([[maybe_unused]] RealT sigma) + int Branch::evaluateHessian( + [[maybe_unused]] RealT sigma + ) { return 0; } diff --git a/GridKit/Model/OptimalPowerFlow/Branch/BranchImpl.hpp b/GridKit/Model/OptimalPowerFlow/Branch/BranchImpl.hpp index 302910466e..eb9c3638d9 100644 --- a/GridKit/Model/OptimalPowerFlow/Branch/BranchImpl.hpp +++ b/GridKit/Model/OptimalPowerFlow/Branch/BranchImpl.hpp @@ -28,7 +28,9 @@ namespace GridKit Model::ConfigurationChecks Branch::verify() const { Model::ConfigurationChecks checks("Branch"); - checks.check(R_ * R_ + X_ * X_ > ZERO, "R and X cannot both be zero"); + checks.check( + R_ * R_ + X_ * X_ > ZERO, "R and X cannot both be zero" + ); checks.check(tap_ > ZERO, "tap must be positive"); checks.check(Smax_ > ZERO, "Smax must be positive"); return checks; @@ -88,7 +90,9 @@ namespace GridKit } template - void Branch::initializeParameters(const ModelDataT& data) + void Branch::initializeParameters( + const ModelDataT& data + ) { using Params = BranchParameters; @@ -107,7 +111,8 @@ namespace GridKit setDerivedParameters(); } - /// Pi-model admittance with the tap and phase shift on the bus-1 side, zero out of service + /// Pi-model admittance with the tap and phase shift on the bus-1 side, zero + /// out of service template void Branch::setDerivedParameters() { @@ -136,8 +141,9 @@ namespace GridKit /// Power \f$P + jQ = V I^*\f$ into bus 1, then into bus 2 template - [[gnu::always_inline]] void - Branch::power(const ScalarT* external, ScalarT* s) const + [[gnu::always_inline]] void Branch::power( + const ScalarT* external, ScalarT* s + ) const { const auto VR1 = static_cast(BranchExternalVariables::VR1); const auto VI1 = static_cast(BranchExternalVariables::VI1); diff --git a/GridKit/Model/OptimalPowerFlow/Bus/Bus.hpp b/GridKit/Model/OptimalPowerFlow/Bus/Bus.hpp index 4a9b2c1876..a7f8068220 100644 --- a/GridKit/Model/OptimalPowerFlow/Bus/Bus.hpp +++ b/GridKit/Model/OptimalPowerFlow/Bus/Bus.hpp @@ -27,7 +27,8 @@ namespace GridKit { P, ///< Active power balance [p.u.] Q, ///< Reactive power balance [p.u.] - VM2, ///< \f$V_\mathrm{r}^2 + V_\mathrm{i}^2\f$ Squared voltage magnitude [p.u.] + VM2, ///< \f$V_\mathrm{r}^2 + V_\mathrm{i}^2\f$ Squared voltage magnitude + ///< [p.u.] }; /** @@ -59,9 +60,12 @@ namespace GridKit static constexpr std::array NUM_PORT_VARIABLES{}; static constexpr std::array NUM_PORT_CONSTRAINTS{}; - /// A port to the bus reads its voltage and contributes to its power balance, the constraints before `VM2` - static constexpr IdxT NUM_SHARED_VARIABLES = Utilities::enum_size(); - static constexpr IdxT NUM_SHARED_CONSTRAINTS = static_cast(BusInternalConstraints::VM2); + /// A port to the bus reads its voltage and contributes to its power + /// balance, the constraints before `VM2` + static constexpr IdxT NUM_SHARED_VARIABLES = + Utilities::enum_size(); + static constexpr IdxT NUM_SHARED_CONSTRAINTS = + static_cast(BusInternalConstraints::VM2); explicit Bus(const ModelDataT& data); @@ -73,7 +77,9 @@ namespace GridKit int evaluateJacobian() override; int evaluateHessian(RealT sigma) override; - [[gnu::always_inline]] void internalConstraints(const ScalarT* x, const ScalarT* external, ScalarT* g) const override; + [[gnu::always_inline]] void internalConstraints( + const ScalarT* x, const ScalarT* external, ScalarT* g + ) const override; /// Real voltage [p.u.] const ScalarT& Vr() const diff --git a/GridKit/Model/OptimalPowerFlow/Bus/BusDependencyTracking.cpp b/GridKit/Model/OptimalPowerFlow/Bus/BusDependencyTracking.cpp index defe563e33..a87d040870 100644 --- a/GridKit/Model/OptimalPowerFlow/Bus/BusDependencyTracking.cpp +++ b/GridKit/Model/OptimalPowerFlow/Bus/BusDependencyTracking.cpp @@ -1,7 +1,8 @@ /** * @file BusDependencyTracking.cpp - * @brief Optimal power flow bus instantiation for `DependencyTracking::Variable`. - * Its derivatives come from the system model dependencies. + * @brief Optimal power flow bus instantiation for + * `DependencyTracking::Variable`. Its derivatives come from the system model + * dependencies. */ #include @@ -25,7 +26,9 @@ namespace GridKit } template - int Bus::evaluateHessian([[maybe_unused]] RealT sigma) + int Bus::evaluateHessian( + [[maybe_unused]] RealT sigma + ) { return 0; } diff --git a/GridKit/Model/OptimalPowerFlow/Bus/BusImpl.hpp b/GridKit/Model/OptimalPowerFlow/Bus/BusImpl.hpp index c61f40556f..8505fa89d9 100644 --- a/GridKit/Model/OptimalPowerFlow/Bus/BusImpl.hpp +++ b/GridKit/Model/OptimalPowerFlow/Bus/BusImpl.hpp @@ -18,7 +18,9 @@ namespace GridKit { template Bus::Bus(const ModelDataT& data) - : ComponentT(std::type_identity{}, std::format("bus {}", data.number)) + : ComponentT( + std::type_identity{}, std::format("bus {}", data.number) + ) { initializeParameters(data); } @@ -74,7 +76,8 @@ namespace GridKit return 0; } - /// Shunt power into the bus, which starts its balance, and the squared voltage magnitude + /// Shunt power into the bus, which starts its balance, and the squared + /// voltage magnitude template [[gnu::always_inline]] void Bus:: internalConstraints( @@ -95,7 +98,9 @@ namespace GridKit } template - void Bus::initializeParameters(const ModelDataT& data) + void Bus::initializeParameters( + const ModelDataT& data + ) { using Params = BusParameters; diff --git a/GridKit/Model/OptimalPowerFlow/Component.hpp b/GridKit/Model/OptimalPowerFlow/Component.hpp index 3264948d6e..3b4ba8d432 100644 --- a/GridKit/Model/OptimalPowerFlow/Component.hpp +++ b/GridKit/Model/OptimalPowerFlow/Component.hpp @@ -66,7 +66,8 @@ namespace GridKit * system vectors and reads and adds to those of the components at its ports */ template - class Component : public Model::OptimizationEvaluator + class Component + : public Model::OptimizationEvaluator { friend class SystemModel; @@ -103,13 +104,13 @@ namespace GridKit Block offset{}; }; - /// Derivative entries in global indices, with room for the dense local block + /// Derivative entries in global indices, with room for the dense local + /// block struct CooBuffer { int resize(IdxT capacity) { - if (rows.resize(capacity) != 0 - || cols.resize(capacity) != 0 + if (rows.resize(capacity) != 0 || cols.resize(capacity) != 0 || values.resize(capacity) != 0) { return 1; @@ -296,10 +297,11 @@ namespace GridKit Block offset_; ///< Global index of each internal block bool bound_{false}; - VectorT local_x_; ///< Internal, then external variables - VectorT local_g_; ///< Internal, then external contributions - IndexVectorT variable_indices_; ///< Global column of each local variable - IndexVectorT constraint_indices_; ///< Global row of each local constraint contribution + VectorT local_x_; ///< Internal, then external variables + VectorT local_g_; ///< Internal, then external contributions + IndexVectorT variable_indices_; ///< Global column of each local variable + IndexVectorT constraint_indices_; ///< Global row of each local constraint + ///< contribution CooBuffer jacobian_entries_; CooBuffer hessian_entries_; }; diff --git a/GridKit/Model/OptimalPowerFlow/ComponentData.hpp b/GridKit/Model/OptimalPowerFlow/ComponentData.hpp index da9c89d248..4b7f3f0b02 100644 --- a/GridKit/Model/OptimalPowerFlow/ComponentData.hpp +++ b/GridKit/Model/OptimalPowerFlow/ComponentData.hpp @@ -17,11 +17,18 @@ namespace GridKit { /// Value of each parameter, typed as in the input file template - using ParameterMap = std::map>; - - /// Data of a device: its `id`, parameter values, and the bus number at each port - template - requires Utilities::SizedEnum && Utilities::SizedEnum + using ParameterMap = + std::map>; + + /// Data of a device: its `id`, parameter values, and the bus number at each + /// port + template < + typename real_type, + typename index_type, + typename parameters_enum, + typename ports_enum> + requires Utilities::SizedEnum + && Utilities::SizedEnum struct ComponentData { using RealT = real_type; diff --git a/GridKit/Model/OptimalPowerFlow/ComponentEnzyme.hpp b/GridKit/Model/OptimalPowerFlow/ComponentEnzyme.hpp index a4eb8451ca..3e8d784d0c 100644 --- a/GridKit/Model/OptimalPowerFlow/ComponentEnzyme.hpp +++ b/GridKit/Model/OptimalPowerFlow/ComponentEnzyme.hpp @@ -22,7 +22,8 @@ namespace GridKit { template template ModelT> - int Component::evaluateGradient(const ModelT& model) + int Component::evaluateGradient(const ModelT& model + ) { std::array().variables> x; std::array().variables> gradient; @@ -35,7 +36,8 @@ namespace GridKit template template ModelT> - int Component::evaluateJacobian(const ModelT& model) + int Component::evaluateJacobian(const ModelT& model + ) { if constexpr (localSize().constraints == 0) { @@ -66,7 +68,9 @@ namespace GridKit template template ModelT> - int Component::evaluateHessian(const ModelT& model, RealT sigma) + int Component::evaluateHessian( + const ModelT& model, RealT sigma + ) { std::array().variables> x; std::array().constraints> lambda; @@ -94,7 +98,9 @@ namespace GridKit /// Keep the entries on or below the diagonal, which the others mirror template - void Component::keepLowerTriangle(CooBuffer& entries) + void Component::keepLowerTriangle( + CooBuffer& entries + ) { IdxT* rows = entries.rows.getData(); IdxT* cols = entries.cols.getData(); diff --git a/GridKit/Model/OptimalPowerFlow/ComponentImpl.hpp b/GridKit/Model/OptimalPowerFlow/ComponentImpl.hpp index c7631c1b23..6a8165cd31 100644 --- a/GridKit/Model/OptimalPowerFlow/ComponentImpl.hpp +++ b/GridKit/Model/OptimalPowerFlow/ComponentImpl.hpp @@ -27,14 +27,18 @@ namespace GridKit { template template ModelT> - Component::Component(std::type_identity, std::string id) - : id_(std::move(id)), - size_(internalSize()) + Component::Component( + std::type_identity, std::string id + ) + : id_(std::move(id)), size_(internalSize()) { tag_.assign(size_.constraints, false); for (IdxT port = 0; port < ModelT::NUM_PORT_VARIABLES.size(); ++port) { - ports_.push_back({{ModelT::NUM_PORT_VARIABLES[port], ModelT::NUM_PORT_CONSTRAINTS[port]}}); + ports_.push_back( + {{ModelT::NUM_PORT_VARIABLES[port], ModelT::NUM_PORT_CONSTRAINTS[port] + }} + ); } constexpr Block local = localSize(); @@ -51,7 +55,9 @@ namespace GridKit } template - int Component::connect(IdxT port, Component& component, const Block& offset) + int Component::connect( + IdxT port, Component& component, const Block& offset + ) { if (bound_ || port >= ports_.size()) { @@ -95,29 +101,40 @@ namespace GridKit return 0; } - /// Copy the internal variables, then the variables each port reads from its component, into `x` + /// Copy the internal variables, then the variables each port reads from its + /// component, into `x` template void Component::gather(ScalarT* x) const { x = std::copy_n(x_.getData(), size_.variables, x); for (const Port& port : ports_) { - x = std::copy_n(port.component->x_.getData() + port.offset.variables, port.size.variables, x); + x = std::copy_n( + port.component->x_.getData() + port.offset.variables, + port.size.variables, + x + ); } } /// Multipliers of the internal, then each port's constraints template - void Component::gatherMultipliers(RealT* lambda) const + void Component::gatherMultipliers(RealT* lambda + ) const { lambda = std::copy_n(lambda_.getData(), size_.constraints, lambda); for (const Port& port : ports_) { - lambda = std::copy_n(port.component->lambda_.getData() + port.offset.constraints, port.size.constraints, lambda); + lambda = std::copy_n( + port.component->lambda_.getData() + port.offset.constraints, + port.size.constraints, + lambda + ); } } - /// Global column of each local variable and row of each local constraint contribution + /// Global column of each local variable and row of each local constraint + /// contribution template void Component::setIndices() { @@ -129,8 +146,16 @@ namespace GridKit rows += size_.constraints; for (const Port& port : ports_) { - std::iota(columns, columns + port.size.variables, port.component->offset_.variables + port.offset.variables); - std::iota(rows, rows + port.size.constraints, port.component->offset_.constraints + port.offset.constraints); + std::iota( + columns, + columns + port.size.variables, + port.component->offset_.variables + port.offset.variables + ); + std::iota( + rows, + rows + port.size.constraints, + port.component->offset_.constraints + port.offset.constraints + ); columns += port.size.variables; rows += port.size.constraints; } @@ -138,7 +163,9 @@ namespace GridKit /// Add the local gradient to the system gradient template - void Component::scatterGradient(const RealT* gradient) + void Component::scatterGradient( + const RealT* gradient + ) { RealT* own = gradient_.getData(); for (IdxT i = 0; i < size_.variables; ++i) @@ -147,7 +174,8 @@ namespace GridKit } for (const Port& port : ports_) { - RealT* target = port.component->gradient_.getData() + port.offset.variables; + RealT* target = + port.component->gradient_.getData() + port.offset.variables; for (IdxT i = 0; i < port.size.variables; ++i) { target[i] += *gradient++; @@ -157,7 +185,8 @@ namespace GridKit /// Add the local contributions to the system constraints template - void Component::scatterConstraints(const ScalarT* g) + void Component::scatterConstraints(const ScalarT* g + ) { ScalarT* own = g_.getData(); for (IdxT i = 0; i < size_.constraints; ++i) @@ -166,7 +195,8 @@ namespace GridKit } for (const Port& port : ports_) { - ScalarT* target = port.component->g_.getData() + port.offset.constraints; + ScalarT* target = + port.component->g_.getData() + port.offset.constraints; for (IdxT i = 0; i < port.size.constraints; ++i) { target[i] += *g++; diff --git a/GridKit/Model/OptimalPowerFlow/Generator/Generator.hpp b/GridKit/Model/OptimalPowerFlow/Generator/Generator.hpp index 45ac7fc7b9..a4eface8d1 100644 --- a/GridKit/Model/OptimalPowerFlow/Generator/Generator.hpp +++ b/GridKit/Model/OptimalPowerFlow/Generator/Generator.hpp @@ -23,7 +23,8 @@ namespace GridKit Q, ///< \f$Q\f$ Reactive power into the bus [p.u.] }; - /// External constraint contributions of a `Generator`, the power into its bus + /// External constraint contributions of a `Generator`, the power into its + /// bus enum class GeneratorExternalConstraints : size_t { DP, ///< \f$\Delta P^\mathrm{bus}\f$ Active power into the bus [p.u.] @@ -54,7 +55,8 @@ namespace GridKit using InternalConstraintsT = Utilities::EmptyEnum; using ExternalConstraintsT = GeneratorExternalConstraints; - static constexpr std::array()> NUM_PORT_VARIABLES{0}; + static constexpr std::array()> + NUM_PORT_VARIABLES{0}; static constexpr std::array()> NUM_PORT_CONSTRAINTS{BusT::NUM_SHARED_CONSTRAINTS}; @@ -67,8 +69,12 @@ namespace GridKit int evaluateJacobian() override; int evaluateHessian(RealT sigma) override; - [[gnu::always_inline]] ScalarT objective(const ScalarT* x, const ScalarT* external) const override; - [[gnu::always_inline]] void externalConstraints(const ScalarT* x, const ScalarT* external, ScalarT* g) const override; + [[gnu::always_inline]] ScalarT objective( + const ScalarT* x, const ScalarT* external + ) const override; + [[gnu::always_inline]] void externalConstraints( + const ScalarT* x, const ScalarT* external, ScalarT* g + ) const override; /// Active power into the bus [p.u.] const ScalarT& P() const diff --git a/GridKit/Model/OptimalPowerFlow/Generator/GeneratorData.hpp b/GridKit/Model/OptimalPowerFlow/Generator/GeneratorData.hpp index 05614f42f4..f6f0f2cffa 100644 --- a/GridKit/Model/OptimalPowerFlow/Generator/GeneratorData.hpp +++ b/GridKit/Model/OptimalPowerFlow/Generator/GeneratorData.hpp @@ -34,6 +34,7 @@ namespace GridKit /// Data of a `Generator` template - using GeneratorData = ComponentData; + using GeneratorData = + ComponentData; } // namespace OptimalPowerFlow } // namespace GridKit diff --git a/GridKit/Model/OptimalPowerFlow/Generator/GeneratorDependencyTracking.cpp b/GridKit/Model/OptimalPowerFlow/Generator/GeneratorDependencyTracking.cpp index 6752403228..f0d6e43d72 100644 --- a/GridKit/Model/OptimalPowerFlow/Generator/GeneratorDependencyTracking.cpp +++ b/GridKit/Model/OptimalPowerFlow/Generator/GeneratorDependencyTracking.cpp @@ -1,7 +1,8 @@ /** * @file GeneratorDependencyTracking.cpp - * @brief Optimal power flow generator instantiation for `DependencyTracking::Variable`. - * Its derivatives come from the system model dependencies. + * @brief Optimal power flow generator instantiation for + * `DependencyTracking::Variable`. Its derivatives come from the system model + * dependencies. */ #include @@ -25,7 +26,9 @@ namespace GridKit } template - int Generator::evaluateHessian([[maybe_unused]] RealT sigma) + int Generator::evaluateHessian( + [[maybe_unused]] RealT sigma + ) { return 0; } diff --git a/GridKit/Model/OptimalPowerFlow/Generator/GeneratorImpl.hpp b/GridKit/Model/OptimalPowerFlow/Generator/GeneratorImpl.hpp index 2ba0cc596d..35f87a2b20 100644 --- a/GridKit/Model/OptimalPowerFlow/Generator/GeneratorImpl.hpp +++ b/GridKit/Model/OptimalPowerFlow/Generator/GeneratorImpl.hpp @@ -23,7 +23,8 @@ namespace GridKit } template - Model::ConfigurationChecks Generator::verify() const + Model::ConfigurationChecks Generator::verify( + ) const { Model::ConfigurationChecks checks("Generator"); checks.check(Pmin_ <= Pmax_, "Pmin must not exceed Pmax"); @@ -56,7 +57,9 @@ namespace GridKit template [[gnu::always_inline]] typename Generator::ScalarT - Generator::objective(const ScalarT* x, [[maybe_unused]] const ScalarT* external) const + Generator::objective( + const ScalarT* x, [[maybe_unused]] const ScalarT* external + ) const { const auto P = static_cast(GeneratorInternalVariables::P); @@ -79,7 +82,9 @@ namespace GridKit } template - void Generator::initializeParameters(const ModelDataT& data) + void Generator::initializeParameters( + const ModelDataT& data + ) { using Params = GeneratorParameters; diff --git a/GridKit/Model/OptimalPowerFlow/Load/Load.hpp b/GridKit/Model/OptimalPowerFlow/Load/Load.hpp index 91d0d1d56b..5324e01392 100644 --- a/GridKit/Model/OptimalPowerFlow/Load/Load.hpp +++ b/GridKit/Model/OptimalPowerFlow/Load/Load.hpp @@ -63,7 +63,9 @@ namespace GridKit int evaluateJacobian() override; int evaluateHessian(RealT sigma) override; - [[gnu::always_inline]] void externalConstraints(const ScalarT* x, const ScalarT* external, ScalarT* g) const override; + [[gnu::always_inline]] void externalConstraints( + const ScalarT* x, const ScalarT* external, ScalarT* g + ) const override; private: void initializeParameters(const ModelDataT& data); diff --git a/GridKit/Model/OptimalPowerFlow/Load/LoadData.hpp b/GridKit/Model/OptimalPowerFlow/Load/LoadData.hpp index cd507fa639..5c6a718590 100644 --- a/GridKit/Model/OptimalPowerFlow/Load/LoadData.hpp +++ b/GridKit/Model/OptimalPowerFlow/Load/LoadData.hpp @@ -33,6 +33,7 @@ namespace GridKit /// Data of a `Load` template - using LoadData = ComponentData; + using LoadData = + ComponentData; } // namespace OptimalPowerFlow } // namespace GridKit diff --git a/GridKit/Model/OptimalPowerFlow/Load/LoadDependencyTracking.cpp b/GridKit/Model/OptimalPowerFlow/Load/LoadDependencyTracking.cpp index a603e7a8a3..26ef978abd 100644 --- a/GridKit/Model/OptimalPowerFlow/Load/LoadDependencyTracking.cpp +++ b/GridKit/Model/OptimalPowerFlow/Load/LoadDependencyTracking.cpp @@ -1,7 +1,8 @@ /** * @file LoadDependencyTracking.cpp - * @brief Optimal power flow load instantiation for `DependencyTracking::Variable`. - * Its derivatives come from the system model dependencies. + * @brief Optimal power flow load instantiation for + * `DependencyTracking::Variable`. Its derivatives come from the system model + * dependencies. */ #include @@ -25,7 +26,9 @@ namespace GridKit } template - int Load::evaluateHessian([[maybe_unused]] RealT sigma) + int Load::evaluateHessian( + [[maybe_unused]] RealT sigma + ) { return 0; } diff --git a/GridKit/Model/OptimalPowerFlow/Load/LoadImpl.hpp b/GridKit/Model/OptimalPowerFlow/Load/LoadImpl.hpp index 27728dce57..b6ea5813f4 100644 --- a/GridKit/Model/OptimalPowerFlow/Load/LoadImpl.hpp +++ b/GridKit/Model/OptimalPowerFlow/Load/LoadImpl.hpp @@ -42,15 +42,18 @@ namespace GridKit const auto DP = static_cast(LoadExternalConstraints::DP); const auto DQ = static_cast(LoadExternalConstraints::DQ); - const ScalarT v2 = external[VR] * external[VR] + external[VI] * external[VI]; - const ScalarT v = std::sqrt(v2); + const ScalarT v2 = + external[VR] * external[VR] + external[VI] * external[VI]; + const ScalarT v = std::sqrt(v2); g[DP] = -u_ * (P_ + Pi_ * v + Pz_ * v2); g[DQ] = -u_ * (Q_ + Qi_ * v + Qz_ * v2); } template - void Load::initializeParameters(const ModelDataT& data) + void Load::initializeParameters( + const ModelDataT& data + ) { using Params = LoadParameters; diff --git a/GridKit/Model/OptimalPowerFlow/SystemModel.hpp b/GridKit/Model/OptimalPowerFlow/SystemModel.hpp index 2943c26552..08edf0a7d8 100644 --- a/GridKit/Model/OptimalPowerFlow/SystemModel.hpp +++ b/GridKit/Model/OptimalPowerFlow/SystemModel.hpp @@ -36,12 +36,12 @@ namespace GridKit template class SystemModel : public Component { - using ComponentT = Component; - using EvaluatorT = Model::OptimizationEvaluator; - using ScalarT = scalar_type; - using IdxT = index_type; - using RealT = typename EvaluatorT::RealT; - using RealVectorT = typename EvaluatorT::RealVectorT; + using ComponentT = Component; + using EvaluatorT = Model::OptimizationEvaluator; + using ScalarT = scalar_type; + using IdxT = index_type; + using RealT = typename EvaluatorT::RealT; + using RealVectorT = typename EvaluatorT::RealVectorT; using IndexVectorT = LinearAlgebra::Vector; using CsrMatrixT = typename EvaluatorT::CsrMatrixT; using BusT = Bus; @@ -83,7 +83,8 @@ namespace GridKit /// Bus by number, which views its solution after `allocate()` BusT* getBus(IdxT number); - /// Generator by case-file `id`, which views its solution after `allocate()` + /// Generator by case-file `id`, which views its solution after + /// `allocate()` GeneratorT* getGenerator(const std::string& id); private: @@ -103,8 +104,10 @@ namespace GridKit int bind(ComponentT& component, const Block& offset); int allocateDerivatives(); - std::unique_ptr assemble(IdxT rows, IdxT cols, Assembly& assembly) const; - int refill(CsrMatrixT& matrix, const Assembly& assembly) const; + std::unique_ptr assemble( + IdxT rows, IdxT cols, Assembly& assembly + ) const; + int refill(CsrMatrixT& matrix, const Assembly& assembly) const; /// Buses first, then devices std::vector> components_; diff --git a/GridKit/Model/OptimalPowerFlow/SystemModelData.cpp b/GridKit/Model/OptimalPowerFlow/SystemModelData.cpp index b30d7273e0..e76550a61f 100644 --- a/GridKit/Model/OptimalPowerFlow/SystemModelData.cpp +++ b/GridKit/Model/OptimalPowerFlow/SystemModelData.cpp @@ -19,7 +19,9 @@ namespace GridKit return json::parse(stream).get>(); } - SystemModelData parseSystemModelData(const std::filesystem::path& file) + SystemModelData parseSystemModelData( + const std::filesystem::path& file + ) { std::ifstream stream(file); if (!stream) diff --git a/GridKit/Model/OptimalPowerFlow/SystemModelData.hpp b/GridKit/Model/OptimalPowerFlow/SystemModelData.hpp index f397fecb6f..adb4f4960b 100644 --- a/GridKit/Model/OptimalPowerFlow/SystemModelData.hpp +++ b/GridKit/Model/OptimalPowerFlow/SystemModelData.hpp @@ -45,6 +45,8 @@ namespace GridKit * std::invalid_argument for an unknown device class, parameter, or port */ SystemModelData parseSystemModelData(std::istream& stream); - SystemModelData parseSystemModelData(const std::filesystem::path& file); + SystemModelData parseSystemModelData( + const std::filesystem::path& file + ); } // namespace OptimalPowerFlow } // namespace GridKit diff --git a/GridKit/Model/OptimalPowerFlow/SystemModelDataJSONParser.hpp b/GridKit/Model/OptimalPowerFlow/SystemModelDataJSONParser.hpp index 9f66976341..d0be58546b 100644 --- a/GridKit/Model/OptimalPowerFlow/SystemModelDataJSONParser.hpp +++ b/GridKit/Model/OptimalPowerFlow/SystemModelDataJSONParser.hpp @@ -23,19 +23,25 @@ namespace GridKit /// Enumerator named `key`, or throw naming its `kind` and `owner` template - EnumT enumKey(const std::string& key, std::string_view kind, std::string_view owner) + EnumT enumKey( + const std::string& key, std::string_view kind, std::string_view owner + ) { const auto value = Utilities::enum_cast(key); if (!value) { - throw std::invalid_argument(std::format("{}: unknown {} '{}'", owner, kind, key)); + throw std::invalid_argument( + std::format("{}: unknown {} '{}'", owner, kind, key) + ); } return *value; } /// Value of each entry of `params`, typed as in the input file template - ParameterMap readParameters(const json& params, std::string_view owner) + ParameterMap readParameters( + const json& params, std::string_view owner + ) { ParameterMap parameters; for (const auto& [key, value] : params.items()) @@ -65,14 +71,23 @@ namespace GridKit void from_json(const json& j, BusData& bus) { j.at("number").get_to(bus.number); - bus.parameters = readParameters(j.at("params"), std::format("bus {}", bus.number)); + bus.parameters = readParameters( + j.at("params"), std::format("bus {}", bus.number) + ); } - template - void from_json(const json& j, ComponentData& device) + template < + typename RealT, + typename IdxT, + typename Parameters, + typename Ports> + void from_json( + const json& j, ComponentData& device + ) { j.at("id").get_to(device.id); - device.parameters = readParameters(j.at("params"), device.id); + device.parameters = + readParameters(j.at("params"), device.id); for (const auto& [key, value] : j.at("ports").items()) { value.get_to(device.ports[enumKey(key, "port", device.id)]); @@ -97,7 +112,8 @@ namespace GridKit } else if (kind == "Generator") { - data.generator.push_back(device.get()); + data.generator.push_back(device.get() + ); } else if (kind == "Load") { @@ -105,7 +121,9 @@ namespace GridKit } else { - throw std::invalid_argument(std::format("OptimalPowerFlow: unknown device class '{}'", kind)); + throw std::invalid_argument( + std::format("OptimalPowerFlow: unknown device class '{}'", kind) + ); } } } diff --git a/GridKit/Model/OptimalPowerFlow/SystemModelDependencyTracking.cpp b/GridKit/Model/OptimalPowerFlow/SystemModelDependencyTracking.cpp index acb547bd27..b945554efe 100644 --- a/GridKit/Model/OptimalPowerFlow/SystemModelDependencyTracking.cpp +++ b/GridKit/Model/OptimalPowerFlow/SystemModelDependencyTracking.cpp @@ -1,6 +1,7 @@ /** * @file SystemModelDependencyTracking.cpp - * @brief Optimal power flow system derivatives from `DependencyTracking::Variable`. + * @brief Optimal power flow system derivatives from + * `DependencyTracking::Variable`. * * @note Used for testing the Enzyme derivatives. */ @@ -14,8 +15,14 @@ namespace GridKit namespace { /// CSR Jacobian of `functions` from their dependencies - template - std::unique_ptr dependencyJacobian(const VectorT& functions, IdxT cols) + template < + typename CsrMatrixT, + typename RealT, + typename VectorT, + typename IdxT> + std::unique_ptr dependencyJacobian( + const VectorT& functions, IdxT cols + ) { const IdxT rows = functions.getSize(); const auto* g = functions.getData(); @@ -41,7 +48,9 @@ namespace GridKit } } - return std::make_unique(rows, cols, row_ptrs[rows], &row_ptrs, &col_data, &vals); + return std::make_unique( + rows, cols, row_ptrs[rows], &row_ptrs, &col_data, &vals + ); } } // namespace @@ -81,9 +90,12 @@ namespace GridKit /// Not available, because dependencies hold first derivatives only template - int SystemModel::evaluateHessian([[maybe_unused]] RealT sigma) + int SystemModel::evaluateHessian( + [[maybe_unused]] RealT sigma + ) { - Log::error() << "OptimalPowerFlow::SystemModel: no Hessian for DependencyTracking::Variable\n"; + Log::error() << "OptimalPowerFlow::SystemModel: no Hessian for " + "DependencyTracking::Variable\n"; return 1; } diff --git a/GridKit/Model/OptimalPowerFlow/SystemModelEnzyme.cpp b/GridKit/Model/OptimalPowerFlow/SystemModelEnzyme.cpp index 44d48463c0..4080e4eddb 100644 --- a/GridKit/Model/OptimalPowerFlow/SystemModelEnzyme.cpp +++ b/GridKit/Model/OptimalPowerFlow/SystemModelEnzyme.cpp @@ -74,7 +74,8 @@ namespace GridKit hessian_assembly_.entries.clear(); for (auto& component : components_) { - if (component->evaluateJacobian() != 0 || component->evaluateHessian(ONE) != 0) + if (component->evaluateJacobian() != 0 + || component->evaluateHessian(ONE) != 0) { return 1; } @@ -89,10 +90,13 @@ namespace GridKit return 0; } - /// Sort and deduplicate the entries of `assembly` into a CSR matrix, and record the CSR entry of each + /// Sort and deduplicate the entries of `assembly` into a CSR matrix, and + /// record the CSR entry of each template std::unique_ptr::CsrMatrixT> - SystemModel::assemble(IdxT rows, IdxT cols, Assembly& assembly) const + SystemModel::assemble( + IdxT rows, IdxT cols, Assembly& assembly + ) const { IdxT nnz_dup = 0; for (const CooBufferT* entries : assembly.entries) @@ -102,7 +106,8 @@ namespace GridKit if (assembly.map_to_csr.resize(nnz_dup) != 0) { - Log::error() << "OptimalPowerFlow::SystemModel: failed to allocate the CSR map\n"; + Log::error( + ) << "OptimalPowerFlow::SystemModel: failed to allocate the CSR map\n"; throw std::bad_alloc{}; } @@ -116,11 +121,15 @@ namespace GridKit { std::copy_n(entries->rows.getData(), entries->nnz, rows_dup + counter); std::copy_n(entries->cols.getData(), entries->nnz, cols_dup + counter); - std::copy_n(entries->values.getData(), entries->nnz, vals_dup + counter); + std::copy_n( + entries->values.getData(), entries->nnz, vals_dup + counter + ); counter += entries->nnz; } - LinearAlgebra::CooMatrix coo(rows, cols, nnz_dup, &rows_dup, &cols_dup, &vals_dup); + LinearAlgebra::CooMatrix coo( + rows, cols, nnz_dup, &rows_dup, &cols_dup, &vals_dup + ); // Populate CSR data with sort and deduplicate IdxT* row_ptrs = coo.getCsrRowData(); @@ -141,12 +150,17 @@ namespace GridKit } assembly.map_to_csr.setDataUpdated(); - return std::make_unique(rows, cols, nnz, &row_ptrs, &csr_cols, &csr_vals); + return std::make_unique( + rows, cols, nnz, &row_ptrs, &csr_cols, &csr_vals + ); } - /// Sum the component entries into the CSR values, or fail if their number changed + /// Sum the component entries into the CSR values, or fail if their number + /// changed template - int SystemModel::refill(CsrMatrixT& matrix, const Assembly& assembly) const + int SystemModel::refill( + CsrMatrixT& matrix, const Assembly& assembly + ) const { IdxT nnz_dup = 0; for (const CooBufferT* entries : assembly.entries) @@ -156,7 +170,8 @@ namespace GridKit if (nnz_dup != assembly.map_to_csr.getSize()) { - Log::error() << "OptimalPowerFlow::SystemModel: " << nnz_dup << " derivative entries, but " + Log::error() << "OptimalPowerFlow::SystemModel: " << nnz_dup + << " derivative entries, but " << assembly.map_to_csr.getSize() << " at assembly\n"; return 1; } diff --git a/GridKit/Model/OptimalPowerFlow/SystemModelImpl.hpp b/GridKit/Model/OptimalPowerFlow/SystemModelImpl.hpp index cc09597592..ec5e6061cb 100644 --- a/GridKit/Model/OptimalPowerFlow/SystemModelImpl.hpp +++ b/GridKit/Model/OptimalPowerFlow/SystemModelImpl.hpp @@ -31,7 +31,9 @@ namespace GridKit * or a port without a bus of this system */ template - SystemModel::SystemModel(const SystemModelData& data) + SystemModel::SystemModel( + const SystemModelData& data + ) { for (const auto& bus : data.bus) { @@ -55,21 +57,26 @@ namespace GridKit } template - SystemModel::SystemModel(std::vector> components) + SystemModel::SystemModel( + std::vector> components + ) : components_(std::move(components)) { for (const auto& component : components_) { if (!component) { - throw std::invalid_argument("OptimalPowerFlow::SystemModel: null component"); + throw std::invalid_argument( + "OptimalPowerFlow::SystemModel: null component" + ); } } } /// Every problem with the data template - Model::ConfigurationChecks SystemModel::verify() const + Model::ConfigurationChecks SystemModel::verify( + ) const { Model::ConfigurationChecks checks; @@ -90,7 +97,10 @@ namespace GridKit std::set ids; for (const auto& component : components_) { - checks.check(ids.insert(component->id()).second, std::format("{}: duplicate id", component->id())); + checks.check( + ids.insert(component->id()).second, + std::format("{}: duplicate id", component->id()) + ); const auto component_checks = component->verify(); for (const auto& error : component_checks.errors()) @@ -157,17 +167,15 @@ namespace GridKit return 0; } - /// Equalities at zero and inequalities unbounded until the components set their limits + /// Equalities at zero and inequalities unbounded until the components set + /// their limits template int SystemModel::initialize() { - if (x_.setToZero() != 0 - || x_lower_.setToConst(-UNBOUNDED) != 0 + if (x_.setToZero() != 0 || x_lower_.setToConst(-UNBOUNDED) != 0 || x_upper_.setToConst(UNBOUNDED) != 0 - || g_lower_.setToZero() != 0 - || g_upper_.setToZero() != 0 - || lambda_.setToZero() != 0 - || z_lower_.setToZero() != 0 + || g_lower_.setToZero() != 0 || g_upper_.setToZero() != 0 + || lambda_.setToZero() != 0 || z_lower_.setToZero() != 0 || z_upper_.setToZero() != 0) { return 1; @@ -244,26 +252,33 @@ namespace GridKit /// @throw std::out_of_range for an unknown bus template - typename SystemModel::BusT* SystemModel::getBus(IdxT number) + typename SystemModel::BusT* SystemModel< + scalar_type, + index_type>::getBus(IdxT number) { return buses_.at(number); } /// @throw std::out_of_range for an unknown generator template - typename SystemModel::GeneratorT* - SystemModel::getGenerator(const std::string& id) + typename SystemModel::GeneratorT* SystemModel< + scalar_type, + index_type>::getGenerator(const std::string& id) { return generators_.at(id); } template - void SystemModel::addBus(const BusData& data) + void SystemModel::addBus( + const BusData& data + ) { auto bus = std::make_unique(data); if (!buses_.emplace(data.number, bus.get()).second) { - throw std::invalid_argument(std::format("OptimalPowerFlow::SystemModel: duplicate bus {}", data.number)); + throw std::invalid_argument(std::format( + "OptimalPowerFlow::SystemModel: duplicate bus {}", data.number + )); } components_.push_back(std::move(bus)); } @@ -274,7 +289,9 @@ namespace GridKit ModelT* SystemModel::addDevice(const DataT& data) { using Ports = typename DataT::Ports; - static_assert(ModelT::NUM_PORT_VARIABLES.size() == Utilities::enum_size()); + static_assert( + ModelT::NUM_PORT_VARIABLES.size() == Utilities::enum_size() + ); auto device = std::make_unique(data); for (const Ports port : Utilities::enum_values()) @@ -282,32 +299,30 @@ namespace GridKit const auto number = data.ports.find(port); if (number == data.ports.end()) { - throw std::invalid_argument(std::format("{}: port '{}' has no bus", data.id, Utilities::enum_name(port))); + throw std::invalid_argument(std::format( + "{}: port '{}' has no bus", data.id, Utilities::enum_name(port) + )); } const auto bus = buses_.find(number->second); if (bus == buses_.end()) { - throw std::invalid_argument( - std::format( - "{}: port '{}' names unknown bus {}", - data.id, - Utilities::enum_name(port), - number->second - ) - ); + throw std::invalid_argument(std::format( + "{}: port '{}' names unknown bus {}", + data.id, + Utilities::enum_name(port), + number->second + )); } if (device->connect(static_cast(port), *bus->second) != 0) { - throw std::invalid_argument( - std::format( - "{}: port '{}' does not fit bus {}", - data.id, - Utilities::enum_name(port), - number->second - ) - ); + throw std::invalid_argument(std::format( + "{}: port '{}' does not fit bus {}", + data.id, + Utilities::enum_name(port), + number->second + )); } } @@ -326,8 +341,7 @@ namespace GridKit size += component->size_; } - if (x_.resize(size.variables) != 0 - || x_lower_.resize(size.variables) != 0 + if (x_.resize(size.variables) != 0 || x_lower_.resize(size.variables) != 0 || x_upper_.resize(size.variables) != 0 || gradient_.resize(size.variables) != 0 || z_lower_.resize(size.variables) != 0 @@ -361,7 +375,9 @@ namespace GridKit /// View the internal blocks of the system vectors from `offset` template - int SystemModel::bind(ComponentT& component, const Block& offset) + int SystemModel::bind( + ComponentT& component, const Block& offset + ) { component.offset_ = offset; const Block& size = component.size_; @@ -370,13 +386,25 @@ namespace GridKit { return local.setData(global.getData() + start, count) != 0; }; if (view(component.x_, x_, offset.variables, size.variables) - || view(component.x_lower_, x_lower_, offset.variables, size.variables) - || view(component.x_upper_, x_upper_, offset.variables, size.variables) - || view(component.gradient_, gradient_, offset.variables, size.variables) + || view( + component.x_lower_, x_lower_, offset.variables, size.variables + ) + || view( + component.x_upper_, x_upper_, offset.variables, size.variables + ) + || view( + component.gradient_, gradient_, offset.variables, size.variables + ) || view(component.g_, g_, offset.constraints, size.constraints) - || view(component.g_lower_, g_lower_, offset.constraints, size.constraints) - || view(component.g_upper_, g_upper_, offset.constraints, size.constraints) - || view(component.lambda_, lambda_, offset.constraints, size.constraints)) + || view( + component.g_lower_, g_lower_, offset.constraints, size.constraints + ) + || view( + component.g_upper_, g_upper_, offset.constraints, size.constraints + ) + || view( + component.lambda_, lambda_, offset.constraints, size.constraints + )) { return 1; } diff --git a/GridKit/Model/OptimizationEvaluator.hpp b/GridKit/Model/OptimizationEvaluator.hpp index d5d6d7c9df..a746539272 100644 --- a/GridKit/Model/OptimizationEvaluator.hpp +++ b/GridKit/Model/OptimizationEvaluator.hpp @@ -56,7 +56,8 @@ namespace GridKit /// Evaluate the Jacobian of \f$g\f$ into `getCsrJacobian()` virtual int evaluateJacobian() = 0; - /// Evaluate the lower Hessian of \f$\sigma f + \lambda^T g\f$ into `getCsrHessian()` + /// Evaluate the lower Hessian of \f$\sigma f + \lambda^T g\f$ into + /// `getCsrHessian()` virtual int evaluateHessian(RealT sigma) = 0; /// Number of variables diff --git a/GridKit/Model/ParameterReader.hpp b/GridKit/Model/ParameterReader.hpp index 3542ff1087..319278ffcd 100644 --- a/GridKit/Model/ParameterReader.hpp +++ b/GridKit/Model/ParameterReader.hpp @@ -55,8 +55,7 @@ namespace GridKit * @param[in] model Model name used in rejection messages. */ ParameterReader(const ModelDataT& data, const char* model) - : parameters_(data.parameters), - model_(model) + : parameters_(data.parameters), model_(model) { } @@ -131,7 +130,9 @@ namespace GridKit /// Read an optional parameter that must hold exactly a T. template - [[nodiscard]] std::optional readExact(ParametersT key, std::string_view reason) const + [[nodiscard]] std::optional readExact( + ParametersT key, std::string_view reason + ) const { const auto* value = find(key); if (value == nullptr) @@ -151,11 +152,9 @@ namespace GridKit /// Reject the model data with a message naming the model and parameter. [[noreturn]] void reject(ParametersT key, std::string_view reason) const { - throw std::invalid_argument( - std::format( - "{}: parameter '{}' {}", model_, magic_enum::enum_name(key), reason - ) - ); + throw std::invalid_argument(std::format( + "{}: parameter '{}' {}", model_, magic_enum::enum_name(key), reason + )); } const ParameterMapT& parameters_; diff --git a/GridKit/Model/PhasorDynamics/Branch/Branch.hpp b/GridKit/Model/PhasorDynamics/Branch/Branch.hpp index 194ffdb0af..000964ba67 100644 --- a/GridKit/Model/PhasorDynamics/Branch/Branch.hpp +++ b/GridKit/Model/PhasorDynamics/Branch/Branch.hpp @@ -18,7 +18,8 @@ namespace GridKit namespace PhasorDynamics { /** - * @brief Implementation of a line or off-nominal transformer branch between two buses. + * @brief Implementation of a line or off-nominal transformer branch between + * two buses. * * The model is implemented in Cartesian coordinates. Positive current * direction is into the buses. @@ -169,18 +170,14 @@ namespace GridKit } public: - __attribute__((always_inline)) inline int evaluateBusResidual11( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* - ); - __attribute__((always_inline)) inline int evaluateBusResidual12( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* - ); - __attribute__((always_inline)) inline int evaluateBusResidual21( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* - ); - __attribute__((always_inline)) inline int evaluateBusResidual22( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* - ); + __attribute__((always_inline)) inline int + evaluateBusResidual11(const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + __attribute__((always_inline)) inline int + evaluateBusResidual12(const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + __attribute__((always_inline)) inline int + evaluateBusResidual21(const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + __attribute__((always_inline)) inline int + evaluateBusResidual22(const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); private: BusT* bus1_; diff --git a/GridKit/Model/PhasorDynamics/Branch/BranchData.hpp b/GridKit/Model/PhasorDynamics/Branch/BranchData.hpp index 3951abbf81..fce588d2ce 100644 --- a/GridKit/Model/PhasorDynamics/Branch/BranchData.hpp +++ b/GridKit/Model/PhasorDynamics/Branch/BranchData.hpp @@ -15,21 +15,27 @@ namespace GridKit /// Initial parameters for a branch enum class BranchParameters : size_t { - R, ///< \f$R\f$ Branch series resistance [p.u.] - X, ///< \f$X\f$ Branch series reactance [p.u.] - G, ///< \f$G\f$ Total line shunt conductance, split equally between the two terminals [p.u.] - B, ///< \f$B\f$ Total line shunt susceptance, split equally between the two terminals [p.u.] - Gmag, ///< \f$G_{\mathrm{mag}}\f$ Magnetizing shunt conductance at bus 1, the tapped side [p.u.] - Bmag, ///< \f$B_{\mathrm{mag}}\f$ Magnetizing shunt susceptance at bus 1, the tapped side [p.u.] - tap, ///< \f$\tau\f$ Off-nominal tap magnitude on the bus-1 side [p.u.] + R, ///< \f$R\f$ Branch series resistance [p.u.] + X, ///< \f$X\f$ Branch series reactance [p.u.] + G, ///< \f$G\f$ Total line shunt conductance, split equally between the + ///< two terminals [p.u.] + B, ///< \f$B\f$ Total line shunt susceptance, split equally between the + ///< two terminals [p.u.] + Gmag, ///< \f$G_{\mathrm{mag}}\f$ Magnetizing shunt conductance at bus 1, + ///< the tapped side [p.u.] + Bmag, ///< \f$B_{\mathrm{mag}}\f$ Magnetizing shunt susceptance at bus 1, + ///< the tapped side [p.u.] + tap, ///< \f$\tau\f$ Off-nominal tap magnitude on the bus-1 side [p.u.] phase, ///< \f$\theta\f$ Off-nominal phase-shift angle [rad] }; /// Buses for a branch enum class BranchBuses : size_t { - bus1, ///< \f$V_{\mathrm{r}1},V_{\mathrm{i}1}\f$ Required Known bus-1 terminal voltage, the tapped side [p.u.] - bus2, ///< \f$V_{\mathrm{r}2},V_{\mathrm{i}2}\f$ Required Known bus-2 terminal voltage [p.u.] + bus1, ///< \f$V_{\mathrm{r}1},V_{\mathrm{i}1}\f$ Required Known bus-1 + ///< terminal voltage, the tapped side [p.u.] + bus2, ///< \f$V_{\mathrm{r}2},V_{\mathrm{i}2}\f$ Required Known bus-2 + ///< terminal voltage [p.u.] }; /// Signal inputs supported for a branch @@ -45,13 +51,17 @@ namespace GridKit /// Variables able to be monitored for a branch enum class BranchMonitorableVariables : size_t { - ir1, ///< \f$I_{\mathrm{r}1}\f$ Bus-1 terminal-current real component [p.u.] - ii1, ///< \f$I_{\mathrm{i}1}\f$ Bus-1 terminal-current imaginary component [p.u.] + ir1, ///< \f$I_{\mathrm{r}1}\f$ Bus-1 terminal-current real component + ///< [p.u.] + ii1, ///< \f$I_{\mathrm{i}1}\f$ Bus-1 terminal-current imaginary component + ///< [p.u.] im1, ///< \f$I_{\mathrm{m}1}\f$ Bus-1 terminal-current magnitude [p.u.] p1, ///< \f$P_1\f$ Bus-1 terminal active power [p.u.] q1, ///< \f$Q_1\f$ Bus-1 terminal reactive power [p.u.] - ir2, ///< \f$I_{\mathrm{r}2}\f$ Bus-2 terminal-current real component [p.u.] - ii2, ///< \f$I_{\mathrm{i}2}\f$ Bus-2 terminal-current imaginary component [p.u.] + ir2, ///< \f$I_{\mathrm{r}2}\f$ Bus-2 terminal-current real component + ///< [p.u.] + ii2, ///< \f$I_{\mathrm{i}2}\f$ Bus-2 terminal-current imaginary component + ///< [p.u.] im2, ///< \f$I_{\mathrm{m}2}\f$ Bus-2 terminal-current magnitude [p.u.] p2, ///< \f$P_2\f$ Bus-2 terminal active power [p.u.] q2, ///< \f$Q_2\f$ Bus-2 terminal reactive power [p.u.] @@ -60,13 +70,13 @@ namespace GridKit /// Initial values supported for a branch enum class BranchInitialValues : size_t { - ir1, ///< \f$I_{r1}\f$ Initial real current into bus 1 on system base - ii1, ///< \f$I_{i1}\f$ Initial imaginary current into bus 1 on system base - ir2, ///< \f$I_{r2}\f$ Initial real current into bus 2 on system base - ii2, ///< \f$I_{i2}\f$ Initial imaginary current into bus 2 on system base + ir1, ///< \f$I_{r1}\f$ Initial real current into bus 1 on system base + ii1, ///< \f$I_{i1}\f$ Initial imaginary current into bus 1 on system base + ir2, ///< \f$I_{r2}\f$ Initial real current into bus 2 on system base + ii2, ///< \f$I_{i2}\f$ Initial imaginary current into bus 2 on system base in_service, ///< Initial service status; defaults to true - tap, ///< Initial off-nominal tap magnitude on the bus-1 side [p.u.] - phase, ///< Initial phase-shift angle [rad] + tap, ///< Initial off-nominal tap magnitude on the bus-1 side [p.u.] + phase, ///< Initial phase-shift angle [rad] }; /** diff --git a/GridKit/Model/PhasorDynamics/Branch/BranchEnzyme.cpp b/GridKit/Model/PhasorDynamics/Branch/BranchEnzyme.cpp index 934f1e28d1..1ebfca282c 100644 --- a/GridKit/Model/PhasorDynamics/Branch/BranchEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Branch/BranchEnzyme.cpp @@ -23,8 +23,8 @@ namespace GridKit if (J_rows_buffer_ == nullptr) { // Reserve space for the dense blocks. - // The size of the buffer is the sum of maximum capacities of the blocks. - // Enzyme will compute the appropriate nnz from sparsification. + // The size of the buffer is the sum of maximum capacities of the + // blocks. Enzyme will compute the appropriate nnz from sparsification. auto bus1_size = static_cast(bus1_->size()); auto bus2_size = static_cast(bus2_->size()); auto buffer_size = (bus1_size + bus2_size) * (bus1_size + bus2_size); diff --git a/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp b/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp index 59fdbcacf6..d8abe7d008 100644 --- a/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp @@ -29,10 +29,10 @@ namespace GridKit * @param data - branch parameters and monitored-variable selections */ template - Branch::Branch(BusT* bus1, BusT* bus2, const ModelDataT& data) - : bus1_(bus1), - bus2_(bus2), - monitor_(std::make_unique(data)) + Branch::Branch( + BusT* bus1, BusT* bus2, const ModelDataT& data + ) + : bus1_(bus1), bus2_(bus2), monitor_(std::make_unique(data)) { initializeParameters(data); initializeMonitor(); @@ -54,7 +54,8 @@ namespace GridKit * @brief Set the component ID */ template - int Branch::setGridKitComponentID(IdxT component_id) + int Branch::setGridKitComponentID(IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -117,13 +118,16 @@ namespace GridKit checks.check(std::isfinite(Bmag_), "Bmag must be finite"); checks.check(std::isfinite(tap_), "tap must be finite"); checks.check(std::isfinite(phase_), "phase must be finite"); - checks.check(R_ * R_ + X_ * X_ > RealT{0.0}, "R and X cannot both be zero"); + checks.check( + R_ * R_ + X_ * X_ > RealT{0.0}, "R and X cannot both be zero" + ); checks.check(tap_ > RealT{0.0}, "tap must be positive"); return checks; } - /// Put the branch in or out of service; out of service, it injects no current. + /// Put the branch in or out of service; out of service, it injects no + /// current. template int Branch::setInService(bool in_service) { @@ -255,7 +259,8 @@ namespace GridKit } /** - * @brief Residual contribution of the branch is computed and pushed to the terminal buses. + * @brief Residual contribution of the branch is computed and pushed to the + * terminal buses. * * Out-of-service branches retain bus voltages but contribute no current. * Empty isolated buses and floating series-only islands can make the @@ -290,7 +295,9 @@ namespace GridKit } template - void Branch::terminalCurrent1(ScalarT& Ir, ScalarT& Ii) + void Branch::terminalCurrent1( + ScalarT& Ir, ScalarT& Ii + ) { Ir = ScalarT{0.0}; Ii = ScalarT{0.0}; @@ -300,7 +307,9 @@ namespace GridKit } template - void Branch::terminalCurrent2(ScalarT& Ir, ScalarT& Ii) + void Branch::terminalCurrent2( + ScalarT& Ir, ScalarT& Ii + ) { Ir = ScalarT{0.0}; Ii = ScalarT{0.0}; @@ -310,7 +319,9 @@ namespace GridKit } template - void Branch::initializeParameters(const ModelDataT& data) + void Branch::initializeParameters( + const ModelDataT& data + ) { using Parameter = typename ModelDataT::Parameters; using Buses = typename ModelDataT::Buses; @@ -338,7 +349,8 @@ namespace GridKit } template - const Model::VariableMonitorBase* Branch::getMonitor() const + const Model::VariableMonitorBase* Branch:: + getMonitor() const { return monitor_.get(); } @@ -347,66 +359,106 @@ namespace GridKit void Branch::initializeMonitor() { using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::ir1, [this] - { - ScalarT Ir; - ScalarT Ii; - terminalCurrent1(Ir, Ii); - return Ir; }); - monitor_->set(Variable::ii1, [this] - { - ScalarT Ir; - ScalarT Ii; - terminalCurrent1(Ir, Ii); - return Ii; }); - monitor_->set(Variable::im1, [this] - { - ScalarT Ir; - ScalarT Ii; - terminalCurrent1(Ir, Ii); - return std::sqrt(Ir * Ir + Ii * Ii); }); - monitor_->set(Variable::p1, [this] - { - ScalarT Ir; - ScalarT Ii; - terminalCurrent1(Ir, Ii); - return Vr1() * Ir + Vi1() * Ii; }); - monitor_->set(Variable::q1, [this] - { - ScalarT Ir; - ScalarT Ii; - terminalCurrent1(Ir, Ii); - return Vi1() * Ir - Vr1() * Ii; }); - monitor_->set(Variable::ir2, [this] - { - ScalarT Ir; - ScalarT Ii; - terminalCurrent2(Ir, Ii); - return Ir; }); - monitor_->set(Variable::ii2, [this] - { - ScalarT Ir; - ScalarT Ii; - terminalCurrent2(Ir, Ii); - return Ii; }); - monitor_->set(Variable::im2, [this] - { - ScalarT Ir; - ScalarT Ii; - terminalCurrent2(Ir, Ii); - return std::sqrt(Ir * Ir + Ii * Ii); }); - monitor_->set(Variable::p2, [this] - { - ScalarT Ir; - ScalarT Ii; - terminalCurrent2(Ir, Ii); - return Vr2() * Ir + Vi2() * Ii; }); - monitor_->set(Variable::q2, [this] - { - ScalarT Ir; - ScalarT Ii; - terminalCurrent2(Ir, Ii); - return Vi2() * Ir - Vr2() * Ii; }); + monitor_->set( + Variable::ir1, + [this] + { + ScalarT Ir; + ScalarT Ii; + terminalCurrent1(Ir, Ii); + return Ir; + } + ); + monitor_->set( + Variable::ii1, + [this] + { + ScalarT Ir; + ScalarT Ii; + terminalCurrent1(Ir, Ii); + return Ii; + } + ); + monitor_->set( + Variable::im1, + [this] + { + ScalarT Ir; + ScalarT Ii; + terminalCurrent1(Ir, Ii); + return std::sqrt(Ir * Ir + Ii * Ii); + } + ); + monitor_->set( + Variable::p1, + [this] + { + ScalarT Ir; + ScalarT Ii; + terminalCurrent1(Ir, Ii); + return Vr1() * Ir + Vi1() * Ii; + } + ); + monitor_->set( + Variable::q1, + [this] + { + ScalarT Ir; + ScalarT Ii; + terminalCurrent1(Ir, Ii); + return Vi1() * Ir - Vr1() * Ii; + } + ); + monitor_->set( + Variable::ir2, + [this] + { + ScalarT Ir; + ScalarT Ii; + terminalCurrent2(Ir, Ii); + return Ir; + } + ); + monitor_->set( + Variable::ii2, + [this] + { + ScalarT Ir; + ScalarT Ii; + terminalCurrent2(Ir, Ii); + return Ii; + } + ); + monitor_->set( + Variable::im2, + [this] + { + ScalarT Ir; + ScalarT Ii; + terminalCurrent2(Ir, Ii); + return std::sqrt(Ir * Ir + Ii * Ii); + } + ); + monitor_->set( + Variable::p2, + [this] + { + ScalarT Ir; + ScalarT Ii; + terminalCurrent2(Ir, Ii); + return Vr2() * Ir + Vi2() * Ii; + } + ); + monitor_->set( + Variable::q2, + [this] + { + ScalarT Ir; + ScalarT Ii; + terminalCurrent2(Ir, Ii); + return Vi2() * Ir - Vr2() * Ii; + } + ); } /** diff --git a/GridKit/Model/PhasorDynamics/Bus/Bus.hpp b/GridKit/Model/PhasorDynamics/Bus/Bus.hpp index 468236b693..206cc34842 100644 --- a/GridKit/Model/PhasorDynamics/Bus/Bus.hpp +++ b/GridKit/Model/PhasorDynamics/Bus/Bus.hpp @@ -120,7 +120,9 @@ namespace GridKit } } coo_jac_ = new CooMatrixT(num_rows, num_cols, nnz_); - coo_jac_->setDataPointers(J_rows_buffer_, J_cols_buffer_, J_vals_buffer_, memory::HOST); + coo_jac_->setDataPointers( + J_rows_buffer_, J_cols_buffer_, J_vals_buffer_, memory::HOST + ); } return 0; @@ -130,7 +132,8 @@ namespace GridKit * @brief Initialize DependencyTracking variable numbers. * * @note Assigns even indices to y and odd indices to yp. - * Should be called in initialize(), after variables have been set (and updated as needed). + * Should be called in initialize(), after variables have been set + * (and updated as needed). */ int initializeDependencyTrackingVariableNumbers() requires std::is_same_v diff --git a/GridKit/Model/PhasorDynamics/Bus/BusData.hpp b/GridKit/Model/PhasorDynamics/Bus/BusData.hpp index 011d30df37..4d0c4aef1c 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusData.hpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusData.hpp @@ -92,8 +92,10 @@ namespace GridKit INVALID, DEFAULT, SLACK, - SIGNAL_VOLTAGE_OUT, ///< Bus with voltage signal outputs and current signal inputs - SIGNAL_VOLTAGE_IN, ///< Bus with voltage signal inputs and current signal outputs + SIGNAL_VOLTAGE_OUT, ///< Bus with voltage signal outputs and current + ///< signal inputs + SIGNAL_VOLTAGE_IN, ///< Bus with voltage signal inputs and current + ///< signal outputs }; BusType bus_type{BusType::INVALID}; ///< The kind of bus this data is for diff --git a/GridKit/Model/PhasorDynamics/Bus/BusDataJSONParser.hpp b/GridKit/Model/PhasorDynamics/Bus/BusDataJSONParser.hpp index 82d4e73a79..7acd0aee5a 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusDataJSONParser.hpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusDataJSONParser.hpp @@ -20,7 +20,8 @@ namespace GridKit /// JSON parser function implementation for the `BusData` type /// - /// See the `README.md` in `GridKit/Model/PhasorDynamics` for more information + /// See the `README.md` in `GridKit/Model/PhasorDynamics` for more + /// information template void from_json(const json& j, BusData& bd) { @@ -28,8 +29,8 @@ namespace GridKit j.at("number").get_to(bd.bus_id); std::stringstream error_context; - error_context << "\n\tSee bus number " << bd.bus_id - << " (\"name\": \"" << bd.name << "\") " + error_context << "\n\tSee bus number " << bd.bus_id << " (\"name\": \"" + << bd.name << "\") " << "in the \"buses\" list of your JSON file."; if (!Utilities::isValidIdentifier(bd.name)) @@ -95,23 +96,26 @@ namespace GridKit // handles std::variant out of the box if (raw_parameter.value().is_boolean()) { - bd.parameters[key.value()] = raw_parameter.value().template get(); + bd.parameters[key.value()] = + raw_parameter.value().template get(); } else if (raw_parameter.value().is_number_float()) { - bd.parameters[key.value()] = raw_parameter.value().template get(); + bd.parameters[key.value()] = + raw_parameter.value().template get(); } else if (raw_parameter.value().is_number_integer()) { - bd.parameters[key.value()] = raw_parameter.value().template get(); + bd.parameters[key.value()] = + raw_parameter.value().template get(); } else { Log::error() << "\n\tInvalid bus parameter value type: " - << "\"" << raw_parameter.key() << "\": " - << raw_parameter.value() - << " (typed as \"" << raw_parameter.value().type_name() - << "\")." << error_context.str() << std::endl; + << "\"" << raw_parameter.key() + << "\": " << raw_parameter.value() << " (typed as \"" + << raw_parameter.value().type_name() << "\")." + << error_context.str() << std::endl; throw std::runtime_error("JSON parser failed"); } } @@ -155,11 +159,14 @@ namespace GridKit if (j.contains("mon")) { - using MonitorableVariables = typename BusData::MonitorableVariables; + using MonitorableVariables = + typename BusData::MonitorableVariables; for (auto& raw_monitored_variable : j.at("mon")) { auto var_name = raw_monitored_variable.get(); - auto monitored = Utilities::enum_cast(var_name, magic_enum::case_insensitive); + auto monitored = Utilities::enum_cast( + var_name, magic_enum::case_insensitive + ); if (monitored.has_value()) { bd.monitored_variables.insert(monitored.value()); diff --git a/GridKit/Model/PhasorDynamics/Bus/BusEnzyme.cpp b/GridKit/Model/PhasorDynamics/Bus/BusEnzyme.cpp index 8de69cf3a5..1eb5961efe 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusEnzyme.cpp @@ -13,9 +13,10 @@ namespace GridKit /** * @brief Jacobian evaluation experimental. * - * This sets values to the fault admittance, zero when cleared. It is needed to get - * the indices into the list of entries that will later be deduplicated. - * Contributions to bus Jacobians from other components are stored in those components. + * This sets values to the fault admittance, zero when cleared. It is needed + * to get the indices into the list of entries that will later be + * deduplicated. Contributions to bus Jacobians from other components are + * stored in those components. * * @return int - error code */ diff --git a/GridKit/Model/PhasorDynamics/Bus/BusFactory.hpp b/GridKit/Model/PhasorDynamics/Bus/BusFactory.hpp index 5daef28935..0e869e9a0f 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusFactory.hpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusFactory.hpp @@ -21,12 +21,15 @@ namespace GridKit using RealT = typename Model::Evaluator::RealT; using SignalNodeSetT = SignalNodeSet; using BusData = GridKit::PhasorDynamics::BusData; - using BusTypeT = typename GridKit::PhasorDynamics::BusData::BusType; + using BusTypeT = + typename GridKit::PhasorDynamics::BusData::BusType; public: BusFactory() = delete; - static BusBase* create(const BusData& data, SignalNodeSetT& signal_nodes) + static BusBase* create( + const BusData& data, SignalNodeSetT& signal_nodes + ) { switch (data.bus_type) { @@ -48,7 +51,9 @@ namespace GridKit } default: // Throw exception - ::GridKit::Utilities::Logger::error() << "Bus type " << static_cast(data.bus_type) << " unrecognized.\n"; + ::GridKit::Utilities::Logger::error() + << "Bus type " << static_cast(data.bus_type) + << " unrecognized.\n"; return nullptr; } } diff --git a/GridKit/Model/PhasorDynamics/Bus/BusImpl.hpp b/GridKit/Model/PhasorDynamics/Bus/BusImpl.hpp index f66777c0dc..c8e3e4887a 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusImpl.hpp @@ -13,7 +13,8 @@ namespace GridKit BusBase::~BusBase() = default; template - const Model::VariableMonitorBase* BusBase::getMonitor() const + const Model::VariableMonitorBase* BusBase:: + getMonitor() const { return monitor_.get(); } @@ -30,8 +31,7 @@ namespace GridKit * - Number of optimization parameters = 0 */ template - Bus::Bus() - : Vr0_(0.0), Vi0_(0.0) + Bus::Bus() : Vr0_(0.0), Vi0_(0.0) { size_ = 2; } @@ -61,21 +61,19 @@ namespace GridKit */ template Bus::Bus(const ModelDataT& data) - : Vr0_(data.Vr0), - Vi0_(data.Vi0) + : Vr0_(data.Vr0), Vi0_(data.Vi0) { - bus_id_ = data.bus_id; - size_ = 2; - monitor_ = std::make_unique("Bus", data.name, data.monitored_variables); + bus_id_ = data.bus_id; + size_ = 2; + monitor_ = + std::make_unique("Bus", data.name, data.monitored_variables); using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::Vr, [this] - { return Vr(); }); - monitor_->set(Variable::Vi, [this] - { return Vi(); }); - monitor_->set(Variable::Vm, [this] - { return std::sqrt(Vr() * Vr() + Vi() * Vi()); }); - monitor_->set(Variable::Va, [this] - { return std::atan2(Vi(), Vr()); }); + monitor_->set(Variable::Vr, [this] { return Vr(); }); + monitor_->set(Variable::Vi, [this] { return Vi(); }); + monitor_->set( + Variable::Vm, [this] { return std::sqrt(Vr() * Vr() + Vi() * Vi()); } + ); + monitor_->set(Variable::Va, [this] { return std::atan2(Vi(), Vr()); }); } template diff --git a/GridKit/Model/PhasorDynamics/Bus/BusInfiniteImpl.hpp b/GridKit/Model/PhasorDynamics/Bus/BusInfiniteImpl.hpp index df6ffb307c..ffcf0c3272 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusInfiniteImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusInfiniteImpl.hpp @@ -13,7 +13,8 @@ namespace GridKit BusBase::~BusBase() = default; template - const Model::VariableMonitorBase* BusBase::getMonitor() const + const Model::VariableMonitorBase* BusBase:: + getMonitor() const { return monitor_.get(); } @@ -60,21 +61,19 @@ namespace GridKit */ template BusInfinite::BusInfinite(const ModelDataT& data) - : Vr_(data.Vr0), - Vi_(data.Vi0) + : Vr_(data.Vr0), Vi_(data.Vi0) { - bus_id_ = data.bus_id; - size_ = 0; - monitor_ = std::make_unique("Bus", data.name, data.monitored_variables); + bus_id_ = data.bus_id; + size_ = 0; + monitor_ = + std::make_unique("Bus", data.name, data.monitored_variables); using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::Vr, [this] - { return Vr(); }); - monitor_->set(Variable::Vi, [this] - { return Vi(); }); - monitor_->set(Variable::Vm, [this] - { return std::sqrt(Vr() * Vr() + Vi() * Vi()); }); - monitor_->set(Variable::Va, [this] - { return std::atan2(Vi(), Vr()); }); + monitor_->set(Variable::Vr, [this] { return Vr(); }); + monitor_->set(Variable::Vi, [this] { return Vi(); }); + monitor_->set( + Variable::Vm, [this] { return std::sqrt(Vr() * Vr() + Vi() * Vi()); } + ); + monitor_->set(Variable::Va, [this] { return std::atan2(Vi(), Vr()); }); } template diff --git a/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageIn/BusSignalVoltageIn.hpp b/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageIn/BusSignalVoltageIn.hpp index f6cea3ca32..0393164720 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageIn/BusSignalVoltageIn.hpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageIn/BusSignalVoltageIn.hpp @@ -32,8 +32,8 @@ namespace GridKit * and Ii(); the resulting sums are published on signal outlets `ir` * and `ii`. * - * @note Signal ports have to be connected before allocate() is called, since - * the output signals are linked there. + * @note Signal ports have to be connected before allocate() is called, + * since the output signals are linked there. * * @warning The current sums are complete only after all attached * components have evaluated their residuals. A consumer of the @@ -155,7 +155,9 @@ namespace GridKit { Log::error() << "BusSignalVoltageIn: voltage inlet " << name << " read without a linked signal\n"; - throw std::runtime_error("BusSignalVoltageIn: voltage inlet has no linked signal"); + throw std::runtime_error( + "BusSignalVoltageIn: voltage inlet has no linked signal" + ); } return port.readSignal(); } @@ -163,7 +165,8 @@ namespace GridKit ScalarT Ir_{0.0}; ScalarT Ii_{0.0}; - /// Current sums are not system variables; the output signals carry no valid index. + /// Current sums are not system variables; the output signals carry no + /// valid index. IdxT ir_index_{INVALID_INDEX}; IdxT ii_index_{INVALID_INDEX}; diff --git a/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageIn/BusSignalVoltageInImpl.hpp b/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageIn/BusSignalVoltageInImpl.hpp index ab4a1db8e4..e4efe378df 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageIn/BusSignalVoltageInImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageIn/BusSignalVoltageInImpl.hpp @@ -34,7 +34,8 @@ namespace GridKit * its input signals only. */ template - BusSignalVoltageIn::BusSignalVoltageIn(ScalarT /* Vr */, ScalarT /* Vi */) + BusSignalVoltageIn:: + BusSignalVoltageIn(ScalarT /* Vr */, ScalarT /* Vi */) { size_ = 0; } @@ -48,20 +49,21 @@ namespace GridKit * @param[in] data - structure with bus data */ template - BusSignalVoltageIn::BusSignalVoltageIn(const ModelDataT& data) + BusSignalVoltageIn::BusSignalVoltageIn( + const ModelDataT& data + ) { - bus_id_ = data.bus_id; - size_ = 0; - monitor_ = std::make_unique("Bus", data.name, data.monitored_variables); + bus_id_ = data.bus_id; + size_ = 0; + monitor_ = + std::make_unique("Bus", data.name, data.monitored_variables); using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::Vr, [this] - { return Vr(); }); - monitor_->set(Variable::Vi, [this] - { return Vi(); }); - monitor_->set(Variable::Vm, [this] - { return std::sqrt(Vr() * Vr() + Vi() * Vi()); }); - monitor_->set(Variable::Va, [this] - { return std::atan2(Vi(), Vr()); }); + monitor_->set(Variable::Vr, [this] { return Vr(); }); + monitor_->set(Variable::Vi, [this] { return Vi(); }); + monitor_->set( + Variable::Vm, [this] { return std::sqrt(Vr() * Vr() + Vi() * Vi()); } + ); + monitor_->set(Variable::Va, [this] { return std::atan2(Vi(), Vr()); }); } template @@ -116,7 +118,8 @@ namespace GridKit * @return The configuration checks; passed() when valid. */ template - Model::ConfigurationChecks BusSignalVoltageIn::verify() const + Model::ConfigurationChecks BusSignalVoltageIn:: + verify() const { Model::ConfigurationChecks checks("BusSignalVoltageIn"); @@ -125,11 +128,17 @@ namespace GridKit const auto& port = ports_.in.template port(); if (!port.connected()) { - checks.fail(std::format("{} signal inlet is not connected; a default voltage is not allowed", name)); + checks.fail(std::format( + "{} signal inlet is not connected; a default voltage is not " + "allowed", + name + )); } else if (!port.linked()) { - checks.fail(std::format("{} signal attached with no linked source", name)); + checks.fail( + std::format("{} signal attached with no linked source", name) + ); } }; @@ -138,7 +147,11 @@ namespace GridKit const auto& port = ports_.out.template port(); if (port.connected() && !port.linked()) { - checks.fail(std::format("{} signal attached but not linked; connect signal ports before allocate()", name)); + checks.fail(std::format( + "{} signal attached but not linked; connect signal ports before " + "allocate()", + name + )); } }; diff --git a/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOut.cpp b/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOut.cpp index f105803080..d2d1531270 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOut.cpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOut.cpp @@ -17,7 +17,8 @@ namespace GridKit template int BusSignalVoltageOut::evaluateJacobian() { - Log::misc() << "BusSignalVoltageOut: Jacobian evaluation is not implemented\n"; + Log::misc( + ) << "BusSignalVoltageOut: Jacobian evaluation is not implemented\n"; return 0; } diff --git a/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOut.hpp b/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOut.hpp index 0e32ff0ee8..b79bb08f63 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOut.hpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOut.hpp @@ -151,7 +151,9 @@ namespace GridKit } } coo_jac_ = new CooMatrixT(num_rows, num_cols, nnz_); - coo_jac_->setDataPointers(J_rows_buffer_, J_cols_buffer_, J_vals_buffer_, memory::HOST); + coo_jac_->setDataPointers( + J_rows_buffer_, J_cols_buffer_, J_vals_buffer_, memory::HOST + ); } return 0; diff --git a/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOutImpl.hpp b/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOutImpl.hpp index 7e58c5a0a7..9490d9d56d 100644 --- a/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOutImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Bus/BusSignalVoltageOut/BusSignalVoltageOutImpl.hpp @@ -33,7 +33,9 @@ namespace GridKit * @brief Constructor setting initial values for the bus voltage. */ template - BusSignalVoltageOut::BusSignalVoltageOut(ScalarT Vr, ScalarT Vi) + BusSignalVoltageOut::BusSignalVoltageOut( + ScalarT Vr, ScalarT Vi + ) : Vr0_(Vr), Vi0_(Vi) { size_ = 2; @@ -45,22 +47,22 @@ namespace GridKit * @param[in] data - structure with bus data */ template - BusSignalVoltageOut::BusSignalVoltageOut(const ModelDataT& data) + BusSignalVoltageOut::BusSignalVoltageOut( + const ModelDataT& data + ) : Vr0_(data.Vr0), Vi0_(data.Vi0) { - bus_id_ = data.bus_id; - size_ = 2; - monitor_ = std::make_unique("Bus", data.name, data.monitored_variables); + bus_id_ = data.bus_id; + size_ = 2; + monitor_ = + std::make_unique("Bus", data.name, data.monitored_variables); using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::Vr, [this] - { return Vr(); }); - monitor_->set(Variable::Vi, [this] - { return Vi(); }); + monitor_->set(Variable::Vr, [this] { return Vr(); }); + monitor_->set(Variable::Vi, [this] { return Vi(); }); monitor_->set( Variable::Vm, [this] { return std::sqrt(Vr() * Vr() + Vi() * Vi()); } ); - monitor_->set(Variable::Va, [this] - { return std::atan2(Vi(), Vr()); }); + monitor_->set(Variable::Va, [this] { return std::atan2(Vi(), Vr()); }); } template @@ -135,7 +137,8 @@ namespace GridKit * @return The configuration checks; passed() when valid. */ template - Model::ConfigurationChecks BusSignalVoltageOut::verify() const + Model::ConfigurationChecks BusSignalVoltageOut:: + verify() const { Model::ConfigurationChecks checks("BusSignalVoltageOut"); @@ -144,13 +147,11 @@ namespace GridKit const auto& port = ports_.in.template port(); if (!port.connected()) { - checks.fail( - std::format( - "{} signal inlet is not connected; a default current is not " - "allowed", - name - ) - ); + checks.fail(std::format( + "{} signal inlet is not connected; a default current is not " + "allowed", + name + )); } else if (!port.linked()) { @@ -165,13 +166,11 @@ namespace GridKit const auto& port = ports_.out.template port(); if (port.connected() && !port.linked()) { - checks.fail( - std::format( - "{} signal attached but not linked; connect signal ports before " - "allocate()", - name - ) - ); + checks.fail(std::format( + "{} signal attached but not linked; connect signal ports before " + "allocate()", + name + )); } }; @@ -194,12 +193,14 @@ namespace GridKit } template - int BusSignalVoltageOut::setFault(bool status, RealT R, RealT X) + int BusSignalVoltageOut::setFault( + bool status, RealT R, RealT X + ) { if (status && !(ZERO < R * R + X * X)) { - Log::error() - << "BusSignalVoltageOut: fault impedance R + jX must be nonzero\n"; + Log::error( + ) << "BusSignalVoltageOut: fault impedance R + jX must be nonzero\n"; return 1; } @@ -234,7 +235,9 @@ namespace GridKit * @return int 0 if successful, non-zero otherwise. */ template - int BusSignalVoltageOut::setAbsoluteTolerance(RealT rel_tol) + int BusSignalVoltageOut::setAbsoluteTolerance( + RealT rel_tol + ) { abs_tol_.setToConst(static_cast(rel_tol)); return 0; diff --git a/GridKit/Model/PhasorDynamics/BusBase.hpp b/GridKit/Model/PhasorDynamics/BusBase.hpp index 6dec007193..f81675c898 100644 --- a/GridKit/Model/PhasorDynamics/BusBase.hpp +++ b/GridKit/Model/PhasorDynamics/BusBase.hpp @@ -41,7 +41,8 @@ namespace GridKit virtual ~BusBase(); - /// Report every configuration problem; passed() when the bus can initialize. + /// Report every configuration problem; passed() when the bus can + /// initialize. virtual Model::ConfigurationChecks verify() const { return {}; @@ -119,7 +120,8 @@ namespace GridKit * Only HOST data is bound because PhasorDynamics currently evaluates * models on the CPU. Supporting DEVICE data would also require sharing * the matching DEVICE pointer and keeping the HOST and DEVICE copies in - * sync. This bind operation does neither, so DEVICE access is unsupported. + * sync. This bind operation does neither, so DEVICE access is + * unsupported. * * @param[in] y - System state vector * @param[in] yp - System state derivative vector @@ -129,14 +131,16 @@ namespace GridKit * * @pre System vectors hold current HOST data of at least offset + size() * elements. This bus's vectors are unallocated or already bound. - * @post allocated_ is true and y_, yp_, f_, abs_tol_ alias system storage. + * @post allocated_ is true and y_, yp_, f_, abs_tol_ alias system + * storage. * * @return 0 if successful, non-zero otherwise. */ - int bind(VectorT& y, VectorT& yp, VectorT& f, VectorT& abs_tol, IdxT offset) + int bind( + VectorT& y, VectorT& yp, VectorT& f, VectorT& abs_tol, IdxT offset + ) { - if (y.getSize() < offset + size_ - || yp.getSize() < offset + size_ + if (y.getSize() < offset + size_ || yp.getSize() < offset + size_ || f.getSize() < offset + size_ || abs_tol.getSize() < offset + size_) { @@ -150,21 +154,26 @@ namespace GridKit auto* f_data = f.getData(memory::HOST); auto* abs_tol_data = abs_tol.getData(memory::HOST); - if (y_data == nullptr || yp_data == nullptr - || f_data == nullptr || abs_tol_data == nullptr) + if (y_data == nullptr || yp_data == nullptr || f_data == nullptr + || abs_tol_data == nullptr) { - Log::error() << "BusBase::bind - system vector data is null or stale\n"; + Log::error( + ) << "BusBase::bind - system vector data is null or stale\n"; return 1; } - const int y_status = y_.setData(y_data + offset, size_, memory::HOST); - const int yp_status = yp_.setData(yp_data + offset, size_, memory::HOST); - const int f_status = f_.setData(f_data + offset, size_, memory::HOST); - const int abs_tol_status = abs_tol_.setData(abs_tol_data + offset, size_, memory::HOST); + const int y_status = y_.setData(y_data + offset, size_, memory::HOST); + const int yp_status = + yp_.setData(yp_data + offset, size_, memory::HOST); + const int f_status = f_.setData(f_data + offset, size_, memory::HOST); + const int abs_tol_status = + abs_tol_.setData(abs_tol_data + offset, size_, memory::HOST); - if (y_status != 0 || yp_status != 0 || f_status != 0 || abs_tol_status != 0) + if (y_status != 0 || yp_status != 0 || f_status != 0 + || abs_tol_status != 0) { - Log::error() << "BusBase::bind - failed to bind vectors to system storage\n"; + Log::error( + ) << "BusBase::bind - failed to bind vectors to system storage\n"; return 1; } diff --git a/GridKit/Model/PhasorDynamics/Component.hpp b/GridKit/Model/PhasorDynamics/Component.hpp index d738aea775..959a28eb0b 100644 --- a/GridKit/Model/PhasorDynamics/Component.hpp +++ b/GridKit/Model/PhasorDynamics/Component.hpp @@ -148,24 +148,28 @@ namespace GridKit * Only HOST data is bound because PhasorDynamics currently evaluates * models on the CPU. Supporting DEVICE data would also require sharing * the matching DEVICE pointer and keeping the HOST and DEVICE copies in - * sync. This bind operation does neither, so DEVICE access is unsupported. + * sync. This bind operation does neither, so DEVICE access is + * unsupported. * * @param[in] y - System state vector * @param[in] yp - System state derivative vector * @param[in] f - System residual vector * @param[in] abs_tol - System absolute tolerance vector - * @param[in] offset - Position of this component's slice in the system vectors + * @param[in] offset - Position of this component's slice in the system + * vectors * * @pre System vectors hold current HOST data of at least offset + size() * elements. This component's vectors are unallocated or already bound. - * @post allocated_ is true and y_, yp_, f_, abs_tol_ alias system storage. + * @post allocated_ is true and y_, yp_, f_, abs_tol_ alias system + * storage. * * @return 0 if successful, non-zero otherwise. */ - int bind(VectorT& y, VectorT& yp, VectorT& f, VectorT& abs_tol, IdxT offset) + int bind( + VectorT& y, VectorT& yp, VectorT& f, VectorT& abs_tol, IdxT offset + ) { - if (y.getSize() < offset + size_ - || yp.getSize() < offset + size_ + if (y.getSize() < offset + size_ || yp.getSize() < offset + size_ || f.getSize() < offset + size_ || abs_tol.getSize() < offset + size_) { @@ -179,21 +183,26 @@ namespace GridKit auto* f_data = f.getData(memory::HOST); auto* abs_tol_data = abs_tol.getData(memory::HOST); - if (y_data == nullptr || yp_data == nullptr - || f_data == nullptr || abs_tol_data == nullptr) + if (y_data == nullptr || yp_data == nullptr || f_data == nullptr + || abs_tol_data == nullptr) { - Log::error() << "Component::bind - system vector data is null or stale\n"; + Log::error( + ) << "Component::bind - system vector data is null or stale\n"; return 1; } - const int y_status = y_.setData(y_data + offset, size_, memory::HOST); - const int yp_status = yp_.setData(yp_data + offset, size_, memory::HOST); - const int f_status = f_.setData(f_data + offset, size_, memory::HOST); - const int abs_tol_status = abs_tol_.setData(abs_tol_data + offset, size_, memory::HOST); + const int y_status = y_.setData(y_data + offset, size_, memory::HOST); + const int yp_status = + yp_.setData(yp_data + offset, size_, memory::HOST); + const int f_status = f_.setData(f_data + offset, size_, memory::HOST); + const int abs_tol_status = + abs_tol_.setData(abs_tol_data + offset, size_, memory::HOST); - if (y_status != 0 || yp_status != 0 || f_status != 0 || abs_tol_status != 0) + if (y_status != 0 || yp_status != 0 || f_status != 0 + || abs_tol_status != 0) { - Log::error() << "Component::bind - failed to bind vectors to system storage\n"; + Log::error( + ) << "Component::bind - failed to bind vectors to system storage\n"; return 1; } @@ -359,7 +368,9 @@ namespace GridKit } } coo_jac_ = new CooMatrixT(num_rows, num_cols, nnz_); - coo_jac_->setDataPointers(J_rows_buffer_, J_cols_buffer_, J_vals_buffer_, memory::HOST); + coo_jac_->setDataPointers( + J_rows_buffer_, J_cols_buffer_, J_vals_buffer_, memory::HOST + ); } return 0; @@ -371,7 +382,8 @@ namespace GridKit * @note Currently only used for testing, particularly for comparing * Enzyme and DependencyTracking Jacobians. * - * @todo The matrix is only computed on the first call, and the data is stale on subsequent calls. + * @todo The matrix is only computed on the first call, and the data is + * stale on subsequent calls. * @todo Unify with system-level construction that retains map_to_csr_. */ int constructCsrFromCoo() @@ -390,10 +402,19 @@ namespace GridKit IdxT* cols = new IdxT[static_cast(nnz_)]; RealT* vals = new RealT[static_cast(nnz_)]; - std::copy(coo_jac_->getColData(), coo_jac_->getColData() + nnz_, cols); + std::copy( + coo_jac_->getColData(), coo_jac_->getColData() + nnz_, cols + ); std::copy(coo_jac_->getValues(), coo_jac_->getValues() + nnz_, vals); - csr_jac_ = new CsrMatrixT(coo_jac_->getNumRows(), coo_jac_->getNumColumns(), nnz_, &row_ptrs, &cols, &vals); + csr_jac_ = new CsrMatrixT( + coo_jac_->getNumRows(), + coo_jac_->getNumColumns(), + nnz_, + &row_ptrs, + &cols, + &vals + ); } return 0; @@ -402,19 +423,20 @@ namespace GridKit /** * @brief CSR construction from Dependency maps. * - * This merges the y and yp dependencies back to the same location in the Jacobian. - * See \ref initializeDependencyTrackingVariableNumbers() for the initial even/odd split. - * The DependencyMap manipulations are expected to be a bottleneck, so this is not intended - * for simulations. + * This merges the y and yp dependencies back to the same location in the + * Jacobian. See \ref initializeDependencyTrackingVariableNumbers() for + * the initial even/odd split. The DependencyMap manipulations are + * expected to be a bottleneck, so this is not intended for simulations. * * @note Currently only used for testing, particularly for comparing - * Enzyme and DependencyTracking Jacobians. Will be used to benchmark the - * performance of the two methods in the near future. + * Enzyme and DependencyTracking Jacobians. Will be used to + * benchmark the performance of the two methods in the near future. * - * @note For dependency maps, there is no functional difference in Jacobian construction - * between components and systems. However, the resulting component-level CSR will - * be invalid if tracked indices are greater than the local `size_`, and should not - * be used for simulation. Systems do not rely on the component-level results. + * @note For dependency maps, there is no functional difference in + * Jacobian construction between components and systems. However, the + * resulting component-level CSR will be invalid if tracked indices are + * greater than the local `size_`, and should not be used for simulation. + * Systems do not rely on the component-level results. */ int constructCsrFromDependencies() requires std::is_same_v @@ -442,8 +464,9 @@ namespace GridKit // Divide the stored index by 2 const size_t jac_col = static_cast(col / 2); - // For counting purposes, there is no need to distinguish odd and even indices. - // Attempt to insert the column into the row and increment nnz for new entries. + // For counting purposes, there is no need to distinguish odd and + // even indices. Attempt to insert the column into the row and + // increment nnz for new entries. if (row_map.insert({jac_col, RealT{}}).second) { ++nnz; @@ -489,8 +512,9 @@ namespace GridKit } } - nnz_ = nnz; - csr_jac_ = new CsrMatrixT(size_, size_, nnz_, &row_ptrs, &cols, &vals); + nnz_ = nnz; + csr_jac_ = + new CsrMatrixT(size_, size_, nnz_, &row_ptrs, &cols, &vals); } else { @@ -536,7 +560,8 @@ namespace GridKit * @brief Initialize DependencyTracking variable numbers. * * @note Assigns even indices to y and odd indices to yp. - * Should be called in initialize(), after variables have been set (and updated as needed). + * Should be called in initialize(), after variables have been set + * (and updated as needed). */ int initializeDependencyTrackingVariableNumbers() requires std::is_same_v diff --git a/GridKit/Model/PhasorDynamics/ComponentData.hpp b/GridKit/Model/PhasorDynamics/ComponentData.hpp index 943b2bf68b..fa9a873ee1 100644 --- a/GridKit/Model/PhasorDynamics/ComponentData.hpp +++ b/GridKit/Model/PhasorDynamics/ComponentData.hpp @@ -56,7 +56,8 @@ namespace GridKit std::string device_class; /// Mapping of parameters to parameter values - std::map> parameters; + std::map> + parameters; /// Mapping of terminal attachments to bus identifiers std::map buses; @@ -73,7 +74,8 @@ namespace GridKit /// Disambiguation string for this device std::string disambiguation_string; - /// Device class and disambiguation string (e.g. "Genrou_1"), for component lookups + /// Device class and disambiguation string (e.g. "Genrou_1"), for + /// component lookups std::string label() const { return device_class + "_" + disambiguation_string; diff --git a/GridKit/Model/PhasorDynamics/ComponentDataJSONParser.hpp b/GridKit/Model/PhasorDynamics/ComponentDataJSONParser.hpp index feef7ca717..9277a47a2b 100644 --- a/GridKit/Model/PhasorDynamics/ComponentDataJSONParser.hpp +++ b/GridKit/Model/PhasorDynamics/ComponentDataJSONParser.hpp @@ -70,28 +70,32 @@ namespace GridKit // handles std::variant out of the box if (raw_parameter.value().is_string()) { - auto str = raw_parameter.value().template get(); - c.parameters[key.value()] = raw_parameter.value().template get(); + auto str = raw_parameter.value().template get(); + c.parameters[key.value()] = + raw_parameter.value().template get(); } else if (raw_parameter.value().is_boolean()) { - c.parameters[key.value()] = raw_parameter.value().template get(); + c.parameters[key.value()] = + raw_parameter.value().template get(); } else if (raw_parameter.value().is_number_float()) { - c.parameters[key.value()] = raw_parameter.value().template get(); + 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(); + c.parameters[key.value()] = + raw_parameter.value().template get(); } else { Log::error() << "\n\tInvalid initial parameter value type: " - << "\"" << raw_parameter.key() << "\": " - << raw_parameter.value() - << " (typed as \"" << raw_parameter.value().type_name() - << "\")." << error_context.str() << std::endl; + << "\"" << raw_parameter.key() + << "\": " << raw_parameter.value() << " (typed as \"" + << raw_parameter.value().type_name() << "\")." + << error_context.str() << std::endl; } } else @@ -106,7 +110,8 @@ namespace GridKit // intentionally split into buses, signal inputs, and signal outputs. // This backward-compatible flat JSON "ports" parsing SHOULD NOT become // the supported design; it only avoids changing every tracked case in - // this PR. The JSON schema should be split once the ingress changes are merged + // this PR. The JSON schema should be split once the ingress changes are + // merged for (auto& raw_port : j.at("ports").items()) { auto bus = Utilities::enum_cast(raw_port.key()); @@ -137,8 +142,7 @@ namespace GridKit } Log::error() << "\n\tInvalid port mapping: \"" << raw_port.key() - << "\" has no value." << error_context.str() - << std::endl; + << "\" has no value." << error_context.str() << std::endl; throw std::runtime_error("JSON parser failed"); } diff --git a/GridKit/Model/PhasorDynamics/Controller/REECB/Reecb.cpp b/GridKit/Model/PhasorDynamics/Controller/REECB/Reecb.cpp index f8aa3ed9e2..09b5a462fa 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REECB/Reecb.cpp +++ b/GridKit/Model/PhasorDynamics/Controller/REECB/Reecb.cpp @@ -13,7 +13,8 @@ namespace GridKit namespace Controller { /** - * @brief Report that a separate Jacobian is unavailable in the plain-real build. + * @brief Report that a separate Jacobian is unavailable in the plain-real + * build. */ template int Reecb::evaluateJacobian() diff --git a/GridKit/Model/PhasorDynamics/Controller/REECB/Reecb.hpp b/GridKit/Model/PhasorDynamics/Controller/REECB/Reecb.hpp index 8560fe1c33..04aa9b147f 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REECB/Reecb.hpp +++ b/GridKit/Model/PhasorDynamics/Controller/REECB/Reecb.hpp @@ -29,38 +29,64 @@ namespace GridKit /// Internal variables and residual rows of a `Reecb`. enum class ReecbInternalVariables : size_t { - VMEAS, ///< \f$V^\mathrm{meas}\f$ Differential filtered terminal voltage [p.u.] - PMEAS, ///< \f$P^\mathrm{meas}\f$ Differential filtered electrical power on component base [p.u.] - XPIQ, ///< \f$x_Q^\mathrm{PI}\f$ Differential reactive-power PI state [p.u.] - XPIV, ///< \f$x_V^\mathrm{PI}\f$ Differential voltage-control PI state on component base [p.u.] - QV, ///< \f$Q_V\f$ Differential reactive-current command lag state on component base [p.u.] - PORD, ///< \f$P^\mathrm{ord}\f$ Differential filtered active-power order on component base [p.u.] - VT, ///< \f$V_T\f$ Algebraic terminal-voltage magnitude [p.u.] - VSAFE, ///< \f$V_\mathrm{safe}^\mathrm{meas}\f$ Algebraic safe measured voltage [p.u.] - SDIP, ///< \f$s_\mathrm{dip}\f$ Algebraic voltage-band gate [-] - IQV, ///< \f$I_q^\mathrm{inj}\f$ Algebraic reactive-current injection on component base [p.u.] - QREF, ///< \f$Q^\mathrm{ref}\f$ Algebraic reactive-power reference on component base [p.u.] - EQ, ///< \f$e_Q\f$ Algebraic reactive-power error on component base [p.u.] - VPIQ, ///< \f$V_Q^\mathrm{PI}\f$ Algebraic reactive-power PI output [p.u.] - EPIV, ///< \f$e_V^\mathrm{PI}\f$ Algebraic voltage-control error [p.u.] - RPORD, ///< \f$r_P^\mathrm{ord}\f$ Algebraic limited active-power order rate [p.u./s] - ILCAP, ///< \f$I_L^\mathrm{cap}\f$ Algebraic off-axis current capacity on component base [p.u.] - IQMAX, ///< \f$I_q^\max\f$ Algebraic reactive-current limit on component base [p.u.] - IPMAX, ///< \f$I_p^\max\f$ Algebraic active-current limit on component base [p.u.] - IQBASE, ///< \f$I_q^\mathrm{base}\f$ Algebraic voltage-controller current on component base [p.u.] - IQRAW, ///< \f$I_q^\mathrm{raw}\f$ Algebraic pre-limit reactive-current command on component base [p.u.] - IQCMD, ///< \f$I_q^\mathrm{cmd}\f$ Algebraic reactive-current command output on system base [p.u.] - IPCMD, ///< \f$I_p^\mathrm{cmd}\f$ Algebraic active-current command output on system base [p.u.] + VMEAS, ///< \f$V^\mathrm{meas}\f$ Differential filtered terminal voltage + ///< [p.u.] + PMEAS, ///< \f$P^\mathrm{meas}\f$ Differential filtered electrical power + ///< on component base [p.u.] + XPIQ, ///< \f$x_Q^\mathrm{PI}\f$ Differential reactive-power PI state + ///< [p.u.] + XPIV, ///< \f$x_V^\mathrm{PI}\f$ Differential voltage-control PI state + ///< on component base [p.u.] + QV, ///< \f$Q_V\f$ Differential reactive-current command lag state on + ///< component base [p.u.] + PORD, ///< \f$P^\mathrm{ord}\f$ Differential filtered active-power order + ///< on component base [p.u.] + VT, ///< \f$V_T\f$ Algebraic terminal-voltage magnitude [p.u.] + VSAFE, ///< \f$V_\mathrm{safe}^\mathrm{meas}\f$ Algebraic safe measured + ///< voltage [p.u.] + SDIP, ///< \f$s_\mathrm{dip}\f$ Algebraic voltage-band gate [-] + IQV, ///< \f$I_q^\mathrm{inj}\f$ Algebraic reactive-current injection on + ///< component base [p.u.] + QREF, ///< \f$Q^\mathrm{ref}\f$ Algebraic reactive-power reference on + ///< component base [p.u.] + EQ, ///< \f$e_Q\f$ Algebraic reactive-power error on component base + ///< [p.u.] + VPIQ, ///< \f$V_Q^\mathrm{PI}\f$ Algebraic reactive-power PI output + ///< [p.u.] + EPIV, ///< \f$e_V^\mathrm{PI}\f$ Algebraic voltage-control error [p.u.] + RPORD, ///< \f$r_P^\mathrm{ord}\f$ Algebraic limited active-power order + ///< rate [p.u./s] + ILCAP, ///< \f$I_L^\mathrm{cap}\f$ Algebraic off-axis current capacity + ///< on component base [p.u.] + IQMAX, ///< \f$I_q^\max\f$ Algebraic reactive-current limit on component + ///< base [p.u.] + IPMAX, ///< \f$I_p^\max\f$ Algebraic active-current limit on component + ///< base [p.u.] + IQBASE, ///< \f$I_q^\mathrm{base}\f$ Algebraic voltage-controller + ///< current on component base [p.u.] + IQRAW, ///< \f$I_q^\mathrm{raw}\f$ Algebraic pre-limit reactive-current + ///< command on component base [p.u.] + IQCMD, ///< \f$I_q^\mathrm{cmd}\f$ Algebraic reactive-current command + ///< output on system base [p.u.] + IPCMD, ///< \f$I_p^\mathrm{cmd}\f$ Algebraic active-current command + ///< output on system base [p.u.] }; /// External signal variables read or initialized by a `Reecb`. enum class ReecbExternalVariables : size_t { - PE, ///< \f$P_e\f$ Optional Known active-power feedback input on system base [p.u.] - QGEN, ///< \f$Q^\mathrm{gen}\f$ Optional Known reactive-power feedback input on system base [p.u.] - QEXT, ///< \f$Q^\mathrm{ext}\f$ Optional Unknown Volt/VAr reference input: system-base reactive power [p.u.], or the terminal-voltage reference [p.u.] when \f$s_Q=1\f$ and \f$s_V=0\f$ - PFAREF, ///< \f$\phi^\mathrm{ref}\f$ Optional Unknown power-factor angle-reference input [rad] - PREF, ///< \f$P^\mathrm{ref}\f$ Optional Unknown active-power reference input on system base [p.u.] + PE, ///< \f$P_e\f$ Optional Known active-power feedback input on system + ///< base [p.u.] + QGEN, ///< \f$Q^\mathrm{gen}\f$ Optional Known reactive-power feedback + ///< input on system base [p.u.] + QEXT, ///< \f$Q^\mathrm{ext}\f$ Optional Unknown Volt/VAr reference + ///< input: system-base reactive power [p.u.], or the + ///< terminal-voltage reference [p.u.] when \f$s_Q=1\f$ and + ///< \f$s_V=0\f$ + PFAREF, ///< \f$\phi^\mathrm{ref}\f$ Optional Unknown power-factor + ///< angle-reference input [rad] + PREF, ///< \f$P^\mathrm{ref}\f$ Optional Unknown active-power reference + ///< input on system base [p.u.] }; /** @@ -155,10 +181,14 @@ namespace GridKit }; /// Smooth asymmetric slew-rate limiter. - [[gnu::always_inline]] static inline ScalarT aslew(ScalarT rate, RealT lower, RealT upper); + [[gnu::always_inline]] static inline ScalarT aslew( + ScalarT rate, RealT lower, RealT upper + ); /// Smooth anti-windup derivative within a moving symmetric band. - [[gnu::always_inline]] static inline ScalarT awband(ScalarT state, ScalarT rate, ScalarT band); + [[gnu::always_inline]] static inline ScalarT awband( + ScalarT state, ScalarT rate, ScalarT band + ); /// Smooth nonnegative root of a current-circle squared radius. template @@ -169,10 +199,14 @@ namespace GridKit /// Overflow-resistant difference of squares. template - [[gnu::always_inline]] static inline ValueT circleSquare(RealT limit, ValueT high); + [[gnu::always_inline]] static inline ValueT circleSquare( + RealT limit, ValueT high + ); /// Solve a feasible initial limit at or above `lower`. - static std::optional solveInitialLimit(RealT lower, RealT high, RealT low); + static std::optional solveInitialLimit( + RealT lower, RealT high, RealT low + ); bool buildInitialPoint(InitialPoint& point); void commitInitialPoint(const InitialPoint& point); @@ -183,13 +217,14 @@ namespace GridKit void setDerivedParameters(); static RealT logOneMinusExp(RealT x); - bool iclamp(RealT output, RealT lower, RealT upper, RealT& input) const; + bool iclamp(RealT output, RealT lower, RealT upper, RealT& input) const; ScalarT& Vr(); ScalarT& Vi(); - static constexpr RealT TIME_CONSTANT_MINIMUM = static_cast(1.0e-3); - static void logTimeConstantWarning(); + static constexpr RealT TIME_CONSTANT_MINIMUM = + static_cast(1.0e-3); + static void logTimeConstantWarning(); static constexpr RealT VMEAS_MINIMUM = static_cast(0.01); diff --git a/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbData.hpp b/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbData.hpp index 494ca3d915..98e56a8787 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbData.hpp +++ b/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbData.hpp @@ -18,67 +18,104 @@ namespace GridKit enum class ReecbParameters : size_t { mva, ///< \f$S^\mathrm{base}\f$ Component power base [MVA] - PfFlag, ///< \f$s_\mathrm{pf}\f$ Power-factor control selector: true = power-factor control, false = reactive-power control [boolean] - VFlag, ///< \f$s_V\f$ Voltage-reference selector under \f$s_Q=1\f$: true = cascaded Q-PI voltage command, false = direct external voltage reference [boolean] - QFlag, ///< \f$s_Q\f$ Reactive-path selector: true = Volt/VAr PI control, false = reactive-current lag [boolean] - Pqflag, ///< \f$s_\mathrm{pq}\f$ Converter current-priority selector: true = P priority, false = Q priority [boolean] - Trv, ///< \f$T_\mathrm{rv}\f$ Voltage-measurement filter time constant [sec] - Tp, ///< \f$T_\mathrm{p}\f$ Electrical-power measurement filter time constant [sec] - Vref0, ///< \f$V^\mathrm{ref}\f$ Reactive-current-injection voltage reference [p.u.] - Vdip, ///< \f$V_\mathrm{dip}\f$ Low-voltage threshold for the voltage-band gate [p.u.] - Vup, ///< \f$V_\mathrm{up}\f$ High-voltage threshold for the voltage-band gate [p.u.] - dbd1, ///< \f$D_1^\mathrm{db}\f$ Lower voltage-error deadband threshold [p.u.] - dbd2, ///< \f$D_2^\mathrm{db}\f$ Upper voltage-error deadband threshold [p.u.] - kqv, ///< \f$K_\mathrm{qv}\f$ Reactive-current injection gain [p.u.] - Iql1, ///< \f$I_{q,\mathrm{inj}}^\min\f$ Minimum reactive-current injection on component base [p.u.] - Iqh1, ///< \f$I_{q,\mathrm{inj}}^\max\f$ Maximum reactive-current injection on component base [p.u.] - Qmax, ///< \f$Q^\max\f$ Maximum reactive-power control output on component base [p.u.] - Qmin, ///< \f$Q^\min\f$ Minimum reactive-power control output on component base [p.u.] - Kqp, ///< \f$K_\mathrm{qp}\f$ Reactive-power proportional gain [p.u.] - Kqi, ///< \f$K_\mathrm{qi}\f$ Reactive-power integral gain [p.u./s] - Vmax, ///< \f$V^\max\f$ Maximum voltage-control output [p.u.] - Vmin, ///< \f$V^\min\f$ Minimum voltage-control output [p.u.] - Kvp, ///< \f$K_\mathrm{vp}\f$ Voltage-control proportional gain [p.u.] - Kvi, ///< \f$K_\mathrm{vi}\f$ Voltage-control integral gain [p.u./s] - Tiq, ///< \f$T_\mathrm{iq}\f$ Reactive-current command lag time constant [sec] - Tpord, ///< \f$T_\mathrm{pord}\f$ Active-power order filter time constant [sec] - dPmax, ///< \f$R_P^\max\f$ Positive active-power ramp-rate limit on component base [p.u./s] - dPmin, ///< \f$R_P^\min\f$ Negative active-power ramp-rate limit on component base [p.u./s] - Pmax, ///< \f$P^\max\f$ Maximum active-power order limit on component base [p.u.] - Pmin, ///< \f$P^\min\f$ Minimum active-power order limit on component base [p.u.] - Imax, ///< \f$I^\max\f$ Maximum converter current on component base [p.u.] + PfFlag, ///< \f$s_\mathrm{pf}\f$ Power-factor control selector: true = + ///< power-factor control, false = reactive-power control + ///< [boolean] + VFlag, ///< \f$s_V\f$ Voltage-reference selector under \f$s_Q=1\f$: true + ///< = cascaded Q-PI voltage command, false = direct external + ///< voltage reference [boolean] + QFlag, ///< \f$s_Q\f$ Reactive-path selector: true = Volt/VAr PI + ///< control, false = reactive-current lag [boolean] + Pqflag, ///< \f$s_\mathrm{pq}\f$ Converter current-priority selector: + ///< true = P priority, false = Q priority [boolean] + Trv, ///< \f$T_\mathrm{rv}\f$ Voltage-measurement filter time constant + ///< [sec] + Tp, ///< \f$T_\mathrm{p}\f$ Electrical-power measurement filter time + ///< constant [sec] + Vref0, ///< \f$V^\mathrm{ref}\f$ Reactive-current-injection voltage + ///< reference [p.u.] + Vdip, ///< \f$V_\mathrm{dip}\f$ Low-voltage threshold for the + ///< voltage-band gate [p.u.] + Vup, ///< \f$V_\mathrm{up}\f$ High-voltage threshold for the + ///< voltage-band gate [p.u.] + dbd1, ///< \f$D_1^\mathrm{db}\f$ Lower voltage-error deadband threshold + ///< [p.u.] + dbd2, ///< \f$D_2^\mathrm{db}\f$ Upper voltage-error deadband threshold + ///< [p.u.] + kqv, ///< \f$K_\mathrm{qv}\f$ Reactive-current injection gain [p.u.] + Iql1, ///< \f$I_{q,\mathrm{inj}}^\min\f$ Minimum reactive-current + ///< injection on component base [p.u.] + Iqh1, ///< \f$I_{q,\mathrm{inj}}^\max\f$ Maximum reactive-current + ///< injection on component base [p.u.] + Qmax, ///< \f$Q^\max\f$ Maximum reactive-power control output on + ///< component base [p.u.] + Qmin, ///< \f$Q^\min\f$ Minimum reactive-power control output on + ///< component base [p.u.] + Kqp, ///< \f$K_\mathrm{qp}\f$ Reactive-power proportional gain [p.u.] + Kqi, ///< \f$K_\mathrm{qi}\f$ Reactive-power integral gain [p.u./s] + Vmax, ///< \f$V^\max\f$ Maximum voltage-control output [p.u.] + Vmin, ///< \f$V^\min\f$ Minimum voltage-control output [p.u.] + Kvp, ///< \f$K_\mathrm{vp}\f$ Voltage-control proportional gain [p.u.] + Kvi, ///< \f$K_\mathrm{vi}\f$ Voltage-control integral gain [p.u./s] + Tiq, ///< \f$T_\mathrm{iq}\f$ Reactive-current command lag time constant + ///< [sec] + Tpord, ///< \f$T_\mathrm{pord}\f$ Active-power order filter time + ///< constant [sec] + dPmax, ///< \f$R_P^\max\f$ Positive active-power ramp-rate limit on + ///< component base [p.u./s] + dPmin, ///< \f$R_P^\min\f$ Negative active-power ramp-rate limit on + ///< component base [p.u./s] + Pmax, ///< \f$P^\max\f$ Maximum active-power order limit on component + ///< base [p.u.] + Pmin, ///< \f$P^\min\f$ Minimum active-power order limit on component + ///< base [p.u.] + Imax, ///< \f$I^\max\f$ Maximum converter current on component base + ///< [p.u.] }; /// Buses for the REECB electrical-control model. enum class ReecbBuses : size_t { - bus, ///< \f$V_\mathrm{r},V_\mathrm{i}\f$ Required Known terminal-bus voltage [p.u.] + bus, ///< \f$V_\mathrm{r},V_\mathrm{i}\f$ Required Known terminal-bus + ///< voltage [p.u.] }; /// Signal inputs for the REECB electrical-control model. enum class ReecbSignalInputs : size_t { - pe, ///< \f$P_e\f$ Optional Known active-power feedback input on system base [p.u.] - qgen, ///< \f$Q^\mathrm{gen}\f$ Optional Known reactive-power feedback input on system base [p.u.] - qext, ///< \f$Q^\mathrm{ext}\f$ Optional Unknown Volt/VAr reference input: system-base reactive power [p.u.], or the terminal-voltage reference [p.u.] when \f$s_Q=1\f$ and \f$s_V=0\f$ - pfaref, ///< \f$\phi^\mathrm{ref}\f$ Optional Unknown power-factor angle-reference input [rad] - pref, ///< \f$P^\mathrm{ref}\f$ Optional Unknown active-power reference input on system base [p.u.] + pe, ///< \f$P_e\f$ Optional Known active-power feedback input on system + ///< base [p.u.] + qgen, ///< \f$Q^\mathrm{gen}\f$ Optional Known reactive-power feedback + ///< input on system base [p.u.] + qext, ///< \f$Q^\mathrm{ext}\f$ Optional Unknown Volt/VAr reference + ///< input: system-base reactive power [p.u.], or the + ///< terminal-voltage reference [p.u.] when \f$s_Q=1\f$ and + ///< \f$s_V=0\f$ + pfaref, ///< \f$\phi^\mathrm{ref}\f$ Optional Unknown power-factor + ///< angle-reference input [rad] + pref, ///< \f$P^\mathrm{ref}\f$ Optional Unknown active-power reference + ///< input on system base [p.u.] }; /// Signal outputs for the REECB electrical-control model. enum class ReecbSignalOutputs : size_t { - iqcmd, ///< \f$I_q^\mathrm{cmd}\f$ Optional Known reactive-current command output on system base [p.u.] - ipcmd, ///< \f$I_p^\mathrm{cmd}\f$ Optional Known active-current command output on system base [p.u.] + iqcmd, ///< \f$I_q^\mathrm{cmd}\f$ Optional Known reactive-current + ///< command output on system base [p.u.] + ipcmd, ///< \f$I_p^\mathrm{cmd}\f$ Optional Known active-current command + ///< output on system base [p.u.] }; /// Variables available through the monitor interface. enum class ReecbMonitorableVariables : size_t { - iqcmd, ///< \f$I_q^\mathrm{cmd}\f$ Reactive-current command output on system base [p.u.] - ipcmd, ///< \f$I_p^\mathrm{cmd}\f$ Active-current command output on system base [p.u.] + iqcmd, ///< \f$I_q^\mathrm{cmd}\f$ Reactive-current command output on + ///< system base [p.u.] + ipcmd, ///< \f$I_p^\mathrm{cmd}\f$ Active-current command output on + ///< system base [p.u.] vmeas, ///< \f$V^\mathrm{meas}\f$ Filtered terminal voltage [p.u.] - pmeas, ///< \f$P^\mathrm{meas}\f$ Filtered electrical power on component base [p.u.] + pmeas, ///< \f$P^\mathrm{meas}\f$ Filtered electrical power on component + ///< base [p.u.] }; /// Initial values for the REECB electrical-control model. @@ -87,7 +124,8 @@ namespace GridKit }; /** - * @brief Model data for REECB parameters, bus and signal ports, and monitored variables. + * @brief Model data for REECB parameters, bus and signal ports, and + * monitored variables. * * @tparam real_type Real parameter value type. * @tparam index_type Integer index type. diff --git a/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbDependencyTracking.cpp b/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbDependencyTracking.cpp index b1841f4288..e65adb80bd 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbDependencyTracking.cpp +++ b/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbDependencyTracking.cpp @@ -1,7 +1,8 @@ /** * @file ReecbDependencyTracking.cpp * @author Luke Lowery (lukel@tamu.edu) - * @brief Dependency-tracking instantiations for the REECB electrical-control model. + * @brief Dependency-tracking instantiations for the REECB electrical-control + * model. */ #include "ReecbImpl.hpp" diff --git a/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbEnzyme.cpp b/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbEnzyme.cpp index 3ca4cc5059..8b711dfbd8 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbEnzyme.cpp @@ -35,15 +35,17 @@ namespace GridKit const auto size = static_cast(size_); const auto bus_size = static_cast(bus_->size()); const auto signal_size = static_cast(ws_.getSize()); - const auto buffer_size = 2 * size * size + size * bus_size + size * signal_size; + const auto buffer_size = + 2 * size * size + size * bus_size + size * signal_size; J_rows_buffer_ = new IdxT[buffer_size]; J_cols_buffer_ = new IdxT[buffer_size]; J_vals_buffer_ = new RealT[buffer_size]; } - using ModelT = GridKit::PhasorDynamics::Controller::Reecb; - using Fn = GridKit::Enzyme::Sparse::MemberFunctions; + using ModelT = + GridKit::PhasorDynamics::Controller::Reecb; + using Fn = GridKit::Enzyme::Sparse::MemberFunctions; nnz_ = 0; diff --git a/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbImpl.hpp b/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbImpl.hpp index 8602cc4530..9105f73cdd 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Controller/REECB/ReecbImpl.hpp @@ -56,16 +56,17 @@ namespace GridKit */ template Reecb::Reecb(BusT* bus, const ModelDataT& data) - : bus_(bus), - monitor_(std::make_unique(data)) + : bus_(bus), monitor_(std::make_unique(data)) { initializeParameters(data); initializeMonitor(); - size_ = static_cast(Utilities::enum_size()); + size_ = + static_cast(Utilities::enum_size()); } /** - * @brief Destroy the electrical controller and its optional variable monitor. + * @brief Destroy the electrical controller and its optional variable + * monitor. */ template Reecb::~Reecb() @@ -78,7 +79,9 @@ namespace GridKit * @param[in] component_id Identifier assigned by the system model. */ template - int Reecb::setGridKitComponentID(IdxT component_id) + int Reecb::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -87,10 +90,10 @@ namespace GridKit /** * @brief Allocate model vectors and wire assigned current-command outputs * - * Sizes the state, residual, bus, and signal-interface buffers, initializes - * identity index maps, and points assigned command nodes at the internal - * system-base states that REECB publishes. Repeated allocation reuses the - * existing model vectors and signal links. + * Sizes the state, residual, bus, and signal-interface buffers, + * initializes identity index maps, and points assigned command nodes at + * the internal system-base states that REECB publishes. Repeated + * allocation reuses the existing model vectors and signal links. */ template int Reecb::allocate() @@ -126,12 +129,16 @@ namespace GridKit if (auto port = ports_.out.template port()) { - port.link(&y[IQCMD], &(this->getVariableIndex(static_cast(IQCMD)))); + port.link( + &y[IQCMD], &(this->getVariableIndex(static_cast(IQCMD))) + ); } if (auto port = ports_.out.template port()) { - port.link(&y[IPCMD], &(this->getVariableIndex(static_cast(IPCMD)))); + port.link( + &y[IPCMD], &(this->getVariableIndex(static_cast(IPCMD))) + ); } allocated_ = true; @@ -154,16 +161,23 @@ namespace GridKit checks.check(bus_ != nullptr, "terminal bus is required"); - const bool valid_component_base = std::isfinite(va_component_base_) - && va_component_base_ > ZERO; - const bool valid_system_base = std::isfinite(va_system_base_) - && va_system_base_ > ZERO; - checks.check(valid_component_base, "component power base must be finite and positive"); - checks.check(valid_system_base, "system power base must be finite and positive"); + const bool valid_component_base = + std::isfinite(va_component_base_) && va_component_base_ > ZERO; + const bool valid_system_base = + std::isfinite(va_system_base_) && va_system_base_ > ZERO; + checks.check( + valid_component_base, + "component power base must be finite and positive" + ); + checks.check( + valid_system_base, "system power base must be finite and positive" + ); if (valid_component_base && valid_system_base) { - const RealT system_to_component = va_system_base_ / va_component_base_; - const RealT component_to_system = va_component_base_ / va_system_base_; + const RealT system_to_component = + va_system_base_ / va_component_base_; + const RealT component_to_system = + va_component_base_ / va_system_base_; checks.check( std::isfinite(system_to_component) && system_to_component > ZERO @@ -178,81 +192,127 @@ namespace GridKit checks.check(std::isfinite(Tp_), "Tp must be finite"); checks.check(std::isfinite(Vref0_), "Vref0 must be finite"); - const bool finite_voltage_thresholds = std::isfinite(Vdip_) && std::isfinite(Vup_); + const bool finite_voltage_thresholds = + std::isfinite(Vdip_) && std::isfinite(Vup_); checks.check(finite_voltage_thresholds, "Vdip and Vup must be finite"); if (finite_voltage_thresholds) { checks.check(Vdip_ < Vup_, "Vdip must be less than Vup"); } - const bool finite_voltage_deadband = std::isfinite(dbd1_) && std::isfinite(dbd2_); + const bool finite_voltage_deadband = + std::isfinite(dbd1_) && std::isfinite(dbd2_); checks.check(finite_voltage_deadband, "dbd1 and dbd2 must be finite"); if (finite_voltage_deadband) { - checks.check(dbd1_ <= ZERO && ZERO <= dbd2_, "dbd1 <= 0 <= dbd2 is required"); + checks.check( + dbd1_ <= ZERO && ZERO <= dbd2_, + "dbd1 <= 0 <= dbd2 is required" + ); } - checks.check(std::isfinite(kqv_) && kqv_ >= ZERO, "kqv must be finite and non-negative"); + checks.check( + std::isfinite(kqv_) && kqv_ >= ZERO, + "kqv must be finite and non-negative" + ); - const bool finite_injection_limits = std::isfinite(Iql1_) && std::isfinite(Iqh1_); + const bool finite_injection_limits = + std::isfinite(Iql1_) && std::isfinite(Iqh1_); checks.check(finite_injection_limits, "Iql1 and Iqh1 must be finite"); if (finite_injection_limits) { - checks.check(Iql1_ <= Iqh1_, "Iql1 must be less than or equal to Iqh1"); + checks.check( + Iql1_ <= Iqh1_, "Iql1 must be less than or equal to Iqh1" + ); } - const bool finite_reactive_limits = std::isfinite(Qmin_) && std::isfinite(Qmax_); + const bool finite_reactive_limits = + std::isfinite(Qmin_) && std::isfinite(Qmax_); checks.check(finite_reactive_limits, "Qmin and Qmax must be finite"); if (finite_reactive_limits) { - checks.check(Qmin_ <= Qmax_, "Qmin must be less than or equal to Qmax"); + checks.check( + Qmin_ <= Qmax_, "Qmin must be less than or equal to Qmax" + ); } - checks.check(std::isfinite(Kqp_) && Kqp_ >= ZERO, "Kqp must be finite and non-negative"); - checks.check(std::isfinite(Kqi_) && Kqi_ >= ZERO, "Kqi must be finite and non-negative"); + checks.check( + std::isfinite(Kqp_) && Kqp_ >= ZERO, + "Kqp must be finite and non-negative" + ); + checks.check( + std::isfinite(Kqi_) && Kqi_ >= ZERO, + "Kqi must be finite and non-negative" + ); - const bool finite_voltage_limits = std::isfinite(Vmin_) && std::isfinite(Vmax_); + const bool finite_voltage_limits = + std::isfinite(Vmin_) && std::isfinite(Vmax_); checks.check(finite_voltage_limits, "Vmin and Vmax must be finite"); if (finite_voltage_limits) { - checks.check(Vmin_ <= Vmax_, "Vmin must be less than or equal to Vmax"); + checks.check( + Vmin_ <= Vmax_, "Vmin must be less than or equal to Vmax" + ); } - checks.check(std::isfinite(Kvp_) && Kvp_ >= ZERO, "Kvp must be finite and non-negative"); - checks.check(std::isfinite(Kvi_) && Kvi_ >= ZERO, "Kvi must be finite and non-negative"); + checks.check( + std::isfinite(Kvp_) && Kvp_ >= ZERO, + "Kvp must be finite and non-negative" + ); + checks.check( + std::isfinite(Kvi_) && Kvi_ >= ZERO, + "Kvi must be finite and non-negative" + ); checks.check(std::isfinite(Tiq_), "Tiq must be finite"); checks.check(std::isfinite(Tpord_), "Tpord must be finite"); - const bool finite_ramp_limits = std::isfinite(dPmin_) && std::isfinite(dPmax_); + const bool finite_ramp_limits = + std::isfinite(dPmin_) && std::isfinite(dPmax_); checks.check(finite_ramp_limits, "dPmin and dPmax must be finite"); if (finite_ramp_limits) { - checks.check(dPmin_ < ZERO && ZERO < dPmax_, "dPmin < 0 < dPmax is required"); + checks.check( + dPmin_ < ZERO && ZERO < dPmax_, + "dPmin < 0 < dPmax is required" + ); } - const bool finite_active_limits = std::isfinite(Pmin_) && std::isfinite(Pmax_); + const bool finite_active_limits = + std::isfinite(Pmin_) && std::isfinite(Pmax_); checks.check(finite_active_limits, "Pmin and Pmax must be finite"); if (finite_active_limits) { - checks.check(Pmin_ <= Pmax_, "Pmin must be less than or equal to Pmax"); + checks.check( + Pmin_ <= Pmax_, "Pmin must be less than or equal to Pmax" + ); } - checks.check(std::isfinite(Imax_) && Imax_ > ZERO, "Imax must be finite and positive"); + checks.check( + std::isfinite(Imax_) && Imax_ > ZERO, + "Imax must be finite and positive" + ); - auto check_optional_signal = [&](const char* name) + auto check_optional_signal = + [&](const char* name) { if (ports_.in.template port().connected() && !ports_.in.template port().linked()) { - checks.fail(std::format("{} signal attached with no linked source", name)); + checks.fail( + std::format("{} signal attached with no linked source", name) + ); } }; check_optional_signal.template operator()("pe"); - check_optional_signal.template operator()("qgen"); - check_optional_signal.template operator()("qext"); - check_optional_signal.template operator()("pfaref"); - check_optional_signal.template operator()("pref"); + check_optional_signal.template operator( + )("qgen"); + check_optional_signal.template operator( + )("qext"); + check_optional_signal.template operator( + )("pfaref"); + check_optional_signal.template operator( + )("pref"); return checks; } @@ -285,7 +345,8 @@ namespace GridKit if (!this->verifyAndLog()) { - Log::error() << "Reecb: cannot initialize with invalid configuration\n"; + Log::error( + ) << "Reecb: cannot initialize with invalid configuration\n"; return 1; } @@ -313,7 +374,8 @@ namespace GridKit * @return true on success. */ template - bool Reecb::buildInitialPoint(InitialPoint& point) + bool Reecb::buildInitialPoint(InitialPoint& point + ) { const auto VMEAS = static_cast(ReecbInternalVariables::VMEAS); const auto PMEAS = static_cast(ReecbInternalVariables::PMEAS); @@ -376,22 +438,26 @@ namespace GridKit vref0 = Vref0_; } - if (!std::isfinite(vr0) || !std::isfinite(vi0) || !std::isfinite(vt0) || !std::isfinite(vmeas_safe0) - || !std::isfinite(ipcmd0) || !std::isfinite(iqcmd0) || !std::isfinite(pmeas0) + if (!std::isfinite(vr0) || !std::isfinite(vi0) || !std::isfinite(vt0) + || !std::isfinite(vmeas_safe0) || !std::isfinite(ipcmd0) + || !std::isfinite(iqcmd0) || !std::isfinite(pmeas0) || !std::isfinite(qgen0) || !std::isfinite(vref0)) { - Log::error() << "Reecb: initial bus, command, and feedback values must be finite\n"; + Log::error() << "Reecb: initial bus, command, and feedback values " + "must be finite\n"; return false; } if (vt0 <= ZERO) { - Log::error() << "Reecb: initial terminal-voltage magnitude must be positive\n"; + Log::error( + ) << "Reecb: initial terminal-voltage magnitude must be positive\n"; return false; } if (ipcmd0 < ZERO) { - Log::error() << "Reecb: initial active-current command must be non-negative\n"; + Log::error( + ) << "Reecb: initial active-current command must be non-negative\n"; return false; } @@ -401,7 +467,8 @@ namespace GridKit RealT iqneed0 = iqabs0; if (QFlag_ && iqabs0 > ZERO) { - iqneed0 += std::numbers::ln2_v / Math::MU + INITIALIZATION_TOLERANCE; + iqneed0 += std::numbers::ln2_v / Math::MU + + INITIALIZATION_TOLERANCE; } RealT high0 = iqabs0; @@ -418,7 +485,8 @@ namespace GridKit ); if (!current_limit) { - Log::error() << "Reecb: adjusted Imax cannot include the initial current commands\n"; + Log::error() << "Reecb: adjusted Imax cannot include the initial " + "current commands\n"; return false; } const RealT imax = current_limit->total_limit; @@ -437,7 +505,8 @@ namespace GridKit if (!iclamp(ipcmd0, ZERO, ipmax0, ipraw0) || !iclamp(iqcmd0, -iqmax0, iqmax0, iqraw0)) { - Log::error() << "Reecb: initial current commands cannot be reproduced by their limiters\n"; + Log::error() << "Reecb: initial current commands cannot be " + "reproduced by their limiters\n"; return false; } @@ -488,7 +557,8 @@ namespace GridKit } else if (VFlag_ && !iclamp(qgen0, qmin, qmax, qtarget0)) { - Log::error() << "Reecb: reactive-power limiter has no finite steady input\n"; + Log::error( + ) << "Reecb: reactive-power limiter has no finite steady input\n"; return false; } @@ -500,7 +570,8 @@ namespace GridKit { if (!iclamp(vmeas0, vmin, vmax, qext0_port)) { - Log::error() << "Reecb: voltage limiter has no finite steady input\n"; + Log::error( + ) << "Reecb: voltage limiter has no finite steady input\n"; return false; } } @@ -508,7 +579,8 @@ namespace GridKit { if (pmeas0 == ZERO && qtarget0 != ZERO) { - Log::error() << "Reecb: power-factor mode cannot reproduce the reactive target at zero active power\n"; + Log::error() << "Reecb: power-factor mode cannot reproduce the " + "reactive target at zero active power\n"; return false; } if (pmeas0 != ZERO) @@ -516,9 +588,11 @@ namespace GridKit pfaref0 = std::atan(qtarget0 / pmeas0); } qref0 = pmeas0 * std::tan(pfaref0); - if (std::abs(qref0 - qtarget0) > std::abs(qtarget0) * INITIALIZATION_TOLERANCE) + if (std::abs(qref0 - qtarget0) + > std::abs(qtarget0) * INITIALIZATION_TOLERANCE) { - Log::error() << "Reecb: power-factor angle cannot reproduce the reactive target\n"; + Log::error() << "Reecb: power-factor angle cannot reproduce the " + "reactive target\n"; return false; } } @@ -535,7 +609,8 @@ namespace GridKit RealT vpiq_input0 = ZERO; if (!iclamp(vmeas0, vmin, vmax, vpiq_input0)) { - Log::error() << "Reecb: voltage limiter has no finite steady input\n"; + Log::error( + ) << "Reecb: voltage limiter has no finite steady input\n"; return false; } xpiq0 = vpiq_input0 - Kqp_ * eq0; @@ -566,7 +641,8 @@ namespace GridKit RealT iqctl_input0 = ZERO; if (!iclamp(iqctl0, -iqmax0, iqmax0, iqctl_input0)) { - Log::error() << "Reecb: voltage-controller current cannot be reproduced by its limiter\n"; + Log::error() << "Reecb: voltage-controller current cannot be " + "reproduced by its limiter\n"; return false; } xpiv0 = iqctl_input0 - Kvp_ * epiv0; @@ -581,7 +657,9 @@ namespace GridKit RealT qrate0 = ZERO; if (QFlag_ && VFlag_) { - qrate0 = sdip0 * Math::antiwindup(Kqp_ * eq0 + xpiq0, Kqi_ * eq0, vmin, vmax); + qrate0 = + sdip0 + * Math::antiwindup(Kqp_ * eq0 + xpiq0, Kqi_ * eq0, vmin, vmax); } const ScalarT vstate0{Kvp_ * epiv0 + xpiv0}; @@ -589,41 +667,51 @@ namespace GridKit RealT vrate0 = ZERO; if (QFlag_) { - vrate0 = sdip0 * static_cast(awband(vstate0, vderiv0, ScalarT{iqmax0})); + vrate0 = + sdip0 + * static_cast(awband(vstate0, vderiv0, ScalarT{iqmax0})); } - const RealT iqbase0 = Math::clamp(Kvp_ * epiv0 + xpiv0, -iqmax0, iqmax0); - RealT iqraw_check = qv0 + iqv0; + const RealT iqbase0 = + Math::clamp(Kvp_ * epiv0 + xpiv0, -iqmax0, iqmax0); + RealT iqraw_check = qv0 + iqv0; if (QFlag_) { iqraw_check = iqbase0 + iqv0; } const RealT iqcmd_check = Math::clamp(iqraw_check, -iqmax0, iqmax0); - const RealT ipcmd_check = Math::clamp(pord0 / vmeas_safe0, ZERO, ipmax0); + const RealT ipcmd_check = + Math::clamp(pord0 / vmeas_safe0, ZERO, ipmax0); if (!std::isfinite(imax) || !std::isfinite(ilcap0) || !std::isfinite(iqmax0) || !std::isfinite(ipmax0) - || !std::isfinite(ipraw0) || !std::isfinite(iqraw0) || !std::isfinite(pord0) - || !std::isfinite(pref0_system) || !std::isfinite(qtarget0) || !std::isfinite(qref0) - || !std::isfinite(qext0_port) || !std::isfinite(pfaref0) || !std::isfinite(eq0) - || !std::isfinite(xpiq0) || !std::isfinite(epiv0) || !std::isfinite(xpiv0) - || !std::isfinite(qv0) || !std::isfinite(qrate0) || !std::isfinite(vrate0) - || !std::isfinite(iqbase0) || !std::isfinite(iqraw_check) - || !std::isfinite(iqcmd_check) || !std::isfinite(ipcmd_check)) + || !std::isfinite(ipraw0) || !std::isfinite(iqraw0) + || !std::isfinite(pord0) || !std::isfinite(pref0_system) + || !std::isfinite(qtarget0) || !std::isfinite(qref0) + || !std::isfinite(qext0_port) || !std::isfinite(pfaref0) + || !std::isfinite(eq0) || !std::isfinite(xpiq0) + || !std::isfinite(epiv0) || !std::isfinite(xpiv0) + || !std::isfinite(qv0) || !std::isfinite(qrate0) + || !std::isfinite(vrate0) || !std::isfinite(iqbase0) + || !std::isfinite(iqraw_check) || !std::isfinite(iqcmd_check) + || !std::isfinite(ipcmd_check)) { Log::error() << "Reecb: initialization produced a nonfinite value\n"; return false; } - if (std::abs(qrate0) > INITIALIZATION_TOLERANCE || std::abs(vrate0) > INITIALIZATION_TOLERANCE) + if (std::abs(qrate0) > INITIALIZATION_TOLERANCE + || std::abs(vrate0) > INITIALIZATION_TOLERANCE) { - Log::error() << "Reecb: controller state rate is nonzero at initialization\n"; + Log::error( + ) << "Reecb: controller state rate is nonzero at initialization\n"; return false; } if (std::abs(iqcmd_check - iqcmd0) > INITIALIZATION_TOLERANCE || std::abs(ipcmd_check - ipcmd0) > INITIALIZATION_TOLERANCE) { - Log::error() << "Reecb: current-command limiter reconstruction is inexact\n"; + Log::error( + ) << "Reecb: current-command limiter reconstruction is inexact\n"; return false; } @@ -670,7 +758,9 @@ namespace GridKit * @param[in] point Initial point. */ template - void Reecb::commitInitialPoint(const InitialPoint& point) + void Reecb::commitInitialPoint( + const InitialPoint& point + ) { const auto PE = static_cast(ReecbExternalVariables::PE); const auto QGEN = static_cast(ReecbExternalVariables::QGEN); @@ -711,32 +801,42 @@ namespace GridKit if (ports_.in.template port()) { - ports_.in.template port().writeValue(qext_set_); + ports_.in.template port().writeValue( + qext_set_ + ); } if (ports_.in.template port()) { - ports_.in.template port().writeValue(pfaref_set_); + ports_.in.template port().writeValue( + pfaref_set_ + ); } if (ports_.in.template port()) { - ports_.in.template port().writeValue(pref_set_); + ports_.in.template port().writeValue( + pref_set_ + ); } if (q_adjusted) { - Log::warning() << "Reecb: Qmin/Qmax adjusted to include the initial reactive power\n"; + Log::warning() << "Reecb: Qmin/Qmax adjusted to include the initial " + "reactive power\n"; } if (v_adjusted) { - Log::warning() << "Reecb: Vmin/Vmax adjusted to include the initial terminal voltage\n"; + Log::warning() << "Reecb: Vmin/Vmax adjusted to include the initial " + "terminal voltage\n"; } if (p_adjusted) { - Log::warning() << "Reecb: Pmin/Pmax adjusted to include the initial active-power order\n"; + Log::warning() << "Reecb: Pmin/Pmax adjusted to include the initial " + "active-power order\n"; } if (imax_adjusted) { - Log::warning() << "Reecb: Imax adjusted to include the initial current commands\n"; + Log::warning( + ) << "Reecb: Imax adjusted to include the initial current commands\n"; } y_.setDataUpdated(); @@ -772,7 +872,8 @@ namespace GridKit /** * @brief Set one absolute tolerance for every REECB variable * - * @param[in] rel_tol Solver relative tolerance used as the absolute floor. + * @param[in] rel_tol Solver relative tolerance used as the absolute + * floor. */ template int Reecb::setAbsoluteTolerance(RealT rel_tol) @@ -807,7 +908,8 @@ namespace GridKit { ws_indices_[QEXT] = qext_port.signalVariableIndex(); } - if (auto pfaref_port = ports_.in.template port()) + if (auto pfaref_port = + ports_.in.template port()) { ws_indices_[PFAREF] = pfaref_port.signalVariableIndex(); } @@ -855,7 +957,8 @@ namespace GridKit { ws[QEXT] = qext_port.readSignal(); } - if (auto pfaref_port = ports_.in.template port()) + if (auto pfaref_port = + ports_.in.template port()) { ws[PFAREF] = pfaref_port.readSignal(); } @@ -868,7 +971,9 @@ namespace GridKit wb[0] = Vr(); wb[1] = Vi(); - evaluateInternalResidual(y_.getData(), yp_.getData(), wb, ws, f_.getData()); + evaluateInternalResidual( + y_.getData(), yp_.getData(), wb, ws, f_.getData() + ); f_.setDataUpdated(); return 0; } @@ -879,7 +984,8 @@ namespace GridKit * @return Monitor, or nullptr when constructed without model data. */ template - const Model::VariableMonitorBase* Reecb::getMonitor() const + const Model::VariableMonitorBase* Reecb:: + getMonitor() const { return monitor_.get(); } @@ -893,7 +999,8 @@ namespace GridKit * @param[in] y Internal variables. * @param[in] yp Internal variable derivatives. * @param[in] wb Terminal-bus voltage components. - * @param[in] ws External signal values in their documented port units and bases. + * @param[in] ws External signal values in their documented port units and + * bases. * @param[out] f Internal residuals. */ template @@ -976,36 +1083,45 @@ namespace GridKit const ScalarT iqcmd = this->toComponentBase(iqcmd_system); const ScalarT ipcmd = this->toComponentBase(ipcmd_system); - const ScalarT verr = Math::deadband2(Vref0_ - vmeas, dbd1_, dbd2_); - const ScalarT q_pi_state = Kqp_ * eq + xpiq; - const ScalarT v_pi_state = Kvp_ * epiv + xpiv; - const ScalarT fpord = (pref - pord) / Tpord_; - // Select before the factored square to avoid 0 * inf on the inactive path. - const ScalarT high = pq_on_ * ipcmd + pq_off_ * iqcmd; - const ScalarT q_pi_rate = q_pi_on_ * sdip * Math::antiwindup(q_pi_state, Kqi_ * eq, Vmin_, Vmax_); - const ScalarT v_pi_rate = q_on_ * sdip * awband(v_pi_state, Kvi_ * epiv, iqmax); - const ScalarT qv_rate = q_off_ * sdip * (qref / vsafe - qv) / Tiq_; - const ScalarT pord_rate = sdip * Math::antiwindup(pord, rpord, Pmin_, Pmax_); - const ScalarT iqv_target = Math::clamp(kqv_ * verr, Iql1_, Iqh1_); + const ScalarT verr = Math::deadband2(Vref0_ - vmeas, dbd1_, dbd2_); + const ScalarT q_pi_state = Kqp_ * eq + xpiq; + const ScalarT v_pi_state = Kvp_ * epiv + xpiv; + const ScalarT fpord = (pref - pord) / Tpord_; + // Select before the factored square to avoid 0 * inf on the inactive + // path. + const ScalarT high = pq_on_ * ipcmd + pq_off_ * iqcmd; + const ScalarT q_pi_rate = + q_pi_on_ * sdip + * Math::antiwindup(q_pi_state, Kqi_ * eq, Vmin_, Vmax_); + const ScalarT v_pi_rate = + q_on_ * sdip * awband(v_pi_state, Kvi_ * epiv, iqmax); + const ScalarT qv_rate = q_off_ * sdip * (qref / vsafe - qv) / Tiq_; + const ScalarT pord_rate = + sdip * Math::antiwindup(pord, rpord, Pmin_, Pmax_); + const ScalarT iqv_target = Math::clamp(kqv_ * verr, Iql1_, Iqh1_); // The Volt/VAr channel is a system-base reactive power unless // direct-voltage mode selects it as a terminal-voltage reference, // which takes no power-base conversion. - const ScalarT qref_target = q_ref_on_ * (pf_on_ * pmeas * std::tan(pfaref) + pf_off_ * this->toComponentBase(extref)); - - f[VMEAS] = -vmeas_dot + (vt - vmeas) / Trv_; - f[PMEAS] = -pmeas_dot + (pe - pmeas) / Tp_; - f[XPIQ] = -xpiq_dot + q_pi_rate; - f[XPIV] = -xpiv_dot + v_pi_rate; - f[QV] = -qv_dot + qv_rate; - f[PORD] = -pord_dot + pord_rate; - f[VT] = -vt * vt + vr * vr + vi * vi; - f[VSAFE] = -vsafe + Math::max(vmeas, VMEAS_MINIMUM); - f[SDIP] = -sdip + Math::inside(vt, Vdip_, Vup_); - f[IQV] = -iqv + iqv_target; - f[QREF] = -qref + qref_target; - f[EQ] = -eq + Math::clamp(qref, Qmin_, Qmax_) - qgen; - f[VPIQ] = -vpiq + Math::clamp(q_pi_state, Vmin_, Vmax_); - f[EPIV] = -epiv + q_pi_on_ * vpiq + v_ref_on_ * Math::clamp(extref, Vmin_, Vmax_) - q_on_ * vmeas; + const ScalarT qref_target = + q_ref_on_ + * (pf_on_ * pmeas * std::tan(pfaref) + pf_off_ * this->toComponentBase(extref)); + + f[VMEAS] = -vmeas_dot + (vt - vmeas) / Trv_; + f[PMEAS] = -pmeas_dot + (pe - pmeas) / Tp_; + f[XPIQ] = -xpiq_dot + q_pi_rate; + f[XPIV] = -xpiv_dot + v_pi_rate; + f[QV] = -qv_dot + qv_rate; + f[PORD] = -pord_dot + pord_rate; + f[VT] = -vt * vt + vr * vr + vi * vi; + f[VSAFE] = -vsafe + Math::max(vmeas, VMEAS_MINIMUM); + f[SDIP] = -sdip + Math::inside(vt, Vdip_, Vup_); + f[IQV] = -iqv + iqv_target; + f[QREF] = -qref + qref_target; + f[EQ] = -eq + Math::clamp(qref, Qmin_, Qmax_) - qgen; + f[VPIQ] = -vpiq + Math::clamp(q_pi_state, Vmin_, Vmax_); + f[EPIV] = -epiv + q_pi_on_ * vpiq + + v_ref_on_ * Math::clamp(extref, Vmin_, Vmax_) + - q_on_ * vmeas; f[RPORD] = -rpord + aslew(fpord, dPmin_, dPmax_); f[ILCAP] = -ilcap + sqrtramp(circleSquare(Imax_, high)); f[IQMAX] = -iqmax + pq_on_ * ilcap + pq_off_ * Imax_; @@ -1031,8 +1147,8 @@ namespace GridKit * @return Limited rate. */ template - [[gnu::always_inline]] inline scalar_type - Reecb::aslew(ScalarT rate, RealT lower, RealT upper) + [[gnu::always_inline]] inline scalar_type Reecb:: + aslew(ScalarT rate, RealT lower, RealT upper) { assert(lower < ZERO && ZERO < upper); return rate @@ -1054,12 +1170,13 @@ namespace GridKit * @todo Fold moving-limit support into Math::antiwindup in CommonMath. */ template - [[gnu::always_inline]] inline scalar_type - Reecb::awband(ScalarT state, ScalarT rate, ScalarT band) + [[gnu::always_inline]] inline scalar_type Reecb:: + awband(ScalarT state, ScalarT rate, ScalarT band) { const ScalarT above_min = Math::above(state, -band); const ScalarT below_max = Math::below(state, band); - return (above_min * below_max + (ONE - below_max) * Math::sigmoid(-rate) + return (above_min * below_max + + (ONE - below_max) * Math::sigmoid(-rate) + (ONE - above_min) * Math::sigmoid(rate)) * rate; } @@ -1079,8 +1196,8 @@ namespace GridKit */ template template - [[gnu::always_inline]] inline ValueT - Reecb::sqrtramp(ValueT x) + [[gnu::always_inline]] inline ValueT Reecb:: + sqrtramp(ValueT x) { const RealT root_width = ONE / Math::MU; const RealT knee = CURRENT_CIRCLE_KNEE; @@ -1092,12 +1209,11 @@ namespace GridKit const ValueT magnitude = normalizer * std::sqrt(scaled_x * scaled_x + scaled_knee * scaled_knee); - const ValueT half_sum = HALF * magnitude - + HALF * absolute; + const ValueT half_sum = + HALF * magnitude + HALF * absolute; const ValueT conjugate = QUARTER * knee * (knee / half_sum); - const ValueT hinged = HALF * x - + HALF * absolute - + conjugate; + const ValueT hinged = + HALF * x + HALF * absolute + conjugate; // Divide through by MU to avoid overflow for large finite circles. return hinged / std::sqrt(hinged + root_width * root_width); } @@ -1110,8 +1226,9 @@ namespace GridKit * @pre `y` is finite and nonnegative. */ template - typename Reecb::RealT - Reecb::isqrtramp(RealT y) + typename Reecb::RealT Reecb< + scalar_type, + index_type>::isqrtramp(RealT y) { if (y <= sqrtramp(ZERO)) { @@ -1120,8 +1237,8 @@ namespace GridKit const RealT mu = Math::MU; const RealT scaled_y = HALF * mu * y; - const RealT hinged = y / mu - * (scaled_y + std::hypot(scaled_y, ONE)); + const RealT hinged = + y / mu * (scaled_y + std::hypot(scaled_y, ONE)); const RealT square = hinged - QUARTER * CURRENT_CIRCLE_KNEE * (CURRENT_CIRCLE_KNEE / hinged); @@ -1137,8 +1254,8 @@ namespace GridKit */ template template - [[gnu::always_inline]] inline ValueT - Reecb::circleSquare(RealT limit, ValueT high) + [[gnu::always_inline]] inline ValueT Reecb:: + circleSquare(RealT limit, ValueT high) { return ((HALF * limit - HALF * high) * (HALF * limit + HALF * high)) @@ -1148,7 +1265,8 @@ namespace GridKit /** * @brief Solve a feasible initial total-current limit * - * @param[in] lower Lower bound for the component-base total-current limit. + * @param[in] lower Lower bound for the component-base total-current + * limit. * @param[in] high Priority-axis current command on the component base. * @param[in] low Required off-axis capacity on the component base. * @return The mutually consistent total limit and off-axis capacity, or @@ -1187,7 +1305,8 @@ namespace GridKit step < std::numeric_limits::digits && cap < low; ++step) { - const RealT next = std::nextafter(imax, std::numeric_limits::max()); + const RealT next = + std::nextafter(imax, std::numeric_limits::max()); if (!std::isfinite(next) || next <= imax) { return std::nullopt; @@ -1234,7 +1353,9 @@ namespace GridKit * @param[in] data Parameters and monitored-variable selections. */ template - void Reecb::initializeParameters(const ModelDataT& data) + void Reecb::initializeParameters( + const ModelDataT& data + ) { using Params = typename ModelDataT::Parameters; @@ -1292,14 +1413,38 @@ namespace GridKit { using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::iqcmd, [this] - { return y_.getData()[static_cast(ReecbInternalVariables::IQCMD)]; }); - monitor_->set(Variable::ipcmd, [this] - { return y_.getData()[static_cast(ReecbInternalVariables::IPCMD)]; }); - monitor_->set(Variable::vmeas, [this] - { return y_.getData()[static_cast(ReecbInternalVariables::VMEAS)]; }); - monitor_->set(Variable::pmeas, [this] - { return y_.getData()[static_cast(ReecbInternalVariables::PMEAS)]; }); + monitor_->set( + Variable::iqcmd, + [this] + { + return y_.getData( + )[static_cast(ReecbInternalVariables::IQCMD)]; + } + ); + monitor_->set( + Variable::ipcmd, + [this] + { + return y_.getData( + )[static_cast(ReecbInternalVariables::IPCMD)]; + } + ); + monitor_->set( + Variable::vmeas, + [this] + { + return y_.getData( + )[static_cast(ReecbInternalVariables::VMEAS)]; + } + ); + monitor_->set( + Variable::pmeas, + [this] + { + return y_.getData( + )[static_cast(ReecbInternalVariables::PMEAS)]; + } + ); } /** @@ -1313,7 +1458,8 @@ namespace GridKit { Log::warning() << "Reecb: any of Trv, Tp, Tiq, or Tpord below " << TIME_CONSTANT_MINIMUM - << " s is raised to that floor to keep the controller lags well posed\n"; + << " s is raised to that floor to keep the controller " + "lags well posed\n"; } /** @@ -1395,14 +1541,16 @@ namespace GridKit * be used in initialization methods but not in residual evaluation. */ template - typename Reecb::RealT - Reecb::logOneMinusExp(RealT x) + typename Reecb::RealT Reecb< + scalar_type, + index_type>::logOneMinusExp(RealT x) { static constexpr auto log_two = std::numbers::ln2_v; if (x < log_two) { - return log_two - HALF * x + std::log(std::sinh(HALF * x)); + return log_two - HALF * x + + std::log(std::sinh(HALF * x)); } return std::log1p(-std::exp(-x)); } @@ -1422,10 +1570,14 @@ namespace GridKit * be used in initialization methods but not in residual evaluation. */ template - bool Reecb::iclamp(RealT output, RealT lower, RealT upper, RealT& input) const + bool Reecb::iclamp( + RealT output, RealT lower, RealT upper, RealT& input + ) const { - if (!std::isfinite(output) || !std::isfinite(lower) || !std::isfinite(upper) || lower > upper - || output < lower - INITIALIZATION_TOLERANCE || output > upper + INITIALIZATION_TOLERANCE) + if (!std::isfinite(output) || !std::isfinite(lower) + || !std::isfinite(upper) || lower > upper + || output < lower - INITIALIZATION_TOLERANCE + || output > upper + INITIALIZATION_TOLERANCE) { return false; } @@ -1437,8 +1589,10 @@ namespace GridKit return true; } - const RealT mu = Math::MU; - const RealT offset = -std::log(std::expm1(mu * HALF * INITIALIZATION_TOLERANCE)) / mu; + const RealT mu = Math::MU; + const RealT offset = + -std::log(std::expm1(mu * HALF * INITIALIZATION_TOLERANCE)) + / mu; if (output == lower) { input = lower - offset; @@ -1452,7 +1606,7 @@ namespace GridKit const RealT a = mu * (output - lower); const RealT b = mu * (upper - output); - input = lower + (a + logOneMinusExp(a) - logOneMinusExp(b)) / mu; + input = lower + (a + logOneMinusExp(a) - logOneMinusExp(b)) / mu; return std::isfinite(input); } diff --git a/GridKit/Model/PhasorDynamics/Controller/REPCA/Repca.cpp b/GridKit/Model/PhasorDynamics/Controller/REPCA/Repca.cpp index ad4e7c8723..08484f9d1d 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REPCA/Repca.cpp +++ b/GridKit/Model/PhasorDynamics/Controller/REPCA/Repca.cpp @@ -13,7 +13,8 @@ namespace GridKit namespace Controller { /** - * @brief Report that a separate Jacobian is unavailable in the plain-real build. + * @brief Report that a separate Jacobian is unavailable in the plain-real + * build. */ template int Repca::evaluateJacobian() diff --git a/GridKit/Model/PhasorDynamics/Controller/REPCA/Repca.hpp b/GridKit/Model/PhasorDynamics/Controller/REPCA/Repca.hpp index 00861d8e04..9a17756f87 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REPCA/Repca.hpp +++ b/GridKit/Model/PhasorDynamics/Controller/REPCA/Repca.hpp @@ -30,42 +30,68 @@ namespace GridKit /// Internal variables of `Repca`. enum class RepcaInternalVariables : size_t { - VMEAS, ///< \f$V^\mathrm{meas}\f$ Differential filtered regulated voltage [p.u.] - QMEAS, ///< \f$Q^\mathrm{meas}\f$ Differential filtered reactive power on component base [p.u.] - XQPI, ///< \f$x_Q^\mathrm{PI}\f$ Differential reactive-power PI state on component base [p.u.] - XQLAG, ///< \f$x_Q^\mathrm{lag}\f$ Differential reactive-command lead-lag state on component base [p.u.] - PMEAS, ///< \f$P^\mathrm{meas}\f$ Differential filtered active power on component base [p.u.] - XPPI, ///< \f$x_P^\mathrm{PI}\f$ Differential active-power PI state on component base [p.u.] - PREF, ///< \f$P^\mathrm{ref}\f$ Differential active-power command lag state on component base [p.u.] - V, ///< \f$V\f$ Algebraic regulated-bus voltage magnitude [p.u.] - VLDC, ///< \f$V^\mathrm{ldc}\f$ Algebraic line-drop compensated voltage magnitude [p.u.] - VDROOP, ///< \f$V^\mathrm{droop}\f$ Algebraic reactive-droop-compensated voltage [p.u.] - VCTRL, ///< \f$V^\mathrm{ctrl}\f$ Algebraic selected voltage-measurement input [p.u.] - SFRZ, ///< \f$s_\mathrm{frz}\f$ Algebraic reactive-power PI voltage-enable gate [-] - ERQ, ///< \f$e_\mathrm{RQ}\f$ Algebraic selected reactive-loop error [p.u.] - ERQDB, ///< \f$e_\mathrm{RQ}^\mathrm{db}\f$ Algebraic deadbanded reactive-loop error [p.u.] - ERQLIM, ///< \f$e_\mathrm{RQ}^\mathrm{lim}\f$ Algebraic limited reactive-loop error [p.u.] - QPI, ///< \f$Q^\mathrm{PI}\f$ Algebraic reactive-power PI output on component base [p.u.] - QEXT, ///< \f$Q^\mathrm{ext}\f$ Algebraic reactive-power command on system base [p.u.] + VMEAS, ///< \f$V^\mathrm{meas}\f$ Differential filtered regulated + ///< voltage [p.u.] + QMEAS, ///< \f$Q^\mathrm{meas}\f$ Differential filtered reactive power + ///< on component base [p.u.] + XQPI, ///< \f$x_Q^\mathrm{PI}\f$ Differential reactive-power PI state on + ///< component base [p.u.] + XQLAG, ///< \f$x_Q^\mathrm{lag}\f$ Differential reactive-command + ///< lead-lag state on component base [p.u.] + PMEAS, ///< \f$P^\mathrm{meas}\f$ Differential filtered active power on + ///< component base [p.u.] + XPPI, ///< \f$x_P^\mathrm{PI}\f$ Differential active-power PI state on + ///< component base [p.u.] + PREF, ///< \f$P^\mathrm{ref}\f$ Differential active-power command lag + ///< state on component base [p.u.] + V, ///< \f$V\f$ Algebraic regulated-bus voltage magnitude [p.u.] + VLDC, ///< \f$V^\mathrm{ldc}\f$ Algebraic line-drop compensated voltage + ///< magnitude [p.u.] + VDROOP, ///< \f$V^\mathrm{droop}\f$ Algebraic reactive-droop-compensated + ///< voltage [p.u.] + VCTRL, ///< \f$V^\mathrm{ctrl}\f$ Algebraic selected voltage-measurement + ///< input [p.u.] + SFRZ, ///< \f$s_\mathrm{frz}\f$ Algebraic reactive-power PI + ///< voltage-enable gate [-] + ERQ, ///< \f$e_\mathrm{RQ}\f$ Algebraic selected reactive-loop error + ///< [p.u.] + ERQDB, ///< \f$e_\mathrm{RQ}^\mathrm{db}\f$ Algebraic deadbanded + ///< reactive-loop error [p.u.] + ERQLIM, ///< \f$e_\mathrm{RQ}^\mathrm{lim}\f$ Algebraic limited + ///< reactive-loop error [p.u.] + QPI, ///< \f$Q^\mathrm{PI}\f$ Algebraic reactive-power PI output on + ///< component base [p.u.] + QEXT, ///< \f$Q^\mathrm{ext}\f$ Algebraic reactive-power command on + ///< system base [p.u.] EF, ///< \f$e_f\f$ Algebraic frequency error after deadband [p.u.] - EP, ///< \f$e_P\f$ Algebraic active-power control error on component base [p.u.] - EPLIM, ///< \f$e_P^\mathrm{lim}\f$ Algebraic limited active-power control error on component base [p.u.] - PPI, ///< \f$P^\mathrm{PI}\f$ Algebraic active-power PI output on component base [p.u.] - PEXT, ///< \f$P^\mathrm{ext}\f$ Algebraic active-power command on system base [p.u.] + EP, ///< \f$e_P\f$ Algebraic active-power control error on component + ///< base [p.u.] + EPLIM, ///< \f$e_P^\mathrm{lim}\f$ Algebraic limited active-power + ///< control error on component base [p.u.] + PPI, ///< \f$P^\mathrm{PI}\f$ Algebraic active-power PI output on + ///< component base [p.u.] + PEXT, ///< \f$P^\mathrm{ext}\f$ Algebraic active-power command on system + ///< base [p.u.] }; /// External variables of `Repca`. enum class RepcaExternalVariables : size_t { - IR, ///< \f$I_\mathrm{r}\f$ Required branch-current real component on system base [p.u.] - II, ///< \f$I_\mathrm{i}\f$ Required branch-current imaginary component on system base [p.u.] - P, ///< \f$P\f$ Required branch active power on system base [p.u.] - Q, ///< \f$Q\f$ Required branch reactive power on system base [p.u.] + IR, ///< \f$I_\mathrm{r}\f$ Required branch-current real component on + ///< system base [p.u.] + II, ///< \f$I_\mathrm{i}\f$ Required branch-current imaginary component + ///< on system base [p.u.] + P, ///< \f$P\f$ Required branch active power on system base [p.u.] + Q, ///< \f$Q\f$ Required branch reactive power on system base [p.u.] FREQ, ///< \f$f\f$ Optional absolute frequency input [p.u.] - VREF, ///< \f$V^\mathrm{ref}\f$ Optional voltage-control reference [p.u.] - PREF, ///< \f$P_\mathrm{plant}^\mathrm{ref}\f$ Optional plant active-power reference on system base [p.u.] - QREF, ///< \f$Q^\mathrm{ref}\f$ Optional reactive-power reference on system base [p.u.] - FREQREF, ///< \f$f^\mathrm{ref}\f$ Optional absolute frequency reference [p.u.] + VREF, ///< \f$V^\mathrm{ref}\f$ Optional voltage-control reference + ///< [p.u.] + PREF, ///< \f$P_\mathrm{plant}^\mathrm{ref}\f$ Optional plant + ///< active-power reference on system base [p.u.] + QREF, ///< \f$Q^\mathrm{ref}\f$ Optional reactive-power reference on + ///< system base [p.u.] + FREQREF, ///< \f$f^\mathrm{ref}\f$ Optional absolute frequency reference + ///< [p.u.] }; /** @@ -114,7 +140,8 @@ namespace GridKit using ExternalVariablesT = RepcaExternalVariables; public: - static constexpr RealT INITIALIZATION_TOLERANCE = static_cast(1.0e-12); + static constexpr RealT INITIALIZATION_TOLERANCE = + static_cast(1.0e-12); Repca(BusT* bus, const ModelDataT& data); ~Repca(); @@ -147,25 +174,33 @@ namespace GridKit private: /// Smooth asymmetric frequency-droop response. - static __attribute__((always_inline)) inline ScalarT droop(ScalarT error, RealT down, RealT up); + static __attribute__((always_inline)) inline ScalarT droop( + ScalarT error, RealT down, RealT up + ); void initializeParameters(const ModelDataT& data); void initializeMonitor(); void setDerivedParameters(); - bool invertClamp(ScalarT output, RealT lower, RealT upper, ScalarT& input) const; + bool invertClamp( + ScalarT output, RealT lower, RealT upper, ScalarT& input + ) const; - bool invertDeadband(ScalarT output, RealT lower, RealT upper, ScalarT& input) const; + bool invertDeadband( + ScalarT output, RealT lower, RealT upper, ScalarT& input + ) const; static RealT logOneMinusExp(RealT x); ScalarT& Vr(); ScalarT& Vi(); - static constexpr RealT TIME_CONSTANT_MINIMUM = static_cast(1.0e-3); - static void logTimeConstantWarning(); + static constexpr RealT TIME_CONSTANT_MINIMUM = + static_cast(1.0e-3); + static void logTimeConstantWarning(); - static constexpr RealT INITIALIZATION_LIMIT_OFFSET = static_cast(0.1); + static constexpr RealT INITIALIZATION_LIMIT_OFFSET = + static_cast(0.1); BusT* bus_{nullptr}; diff --git a/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaData.hpp b/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaData.hpp index 2f6f37d41c..80b2134a88 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaData.hpp +++ b/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaData.hpp @@ -18,73 +18,105 @@ namespace GridKit enum class RepcaParameters : size_t { mva, ///< \f$S^\mathrm{base}\f$ Component power base [MVA] - VcompFlag, ///< \f$s_\mathrm{comp}\f$ Voltage-compensation selector [boolean] - RefFlag, ///< \f$s_\mathrm{ref}\f$ Reactive-loop reference selector [boolean] - Freqflag, ///< \f$s_\mathrm{freq}\f$ Active-power output selector [boolean] - Tfltr, ///< \f$T_\mathrm{fltr}\f$ Voltage and reactive-power filter time constant [sec] - Vfrz, ///< \f$V^\mathrm{frz}\f$ Reactive-power PI freeze threshold [p.u.] - Rc, ///< \f$R_c\f$ Line-drop resistance on component base [p.u.] - Xc, ///< \f$X_c\f$ Line-drop reactance on component base [p.u.] - Kc, ///< \f$K_c\f$ Reactive-current compensation gain [p.u.] - dbdlow, ///< \f$D_\mathrm{bd1}\f$ Lower reactive-loop deadband threshold [p.u.] - dbdupper, ///< \f$D_\mathrm{bd2}\f$ Upper reactive-loop deadband threshold [p.u.] - emax, ///< \f$e^{\max}\f$ Maximum reactive-loop error [p.u.] - emin, ///< \f$e^{\min}\f$ Minimum reactive-loop error [p.u.] - Kp, ///< \f$K_\mathrm{p}\f$ Reactive-power proportional gain [p.u.] - Ki, ///< \f$K_\mathrm{i}\f$ Reactive-power integral gain [p.u./s] - Qmax, ///< \f$Q^{\max}\f$ Maximum reactive-power command on component base [p.u.] - Qmin, ///< \f$Q^{\min}\f$ Minimum reactive-power command on component base [p.u.] - Tft, ///< \f$T_\mathrm{ft}\f$ Reactive-command lead time constant [sec] - Tfv, ///< \f$T_\mathrm{fv}\f$ Reactive-command lag time constant [sec] - Tp, ///< \f$T_\mathrm{p}\f$ Active-power measurement filter time constant [sec] - fdbd1, ///< \f$D_\mathrm{bd1}^{f}\f$ Lower frequency-error deadband threshold [p.u.] - fdbd2, ///< \f$D_\mathrm{bd2}^{f}\f$ Upper frequency-error deadband threshold [p.u.] - Ddn, ///< \f$D_\mathrm{dn}\f$ Down-regulation (overfrequency) gain [p.u./p.u.] - Dup, ///< \f$D_\mathrm{up}\f$ Up-regulation (underfrequency) gain [p.u./p.u.] - femax, ///< \f$e_P^{\max}\f$ Maximum active-power error [p.u.] - femin, ///< \f$e_P^{\min}\f$ Minimum active-power error [p.u.] - Kpg, ///< \f$K_\mathrm{pg}\f$ Active-power proportional gain [p.u.] - Kig, ///< \f$K_\mathrm{ig}\f$ Active-power integral gain [p.u./s] - Pmax, ///< \f$P^{\max}\f$ Maximum active-power command on component base [p.u.] - Pmin, ///< \f$P^{\min}\f$ Minimum active-power command on component base [p.u.] - Tlag, ///< \f$T_\mathrm{lag}\f$ Active-power command lag time constant [sec] + VcompFlag, ///< \f$s_\mathrm{comp}\f$ Voltage-compensation selector + ///< [boolean] + RefFlag, ///< \f$s_\mathrm{ref}\f$ Reactive-loop reference selector + ///< [boolean] + Freqflag, ///< \f$s_\mathrm{freq}\f$ Active-power output selector + ///< [boolean] + Tfltr, ///< \f$T_\mathrm{fltr}\f$ Voltage and reactive-power filter time + ///< constant [sec] + Vfrz, ///< \f$V^\mathrm{frz}\f$ Reactive-power PI freeze threshold + ///< [p.u.] + Rc, ///< \f$R_c\f$ Line-drop resistance on component base [p.u.] + Xc, ///< \f$X_c\f$ Line-drop reactance on component base [p.u.] + Kc, ///< \f$K_c\f$ Reactive-current compensation gain [p.u.] + dbdlow, ///< \f$D_\mathrm{bd1}\f$ Lower reactive-loop deadband threshold + ///< [p.u.] + dbdupper, ///< \f$D_\mathrm{bd2}\f$ Upper reactive-loop deadband + ///< threshold [p.u.] + emax, ///< \f$e^{\max}\f$ Maximum reactive-loop error [p.u.] + emin, ///< \f$e^{\min}\f$ Minimum reactive-loop error [p.u.] + Kp, ///< \f$K_\mathrm{p}\f$ Reactive-power proportional gain [p.u.] + Ki, ///< \f$K_\mathrm{i}\f$ Reactive-power integral gain [p.u./s] + Qmax, ///< \f$Q^{\max}\f$ Maximum reactive-power command on component + ///< base [p.u.] + Qmin, ///< \f$Q^{\min}\f$ Minimum reactive-power command on component + ///< base [p.u.] + Tft, ///< \f$T_\mathrm{ft}\f$ Reactive-command lead time constant [sec] + Tfv, ///< \f$T_\mathrm{fv}\f$ Reactive-command lag time constant [sec] + Tp, ///< \f$T_\mathrm{p}\f$ Active-power measurement filter time + ///< constant [sec] + fdbd1, ///< \f$D_\mathrm{bd1}^{f}\f$ Lower frequency-error deadband + ///< threshold [p.u.] + fdbd2, ///< \f$D_\mathrm{bd2}^{f}\f$ Upper frequency-error deadband + ///< threshold [p.u.] + Ddn, ///< \f$D_\mathrm{dn}\f$ Down-regulation (overfrequency) gain + ///< [p.u./p.u.] + Dup, ///< \f$D_\mathrm{up}\f$ Up-regulation (underfrequency) gain + ///< [p.u./p.u.] + femax, ///< \f$e_P^{\max}\f$ Maximum active-power error [p.u.] + femin, ///< \f$e_P^{\min}\f$ Minimum active-power error [p.u.] + Kpg, ///< \f$K_\mathrm{pg}\f$ Active-power proportional gain [p.u.] + Kig, ///< \f$K_\mathrm{ig}\f$ Active-power integral gain [p.u./s] + Pmax, ///< \f$P^{\max}\f$ Maximum active-power command on component base + ///< [p.u.] + Pmin, ///< \f$P^{\min}\f$ Minimum active-power command on component base + ///< [p.u.] + Tlag, ///< \f$T_\mathrm{lag}\f$ Active-power command lag time constant + ///< [sec] }; /// Buses for `Repca`. enum class RepcaBuses : size_t { - bus, ///< \f$V_\mathrm{r},V_\mathrm{i}\f$ Required Known regulated-bus voltage [p.u.] + bus, ///< \f$V_\mathrm{r},V_\mathrm{i}\f$ Required Known regulated-bus + ///< voltage [p.u.] }; /// Signal inputs for the `Repca`. enum class RepcaSignalInputs : size_t { - ir, ///< \f$I_\mathrm{r}\f$ Required Known branch-current real input on system base [p.u.] - ii, ///< \f$I_\mathrm{i}\f$ Required Known branch-current imaginary input on system base [p.u.] - p, ///< \f$P\f$ Required Known branch active-power input on system base [p.u.] - q, ///< \f$Q\f$ Required Known branch reactive-power input on system base [p.u.] - freq, ///< \f$f\f$ Optional Known frequency input [p.u.] - vref, ///< \f$V^\mathrm{ref}\f$ Optional Unknown voltage-reference input [p.u.] - pref, ///< \f$P_\mathrm{plant}^\mathrm{ref}\f$ Optional Unknown plant active-power reference on system base [p.u.] - qref, ///< \f$Q^\mathrm{ref}\f$ Optional Unknown reactive-power reference on system base [p.u.] - freqref, ///< \f$f^\mathrm{ref}\f$ Optional Unknown frequency-reference input [p.u.] + ir, ///< \f$I_\mathrm{r}\f$ Required Known branch-current real input on + ///< system base [p.u.] + ii, ///< \f$I_\mathrm{i}\f$ Required Known branch-current imaginary + ///< input on system base [p.u.] + p, ///< \f$P\f$ Required Known branch active-power input on system base + ///< [p.u.] + q, ///< \f$Q\f$ Required Known branch reactive-power input on system + ///< base [p.u.] + freq, ///< \f$f\f$ Optional Known frequency input [p.u.] + vref, ///< \f$V^\mathrm{ref}\f$ Optional Unknown voltage-reference input + ///< [p.u.] + pref, ///< \f$P_\mathrm{plant}^\mathrm{ref}\f$ Optional Unknown plant + ///< active-power reference on system base [p.u.] + qref, ///< \f$Q^\mathrm{ref}\f$ Optional Unknown reactive-power + ///< reference on system base [p.u.] + freqref, ///< \f$f^\mathrm{ref}\f$ Optional Unknown frequency-reference + ///< input [p.u.] }; /// Signal outputs for `Repca`. enum class RepcaSignalOutputs : size_t { - qext, ///< \f$Q^\mathrm{ext}\f$ Optional Known reactive-power command output on system base [p.u.] - pext, ///< \f$P^\mathrm{ext}\f$ Optional Known active-power command output on system base [p.u.] + qext, ///< \f$Q^\mathrm{ext}\f$ Optional Known reactive-power command + ///< output on system base [p.u.] + pext, ///< \f$P^\mathrm{ext}\f$ Optional Known active-power command + ///< output on system base [p.u.] }; /// Variables available through the monitor interface. enum class RepcaMonitorableVariables : size_t { - qext, ///< \f$Q^\mathrm{ext}\f$ Reactive-power command output on system base [p.u.] - pext, ///< \f$P^\mathrm{ext}\f$ Active-power command output on system base [p.u.] + qext, ///< \f$Q^\mathrm{ext}\f$ Reactive-power command output on system + ///< base [p.u.] + pext, ///< \f$P^\mathrm{ext}\f$ Active-power command output on system + ///< base [p.u.] vmeas, ///< \f$V^\mathrm{meas}\f$ Filtered regulated voltage [p.u.] - qmeas, ///< \f$Q^\mathrm{meas}\f$ Filtered reactive-power signal on component base [p.u.] - pmeas, ///< \f$P^\mathrm{meas}\f$ Filtered active-power signal on component base [p.u.] + qmeas, ///< \f$Q^\mathrm{meas}\f$ Filtered reactive-power signal on + ///< component base [p.u.] + pmeas, ///< \f$P^\mathrm{meas}\f$ Filtered active-power signal on + ///< component base [p.u.] }; /// Initial values for `Repca`. @@ -93,7 +125,8 @@ namespace GridKit }; /** - * @brief Model data for REPCA parameters, bus and signal ports, and monitored variables. + * @brief Model data for REPCA parameters, bus and signal ports, and + * monitored variables. * * @tparam real_type Real parameter value type. * @tparam index_type Integer index type. diff --git a/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaEnzyme.cpp b/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaEnzyme.cpp index 016c73327c..06dd8f3e5a 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaEnzyme.cpp @@ -35,15 +35,17 @@ namespace GridKit const auto size = static_cast(size_); const auto bus_size = static_cast(bus_->size()); const auto signal_size = static_cast(ws_.getSize()); - const auto buffer_size = 2 * size * size + size * bus_size + size * signal_size; + const auto buffer_size = + 2 * size * size + size * bus_size + size * signal_size; J_rows_buffer_ = new IdxT[buffer_size]; J_cols_buffer_ = new IdxT[buffer_size]; J_vals_buffer_ = new RealT[buffer_size]; } - using ModelT = GridKit::PhasorDynamics::Controller::Repca; - using Fn = GridKit::Enzyme::Sparse::MemberFunctions; + using ModelT = + GridKit::PhasorDynamics::Controller::Repca; + using Fn = GridKit::Enzyme::Sparse::MemberFunctions; nnz_ = 0; diff --git a/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaImpl.hpp b/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaImpl.hpp index 892d3c4a58..52031676a8 100644 --- a/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Controller/REPCA/RepcaImpl.hpp @@ -36,12 +36,12 @@ namespace GridKit */ template Repca::Repca(BusT* bus, const ModelDataT& data) - : bus_(bus), - monitor_(std::make_unique(data)) + : bus_(bus), monitor_(std::make_unique(data)) { initializeParameters(data); initializeMonitor(); - size_ = static_cast(Utilities::enum_size()); + size_ = + static_cast(Utilities::enum_size()); } /** @@ -58,7 +58,9 @@ namespace GridKit * @param[in] component_id Identifier assigned by the system model. */ template - int Repca::setGridKitComponentID(IdxT component_id) + int Repca::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -67,9 +69,9 @@ namespace GridKit /** * @brief Allocate model vectors and wire assigned command outputs * - * Sizes the state, residual, bus, and signal-interface buffers, initializes - * identity index maps, and points assigned `qext` and `pext` nodes at - * the internal system-base states that REPCA publishes. Repeated + * Sizes the state, residual, bus, and signal-interface buffers, + * initializes identity index maps, and points assigned `qext` and `pext` + * nodes at the internal system-base states that REPCA publishes. Repeated * allocation reuses the existing model vectors and signal links. */ template @@ -106,12 +108,16 @@ namespace GridKit if (auto port = ports_.out.template port()) { - port.link(&y[QEXT], &(this->getVariableIndex(static_cast(QEXT)))); + port.link( + &y[QEXT], &(this->getVariableIndex(static_cast(QEXT))) + ); } if (auto port = ports_.out.template port()) { - port.link(&y[PEXT], &(this->getVariableIndex(static_cast(PEXT)))); + port.link( + &y[PEXT], &(this->getVariableIndex(static_cast(PEXT))) + ); } allocated_ = true; @@ -139,17 +145,21 @@ namespace GridKit && mva_base_ > ZERO && std::isfinite(va_component_base_) && va_component_base_ > ZERO; - const bool valid_system_base = std::isfinite(va_system_base_) - && va_system_base_ > ZERO; + const bool valid_system_base = + std::isfinite(va_system_base_) && va_system_base_ > ZERO; checks.check( valid_component_base, "mva must define a finite positive component power base" ); - checks.check(valid_system_base, "system power base must be finite and positive"); + checks.check( + valid_system_base, "system power base must be finite and positive" + ); if (valid_component_base && valid_system_base) { - const RealT system_to_component = va_system_base_ / va_component_base_; - const RealT component_to_system = va_component_base_ / va_system_base_; + const RealT system_to_component = + va_system_base_ / va_component_base_; + const RealT component_to_system = + va_component_base_ / va_system_base_; checks.check( std::isfinite(system_to_component) && system_to_component > ZERO @@ -183,7 +193,8 @@ namespace GridKit ); checks.check(Pmin_ <= Pmax_, "Pmin must be less than or equal to Pmax"); - auto check_required_signal = [&](const char* name) + auto check_required_signal = + [&](const char* name) { if (!ports_.in.template port().connected()) { @@ -191,7 +202,9 @@ namespace GridKit } else if (!ports_.in.template port().linked()) { - checks.fail(std::format("{} signal attached with no linked source", name)); + checks.fail( + std::format("{} signal attached with no linked source", name) + ); } }; @@ -200,20 +213,28 @@ namespace GridKit check_required_signal.template operator()("p"); check_required_signal.template operator()("q"); - auto check_optional_signal = [&](const char* name) + auto check_optional_signal = + [&](const char* name) { if (ports_.in.template port().connected() && !ports_.in.template port().linked()) { - checks.fail(std::format("{} signal attached with no linked source", name)); + checks.fail( + std::format("{} signal attached with no linked source", name) + ); } }; - check_optional_signal.template operator()("vref"); - check_optional_signal.template operator()("pref"); - check_optional_signal.template operator()("qref"); - check_optional_signal.template operator()("freq"); - check_optional_signal.template operator()("freqref"); + check_optional_signal.template operator( + )("vref"); + check_optional_signal.template operator( + )("pref"); + check_optional_signal.template operator( + )("qref"); + check_optional_signal.template operator( + )("freq"); + check_optional_signal.template operator( + )("freqref"); return checks; } @@ -222,9 +243,9 @@ namespace GridKit * @brief Initialize REPCA from the initial plant commands * * Reads the required bus and measurement ports, preserves the initial - * system-base `qext` value and, when frequency control is enabled, `pext`, - * reconstructs the steady controller state, and publishes the resolved - * optional references. + * system-base `qext` value and, when frequency control is enabled, + * `pext`, reconstructs the steady controller state, and publishes the + * resolved optional references. * * @pre allocate() has completed. * @pre verify() reports a valid parameter and port configuration. @@ -271,7 +292,8 @@ namespace GridKit if (!this->verifyAndLog()) { - Log::error() << "Repca: cannot initialize with invalid configuration\n"; + Log::error( + ) << "Repca: cannot initialize with invalid configuration\n"; return 1; } @@ -301,15 +323,14 @@ namespace GridKit } auto is_finite = [](ScalarT value) - { - return std::isfinite(static_cast(value)); - }; + { return std::isfinite(static_cast(value)); }; if (!is_finite(vr) || !is_finite(vi) || !is_finite(ir_system) || !is_finite(ii_system) || !is_finite(p_system) || !is_finite(q_system) || !is_finite(freq) || !is_finite(qext0) || (Freqflag_ && !is_finite(pext0))) { - Log::error() << "Repca: initial bus, signal, and command values must be finite\n"; + Log::error() << "Repca: initial bus, signal, and command values must " + "be finite\n"; return 1; } @@ -334,7 +355,8 @@ namespace GridKit if (!invertClamp(zero, emin_, emax_, erqdb0) || !invertDeadband(erqdb0, dbdlow_, dbdupper_, erq0)) { - Log::error() << "Repca: reactive error blocks have no finite steady input\n"; + Log::error( + ) << "Repca: reactive error blocks have no finite steady input\n"; return 1; } const ScalarT erqlim0 = zero; @@ -347,7 +369,8 @@ namespace GridKit ScalarT qpi_input0{}; if (!invertClamp(qpi0, qmin, qmax, qpi_input0)) { - Log::error() << "Repca: reactive-power PI limiter has no finite steady input\n"; + Log::error( + ) << "Repca: reactive-power PI limiter has no finite steady input\n"; return 1; } const ScalarT xqpi0 = qpi_input0 - Kp_ * erqlim0; @@ -357,7 +380,8 @@ namespace GridKit if (!invertDeadband(zero, fdbd1_, fdbd2_, frequency_error0) || !invertClamp(zero, femin_, femax_, ep0)) { - Log::error() << "Repca: active error blocks have no finite steady input\n"; + Log::error( + ) << "Repca: active error blocks have no finite steady input\n"; return 1; } const ScalarT ef0 = zero; @@ -372,7 +396,8 @@ namespace GridKit ScalarT ppi_input0{}; if (!invertClamp(ppi0, pmin, pmax, ppi_input0)) { - Log::error() << "Repca: active-power PI limiter has no finite steady input\n"; + Log::error( + ) << "Repca: active-power PI limiter has no finite steady input\n"; return 1; } const ScalarT xppi0 = ppi_input0 - Kpg_ * eplim0; @@ -389,7 +414,8 @@ namespace GridKit { qref0_system = this->toSystemBase(qmeas0 + erq0); } - const ScalarT pref0_system = p_system + this->toSystemBase(ep0 - pfreq0); + const ScalarT pref0_system = + p_system + this->toSystemBase(ep0 - pfreq0); const bool candidates_are_finite = is_finite(qext0_system) && (!Freqflag_ || is_finite(pext0_system)) @@ -458,27 +484,30 @@ namespace GridKit { qref_port.writeValue(qref_set_); } - if (auto freqref_port = ports_.in.template port()) + if (auto freqref_port = + ports_.in.template port()) { freqref_port.writeValue(freqref_set_); } if (q_adjusted) { - Log::warning() << "Repca: initial reactive PI output is outside [Qmin, Qmax]; " - "the limits are adjusted to include the initialized value\n"; + Log::warning( + ) << "Repca: initial reactive PI output is outside [Qmin, Qmax]; " + "the limits are adjusted to include the initialized value\n"; } if (p_adjusted) { - Log::warning() << "Repca: initial active PI output is outside [Pmin, Pmax]; " - "the limits are adjusted to include the initialized value\n"; + Log::warning( + ) << "Repca: initial active PI output is outside [Pmin, Pmax]; " + "the limits are adjusted to include the initialized value\n"; } - if (Freqflag_ - && (Ddn_ != ZERO || Dup_ != ZERO) + if (Freqflag_ && (Ddn_ != ZERO || Dup_ != ZERO) && !ports_.in.template port()) { Log::warning() << "Repca: Freqflag is enabled without a freq signal; " - "frequency remains nominal and cannot track bus-frequency deviations\n"; + "frequency remains nominal and cannot track " + "bus-frequency deviations\n"; } y_.setDataUpdated(); @@ -545,21 +574,28 @@ namespace GridKit template int Repca::setSignalIndices() { - const auto IR = static_cast(RepcaExternalVariables::IR); - const auto II = static_cast(RepcaExternalVariables::II); - const auto P = static_cast(RepcaExternalVariables::P); - const auto Q = static_cast(RepcaExternalVariables::Q); - const auto FREQ = static_cast(RepcaExternalVariables::FREQ); - const auto VREF = static_cast(RepcaExternalVariables::VREF); - const auto PREF = static_cast(RepcaExternalVariables::PREF); - const auto QREF = static_cast(RepcaExternalVariables::QREF); - const auto FREQREF = static_cast(RepcaExternalVariables::FREQREF); + const auto IR = static_cast(RepcaExternalVariables::IR); + const auto II = static_cast(RepcaExternalVariables::II); + const auto P = static_cast(RepcaExternalVariables::P); + const auto Q = static_cast(RepcaExternalVariables::Q); + const auto FREQ = static_cast(RepcaExternalVariables::FREQ); + const auto VREF = static_cast(RepcaExternalVariables::VREF); + const auto PREF = static_cast(RepcaExternalVariables::PREF); + const auto QREF = static_cast(RepcaExternalVariables::QREF); + const auto FREQREF = + static_cast(RepcaExternalVariables::FREQREF); std::fill(ws_indices_.begin(), ws_indices_.end(), INVALID_INDEX); - ws_indices_[IR] = ports_.in.template port().signalVariableIndex(); - ws_indices_[II] = ports_.in.template port().signalVariableIndex(); - ws_indices_[P] = ports_.in.template port().signalVariableIndex(); - ws_indices_[Q] = ports_.in.template port().signalVariableIndex(); + ws_indices_[IR] = + ports_.in.template port().signalVariableIndex( + ); + ws_indices_[II] = + ports_.in.template port().signalVariableIndex( + ); + ws_indices_[P] = + ports_.in.template port().signalVariableIndex(); + ws_indices_[Q] = + ports_.in.template port().signalVariableIndex(); if (auto freq_port = ports_.in.template port()) { ws_indices_[FREQ] = freq_port.signalVariableIndex(); @@ -576,7 +612,8 @@ namespace GridKit { ws_indices_[QREF] = qref_port.signalVariableIndex(); } - if (auto freqref_port = ports_.in.template port()) + if (auto freqref_port = + ports_.in.template port()) { ws_indices_[FREQREF] = freqref_port.signalVariableIndex(); } @@ -594,15 +631,16 @@ namespace GridKit template int Repca::evaluateResidual() { - const auto IR = static_cast(RepcaExternalVariables::IR); - const auto II = static_cast(RepcaExternalVariables::II); - const auto P = static_cast(RepcaExternalVariables::P); - const auto Q = static_cast(RepcaExternalVariables::Q); - const auto FREQ = static_cast(RepcaExternalVariables::FREQ); - const auto VREF = static_cast(RepcaExternalVariables::VREF); - const auto PREF = static_cast(RepcaExternalVariables::PREF); - const auto QREF = static_cast(RepcaExternalVariables::QREF); - const auto FREQREF = static_cast(RepcaExternalVariables::FREQREF); + const auto IR = static_cast(RepcaExternalVariables::IR); + const auto II = static_cast(RepcaExternalVariables::II); + const auto P = static_cast(RepcaExternalVariables::P); + const auto Q = static_cast(RepcaExternalVariables::Q); + const auto FREQ = static_cast(RepcaExternalVariables::FREQ); + const auto VREF = static_cast(RepcaExternalVariables::VREF); + const auto PREF = static_cast(RepcaExternalVariables::PREF); + const auto QREF = static_cast(RepcaExternalVariables::QREF); + const auto FREQREF = + static_cast(RepcaExternalVariables::FREQREF); auto* ws = ws_.getData(); @@ -633,7 +671,8 @@ namespace GridKit { ws[QREF] = qref_port.readSignal(); } - if (auto freqref_port = ports_.in.template port()) + if (auto freqref_port = + ports_.in.template port()) { ws[FREQREF] = freqref_port.readSignal(); } @@ -654,10 +693,12 @@ namespace GridKit /** * @brief Access the configured monitor * - * @return Monitor for this model, or nullptr when constructed without data. + * @return Monitor for this model, or nullptr when constructed without + * data. */ template - const Model::VariableMonitorBase* Repca::getMonitor() const + const Model::VariableMonitorBase* Repca:: + getMonitor() const { return monitor_.get(); } @@ -687,38 +728,41 @@ namespace GridKit ScalarT* f ) { - const auto VMEAS = static_cast(RepcaInternalVariables::VMEAS); - const auto QMEAS = static_cast(RepcaInternalVariables::QMEAS); - const auto XQPI = static_cast(RepcaInternalVariables::XQPI); - const auto XQLAG = static_cast(RepcaInternalVariables::XQLAG); - const auto PMEAS = static_cast(RepcaInternalVariables::PMEAS); - const auto XPPI = static_cast(RepcaInternalVariables::XPPI); - const auto PREF_STATE = static_cast(RepcaInternalVariables::PREF); - const auto V = static_cast(RepcaInternalVariables::V); - const auto VLDC = static_cast(RepcaInternalVariables::VLDC); - const auto VDROOP = static_cast(RepcaInternalVariables::VDROOP); - const auto VCTRL = static_cast(RepcaInternalVariables::VCTRL); - const auto SFRZ = static_cast(RepcaInternalVariables::SFRZ); - const auto ERQ = static_cast(RepcaInternalVariables::ERQ); - const auto ERQDB = static_cast(RepcaInternalVariables::ERQDB); - const auto ERQLIM = static_cast(RepcaInternalVariables::ERQLIM); - const auto QPI = static_cast(RepcaInternalVariables::QPI); - const auto QEXT = static_cast(RepcaInternalVariables::QEXT); - const auto EF = static_cast(RepcaInternalVariables::EF); - const auto EP = static_cast(RepcaInternalVariables::EP); - const auto EPLIM = static_cast(RepcaInternalVariables::EPLIM); - const auto PPI = static_cast(RepcaInternalVariables::PPI); - const auto PEXT = static_cast(RepcaInternalVariables::PEXT); - - const auto IR = static_cast(RepcaExternalVariables::IR); - const auto II = static_cast(RepcaExternalVariables::II); - const auto P = static_cast(RepcaExternalVariables::P); - const auto Q = static_cast(RepcaExternalVariables::Q); - const auto FREQ = static_cast(RepcaExternalVariables::FREQ); - const auto VREF = static_cast(RepcaExternalVariables::VREF); - const auto PREF_INPUT = static_cast(RepcaExternalVariables::PREF); - const auto QREF = static_cast(RepcaExternalVariables::QREF); - const auto FREQREF = static_cast(RepcaExternalVariables::FREQREF); + const auto VMEAS = static_cast(RepcaInternalVariables::VMEAS); + const auto QMEAS = static_cast(RepcaInternalVariables::QMEAS); + const auto XQPI = static_cast(RepcaInternalVariables::XQPI); + const auto XQLAG = static_cast(RepcaInternalVariables::XQLAG); + const auto PMEAS = static_cast(RepcaInternalVariables::PMEAS); + const auto XPPI = static_cast(RepcaInternalVariables::XPPI); + const auto PREF_STATE = + static_cast(RepcaInternalVariables::PREF); + const auto V = static_cast(RepcaInternalVariables::V); + const auto VLDC = static_cast(RepcaInternalVariables::VLDC); + const auto VDROOP = static_cast(RepcaInternalVariables::VDROOP); + const auto VCTRL = static_cast(RepcaInternalVariables::VCTRL); + const auto SFRZ = static_cast(RepcaInternalVariables::SFRZ); + const auto ERQ = static_cast(RepcaInternalVariables::ERQ); + const auto ERQDB = static_cast(RepcaInternalVariables::ERQDB); + const auto ERQLIM = static_cast(RepcaInternalVariables::ERQLIM); + const auto QPI = static_cast(RepcaInternalVariables::QPI); + const auto QEXT = static_cast(RepcaInternalVariables::QEXT); + const auto EF = static_cast(RepcaInternalVariables::EF); + const auto EP = static_cast(RepcaInternalVariables::EP); + const auto EPLIM = static_cast(RepcaInternalVariables::EPLIM); + const auto PPI = static_cast(RepcaInternalVariables::PPI); + const auto PEXT = static_cast(RepcaInternalVariables::PEXT); + + const auto IR = static_cast(RepcaExternalVariables::IR); + const auto II = static_cast(RepcaExternalVariables::II); + const auto P = static_cast(RepcaExternalVariables::P); + const auto Q = static_cast(RepcaExternalVariables::Q); + const auto FREQ = static_cast(RepcaExternalVariables::FREQ); + const auto VREF = static_cast(RepcaExternalVariables::VREF); + const auto PREF_INPUT = + static_cast(RepcaExternalVariables::PREF); + const auto QREF = static_cast(RepcaExternalVariables::QREF); + const auto FREQREF = + static_cast(RepcaExternalVariables::FREQREF); const ScalarT vmeas = y[VMEAS]; const ScalarT qmeas = y[QMEAS]; @@ -768,10 +812,12 @@ namespace GridKit const ScalarT vldc_i = vi - Rc_ * ii - Xc_ * ir; const ScalarT pfreq = droop(ef, Ddn_, Dup_); - const ScalarT q_pi_rate = q_feedback_gain_ * (qpi - Math::clamp(xqpi, Qmin_, Qmax_)) - + Math::antiwindup(xqpi, q_integral_gain_ * erqlim, Qmin_, Qmax_); - const ScalarT p_pi_rate = p_feedback_gain_ * (ppi - Math::clamp(xppi, Pmin_, Pmax_)) - + Math::antiwindup(xppi, p_integral_gain_ * eplim, Pmin_, Pmax_); + const ScalarT q_pi_rate = + q_feedback_gain_ * (qpi - Math::clamp(xqpi, Qmin_, Qmax_)) + + Math::antiwindup(xqpi, q_integral_gain_ * erqlim, Qmin_, Qmax_); + const ScalarT p_pi_rate = + p_feedback_gain_ * (ppi - Math::clamp(xppi, Pmin_, Pmax_)) + + Math::antiwindup(xppi, p_integral_gain_ * eplim, Pmin_, Pmax_); f[VMEAS] = -vmeas_dot + (vctrl - vmeas) / Tfltr_; f[QMEAS] = -qmeas_dot + (q - qmeas) / Tfltr_; @@ -814,8 +860,9 @@ namespace GridKit * @return Active-power frequency response. */ template - __attribute__((always_inline)) inline scalar_type - Repca::droop(ScalarT error, RealT down, RealT up) + __attribute__((always_inline)) inline scalar_type Repca< + scalar_type, + index_type>::droop(ScalarT error, RealT down, RealT up) { return error * (down + (up - down) * Math::sigmoid(error)); } @@ -830,7 +877,9 @@ namespace GridKit * @param[in] data Parameters and monitored-variable selections. */ template - void Repca::initializeParameters(const ModelDataT& data) + void Repca::initializeParameters( + const ModelDataT& data + ) { using Params = typename ModelDataT::Parameters; @@ -879,16 +928,46 @@ namespace GridKit { using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::qext, [this] - { return y_.getData()[static_cast(RepcaInternalVariables::QEXT)]; }); - monitor_->set(Variable::pext, [this] - { return y_.getData()[static_cast(RepcaInternalVariables::PEXT)]; }); - monitor_->set(Variable::vmeas, [this] - { return y_.getData()[static_cast(RepcaInternalVariables::VMEAS)]; }); - monitor_->set(Variable::qmeas, [this] - { return y_.getData()[static_cast(RepcaInternalVariables::QMEAS)]; }); - monitor_->set(Variable::pmeas, [this] - { return y_.getData()[static_cast(RepcaInternalVariables::PMEAS)]; }); + monitor_->set( + Variable::qext, + [this] + { + return y_.getData( + )[static_cast(RepcaInternalVariables::QEXT)]; + } + ); + monitor_->set( + Variable::pext, + [this] + { + return y_.getData( + )[static_cast(RepcaInternalVariables::PEXT)]; + } + ); + monitor_->set( + Variable::vmeas, + [this] + { + return y_.getData( + )[static_cast(RepcaInternalVariables::VMEAS)]; + } + ); + monitor_->set( + Variable::qmeas, + [this] + { + return y_.getData( + )[static_cast(RepcaInternalVariables::QMEAS)]; + } + ); + monitor_->set( + Variable::pmeas, + [this] + { + return y_.getData( + )[static_cast(RepcaInternalVariables::PMEAS)]; + } + ); } /** @@ -902,7 +981,8 @@ namespace GridKit { Log::warning() << "Repca: Tfltr, Tfv, Tp, and Tlag below " << TIME_CONSTANT_MINIMUM - << " s are raised to that floor to keep the controller lags well posed\n"; + << " s are raised to that floor to keep the controller " + "lags well posed\n"; } /** @@ -970,15 +1050,14 @@ namespace GridKit * do not use it during residual evaluation. */ template - bool Repca::invertClamp(ScalarT output, RealT lower, RealT upper, ScalarT& input) const + bool Repca::invertClamp( + ScalarT output, RealT lower, RealT upper, ScalarT& input + ) const { const RealT value = static_cast(output); - if (!std::isfinite(value) - || !std::isfinite(lower) - || !std::isfinite(upper) - || lower > upper - || value < lower + if (!std::isfinite(value) || !std::isfinite(lower) + || !std::isfinite(upper) || lower > upper || value < lower || value > upper) { return false; @@ -1007,9 +1086,10 @@ namespace GridKit const RealT mu = Math::MU; const RealT scaled_lower_distance = mu * distance_from_lower; const RealT scaled_upper_distance = mu * distance_from_upper; - const RealT log_lower = logOneMinusExp(scaled_lower_distance); - const RealT log_upper = logOneMinusExp(scaled_upper_distance); - const RealT correction = (scaled_lower_distance + log_lower - log_upper) / mu; + const RealT log_lower = logOneMinusExp(scaled_lower_distance); + const RealT log_upper = logOneMinusExp(scaled_upper_distance); + const RealT correction = + (scaled_lower_distance + log_lower - log_upper) / mu; input = static_cast(lower + correction); return std::isfinite(static_cast(input)); @@ -1027,14 +1107,14 @@ namespace GridKit * do not use it during residual evaluation. */ template - bool Repca::invertDeadband(ScalarT output, RealT lower, RealT upper, ScalarT& input) const + bool Repca::invertDeadband( + ScalarT output, RealT lower, RealT upper, ScalarT& input + ) const { const RealT value = static_cast(output); - if (!std::isfinite(value) - || !std::isfinite(lower) - || !std::isfinite(upper) - || lower > upper) + if (!std::isfinite(value) || !std::isfinite(lower) + || !std::isfinite(upper) || lower > upper) { return false; } @@ -1059,8 +1139,7 @@ namespace GridKit const RealT lower_output = Math::deadband2(lower_input, lower, upper); const RealT upper_output = Math::deadband2(upper_input, lower, upper); - if (!std::isfinite(lower_output) - || !std::isfinite(upper_output) + if (!std::isfinite(lower_output) || !std::isfinite(upper_output) || lower_output - value > INITIALIZATION_TOLERANCE || value - upper_output > INITIALIZATION_TOLERANCE) { @@ -1069,7 +1148,8 @@ namespace GridKit for (std::size_t iteration = 0; iteration < 128; ++iteration) { - const RealT mid = lower_input + HALF * (upper_input - lower_input); + const RealT mid = + lower_input + HALF * (upper_input - lower_input); if (Math::deadband2(mid, lower, upper) < value) { lower_input = mid; @@ -1080,8 +1160,9 @@ namespace GridKit } } - const RealT result = lower_input + HALF * (upper_input - lower_input); - input = static_cast(result); + const RealT result = + lower_input + HALF * (upper_input - lower_input); + input = static_cast(result); return std::isfinite(result) && std::abs(Math::deadband2(result, lower, upper) - value) <= INITIALIZATION_TOLERANCE; @@ -1098,8 +1179,9 @@ namespace GridKit * @return Numerically stable value of log(1 - exp(-x)). */ template - typename Repca::RealT - Repca::logOneMinusExp(RealT x) + typename Repca::RealT Repca< + scalar_type, + index_type>::logOneMinusExp(RealT x) { static constexpr auto log_two = std::numbers::ln2_v; diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCA/Regca.cpp b/GridKit/Model/PhasorDynamics/Converter/REGCA/Regca.cpp index cf20675bb0..74ea81a5c4 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REGCA/Regca.cpp +++ b/GridKit/Model/PhasorDynamics/Converter/REGCA/Regca.cpp @@ -13,7 +13,8 @@ namespace GridKit namespace Converter { /** - * @brief Report that a separate Jacobian is unavailable in the plain build. + * @brief Report that a separate Jacobian is unavailable in the plain + * build. */ template int Regca::evaluateJacobian() diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCA/Regca.hpp b/GridKit/Model/PhasorDynamics/Converter/REGCA/Regca.hpp index 9701c87350..bb0d519fcc 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REGCA/Regca.hpp +++ b/GridKit/Model/PhasorDynamics/Converter/REGCA/Regca.hpp @@ -37,13 +37,15 @@ namespace GridKit /// Internal variables of a `Regca` enum class RegcaInternalVariables : size_t { - VM, ///< \f$V_M\f$ Filtered terminal voltage - IQ, ///< \f$I_q\f$ Reactive-current state on component base - IP, ///< \f$I_p\f$ Active-current state on component base - VT, ///< \f$V_T\f$ Terminal voltage magnitude - IR, ///< \f$I_\mathrm{r}\f$ Branch-current real component on system base - II, ///< \f$I_\mathrm{i}\f$ Branch-current imaginary component on system base - IQEXTRA, ///< \f$I_q^\mathrm{extra}\f$ Extra inductive current from HVRCM on component base + VM, ///< \f$V_M\f$ Filtered terminal voltage + IQ, ///< \f$I_q\f$ Reactive-current state on component base + IP, ///< \f$I_p\f$ Active-current state on component base + VT, ///< \f$V_T\f$ Terminal voltage magnitude + IR, ///< \f$I_\mathrm{r}\f$ Branch-current real component on system base + II, ///< \f$I_\mathrm{i}\f$ Branch-current imaginary component on system + ///< base + IQEXTRA, ///< \f$I_q^\mathrm{extra}\f$ Extra inductive current from + ///< HVRCM on component base IL, ///< \f$I_L\f$ LVPL upper-limit current curve on component base PBR, ///< \f$P^\mathrm{br}\f$ Branch active power on system base QBR, ///< \f$Q^\mathrm{br}\f$ Branch reactive power on system base @@ -53,11 +55,13 @@ namespace GridKit enum class RegcaExternalVariables : size_t { IPCMD, ///< \f$I_p^\mathrm{cmd}\f$ Active-current command on system base - IQCMD, ///< \f$I_q^\mathrm{cmd}\f$ Reactive-current command on system base + IQCMD, ///< \f$I_q^\mathrm{cmd}\f$ Reactive-current command on system + ///< base }; /** - * @brief First-generation WECC renewable generator/converter model (REGCA). + * @brief First-generation WECC renewable generator/converter model + * (REGCA). * * @tparam scalar_type Plain real or differentiable scalar type. * @tparam index_type Integer index type. @@ -204,8 +208,9 @@ namespace GridKit static RealT iramp(RealT value); - static constexpr RealT TIME_CONSTANT_MINIMUM = static_cast(1.0e-3); - static constexpr RealT KL_ = static_cast(100.0); + static constexpr RealT TIME_CONSTANT_MINIMUM = + static_cast(1.0e-3); + static constexpr RealT KL_ = static_cast(100.0); static void logTimeConstantWarning(); BusT* bus_{nullptr}; diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaData.hpp b/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaData.hpp index 23e0076053..eb233f3093 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaData.hpp +++ b/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaData.hpp @@ -55,8 +55,8 @@ namespace GridKit /// Signal outputs for the REGCA converter model. enum class RegcaSignalOutputs : size_t { - ir, ///< Optional terminal-current real-component output signal ID - ii, ///< Optional terminal-current imaginary-component output signal ID + ir, ///< Optional terminal-current real-component output signal ID + ii, ///< Optional terminal-current imaginary-component output signal ID pbranch, ///< Optional branch active-power output signal ID qbranch, ///< Optional branch reactive-power output signal ID }; @@ -73,8 +73,8 @@ namespace GridKit /// Initial values for the REGCA converter model. enum class RegcaInitialValues : size_t { - ir, ///< Initial real terminal current into the bus on system base - ii, ///< Initial imaginary terminal current into the bus on system base + ir, ///< Initial real terminal current into the bus on system base + ii, ///< Initial imaginary terminal current into the bus on system base in_service, ///< Initial service status; defaults to true }; diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaEnzyme.cpp b/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaEnzyme.cpp index 355e13a84a..0477c7c01c 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaEnzyme.cpp @@ -29,10 +29,11 @@ namespace GridKit auto size = static_cast(size_); auto bus_size = static_cast(bus_->size()); auto signal_size = static_cast(ws_.getSize()); - auto buffer_size = 2 * size * size + 2 * size * bus_size + size * signal_size; - J_rows_buffer_ = new IdxT[buffer_size]; - J_cols_buffer_ = new IdxT[buffer_size]; - J_vals_buffer_ = new RealT[buffer_size]; + auto buffer_size = + 2 * size * size + 2 * size * bus_size + size * signal_size; + J_rows_buffer_ = new IdxT[buffer_size]; + J_cols_buffer_ = new IdxT[buffer_size]; + J_vals_buffer_ = new RealT[buffer_size]; } using RegcaT = GridKit::PhasorDynamics::Converter::Regca; diff --git a/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaImpl.hpp b/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaImpl.hpp index 0f2b46aa57..62c0b10d22 100644 --- a/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Converter/REGCA/RegcaImpl.hpp @@ -38,12 +38,12 @@ namespace GridKit */ template Regca::Regca(BusT* bus, const ModelDataT& data) - : bus_(bus), - monitor_(std::make_unique(data)) + : bus_(bus), monitor_(std::make_unique(data)) { initializeParameters(data); initializeMonitor(); - size_ = static_cast(Utilities::enum_size()); + size_ = + static_cast(Utilities::enum_size()); } template @@ -60,17 +60,20 @@ namespace GridKit template void Regca::logTimeConstantWarning() { - Log::warning() << "Regca: Tg and TM below " << TIME_CONSTANT_MINIMUM - << " s are raised to that floor to keep the current-control " - << "and voltage-sensor lags well posed\n"; + Log::warning( + ) << "Regca: Tg and TM below " + << TIME_CONSTANT_MINIMUM + << " s are raised to that floor to keep the current-control " + << "and voltage-sensor lags well posed\n"; } /** * @brief Resolve parameter-derived constants and limiter selections. * - * The time constants are raised to the well-posedness floor. Complementary - * LVPL masks keep the residual branchless, while the sign of the initial - * reactive-power injection selects the applicable recovery-rate limit. + * The time constants are raised to the well-posedness floor. + * Complementary LVPL masks keep the residual branchless, while the sign + * of the initial reactive-power injection selects the applicable + * recovery-rate limit. */ template void Regca::setDerivedParameters() @@ -174,7 +177,9 @@ namespace GridKit * @param[in] data REGCA parameter data. */ template - void Regca::initializeParameters(const ModelDataT& data) + void Regca::initializeParameters( + const ModelDataT& data + ) { using Params = typename ModelDataT::Parameters; @@ -202,10 +207,12 @@ namespace GridKit /** * @brief Access the model monitor. * - * @return Monitor for this model, or nullptr when constructed without data. + * @return Monitor for this model, or nullptr when constructed without + * data. */ template - const Model::VariableMonitorBase* Regca::getMonitor() const + const Model::VariableMonitorBase* Regca:: + getMonitor() const { return monitor_.get(); } @@ -221,18 +228,28 @@ namespace GridKit { using Variable = typename ModelDataT::MonitorableVariables; auto index = [](RegcaInternalVariables variable) - { - return static_cast(variable); - }; - - monitor_->set(Variable::ir, [this, index] - { return y_.getData()[index(RegcaInternalVariables::IR)]; }); - monitor_->set(Variable::ii, [this, index] - { return y_.getData()[index(RegcaInternalVariables::II)]; }); - monitor_->set(Variable::p, [this, index] - { return y_.getData()[index(RegcaInternalVariables::PBR)]; }); - monitor_->set(Variable::q, [this, index] - { return y_.getData()[index(RegcaInternalVariables::QBR)]; }); + { return static_cast(variable); }; + + monitor_->set( + Variable::ir, + [this, index] + { return y_.getData()[index(RegcaInternalVariables::IR)]; } + ); + monitor_->set( + Variable::ii, + [this, index] + { return y_.getData()[index(RegcaInternalVariables::II)]; } + ); + monitor_->set( + Variable::p, + [this, index] + { return y_.getData()[index(RegcaInternalVariables::PBR)]; } + ); + monitor_->set( + Variable::q, + [this, index] + { return y_.getData()[index(RegcaInternalVariables::QBR)]; } + ); } /** @@ -241,7 +258,9 @@ namespace GridKit * @param[in] component_id Component identifier. */ template - int Regca::setGridKitComponentID(IdxT component_id) + int Regca::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -250,9 +269,10 @@ namespace GridKit /** * @brief Allocate model storage and connect assigned output signals. * - * State, residual, tolerance, and interface buffers are sized; local index - * maps are initialized; and assigned output signals are connected to the - * states they publish. Repeated calls reuse the allocated model vectors. + * State, residual, tolerance, and interface buffers are sized; local + * index maps are initialized; and assigned output signals are connected + * to the states they publish. Repeated calls reuse the allocated model + * vectors. */ template int Regca::allocate() @@ -333,8 +353,8 @@ namespace GridKit * @brief Validate the REGCA configuration. * * Applies the parameter conditions documented in the README, requires a - * terminal bus, and checks that attached command ports have linked sources. - * Operating-point admissibility is checked by initialize(). + * terminal bus, and checks that attached command ports have linked + * sources. Operating-point admissibility is checked by initialize(). * * @return The configuration checks; passed() when valid. */ @@ -351,7 +371,10 @@ namespace GridKit checks.check(mva_base_ > ZERO, "mva must be positive"); checks.check(Rpmax_ >= ZERO, "Rpmax must be non-negative"); checks.check(IL1_ >= ZERO, "IL1 must be non-negative"); - checks.check(ZERO <= VL0_ && VL0_ < VL1_, "VL0/VL1 must satisfy 0 <= VL0 < VL1"); + checks.check( + ZERO <= VL0_ && VL0_ < VL1_, + "VL0/VL1 must satisfy 0 <= VL0 < VL1" + ); checks.check( ZERO <= VA0_ && VA0_ < VA1_ && VA1_ < Vhvmax_, "VA0/VA1/Vhvmax must satisfy 0 <= VA0 < VA1 < Vhvmax" @@ -385,26 +408,28 @@ namespace GridKit * * @pre allocate() has completed, verify() reports no errors, and the * terminal bus has been initialized. - * @pre \f$V_{A1} \le V_{T,0} < V_\mathrm{hv}^{\max}\f$, and with LVPL enabled + * @pre \f$V_{A1} \le V_{T,0} < V_\mathrm{hv}^{\max}\f$, and with LVPL + * enabled * \f$I_{p,0} \le I_{L,0}\f$. - * @post All internal derivatives are zero. Unattached command ports retain - * the resolved setpoints as constant commands. + * @post All internal derivatives are zero. Unattached command ports + * retain the resolved setpoints as constant commands. * @return Zero on success; nonzero when the operating point is rejected. */ template int Regca::initialize() { - const auto VM = static_cast(RegcaInternalVariables::VM); - const auto IQ = static_cast(RegcaInternalVariables::IQ); - const auto IP = static_cast(RegcaInternalVariables::IP); - const auto VT = static_cast(RegcaInternalVariables::VT); - const auto IR = static_cast(RegcaInternalVariables::IR); - const auto II = static_cast(RegcaInternalVariables::II); - const auto IQEXTRA = static_cast(RegcaInternalVariables::IQEXTRA); - const auto IL = static_cast(RegcaInternalVariables::IL); - const auto PBR = static_cast(RegcaInternalVariables::PBR); - const auto QBR = static_cast(RegcaInternalVariables::QBR); - auto* y = y_.getData(); + const auto VM = static_cast(RegcaInternalVariables::VM); + const auto IQ = static_cast(RegcaInternalVariables::IQ); + const auto IP = static_cast(RegcaInternalVariables::IP); + const auto VT = static_cast(RegcaInternalVariables::VT); + const auto IR = static_cast(RegcaInternalVariables::IR); + const auto II = static_cast(RegcaInternalVariables::II); + const auto IQEXTRA = + static_cast(RegcaInternalVariables::IQEXTRA); + const auto IL = static_cast(RegcaInternalVariables::IL); + const auto PBR = static_cast(RegcaInternalVariables::PBR); + const auto QBR = static_cast(RegcaInternalVariables::QBR); + auto* y = y_.getData(); const ScalarT vr = Vr(); const ScalarT vi = Vi(); @@ -412,7 +437,8 @@ namespace GridKit if (vt <= ZERO) { - Log::error() << "Regca: terminal voltage magnitude must be positive at initialization\n"; + Log::error() << "Regca: terminal voltage magnitude must be positive " + "at initialization\n"; return 1; } if (vt < VA1_) @@ -431,13 +457,15 @@ namespace GridKit // P0 is a system-base power-flow injection. Resolve the component-base // active current through the LVACM network-interface gain. const ScalarT lvacm = Math::linseg(vt, VA0_, VA1_, ONE); - const ScalarT ip0 = this->toComponentBase(static_cast(p0_) / vt) / lvacm; - const ScalarT il0 = Math::linseg(vt, VL0_, VL1_, IL1_) - + KL_ * Math::ramp(vt - VL1_); + const ScalarT ip0 = + this->toComponentBase(static_cast(p0_) / vt) / lvacm; + const ScalarT il0 = + Math::linseg(vt, VL0_, VL1_, IL1_) + KL_ * Math::ramp(vt - VL1_); if (sL_ && ip0 > il0) { - Log::error() << "Regca: initial active current exceeds the LVPL ceiling\n"; + Log::error( + ) << "Regca: initial active current exceeds the LVPL ceiling\n"; return 1; } const ScalarT ipcmd0 = ip0; @@ -445,10 +473,11 @@ namespace GridKit // Invert the HVRCM ceiling and preserve the requested Q0. const RealT margin = Vhvmax_ - static_cast(vt); const ScalarT iqextra0 = static_cast(margin - iramp(margin)); - const ScalarT qnet0 = this->toComponentBase(static_cast(q0_) / vt); - const ScalarT iqcmd0 = qnet0 + iqextra0; - const ScalarT ir0 = (vi * qnet0 + vr * ip0 * lvacm) / vt; - const ScalarT ii0 = (-vr * qnet0 + vi * ip0 * lvacm) / vt; + const ScalarT qnet0 = + this->toComponentBase(static_cast(q0_) / vt); + const ScalarT iqcmd0 = qnet0 + iqextra0; + const ScalarT ir0 = (vi * qnet0 + vr * ip0 * lvacm) / vt; + const ScalarT ii0 = (-vr * qnet0 + vi * ip0 * lvacm) / vt; y[VM] = vt; y[VT] = vt; @@ -467,11 +496,13 @@ namespace GridKit // Publish the resolved system-base commands for downstream controller // initialization. Unattached ports retain these values as constant // commands. - if (auto ipcmd_port = ports_.in.template port()) + if (auto ipcmd_port = + ports_.in.template port()) { ipcmd_port.writeValue(ipcmd_set_); } - if (auto iqcmd_port = ports_.in.template port()) + if (auto iqcmd_port = + ports_.in.template port()) { iqcmd_port.writeValue(iqcmd_set_); } @@ -502,7 +533,8 @@ namespace GridKit } /** - * @brief Set every REGCA absolute tolerance to the solver relative tolerance. + * @brief Set every REGCA absolute tolerance to the solver relative + * tolerance. * * @param[in] rel_tol Solver relative tolerance. */ @@ -536,16 +568,17 @@ namespace GridKit ScalarT* f ) { - const auto VM = static_cast(RegcaInternalVariables::VM); - const auto IQ = static_cast(RegcaInternalVariables::IQ); - const auto IP = static_cast(RegcaInternalVariables::IP); - const auto VT = static_cast(RegcaInternalVariables::VT); - const auto IR = static_cast(RegcaInternalVariables::IR); - const auto II = static_cast(RegcaInternalVariables::II); - const auto IQEXTRA = static_cast(RegcaInternalVariables::IQEXTRA); - const auto IL = static_cast(RegcaInternalVariables::IL); - const auto PBR = static_cast(RegcaInternalVariables::PBR); - const auto QBR = static_cast(RegcaInternalVariables::QBR); + const auto VM = static_cast(RegcaInternalVariables::VM); + const auto IQ = static_cast(RegcaInternalVariables::IQ); + const auto IP = static_cast(RegcaInternalVariables::IP); + const auto VT = static_cast(RegcaInternalVariables::VT); + const auto IR = static_cast(RegcaInternalVariables::IR); + const auto II = static_cast(RegcaInternalVariables::II); + const auto IQEXTRA = + static_cast(RegcaInternalVariables::IQEXTRA); + const auto IL = static_cast(RegcaInternalVariables::IL); + const auto PBR = static_cast(RegcaInternalVariables::PBR); + const auto QBR = static_cast(RegcaInternalVariables::QBR); const auto IPCMD = static_cast(RegcaExternalVariables::IPCMD); const auto IQCMD = static_cast(RegcaExternalVariables::IQCMD); @@ -585,9 +618,10 @@ namespace GridKit // chain rule (inside() is the linseg slope mask and ramp' = sigmoid); // a pinned Ip tracks the moving ceiling. const ScalarT vm_rate = (vt - vm) / TM_; - const ScalarT il_rate = (IL1_ / (VL1_ - VL0_) * Math::inside(vm, VL0_, VL1_) - + KL_ * Math::sigmoid(vm - VL1_)) - * vm_rate; + const ScalarT il_rate = + (IL1_ / (VL1_ - VL0_) * Math::inside(vm, VL0_, VL1_) + + KL_ * Math::sigmoid(vm - VL1_)) + * vm_rate; const ScalarT lvacm = Math::linseg(vt, VA0_, VA1_, ONE); const ScalarT qnet = iq - iqextra; @@ -595,9 +629,9 @@ namespace GridKit f[IQ] = -iq_dot + iq_rate; f[IP] = -ip_dot + bypass_lvpl_ * fp_limited + use_lvpl_ * awmax(ip, fp_limited, il, il_rate); - f[VT] = -vt * vt + vr * vr + vi * vi; - f[IR] = -this->toComponentBase(vt * ir) + vi * qnet + vr * ip * lvacm; - f[II] = -this->toComponentBase(vt * ii) - vr * qnet + vi * ip * lvacm; + f[VT] = -vt * vt + vr * vr + vi * vi; + f[IR] = -this->toComponentBase(vt * ir) + vi * qnet + vr * ip * lvacm; + f[II] = -this->toComponentBase(vt * ii) - vr * qnet + vi * ip * lvacm; f[IQEXTRA] = -Math::min(iqextra, Vhvmax_ - vt); f[IL] = -il + Math::linseg(vm, VL0_, VL1_, IL1_) + KL_ * Math::ramp(vm - VL1_); @@ -645,11 +679,13 @@ namespace GridKit const auto IQCMD = static_cast(RegcaExternalVariables::IQCMD); std::fill(ws_indices_.begin(), ws_indices_.end(), INVALID_INDEX); - if (auto ipcmd_port = ports_.in.template port()) + if (auto ipcmd_port = + ports_.in.template port()) { ws_indices_[IPCMD] = ipcmd_port.signalVariableIndex(); } - if (auto iqcmd_port = ports_.in.template port()) + if (auto iqcmd_port = + ports_.in.template port()) { ws_indices_[IQCMD] = iqcmd_port.signalVariableIndex(); } @@ -661,8 +697,9 @@ namespace GridKit * @brief Evaluate model residuals and accumulate the branch current. * * Refreshes the bus and signal interface buffers, evaluates the internal - * and bus residuals, and accumulates the converter current into the terminal - * bus. Unattached command ports use the setpoints latched by initialize(). + * and bus residuals, and accumulates the converter current into the + * terminal bus. Unattached command ports use the setpoints latched by + * initialize(). * * @pre The terminal-bus residual has been zeroed for this evaluation. */ @@ -677,12 +714,14 @@ namespace GridKit ws[IPCMD] = ipcmd_set_; ws[IQCMD] = iqcmd_set_; - if (auto ipcmd_port = ports_.in.template port()) + if (auto ipcmd_port = + ports_.in.template port()) { ws[IPCMD] = ipcmd_port.readSignal(); } - if (auto iqcmd_port = ports_.in.template port()) + if (auto iqcmd_port = + ports_.in.template port()) { ws[IQCMD] = iqcmd_port.readSignal(); } diff --git a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1a.cpp b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1a.cpp index 4a59b8feed..b7d3c90e29 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1a.cpp +++ b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1a.cpp @@ -13,7 +13,8 @@ namespace GridKit namespace Exciter { /** - * @brief Report that a separate Jacobian is unavailable in the plain build. + * @brief Report that a separate Jacobian is unavailable in the plain + * build. */ template int Esdc1a::evaluateJacobian() diff --git a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1a.hpp b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1a.hpp index 4281b6dc2f..9871ce4d33 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1a.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1a.hpp @@ -30,11 +30,14 @@ namespace GridKit /// Internal variables of an `Esdc1a`. enum class Esdc1aInternalVariables : size_t { - EFDP, ///< \f$E_{\mathrm{fd}}'\f$ Differential exciter field-voltage state [p.u.] - VC, ///< \f$V_C\f$ Differential filtered terminal-voltage magnitude [p.u.] + EFDP, ///< \f$E_{\mathrm{fd}}'\f$ Differential exciter field-voltage + ///< state [p.u.] + VC, ///< \f$V_C\f$ Differential filtered terminal-voltage magnitude + ///< [p.u.] VR, ///< \f$V_R\f$ Differential voltage-regulator output [p.u.] VF, ///< \f$V_F\f$ Differential stabilizing feedback state [p.u.] - XLL, ///< \f$x_{\mathrm{LL}}\f$ Differential input lead-lag denominator state [p.u.] + XLL, ///< \f$x_{\mathrm{LL}}\f$ Differential input lead-lag denominator + ///< state [p.u.] EV, ///< \f$e_V\f$ Algebraic voltage-error summing output [p.u.] VLL, ///< \f$V_{\mathrm{LL}}\f$ Algebraic input lead-lag output [p.u.] VHV, ///< \f$V_{\mathrm{HV}}\f$ Algebraic high-value gate output [p.u.] @@ -47,9 +50,11 @@ namespace GridKit enum class Esdc1aExternalVariables : size_t { OMEGA, ///< \f$\omega\f$ Known machine speed deviation [p.u.] - VREF, ///< \f$V_{\mathrm{ref}}\f$ Unknown voltage-control reference [p.u.] + VREF, ///< \f$V_{\mathrm{ref}}\f$ Unknown voltage-control reference + ///< [p.u.] VS, ///< \f$V_S\f$ Known stabilizer input signal [p.u.] - VUEL, ///< \f$V_{\mathrm{UEL}}\f$ Known under-excitation limiter input [p.u.] + VUEL, ///< \f$V_{\mathrm{UEL}}\f$ Known under-excitation limiter input + ///< [p.u.] }; /** @@ -139,8 +144,9 @@ namespace GridKit ScalarT& Vr(); ScalarT& Vi(); - static constexpr RealT TIME_CONSTANT_MINIMUM = static_cast(1.0e-3); - static void logTimeConstantWarning(); + static constexpr RealT TIME_CONSTANT_MINIMUM = + static_cast(1.0e-3); + static void logTimeConstantWarning(); BusT* bus_{nullptr}; diff --git a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aData.hpp b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aData.hpp index 4a87716db4..9e72e6b31b 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aData.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aData.hpp @@ -29,26 +29,31 @@ namespace GridKit Te, ///< \f$T_E\f$ Exciter time constant [sec] Kf, ///< \f$K_F\f$ Stabilizing feedback gain [p.u.] Tf1, ///< \f$T_{F1}\f$ Stabilizing feedback time constant [sec] - Spdmlt, ///< \f$s_{\mathrm{spd}}\f$ Field-voltage speed-multiplier flag [boolean] + Spdmlt, ///< \f$s_{\mathrm{spd}}\f$ Field-voltage speed-multiplier flag + ///< [boolean] E1, ///< \f$E_1\f$ First saturation voltage point [p.u.] Se1, ///< \f$S_E(E_1)\f$ Saturation coefficient at \f$E_1\f$ [p.u.] E2, ///< \f$E_2\f$ Second saturation voltage point [p.u.] Se2, ///< \f$S_E(E_2)\f$ Saturation coefficient at \f$E_2\f$ [p.u.] UEL, ///< \f$I_{\mathrm{UEL}}\f$ UEL input-routing selector [integer] - exclim, ///< \f$s_{\mathrm{lim}}\f$ Exciter field-voltage-state lower-limit flag [boolean] + exclim, ///< \f$s_{\mathrm{lim}}\f$ Exciter field-voltage-state + ///< lower-limit flag [boolean] }; /// Buses for the ESDC1A exciter model. enum class Esdc1aBuses : size_t { - bus, ///< \f$V_{\mathrm{r}},V_{\mathrm{i}}\f$ Required Known terminal-bus voltage [p.u.] + bus, ///< \f$V_{\mathrm{r}},V_{\mathrm{i}}\f$ Required Known + ///< terminal-bus voltage [p.u.] }; /// Signal inputs for the ESDC1A exciter model. enum class Esdc1aSignalInputs : size_t { - speed, ///< \f$\omega\f$ Known machine speed-deviation input [p.u.]; required when \f$s_{\mathrm{spd}}=1\f$ - vref, ///< \f$V_{\mathrm{ref}}\f$ Optional Unknown voltage-reference input [p.u.] + speed, ///< \f$\omega\f$ Known machine speed-deviation input [p.u.]; + ///< required when \f$s_{\mathrm{spd}}=1\f$ + vref, ///< \f$V_{\mathrm{ref}}\f$ Optional Unknown voltage-reference + ///< input [p.u.] vs, ///< \f$V_S\f$ Optional Known stabilizer input [p.u.] vuel, ///< \f$V_{\mathrm{UEL}}\f$ Optional Known UEL input [p.u.] }; @@ -56,7 +61,8 @@ namespace GridKit /// Signal outputs for the ESDC1A exciter model. enum class Esdc1aSignalOutputs : size_t { - efd, ///< \f$E_{\mathrm{fd}}\f$ Required Known field-voltage output [p.u.] + efd, ///< \f$E_{\mathrm{fd}}\f$ Required Known field-voltage output + ///< [p.u.] }; /// Variables available through the monitor interface. diff --git a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aEnzyme.cpp b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aEnzyme.cpp index b3ae0deaad..63516b9b73 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aEnzyme.cpp @@ -34,14 +34,16 @@ namespace GridKit auto size = static_cast(size_); auto bus_size = static_cast(bus_->size()); auto signal_size = static_cast(ws_.getSize()); - auto buffer_size = 2 * size * size + size * bus_size + size * signal_size; - J_rows_buffer_ = new IdxT[buffer_size]; - J_cols_buffer_ = new IdxT[buffer_size]; - J_vals_buffer_ = new RealT[buffer_size]; + auto buffer_size = + 2 * size * size + size * bus_size + size * signal_size; + J_rows_buffer_ = new IdxT[buffer_size]; + J_cols_buffer_ = new IdxT[buffer_size]; + J_vals_buffer_ = new RealT[buffer_size]; } - using ModelT = GridKit::PhasorDynamics::Exciter::Esdc1a; - using Fn = GridKit::Enzyme::Sparse::MemberFunctions; + using ModelT = + GridKit::PhasorDynamics::Exciter::Esdc1a; + using Fn = GridKit::Enzyme::Sparse::MemberFunctions; nnz_ = 0; diff --git a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aImpl.hpp b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aImpl.hpp index 0b6aa18b4c..1a9976c4a7 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/ESDC1A/Esdc1aImpl.hpp @@ -37,12 +37,12 @@ namespace GridKit */ template Esdc1a::Esdc1a(BusT* bus, const ModelDataT& data) - : bus_(bus), - monitor_(std::make_unique(data)) + : bus_(bus), monitor_(std::make_unique(data)) { initializeParameters(data); initializeMonitor(); - size_ = static_cast(Utilities::enum_size()); + size_ = + static_cast(Utilities::enum_size()); } /** @@ -60,7 +60,9 @@ namespace GridKit * @return Zero on success. */ template - int Esdc1a::setGridKitComponentID(IdxT component_id) + int Esdc1a::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -95,7 +97,8 @@ namespace GridKit wb_.resize(2); wb_.setToZero(); - const auto signal_size = Utilities::enum_size(); + const auto signal_size = + Utilities::enum_size(); ws_.resize(static_cast(signal_size)); ws_.setToZero(); ws_indices_.assign(signal_size, INVALID_INDEX); @@ -138,7 +141,9 @@ namespace GridKit } checks.check(Ka_ > ZERO, "Ka must be positive"); - checks.check(Vrmin_ <= Vrmax_, "Vrmin must be less than or equal to Vrmax"); + checks.check( + Vrmin_ <= Vrmax_, "Vrmin must be less than or equal to Vrmax" + ); checks.check( UEL_ >= static_cast(0) && UEL_ <= static_cast(3), "UEL must be 0, 1, 2, or 3" @@ -151,13 +156,26 @@ namespace GridKit if (!saturation_disabled) { - checks.check(E1_ > ZERO, "E1 must be positive when saturation is enabled"); - checks.check(E2_ > ZERO, "E2 must be positive when saturation is enabled"); - checks.check(Se1_ >= ZERO, "Se1 must be non-negative when saturation is enabled"); - checks.check(Se2_ >= ZERO, "Se2 must be non-negative when saturation is enabled"); - - const bool sat_ordered = (E2_ > E1_ && Se2_ > Se1_) || (E2_ < E1_ && Se2_ < Se1_); - checks.check(sat_ordered, "E1/E2 and Se1/Se2 must be ordered consistently"); + checks.check( + E1_ > ZERO, "E1 must be positive when saturation is enabled" + ); + checks.check( + E2_ > ZERO, "E2 must be positive when saturation is enabled" + ); + checks.check( + Se1_ >= ZERO, + "Se1 must be non-negative when saturation is enabled" + ); + checks.check( + Se2_ >= ZERO, + "Se2 must be non-negative when saturation is enabled" + ); + + const bool sat_ordered = + (E2_ > E1_ && Se2_ > Se1_) || (E2_ < E1_ && Se2_ < Se1_); + checks.check( + sat_ordered, "E1/E2 and Se1/Se2 must be ordered consistently" + ); } if (!ports_.out.template port().connected()) @@ -165,7 +183,9 @@ namespace GridKit checks.fail("required efd output signal is not assigned"); } - if (Spdmlt_ && !ports_.in.template port().connected()) + if (Spdmlt_ + && !ports_.in.template port().connected( + )) { checks.fail("speed signal is required when Spdmlt is enabled"); } @@ -178,14 +198,19 @@ namespace GridKit if (ports_.in.template port().connected() && !ports_.in.template port().linked()) { - checks.fail(std::format("{} signal attached with no linked source", name)); + checks.fail( + std::format("{} signal attached with no linked source", name) + ); } }; - check_attached_signal.template operator()("speed"); - check_attached_signal.template operator()("vref"); + check_attached_signal.template operator( + )("speed"); + check_attached_signal.template operator( + )("vref"); check_attached_signal.template operator()("vs"); - check_attached_signal.template operator()("vuel"); + check_attached_signal.template operator( + )("vuel"); return checks; } @@ -200,14 +225,15 @@ namespace GridKit * @warning IEEE Std 421.5-2016 states: “In some programs, if * \f$K_{E}\f$ is entered as zero, \f$K_{E}\f$ is automatically * calculated by the program to represent a self-excited shunt - * field and a trimmed rheostat as its initial condition.” GridKit - * preserves the configured \f$K_{E}\f$ and resolves + * field and a trimmed rheostat as its initial condition.” + * GridKit preserves the configured \f$K_{E}\f$ and resolves * \f$K_{E}^{\mathrm{eff}}\f$ using the PSS/E-compatible * \f$V_R = V_R^{\max}/10 = 0.1 V_R^{\max}\f$ rule. The divisor * 10 is unitless and represents 10% of the maximum regulator * output. * - * @return Zero on success; nonzero when the configuration or operating point is rejected. + * @return Zero on success; nonzero when the configuration or operating + * point is rejected. */ template int Esdc1a::initialize() @@ -227,7 +253,8 @@ namespace GridKit bool ret = this->verifyAndLog(); if (!ret) { - Log::error() << "Esdc1a: cannot initialize with invalid configuration\n"; + Log::error( + ) << "Esdc1a: cannot initialize with invalid configuration\n"; return 1; } @@ -238,7 +265,8 @@ namespace GridKit const ScalarT efd0 = y[EFD]; ScalarT omega0{ZERO}; - if (auto omega_port = ports_.in.template port()) + if (auto omega_port = + ports_.in.template port()) { omega0 = omega_port.readSignal(); } @@ -250,7 +278,8 @@ namespace GridKit } ScalarT vuel0{ZERO}; - if (auto vuel_port = ports_.in.template port()) + if (auto vuel_port = + ports_.in.template port()) { vuel0 = vuel_port.readSignal(); } @@ -258,11 +287,11 @@ namespace GridKit const ScalarT vc0 = std::sqrt(Vr() * Vr() + Vi() * Vi()); ret = std::isfinite(static_cast(efd0)) - && std::isfinite(static_cast(vc0)) - && vc0 > ZERO; + && std::isfinite(static_cast(vc0)) && vc0 > ZERO; if (!ret) { - Log::error() << "Esdc1a: initial bus-voltage magnitude must be finite and positive, " + Log::error() << "Esdc1a: initial bus-voltage magnitude must be " + "finite and positive, " "and the field-voltage seed must be finite\n"; return 1; } @@ -272,7 +301,8 @@ namespace GridKit && std::isfinite(static_cast(vuel0)); if (!ret) { - Log::error() << "Esdc1a: initial speed, stabilizer, and UEL inputs must be finite\n"; + Log::error() << "Esdc1a: initial speed, stabilizer, and UEL inputs " + "must be finite\n"; return 1; } @@ -282,7 +312,8 @@ namespace GridKit && speed_multiplier > ZERO; if (!ret) { - Log::error() << "Esdc1a: speed multiplier must be finite and positive at initialization\n"; + Log::error() << "Esdc1a: speed multiplier must be finite and " + "positive at initialization\n"; return 1; } @@ -291,7 +322,8 @@ namespace GridKit ret = !exclim_ || efdp0 >= ZERO; if (!ret) { - Log::error() << "Esdc1a: initial Efd' is below its enabled zero limit\n"; + Log::error( + ) << "Esdc1a: initial Efd' is below its enabled zero limit\n"; return 1; } @@ -330,7 +362,8 @@ namespace GridKit ret = gate_margin0 > ZERO; if (!ret) { - Log::error() << "Esdc1a: smooth high-value gate is active at initialization\n"; + Log::error( + ) << "Esdc1a: smooth high-value gate is active at initialization\n"; return 1; } vll0 = vuel0 + inverseRamp(gate_margin0); @@ -357,7 +390,8 @@ namespace GridKit vs_set_ = static_cast(vs0); vuel_set_ = static_cast(vuel0); - if (auto vref_port = ports_.in.template port()) + if (auto vref_port = + ports_.in.template port()) { vref_port.writeValue(vref_set_); } @@ -430,11 +464,13 @@ namespace GridKit const auto VUEL = static_cast(Esdc1aExternalVariables::VUEL); std::fill(ws_indices_.begin(), ws_indices_.end(), INVALID_INDEX); - if (auto speed_port = ports_.in.template port()) + if (auto speed_port = + ports_.in.template port()) { ws_indices_[OMEGA] = speed_port.signalVariableIndex(); } - if (auto vref_port = ports_.in.template port()) + if (auto vref_port = + ports_.in.template port()) { ws_indices_[VREF] = vref_port.signalVariableIndex(); } @@ -442,7 +478,8 @@ namespace GridKit { ws_indices_[VS] = vs_port.signalVariableIndex(); } - if (auto vuel_port = ports_.in.template port()) + if (auto vuel_port = + ports_.in.template port()) { ws_indices_[VUEL] = vuel_port.signalVariableIndex(); } @@ -475,11 +512,13 @@ namespace GridKit ws[VS] = vs_set_; ws[VUEL] = vuel_set_; - if (auto omega_port = ports_.in.template port()) + if (auto omega_port = + ports_.in.template port()) { ws[OMEGA] = omega_port.readSignal(); } - if (auto vref_port = ports_.in.template port()) + if (auto vref_port = + ports_.in.template port()) { ws[VREF] = vref_port.readSignal(); } @@ -487,7 +526,8 @@ namespace GridKit { ws[VS] = vs_port.readSignal(); } - if (auto vuel_port = ports_.in.template port()) + if (auto vuel_port = + ports_.in.template port()) { ws[VUEL] = vuel_port.readSignal(); } @@ -512,7 +552,8 @@ namespace GridKit * constructed without data. */ template - const Model::VariableMonitorBase* Esdc1a::getMonitor() const + const Model::VariableMonitorBase* Esdc1a:: + getMonitor() const { return monitor_.get(); } @@ -584,22 +625,24 @@ namespace GridKit const ScalarT vs = ws[VS]; const ScalarT vuel = ws[VUEL]; - const ScalarT ec = std::sqrt(wb[0] * wb[0] + wb[1] * wb[1]); - const ScalarT ev_target = vref + vs + uel_on_ * vuel - vc - vf; - const ScalarT vfe_target = Ke_eff_ * efdp + se; - const ScalarT efdp_rate = (vr - vfe) / Te_; - const ScalarT limited_efdp_rate = (ONE - lim_on_) * efdp_rate - + lim_on_ * awmin(efdp, efdp_rate, ZERO); + const ScalarT ec = std::sqrt(wb[0] * wb[0] + wb[1] * wb[1]); + const ScalarT ev_target = vref + vs + uel_on_ * vuel - vc - vf; + const ScalarT vfe_target = Ke_eff_ * efdp + se; + const ScalarT efdp_rate = (vr - vfe) / Te_; + const ScalarT limited_efdp_rate = + (ONE - lim_on_) * efdp_rate + + lim_on_ * awmin(efdp, efdp_rate, ZERO); f[EFDP] = -efdp_dot + limited_efdp_rate; f[VC] = -vc_dot + (ec - vc) / Tr_; - f[VR] = -vr_dot + Math::antiwindup(vr, -vr + Ka_ * vhv, Vrmin_, Vrmax_) / Ta_; - f[VF] = -vf_dot + (-vf + Kf_ * limited_efdp_rate) / Tf1_; - f[XLL] = -xll_dot + (ev - xll) / Tb_; - f[EV] = -ev + ev_target; - f[VLL] = -vll + xll + (Tc_ / Tb_) * (ev - xll); - f[VHV] = -vhv + uel_on_ * vll - + (ONE - uel_on_) * Math::max(vll, vuel); + f[VR] = + -vr_dot + Math::antiwindup(vr, -vr + Ka_ * vhv, Vrmin_, Vrmax_) / Ta_; + f[VF] = -vf_dot + (-vf + Kf_ * limited_efdp_rate) / Tf1_; + f[XLL] = -xll_dot + (ev - xll) / Tb_; + f[EV] = -ev + ev_target; + f[VLL] = -vll + xll + (Tc_ / Tb_) * (ev - xll); + f[VHV] = + -vhv + uel_on_ * vll + (ONE - uel_on_) * Math::max(vll, vuel); f[SE] = -se + SB_ * Math::qramp(efdp - SA_); f[VFE] = -vfe + vfe_target; f[EFD] = -efd + (ONE + spd_on_ * omega) * efdp; @@ -644,7 +687,9 @@ namespace GridKit * @param[in] data Parameters and monitored-variable selections. */ template - void Esdc1a::initializeParameters(const ModelDataT& data) + void Esdc1a::initializeParameters( + const ModelDataT& data + ) { using Params = typename ModelDataT::Parameters; @@ -682,18 +727,54 @@ namespace GridKit { using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::efd, [this] - { return y_.getData()[static_cast(Esdc1aInternalVariables::EFD)]; }); - monitor_->set(Variable::vc, [this] - { return y_.getData()[static_cast(Esdc1aInternalVariables::VC)]; }); - monitor_->set(Variable::vr, [this] - { return y_.getData()[static_cast(Esdc1aInternalVariables::VR)]; }); - monitor_->set(Variable::vf, [this] - { return y_.getData()[static_cast(Esdc1aInternalVariables::VF)]; }); - monitor_->set(Variable::se, [this] - { return y_.getData()[static_cast(Esdc1aInternalVariables::SE)]; }); - monitor_->set(Variable::vfe, [this] - { return y_.getData()[static_cast(Esdc1aInternalVariables::VFE)]; }); + monitor_->set( + Variable::efd, + [this] + { + return y_.getData( + )[static_cast(Esdc1aInternalVariables::EFD)]; + } + ); + monitor_->set( + Variable::vc, + [this] + { + return y_.getData( + )[static_cast(Esdc1aInternalVariables::VC)]; + } + ); + monitor_->set( + Variable::vr, + [this] + { + return y_.getData( + )[static_cast(Esdc1aInternalVariables::VR)]; + } + ); + monitor_->set( + Variable::vf, + [this] + { + return y_.getData( + )[static_cast(Esdc1aInternalVariables::VF)]; + } + ); + monitor_->set( + Variable::se, + [this] + { + return y_.getData( + )[static_cast(Esdc1aInternalVariables::SE)]; + } + ); + monitor_->set( + Variable::vfe, + [this] + { + return y_.getData( + )[static_cast(Esdc1aInternalVariables::VFE)]; + } + ); } /** @@ -707,7 +788,8 @@ namespace GridKit { Log::warning() << "Esdc1a: Tr, Ta, Tb, Te, and Tf1 below " << TIME_CONSTANT_MINIMUM - << " s are raised to that floor to keep the exciter lags well posed\n"; + << " s are raised to that floor to keep the exciter " + "lags well posed\n"; } /** @@ -763,7 +845,8 @@ namespace GridKit // The disabled test matches the verify() predicate exactly. const bool saturation_disabled = Se1_ == ZERO && Se2_ == ZERO; - const bool sat_ordered = (E2_ > E1_ && Se2_ > Se1_) || (E2_ < E1_ && Se2_ < Se1_); + const bool sat_ordered = + (E2_ > E1_ && Se2_ > Se1_) || (E2_ < E1_ && Se2_ < Se1_); const bool saturation_consistent = E1_ > ZERO && E2_ > ZERO && Se1_ >= ZERO && Se2_ >= ZERO && sat_ordered; @@ -808,8 +891,9 @@ namespace GridKit * @pre @p ramp_output is finite and strictly positive. */ template - typename Esdc1a::RealT - Esdc1a::inverseRamp(RealT ramp_output) const + typename Esdc1a::RealT Esdc1a< + scalar_type, + index_type>::inverseRamp(RealT ramp_output) const { const RealT mu = Math::MU; return ramp_output + std::log(-std::expm1(-mu * ramp_output)) / mu; diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1.hpp b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1.hpp index 3e1ead22fa..e129878725 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1.hpp @@ -33,7 +33,8 @@ namespace GridKit VF, ///< Feedback voltage VE, ///< Exciter control voltage EFD, ///< Efd - KSAT, ///< \f$E_{\mathrm{fd}}'S(E_{\mathrm{fd}}')\f$ Scaled-quadratic saturation contribution + KSAT, ///< \f$E_{\mathrm{fd}}'S(E_{\mathrm{fd}}')\f$ Scaled-quadratic + ///< saturation contribution }; /// External variables of a `Ieeet1` @@ -103,17 +104,13 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; - __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, - const ScalarT*, - const ScalarT*, - const ScalarT*, - ScalarT* - ); + __attribute__((always_inline)) inline int + evaluateInternalResidual(const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); private: - static constexpr RealT TIME_CONSTANT_MINIMUM = static_cast(1.0e-3); - static void logTimeConstantWarning(); + static constexpr RealT TIME_CONSTANT_MINIMUM = + static_cast(1.0e-3); + static void logTimeConstantWarning(); // Signal pointers BusT* bus_; @@ -141,7 +138,8 @@ namespace GridKit RealT SA_{0}; RealT SB_{0}; - // Runtime connection masks keep the summing junction Enzyme sparse-solvable + // Runtime connection masks keep the summing junction Enzyme + // sparse-solvable RealT uel_on_{0}; RealT oel_on_{0}; diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Enzyme.cpp b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Enzyme.cpp index f24b20d97b..ccdcf50e0e 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Enzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Enzyme.cpp @@ -25,15 +25,17 @@ namespace GridKit if (J_rows_buffer_ == nullptr) { // Reserve space for the dense blocks. - // The size of the buffer is the sum of maximum capacities of the blocks. - // Enzyme will compute the appropriate nnz from sparsification. + // The size of the buffer is the sum of maximum capacities of the + // blocks. Enzyme will compute the appropriate nnz from + // sparsification. auto size = static_cast(size_); auto bus_size = static_cast(bus_->size()); auto signal_size = static_cast(ws_.getSize()); - auto buffer_size = 2 * size * size + size * bus_size + size * signal_size; - J_rows_buffer_ = new IdxT[buffer_size]; - J_cols_buffer_ = new IdxT[buffer_size]; - J_vals_buffer_ = new RealT[buffer_size]; + auto buffer_size = + 2 * size * size + size * bus_size + size * signal_size; + J_rows_buffer_ = new IdxT[buffer_size]; + J_cols_buffer_ = new IdxT[buffer_size]; + J_vals_buffer_ = new RealT[buffer_size]; } nnz_ = 0; diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp index 5f741df1ea..9f48dbbf3d 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp @@ -37,8 +37,7 @@ namespace GridKit */ template Ieeet1::Ieeet1(BusT* bus, const ModelDataT& data) - : bus_(bus), - monitor_(std::make_unique(data)) + : bus_(bus), monitor_(std::make_unique(data)) { // Parse data struct into model this->initModelParams(data); @@ -65,7 +64,9 @@ namespace GridKit * @brief Set the component ID */ template - int Ieeet1::setGridKitComponentID(IdxT component_id) + int Ieeet1::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -100,13 +101,15 @@ namespace GridKit wb_.resize(2); // Resize signal variable data - const auto signal_size = Utilities::enum_size(); + const auto signal_size = + Utilities::enum_size(); ws_.resize(static_cast(signal_size)); ws_.setToZero(); ws_indices_.assign(signal_size, INVALID_INDEX); // Set output signals - if (auto efd_port = ports_.out.template port()) + if (auto efd_port = + ports_.out.template port()) { efd_port.link(&y_.getData()[7], &(this->getVariableIndex(7))); } @@ -124,7 +127,9 @@ namespace GridKit Model::ConfigurationChecks checks("Ieeet1"); checks.check(Ka_ > ZERO, "Ka must be positive"); - checks.check(Vrmin_ <= Vrmax_, "Vrmin must be less than or equal to Vrmax"); + checks.check( + Vrmin_ <= Vrmax_, "Vrmin must be less than or equal to Vrmax" + ); checks.check( Ispdlim_ == ZERO || Ispdlim_ == ONE, "Ispdlim must be 0 or 1" @@ -135,13 +140,26 @@ namespace GridKit if (!saturation_disabled) { - checks.check(E1_ > ZERO, "E1 must be positive when saturation is enabled"); - checks.check(E2_ > ZERO, "E2 must be positive when saturation is enabled"); - checks.check(Se1_ >= ZERO, "Se1 must be non-negative when saturation is enabled"); - checks.check(Se2_ >= ZERO, "Se2 must be non-negative when saturation is enabled"); - - const bool sat_ordered = (E2_ > E1_ && Se2_ > Se1_) || (E2_ < E1_ && Se2_ < Se1_); - checks.check(sat_ordered, "E1/E2 and Se1/Se2 must be ordered consistently"); + checks.check( + E1_ > ZERO, "E1 must be positive when saturation is enabled" + ); + checks.check( + E2_ > ZERO, "E2 must be positive when saturation is enabled" + ); + checks.check( + Se1_ >= ZERO, + "Se1 must be non-negative when saturation is enabled" + ); + checks.check( + Se2_ >= ZERO, + "Se2 must be non-negative when saturation is enabled" + ); + + const bool sat_ordered = + (E2_ > E1_ && Se2_ > Se1_) || (E2_ < E1_ && Se2_ < Se1_); + checks.check( + sat_ordered, "E1/E2 and Se1/Se2 must be ordered consistently" + ); } auto check_attached_signal = @@ -150,15 +168,21 @@ namespace GridKit auto port = ports_.in.template port(); if (port.connected() && !port.linked()) { - checks.fail(std::format("{} signal attached with no linked source", name)); + checks.fail( + std::format("{} signal attached with no linked source", name) + ); } }; - check_attached_signal.template operator()("speed"); - check_attached_signal.template operator()("vref"); + check_attached_signal.template operator( + )("speed"); + check_attached_signal.template operator( + )("vref"); check_attached_signal.template operator()("vs"); - check_attached_signal.template operator()("vuel"); - check_attached_signal.template operator()("voel"); + check_attached_signal.template operator( + )("vuel"); + check_attached_signal.template operator( + )("voel"); return checks; } @@ -180,8 +204,8 @@ namespace GridKit * @warning IEEE Std 421.5-2016 states: “In some programs, if * \f$K_{E}\f$ is entered as zero, \f$K_{E}\f$ is automatically * calculated by the program to represent a self-excited shunt - * field and a trimmed rheostat as its initial condition.” GridKit - * preserves the configured \f$K_{E}\f$ and resolves + * field and a trimmed rheostat as its initial condition.” + * GridKit preserves the configured \f$K_{E}\f$ and resolves * \f$K_{E}^{\mathrm{eff}}\f$ using the PSS/E-compatible * \f$V_R = V_R^{\max}/10 = 0.1 V_R^{\max}\f$ rule. The divisor * 10 is unitless and represents 10% of the maximum regulator @@ -192,7 +216,8 @@ namespace GridKit { if (!this->verifyAndLog()) { - Log::error() << "Ieeet1: cannot initialize with invalid configuration\n"; + Log::error( + ) << "Ieeet1: cannot initialize with invalid configuration\n"; return 1; } @@ -213,7 +238,8 @@ namespace GridKit } // Setpoint members provide the defaults for unattached signals. - auto read_signal = [&](const ScalarT& default_value) -> ScalarT + auto read_signal = + [&](const ScalarT& default_value) -> ScalarT { if (auto port = ports_.in.template port()) { @@ -222,10 +248,14 @@ namespace GridKit return default_value; }; - const ScalarT omega = read_signal.template operator()(omega_set_); - const ScalarT vs = read_signal.template operator()(vs_set_); - const ScalarT vuel = read_signal.template operator()(vuel_set_); - const ScalarT voel = read_signal.template operator()(voel_set_); + const ScalarT omega = read_signal.template operator( + )(omega_set_); + const ScalarT vs = + read_signal.template operator()(vs_set_); + const ScalarT vuel = + read_signal.template operator()(vuel_set_); + const ScalarT voel = + read_signal.template operator()(voel_set_); uel_on_ = ZERO; if (ports_.in.template port()) @@ -255,7 +285,8 @@ namespace GridKit Log::error() << "Ieeet1: derived effective Ke must be finite\n"; return 1; } - Log::misc() << "Ieeet1: Ke is zero so effective Ke is derived during initialization\n"; + Log::misc() << "Ieeet1: Ke is zero so effective Ke is derived during " + "initialization\n"; } else { @@ -268,7 +299,8 @@ namespace GridKit ScalarT vf{0}; ScalarT vfx = (Kf_ / Tf_) * efdp; - const ScalarT vref = Ec + vtr + vf - vs - uel_on_ * vuel - oel_on_ * voel; + const ScalarT vref = + Ec + vtr + vf - vs - uel_on_ * vuel - oel_on_ * voel; y[0] = Ec; // y0 - vts - Sensed term volt y[1] = vr; // y1 - vr - Voltage reg @@ -291,7 +323,8 @@ namespace GridKit vuel_set_ = static_cast(vuel); voel_set_ = static_cast(voel); - if (auto vref_port = ports_.in.template port()) + if (auto vref_port = + ports_.in.template port()) { vref_port.writeValue(vref_set_); } @@ -430,11 +463,13 @@ namespace GridKit const auto VOEL = static_cast(Ieeet1ExternalVariables::VOEL); std::fill(ws_indices_.begin(), ws_indices_.end(), INVALID_INDEX); - if (auto speed_port = ports_.in.template port()) + if (auto speed_port = + ports_.in.template port()) { ws_indices_[OMEGA] = speed_port.signalVariableIndex(); } - if (auto vref_port = ports_.in.template port()) + if (auto vref_port = + ports_.in.template port()) { ws_indices_[VREF] = vref_port.signalVariableIndex(); } @@ -442,11 +477,13 @@ namespace GridKit { ws_indices_[VS] = vs_port.signalVariableIndex(); } - if (auto vuel_port = ports_.in.template port()) + if (auto vuel_port = + ports_.in.template port()) { ws_indices_[VUEL] = vuel_port.signalVariableIndex(); } - if (auto voel_port = ports_.in.template port()) + if (auto voel_port = + ports_.in.template port()) { ws_indices_[VOEL] = voel_port.signalVariableIndex(); } @@ -469,18 +506,21 @@ namespace GridKit auto* ws = ws_.getData(); - // Attached signals are read live; unattached ones keep the latched value. + // Attached signals are read live; unattached ones keep the latched + // value. ws[OMEGA] = omega_set_; ws[VREF] = vref_set_; ws[VS] = vs_set_; ws[VUEL] = vuel_set_; ws[VOEL] = voel_set_; - if (auto speed_port = ports_.in.template port()) + if (auto speed_port = + ports_.in.template port()) { ws[OMEGA] = speed_port.readSignal(); } - if (auto vref_port = ports_.in.template port()) + if (auto vref_port = + ports_.in.template port()) { ws[VREF] = vref_port.readSignal(); } @@ -488,11 +528,13 @@ namespace GridKit { ws[VS] = vs_port.readSignal(); } - if (auto vuel_port = ports_.in.template port()) + if (auto vuel_port = + ports_.in.template port()) { ws[VUEL] = vuel_port.readSignal(); } - if (auto voel_port = ports_.in.template port()) + if (auto voel_port = + ports_.in.template port()) { ws[VOEL] = voel_port.readSignal(); } @@ -517,7 +559,9 @@ namespace GridKit * @brief Initialization Exciter Parameters from data structure */ template - void Ieeet1::initModelParams(const ModelDataT& data) + void Ieeet1::initModelParams( + const ModelDataT& data + ) { using Parameter = typename ModelDataT::Parameters; @@ -587,10 +631,10 @@ namespace GridKit return; } - const bool sat_ordered = (E2_ > E1_ && Se2_ > Se1_) || (E2_ < E1_ && Se2_ < Se1_); - if (E1_ <= ZERO || E2_ <= ZERO - || Se1_ < ZERO || Se2_ < ZERO - || !sat_ordered) + const bool sat_ordered = + (E2_ > E1_ && Se2_ > Se1_) || (E2_ < E1_ && Se2_ < Se1_); + if (E1_ <= ZERO || E2_ <= ZERO || Se1_ < ZERO + || Se2_ < ZERO || !sat_ordered) { return; } @@ -619,7 +663,8 @@ namespace GridKit } template - const Model::VariableMonitorBase* Ieeet1::getMonitor() const + const Model::VariableMonitorBase* Ieeet1:: + getMonitor() const { return monitor_.get(); } @@ -628,10 +673,11 @@ namespace GridKit void Ieeet1::initializeMonitor() { using Variable = ModelDataT::MonitorableVariables; - monitor_->set(Variable::efd, [this] - { return y_.getData()[7]; }); - monitor_->set(Variable::ksat, [this] - { return SB_ * Math::qramp(y_.getData()[2] - SA_); }); + monitor_->set(Variable::efd, [this] { return y_.getData()[7]; }); + monitor_->set( + Variable::ksat, + [this] { return SB_ * Math::qramp(y_.getData()[2] - SA_); } + ); } } // namespace Exciter } // namespace PhasorDynamics diff --git a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPti.hpp b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPti.hpp index f9b1743de7..24244b9779 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPti.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPti.hpp @@ -90,13 +90,8 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; - __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, - const ScalarT*, - const ScalarT*, - const ScalarT*, - ScalarT* - ); + __attribute__((always_inline)) inline int + evaluateInternalResidual(const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); private: BusT* bus_{nullptr}; @@ -108,7 +103,8 @@ namespace GridKit RealT Efdmax_{0}; RealT Efdmin_{0}; - // Runtime connection masks keep the summing junction Enzyme sparse-solvable + // Runtime connection masks keep the summing junction Enzyme + // sparse-solvable RealT uel_on_{0}; RealT oel_on_{0}; diff --git a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiEnzyme.cpp b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiEnzyme.cpp index 0c6a95f9a9..903af99533 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiEnzyme.cpp @@ -20,15 +20,17 @@ namespace GridKit if (J_rows_buffer_ == nullptr) { // Reserve space for the dense blocks. - // The size of the buffer is the sum of maximum capacities of the blocks. - // Enzyme will compute the appropriate nnz from sparsification. + // The size of the buffer is the sum of maximum capacities of the + // blocks. Enzyme will compute the appropriate nnz from + // sparsification. auto size = static_cast(size_); auto bus_size = static_cast(bus_->size()); auto signal_size = static_cast(ws_.getSize()); - auto buffer_size = 2 * size * size + size * bus_size + size * signal_size; - J_rows_buffer_ = new IdxT[buffer_size]; - J_cols_buffer_ = new IdxT[buffer_size]; - J_vals_buffer_ = new RealT[buffer_size]; + auto buffer_size = + 2 * size * size + size * bus_size + size * signal_size; + J_rows_buffer_ = new IdxT[buffer_size]; + J_cols_buffer_ = new IdxT[buffer_size]; + J_vals_buffer_ = new RealT[buffer_size]; } nnz_ = 0; diff --git a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp index 34f486d033..b78d8f451b 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp @@ -27,9 +27,10 @@ namespace GridKit using Log = ::GridKit::Utilities::Logger; template - SexsPti::SexsPti(BusT* bus, const ModelDataT& data) - : bus_(bus), - monitor_(std::make_unique(data)) + SexsPti::SexsPti( + BusT* bus, const ModelDataT& data + ) + : bus_(bus), monitor_(std::make_unique(data)) { initModelParams(data); initializeMonitor(); @@ -42,7 +43,9 @@ namespace GridKit } template - int SexsPti::setGridKitComponentID(IdxT component_id) + int SexsPti::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -71,12 +74,14 @@ namespace GridKit wb_.resize(2); - const auto signal_size = Utilities::enum_size(); + const auto signal_size = + Utilities::enum_size(); ws_.resize(static_cast(signal_size)); ws_.setToZero(); ws_indices_.assign(signal_size, INVALID_INDEX); - if (auto efd_port = ports_.out.template port()) + if (auto efd_port = + ports_.out.template port()) { efd_port.link(&y_.getData()[1], &(this->getVariableIndex(1))); } @@ -86,7 +91,8 @@ namespace GridKit } template - Model::ConfigurationChecks SexsPti::verify() const + Model::ConfigurationChecks SexsPti::verify( + ) const { Model::ConfigurationChecks checks("SexsPti"); @@ -127,14 +133,20 @@ namespace GridKit auto port = ports_.in.template port(); if (port.connected() && !port.linked()) { - checks.fail(std::format("{} signal attached with no linked source", name)); + checks.fail( + std::format("{} signal attached with no linked source", name) + ); } }; - check_attached_signal.template operator()("vref"); - check_attached_signal.template operator()("vs"); - check_attached_signal.template operator()("vuel"); - check_attached_signal.template operator()("voel"); + check_attached_signal.template operator( + )("vref"); + check_attached_signal.template operator()("vs" + ); + check_attached_signal.template operator( + )("vuel"); + check_attached_signal.template operator( + )("voel"); return checks; } @@ -152,7 +164,9 @@ namespace GridKit } // Setpoint members provide the defaults for unattached signals. - auto read_signal = [&](const ScalarT& default_value) -> ScalarT + auto read_signal = [&]( + const ScalarT& default_value + ) -> ScalarT { if (auto port = ports_.in.template port()) { @@ -161,9 +175,12 @@ namespace GridKit return default_value; }; - const ScalarT vs = read_signal.template operator()(vs_set_); - const ScalarT vuel = read_signal.template operator()(vuel_set_); - const ScalarT voel = read_signal.template operator()(voel_set_); + const ScalarT vs = + read_signal.template operator()(vs_set_); + const ScalarT vuel = + read_signal.template operator()(vuel_set_); + const ScalarT voel = + read_signal.template operator()(voel_set_); uel_on_ = ZERO; if (ports_.in.template port()) @@ -198,7 +215,8 @@ namespace GridKit vuel_set_ = static_cast(vuel); voel_set_ = static_cast(voel); - if (auto vref_port = ports_.in.template port()) + if (auto vref_port = + ports_.in.template port()) { vref_port.writeValue(vref_set_); } @@ -293,7 +311,8 @@ namespace GridKit const auto VOEL = static_cast(SexsPtiExternalVariables::VOEL); std::fill(ws_indices_.begin(), ws_indices_.end(), INVALID_INDEX); - if (auto vref_port = ports_.in.template port()) + if (auto vref_port = + ports_.in.template port()) { ws_indices_[VREF] = vref_port.signalVariableIndex(); } @@ -301,11 +320,13 @@ namespace GridKit { ws_indices_[VS] = vs_port.signalVariableIndex(); } - if (auto vuel_port = ports_.in.template port()) + if (auto vuel_port = + ports_.in.template port()) { ws_indices_[VUEL] = vuel_port.signalVariableIndex(); } - if (auto voel_port = ports_.in.template port()) + if (auto voel_port = + ports_.in.template port()) { ws_indices_[VOEL] = voel_port.signalVariableIndex(); } @@ -323,13 +344,15 @@ namespace GridKit auto* ws = ws_.getData(); - // Attached signals are read live; unattached ones keep the latched value. + // Attached signals are read live; unattached ones keep the latched + // value. ws[VREF] = vref_set_; ws[VS] = vs_set_; ws[VUEL] = vuel_set_; ws[VOEL] = voel_set_; - if (auto vref_port = ports_.in.template port()) + if (auto vref_port = + ports_.in.template port()) { ws[VREF] = vref_port.readSignal(); } @@ -337,11 +360,13 @@ namespace GridKit { ws[VS] = vs_port.readSignal(); } - if (auto vuel_port = ports_.in.template port()) + if (auto vuel_port = + ports_.in.template port()) { ws[VUEL] = vuel_port.readSignal(); } - if (auto voel_port = ports_.in.template port()) + if (auto voel_port = + ports_.in.template port()) { ws[VOEL] = voel_port.readSignal(); } @@ -361,7 +386,9 @@ namespace GridKit } template - void SexsPti::initModelParams(const ModelDataT& data) + void SexsPti::initModelParams( + const ModelDataT& data + ) { using Params = typename ModelDataT::Parameters; @@ -376,7 +403,8 @@ namespace GridKit } template - const Model::VariableMonitorBase* SexsPti::getMonitor() const + const Model::VariableMonitorBase* SexsPti:: + getMonitor() const { return monitor_.get(); } @@ -385,8 +413,7 @@ namespace GridKit void SexsPti::initializeMonitor() { using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::efd, [this] - { return y_.getData()[1]; }); + monitor_->set(Variable::efd, [this] { return y_.getData()[1]; }); } } // namespace Exciter diff --git a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPti.cpp b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPti.cpp index b83798ece1..9a454313dc 100644 --- a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPti.cpp +++ b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPti.cpp @@ -13,7 +13,8 @@ namespace GridKit namespace Governor { /** - * @brief Report that a separate Jacobian is unavailable in the plain-real build. + * @brief Report that a separate Jacobian is unavailable in the plain-real + * build. */ template int GastPti::evaluateJacobian() diff --git a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPti.hpp b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPti.hpp index 7ef810adc5..5c55e23ffa 100644 --- a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPti.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPti.hpp @@ -24,20 +24,28 @@ namespace GridKit /// Internal variables and residual rows of a `GastPti`. enum class GastPtiInternalVariables : size_t { - XVALVE, ///< \f$x_V\f$ Differential fuel-valve state on component base [p.u.] - XFLOW, ///< \f$x_F\f$ Differential fuel-flow state on component base [p.u.] - XTEMP, ///< \f$x_T\f$ Differential exhaust-temperature feedback state on component base [p.u.] - VLOAD, ///< \f$V_D\f$ Algebraic speed/load fuel demand on component base [p.u.] - VTEMP, ///< \f$V_T\f$ Algebraic temperature-limit demand on component base [p.u.] - VLV, ///< \f$V\f$ Algebraic smooth low-value selector output on component base [p.u.] - PMECH, ///< \f$P_{\text{m}}\f$ Algebraic mechanical-power output on system base [p.u.] + XVALVE, ///< \f$x_V\f$ Differential fuel-valve state on component base + ///< [p.u.] + XFLOW, ///< \f$x_F\f$ Differential fuel-flow state on component base + ///< [p.u.] + XTEMP, ///< \f$x_T\f$ Differential exhaust-temperature feedback state on + ///< component base [p.u.] + VLOAD, ///< \f$V_D\f$ Algebraic speed/load fuel demand on component base + ///< [p.u.] + VTEMP, ///< \f$V_T\f$ Algebraic temperature-limit demand on component + ///< base [p.u.] + VLV, ///< \f$V\f$ Algebraic smooth low-value selector output on + ///< component base [p.u.] + PMECH, ///< \f$P_{\text{m}}\f$ Algebraic mechanical-power output on + ///< system base [p.u.] }; /// External signal variables read or initialized by a `GastPti`. enum class GastPtiExternalVariables : size_t { OMEGA, ///< \f$\omega\f$ Machine speed deviation [p.u.] - PREF, ///< \f$P^\mathrm{ref}\f$ Active-power/load reference on system base [p.u.] + PREF, ///< \f$P^\mathrm{ref}\f$ Active-power/load reference on system + ///< base [p.u.] }; /** @@ -120,8 +128,9 @@ namespace GridKit static RealT iramp(RealT value); - static constexpr RealT TIME_CONSTANT_MINIMUM = static_cast(1.0e-3); - static void logTimeConstantWarning(); + static constexpr RealT TIME_CONSTANT_MINIMUM = + static_cast(1.0e-3); + static void logTimeConstantWarning(); RealT R_{static_cast(0.05)}; RealT T1_{static_cast(0.4)}; diff --git a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiData.hpp b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiData.hpp index 93d5c652bc..4e7a5c7100 100644 --- a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiData.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiData.hpp @@ -17,16 +17,22 @@ namespace GridKit /// Parameter keys for GASTPTI; all are optional with documented defaults. enum class GastPtiParameters : size_t { - R, ///< \f$R\f$ Speed-deviation droop per component-power deviation [p.u.] - T1, ///< \f$T_1\f$ Fuel-valve time constant [sec] - T2, ///< \f$T_2\f$ Fuel-flow time constant [sec] - T3, ///< \f$T_3\f$ Exhaust-temperature time constant [sec] - At, ///< \f$A_T\f$ Ambient-temperature load limit on component base [p.u.] - Kt, ///< \f$K_T\f$ Exhaust-temperature feedback gain [p.u.] - Vmax, ///< \f$V^{\max}\f$ Configured upper valve limit on component base [p.u.] - Vmin, ///< \f$V^{\min}\f$ Configured lower valve limit on component base [p.u.] - Dturb, ///< \f$D^\mathrm{turb}\f$ Component-base power per speed deviation [p.u.] - Trate ///< \f$T^\mathrm{rate}\f$ MW rating defining the component base [MW] + R, ///< \f$R\f$ Speed-deviation droop per component-power deviation + ///< [p.u.] + T1, ///< \f$T_1\f$ Fuel-valve time constant [sec] + T2, ///< \f$T_2\f$ Fuel-flow time constant [sec] + T3, ///< \f$T_3\f$ Exhaust-temperature time constant [sec] + At, ///< \f$A_T\f$ Ambient-temperature load limit on component base + ///< [p.u.] + Kt, ///< \f$K_T\f$ Exhaust-temperature feedback gain [p.u.] + Vmax, ///< \f$V^{\max}\f$ Configured upper valve limit on component base + ///< [p.u.] + Vmin, ///< \f$V^{\min}\f$ Configured lower valve limit on component base + ///< [p.u.] + Dturb, ///< \f$D^\mathrm{turb}\f$ Component-base power per speed + ///< deviation [p.u.] + Trate ///< \f$T^\mathrm{rate}\f$ MW rating defining the component base + ///< [MW] }; /// Buses for the GASTPTI governor model. @@ -37,25 +43,31 @@ namespace GridKit /// Signal inputs for the GASTPTI governor model. enum class GastPtiSignalInputs : size_t { - speed, ///< \f$\omega\f$ Optional Known machine speed-deviation input [p.u.] - pref, ///< \f$P^\mathrm{ref}\f$ Optional Unknown load-reference input on system base [p.u.] + speed, ///< \f$\omega\f$ Optional Known machine speed-deviation input + ///< [p.u.] + pref, ///< \f$P^\mathrm{ref}\f$ Optional Unknown load-reference input on + ///< system base [p.u.] }; /// Signal outputs for the GASTPTI governor model. enum class GastPtiSignalOutputs : size_t { - pmech, ///< \f$P_{\text{m}}\f$ Required Known mechanical-power output on system base [p.u.] + pmech, ///< \f$P_{\text{m}}\f$ Required Known mechanical-power output on + ///< system base [p.u.] }; /// Variables available through the monitor interface. enum class GastPtiMonitorableVariables : size_t { - pmech, ///< \f$P_{\text{m}}\f$ Mechanical-power output on system base [p.u.] + pmech, ///< \f$P_{\text{m}}\f$ Mechanical-power output on system base + ///< [p.u.] xvalve, ///< \f$x_V\f$ Fuel-valve state on component base [p.u.] xflow, ///< \f$x_F\f$ Fuel-flow state on component base [p.u.] - xtemp, ///< \f$x_T\f$ Exhaust-temperature feedback state on component base [p.u.] + xtemp, ///< \f$x_T\f$ Exhaust-temperature feedback state on component + ///< base [p.u.] vload, ///< \f$V_D\f$ Speed/load fuel demand on component base [p.u.] - vtemp, ///< \f$V_T\f$ Temperature-limit fuel demand on component base [p.u.] + vtemp, ///< \f$V_T\f$ Temperature-limit fuel demand on component base + ///< [p.u.] }; /// Initial values for the GASTPTI governor model. @@ -64,7 +76,8 @@ namespace GridKit }; /** - * @brief Model data for GASTPTI parameters, signal ports, and monitored variables. + * @brief Model data for GASTPTI parameters, signal ports, and monitored + * variables. * * @tparam real_type Real parameter value type. * @tparam index_type Integer index type. diff --git a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiEnzyme.cpp b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiEnzyme.cpp index 335e170cba..9ede9b9afa 100644 --- a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiEnzyme.cpp @@ -39,8 +39,9 @@ namespace GridKit J_vals_buffer_ = new RealT[buffer_size]; } - using ModelT = GridKit::PhasorDynamics::Governor::GastPti; - using Fn = GridKit::Enzyme::Sparse::MemberFunctions; + using ModelT = + GridKit::PhasorDynamics::Governor::GastPti; + using Fn = GridKit::Enzyme::Sparse::MemberFunctions; nnz_ = 0; diff --git a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiImpl.hpp b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiImpl.hpp index bdeadf611a..8e10743c8f 100644 --- a/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/GASTPTI/GastPtiImpl.hpp @@ -39,7 +39,8 @@ namespace GridKit { initializeParameters(data); initializeMonitor(); - size_ = static_cast(Utilities::enum_size()); + size_ = + static_cast(Utilities::enum_size()); } /** @@ -56,7 +57,9 @@ namespace GridKit * @param[in] component_id Identifier assigned by the system model. */ template - int GastPti::setGridKitComponentID(IdxT component_id) + int GastPti::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -88,7 +91,8 @@ namespace GridKit variable_indices_.resize(size); residual_indices_.resize(size); - const auto signal_size = Utilities::enum_size(); + const auto signal_size = + Utilities::enum_size(); ws_.resize(static_cast(signal_size)); ws_.setToZero(); ws_indices_.assign(signal_size, INVALID_INDEX); @@ -101,7 +105,8 @@ namespace GridKit auto* y = y_.getData(); - if (auto pmech_port = ports_.out.template port()) + if (auto pmech_port = + ports_.out.template port()) { pmech_port.link( &y[PMECH], &(this->getVariableIndex(static_cast(PMECH))) @@ -122,13 +127,16 @@ namespace GridKit * @return The configuration checks; passed() when valid. */ template - Model::ConfigurationChecks GastPti::verify() const + Model::ConfigurationChecks GastPti::verify( + ) const { const auto PMECH = static_cast(GastPtiInternalVariables::PMECH); Model::ConfigurationChecks checks("GastPti"); - checks.check(std::isfinite(R_) && R_ > ZERO, "R must be finite and positive"); + checks.check( + std::isfinite(R_) && R_ > ZERO, "R must be finite and positive" + ); checks.check( std::isfinite(At_) && At_ >= ZERO, "At must be finite and non-negative" @@ -142,24 +150,33 @@ namespace GridKit checks.check(finite_limits, "Vmin and Vmax must be finite"); if (finite_limits) { - checks.check(Vmin_ <= Vmax_, "Vmin must be less than or equal to Vmax"); + checks.check( + Vmin_ <= Vmax_, "Vmin must be less than or equal to Vmax" + ); } checks.check( std::isfinite(Dturb_) && Dturb_ >= ZERO, "Dturb must be finite and non-negative" ); - const bool valid_component_base = std::isfinite(va_component_base_) - && va_component_base_ > ZERO; - const bool valid_system_base = std::isfinite(va_system_base_) - && va_system_base_ > ZERO; - checks.check(valid_component_base, "component power base must be finite and positive"); - checks.check(valid_system_base, "system power base must be finite and positive"); + const bool valid_component_base = + std::isfinite(va_component_base_) && va_component_base_ > ZERO; + const bool valid_system_base = + std::isfinite(va_system_base_) && va_system_base_ > ZERO; + checks.check( + valid_component_base, + "component power base must be finite and positive" + ); + checks.check( + valid_system_base, "system power base must be finite and positive" + ); if (valid_component_base && valid_system_base) { - const RealT system_to_component = va_system_base_ / va_component_base_; - const RealT component_to_system = va_component_base_ / va_system_base_; + const RealT system_to_component = + va_system_base_ / va_component_base_; + const RealT component_to_system = + va_component_base_ / va_system_base_; checks.check( std::isfinite(system_to_component) && system_to_component > ZERO @@ -185,7 +202,9 @@ namespace GridKit { if (!port.linked()) { - checks.fail(std::format("{} port attached with no linked source", name)); + checks.fail( + std::format("{} port attached with no linked source", name) + ); } else { @@ -195,14 +214,10 @@ namespace GridKit return false; }; - const auto omega_linked = - check_attached_signal.template operator()( - "speed" - ); - const auto pref_linked = - check_attached_signal.template operator()( - "pref" - ); + const auto omega_linked = check_attached_signal.template operator( + )("speed"); + const auto pref_linked = check_attached_signal.template operator( + )("pref"); if (variable_indices_.size() == static_cast(size_)) { @@ -226,10 +241,10 @@ namespace GridKit } if (omega_linked && pref_linked) { - auto omega = ports_.in.template port(); + auto omega = ports_.in.template port(); auto omega_index = omega.signalVariableIndex(); - auto pref = ports_.in.template port(); - auto pref_index = pref.signalVariableIndex(); + auto pref = ports_.in.template port(); + auto pref_index = pref.signalVariableIndex(); if (omega_index != INVALID_INDEX || pref_index != INVALID_INDEX) @@ -269,13 +284,14 @@ namespace GridKit template int GastPti::initialize() { - const auto XVALVE = static_cast(GastPtiInternalVariables::XVALVE); - const auto XFLOW = static_cast(GastPtiInternalVariables::XFLOW); - const auto XTEMP = static_cast(GastPtiInternalVariables::XTEMP); - const auto VLOAD = static_cast(GastPtiInternalVariables::VLOAD); - const auto VTEMP = static_cast(GastPtiInternalVariables::VTEMP); - const auto VLV = static_cast(GastPtiInternalVariables::VLV); - const auto PMECH = static_cast(GastPtiInternalVariables::PMECH); + const auto XVALVE = + static_cast(GastPtiInternalVariables::XVALVE); + const auto XFLOW = static_cast(GastPtiInternalVariables::XFLOW); + const auto XTEMP = static_cast(GastPtiInternalVariables::XTEMP); + const auto VLOAD = static_cast(GastPtiInternalVariables::VLOAD); + const auto VTEMP = static_cast(GastPtiInternalVariables::VTEMP); + const auto VLV = static_cast(GastPtiInternalVariables::VLV); + const auto PMECH = static_cast(GastPtiInternalVariables::PMECH); if (!allocated_) { @@ -285,7 +301,8 @@ namespace GridKit if (!this->verifyAndLog()) { - Log::error() << "GastPti: cannot initialize with invalid configuration\n"; + Log::error( + ) << "GastPti: cannot initialize with invalid configuration\n"; return 1; } @@ -298,7 +315,8 @@ namespace GridKit } RealT omega0 = ZERO; - if (auto omega_port = ports_.in.template port()) + if (auto omega_port = + ports_.in.template port()) { omega0 = static_cast(omega_port.readSignal()); } @@ -316,7 +334,8 @@ namespace GridKit if (!std::isfinite(pmech0_value) || !std::isfinite(xflow0) || !std::isfinite(vtemp0)) { - Log::error() << "GastPti: initial power, fuel-flow, and temperature candidates must be finite\n"; + Log::error() << "GastPti: initial power, fuel-flow, and temperature " + "candidates must be finite\n"; return 1; } @@ -326,14 +345,17 @@ namespace GridKit if (!std::isfinite(Vmin_response) || !std::isfinite(Vmax_response) || Vmin_response > Vmax_response) { - Log::error() << "GastPti: initial response limits must be finite and ordered\n"; + Log::error( + ) << "GastPti: initial response limits must be finite and ordered\n"; return 1; } if (xflow0 < Vmin_ || xflow0 > Vmax_) { - Log::warning() << "GastPti: initial fuel flow is outside [Vmin, Vmax]; " - "response limits are adjusted to include the initialized value\n"; + Log::warning( + ) << "GastPti: initial fuel flow is outside [Vmin, Vmax]; " + "response limits are adjusted to include the initialized " + "value\n"; } const bool valve_active = Vmin_response < Vmax_response; @@ -388,7 +410,8 @@ namespace GridKit y[VLV] = static_cast(vlv0); pref_set_ = static_cast(pref0); - if (auto pref_port = ports_.in.template port()) + if (auto pref_port = + ports_.in.template port()) { pref_port.writeValue(pref_set_); } @@ -415,9 +438,10 @@ namespace GridKit template int GastPti::tagDifferentiable() { - const auto XVALVE = static_cast(GastPtiInternalVariables::XVALVE); - const auto XFLOW = static_cast(GastPtiInternalVariables::XFLOW); - const auto XTEMP = static_cast(GastPtiInternalVariables::XTEMP); + const auto XVALVE = + static_cast(GastPtiInternalVariables::XVALVE); + const auto XFLOW = static_cast(GastPtiInternalVariables::XFLOW); + const auto XTEMP = static_cast(GastPtiInternalVariables::XTEMP); std::fill(tag_.begin(), tag_.end(), false); tag_[XVALVE] = true; @@ -452,11 +476,13 @@ namespace GridKit const auto PREF = static_cast(GastPtiExternalVariables::PREF); std::fill(ws_indices_.begin(), ws_indices_.end(), INVALID_INDEX); - if (auto speed_port = ports_.in.template port()) + if (auto speed_port = + ports_.in.template port()) { ws_indices_[OMEGA] = speed_port.signalVariableIndex(); } - if (auto pref_port = ports_.in.template port()) + if (auto pref_port = + ports_.in.template port()) { ws_indices_[PREF] = pref_port.signalVariableIndex(); } @@ -484,11 +510,13 @@ namespace GridKit ws[OMEGA] = ZERO; ws[PREF] = pref_set_; - if (auto omega_port = ports_.in.template port()) + if (auto omega_port = + ports_.in.template port()) { ws[OMEGA] = omega_port.readSignal(); } - if (auto pref_port = ports_.in.template port()) + if (auto pref_port = + ports_.in.template port()) { ws[PREF] = pref_port.readSignal(); } @@ -509,7 +537,8 @@ namespace GridKit * constructed without data. */ template - const Model::VariableMonitorBase* GastPti::getMonitor() const + const Model::VariableMonitorBase* GastPti:: + getMonitor() const { return monitor_.get(); } @@ -526,11 +555,13 @@ namespace GridKit * @param[in] y Internal variables in `GastPtiInternalVariables` order; * each variable uses the base documented by its enum. * @param[in] yp Internal derivatives in the same enum order and bases. - * @param[in] wb Bus voltage components; unused, GASTPTI attaches to no bus. + * @param[in] wb Bus voltage components; unused, GASTPTI attaches to no + * bus. * @param[in] ws External signals in `GastPtiExternalVariables` order: * per-unit speed deviation followed by system-base * active-power reference. - * @param[out] f Model-owned residuals in `GastPtiInternalVariables` order. + * @param[out] f Model-owned residuals in `GastPtiInternalVariables` + * order. */ template [[gnu::always_inline]] inline int GastPti:: @@ -542,13 +573,14 @@ namespace GridKit ScalarT* f ) { - const auto XVALVE = static_cast(GastPtiInternalVariables::XVALVE); - const auto XFLOW = static_cast(GastPtiInternalVariables::XFLOW); - const auto XTEMP = static_cast(GastPtiInternalVariables::XTEMP); - const auto VLOAD = static_cast(GastPtiInternalVariables::VLOAD); - const auto VTEMP = static_cast(GastPtiInternalVariables::VTEMP); - const auto VLV = static_cast(GastPtiInternalVariables::VLV); - const auto PMECH = static_cast(GastPtiInternalVariables::PMECH); + const auto XVALVE = + static_cast(GastPtiInternalVariables::XVALVE); + const auto XFLOW = static_cast(GastPtiInternalVariables::XFLOW); + const auto XTEMP = static_cast(GastPtiInternalVariables::XTEMP); + const auto VLOAD = static_cast(GastPtiInternalVariables::VLOAD); + const auto VTEMP = static_cast(GastPtiInternalVariables::VTEMP); + const auto VLV = static_cast(GastPtiInternalVariables::VLV); + const auto PMECH = static_cast(GastPtiInternalVariables::PMECH); const auto OMEGA = static_cast(GastPtiExternalVariables::OMEGA); const auto PREF = static_cast(GastPtiExternalVariables::PREF); @@ -615,7 +647,9 @@ namespace GridKit * @param[in] data Parameters and monitored-variable selections. */ template - void GastPti::initializeParameters(const ModelDataT& data) + void GastPti::initializeParameters( + const ModelDataT& data + ) { using Params = typename ModelDataT::Parameters; @@ -651,18 +685,54 @@ namespace GridKit { using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::pmech, [this] - { return y_.getData()[static_cast(GastPtiInternalVariables::PMECH)]; }); - monitor_->set(Variable::xvalve, [this] - { return y_.getData()[static_cast(GastPtiInternalVariables::XVALVE)]; }); - monitor_->set(Variable::xflow, [this] - { return y_.getData()[static_cast(GastPtiInternalVariables::XFLOW)]; }); - monitor_->set(Variable::xtemp, [this] - { return y_.getData()[static_cast(GastPtiInternalVariables::XTEMP)]; }); - monitor_->set(Variable::vload, [this] - { return y_.getData()[static_cast(GastPtiInternalVariables::VLOAD)]; }); - monitor_->set(Variable::vtemp, [this] - { return y_.getData()[static_cast(GastPtiInternalVariables::VTEMP)]; }); + monitor_->set( + Variable::pmech, + [this] + { + return y_.getData( + )[static_cast(GastPtiInternalVariables::PMECH)]; + } + ); + monitor_->set( + Variable::xvalve, + [this] + { + return y_.getData( + )[static_cast(GastPtiInternalVariables::XVALVE)]; + } + ); + monitor_->set( + Variable::xflow, + [this] + { + return y_.getData( + )[static_cast(GastPtiInternalVariables::XFLOW)]; + } + ); + monitor_->set( + Variable::xtemp, + [this] + { + return y_.getData( + )[static_cast(GastPtiInternalVariables::XTEMP)]; + } + ); + monitor_->set( + Variable::vload, + [this] + { + return y_.getData( + )[static_cast(GastPtiInternalVariables::VLOAD)]; + } + ); + monitor_->set( + Variable::vtemp, + [this] + { + return y_.getData( + )[static_cast(GastPtiInternalVariables::VTEMP)]; + } + ); } /** @@ -676,7 +746,8 @@ namespace GridKit { Log::warning() << "GastPti: T1, T2, and T3 below " << TIME_CONSTANT_MINIMUM - << " s are raised to that floor to keep the turbine lags well posed\n"; + << " s are raised to that floor to keep the turbine " + "lags well posed\n"; } /** diff --git a/GridKit/Model/PhasorDynamics/Governor/HYGOV/Hygov.hpp b/GridKit/Model/PhasorDynamics/Governor/HYGOV/Hygov.hpp index 7ad2c09e3e..bfa24f1b69 100644 --- a/GridKit/Model/PhasorDynamics/Governor/HYGOV/Hygov.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/HYGOV/Hygov.hpp @@ -37,16 +37,18 @@ namespace GridKit EF, ///< \f$e_f\f$ Governor error on component base FC, ///< \f$f_c\f$ Desired-gate derivative target RC, ///< \f$r_c\f$ Rate-limited desired-gate derivative target - PGV, ///< \f$P_{\mathrm{GV}}\f$ Gate-to-power curve output on component base - H, ///< \f$H\f$ Turbine head on component base - PMECH, ///< \f$P_{\mathrm{m}}\f$ Mechanical-power output on system base + PGV, ///< \f$P_{\mathrm{GV}}\f$ Gate-to-power curve output on component + ///< base + H, ///< \f$H\f$ Turbine head on component base + PMECH, ///< \f$P_{\mathrm{m}}\f$ Mechanical-power output on system base }; /// External variables of a `Hygov`. enum class HygovExternalVariables : size_t { OMEGA, ///< \f$\omega\f$ Machine speed deviation - PREF, ///< \f$P^{\mathrm{ref}}\f$ Active-power/load reference on system base + PREF, ///< \f$P^{\mathrm{ref}}\f$ Active-power/load reference on system + ///< base PAUX, ///< \f$P^{\mathrm{aux}}\f$ Auxiliary power input on system base }; @@ -130,7 +132,8 @@ namespace GridKit /// Evaluate the nonlinear gate-to-power curve as a fixed sum of /// smooth linear segments. - __attribute__((always_inline)) inline ScalarT gatePower(ScalarT gate) const; + __attribute__((always_inline)) inline ScalarT gatePower(ScalarT gate + ) const; /// Steady component-base mechanical power at a gate and dam head. RealT initialMechanicalPower(RealT gate, RealT Hdam) const; @@ -147,8 +150,9 @@ namespace GridKit /// Solve the dam head that reproduces mechanical power at Gv5. RealT solveInitialDamHead(RealT pmech) const; - static constexpr RealT TIME_CONSTANT_MINIMUM = static_cast(1.0e-3); - static void logTimeConstantWarning(); + static constexpr RealT TIME_CONSTANT_MINIMUM = + static_cast(1.0e-3); + static void logTimeConstantWarning(); /// Accepted seed distance beyond the achievable-power range edge. static constexpr RealT INITIALIZATION_TOLERANCE = diff --git a/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovData.hpp b/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovData.hpp index e764238978..f84ed827eb 100644 --- a/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovData.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovData.hpp @@ -23,7 +23,8 @@ namespace GridKit Tr, ///< \f$T_r\f$ Temporary-droop reset time constant Tf, ///< \f$T_f\f$ Governor error filter time constant Tg, ///< \f$T_g\f$ Gate servo time constant - Velm, ///< \f$V_{\mathrm{elm}}\f$ Maximum desired-gate velocity magnitude + Velm, ///< \f$V_{\mathrm{elm}}\f$ Maximum desired-gate velocity + ///< magnitude Gmax, ///< \f$G^{\max}\f$ Configured upper gate response limit Gmin, ///< \f$G^{\min}\f$ Configured lower gate response limit Tw, ///< \f$T_w\f$ Water inertia time constant @@ -31,22 +32,23 @@ namespace GridKit Dturb, ///< \f$D_{\mathrm{turb}}\f$ Turbine damping coefficient Qnl, ///< \f$q_{\mathrm{NL}}\f$ No-load flow at nominal head Tn, ///< \f$T_n\f$ Speed lead-lag numerator time constant - Tnp, ///< \f$T_{\mathrm{np}}\f$ Speed lead-lag denominator time constant - db1, ///< \f$D_{\omega}\f$ Type 1 speed deadband threshold - db2, ///< \f$D_2\f$ Unsupported mechanical backlash. Nonzero values warn and are ignored - Hdam, ///< \f$H_{\mathrm{dam}}\f$ Head available at dam - Gv0, ///< \f$G_V^{(0)}\f$ Gate point 0 - Gv1, ///< \f$G_V^{(1)}\f$ Gate point 1 - Gv2, ///< \f$G_V^{(2)}\f$ Gate point 2 - Gv3, ///< \f$G_V^{(3)}\f$ Gate point 3 - Gv4, ///< \f$G_V^{(4)}\f$ Gate point 4 - Gv5, ///< \f$G_V^{(5)}\f$ Gate point 5 - Pgv0, ///< \f$P_{\mathrm{GV}}^{(0)}\f$ Power point 0 - Pgv1, ///< \f$P_{\mathrm{GV}}^{(1)}\f$ Power point 1 - Pgv2, ///< \f$P_{\mathrm{GV}}^{(2)}\f$ Power point 2 - Pgv3, ///< \f$P_{\mathrm{GV}}^{(3)}\f$ Power point 3 - Pgv4, ///< \f$P_{\mathrm{GV}}^{(4)}\f$ Power point 4 - Pgv5, ///< \f$P_{\mathrm{GV}}^{(5)}\f$ Power point 5 + Tnp, ///< \f$T_{\mathrm{np}}\f$ Speed lead-lag denominator time constant + db1, ///< \f$D_{\omega}\f$ Type 1 speed deadband threshold + db2, ///< \f$D_2\f$ Unsupported mechanical backlash. Nonzero values warn + ///< and are ignored + Hdam, ///< \f$H_{\mathrm{dam}}\f$ Head available at dam + Gv0, ///< \f$G_V^{(0)}\f$ Gate point 0 + Gv1, ///< \f$G_V^{(1)}\f$ Gate point 1 + Gv2, ///< \f$G_V^{(2)}\f$ Gate point 2 + Gv3, ///< \f$G_V^{(3)}\f$ Gate point 3 + Gv4, ///< \f$G_V^{(4)}\f$ Gate point 4 + Gv5, ///< \f$G_V^{(5)}\f$ Gate point 5 + Pgv0, ///< \f$P_{\mathrm{GV}}^{(0)}\f$ Power point 0 + Pgv1, ///< \f$P_{\mathrm{GV}}^{(1)}\f$ Power point 1 + Pgv2, ///< \f$P_{\mathrm{GV}}^{(2)}\f$ Power point 2 + Pgv3, ///< \f$P_{\mathrm{GV}}^{(3)}\f$ Power point 3 + Pgv4, ///< \f$P_{\mathrm{GV}}^{(4)}\f$ Power point 4 + Pgv5, ///< \f$P_{\mathrm{GV}}^{(5)}\f$ Power point 5 }; /// Buses for the HYGOV governor model. diff --git a/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovEnzyme.cpp b/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovEnzyme.cpp index f3ad7ba720..14e69f7582 100644 --- a/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovEnzyme.cpp @@ -27,8 +27,9 @@ namespace GridKit J_vals_buffer_ = new RealT[buffer_size]; } - using ModelT = GridKit::PhasorDynamics::Governor::Hygov; - using Fn = GridKit::Enzyme::Sparse::MemberFunctions; + using ModelT = + GridKit::PhasorDynamics::Governor::Hygov; + using Fn = GridKit::Enzyme::Sparse::MemberFunctions; nnz_ = 0; diff --git a/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovImpl.hpp b/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovImpl.hpp index f2c83a4cfa..f5d06167b8 100644 --- a/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/HYGOV/HygovImpl.hpp @@ -38,7 +38,8 @@ namespace GridKit { initializeParameters(data); initializeMonitor(); - size_ = static_cast(Utilities::enum_size()); + size_ = + static_cast(Utilities::enum_size()); } template @@ -53,7 +54,9 @@ namespace GridKit * @return int 0 on success. */ template - int Hygov::setGridKitComponentID(IdxT component_id) + int Hygov::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -100,7 +103,9 @@ namespace GridKit if (auto port = ports_.out.template port()) { auto* y = y_.getData(); - port.link(&y[PMECH], &(this->getVariableIndex(static_cast(PMECH)))); + port.link( + &y[PMECH], &(this->getVariableIndex(static_cast(PMECH))) + ); } allocated_ = true; @@ -122,10 +127,10 @@ namespace GridKit { Model::ConfigurationChecks checks("Hygov"); - const bool valid_component_base = std::isfinite(va_component_base_) - && va_component_base_ > ZERO; - const bool valid_system_base = std::isfinite(va_system_base_) - && va_system_base_ > ZERO; + const bool valid_component_base = + std::isfinite(va_component_base_) && va_component_base_ > ZERO; + const bool valid_system_base = + std::isfinite(va_system_base_) && va_system_base_ > ZERO; checks.check( valid_component_base, "component power base must be finite and positive" @@ -135,9 +140,11 @@ namespace GridKit ); if (valid_component_base && valid_system_base) { - const RealT system_to_component = va_system_base_ / va_component_base_; - const RealT component_to_system = va_component_base_ / va_system_base_; - const bool valid_base_ratios = std::isfinite(system_to_component) + const RealT system_to_component = + va_system_base_ / va_component_base_; + const RealT component_to_system = + va_component_base_ / va_system_base_; + const bool valid_base_ratios = std::isfinite(system_to_component) && system_to_component > ZERO && std::isfinite(component_to_system) && component_to_system > ZERO; @@ -163,8 +170,12 @@ namespace GridKit const bool gate_points_increase = Gv_[i - 1] < Gv_[i]; const bool power_points_increase = Pgv_[i - 1] <= Pgv_[i]; - checks.check(gate_points_increase, "Gv points must be strictly increasing"); - checks.check(power_points_increase, "Pgv points must be non-decreasing"); + checks.check( + gate_points_increase, "Gv points must be strictly increasing" + ); + checks.check( + power_points_increase, "Pgv points must be non-decreasing" + ); if (!gate_points_increase || !power_points_increase) { @@ -173,22 +184,23 @@ namespace GridKit } const bool minimum_gate_is_valid = Gv_[0] <= Gmin_; const bool maximum_gate_is_valid = Gmax_ <= Gv_[5]; - checks.check(minimum_gate_is_valid, "Gmin must be at or above the first Gv point"); - checks.check(maximum_gate_is_valid, "Gmax must be at or below the last Gv point"); - - const bool can_check_power_range = curve_shape_is_valid - && Gmin_ < Gmax_ - && minimum_gate_is_valid - && maximum_gate_is_valid - && At_ > ZERO - && Hdam_ > ZERO; + checks.check( + minimum_gate_is_valid, "Gmin must be at or above the first Gv point" + ); + checks.check( + maximum_gate_is_valid, "Gmax must be at or below the last Gv point" + ); + + const bool can_check_power_range = + curve_shape_is_valid && Gmin_ < Gmax_ && minimum_gate_is_valid + && maximum_gate_is_valid && At_ > ZERO && Hdam_ > ZERO; if (can_check_power_range) { // A rise no wider than the tolerance that pins a seed to a range // edge leaves the gate undetermined by the mechanical power. - const RealT minimum_power = initialMechanicalPower(Gv_[0], Hdam_); - const RealT maximum_power = initialMechanicalPower(Gv_[5], Hdam_); - const RealT power_range = maximum_power - minimum_power; + const RealT minimum_power = initialMechanicalPower(Gv_[0], Hdam_); + const RealT maximum_power = initialMechanicalPower(Gv_[5], Hdam_); + const RealT power_range = maximum_power - minimum_power; const bool finite_power_range = std::isfinite(minimum_power) && std::isfinite(maximum_power) && std::isfinite(power_range); @@ -217,13 +229,18 @@ namespace GridKit if (ports_.in.template port().connected() && !ports_.in.template port().linked()) { - checks.fail(std::format("{} signal attached with no linked source", name)); + checks.fail( + std::format("{} signal attached with no linked source", name) + ); } }; - check_attached_signal.template operator()("speed"); - check_attached_signal.template operator()("pref"); - check_attached_signal.template operator()("paux"); + check_attached_signal.template operator( + )("speed"); + check_attached_signal.template operator( + )("pref"); + check_attached_signal.template operator( + )("paux"); return checks; } @@ -233,8 +250,8 @@ namespace GridKit * * Reads the assigned system-base `pmech` node and the attached speed * and auxiliary-power inputs, solves the component-base steady state - * that preserves the given value, and publishes the resolved load reference - * to an attached `pref` signal. + * that preserves the given value, and publishes the resolved load + * reference to an attached `pref` signal. * * @pre allocate() has completed. * @pre The machine model has initialized the assigned `pmech` node. @@ -254,23 +271,25 @@ namespace GridKit template int Hygov::initialize() { - const auto XN = static_cast(HygovInternalVariables::XN); - const auto XF = static_cast(HygovInternalVariables::XF); - const auto C = static_cast(HygovInternalVariables::C); - const auto G = static_cast(HygovInternalVariables::G); - const auto Q = static_cast(HygovInternalVariables::Q); - const auto OMEGADB = static_cast(HygovInternalVariables::OMEGADB); - const auto EF = static_cast(HygovInternalVariables::EF); - const auto FC = static_cast(HygovInternalVariables::FC); - const auto RC = static_cast(HygovInternalVariables::RC); - const auto PGV = static_cast(HygovInternalVariables::PGV); - const auto H = static_cast(HygovInternalVariables::H); - const auto PMECH = static_cast(HygovInternalVariables::PMECH); + const auto XN = static_cast(HygovInternalVariables::XN); + const auto XF = static_cast(HygovInternalVariables::XF); + const auto C = static_cast(HygovInternalVariables::C); + const auto G = static_cast(HygovInternalVariables::G); + const auto Q = static_cast(HygovInternalVariables::Q); + const auto OMEGADB = + static_cast(HygovInternalVariables::OMEGADB); + const auto EF = static_cast(HygovInternalVariables::EF); + const auto FC = static_cast(HygovInternalVariables::FC); + const auto RC = static_cast(HygovInternalVariables::RC); + const auto PGV = static_cast(HygovInternalVariables::PGV); + const auto H = static_cast(HygovInternalVariables::H); + const auto PMECH = static_cast(HygovInternalVariables::PMECH); bool ret = this->verifyAndLog(); if (!ret) { - Log::error() << "Hygov: cannot initialize with invalid configuration\n"; + Log::error( + ) << "Hygov: cannot initialize with invalid configuration\n"; return 1; } @@ -281,7 +300,8 @@ namespace GridKit const ScalarT pmech0_system = y[PMECH]; ScalarT omega0{ZERO}; - if (auto omega_port = ports_.in.template port()) + if (auto omega_port = + ports_.in.template port()) { omega0 = omega_port.readSignal(); } @@ -293,25 +313,23 @@ namespace GridKit } auto is_finite = [](ScalarT value) - { - return std::isfinite(static_cast(value)); - }; - ret = is_finite(pmech0_system) - && is_finite(omega0) + { return std::isfinite(static_cast(value)); }; + ret = is_finite(pmech0_system) && is_finite(omega0) && is_finite(paux0_system); if (!ret) { - Log::error() << "Hygov: initial pmech, speed, and paux values must be finite\n"; + Log::error( + ) << "Hygov: initial pmech, speed, and paux values must be finite\n"; return 1; } const ScalarT pmech0 = this->toComponentBase(pmech0_system); const ScalarT paux0 = this->toComponentBase(paux0_system); - ret = is_finite(pmech0) - && is_finite(paux0); + ret = is_finite(pmech0) && is_finite(paux0); if (!ret) { - Log::error() << "Hygov: initial power-base conversions must be finite\n"; + Log::error( + ) << "Hygov: initial power-base conversions must be finite\n"; return 1; } @@ -324,7 +342,8 @@ namespace GridKit ret = speed0 == ZERO; if (!ret) { - Log::error() << "Hygov: initialization requires zero speed deviation\n"; + Log::error( + ) << "Hygov: initialization requires zero speed deviation\n"; return 1; } @@ -338,7 +357,8 @@ namespace GridKit Hdam0 = solveInitialDamHead(pmech0_value); if (!std::isfinite(Hdam0)) { - Log::error() << "Hygov: no finite Hdam reproduces the initial mechanical power\n"; + Log::error() << "Hygov: no finite Hdam reproduces the initial " + "mechanical power\n"; return 1; } } @@ -347,7 +367,8 @@ namespace GridKit gate0 = solveInitialGate(pmech0_value); if (!std::isfinite(gate0)) { - Log::error() << "Hygov: initial mechanical power is below the first Gv endpoint\n"; + Log::error() << "Hygov: initial mechanical power is below the " + "first Gv endpoint\n"; return 1; } } @@ -361,14 +382,11 @@ namespace GridKit const ScalarT omegadb0 = Math::deadband1(omega0, -db1_, db1_); const ScalarT xn0 = omegadb0; const ScalarT yomega0 = xn0 + leadlag_gain_ * (omegadb0 - xn0); - const ScalarT pref0 = this->toSystemBase(yomega0 + Rperm_ * gate0 - paux0); - - ret = is_finite(h0) - && is_finite(pgv0) - && is_finite(q0) - && is_finite(omegadb0) - && is_finite(xn0) - && is_finite(yomega0) + const ScalarT pref0 = + this->toSystemBase(yomega0 + Rperm_ * gate0 - paux0); + + ret = is_finite(h0) && is_finite(pgv0) && is_finite(q0) + && is_finite(omegadb0) && is_finite(xn0) && is_finite(yomega0) && is_finite(pref0); if (!ret) { @@ -401,12 +419,14 @@ namespace GridKit if (Hdam_eff_ > Hdam_) { - Log::warning() << "Hygov: effective Hdam raised to match initial mechanical power\n"; + Log::warning() << "Hygov: effective Hdam raised to match initial " + "mechanical power\n"; } if (gate0 < Gmin_ || gate0 > Gmax_) { Log::warning() << "Hygov: initial gate is outside [Gmin, Gmax]; " - "response limits are adjusted to include the initialized value\n"; + "response limits are adjusted to include the " + "initialized value\n"; } y_.setDataUpdated(); @@ -477,7 +497,8 @@ namespace GridKit const auto PAUX = static_cast(HygovExternalVariables::PAUX); std::fill(ws_indices_.begin(), ws_indices_.end(), INVALID_INDEX); - if (auto speed_port = ports_.in.template port()) + if (auto speed_port = + ports_.in.template port()) { ws_indices_[OMEGA] = speed_port.signalVariableIndex(); } @@ -517,7 +538,8 @@ namespace GridKit ws[PREF] = pref_set_; ws[PAUX] = paux_set_; - if (auto omega_port = ports_.in.template port()) + if (auto omega_port = + ports_.in.template port()) { ws[OMEGA] = omega_port.readSignal(); } @@ -546,7 +568,8 @@ namespace GridKit * constructed without data. */ template - const Model::VariableMonitorBase* Hygov::getMonitor() const + const Model::VariableMonitorBase* Hygov:: + getMonitor() const { return monitor_.get(); } @@ -577,18 +600,19 @@ namespace GridKit ScalarT* f ) { - const auto XN = static_cast(HygovInternalVariables::XN); - const auto XF = static_cast(HygovInternalVariables::XF); - const auto C = static_cast(HygovInternalVariables::C); - const auto G = static_cast(HygovInternalVariables::G); - const auto Q = static_cast(HygovInternalVariables::Q); - const auto OMEGADB = static_cast(HygovInternalVariables::OMEGADB); - const auto EF = static_cast(HygovInternalVariables::EF); - const auto FC = static_cast(HygovInternalVariables::FC); - const auto RC = static_cast(HygovInternalVariables::RC); - const auto PGV = static_cast(HygovInternalVariables::PGV); - const auto H = static_cast(HygovInternalVariables::H); - const auto PMECH = static_cast(HygovInternalVariables::PMECH); + const auto XN = static_cast(HygovInternalVariables::XN); + const auto XF = static_cast(HygovInternalVariables::XF); + const auto C = static_cast(HygovInternalVariables::C); + const auto G = static_cast(HygovInternalVariables::G); + const auto Q = static_cast(HygovInternalVariables::Q); + const auto OMEGADB = + static_cast(HygovInternalVariables::OMEGADB); + const auto EF = static_cast(HygovInternalVariables::EF); + const auto FC = static_cast(HygovInternalVariables::FC); + const auto RC = static_cast(HygovInternalVariables::RC); + const auto PGV = static_cast(HygovInternalVariables::PGV); + const auto H = static_cast(HygovInternalVariables::H); + const auto PMECH = static_cast(HygovInternalVariables::PMECH); const auto OMEGA = static_cast(HygovExternalVariables::OMEGA); const auto PREF = static_cast(HygovExternalVariables::PREF); @@ -619,18 +643,19 @@ namespace GridKit const ScalarT yomega = xn + leadlag_gain_ * (omegadb - xn); - f[XN] = -xn_dot + (omegadb - xn) / Tnp_; - f[XF] = -xf_dot + (ef - xf) / Tf_; - f[C] = -c_dot + Math::antiwindup(c, rc, Gmin_response_, Gmax_response_); - f[G] = -g_dot + (c - g) / Tg_; - f[Q] = -q_dot + (Hdam_eff_ - head) / Tw_; + f[XN] = -xn_dot + (omegadb - xn) / Tnp_; + f[XF] = -xf_dot + (ef - xf) / Tf_; + f[C] = -c_dot + Math::antiwindup(c, rc, Gmin_response_, Gmax_response_); + f[G] = -g_dot + (c - g) / Tg_; + f[Q] = -q_dot + (Hdam_eff_ - head) / Tw_; f[OMEGADB] = -omegadb + Math::deadband1(omega, -db1_, db1_); - f[EF] = -ef + this->toComponentBase(pref + paux) - yomega - Rperm_ * c; - f[FC] = -Rtemp_ * fc + xf / Tr_ + (ef - xf) / Tf_; - f[RC] = -rc + Math::clamp(fc, -Velm_, Velm_); - f[PGV] = -pgv + gatePower(g); - f[H] = -q * q + head * pgv * pgv; - f[PMECH] = -this->toComponentBase(pmech) + At_ * head * (q - Qnl_) - Dturb_ * omega * g; + f[EF] = -ef + this->toComponentBase(pref + paux) - yomega - Rperm_ * c; + f[FC] = -Rtemp_ * fc + xf / Tr_ + (ef - xf) / Tf_; + f[RC] = -rc + Math::clamp(fc, -Velm_, Velm_); + f[PGV] = -pgv + gatePower(g); + f[H] = -q * q + head * pgv * pgv; + f[PMECH] = -this->toComponentBase(pmech) + At_ * head * (q - Qnl_) + - Dturb_ * omega * g; return 0; } @@ -649,7 +674,9 @@ namespace GridKit * @param[in] data Parameters and monitored-variable selections. */ template - void Hygov::initializeParameters(const ModelDataT& data) + void Hygov::initializeParameters( + const ModelDataT& data + ) { using Params = typename ModelDataT::Parameters; @@ -692,8 +719,9 @@ namespace GridKit if (db2_ != ZERO) { - Log::warning() << "Hygov: nonzero db2 requests mechanical backlash, " - "but backlash is not implemented and db2 is ignored\n"; + Log::warning( + ) << "Hygov: nonzero db2 requests mechanical backlash, " + "but backlash is not implemented and db2 is ignored\n"; } setDerivedParameters(); @@ -711,18 +739,50 @@ namespace GridKit { using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::pmech, [this] - { return y_.getData()[static_cast(HygovInternalVariables::PMECH)]; }); - monitor_->set(Variable::filter, [this] - { return y_.getData()[static_cast(HygovInternalVariables::XF)]; }); - monitor_->set(Variable::desiredgate, [this] - { return y_.getData()[static_cast(HygovInternalVariables::C)]; }); - monitor_->set(Variable::gate, [this] - { return y_.getData()[static_cast(HygovInternalVariables::G)]; }); - monitor_->set(Variable::flow, [this] - { return y_.getData()[static_cast(HygovInternalVariables::Q)]; }); - monitor_->set(Variable::head, [this] - { return y_.getData()[static_cast(HygovInternalVariables::H)]; }); + monitor_->set( + Variable::pmech, + [this] + { + return y_.getData( + )[static_cast(HygovInternalVariables::PMECH)]; + } + ); + monitor_->set( + Variable::filter, + [this] + { + return y_.getData( + )[static_cast(HygovInternalVariables::XF)]; + } + ); + monitor_->set( + Variable::desiredgate, + [this] + { + return y_.getData()[static_cast(HygovInternalVariables::C)]; + } + ); + monitor_->set( + Variable::gate, + [this] + { + return y_.getData()[static_cast(HygovInternalVariables::G)]; + } + ); + monitor_->set( + Variable::flow, + [this] + { + return y_.getData()[static_cast(HygovInternalVariables::Q)]; + } + ); + monitor_->set( + Variable::head, + [this] + { + return y_.getData()[static_cast(HygovInternalVariables::H)]; + } + ); } /** @@ -752,22 +812,20 @@ namespace GridKit // Model data uses an all-exact-zero curve to mean "no curve supplied", // so this is an exact comparison by intent rather than a tolerance // test. Any nonzero point selects the given curve. - auto is_nonzero = [](RealT value) - { return value != ZERO; }; + auto is_nonzero = [](RealT value) { return value != ZERO; }; const bool curve_supplied = std::any_of(Gv_.begin(), Gv_.end(), is_nonzero) || std::any_of(Pgv_.begin(), Pgv_.end(), is_nonzero); if (!curve_supplied) { - Gv_ = { - ZERO, - static_cast(0.2), - static_cast(0.4), - static_cast(0.6), - static_cast(0.8), - ONE - }; + Gv_ = + {ZERO, + static_cast(0.2), + static_cast(0.4), + static_cast(0.6), + static_cast(0.8), + ONE}; Pgv_ = Gv_; } @@ -782,9 +840,10 @@ namespace GridKit } } - // HYGOV residuals solve explicitly for the state derivatives to preserve - // Hessenberg form. A zero time constant would instead require an implicit - // residual formulation, so enforce a strictly positive lower bound. + // HYGOV residuals solve explicitly for the state derivatives to + // preserve Hessenberg form. A zero time constant would instead require + // an implicit residual formulation, so enforce a strictly positive + // lower bound. Tr_ = std::max(Tr_, TIME_CONSTANT_MINIMUM); Tf_ = std::max(Tf_, TIME_CONSTANT_MINIMUM); Tg_ = std::max(Tg_, TIME_CONSTANT_MINIMUM); @@ -808,15 +867,16 @@ namespace GridKit * @return Turbine power at nominal head. */ template - __attribute__((always_inline)) inline scalar_type - Hygov::gatePower(scalar_type gate) const + __attribute__((always_inline)) inline scalar_type Hygov< + scalar_type, + index_type>::gatePower(scalar_type gate) const { - ScalarT retval = Pgv_[0] - + Math::linseg(gate, Gv_[0], Gv_[1], Pgv_[1] - Pgv_[0]) - + Math::linseg(gate, Gv_[1], Gv_[2], Pgv_[2] - Pgv_[1]) - + Math::linseg(gate, Gv_[2], Gv_[3], Pgv_[3] - Pgv_[2]) - + Math::linseg(gate, Gv_[3], Gv_[4], Pgv_[4] - Pgv_[3]) - + Math::linseg(gate, Gv_[4], Gv_[5], Pgv_[5] - Pgv_[4]); + ScalarT retval = + Pgv_[0] + Math::linseg(gate, Gv_[0], Gv_[1], Pgv_[1] - Pgv_[0]) + + Math::linseg(gate, Gv_[1], Gv_[2], Pgv_[2] - Pgv_[1]) + + Math::linseg(gate, Gv_[2], Gv_[3], Pgv_[3] - Pgv_[2]) + + Math::linseg(gate, Gv_[3], Gv_[4], Pgv_[4] - Pgv_[3]) + + Math::linseg(gate, Gv_[4], Gv_[5], Pgv_[5] - Pgv_[4]); return retval; } @@ -845,8 +905,9 @@ namespace GridKit scalar_type, index_type>::initialMechanicalPower(RealT gate, RealT Hdam) const { - const RealT pgv = static_cast(gatePower(static_cast(gate))); - const RealT q = std::sqrt(Hdam) * pgv; + const RealT pgv = + static_cast(gatePower(static_cast(gate))); + const RealT q = std::sqrt(Hdam) * pgv; return At_ * Hdam * (q - Qnl_); } @@ -864,7 +925,8 @@ namespace GridKit * @param[in] fa Residual at the lower endpoint. * @param[in] fb Residual at the upper endpoint. * @param[in] residual Residual callable. - * @pre The endpoints are finite, @f$a < b@f$, and @f$f(a) \le 0 \le f(b)@f$. + * @pre The endpoints are finite, @f$a < b@f$, and @f$f(a) \le 0 \le + * f(b)@f$. * @return The endpoint with the smaller residual magnitude, or a quiet * NaN if an interior residual is NaN. */ @@ -927,8 +989,9 @@ namespace GridKit * during initialization, but not during residual evaluation. */ template - typename Hygov::RealT - Hygov::solveInitialGate(RealT pmech) const + typename Hygov::RealT Hygov< + scalar_type, + index_type>::solveInitialGate(RealT pmech) const { const auto residual = [this, pmech](RealT gate) { return initialMechanicalPower(gate, Hdam_) - pmech; }; @@ -967,14 +1030,16 @@ namespace GridKit * @pre The initial mechanical power exceeds the last gate-curve endpoint. * * @param[in] pmech Mechanical power on the component base. - * @return Effective dam head, or a quiet NaN when no finite value is found. + * @return Effective dam head, or a quiet NaN when no finite value is + * found. * * @warning This function contains conditional branching and may be used * during initialization, but not during residual evaluation. */ template - typename Hygov::RealT - Hygov::solveInitialDamHead(RealT pmech) const + typename Hygov::RealT Hygov< + scalar_type, + index_type>::solveInitialDamHead(RealT pmech) const { const RealT nan = std::numeric_limits::quiet_NaN(); const auto residual = [this, pmech](RealT Hdam) diff --git a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp index eb5034f4f0..c4f12884c7 100644 --- a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp @@ -94,13 +94,8 @@ namespace GridKit } public: - __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, - const ScalarT*, - const ScalarT*, - const ScalarT*, - ScalarT* - ); + __attribute__((always_inline)) inline int + evaluateInternalResidual(const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); private: // Input parameters @@ -123,8 +118,9 @@ namespace GridKit void initializeParameters(const ModelDataT& data); void setDerivedParams(); - static constexpr RealT TIME_CONSTANT_MINIMUM = static_cast(1.0e-3); - static void logTimeConstantWarning(); + static constexpr RealT TIME_CONSTANT_MINIMUM = + static_cast(1.0e-3); + static void logTimeConstantWarning(); }; } // namespace Governor diff --git a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Data.hpp b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Data.hpp index 7497a598ec..4b37f214b4 100644 --- a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Data.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Data.hpp @@ -18,7 +18,8 @@ namespace GridKit /** * @brief Parameter keys for TGOV1 Governor model. * - * These enum values serve as keys for the parameters map in ComponentData. + * These enum values serve as keys for the parameters map in + * ComponentData. */ enum class Tgov1Parameters : size_t { diff --git a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Enzyme.cpp b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Enzyme.cpp index f6141c7c43..1d5fdb8a79 100644 --- a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Enzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Enzyme.cpp @@ -25,8 +25,9 @@ namespace GridKit if (J_rows_buffer_ == nullptr) { // Reserve space for the dense blocks. - // The size of the buffer is the sum of maximum capacities of the blocks. - // Enzyme will compute the appropriate nnz from sparsification. + // The size of the buffer is the sum of maximum capacities of the + // blocks. Enzyme will compute the appropriate nnz from + // sparsification. auto size = static_cast(size_); auto signal_size = static_cast(ws_.getSize()); auto buffer_size = 2 * size * size + size * signal_size; diff --git a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp index b7043c714b..93fa4eff2d 100644 --- a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp @@ -49,7 +49,9 @@ namespace GridKit * @param data Structure containing model parameters. */ template - void Tgov1::initializeParameters(const ModelDataT& data) + void Tgov1::initializeParameters( + const ModelDataT& data + ) { using Parameter = typename ModelDataT::Parameters; @@ -100,7 +102,9 @@ namespace GridKit * @brief Set the component ID */ template - int Tgov1::setGridKitComponentID(IdxT component_id) + int Tgov1::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -138,7 +142,8 @@ namespace GridKit ws_indices_.assign(signal_size, INVALID_INDEX); // Set output signals - if (auto pmech_port = ports_.out.template port()) + if (auto pmech_port = + ports_.out.template port()) { auto* y = y_.getData(); const auto PM = static_cast(Tgov1InternalVariables::PM); @@ -160,9 +165,13 @@ namespace GridKit Model::ConfigurationChecks checks("Tgov1"); checks.check(Trate_ > ZERO, "Trate must be positive"); - checks.check(va_system_base_ > ZERO, "system power base must be positive"); + checks.check( + va_system_base_ > ZERO, "system power base must be positive" + ); checks.check(R_ != ZERO, "R must be nonzero"); - checks.check(Pvmin_ <= Pvmax_, "Pvmin must be less than or equal to Pvmax"); + checks.check( + Pvmin_ <= Pvmax_, "Pvmin must be less than or equal to Pvmax" + ); checks.check( ports_.out.template port().connected(), "pmech output signal must be assigned" @@ -192,7 +201,8 @@ namespace GridKit { if (!this->verifyAndLog()) { - Log::error() << "Tgov1: cannot initialize with invalid configuration\n"; + Log::error( + ) << "Tgov1: cannot initialize with invalid configuration\n"; return 1; } @@ -203,7 +213,8 @@ namespace GridKit auto* y = y_.getData(); ScalarT omega0{ZERO}; - if (auto speed_port = ports_.in.template port()) + if (auto speed_port = + ports_.in.template port()) { omega0 = speed_port.readSignal(); } @@ -214,12 +225,15 @@ namespace GridKit const ScalarT pturb0 = pv0; const ScalarT pref0 = omega0 + R_ * pv0; - const RealT pv0_value = static_cast(pv0); - const RealT limit_tolerance = static_cast(4.0) * std::numeric_limits::epsilon(); - if (pv0_value < Pvmin_ - limit_tolerance || pv0_value > Pvmax_ + limit_tolerance) + const RealT pv0_value = static_cast(pv0); + const RealT limit_tolerance = + static_cast(4.0) * std::numeric_limits::epsilon(); + if (pv0_value < Pvmin_ - limit_tolerance + || pv0_value > Pvmax_ + limit_tolerance) { - Log::error() << "Tgov1: initial valve position is outside [Pvmin, Pvmax]. " - "Check initial dispatch and valve limits\n"; + Log::error( + ) << "Tgov1: initial valve position is outside [Pvmin, Pvmax]. " + "Check initial dispatch and valve limits\n"; return 1; } @@ -294,8 +308,9 @@ namespace GridKit const auto PV = static_cast(Tgov1InternalVariables::PV); const auto PM = static_cast(Tgov1InternalVariables::PM); - const auto DELTAOMEGA = static_cast(Tgov1ExternalVariables::DELTAOMEGA); - const auto PREF = static_cast(Tgov1ExternalVariables::PREF); + const auto DELTAOMEGA = + static_cast(Tgov1ExternalVariables::DELTAOMEGA); + const auto PREF = static_cast(Tgov1ExternalVariables::PREF); const ScalarT pturb = y[PTX]; const ScalarT pv = y[PV]; @@ -308,8 +323,11 @@ namespace GridKit const ScalarT pref = ws[PREF]; f[PTX] = -pturb_dot - (pturb - pv - T2_ * pv_dot) / T3_; - f[PV] = -pv_dot + Math::antiwindup(pv, -pv + (pref - omega) / R_, Pvmin_, Pvmax_) / T1_; - f[PM] = -this->toComponentBase(pmech) + pturb - Dt_ * omega; + f[PV] = + -pv_dot + + Math::antiwindup(pv, -pv + (pref - omega) / R_, Pvmin_, Pvmax_) + / T1_; + f[PM] = -this->toComponentBase(pmech) + pturb - Dt_ * omega; return 0; } @@ -321,12 +339,14 @@ namespace GridKit template int Tgov1::setSignalIndices() { - const auto DELTAOMEGA = static_cast(Tgov1ExternalVariables::DELTAOMEGA); - const auto PREF = static_cast(Tgov1ExternalVariables::PREF); + const auto DELTAOMEGA = + static_cast(Tgov1ExternalVariables::DELTAOMEGA); + const auto PREF = static_cast(Tgov1ExternalVariables::PREF); std::fill(ws_indices_.begin(), ws_indices_.end(), INVALID_INDEX); - if (auto speed_port = ports_.in.template port()) + if (auto speed_port = + ports_.in.template port()) { ws_indices_[DELTAOMEGA] = speed_port.signalVariableIndex(); } @@ -346,15 +366,17 @@ namespace GridKit template int Tgov1::evaluateResidual() { - const auto DELTAOMEGA = static_cast(Tgov1ExternalVariables::DELTAOMEGA); - const auto PREF = static_cast(Tgov1ExternalVariables::PREF); + const auto DELTAOMEGA = + static_cast(Tgov1ExternalVariables::DELTAOMEGA); + const auto PREF = static_cast(Tgov1ExternalVariables::PREF); auto* ws = ws_.getData(); ws[DELTAOMEGA] = ScalarT{ZERO}; ws[PREF] = pref_set_; - if (auto speed_port = ports_.in.template port()) + if (auto speed_port = + ports_.in.template port()) { ws[DELTAOMEGA] = speed_port.readSignal(); } diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZ.hpp b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZ.hpp index fc352bde83..4f122fc2c2 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZ.hpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZ.hpp @@ -100,12 +100,10 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; public: - __attribute__((always_inline)) inline int evaluateBusResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* - ); - __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* - ); + __attribute__((always_inline)) inline int + evaluateBusResidual(const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + __attribute__((always_inline)) inline int + evaluateInternalResidual(const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); private: BusT* bus_{nullptr}; diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZData.hpp b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZData.hpp index c1c8d2493f..6c0155b0a0 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZData.hpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZData.hpp @@ -45,8 +45,8 @@ namespace GridKit /// Initial values supported for a load enum class LoadZInitialValues : size_t { - ir, ///< Initial real terminal current into the bus on system base - ii, ///< Initial imaginary terminal current into the bus on system base + ir, ///< Initial real terminal current into the bus on system base + ii, ///< Initial imaginary terminal current into the bus on system base in_service, ///< Initial service status; defaults to true }; diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZEnzyme.cpp b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZEnzyme.cpp index a20ef95cb6..23494411bd 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZEnzyme.cpp @@ -23,8 +23,8 @@ namespace GridKit if (J_rows_buffer_ == nullptr) { // Reserve space for the dense blocks. - // The size of the buffer is the sum of maximum capacities of the blocks. - // Enzyme will compute the appropriate nnz from sparsification. + // The size of the buffer is the sum of maximum capacities of the + // blocks. Enzyme will compute the appropriate nnz from sparsification. auto size = static_cast(size_); auto bus_size = static_cast(bus_->size()); auto buffer_size = size * size + 2 * size * bus_size; diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZImpl.hpp b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZImpl.hpp index fde033b60e..a03439809b 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZ/LoadZImpl.hpp @@ -231,7 +231,8 @@ namespace GridKit } template - const Model::VariableMonitorBase* LoadZ::getMonitor() const + const Model::VariableMonitorBase* LoadZ:: + getMonitor() const { return monitor_.get(); } @@ -241,10 +242,14 @@ namespace GridKit { using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::p, [this] - { return Vr() * y_.getData()[0] + Vi() * y_.getData()[1]; }); - monitor_->set(Variable::q, [this] - { return Vi() * y_.getData()[0] - Vr() * y_.getData()[1]; }); + monitor_->set( + Variable::p, + [this] { return Vr() * y_.getData()[0] + Vi() * y_.getData()[1]; } + ); + monitor_->set( + Variable::q, + [this] { return Vi() * y_.getData()[0] - Vr() * y_.getData()[1]; } + ); } } // namespace PhasorDynamics diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIP.hpp b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIP.hpp index 9494d569d3..14b7e16055 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIP.hpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIP.hpp @@ -113,12 +113,10 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; public: - __attribute__((always_inline)) inline int evaluateBusResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* - ); - __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* - ); + __attribute__((always_inline)) inline int + evaluateBusResidual(const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + __attribute__((always_inline)) inline int + evaluateInternalResidual(const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); private: BusT* bus_{nullptr}; diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPData.hpp b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPData.hpp index dae58b1fdf..e2c25c24b6 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPData.hpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPData.hpp @@ -45,8 +45,8 @@ namespace GridKit /// Initial values supported for a loadZIP enum class LoadZIPInitialValues : size_t { - ir, ///< Initial real terminal current into the bus on system base - ii, ///< Initial imaginary terminal current into the bus on system base + ir, ///< Initial real terminal current into the bus on system base + ii, ///< Initial imaginary terminal current into the bus on system base in_service, ///< Initial service status; defaults to true }; diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPEnzyme.cpp b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPEnzyme.cpp index 63f93e5a6a..cb0db11bfe 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPEnzyme.cpp @@ -18,8 +18,8 @@ namespace GridKit if (J_rows_buffer_ == nullptr) { // Reserve space for the dense blocks. - // The size of the buffer is the sum of maximum capacities of the blocks. - // Enzyme will compute the appropriate nnz from sparsification. + // The size of the buffer is the sum of maximum capacities of the + // blocks. Enzyme will compute the appropriate nnz from sparsification. auto size = static_cast(size_); auto bus_size = static_cast(bus_->size()); auto buffer_size = size * size + 2 * size * bus_size; diff --git a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPImpl.hpp b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPImpl.hpp index c2ee3b16b8..d97bf831e6 100644 --- a/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Load/LoadZIP/LoadZIPImpl.hpp @@ -32,7 +32,9 @@ namespace GridKit } template - void LoadZIP::initializeParameters(const ModelDataT& data) + void LoadZIP::initializeParameters( + const ModelDataT& data + ) { using Parameter = typename ModelDataT::Parameters; @@ -50,7 +52,9 @@ namespace GridKit * @brief Set the component ID */ template - int LoadZIP::setGridKitComponentID(IdxT component_id) + int LoadZIP::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -230,7 +234,7 @@ namespace GridKit const RealT Vnom2 = Vnom_ * Vnom_; const ScalarT V2 = Vr * Vr + Vi * Vi; const ScalarT V = std::sqrt(V2); - const ScalarT zip = alphaZ_ + alphaI_ * Vnom_ / V + alphaP_ * Vnom2 / V2; + const ScalarT zip = alphaZ_ + alphaI_ * Vnom_ / V + alphaP_ * Vnom2 / V2; f[0] = Ir + (G_ * Vr + B_ * Vi) * zip; f[1] = Ii + (G_ * Vi - B_ * Vr) * zip; @@ -253,7 +257,8 @@ namespace GridKit } template - const Model::VariableMonitorBase* LoadZIP::getMonitor() const + const Model::VariableMonitorBase* LoadZIP:: + getMonitor() const { return monitor_.get(); } @@ -263,16 +268,26 @@ namespace GridKit { using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::ir, [this] - { return y_.getData()[0]; }); - monitor_->set(Variable::ii, [this] - { return y_.getData()[1]; }); - monitor_->set(Variable::im, [this] - { return std::sqrt(y_.getData()[0] * y_.getData()[0] + y_.getData()[1] * y_.getData()[1]); }); - monitor_->set(Variable::p, [this] - { return Vr() * y_.getData()[0] + Vi() * y_.getData()[1]; }); - monitor_->set(Variable::q, [this] - { return Vi() * y_.getData()[0] - Vr() * y_.getData()[1]; }); + monitor_->set(Variable::ir, [this] { return y_.getData()[0]; }); + monitor_->set(Variable::ii, [this] { return y_.getData()[1]; }); + monitor_->set( + Variable::im, + [this] + { + return std::sqrt( + y_.getData()[0] * y_.getData()[0] + + y_.getData()[1] * y_.getData()[1] + ); + } + ); + monitor_->set( + Variable::p, + [this] { return Vr() * y_.getData()[0] + Vi() * y_.getData()[1]; } + ); + monitor_->set( + Variable::q, + [this] { return Vi() * y_.getData()[0] - Vr() * y_.getData()[1]; } + ); } } // namespace PhasorDynamics diff --git a/GridKit/Model/PhasorDynamics/SignalNode/SignalNodeDataJSONParser.hpp b/GridKit/Model/PhasorDynamics/SignalNode/SignalNodeDataJSONParser.hpp index 4f2a18d7b8..c0e4a43a99 100644 --- a/GridKit/Model/PhasorDynamics/SignalNode/SignalNodeDataJSONParser.hpp +++ b/GridKit/Model/PhasorDynamics/SignalNode/SignalNodeDataJSONParser.hpp @@ -14,7 +14,8 @@ namespace GridKit /// JSON parser function implementation for the `BusData` type /// - /// See the `README.md` in `GridKit/Model/PhasorDynamics` for more information + /// See the `README.md` in `GridKit/Model/PhasorDynamics` for more + /// information template void from_json(const json& j, SignalNodeData& sd) { diff --git a/GridKit/Model/PhasorDynamics/SignalSource/ConstantSignalSourceImpl.hpp b/GridKit/Model/PhasorDynamics/SignalSource/ConstantSignalSourceImpl.hpp index 31fd1db640..ca1700ede0 100644 --- a/GridKit/Model/PhasorDynamics/SignalSource/ConstantSignalSourceImpl.hpp +++ b/GridKit/Model/PhasorDynamics/SignalSource/ConstantSignalSourceImpl.hpp @@ -16,7 +16,9 @@ namespace GridKit * @brief Construct with values from input data */ template - ConstantSignalSource::ConstantSignalSource(const ModelDataT& data) + ConstantSignalSource::ConstantSignalSource( + const ModelDataT& data + ) { initializeParameters(data); size_ = 0; @@ -31,7 +33,9 @@ namespace GridKit * @brief Set value from input data */ template - void ConstantSignalSource::initializeParameters(const ModelDataT& data) + void ConstantSignalSource::initializeParameters( + const ModelDataT& data + ) { using Parameters = ModelDataT::Parameters; @@ -51,7 +55,9 @@ namespace GridKit * @brief Set the component ID */ template - int ConstantSignalSource::setGridKitComponentID(IdxT component_id) + int ConstantSignalSource::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -79,7 +85,8 @@ namespace GridKit } template - Model::ConfigurationChecks ConstantSignalSource::verify() const + Model::ConfigurationChecks ConstantSignalSource:: + verify() const { return {}; } @@ -97,7 +104,9 @@ namespace GridKit } template - int ConstantSignalSource::setAbsoluteTolerance(RealT) + int ConstantSignalSource::setAbsoluteTolerance( + RealT + ) { return 0; } diff --git a/GridKit/Model/PhasorDynamics/SignalSource/FunctionSignalSource.hpp b/GridKit/Model/PhasorDynamics/SignalSource/FunctionSignalSource.hpp index 260c1b4b37..129550d43b 100644 --- a/GridKit/Model/PhasorDynamics/SignalSource/FunctionSignalSource.hpp +++ b/GridKit/Model/PhasorDynamics/SignalSource/FunctionSignalSource.hpp @@ -64,8 +64,7 @@ namespace GridKit } private: - const FuncT f_default_ = [](auto) - { return static_cast(0.0); }; + const FuncT f_default_ = [](auto) { return static_cast(0.0); }; FuncT parseFunction(const std::string& expr); diff --git a/GridKit/Model/PhasorDynamics/SignalSource/FunctionSignalSourceImpl.hpp b/GridKit/Model/PhasorDynamics/SignalSource/FunctionSignalSourceImpl.hpp index c305aa317a..179c97cd24 100644 --- a/GridKit/Model/PhasorDynamics/SignalSource/FunctionSignalSourceImpl.hpp +++ b/GridKit/Model/PhasorDynamics/SignalSource/FunctionSignalSourceImpl.hpp @@ -13,7 +13,9 @@ namespace GridKit * @brief Construct with values from input data */ template - FunctionSignalSource::FunctionSignalSource(const ModelDataT& data) + FunctionSignalSource::FunctionSignalSource( + const ModelDataT& data + ) { initializeParameters(data); size_ = 0; @@ -25,18 +27,17 @@ namespace GridKit } template - FunctionSignalSource::FuncT - FunctionSignalSource::parseFunction(const std::string& expr) + FunctionSignalSource::FuncT FunctionSignalSource< + scalar_type, + index_type>::parseFunction(const std::string& expr) { if (expr == "sin") { - return [](RealT t) - { return static_cast(std::sin(t)); }; + return [](RealT t) { return static_cast(std::sin(t)); }; } if (expr == "cos") { - return [](RealT t) - { return static_cast(std::cos(t)); }; + return [](RealT t) { return static_cast(std::cos(t)); }; } throw std::runtime_error("FunctionSignalSource: Unsupported function"); @@ -46,7 +47,9 @@ namespace GridKit * @brief Set value from input data */ template - void FunctionSignalSource::initializeParameters(const ModelDataT& data) + void FunctionSignalSource::initializeParameters( + const ModelDataT& data + ) { using Parameters = ModelDataT::Parameters; if (data.parameters.contains(Parameters::Fr)) @@ -62,7 +65,9 @@ namespace GridKit } template - void FunctionSignalSource::updateTime(RealT t, RealT a) + void FunctionSignalSource::updateTime( + RealT t, RealT a + ) { Component::updateTime(t, a); s_real_ = f_real_(t); @@ -73,7 +78,9 @@ namespace GridKit * @brief Set the component ID */ template - int FunctionSignalSource::setGridKitComponentID(IdxT component_id) + int FunctionSignalSource::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -101,7 +108,8 @@ namespace GridKit } template - Model::ConfigurationChecks FunctionSignalSource::verify() const + Model::ConfigurationChecks FunctionSignalSource:: + verify() const { return {}; } @@ -119,7 +127,9 @@ namespace GridKit } template - int FunctionSignalSource::setAbsoluteTolerance(RealT) + int FunctionSignalSource::setAbsoluteTolerance( + RealT + ) { return 0; } diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp index 20cf7a38f4..f074f30672 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp @@ -32,7 +32,8 @@ namespace GridKit V5, ///< \f$v_5\f$ Lead-lag 1 output V6, ///< \f$v_6\f$ Lead-lag 2 output V7, ///< \f$v_7\f$ Unlimited stabilizer signal - VSS, ///< \f$V_{\mathrm{ss}}\f$ Limited stabilizer signal and model output + VSS, ///< \f$V_{\mathrm{ss}}\f$ Limited stabilizer signal and model + ///< output }; /// External variables of an `Ieeest`. @@ -96,13 +97,8 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; - __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, - const ScalarT*, - const ScalarT*, - const ScalarT*, - ScalarT* - ); + __attribute__((always_inline)) inline int + evaluateInternalResidual(const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); private: RealT A1_{0}; @@ -130,7 +126,8 @@ namespace GridKit RealT a3_{0}; RealT a4_{0}; - // Precomputed masks and safe inverse coefficients for branch-free degenerate paths. + // Precomputed masks and safe inverse coefficients for branch-free + // degenerate paths. RealT use_notch_{0}; RealT bypass_notch_{1}; RealT use_4th_order_{0}; diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestData.hpp b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestData.hpp index 7d4e980cba..a1acadc20e 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestData.hpp +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestData.hpp @@ -19,23 +19,23 @@ namespace GridKit */ enum class IeeestParameters : size_t { - A1, ///< \f$A_1\f$ Notch-filter denominator coefficient - A2, ///< \f$A_2\f$ Notch-filter denominator coefficient - A3, ///< \f$A_3\f$ Notch-filter denominator coefficient - A4, ///< \f$A_4\f$ Notch-filter denominator coefficient - A5, ///< \f$A_5\f$ Notch-filter numerator coefficient - A6, ///< \f$A_6\f$ Notch-filter numerator coefficient - T1, ///< \f$T_1\f$ Lead-lag 1 numerator time constant - T2, ///< \f$T_2\f$ Lead-lag 1 denominator time constant - T3, ///< \f$T_3\f$ Lead-lag 2 numerator time constant - T4, ///< \f$T_4\f$ Lead-lag 2 denominator time constant - T5, ///< \f$T_5\f$ Washout numerator time constant - T6, ///< \f$T_6\f$ Washout denominator time constant - Ks, ///< \f$K_s\f$ Stabilizer gain - Lsmin, ///< \f$L_s^{\min}\f$ Minimum stabilizer output limit - Lsmax, ///< \f$L_s^{\max}\f$ Maximum stabilizer output limit - Vcl, ///< \f$V_{\mathrm{cl}}\f$ Unsupported lower input-cutout threshold - Vcu, ///< \f$V_{\mathrm{cu}}\f$ Unsupported upper input-cutout threshold + A1, ///< \f$A_1\f$ Notch-filter denominator coefficient + A2, ///< \f$A_2\f$ Notch-filter denominator coefficient + A3, ///< \f$A_3\f$ Notch-filter denominator coefficient + A4, ///< \f$A_4\f$ Notch-filter denominator coefficient + A5, ///< \f$A_5\f$ Notch-filter numerator coefficient + A6, ///< \f$A_6\f$ Notch-filter numerator coefficient + T1, ///< \f$T_1\f$ Lead-lag 1 numerator time constant + T2, ///< \f$T_2\f$ Lead-lag 1 denominator time constant + T3, ///< \f$T_3\f$ Lead-lag 2 numerator time constant + T4, ///< \f$T_4\f$ Lead-lag 2 denominator time constant + T5, ///< \f$T_5\f$ Washout numerator time constant + T6, ///< \f$T_6\f$ Washout denominator time constant + Ks, ///< \f$K_s\f$ Stabilizer gain + Lsmin, ///< \f$L_s^{\min}\f$ Minimum stabilizer output limit + Lsmax, ///< \f$L_s^{\max}\f$ Maximum stabilizer output limit + Vcl, ///< \f$V_{\mathrm{cl}}\f$ Unsupported lower input-cutout threshold + Vcu, ///< \f$V_{\mathrm{cu}}\f$ Unsupported upper input-cutout threshold Tdelay, ///< \f$T_{\mathrm{delay}}\f$ Unsupported input delay }; @@ -67,7 +67,8 @@ namespace GridKit */ enum class IeeestMonitorableVariables : size_t { - vss, ///< \f$V_{\mathrm{ss}}\f$ Limited stabilizer signal and model output + vss, ///< \f$V_{\mathrm{ss}}\f$ Limited stabilizer signal and model + ///< output }; /** diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestDependencyTracking.cpp b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestDependencyTracking.cpp index 376b1fe210..484bebdaa9 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestDependencyTracking.cpp +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestDependencyTracking.cpp @@ -1,7 +1,8 @@ /** * @file IeeestDependencyTracking.cpp * @author Luke Lowery (lukel@tamu.edu) - * @brief DependencyTracking Jacobian stub and template instantiations for IEEEST Stabilizer. + * @brief DependencyTracking Jacobian stub and template instantiations for + * IEEEST Stabilizer. */ #include "IeeestImpl.hpp" diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestEnzyme.cpp b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestEnzyme.cpp index 309048f70e..b4e39b6c31 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestEnzyme.cpp @@ -27,8 +27,9 @@ namespace GridKit if (J_rows_buffer_ == nullptr) { // Reserve space for the dense blocks. - // The size of the buffer is the sum of maximum capacities of the blocks. - // Enzyme will compute the appropriate nnz from sparsification. + // The size of the buffer is the sum of maximum capacities of the + // blocks. Enzyme will compute the appropriate nnz from + // sparsification. auto size = static_cast(size_); auto signal_size = static_cast(ws_.getSize()); auto buffer_size = 2 * size * size + size * signal_size; diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp index a8b9dadd59..9a3ef65bfc 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp @@ -39,7 +39,9 @@ namespace GridKit } template - void Ieeest::initializeParameters(const ModelDataT& data) + void Ieeest::initializeParameters( + const ModelDataT& data + ) { using Parameter = typename ModelDataT::Parameters; @@ -70,16 +72,18 @@ namespace GridKit a3_ = A1_ * A4_ + A2_ * A3_; a4_ = A2_ * A4_; - // Precompute masks and safe inverse coefficients so the residual stays branch-free. - use_notch_ = static_cast(a2_ != 0.0 || a3_ != 0.0 || a4_ != 0.0); + // Precompute masks and safe inverse coefficients so the residual stays + // branch-free. + use_notch_ = static_cast(a2_ != 0.0 || a3_ != 0.0 || a4_ != 0.0); bypass_notch_ = 1.0 - use_notch_; use_4th_order_ = static_cast(a4_ != 0.0); use_3rd_order_ = static_cast(a4_ == 0.0 && a3_ != 0.0); - use_2nd_order_ = static_cast(a4_ == 0.0 && a3_ == 0.0 && a2_ != 0.0); - safe_inv_a4_ = use_4th_order_ / (a4_ + (1.0 - use_4th_order_)); - safe_inv_a3_ = use_3rd_order_ / (a3_ + (1.0 - use_3rd_order_)); - safe_inv_a2_ = use_2nd_order_ / (a2_ + (1.0 - use_2nd_order_)); + use_2nd_order_ = + static_cast(a4_ == 0.0 && a3_ == 0.0 && a2_ != 0.0); + safe_inv_a4_ = use_4th_order_ / (a4_ + (1.0 - use_4th_order_)); + safe_inv_a3_ = use_3rd_order_ / (a3_ + (1.0 - use_3rd_order_)); + safe_inv_a2_ = use_2nd_order_ / (a2_ + (1.0 - use_2nd_order_)); use_T2_block_ = static_cast(T2_ != 0.0); bypass_T2_block_ = 1.0 - use_T2_block_; @@ -92,7 +96,9 @@ namespace GridKit } template - int Ieeest::setGridKitComponentID(IdxT component_id) + int Ieeest::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -122,7 +128,8 @@ namespace GridKit ws_indices_.resize(1); ws_indices_[0] = INVALID_INDEX; - if (auto output_port = ports_.out.template port()) + if (auto output_port = + ports_.out.template port()) { output_port.link(&y_.getData()[11], &(this->getVariableIndex(11))); } @@ -159,12 +166,13 @@ namespace GridKit { if (!this->verifyAndLog()) { - Log::error() << "Ieeest: cannot initialize with invalid configuration\n"; + Log::error( + ) << "Ieeest: cannot initialize with invalid configuration\n"; return 1; } - auto input_port = ports_.in.template port(); - const ScalarT u = input_port.readSignal(); + auto input_port = ports_.in.template port(); + const ScalarT u = input_port.readSignal(); auto* y = y_.getData(); auto* yp = yp_.getData(); @@ -272,21 +280,30 @@ namespace GridKit ScalarT u = ws[0]; - const ScalarT x2_rhs = (use_4th_order_ + use_3rd_order_) * x3 - + use_2nd_order_ * (-a0_ * x1 - a1_ * x2 + u) * safe_inv_a2_; + const ScalarT x2_rhs = + (use_4th_order_ + use_3rd_order_) * x3 + + use_2nd_order_ * (-a0_ * x1 - a1_ * x2 + u) * safe_inv_a2_; f[0] = -x1_dot + use_notch_ * x2; f[1] = -x2_dot + x2_rhs; 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] = -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 + A6_ * x2_rhs); - 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); + + 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] = -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 + A6_ * x2_rhs); + 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; @@ -300,7 +317,8 @@ namespace GridKit int Ieeest::setSignalIndices() { ws_indices_[0] = INVALID_INDEX; - if (auto input_port = ports_.in.template port()) + if (auto input_port = + ports_.in.template port()) { ws_indices_[0] = input_port.signalVariableIndex(); } @@ -313,7 +331,8 @@ namespace GridKit { auto* ws = ws_.getData(); - if (auto input_port = ports_.in.template port()) + if (auto input_port = + ports_.in.template port()) { ws[0] = input_port.readSignal(); } @@ -328,7 +347,8 @@ namespace GridKit } template - const Model::VariableMonitorBase* Ieeest::getMonitor() const + const Model::VariableMonitorBase* Ieeest:: + getMonitor() const { return monitor_.get(); } @@ -337,8 +357,7 @@ namespace GridKit void Ieeest::initializeMonitor() { using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::vss, [this] - { return y_.getData()[11]; }); + monitor_->set(Variable::vss, [this] { return y_.getData()[11]; }); } } // namespace Stabilizer diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/Genrou.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/Genrou.hpp index 3458c90fd7..cd79a40f3b 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/Genrou.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/Genrou.hpp @@ -137,12 +137,10 @@ namespace GridKit } public: - __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* - ); - __attribute__((always_inline)) inline int evaluateBusResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* - ); + __attribute__((always_inline)) inline int + evaluateInternalResidual(const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + __attribute__((always_inline)) inline int + evaluateBusResidual(const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); private: /* Identification */ @@ -192,8 +190,10 @@ namespace GridKit RealT G_; RealT B_; /* Setpoints for control variables (determined at initialization) */ - ScalarT pmech_set_{0.0}; // TODO remove default initialization and ensure this gets set - ScalarT efd_set_{0.0}; // TODO remove default initialization and ensure this gets set + ScalarT pmech_set_{0.0 + }; // TODO remove default initialization and ensure this gets set + ScalarT efd_set_{0.0 + }; // TODO remove default initialization and ensure this gets set /// Variable monitor std::unique_ptr monitor_; diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouData.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouData.hpp index a8b8ef9627..d3a4179931 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouData.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouData.hpp @@ -70,8 +70,8 @@ namespace GridKit /// Initial values for a Genrou generator model enum class GenrouInitialValues : size_t { - ir, ///< Initial real terminal current into the bus on system base - ii, ///< Initial imaginary terminal current into the bus on system base + ir, ///< Initial real terminal current into the bus on system base + ii, ///< Initial imaginary terminal current into the bus on system base in_service, ///< Initial service status; defaults to true }; diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouEnzyme.cpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouEnzyme.cpp index a11cb9c778..03ea682ec7 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouEnzyme.cpp @@ -23,15 +23,16 @@ namespace GridKit if (J_rows_buffer_ == nullptr) { // Reserve space for the dense blocks. - // The size of the buffer is the sum of maximum capacities of the blocks. - // Enzyme will compute the appropriate nnz from sparsification. + // The size of the buffer is the sum of maximum capacities of the + // blocks. Enzyme will compute the appropriate nnz from sparsification. auto size = static_cast(size_); auto bus_size = static_cast(bus_->size()); auto signal_size = static_cast(ws_.getSize()); - auto buffer_size = 2 * size * size + size * signal_size + 2 * size * bus_size; - J_rows_buffer_ = new IdxT[buffer_size]; - J_cols_buffer_ = new IdxT[buffer_size]; - J_vals_buffer_ = new RealT[buffer_size]; + auto buffer_size = + 2 * size * size + size * signal_size + 2 * size * bus_size; + J_rows_buffer_ = new IdxT[buffer_size]; + J_cols_buffer_ = new IdxT[buffer_size]; + J_vals_buffer_ = new RealT[buffer_size]; } nnz_ = 0; diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouImpl.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouImpl.hpp index 3984de2f6b..924d9900a7 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouImpl.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/GenrouImpl.hpp @@ -36,10 +36,12 @@ namespace GridKit { } - /// Helper function to extract and assign model parameters from the model's associated - /// data structure. + /// Helper function to extract and assign model parameters from the model's + /// associated data structure. template - void Genrou::initializeParameters(const ModelDataT& data) + void Genrou::initializeParameters( + const ModelDataT& data + ) { using Parameter = typename ModelDataT::Parameters; using Buses = typename ModelDataT::Buses; @@ -73,7 +75,8 @@ namespace GridKit } template - const Model::VariableMonitorBase* Genrou::getMonitor() const + const Model::VariableMonitorBase* Genrou:: + getMonitor() const { return monitor_.get(); } @@ -83,27 +86,41 @@ namespace GridKit { using Variable = typename ModelDataT::MonitorableVariables; // Convert monitored terminal values to system base. - monitor_->set(Variable::ir, [this] - { return this->toSystemBase(y_.getData()[15]); }); - monitor_->set(Variable::ii, [this] - { return this->toSystemBase(y_.getData()[16]); }); - monitor_->set(Variable::p, [this] - { return this->toSystemBase(Vr() * y_.getData()[15] + Vi() * y_.getData()[16]); }); - monitor_->set(Variable::q, [this] - { return this->toSystemBase(Vi() * y_.getData()[15] - Vr() * y_.getData()[16]); }); - monitor_->set(Variable::delta, [this] - { return y_.getData()[0]; }); - monitor_->set(Variable::omega, [this] - { return y_.getData()[1]; }); - monitor_->set(Variable::speed, [this] - { return 1.0 + y_.getData()[1]; }); + monitor_->set( + Variable::ir, [this] { return this->toSystemBase(y_.getData()[15]); } + ); + monitor_->set( + Variable::ii, [this] { return this->toSystemBase(y_.getData()[16]); } + ); + monitor_->set( + Variable::p, + [this] + { + return this->toSystemBase( + Vr() * y_.getData()[15] + Vi() * y_.getData()[16] + ); + } + ); + monitor_->set( + Variable::q, + [this] + { + return this->toSystemBase( + Vi() * y_.getData()[15] - Vr() * y_.getData()[16] + ); + } + ); + monitor_->set(Variable::delta, [this] { return y_.getData()[0]; }); + monitor_->set(Variable::omega, [this] { return y_.getData()[1]; }); + monitor_->set(Variable::speed, [this] { return 1.0 + y_.getData()[1]; }); } /** * @brief Set the component ID */ template - int Genrou::setGridKitComponentID(IdxT component_id) + int Genrou::setGridKitComponentID(IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -142,7 +159,8 @@ namespace GridKit ws_indices_[1] = INVALID_INDEX; // Set output signals - if (auto speed_port = ports_.out.template port()) + if (auto speed_port = + ports_.out.template port()) { speed_port.link(&y_.getData()[1], &(this->getVariableIndex(1))); } @@ -204,9 +222,10 @@ namespace GridKit (vi + Ra_ * ii) * ksat_prime + xsat_delta * ir, (vr + Ra_ * ir) * ksat_prime - xsat_delta * ii ); - ScalarT id = ir * std::sin(delta) - ii * std::cos(delta); - ScalarT iq = ir * std::cos(delta) + ii * std::sin(delta); - ScalarT vq = vr * std::cos(delta) + vi * std::sin(delta) + id * Xqpp_ + iq * Ra_; + ScalarT id = ir * std::sin(delta) - ii * std::cos(delta); + ScalarT iq = ir * std::cos(delta) + ii * std::sin(delta); + ScalarT vq = + vr * std::cos(delta) + vi * std::sin(delta) + id * Xqpp_ + iq * Ra_; ScalarT Edp = (Xq1_ - Xqd_ * (Xqp_ - Xqpp_) * ksat) * iq / ksat_prime; ScalarT psiqp = Edp + Xq2_ * iq; ScalarT psidp = vq - (Xdpp_ - Xl_) * id; @@ -244,12 +263,15 @@ namespace GridKit // Convert Te to system base for governor PM signal. ScalarT Te = y[12]; pmech_set_ = static_cast(this->toSystemBase(Te)); - if (auto pmech_port = ports_.in.template port()) + if (auto pmech_port = + ports_.in.template port()) { pmech_port.writeValue(pmech_set_); } - efd_set_ = static_cast(Eqp + Xd1_ * (id + Xd3_ * (Eqp - psidp - Xd2_ * id)) + psidpp * ksat); + efd_set_ = static_cast( + Eqp + Xd1_ * (id + Xd3_ * (Eqp - psidp - Xd2_ * id)) + psidpp * ksat + ); if (auto efd_port = ports_.in.template port()) { efd_port.writeValue(efd_set_); @@ -357,11 +379,19 @@ namespace GridKit /* 6 Genrou differential equations */ f[0] = delta_dot - omega * (TWO * pi * freq_system_base_); - f[1] = omega_dot - (ONE / (TWO * H_)) * ((pmech - D_ * omega) / (ONE + omega) - telec); - f[2] = Eqp_dot - (ONE / Tdop_) * (efd - (Eqp + Xd1_ * (id + Xd3_ * (Eqp - psidp - Xd2_ * id)) + psidpp * ksat)); + f[1] = omega_dot + - (ONE / (TWO * H_)) + * ((pmech - D_ * omega) / (ONE + omega) - telec); + f[2] = + Eqp_dot + - (ONE / Tdop_) + * (efd - (Eqp + Xd1_ * (id + Xd3_ * (Eqp - psidp - Xd2_ * id)) + psidpp * ksat)); f[3] = psidp_dot - (ONE / Tdopp_) * (Eqp - psidp - Xd2_ * id); f[4] = psiqp_dot - (ONE / Tqopp_) * (Edp - psiqp + Xq2_ * iq); - f[5] = Edp_dot - (ONE / Tqop_) * (-Edp + Xqd_ * psiqpp * ksat + Xq1_ * (iq - Xq3_ * (Edp + iq * Xq2_ - psiqp))); + f[5] = + Edp_dot + - (ONE / Tqop_) + * (-Edp + Xqd_ * psiqpp * ksat + Xq1_ * (iq - Xq3_ * (Edp + iq * Xq2_ - psiqp))); /* 11 Genrou algebraic equations */ f[6] = psiqpp - (-psiqp * Xq4_ - Edp * Xq5_); @@ -373,8 +403,12 @@ namespace GridKit f[12] = telec - ((psidpp - id * Xdpp_) * iq - (psiqpp - iq * Xdpp_) * id); f[13] = id - (ir * std::sin(delta) - ii * std::cos(delta)); f[14] = iq - (ir * std::cos(delta) + ii * std::sin(delta)); - f[15] = ir - (G_ * (std::sin(delta) * vd + std::cos(delta) * vq - vr) - B_ * (-std::cos(delta) * vd + std::sin(delta) * vq - vi)); - f[16] = ii - (B_ * (std::sin(delta) * vd + std::cos(delta) * vq - vr) + G_ * (-std::cos(delta) * vd + std::sin(delta) * vq - vi)); + f[15] = + ir + - (G_ * (std::sin(delta) * vd + std::cos(delta) * vq - vr) - B_ * (-std::cos(delta) * vd + std::sin(delta) * vq - vi)); + f[16] = + ii + - (B_ * (std::sin(delta) * vd + std::cos(delta) * vq - vr) + G_ * (-std::cos(delta) * vd + std::sin(delta) * vq - vi)); return 0; } @@ -410,7 +444,8 @@ namespace GridKit int Genrou::setSignalIndices() { ws_indices_[0] = INVALID_INDEX; - if (auto pmech_port = ports_.in.template port()) + if (auto pmech_port = + ports_.in.template port()) { ws_indices_[0] = pmech_port.signalVariableIndex(); } @@ -435,7 +470,8 @@ namespace GridKit // Mechanical Power ws[0] = pmech_set_; - if (auto pmech_port = ports_.in.template port()) + if (auto pmech_port = + ports_.in.template port()) { ws[0] = pmech_port.readSignal(); } diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/Gensal.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/Gensal.hpp index 73d7fe980f..889dc60571 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/Gensal.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/Gensal.hpp @@ -133,12 +133,10 @@ namespace GridKit } public: - __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* - ); - __attribute__((always_inline)) inline int evaluateBusResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* - ); + __attribute__((always_inline)) inline int + evaluateInternalResidual(const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + __attribute__((always_inline)) inline int + evaluateBusResidual(const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); private: /* Identification */ @@ -179,8 +177,10 @@ namespace GridKit RealT G_; RealT B_; /* Setpoints for control variables (determined at initialization) */ - ScalarT pmech_set_{0.0}; // TODO remove default initialization and ensure this gets set - ScalarT efd_set_{0.0}; // TODO remove default initialization and ensure this gets set + ScalarT pmech_set_{0.0 + }; // TODO remove default initialization and ensure this gets set + ScalarT efd_set_{0.0 + }; // TODO remove default initialization and ensure this gets set /// Variable monitor std::unique_ptr monitor_; diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalData.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalData.hpp index f8d55827d5..5e17a42c06 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalData.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalData.hpp @@ -43,7 +43,8 @@ namespace GridKit enum class GensalSignalInputs : size_t { pmech, ///< \f$P_m\f$ Unique ID of the signal providing mechanical power - efd, ///< \f$E_{fd}\f$ Unique ID of the signal providing exciter field voltage + efd, ///< \f$E_{fd}\f$ Unique ID of the signal providing exciter field + ///< voltage }; /// Signal outputs for a Gensal generator model @@ -76,8 +77,10 @@ namespace GridKit /// Initial values for a Gensal generator model enum class GensalInitialValues : size_t { - ir, ///< \f$I_r\f$ Initial real terminal current into the bus on system base - ii, ///< \f$I_i\f$ Initial imaginary terminal current into the bus on system base + ir, ///< \f$I_r\f$ Initial real terminal current into the bus on system + ///< base + ii, ///< \f$I_i\f$ Initial imaginary terminal current into the bus on + ///< system base in_service, ///< Initial service status; defaults to true }; diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalEnzyme.cpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalEnzyme.cpp index 5364df000a..f0e81e8fd9 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalEnzyme.cpp @@ -23,15 +23,16 @@ namespace GridKit if (J_rows_buffer_ == nullptr) { // Reserve space for the dense blocks. - // The size of the buffer is the sum of maximum capacities of the blocks. - // Enzyme will compute the appropriate nnz from sparsification. + // The size of the buffer is the sum of maximum capacities of the + // blocks. Enzyme will compute the appropriate nnz from sparsification. auto size = static_cast(size_); auto bus_size = static_cast(bus_->size()); auto signal_size = static_cast(ws_.getSize()); - auto buffer_size = 2 * size * size + size * signal_size + 2 * size * bus_size; - J_rows_buffer_ = new IdxT[buffer_size]; - J_cols_buffer_ = new IdxT[buffer_size]; - J_vals_buffer_ = new RealT[buffer_size]; + auto buffer_size = + 2 * size * size + size * signal_size + 2 * size * bus_size; + J_rows_buffer_ = new IdxT[buffer_size]; + J_cols_buffer_ = new IdxT[buffer_size]; + J_vals_buffer_ = new RealT[buffer_size]; } nnz_ = 0; diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalImpl.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalImpl.hpp index 26a4c33282..239c1a592c 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalImpl.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/GensalImpl.hpp @@ -23,8 +23,7 @@ namespace GridKit */ template Gensal::Gensal(BusT* bus, const ModelDataT& data) - : bus_(bus), - monitor_(std::make_unique(data)) + : bus_(bus), monitor_(std::make_unique(data)) { initializeParameters(data); initializeMonitor(); @@ -38,10 +37,12 @@ namespace GridKit { } - /// Helper function to extract and assign model parameters from the model's associated - /// data structure. + /// Helper function to extract and assign model parameters from the model's + /// associated data structure. template - void Gensal::initializeParameters(const ModelDataT& data) + void Gensal::initializeParameters( + const ModelDataT& data + ) { using Parameter = typename ModelDataT::Parameters; @@ -66,7 +67,8 @@ namespace GridKit } template - const Model::VariableMonitorBase* Gensal::getMonitor() const + const Model::VariableMonitorBase* Gensal:: + getMonitor() const { return monitor_.get(); } @@ -76,45 +78,50 @@ namespace GridKit { using Variable = typename ModelDataT::MonitorableVariables; // Convert monitored terminal values to system base. - monitor_->set(Variable::ir, [this] - { return this->toSystemBase(y_.getData()[12]); }); - monitor_->set(Variable::ii, [this] - { return this->toSystemBase(y_.getData()[13]); }); - monitor_->set(Variable::p, [this] - { return this->toSystemBase(Vr() * y_.getData()[12] + Vi() * y_.getData()[13]); }); - monitor_->set(Variable::q, [this] - { return this->toSystemBase(Vi() * y_.getData()[12] - Vr() * y_.getData()[13]); }); - monitor_->set(Variable::delta, [this] - { return y_.getData()[0]; }); - monitor_->set(Variable::omega, [this] - { return y_.getData()[1]; }); - monitor_->set(Variable::speed, [this] - { return 1.0 + y_.getData()[1]; }); - monitor_->set(Variable::Eqp, [this] - { return y_.getData()[2]; }); - monitor_->set(Variable::psidp, [this] - { return y_.getData()[3]; }); - monitor_->set(Variable::psiqpp, [this] - { return y_.getData()[4]; }); - monitor_->set(Variable::psidpp, [this] - { return y_.getData()[5]; }); - monitor_->set(Variable::vd, [this] - { return y_.getData()[7]; }); - monitor_->set(Variable::vq, [this] - { return y_.getData()[8]; }); - monitor_->set(Variable::te, [this] - { return y_.getData()[9]; }); - monitor_->set(Variable::id, [this] - { return y_.getData()[10]; }); - monitor_->set(Variable::iq, [this] - { return y_.getData()[11]; }); + monitor_->set( + Variable::ir, [this] { return this->toSystemBase(y_.getData()[12]); } + ); + monitor_->set( + Variable::ii, [this] { return this->toSystemBase(y_.getData()[13]); } + ); + monitor_->set( + Variable::p, + [this] + { + return this->toSystemBase( + Vr() * y_.getData()[12] + Vi() * y_.getData()[13] + ); + } + ); + monitor_->set( + Variable::q, + [this] + { + return this->toSystemBase( + Vi() * y_.getData()[12] - Vr() * y_.getData()[13] + ); + } + ); + monitor_->set(Variable::delta, [this] { return y_.getData()[0]; }); + monitor_->set(Variable::omega, [this] { return y_.getData()[1]; }); + monitor_->set(Variable::speed, [this] { return 1.0 + y_.getData()[1]; }); + monitor_->set(Variable::Eqp, [this] { return y_.getData()[2]; }); + monitor_->set(Variable::psidp, [this] { return y_.getData()[3]; }); + monitor_->set(Variable::psiqpp, [this] { return y_.getData()[4]; }); + monitor_->set(Variable::psidpp, [this] { return y_.getData()[5]; }); + monitor_->set(Variable::vd, [this] { return y_.getData()[7]; }); + monitor_->set(Variable::vq, [this] { return y_.getData()[8]; }); + monitor_->set(Variable::te, [this] { return y_.getData()[9]; }); + monitor_->set(Variable::id, [this] { return y_.getData()[10]; }); + monitor_->set(Variable::iq, [this] { return y_.getData()[11]; }); } /** * @brief Set the component ID */ template - int Gensal::setGridKitComponentID(IdxT component_id) + int Gensal::setGridKitComponentID(IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -153,7 +160,8 @@ namespace GridKit ws_indices_[1] = INVALID_INDEX; // Set output signals - if (auto speed_port = ports_.out.template port()) + if (auto speed_port = + ports_.out.template port()) { speed_port.link(&y_.getData()[1], &(this->getVariableIndex(1))); } @@ -210,7 +218,8 @@ namespace GridKit ScalarT iq = ir * std::cos(delta) + ii * std::sin(delta); ScalarT psiqpp = -Xq2_ * iq; ScalarT vd = -psiqpp * (ONE + omega); - ScalarT vq = vr * std::cos(delta) + vi * std::sin(delta) + id * Xdpp_ + iq * Ra_; + ScalarT vq = + vr * std::cos(delta) + vi * std::sin(delta) + id * Xdpp_ + iq * Ra_; ScalarT psidpp = vq / (ONE + omega); ScalarT psidp = psidpp - (Xdpp_ - Xl_) * id; ScalarT Eqp = psidp + Xd2_ * id; @@ -237,12 +246,15 @@ namespace GridKit // Convert Te to system base for governor PM signal. pmech_set_ = static_cast(this->toSystemBase(Te)); - if (auto pmech_port = ports_.in.template port()) + if (auto pmech_port = + ports_.in.template port()) { pmech_port.writeValue(pmech_set_); } - efd_set_ = static_cast(Eqp + Xd1_ * (id + Xd3_ * (Eqp - psidp - Xd2_ * id)) + Eqp * ksat); + efd_set_ = static_cast( + Eqp + Xd1_ * (id + Xd3_ * (Eqp - psidp - Xd2_ * id)) + Eqp * ksat + ); if (auto efd_port = ports_.in.template port()) { efd_port.writeValue(efd_set_); @@ -346,8 +358,13 @@ namespace GridKit /* 5 Gensal differential equations */ f[0] = delta_dot - omega * (TWO * pi * freq_system_base_); - f[1] = omega_dot - (ONE / (TWO * H_)) * ((pmech - D_ * omega) / (ONE + omega) - telec); - f[2] = Eqp_dot - (ONE / Tdop_) * (efd - (Eqp + Xd1_ * (id + Xd3_ * (Eqp - psidp - Xd2_ * id)) + Eqp * ksat)); + f[1] = omega_dot + - (ONE / (TWO * H_)) + * ((pmech - D_ * omega) / (ONE + omega) - telec); + f[2] = + Eqp_dot + - (ONE / Tdop_) + * (efd - (Eqp + Xd1_ * (id + Xd3_ * (Eqp - psidp - Xd2_ * id)) + Eqp * ksat)); f[3] = psidp_dot - (ONE / Tdopp_) * (Eqp - psidp - Xd2_ * id); f[4] = psiqpp_dot - (ONE / Tqopp_) * (-psiqpp - Xq2_ * iq); @@ -359,8 +376,12 @@ namespace GridKit f[9] = telec - ((psidpp - id * Xdpp_) * iq - (psiqpp - iq * Xdpp_) * id); f[10] = id - (ir * std::sin(delta) - ii * std::cos(delta)); f[11] = iq - (ir * std::cos(delta) + ii * std::sin(delta)); - f[12] = ir - (G_ * (std::sin(delta) * vd + std::cos(delta) * vq - vr) - B_ * (-std::cos(delta) * vd + std::sin(delta) * vq - vi)); - f[13] = ii - (B_ * (std::sin(delta) * vd + std::cos(delta) * vq - vr) + G_ * (-std::cos(delta) * vd + std::sin(delta) * vq - vi)); + f[12] = + ir + - (G_ * (std::sin(delta) * vd + std::cos(delta) * vq - vr) - B_ * (-std::cos(delta) * vd + std::sin(delta) * vq - vi)); + f[13] = + ii + - (B_ * (std::sin(delta) * vd + std::cos(delta) * vq - vr) + G_ * (-std::cos(delta) * vd + std::sin(delta) * vq - vi)); return 0; } @@ -396,7 +417,8 @@ namespace GridKit int Gensal::setSignalIndices() { ws_indices_[0] = INVALID_INDEX; - if (auto pmech_port = ports_.in.template port()) + if (auto pmech_port = + ports_.in.template port()) { ws_indices_[0] = pmech_port.signalVariableIndex(); } @@ -421,7 +443,8 @@ namespace GridKit // Mechanical Power ws[0] = pmech_set_; - if (auto pmech_port = ports_.in.template port()) + if (auto pmech_port = + ports_.in.template port()) { ws[0] = pmech_port.readSignal(); } diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassical.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassical.hpp index 5072030e59..df14efb98e 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassical.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassical.hpp @@ -69,7 +69,7 @@ namespace GridKit using BusT = BusBase; using ModelDataT = GenClassicalData; using SignalPortsT = SignalPorts; - using MonitorT = Model::VariableMonitor; + using MonitorT = Model::VariableMonitor; public: GenClassical(BusT* bus, const ModelDataT& data); @@ -122,12 +122,10 @@ namespace GridKit } public: - __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* - ); - __attribute__((always_inline)) inline int evaluateBusResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT* - ); + __attribute__((always_inline)) inline int + evaluateInternalResidual(const ScalarT*, const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); + __attribute__((always_inline)) inline int + evaluateBusResidual(const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); private: /* Identification */ diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalData.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalData.hpp index 65b028171a..d9689cfbe1 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalData.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalData.hpp @@ -34,7 +34,8 @@ namespace GridKit enum class GenClassicalSignalInputs : size_t { pmech, ///< \f$P_m\f$ Unique ID of the signal providing mechanical power - efd, ///< \f$E_{fd}\f$ Unique ID of the signal providing exciter field voltage + efd, ///< \f$E_{fd}\f$ Unique ID of the signal providing exciter field + ///< voltage }; /// Signal outputs for a classical generator model @@ -58,8 +59,10 @@ namespace GridKit /// Initial values for a classical generator model enum class GenClassicalInitialValues : size_t { - ir, ///< \f$I_r\f$ Initial real terminal current into the bus on system base - ii, ///< \f$I_i\f$ Initial imaginary terminal current into the bus on system base + ir, ///< \f$I_r\f$ Initial real terminal current into the bus on system + ///< base + ii, ///< \f$I_i\f$ Initial imaginary terminal current into the bus on + ///< system base in_service, ///< Initial service status; defaults to true }; diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalEnzyme.cpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalEnzyme.cpp index 9ee609017c..48a3001cd6 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalEnzyme.cpp @@ -23,15 +23,16 @@ namespace GridKit if (J_rows_buffer_ == nullptr) { // Reserve space for the dense blocks. - // The size of the buffer is the sum of maximum capacities of the blocks. - // Enzyme will compute the appropriate nnz from sparsification. + // The size of the buffer is the sum of maximum capacities of the + // blocks. Enzyme will compute the appropriate nnz from sparsification. auto size = static_cast(size_); auto bus_size = static_cast(bus_->size()); auto signal_size = static_cast(ws_.getSize()); - auto buffer_size = 2 * size * size + size * signal_size + 2 * size * bus_size; - J_rows_buffer_ = new IdxT[buffer_size]; - J_cols_buffer_ = new IdxT[buffer_size]; - J_vals_buffer_ = new RealT[buffer_size]; + auto buffer_size = + 2 * size * size + size * signal_size + 2 * size * bus_size; + J_rows_buffer_ = new IdxT[buffer_size]; + J_cols_buffer_ = new IdxT[buffer_size]; + J_vals_buffer_ = new RealT[buffer_size]; } nnz_ = 0; diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalImpl.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalImpl.hpp index 523d0bef77..e6aec46c48 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalImpl.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassicalImpl.hpp @@ -27,9 +27,10 @@ namespace GridKit * @brief Constructor for a classical generator model */ template - GenClassical::GenClassical(BusT* bus, const ModelDataT& data) - : bus_(bus), - monitor_(std::make_unique(data)) + GenClassical::GenClassical( + BusT* bus, const ModelDataT& data + ) + : bus_(bus), monitor_(std::make_unique(data)) { initializeParameters(data); initializeMonitor(); @@ -45,7 +46,9 @@ namespace GridKit /// Read model parameters from the data structure template - void GenClassical::initializeParameters(const ModelDataT& data) + void GenClassical::initializeParameters( + const ModelDataT& data + ) { using Parameter = typename ModelDataT::Parameters; @@ -61,7 +64,8 @@ namespace GridKit } template - const Model::VariableMonitorBase* GenClassical::getMonitor() const + const Model::VariableMonitorBase* GenClassical:: + getMonitor() const { return monitor_.get(); } @@ -71,27 +75,42 @@ namespace GridKit { using Variable = typename ModelDataT::MonitorableVariables; // Convert monitored terminal values to system base. - monitor_->set(Variable::ir, [this] - { return this->toSystemBase(y_.getData()[3]); }); - monitor_->set(Variable::ii, [this] - { return this->toSystemBase(y_.getData()[4]); }); - monitor_->set(Variable::p, [this] - { return this->toSystemBase(Vr() * y_.getData()[3] + Vi() * y_.getData()[4]); }); - monitor_->set(Variable::q, [this] - { return this->toSystemBase(Vi() * y_.getData()[3] - Vr() * y_.getData()[4]); }); - monitor_->set(Variable::delta, [this] - { return y_.getData()[0]; }); - monitor_->set(Variable::omega, [this] - { return y_.getData()[1]; }); - monitor_->set(Variable::speed, [this] - { return 1.0 + y_.getData()[1]; }); + monitor_->set( + Variable::ir, [this] { return this->toSystemBase(y_.getData()[3]); } + ); + monitor_->set( + Variable::ii, [this] { return this->toSystemBase(y_.getData()[4]); } + ); + monitor_->set( + Variable::p, + [this] + { + return this->toSystemBase( + Vr() * y_.getData()[3] + Vi() * y_.getData()[4] + ); + } + ); + monitor_->set( + Variable::q, + [this] + { + return this->toSystemBase( + Vi() * y_.getData()[3] - Vr() * y_.getData()[4] + ); + } + ); + monitor_->set(Variable::delta, [this] { return y_.getData()[0]; }); + monitor_->set(Variable::omega, [this] { return y_.getData()[1]; }); + monitor_->set(Variable::speed, [this] { return 1.0 + y_.getData()[1]; }); } /** * @brief Set the component ID */ template - int GenClassical::setGridKitComponentID(IdxT component_id) + int GenClassical::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -130,7 +149,8 @@ namespace GridKit ws_indices_[1] = INVALID_INDEX; // Set output signals - if (auto speed_port = ports_.out.template port()) + if (auto speed_port = + ports_.out.template port()) { speed_port.link(&y_.getData()[1], &(this->getVariableIndex(1))); } @@ -143,11 +163,13 @@ namespace GridKit * @brief verify method checks that attached signals are also linked */ template - Model::ConfigurationChecks GenClassical::verify() const + Model::ConfigurationChecks GenClassical::verify( + ) const { Model::ConfigurationChecks checks("GenClassical"); - auto pmech_port = ports_.in.template port(); + auto pmech_port = + ports_.in.template port(); if (pmech_port.connected() && !pmech_port.linked()) { checks.fail("pmech signal attached with no linked governor"); @@ -183,7 +205,10 @@ namespace GridKit ScalarT omega = static_cast(0.0); ScalarT efd = std::sqrt(Er * Er + Ei * Ei); - ScalarT Te = G_ * efd * efd - efd * ((G_ * vr - B_ * vi) * std::cos(delta) + (B_ * vr + G_ * vi) * std::sin(delta)); + ScalarT Te = + G_ * efd * efd + - efd + * ((G_ * vr - B_ * vi) * std::cos(delta) + (B_ * vr + G_ * vi) * std::sin(delta)); auto* y = y_.getData(); auto* yp = yp_.getData(); @@ -196,13 +221,15 @@ namespace GridKit // Convert Te to system base for governor PM signal. pmech_set_ = static_cast(this->toSystemBase(Te)); - if (auto pmech_port = ports_.in.template port()) + if (auto pmech_port = + ports_.in.template port()) { pmech_port.writeValue(pmech_set_); } efd_set_ = static_cast(efd); - if (auto efd_port = ports_.in.template port()) + if (auto efd_port = + ports_.in.template port()) { efd_port.writeValue(efd_set_); } @@ -250,7 +277,9 @@ namespace GridKit * error cannot be used. */ template - int GenClassical::setAbsoluteTolerance(RealT rel_tol) + int GenClassical::setAbsoluteTolerance( + RealT rel_tol + ) { abs_tol_.setToConst(static_cast(rel_tol)); return 0; @@ -293,12 +322,20 @@ namespace GridKit // GenClassical differential equations f[0] = delta_dot - omega * (TWO * pi * freq_system_base_); - f[1] = omega_dot - (ONE / (TWO * H_)) * ((pmech - D_ * omega) / (ONE + omega) - telec); + f[1] = omega_dot + - (ONE / (TWO * H_)) + * ((pmech - D_ * omega) / (ONE + omega) - telec); // GenClassical algebraic equations - f[2] = telec - (G_ * efd * efd - efd * ((G_ * vr - B_ * vi) * std::cos(delta) + (B_ * vr + G_ * vi) * std::sin(delta))); - f[3] = ir - (efd * (G_ * std::cos(delta) - B_ * std::sin(delta)) - G_ * vr + B_ * vi); - f[4] = ii - (efd * (B_ * std::cos(delta) + G_ * std::sin(delta)) - B_ * vr - G_ * vi); + f[2] = + telec + - (G_ * efd * efd - efd * ((G_ * vr - B_ * vi) * std::cos(delta) + (B_ * vr + G_ * vi) * std::sin(delta))); + f[3] = + ir + - (efd * (G_ * std::cos(delta) - B_ * std::sin(delta)) - G_ * vr + B_ * vi); + f[4] = + ii + - (efd * (B_ * std::cos(delta) + G_ * std::sin(delta)) - B_ * vr - G_ * vi); return 0; } @@ -332,13 +369,15 @@ namespace GridKit int GenClassical::setSignalIndices() { ws_indices_[0] = INVALID_INDEX; - if (auto pmech_port = ports_.in.template port()) + if (auto pmech_port = + ports_.in.template port()) { ws_indices_[0] = pmech_port.signalVariableIndex(); } ws_indices_[1] = INVALID_INDEX; - if (auto efd_port = ports_.in.template port()) + if (auto efd_port = + ports_.in.template port()) { ws_indices_[1] = efd_port.signalVariableIndex(); } @@ -356,13 +395,15 @@ namespace GridKit auto* ws = ws_.getData(); ws[0] = pmech_set_; - if (auto pmech_port = ports_.in.template port()) + if (auto pmech_port = + ports_.in.template port()) { ws[0] = pmech_port.readSignal(); } ws[1] = efd_set_; - if (auto efd_port = ports_.in.template port()) + if (auto efd_port = + ports_.in.template port()) { ws[1] = efd_port.readSignal(); } diff --git a/GridKit/Model/PhasorDynamics/SystemModel.hpp b/GridKit/Model/PhasorDynamics/SystemModel.hpp index d2e38582c2..30493a75e8 100644 --- a/GridKit/Model/PhasorDynamics/SystemModel.hpp +++ b/GridKit/Model/PhasorDynamics/SystemModel.hpp @@ -68,12 +68,12 @@ namespace GridKit using Component::allocated_; private: - using ScalarT = scalar_type; - using IdxT = index_type; - using RealT = typename Model::Evaluator::RealT; - using CsrMatrixT = typename Model::Evaluator::CsrMatrixT; - using CooMatrixT = typename Model::Evaluator::CooMatrixT; - using BusT = BusBase; + using ScalarT = scalar_type; + using IdxT = index_type; + using RealT = typename Model::Evaluator::RealT; + using CsrMatrixT = typename Model::Evaluator::CsrMatrixT; + using CooMatrixT = typename Model::Evaluator::CooMatrixT; + using BusT = BusBase; using SignalNodeSetT = SignalNodeSet; using SignalNodeT = SignalNodeSetT::SignalNodeT; using ComponentT = Component; @@ -149,17 +149,22 @@ namespace GridKit std::vector components_; std::vector subsystems_; - /// Component labels (device class and case-file ID), by gridkit_component_id + /// Component labels (device class and case-file ID), by + /// gridkit_component_id std::vector component_labels_; /// Map between component label and gridkit_component_id std::map gridkit_component_indices_; - std::map gridkit_bus_indices_; ///< Map between gridkit_bus_id and bus_id - std::map external_buses_; ///< Parent's buses by bus_id, not owned - std::vector ordered_external_buses_; ///< External buses in construction order, not owned + std::map + gridkit_bus_indices_; ///< Map between gridkit_bus_id and bus_id + std::map + external_buses_; ///< Parent's buses by bus_id, not owned + std::vector + ordered_external_buses_; ///< External buses in construction order, not + ///< owned - IdxT offset_{0}; ///< Global index of this system's first variable + IdxT offset_{0}; ///< Global index of this system's first variable bool is_subsystem_{false}; ///< Allocated and bound by a parent system bool owns_components_{false}; diff --git a/GridKit/Model/PhasorDynamics/SystemModelData.cpp b/GridKit/Model/PhasorDynamics/SystemModelData.cpp index 0dcada8a8f..4f41f09128 100644 --- a/GridKit/Model/PhasorDynamics/SystemModelData.cpp +++ b/GridKit/Model/PhasorDynamics/SystemModelData.cpp @@ -20,7 +20,9 @@ namespace GridKit return data; } - SystemModelData parseSystemModelData(const std::filesystem::path& filePath) + SystemModelData parseSystemModelData( + const std::filesystem::path& filePath + ) { auto stream = std::ifstream(filePath); if (!stream) diff --git a/GridKit/Model/PhasorDynamics/SystemModelData.hpp b/GridKit/Model/PhasorDynamics/SystemModelData.hpp index 49a6e9dc01..e16dc1360f 100644 --- a/GridKit/Model/PhasorDynamics/SystemModelData.hpp +++ b/GridKit/Model/PhasorDynamics/SystemModelData.hpp @@ -100,27 +100,34 @@ namespace GridKit /// consolidate components in a single container. /// - Convert string to enum /// - Associate component type to its corresponding enum - /// - Consolidate components to allow writing to them using the enum as the argument - std::vector bus; ///< Buses within the model - std::vector branch; ///< Branches within the model - std::vector regca; ///< REGCA converter instances within the model - std::vector reecb; ///< REECB electrical controllers within the model - std::vector repca; ///< REPCA plant controllers within the model - std::vector genrou; ///< GENROU instances within the model - std::vector gensal; ///< GENSAL instances within the model - std::vector genclassical; ///< Classical generator instances within the model - std::vector loadz; ///< LoadZ instances within the model - std::vector loadzip; ///< LoadZIP instances within the model - std::vector gov; ///< Governors within the model - std::vector esdc1a; ///< ESDC1A exciters within the model - std::vector gastpti; ///< GASTPTI governors within the model - std::vector hygov; ///< HYGOV governors within the model - std::vector exciter; ///< Exciters within the model - std::vector sexspti; ///< SEXS-PTI exciters within the model - std::vector stabilizer; ///< Stabilizers within the model - std::vector constant_source; ///< Constant signal sources within the model - std::vector function_source; ///< Function signal sources within the model - std::vector signal; ///< Signal nodes + /// - Consolidate components to allow writing to them using the enum as + /// the argument + std::vector bus; ///< Buses within the model + std::vector branch; ///< Branches within the model + std::vector + regca; ///< REGCA converter instances within the model + std::vector + reecb; ///< REECB electrical controllers within the model + std::vector + repca; ///< REPCA plant controllers within the model + std::vector genrou; ///< GENROU instances within the model + std::vector gensal; ///< GENSAL instances within the model + std::vector + genclassical; ///< Classical generator instances within the model + std::vector loadz; ///< LoadZ instances within the model + std::vector loadzip; ///< LoadZIP instances within the model + std::vector gov; ///< Governors within the model + std::vector esdc1a; ///< ESDC1A exciters within the model + std::vector gastpti; ///< GASTPTI governors within the model + std::vector hygov; ///< HYGOV governors within the model + std::vector exciter; ///< Exciters within the model + std::vector sexspti; ///< SEXS-PTI exciters within the model + std::vector stabilizer; ///< Stabilizers within the model + std::vector + constant_source; ///< Constant signal sources within the model + std::vector + function_source; ///< Function signal sources within the model + std::vector signal; ///< Signal nodes /// Monitor sink specs std::vector monitor_sink; @@ -128,7 +135,8 @@ namespace GridKit /// Subsystem ID, unique in the hierarchy; empty for the top system std::string id; - /// Hierarchy level: 0 for the top system, parent level + 1 for a subsystem + /// Hierarchy level: 0 for the top system, parent level + 1 for a + /// subsystem IdxT level{0}; /// Hierarchical subsystems; devices may use buses of this system and @@ -141,6 +149,8 @@ namespace GridKit */ SystemModelData parseSystemModelData(std::istream& stream); SystemModelData parseSystemModelData(std::istream&& stream); - SystemModelData parseSystemModelData(const std::filesystem::path& filePath); + SystemModelData parseSystemModelData( + const std::filesystem::path& filePath + ); } // namespace PhasorDynamics } // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/SystemModelDataJSONParser.hpp b/GridKit/Model/PhasorDynamics/SystemModelDataJSONParser.hpp index 05f32463ca..e1ef6a4062 100644 --- a/GridKit/Model/PhasorDynamics/SystemModelDataJSONParser.hpp +++ b/GridKit/Model/PhasorDynamics/SystemModelDataJSONParser.hpp @@ -25,7 +25,8 @@ namespace GridKit /// JSON parser function implementation for the `SystemModelData` type /// - /// See the `README.md` in `GridKit/Model/PhasorDynamics` for more information + /// See the `README.md` in `GridKit/Model/PhasorDynamics` for more + /// information template void from_json(const json& j, SystemModelData& sm) { @@ -123,7 +124,8 @@ namespace GridKit } else if (kind == "GenClassical") { - typename SystemModelData::GenClassicalDataT gen_classical; + typename SystemModelData::GenClassicalDataT + gen_classical; raw_component.get_to(gen_classical); sm.genclassical.push_back(gen_classical); } @@ -225,7 +227,8 @@ namespace GridKit { if (!j.at("subsystems").empty() && !j.at("devices").empty()) { - Log::error() << "\n\tA system with subsystems may only contain buses and subsystems; " + Log::error() << "\n\tA system with subsystems may only contain buses " + "and subsystems; " << "move its devices into a subsystem.\n"; throw std::runtime_error("JSON parser failed"); } @@ -237,7 +240,8 @@ namespace GridKit subsystem.va_base = sm.va_base; subsystem.level = sm.level + 1; - if (!raw_subsystem.contains("id") || !raw_subsystem.at("id").is_string()) + if (!raw_subsystem.contains("id") + || !raw_subsystem.at("id").is_string()) { Log::error() << "\n\tEach subsystem requires a string \"id\".\n"; throw std::runtime_error("JSON parser failed"); @@ -247,10 +251,12 @@ namespace GridKit // The level is redundant here; it allows a flat layout later. if (!raw_subsystem.contains("level") || !raw_subsystem.at("level").is_number_integer() - || raw_subsystem.at("level").get() != static_cast(subsystem.level)) + || raw_subsystem.at("level").get() + != static_cast(subsystem.level)) { - Log::error() << "\n\tSubsystem \"" << subsystem.id << "\" requires \"level\": " - << subsystem.level << " (parent level + 1).\n"; + Log::error() << "\n\tSubsystem \"" << subsystem.id + << "\" requires \"level\": " << subsystem.level + << " (parent level + 1).\n"; throw std::runtime_error("JSON parser failed"); } diff --git a/GridKit/Model/PhasorDynamics/SystemModelDependencyTracking.cpp b/GridKit/Model/PhasorDynamics/SystemModelDependencyTracking.cpp index e4d3430550..65ceefaa83 100644 --- a/GridKit/Model/PhasorDynamics/SystemModelDependencyTracking.cpp +++ b/GridKit/Model/PhasorDynamics/SystemModelDependencyTracking.cpp @@ -11,8 +11,10 @@ namespace GridKit template bool SystemModel::hasJacobian() { - Log::warning() << "DependencyTracking::Variable Jacobians are only available for testing.\n" - << "Falling back to dense Jacobians for PhasorDyanmics simulations.\n"; + Log::warning( + ) << "DependencyTracking::Variable Jacobians are only available for " + "testing.\n" + << "Falling back to dense Jacobians for PhasorDyanmics simulations.\n"; return false; } diff --git a/GridKit/Model/PhasorDynamics/SystemModelEnzyme.cpp b/GridKit/Model/PhasorDynamics/SystemModelEnzyme.cpp index fe752d73cb..7ed6a3f7d6 100644 --- a/GridKit/Model/PhasorDynamics/SystemModelEnzyme.cpp +++ b/GridKit/Model/PhasorDynamics/SystemModelEnzyme.cpp @@ -31,9 +31,10 @@ namespace GridKit if (!has_jacobian && !is_subsystem_) { - Log::warning() << "GridKit was built with Enzyme, but some models " - "don't have Jacobians available. " - "Falling back to dense Jacobians in PhasorDynamics.\n"; + Log::warning( + ) << "GridKit was built with Enzyme, but some models " + "don't have Jacobians available. " + "Falling back to dense Jacobians in PhasorDynamics.\n"; } return has_jacobian; @@ -52,7 +53,8 @@ namespace GridKit bus->evaluateJacobian(); } - // Evaluate component Jacobians, including contribution to the bus Jacobians + // Evaluate component Jacobians, including contribution to the bus + // Jacobians for (const auto& component : components_) { component->evaluateJacobian(); @@ -67,10 +69,13 @@ namespace GridKit /** * @brief Evaluate system Jacobian using component-level Jacobians. * - * - Evaluate component-level Jacobians (stored as CooMatrixT), including subsystems'. + * - Evaluate component-level Jacobians (stored as CooMatrixT), including + * subsystems'. * - If not already constructed, construct system-level Jacobian. - * This used a system-level CooMatrix to deduplicate and sort the sparsity pattern. - * - If already constructed, reset Jacobian values to zero and accumulate contributions. + * This used a system-level CooMatrix to deduplicate and sort the sparsity + * pattern. + * - If already constructed, reset Jacobian values to zero and accumulate + * contributions. * * A subsystem assembles its Jacobian in global indices. Its external buses * precede its own variables, so the Jacobian size is offset() + size(). @@ -97,7 +102,11 @@ namespace GridKit for (size_t k = 0; k < systems.size(); ++k) { SystemModel* system = systems[k]; - systems.insert(systems.end(), system->subsystems_.begin(), system->subsystems_.end()); + systems.insert( + systems.end(), + system->subsystems_.begin(), + system->subsystems_.end() + ); for (const auto& component : system->components_) { @@ -109,7 +118,8 @@ namespace GridKit } else { - Log::warning() << "A component has returned a nullptr Jacobian.\n"; + Log::warning() + << "A component has returned a nullptr Jacobian.\n"; } } @@ -128,7 +138,8 @@ namespace GridKit } } - // Allocate COO triplet arrays (we own these until we hand off to CsrMatrix) + // Allocate COO triplet arrays (we own these until we hand off to + // CsrMatrix) IdxT* rows_dup = new IdxT[static_cast(nnz_dup)]; IdxT* cols_dup = new IdxT[static_cast(nnz_dup)]; RealT* vals_dup = new RealT[static_cast(nnz_dup)]; @@ -139,7 +150,11 @@ namespace GridKit for (size_t k = 0; k < systems.size(); ++k) { SystemModel* system = systems[k]; - systems.insert(systems.end(), system->subsystems_.begin(), system->subsystems_.end()); + systems.insert( + systems.end(), + system->subsystems_.begin(), + system->subsystems_.end() + ); for (const auto& component : system->components_) { @@ -160,7 +175,8 @@ namespace GridKit } else { - Log::warning() << "A component has returned a nullptr Jacobian.\n"; + Log::warning() + << "A component has returned a nullptr Jacobian.\n"; } } @@ -234,7 +250,11 @@ namespace GridKit for (size_t k = 0; k < systems.size(); ++k) { SystemModel* system = systems[k]; - systems.insert(systems.end(), system->subsystems_.begin(), system->subsystems_.end()); + systems.insert( + systems.end(), + system->subsystems_.begin(), + system->subsystems_.end() + ); for (const auto& component : system->components_) { diff --git a/GridKit/Model/PhasorDynamics/SystemModelImpl.hpp b/GridKit/Model/PhasorDynamics/SystemModelImpl.hpp index c1141746d2..055361b274 100644 --- a/GridKit/Model/PhasorDynamics/SystemModelImpl.hpp +++ b/GridKit/Model/PhasorDynamics/SystemModelImpl.hpp @@ -39,13 +39,16 @@ namespace GridKit * subsystems, are created, and correctly connected into the system model. */ template - SystemModel::SystemModel(const SystemModelData& data) + SystemModel::SystemModel( + const SystemModelData& data + ) : SystemModel(data, {}) { } /** - * @brief Construct a subsystem connected to its parent's buses (external buses) + * @brief Construct a subsystem connected to its parent's buses (external + * buses) * * @param[in] data - Subsystem data with the buses it owns * @param[in] external_buses - Parent's buses that subsystem devices may @@ -79,7 +82,8 @@ namespace GridKit // Add electrical buses for (const auto& busdata : data.bus) { - BusBase* bus = BusFactory::create(busdata, signal_nodes_); + BusBase* bus = + BusFactory::create(busdata, signal_nodes_); addBus(bus); } @@ -258,7 +262,8 @@ namespace GridKit bus_index = excitedata.buses.at(Ieeet1Buses::bus); } - auto* exciter = new Ieeet1(getBus(bus_index), excitedata); + auto* exciter = + new Ieeet1(getBus(bus_index), excitedata); addComponent(exciter, excitedata.label()); exciter->getPorts().connect(excitedata, signal_nodes_); @@ -286,7 +291,8 @@ namespace GridKit bus_index = excitedata.buses.at(SexsPtiBuses::bus); } - auto* exciter = new SexsPti(getBus(bus_index), excitedata); + auto* exciter = + new SexsPti(getBus(bus_index), excitedata); addComponent(exciter, excitedata.label()); exciter->getPorts().connect(excitedata, signal_nodes_); @@ -325,14 +331,16 @@ namespace GridKit } // Add subsystems; they may use this system's buses and its external - // buses. Added after devices, so devices above cannot use subsystem buses. + // buses. Added after devices, so devices above cannot use subsystem + // buses. if (!data.subsystems.empty()) { std::vector visible_buses(external_buses); visible_buses.insert(visible_buses.end(), buses_.begin(), buses_.end()); for (const auto& subsystem_data : data.subsystems) { - auto subsystem = std::make_unique(subsystem_data, visible_buses); + auto subsystem = + std::make_unique(subsystem_data, visible_buses); addSubsystem(subsystem.get()); subsystem.release(); } @@ -379,7 +387,9 @@ namespace GridKit * @note Should default to 0. */ template - int SystemModel::setGridKitComponentID(IdxT component_id) + int SystemModel::setGridKitComponentID( + IdxT component_id + ) { gridkit_component_id_ = component_id; return 0; @@ -412,7 +422,8 @@ namespace GridKit // Allocate global vectors if (!allocated_) { - // Topology changes invalidate the Jacobian sparsity pattern and COO-to-CSR map. + // Topology changes invalidate the Jacobian sparsity pattern and + // COO-to-CSR map. delete csr_jac_; csr_jac_ = nullptr; @@ -423,12 +434,11 @@ namespace GridKit this->allocateVectors(size_); } - if (y_.getSize() != size_ - || yp_.getSize() != size_ - || f_.getSize() != size_ - || abs_tol_.getSize() != size_) + if (y_.getSize() != size_ || yp_.getSize() != size_ + || f_.getSize() != size_ || abs_tol_.getSize() != size_) { - Log::error() << "SystemModel vector sizes do not match the system size\n"; + Log::error( + ) << "SystemModel vector sizes do not match the system size\n"; throw std::runtime_error("SystemModel allocation failed"); } @@ -440,15 +450,16 @@ namespace GridKit throw std::runtime_error("SystemModel allocation failed"); } - // Signal input indices need all variable indices and a verified configuration + // Signal input indices need all variable indices and a verified + // configuration if (this->setSignalIndices() != 0) { throw std::runtime_error("SystemModel allocation failed"); } - // Sparse-pattern discovery requires an initialized operating point. A failed - // initialization aborts allocation before residual/Jacobian evaluation or - // monitor startup. + // Sparse-pattern discovery requires an initialized operating point. A + // failed initialization aborts allocation before residual/Jacobian + // evaluation or monitor startup. // @todo Replace with a sparsity analysis that sets the NNZ and allocates // the Jacobian without needing the Jacobian values. if (hasJacobian()) @@ -475,8 +486,9 @@ namespace GridKit * @brief Set and return the size of this system, including subsystems */ template - typename SystemModel::IdxT - SystemModel::computeSize() + typename SystemModel::IdxT SystemModel< + scalar_type, + index_type>::computeSize() { size_ = 0; @@ -561,7 +573,8 @@ namespace GridKit const int bind_status = component->bind(y_, yp_, f_, abs_tol_, offset); if (bind_status != 0) { - Log::error() << "Failed to bind component vectors to system storage\n"; + Log::error( + ) << "Failed to bind component vectors to system storage\n"; throw std::runtime_error("SystemModel allocation failed"); } @@ -585,7 +598,8 @@ namespace GridKit const int bind_status = subsystem->bind(y_, yp_, f_, abs_tol_, offset); if (bind_status != 0) { - Log::error() << "Failed to bind subsystem vectors to system storage\n"; + Log::error( + ) << "Failed to bind subsystem vectors to system storage\n"; throw std::runtime_error("SystemModel allocation failed"); } @@ -608,7 +622,8 @@ namespace GridKit * the component ID. passed() is true when all is well. */ template - Model::ConfigurationChecks SystemModel::verify() const + Model::ConfigurationChecks SystemModel::verify( + ) const { Model::ConfigurationChecks checks; @@ -618,7 +633,9 @@ namespace GridKit const auto component_checks = component->verify(); for (const auto& error : component_checks.errors()) { - checks.fail(std::format("component {}: {}", component->getGridKitComponentID(), error)); + checks.fail(std::format( + "component {}: {}", component->getGridKitComponentID(), error + )); } } @@ -627,7 +644,9 @@ namespace GridKit const auto subsystem_checks = subsystem->verify(); for (const auto& error : subsystem_checks.errors()) { - checks.fail(std::format("subsystem {}: {}", subsystem->getGridKitComponentID(), error)); + checks.fail(std::format( + "subsystem {}: {}", subsystem->getGridKitComponentID(), error + )); } } @@ -686,8 +705,8 @@ namespace GridKit * * @todo Implement writing to system vectors in a thread-safe way. * - * @note Currently assuming each component stores variables contiguously in memory and - * that these are simply concatenated in the global system. + * @note Currently assuming each component stores variables contiguously in + * memory and that these are simply concatenated in the global system. */ template int SystemModel::initialize() @@ -738,7 +757,8 @@ namespace GridKit * @brief Add monitors from buses, components and subsystems to `monitor` */ template - void SystemModel::addMonitorsTo(MonitorT& monitor) const + void SystemModel::addMonitorsTo(MonitorT& monitor + ) const { for (const auto* bus : buses_) { @@ -840,7 +860,8 @@ namespace GridKit * error cannot be used. */ template - int SystemModel::setAbsoluteTolerance(RealT rel_tol) + int SystemModel::setAbsoluteTolerance(RealT rel_tol + ) { for (const auto& bus : buses_) { @@ -922,7 +943,8 @@ namespace GridKit /** * @brief Add bus * - * Add bus at the end of the bus array and map bus ID with GridKit's ID for the bus + * Add bus at the end of the bus array and map bus ID with GridKit's ID for + * the bus * */ template @@ -937,16 +959,19 @@ namespace GridKit /** * @brief Add component * - * Add component at the end of the components array and set GridKit's component ID + * Add component at the end of the components array and set GridKit's + * component ID * * @param[in] component - Component to add - * @param[in] label - ComponentData::label() of the device (e.g. "Genrou_1"), - * or empty for components without case-file data + * @param[in] label - ComponentData::label() of the device (e.g. + * "Genrou_1"), or empty for components without case-file data * * @pre This system has no subsystems. */ template - void SystemModel::addComponent(ComponentT* component, const std::string& label) + void SystemModel::addComponent( + ComponentT* component, const std::string& label + ) { if (!subsystems_.empty()) { @@ -973,7 +998,9 @@ namespace GridKit * has the same system bases. This system has no devices. */ template - void SystemModel::addSubsystem(SystemModel* subsystem) + void SystemModel::addSubsystem( + SystemModel* subsystem + ) { if (subsystem == nullptr || subsystem == this || subsystem->is_subsystem_) { @@ -1030,8 +1057,9 @@ namespace GridKit * */ template - SystemModel::BusT* - SystemModel::getBus(IdxT bus_id) + SystemModel::BusT* SystemModel< + scalar_type, + index_type>::getBus(IdxT bus_id) { BusT* bus = findBus(bus_id); if (bus == nullptr && external_buses_.contains(bus_id)) @@ -1051,8 +1079,9 @@ namespace GridKit * nullptr if there is none */ template - SystemModel::BusT* - SystemModel::findBus(IdxT bus_id) + SystemModel::BusT* SystemModel< + scalar_type, + index_type>::findBus(IdxT bus_id) { BusT* bus = nullptr; const auto it = gridkit_bus_indices_.find(bus_id); @@ -1062,7 +1091,8 @@ namespace GridKit assert(bus->busID() == bus_id); } - for (IdxT subsystem = 0; bus == nullptr && subsystem < numSubsystems(); ++subsystem) + for (IdxT subsystem = 0; bus == nullptr && subsystem < numSubsystems(); + ++subsystem) { bus = subsystems_[subsystem]->findBus(bus_id); } @@ -1070,8 +1100,9 @@ namespace GridKit } template - typename SystemModel::IdxT - SystemModel::numComponents() const + typename SystemModel::IdxT SystemModel< + scalar_type, + index_type>::numComponents() const { return static_cast(components_.size()); } @@ -1081,22 +1112,24 @@ namespace GridKit * this system, empty if it has none */ template - const std::string& - SystemModel::getComponentLabel(IdxT gridkit_component_id) const + const std::string& SystemModel::getComponentLabel( + IdxT gridkit_component_id + ) const { return component_labels_.at(gridkit_component_id); } template - typename SystemModel::IdxT - SystemModel::numSubsystems() const + typename SystemModel::IdxT SystemModel< + scalar_type, + index_type>::numSubsystems() const { return static_cast(subsystems_.size()); } template - SystemModel* - SystemModel::getSubsystem(IdxT index) + SystemModel* SystemModel:: + getSubsystem(IdxT index) { return subsystems_.at(index); } @@ -1105,8 +1138,9 @@ namespace GridKit * @brief Global index of this system's first variable and residual */ template - typename SystemModel::IdxT - SystemModel::offset() const + typename SystemModel::IdxT SystemModel< + scalar_type, + index_type>::offset() const { return offset_; } @@ -1126,8 +1160,9 @@ namespace GridKit * */ template - SystemModel::SignalNodeT* - SystemModel::getSignalNode(IdxT signal_id) + SystemModel::SignalNodeT* SystemModel< + scalar_type, + index_type>::getSignalNode(IdxT signal_id) { SignalNodeT* node = findSignalNode(signal_id); if (node == nullptr) @@ -1143,11 +1178,13 @@ namespace GridKit * nullptr if there is none */ template - SystemModel::SignalNodeT* - SystemModel::findSignalNode(IdxT signal_id) + SystemModel::SignalNodeT* SystemModel< + scalar_type, + index_type>::findSignalNode(IdxT signal_id) { SignalNodeT* node = signal_nodes_.find(signal_id); - for (IdxT subsystem = 0; node == nullptr && subsystem < numSubsystems(); ++subsystem) + for (IdxT subsystem = 0; node == nullptr && subsystem < numSubsystems(); + ++subsystem) { node = subsystems_[subsystem]->findSignalNode(signal_id); } @@ -1159,10 +1196,12 @@ namespace GridKit * */ template - SystemModel::ComponentT* - SystemModel::getComponent(IdxT gridkit_component_id) + SystemModel::ComponentT* SystemModel< + scalar_type, + index_type>::getComponent(IdxT gridkit_component_id) { - // gridkit_component_id_ is set by System model and guaranteed to be unique + // gridkit_component_id_ is set by System model and guaranteed to be + // unique return components_[gridkit_component_id]; } @@ -1171,8 +1210,9 @@ namespace GridKit * case-file `id` */ template - SystemModel::BranchT* - SystemModel::getBranch(const std::string& id) + SystemModel::BranchT* SystemModel< + scalar_type, + index_type>::getBranch(const std::string& id) { BranchT* branch = dynamic_cast(findComponent("Branch_" + id)); if (branch == nullptr) @@ -1188,8 +1228,9 @@ namespace GridKit * label (device class and case-file ID, e.g. "Genrou_1") */ template - SystemModel::ComponentT* - SystemModel::getComponent(const std::string& label) + SystemModel::ComponentT* SystemModel< + scalar_type, + index_type>::getComponent(const std::string& label) { ComponentT* component = findComponent(label); if (component == nullptr) @@ -1205,8 +1246,9 @@ namespace GridKit * label, or nullptr if there is none */ template - SystemModel::ComponentT* - SystemModel::findComponent(const std::string& label) + SystemModel::ComponentT* SystemModel< + scalar_type, + index_type>::findComponent(const std::string& label) { ComponentT* component = nullptr; const auto it = gridkit_component_indices_.find(label); @@ -1215,7 +1257,9 @@ namespace GridKit component = components_[it->second]; } - for (IdxT subsystem = 0; component == nullptr && subsystem < numSubsystems(); ++subsystem) + for (IdxT subsystem = 0; + component == nullptr && subsystem < numSubsystems(); + ++subsystem) { component = subsystems_[subsystem]->findComponent(label); } diff --git a/GridKit/Model/PowerElectronics/Bus/Bus.hpp b/GridKit/Model/PowerElectronics/Bus/Bus.hpp index 9277039f30..e198c7a316 100644 --- a/GridKit/Model/PowerElectronics/Bus/Bus.hpp +++ b/GridKit/Model/PowerElectronics/Bus/Bus.hpp @@ -10,8 +10,7 @@ namespace GridKit class Bus : public NodeBase { public: - Bus() - : NodeBase(1, 0) + Bus() : NodeBase(1, 0) { } }; diff --git a/GridKit/Model/PowerElectronics/Bus/GroundedBus.hpp b/GridKit/Model/PowerElectronics/Bus/GroundedBus.hpp index 9076c18353..8b3da02272 100644 --- a/GridKit/Model/PowerElectronics/Bus/GroundedBus.hpp +++ b/GridKit/Model/PowerElectronics/Bus/GroundedBus.hpp @@ -24,7 +24,12 @@ namespace GridKit if (int err_code = NodeBase::allocate()) return err_code; - this->setExternalConnectionNodes(0, ExternalConnection{.y_ = &voltage_, .yp_ = &dummy_, .f_ = &dummy_, .idx_ = INVALID_INDEX}); + this->setExternalConnectionNodes( + 0, + ExternalConnection< + ScalarT, + IdxT>{.y_ = &voltage_, .yp_ = &dummy_, .f_ = &dummy_, .idx_ = INVALID_INDEX} + ); return 0; } diff --git a/GridKit/Model/PowerElectronics/Bus/MicrogridBus.hpp b/GridKit/Model/PowerElectronics/Bus/MicrogridBus.hpp index 3341af86fa..6e4b909c60 100644 --- a/GridKit/Model/PowerElectronics/Bus/MicrogridBus.hpp +++ b/GridKit/Model/PowerElectronics/Bus/MicrogridBus.hpp @@ -10,8 +10,7 @@ namespace GridKit class MicrogridBus : public NodeBase { public: - MicrogridBus() - : NodeBase(2, 0) + MicrogridBus() : NodeBase(2, 0) { } }; diff --git a/GridKit/Model/PowerElectronics/Bus/SignalNode.hpp b/GridKit/Model/PowerElectronics/Bus/SignalNode.hpp index c98ed636f0..1d72264c15 100644 --- a/GridKit/Model/PowerElectronics/Bus/SignalNode.hpp +++ b/GridKit/Model/PowerElectronics/Bus/SignalNode.hpp @@ -10,8 +10,7 @@ namespace GridKit class SignalNode : public NodeBase { public: - SignalNode() - : NodeBase(1, 0) + SignalNode() : NodeBase(1, 0) { } }; diff --git a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp index d6465a8b02..14a2d0d9cc 100644 --- a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp +++ b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp @@ -17,8 +17,7 @@ namespace GridKit * Calls default ModelEvaluatorImpl constructor. */ template - Capacitor::Capacitor(IdxT id, RealT C) - : C_(C) + Capacitor::Capacitor(IdxT id, RealT C) : C_(C) { size_ = 3; n_intern_ = 1; @@ -107,7 +106,9 @@ namespace GridKit // Create dF/dy std::vector rcord{0, 1, 2, 2, 2}; std::vector ccord{2, 2, 0, 1, 2}; - std::vector vals{C_ * alpha_, -C_ * alpha_, 1.0, -1.0, -1.0 - C_ * alpha_}; + std::vector vals{ + C_ * alpha_, -C_ * alpha_, 1.0, -1.0, -1.0 - C_ * alpha_ + }; this->setJacValues(rcord, ccord, vals); return 0; diff --git a/GridKit/Model/PowerElectronics/Component.hpp b/GridKit/Model/PowerElectronics/Component.hpp index 9dead1e8ac..e937d9780d 100644 --- a/GridKit/Model/PowerElectronics/Component.hpp +++ b/GridKit/Model/PowerElectronics/Component.hpp @@ -33,27 +33,27 @@ namespace GridKit /** * @brief Constructs a copy of a circuit component. * - * Copies the component metadata, local vector data, connection-node mapping, - * and COO Jacobian storage. Dynamically allocated component-owned data is - * deep-copied so that the new component does not share ownership of this - * storage with @p other. + * Copies the component metadata, local vector data, connection-node + * mapping, and COO Jacobian storage. Dynamically allocated + * component-owned data is deep-copied so that the new component does not + * share ownership of this storage with @p other. * * Pointers to state, state-derivative, and residual storage supplied by a - * parent system are copied as-is. Consequently, the copied component initially - * references the same parent-system storage as @p other. The pointer arrays - * used for external variables are independently allocated, but their entries - * point to the same external state, state-derivative, and residual storage as - * the original component. + * parent system are copied as-is. Consequently, the copied component + * initially references the same parent-system storage as @p other. The + * pointer arrays used for external variables are independently allocated, + * but their entries point to the same external state, state-derivative, + * and residual storage as the original component. * - * Local vectors, including the state, state derivative, residual, tolerances, - * quadrature data, adjoint data, and parameter vectors, retain the values of - * the original component. + * Local vectors, including the state, state derivative, residual, + * tolerances, quadrature data, adjoint data, and parameter vectors, + * retain the values of the original component. * * @param other Component to copy. * - * @note If the copied component is subsequently attached to a different parent - * system, its state, state-derivative, and residual pointers must be - * reassigned to the storage provided by that system before evaluation. + * @note If the copied component is subsequently attached to a different + * parent system, its state, state-derivative, and residual pointers must + * be reassigned to the storage provided by that system before evaluation. */ Component(const Component& other) : n_extern_(other.n_extern_), @@ -93,7 +93,8 @@ namespace GridKit */ if (other.connection_nodes_) { - connection_nodes_ = std::make_unique(static_cast(size_)); + connection_nodes_ = + std::make_unique(static_cast(size_)); for (size_t i = 0; i < static_cast(size_); ++i) { @@ -106,7 +107,8 @@ namespace GridKit */ if (other.jacobian_coo_rows_) { - jacobian_coo_rows_ = std::make_unique(static_cast(nnz_)); + jacobian_coo_rows_ = + std::make_unique(static_cast(nnz_)); for (size_t i = 0; i < static_cast(nnz_); ++i) { @@ -119,7 +121,8 @@ namespace GridKit */ if (other.jacobian_coo_cols_) { - jacobian_coo_cols_ = std::make_unique(static_cast(nnz_)); + jacobian_coo_cols_ = + std::make_unique(static_cast(nnz_)); for (size_t i = 0; i < static_cast(nnz_); ++i) { @@ -132,7 +135,8 @@ namespace GridKit */ if (other.jacobian_coo_values_) { - jacobian_coo_values_ = std::make_unique(static_cast(nnz_)); + jacobian_coo_values_ = + std::make_unique(static_cast(nnz_)); for (size_t i = 0; i < static_cast(nnz_); ++i) { @@ -142,9 +146,11 @@ namespace GridKit if (size_ > 0) { - y_ext_ = std::make_unique(static_cast(size_)); - yp_ext_ = std::make_unique(static_cast(size_)); - f_ext_ = std::make_unique(static_cast(size_)); + y_ext_ = + std::make_unique(static_cast(size_)); + yp_ext_ = + std::make_unique(static_cast(size_)); + f_ext_ = std::make_unique(static_cast(size_)); for (size_t i = 0; i < static_cast(size_); ++i) { @@ -178,12 +184,14 @@ namespace GridKit * system-owned state or residual storage. * * @note By default, the cloned component's state, state-derivative, and - * residual pointers are not set. The user is responsible for setting these - * pointers to the appropriate storage before evaluating the residual. + * residual pointers are not set. The user is responsible for setting + * these pointers to the appropriate storage before evaluating the + * residual. */ virtual Component* clone() const { - throw std::runtime_error("clone() is not supported for this component."); + throw std::runtime_error("clone() is not supported for this component." + ); } /** @@ -200,7 +208,8 @@ namespace GridKit } /** - * @note Cannot be marked final, since it is overridden to recurse in the system model. + * @note Cannot be marked final, since it is overridden to recurse in the + * system model. */ void updateTime(RealT t, RealT a) override { @@ -229,14 +238,16 @@ namespace GridKit } /** - * @brief Create the mappings from local to global indices for an internal variable. - * Used for constructing system Jacobians \see connection_nodes_. + * @brief Create the mappings from local to global indices for an internal + * variable. Used for constructing system Jacobians \see + * connection_nodes_. * * @param local_index The index of the local variable * @param global_index The index of the corresponding system variable. * - * @pre `local_index` *must* be the index of an internal variable. Using this method for - * an external variable will not properly setup the data pointers for that variable. + * @pre `local_index` *must* be the index of an internal variable. Using + * this method for an external variable will not properly setup the data + * pointers for that variable. */ int setInternalConnectionNodes(size_t local_index, IdxT global_index) { @@ -246,18 +257,22 @@ namespace GridKit } /** - * @brief Create the mappings from local to global indices for an external variable. - * External variables need extra information than internal variables - their data - * pointers \ref y_ext_, \ref yp_ext_, and \ref f_ext_. + * @brief Create the mappings from local to global indices for an external + * variable. External variables need extra information than internal + * variables - their data pointers \ref y_ext_, \ref yp_ext_, and \ref + * f_ext_. * * @param local_index The index of the local variable * @param connection The necessary connection information for the variable * - * @pre `local_index` *must* be the index of an external variable. As of now, using this method - * to set information for a local variable will silently discard the unnecessary information, but - * this may change in the future. + * @pre `local_index` *must* be the index of an external variable. As of + * now, using this method to set information for a local variable will + * silently discard the unnecessary information, but this may change in + * the future. */ - int setExternalConnectionNodes(size_t local_index, ExternalConnection connection) + int setExternalConnectionNodes( + size_t local_index, ExternalConnection connection + ) { assert(extern_indices_.contains(local_index)); y_ext_[local_index] = connection.y_; @@ -285,7 +300,8 @@ namespace GridKit } /** - * @brief Given the location of value in the local vector map to global index + * @brief Given the location of value in the local vector map to global + * index * * f(local_index) = global_index * @@ -307,25 +323,32 @@ namespace GridKit /** * @brief Allocates all of the internal buffers for the component. - * If a components needs a more specialized allocation (such as by having additional internal buffers), - * it should override this function and then call it in the body to ensure it stays up-to-date with - * new implementations. + * If a components needs a more specialized allocation (such as by having + * additional internal buffers), it should override this function and then + * call it in the body to ensure it stays up-to-date with new + * implementations. * - * @pre \ref nnz_ and \ref size_ must be set. Typically these are set by the child object in its constructor. + * @pre \ref nnz_ and \ref size_ must be set. Typically these are set by + * the child object in its constructor. * * @return An error code, or 0 if success */ int allocate() override { - jacobian_coo_rows_ = std::make_unique(static_cast(nnz_)); - jacobian_coo_cols_ = std::make_unique(static_cast(nnz_)); - jacobian_coo_values_ = std::make_unique(static_cast(nnz_)); + jacobian_coo_rows_ = + std::make_unique(static_cast(nnz_)); + jacobian_coo_cols_ = + std::make_unique(static_cast(nnz_)); + jacobian_coo_values_ = + std::make_unique(static_cast(nnz_)); - y_ext_ = std::make_unique(static_cast(size_)); - yp_ext_ = std::make_unique(static_cast(size_)); - f_ext_ = std::make_unique(static_cast(size_)); + y_ext_ = std::make_unique(static_cast(size_)); + yp_ext_ = + std::make_unique(static_cast(size_)); + f_ext_ = std::make_unique(static_cast(size_)); - connection_nodes_ = std::make_unique(static_cast(size_)); + connection_nodes_ = + std::make_unique(static_cast(size_)); tag_.resize(static_cast(size_)); @@ -369,10 +392,11 @@ namespace GridKit } /** - * @brief Evaluating the residual of a Component should be done by evaluating the - * internal residuals and external residuals. Components should overload those - * functions for their residuals (and the system will call those function instead of this one), - * so there is no reason to overload this functionality. + * @brief Evaluating the residual of a Component should be done by + * evaluating the internal residuals and external residuals. Components + * should overload those functions for their residuals (and the system + * will call those function instead of this one), so there is no reason to + * overload this functionality. * * @return An error code, or 0 is successful. */ @@ -395,8 +419,8 @@ namespace GridKit virtual int evaluateInternalResidual() = 0; /** - * @brief Evaluate all residual contributions for the component's external variables, - * accumulating them through `f_ext_`. + * @brief Evaluate all residual contributions for the component's external + * variables, accumulating them through `f_ext_`. * * @return An error code, or 0 if successful. */ @@ -419,8 +443,9 @@ namespace GridKit protected: /** - * @brief Reset the Jacobian so it can be constructed. Helper method for \ref setJacValues(). - * Sets \ref current_jac_size_ to 0 so that future calls to `setJacValues()` will override previous values. + * @brief Reset the Jacobian so it can be constructed. Helper method for + * \ref setJacValues(). Sets \ref current_jac_size_ to 0 so that future + * calls to `setJacValues()` will override previous values. * */ void zeroJacMatrix() @@ -429,16 +454,23 @@ namespace GridKit } /** - * @brief Helper method for adding values to the Jacobian. Copies the rows, cols, and vals buffers and appends - * them to the end of the corresponding Jacobian buffers. Uses \ref current_jac_size_ to tell where the end of - * the Jacobian currently is. + * @brief Helper method for adding values to the Jacobian. Copies the + * rows, cols, and vals buffers and appends them to the end of the + * corresponding Jacobian buffers. Uses \ref current_jac_size_ to tell + * where the end of the Jacobian currently is. * * @pre `rows`, `cols`, `vals` must all be the same size * @pre \ref allocate() must be called first. - * @pre Must call \ref zeroJacMatrix() before starting construction of a new Jacobian - * @pre The must be enough room for the values in the allocated buffers, i.e. `current_jac_size_ + rows.size() <= nnz_` + * @pre Must call \ref zeroJacMatrix() before starting construction of a + * new Jacobian + * @pre The must be enough room for the values in the allocated buffers, + * i.e. `current_jac_size_ + rows.size() <= nnz_` */ - void setJacValues(const std::vector& rows, const std::vector& cols, const std::vector& vals) + void setJacValues( + const std::vector& rows, + const std::vector& cols, + const std::vector& vals + ) { assert(rows.size() == cols.size()); assert(rows.size() == vals.size()); @@ -645,17 +677,19 @@ namespace GridKit /** * @brief Allocate state and residual storage owned by this component. * - * Most components do not need state and residual storages. The most notable exception - * is currently the system, so a separate flag is provided for the system. - * Systems still can't directly access \ref y_, \ref yp_, and \ref f_, so they need - * their corresponding \ref y_int_, \ref yp_int_, and \ref f_int_ set, since there isn't - * another system above them to set it. + * Most components do not need state and residual storages. The most + * notable exception is currently the system, so a separate flag is + * provided for the system. Systems still can't directly access \ref y_, + * \ref yp_, and \ref f_, so they need their corresponding \ref y_int_, + * \ref yp_int_, and \ref f_int_ set, since there isn't another system + * above them to set it. * - * @todo This is a weird exception specifically for systems - and in a hierarchical setting - * will only be needed by the *topmost* system - subsystems shouldn't allocate and should have their - * internal pointers set by the system above them. Ideally we can remove this exception by having - * the integrator allocate these buffers instead of the system and set the internal pointers for the - * topmost system. + * @todo This is a weird exception specifically for systems - and in a + * hierarchical setting will only be needed by the *topmost* system - + * subsystems shouldn't allocate and should have their internal pointers + * set by the system above them. Ideally we can remove this exception by + * having the integrator allocate these buffers instead of the system and + * set the internal pointers for the topmost system. */ void allocateVectors(IdxT n, bool system = false) { @@ -673,27 +707,36 @@ namespace GridKit } } - /// Number of external variables in this component - ones which are referenced but not owned by this component. + /// Number of external variables in this component - ones which are + /// referenced but not owned by this component. size_t n_extern_; - /// Number of internal variables in this component - ones which are only referenced by this component. + /// Number of internal variables in this component - ones which are only + /// referenced by this component. size_t n_intern_; /** - * @brief A set of variable indices which correspond to the external variables. Variables indices not in this set are internal. + * @brief A set of variable indices which correspond to the external + * variables. Variables indices not in this set are internal. * - * @invariant Must have a size of \ref n_extern_. Each element must be in the range [0, \ref size_ - 1]. Not currently verified anywhere. + * @invariant Must have a size of \ref n_extern_. Each element must be in + * the range [0, \ref size_ - 1]. Not currently verified anywhere. */ std::set extern_indices_; /** - * @brief A map from local variable indices to system (global) variable indices. Used for Jacobian construction in + * @brief A map from local variable indices to system (global) variable + * indices. Used for Jacobian construction in * \ref PowerElectronics::SystemModel::evaluateJacobian(). - * @note If a variable does not map to a corresponding variable in the system (such as with reference nodes), a special - * sentinel value of \ref INVALID_INDEX is used. During Jacobian construction, such rows and columns will be pruned. + * @note If a variable does not map to a corresponding variable in the + * system (such as with reference nodes), a special sentinel value of \ref + * INVALID_INDEX is used. During Jacobian construction, such rows and + * columns will be pruned. */ std::unique_ptr connection_nodes_; - /// The number of variables in this component. Should be equal to \ref n_extern_ plus \ref n_intern_. \see size() + /// The number of variables in this component. Should be equal to \ref + /// n_extern_ plus \ref n_intern_. \see size() IdxT size_{0}; - /// The number of nonzero elements in this component's Jacobian. \see nnz() + /// The number of nonzero elements in this component's Jacobian. \see + /// nnz() IdxT nnz_{0}; IdxT size_quad_{0}; IdxT size_opt_{0}; @@ -703,7 +746,8 @@ namespace GridKit std::unique_ptr jacobian_coo_cols_; std::unique_ptr jacobian_coo_values_; - /// The number of non-zero elements currently inserted into the Jacobian. See \ref setJacValues() + /// The number of non-zero elements currently inserted into the Jacobian. + /// See \ref setJacValues() size_t current_jac_size_{0}; /// @brief A pointer to the internal variables of this component. @@ -715,25 +759,29 @@ namespace GridKit /** * An array of (input) pointers to state values for external variables. - * \note The size of this array is equal to \ref size_, allowing you to index it with the index - * of the variable in question (i.e. consistent with \ref extern_indices_). Therefore, accessing - * and dereferencing the pointer in an internal variable index is undefined behavior. + * \note The size of this array is equal to \ref size_, allowing you to + * index it with the index of the variable in question (i.e. consistent + * with \ref extern_indices_). Therefore, accessing and dereferencing the + * pointer in an internal variable index is undefined behavior. * \see setExternalConnectionNodes() */ std::unique_ptr y_ext_; /** - * An array of (input) pointers to derivative values for external variables. - * \note The size of this array is equal to \ref size_, allowing you to index it with the index - * of the variable in question (i.e. consistent with \ref extern_indices_). Therefore, accessing - * and dereferencing the pointer in an internal variable index is undefined behavior. + * An array of (input) pointers to derivative values for external + * variables. + * \note The size of this array is equal to \ref size_, allowing you to + * index it with the index of the variable in question (i.e. consistent + * with \ref extern_indices_). Therefore, accessing and dereferencing the + * pointer in an internal variable index is undefined behavior. * \see setExternalConnectionNodes() */ std::unique_ptr yp_ext_; /** * An array of (output) pointers to residuals for external variables. - * \note The size of this array is equal to \ref size_, allowing you to index it with the index - * of the variable in question (i.e. consistent with \ref extern_indices_). Therefore, accessing - * and dereferencing the pointer in an internal variable index is undefined behavior. + * \note The size of this array is equal to \ref size_, allowing you to + * index it with the index of the variable in question (i.e. consistent + * with \ref extern_indices_). Therefore, accessing and dereferencing the + * pointer in an internal variable index is undefined behavior. * \see setExternalConnectionNodes() */ std::unique_ptr f_ext_; @@ -763,23 +811,29 @@ namespace GridKit private: /** - * The internal buffer for state for the component. For most components, it will be empty and shouldn't be accessed. - * Instead use \ref y_int_ for an internal variable or \ref y_ext_ for an external variable, respectively. - * For components which want an internal buffer (such as a system), make sure that \ref y_int_ points here. + * The internal buffer for state for the component. For most components, + * it will be empty and shouldn't be accessed. Instead use \ref y_int_ for + * an internal variable or \ref y_ext_ for an external variable, + * respectively. For components which want an internal buffer (such as a + * system), make sure that \ref y_int_ points here. * \see allocateVectors() */ VectorT y_; /** - * The internal buffer for derivatives for the component. For most components, it will be empty and shouldn't be accessed. - * Instead use \ref yp_int_ for an internal variable or \ref yp_ext_ for an external variable, respectively. - * For components which want an internal buffer (such as a system), make sure that \ref yp_int_ points here. + * The internal buffer for derivatives for the component. For most + * components, it will be empty and shouldn't be accessed. Instead use + * \ref yp_int_ for an internal variable or \ref yp_ext_ for an external + * variable, respectively. For components which want an internal buffer + * (such as a system), make sure that \ref yp_int_ points here. * \see allocateVectors() */ VectorT yp_; /** - * The internal buffer for state for the component. For most components, it will be empty and shouldn't be accessed. - * Instead use \ref f_int_ for an internal variable or \ref f_ext_ for an external variable, respectively. - * For components which want an internal buffer (such as a system), make sure that \ref f_int_ points here. + * The internal buffer for state for the component. For most components, + * it will be empty and shouldn't be accessed. Instead use \ref f_int_ for + * an internal variable or \ref f_ext_ for an external variable, + * respectively. For components which want an internal buffer (such as a + * system), make sure that \ref f_int_ points here. * \see allocateVectors() */ VectorT f_; diff --git a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp index fa624f26ef..0eb4eb1725 100644 --- a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp +++ b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp @@ -44,8 +44,9 @@ namespace GridKit { assert(refframe_ || node_ref_->size() == 1); assert(node_bus_->size() == 2); - // internals [Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi, \delta_i] - // externals [\omega_ref, vba_out, vbb_out] + // internals [Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, + // vo_di, vo_qi, io_di, io_qi, \delta_i] externals [\omega_ref, vba_out, + // vbb_out] size_ = refframe_ ? 15 : 16; n_intern_ = refframe_ ? 12 : 13; n_extern_ = 3; @@ -110,13 +111,19 @@ namespace GridKit ScalarT delta = refframe_ ? ScalarT(0.0) : y_int_[12]; // Take incoming voltages to current rotator reference frame - ScalarT vbd_in = std::cos(delta) * *y_ext_[1] + std::sin(delta) * *y_ext_[2]; - ScalarT vbq_in = -std::sin(delta) * *y_ext_[1] + std::cos(delta) * *y_ext_[2]; + ScalarT vbd_in = + std::cos(delta) * *y_ext_[1] + std::sin(delta) * *y_ext_[2]; + ScalarT vbq_in = + -std::sin(delta) * *y_ext_[1] + std::cos(delta) * *y_ext_[2]; // ### Internal Components ## // P and Q equations - f_int_[0] = -yp_int_[0] + wc_ * (y_int_[8] * y_int_[10] + y_int_[9] * y_int_[11] - y_int_[0]); - f_int_[1] = -yp_int_[1] + wc_ * (-y_int_[8] * y_int_[11] + y_int_[9] * y_int_[10] - y_int_[1]); + f_int_[0] = + -yp_int_[0] + + wc_ * (y_int_[8] * y_int_[10] + y_int_[9] * y_int_[11] - y_int_[0]); + f_int_[1] = + -yp_int_[1] + + wc_ * (-y_int_[8] * y_int_[11] + y_int_[9] * y_int_[10] - y_int_[1]); // Voltage control ScalarT vod_star = Vn_ - nq_ * y_int_[1]; @@ -125,26 +132,36 @@ namespace GridKit f_int_[2] = -yp_int_[2] + vod_star - y_int_[8]; f_int_[3] = -yp_int_[3] + voq_star - y_int_[9]; - ScalarT ild_star = F_ * y_int_[10] - wb_ * Cf_ * y_int_[9] + Kpv_ * (vod_star - y_int_[8]) + Kiv_ * y_int_[2]; - ScalarT ilq_star = F_ * y_int_[11] + wb_ * Cf_ * y_int_[8] + Kpv_ * (voq_star - y_int_[9]) + Kiv_ * y_int_[3]; + ScalarT ild_star = F_ * y_int_[10] - wb_ * Cf_ * y_int_[9] + + Kpv_ * (vod_star - y_int_[8]) + Kiv_ * y_int_[2]; + ScalarT ilq_star = F_ * y_int_[11] + wb_ * Cf_ * y_int_[8] + + Kpv_ * (voq_star - y_int_[9]) + Kiv_ * y_int_[3]; // Current control f_int_[4] = -yp_int_[4] + ild_star - y_int_[6]; f_int_[5] = -yp_int_[5] + ilq_star - y_int_[7]; - ScalarT vid_star = -wb_ * Lf_ * y_int_[7] + Kpc_ * (ild_star - y_int_[6]) + Kic_ * y_int_[4]; - ScalarT viq_star = wb_ * Lf_ * y_int_[6] + Kpc_ * (ilq_star - y_int_[7]) + Kic_ * y_int_[5]; + ScalarT vid_star = -wb_ * Lf_ * y_int_[7] + Kpc_ * (ild_star - y_int_[6]) + + Kic_ * y_int_[4]; + ScalarT viq_star = wb_ * Lf_ * y_int_[6] + Kpc_ * (ilq_star - y_int_[7]) + + Kic_ * y_int_[5]; // Output LC Filter - f_int_[6] = -yp_int_[6] - (rLf_ / Lf_) * y_int_[6] + omega * y_int_[7] + (vid_star - y_int_[8]) / Lf_; - f_int_[7] = -yp_int_[7] - (rLf_ / Lf_) * y_int_[7] - omega * y_int_[6] + (viq_star - y_int_[9]) / Lf_; + f_int_[6] = -yp_int_[6] - (rLf_ / Lf_) * y_int_[6] + omega * y_int_[7] + + (vid_star - y_int_[8]) / Lf_; + f_int_[7] = -yp_int_[7] - (rLf_ / Lf_) * y_int_[7] - omega * y_int_[6] + + (viq_star - y_int_[9]) / Lf_; - f_int_[8] = -yp_int_[8] + omega * y_int_[9] + (y_int_[6] - y_int_[10]) / Cf_; - f_int_[9] = -yp_int_[9] - omega * y_int_[8] + (y_int_[7] - y_int_[11]) / Cf_; + f_int_[8] = + -yp_int_[8] + omega * y_int_[9] + (y_int_[6] - y_int_[10]) / Cf_; + f_int_[9] = + -yp_int_[9] - omega * y_int_[8] + (y_int_[7] - y_int_[11]) / Cf_; // Output Connector - f_int_[10] = -yp_int_[10] - (rLc_ / Lc_) * y_int_[10] + omega * y_int_[11] + (y_int_[8] - vbd_in) / Lc_; - f_int_[11] = -yp_int_[11] - (rLc_ / Lc_) * y_int_[11] - omega * y_int_[10] + (y_int_[9] - vbq_in) / Lc_; + f_int_[10] = -yp_int_[10] - (rLc_ / Lc_) * y_int_[10] + omega * y_int_[11] + + (y_int_[8] - vbd_in) / Lc_; + f_int_[11] = -yp_int_[11] - (rLc_ / Lc_) * y_int_[11] - omega * y_int_[10] + + (y_int_[9] - vbq_in) / Lc_; // Rotor difference angle if (!refframe_) @@ -175,26 +192,49 @@ namespace GridKit } /** - * @brief Compute the jacobian of the DistributedGenerator for iteration. dF/dy - \alpha dF/dy' + * @brief Compute the jacobian of the DistributedGenerator for iteration. + dF/dy - \alpha dF/dy' * * The matrix dF/dy should be * - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - [-1, 0, 0, 0, -mp, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - [ 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, 0, wc*x15, wc*x16, wc*x13, wc*x14] - [ 0, 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, -wc*x16, wc*x15, wc*x14, -wc*x13] - [ 0, 0, 0, 0, 0, -nq, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0] - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0] - [ 0, 0, 0, 0, 0, -Kpv*nq, Kiv, 0, 0, 0, -1, 0, -Kpv, -Cf*wb, F, 0] - [ 0, 0, 0, 0, 0, 0, 0, Kiv, 0, 0, 0, -1, Cf*wb, -Kpv, 0, F] - [ 0, 0, 0, 0, -mp*x12, -(Kpc*Kpv*nq)/Lf, (Kiv*Kpc)/Lf, 0, Kic/Lf, 0, - Kpc/Lf - rLf/Lf, -mp*x5, -(Kpc*Kpv + 1)/Lf, -(Cf*Kpc*wb)/Lf, (F*Kpc)/Lf, 0] - [ 0, 0, 0, 0, mp*x11, 0, 0, (Kiv*Kpc)/Lf, 0, Kic/Lf, mp*x5, - Kpc/Lf - rLf/Lf, (Cf*Kpc*wb)/Lf, -(Kpc*Kpv + 1)/Lf, 0, (F*Kpc)/Lf] - [ 0, 0, 0, 0, -mp*x14, 0, 0, 0, 0, 0, 1/Cf, 0, 0, wb - mp*x5, -1/Cf, 0] - [ 0, 0, 0, 0, mp*x13, 0, 0, 0, 0, 0, 0, 1/Cf, mp*x5 - wb, 0, 0, -1/Cf] - [ 0, -cos(x4)/Lc, -sin(x4)/Lc, -(x3*cos(x4) - x2*sin(x4))/Lc, -mp*x16, 0, 0, 0, 0, 0, 0, 0, 1/Lc, 0, -rLc/Lc, wb - mp*x5] - [ 0, sin(x4)/Lc, -cos(x4)/Lc, (x2*cos(x4) + x3*sin(x4))/Lc, mp*x15, 0, 0, 0, 0, 0, 0, 0, 0, 1/Lc, mp*x5 - wb, -rLc/Lc] + [ 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0] [ 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0] [ 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0] + [-1, 0, 0, 0, -mp, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0] [ 0, 0, 0, 0, -wc, 0, 0, + 0, 0, 0, 0, 0, wc*x15, + wc*x16, wc*x13, wc*x14] [ 0, 0, 0, 0, 0, + -wc, 0, 0, 0, 0, 0, 0, + -wc*x16, wc*x15, wc*x14, -wc*x13] [ 0, 0, 0, 0, + 0, -nq, 0, 0, 0, 0, 0, 0, -1, + 0, 0, 0] [ 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + -1, 0, 0] [ 0, 0, 0, 0, 0, + -Kpv*nq, Kiv, 0, 0, 0, -1, 0, + -Kpv, -Cf*wb, F, 0] [ 0, 0, 0, 0, 0, + 0, 0, Kiv, 0, 0, 0, -1, Cf*wb, + -Kpv, 0, F] [ 0, 0, 0, 0, -mp*x12, + -(Kpc*Kpv*nq)/Lf, (Kiv*Kpc)/Lf, 0, Kic/Lf, 0, - Kpc/Lf - + rLf/Lf, -mp*x5, -(Kpc*Kpv + 1)/Lf, -(Cf*Kpc*wb)/Lf, (F*Kpc)/Lf, + 0] [ 0, 0, 0, 0, mp*x11, 0, + 0, (Kiv*Kpc)/Lf, 0, Kic/Lf, mp*x5, - Kpc/Lf - rLf/Lf, + (Cf*Kpc*wb)/Lf, -(Kpc*Kpv + 1)/Lf, 0, (F*Kpc)/Lf] [ 0, 0, + 0, 0, -mp*x14, 0, 0, + 0, 0, 0, 1/Cf, 0, 0, + wb - mp*x5, -1/Cf, 0] [ 0, 0, 0, 0, + mp*x13, 0, 0, 0, 0, 0, 0, + 1/Cf, mp*x5 - wb, 0, 0, -1/Cf] [ 0, + -cos(x4)/Lc, -sin(x4)/Lc, -(x3*cos(x4) - x2*sin(x4))/Lc, -mp*x16, 0, 0, 0, + 0, 0, 0, 0, 1/Lc, 0, + -rLc/Lc, wb - mp*x5] [ 0, sin(x4)/Lc, -cos(x4)/Lc, (x2*cos(x4) + + x3*sin(x4))/Lc, mp*x15, 0, 0, 0, 0, 0, + 0, 0, 0, 1/Lc, mp*x5 - wb, + -rLc/Lc] * 'Generated from MATLAB symbolic' * * @tparam ScalarT @@ -369,7 +409,10 @@ namespace GridKit { rtemp.push_back(13); ctemp.push_back(15); - valtemp.push_back((1.0 / Lc_) * (std::sin(delta) * static_cast(*y_ext_[1]) - std::cos(delta) * static_cast(*y_ext_[2]))); + valtemp.push_back( + (1.0 / Lc_) + * (std::sin(delta) * static_cast(*y_ext_[1]) - std::cos(delta) * static_cast(*y_ext_[2])) + ); } this->setJacValues(rtemp, ctemp, valtemp); @@ -388,7 +431,10 @@ namespace GridKit { rtemp.push_back(14); ctemp.push_back(15); - valtemp.push_back((1.0 / Lc_) * (std::cos(delta) * static_cast(*y_ext_[1]) + std::sin(delta) * static_cast(*y_ext_[2]))); + valtemp.push_back( + (1.0 / Lc_) + * (std::cos(delta) * static_cast(*y_ext_[1]) + std::sin(delta) * static_cast(*y_ext_[2])) + ); } this->setJacValues(rtemp, ctemp, valtemp); diff --git a/GridKit/Model/PowerElectronics/ExternalConnection.hpp b/GridKit/Model/PowerElectronics/ExternalConnection.hpp index f0a3322cd9..1faae665f8 100644 --- a/GridKit/Model/PowerElectronics/ExternalConnection.hpp +++ b/GridKit/Model/PowerElectronics/ExternalConnection.hpp @@ -6,8 +6,8 @@ namespace GridKit { /** * @brief The connection of a component's external variable to its system. - * Allows the component to access data about that external variable and allows - * the system to construct Jacobian information about that variable. + * Allows the component to access data about that external variable and + * allows the system to construct Jacobian information about that variable. * @see Component::setExternalConnectionNodes() */ template @@ -15,11 +15,14 @@ namespace GridKit { /// A pointer to the state value of the variable. \see Component::y_ext_ const ScalarT* y_; - /// A pointer to the derivative value of the variable. \see Component::yp_ext_ + /// A pointer to the derivative value of the variable. \see + /// Component::yp_ext_ const ScalarT* yp_; - /// A pointer to the residual buffer of the variable. \see Component::f_ext_ + /// A pointer to the residual buffer of the variable. \see + /// Component::f_ext_ ScalarT* f_; - /// The corresponding system variable index. \see Component::connection_nodes_ + /// The corresponding system variable index. \see + /// Component::connection_nodes_ IdxT idx_; }; } // namespace PowerElectronics diff --git a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp index e5e87cf219..8ba9164157 100644 --- a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp +++ b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp @@ -23,14 +23,17 @@ namespace GridKit * @param[in] Lls - stator leakage inductance */ template - InductionMotor::InductionMotor(IdxT id, RealT Lls, RealT Rs, RealT Llr, RealT Rr, RealT Lms, RealT RJ, RealT P) - : Lls_(Lls), - Rs_(Rs), - Llr_(Llr), - Rr_(Rr), - Lms_(Lms), - RJ_(RJ), - P_(P) + InductionMotor::InductionMotor( + IdxT id, + RealT Lls, + RealT Rs, + RealT Llr, + RealT Rr, + RealT Lms, + RealT RJ, + RealT P + ) + : Lls_(Lls), Rs_(Rs), Llr_(Llr), Rr_(Rr), Lms_(Lms), RJ_(RJ), P_(P) { size_ = 10; n_intern_ = 5; @@ -90,11 +93,22 @@ namespace GridKit template int InductionMotor::evaluateInternalResidual() { - f_int_[0] = (1.0 / 3.0) * (2.0 * *y_ext_[0] - *y_ext_[1] - *y_ext_[2]) - Rs_ * y_int_[0] - (Lls_ + Lms_) * yp_int_[0] - Lms_ * yp_int_[1]; - f_int_[1] = (1.0 / std::sqrt(3.0)) * (-*y_ext_[1] + *y_ext_[2]) - Rs_ * y_int_[1] - (Lls_ + Lms_) * yp_int_[1] - Lms_ * yp_int_[0]; - f_int_[2] = (*y_ext_[0] + *y_ext_[1] + *y_ext_[2]) / 3.0 - Rs_ * y_int_[2] - Lls_ * yp_int_[7]; - f_int_[3] = Rr_ * y_int_[3] + (Llr_ + Lms_) * yp_int_[3] + Lms_ * yp_int_[0] - (P_ / 2.0) * *y_ext_[3] * ((Llr_ + Lms_) * y_int_[4] + Lms_ * y_int_[1]); - f_int_[4] = Rr_ * y_int_[4] + (Llr_ + Lms_) * yp_int_[4] + Lms_ * yp_int_[1] + (P_ / 2.0) * *y_ext_[3] * ((Llr_ + Lms_) * y_int_[3] + Lms_ * y_int_[0]); + f_int_[0] = (1.0 / 3.0) * (2.0 * *y_ext_[0] - *y_ext_[1] - *y_ext_[2]) + - Rs_ * y_int_[0] - (Lls_ + Lms_) * yp_int_[0] + - Lms_ * yp_int_[1]; + f_int_[1] = (1.0 / std::sqrt(3.0)) * (-*y_ext_[1] + *y_ext_[2]) + - Rs_ * y_int_[1] - (Lls_ + Lms_) * yp_int_[1] + - Lms_ * yp_int_[0]; + f_int_[2] = (*y_ext_[0] + *y_ext_[1] + *y_ext_[2]) / 3.0 - Rs_ * y_int_[2] + - Lls_ * yp_int_[7]; + f_int_[3] = Rr_ * y_int_[3] + (Llr_ + Lms_) * yp_int_[3] + + Lms_ * yp_int_[0] + - (P_ / 2.0) * *y_ext_[3] + * ((Llr_ + Lms_) * y_int_[4] + Lms_ * y_int_[1]); + f_int_[4] = Rr_ * y_int_[4] + (Llr_ + Lms_) * yp_int_[4] + + Lms_ * yp_int_[1] + + (P_ / 2.0) * *y_ext_[3] + * ((Llr_ + Lms_) * y_int_[3] + Lms_ * y_int_[0]); return 0; } @@ -102,9 +116,13 @@ namespace GridKit int InductionMotor::evaluateExternalResidual() { *f_ext_[0] += y_int_[0] + y_int_[2]; - *f_ext_[1] += (-1.0 / 2.0) * y_int_[0] - (std::sqrt(3.0) / 2.0) * y_int_[1] + y_int_[2]; - *f_ext_[2] += (-1.0 / 2.0) * y_int_[0] + (std::sqrt(3.0) / 2.0) * y_int_[1] + y_int_[2]; - *f_ext_[3] += RJ_ * *yp_ext_[3] - (3.0 / 4.0) * P_ * Lms_ * (y_int_[0] * y_int_[4] - y_int_[1] * y_int_[3]); + *f_ext_[1] += (-1.0 / 2.0) * y_int_[0] + - (std::sqrt(3.0) / 2.0) * y_int_[1] + y_int_[2]; + *f_ext_[2] += (-1.0 / 2.0) * y_int_[0] + + (std::sqrt(3.0) / 2.0) * y_int_[1] + y_int_[2]; + *f_ext_[3] += RJ_ * *yp_ext_[3] + - (3.0 / 4.0) * P_ * Lms_ + * (y_int_[0] * y_int_[4] - y_int_[1] * y_int_[3]); *f_ext_[4] += *yp_ext_[4] - *y_ext_[3]; return 0; } diff --git a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp index a79e1ffa87..dedef90617 100644 --- a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp +++ b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp @@ -41,7 +41,16 @@ namespace GridKit using Component::n_intern_; public: - InductionMotor(IdxT id, RealT Lls, RealT Rs, RealT Llr, RealT Rr, RealT Lms, RealT RJ, RealT P); + InductionMotor( + IdxT id, + RealT Lls, + RealT Rs, + RealT Llr, + RealT Rr, + RealT Lms, + RealT RJ, + RealT P + ); virtual ~InductionMotor(); int initialize(); diff --git a/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp b/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp index b699e7b29a..c8986aec24 100644 --- a/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp +++ b/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp @@ -14,7 +14,9 @@ namespace GridKit * Calls default ModelEvaluatorImpl constructor. */ template - Inductor::Inductor(IdxT id, RealT L, NodeT* node1, NodeT* node2) + Inductor::Inductor( + IdxT id, RealT L, NodeT* node1, NodeT* node2 + ) : L_(L), node1_(node1), node2_(node2) { assert(node1_->size() == 1); diff --git a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp index d61d25a3a0..10912fe6d1 100644 --- a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp +++ b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp @@ -27,12 +27,10 @@ namespace GridKit * @param[in] M - mutual inductance */ template - LinearTransformer::LinearTransformer(IdxT id, RealT L0, RealT L1, RealT R0, RealT R1, RealT M) - : L0_(L0), - L1_(L1), - R0_(R0), - R1_(R1), - M_(M) + LinearTransformer::LinearTransformer( + IdxT id, RealT L0, RealT L1, RealT R0, RealT R1, RealT M + ) + : L0_(L0), L1_(L1), R0_(R0), R1_(R1), M_(M) { size_ = 4; n_intern_ = 2; @@ -91,8 +89,10 @@ namespace GridKit template int LinearTransformer::evaluateInternalResidual() { - f_int_[0] = *y_ext_[0] - R0_ * y_int_[0] - L0_ * yp_int_[0] - M_ * yp_int_[1]; - f_int_[1] = *y_ext_[1] - R1_ * y_int_[1] - M_ * yp_int_[0] - L1_ * yp_int_[1]; + f_int_[0] = + *y_ext_[0] - R0_ * y_int_[0] - L0_ * yp_int_[0] - M_ * yp_int_[1]; + f_int_[1] = + *y_ext_[1] - R1_ * y_int_[1] - M_ * yp_int_[0] - L1_ * yp_int_[1]; return 0; } diff --git a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp index 11ed78dd4d..9f925d3284 100644 --- a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp +++ b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp @@ -41,7 +41,9 @@ namespace GridKit using Component::n_intern_; public: - LinearTransformer(IdxT id, RealT L0, RealT L1, RealT R0, RealT R1, RealT M); + LinearTransformer( + IdxT id, RealT L0, RealT L1, RealT R0, RealT R1, RealT M + ); virtual ~LinearTransformer(); int initialize(); diff --git a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp index f76c5ec5d0..8ed2b91bf1 100644 --- a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -16,12 +16,14 @@ namespace GridKit * * In DQ space * Each microgrid line has a virtual resistance RN - * Model is from paper: "Modeling, Analysis and Testing of Autonomous Operation - * of an Inverter-Based Microgrid", Nagaraju Pogaku, Milan Prodanovic, and - * Timothy C. Green, Section E + * Model is from paper: "Modeling, Analysis and Testing of Autonomous + * Operation of an Inverter-Based Microgrid", Nagaraju Pogaku, Milan + * Prodanovic, and Timothy C. Green, Section E */ template - MicrogridBusDQ::MicrogridBusDQ(IdxT id, RealT RN, NodeT* node1) + MicrogridBusDQ::MicrogridBusDQ( + IdxT id, RealT RN, NodeT* node1 + ) : RN_(RN), node1_(node1) { assert(node1_->size() == 2); @@ -48,7 +50,8 @@ namespace GridKit return 0; } - /// There are no internal variables in this component, so \ref tag_ can be set arbitrarily. + /// There are no internal variables in this component, so \ref tag_ can be + /// set arbitrarily. template int MicrogridBusDQ::tagDifferentiable() { @@ -81,8 +84,9 @@ namespace GridKit /** * @brief Evaluate residual - * This model has "Virtual resistors". The voltage of the bus divided by its virtual resistance. - * The components are external to allow for outside components to add inductances to the terms. + * This model has "Virtual resistors". The voltage of the bus divided by its + * virtual resistance. The components are external to allow for outside + * components to add inductances to the terms. * * reference to equations in class header * diff --git a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp index 4ac28f4893..128d416ba1 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp @@ -15,19 +15,18 @@ namespace GridKit * Calls default ModelEvaluatorImpl constructor. * * - * Model is from paper: "Modeling, Analysis and Testing of Autonomous Operation - * of an Inverter-Based Microgrid", Nagaraju Pogaku, Milan Prodanovic, and - * Timothy C. Green, Section C + * Model is from paper: "Modeling, Analysis and Testing of Autonomous + * Operation of an Inverter-Based Microgrid", Nagaraju Pogaku, Milan + * Prodanovic, and Timothy C. Green, Section C * - * @todo Consider having \omegaref as a global constant, not a node variable. + * @todo Consider having \omegaref as a global constant, not a node + * variable. */ template - MicrogridLine::MicrogridLine(IdxT id, RealT R, RealT L, NodeT* node_ref, NodeT* bus1, NodeT* bus2) - : R_(R), - L_(L), - node_ref_(node_ref), - bus1_(bus1), - bus2_(bus2) + MicrogridLine::MicrogridLine( + IdxT id, RealT R, RealT L, NodeT* node_ref, NodeT* bus1, NodeT* bus2 + ) + : R_(R), L_(L), node_ref_(node_ref), bus1_(bus1), bus2_(bus2) { assert(node_ref_->size() == 1); assert(bus1_->size() == 2); @@ -93,8 +92,10 @@ namespace GridKit template int MicrogridLine::evaluateInternalResidual() { - f_int_[0] = -yp_int_[0] - (R_ / L_) * y_int_[0] + *y_ext_[0] * y_int_[1] + (*y_ext_[1] - *y_ext_[3]) / L_; - f_int_[1] = -yp_int_[1] - (R_ / L_) * y_int_[1] - *y_ext_[0] * y_int_[0] + (*y_ext_[2] - *y_ext_[4]) / L_; + f_int_[0] = -yp_int_[0] - (R_ / L_) * y_int_[0] + *y_ext_[0] * y_int_[1] + + (*y_ext_[1] - *y_ext_[3]) / L_; + f_int_[1] = -yp_int_[1] - (R_ / L_) * y_int_[1] - *y_ext_[0] * y_int_[0] + + (*y_ext_[2] - *y_ext_[4]) / L_; return 0; } @@ -135,12 +136,24 @@ namespace GridKit std::vector rcord(ccord.size(), 5); std::vector vals{}; - vals = {static_cast(y_int_[1]), (1.0 / L_), -(1.0 / L_), -(R_ / L_) - alpha_, static_cast(*y_ext_[0])}; + vals = { + static_cast(y_int_[1]), + (1.0 / L_), + -(1.0 / L_), + -(R_ / L_) - alpha_, + static_cast(*y_ext_[0]) + }; this->setJacValues(rcord, ccord, vals); std::vector ccor2{0, 2, 4, 5, 6}; std::fill(rcord.begin(), rcord.end(), 6); - vals = {-static_cast(y_int_[0]), (1.0 / L_), -(1.0 / L_), -static_cast(*y_ext_[0]), -(R_ / L_) - alpha_}; + vals = { + -static_cast(y_int_[0]), + (1.0 / L_), + -(1.0 / L_), + -static_cast(*y_ext_[0]), + -(R_ / L_) - alpha_ + }; this->setJacValues(rcord, ccor2, vals); return 0; diff --git a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp index dd520cb458..a0871d00d5 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp +++ b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp @@ -43,7 +43,9 @@ namespace GridKit using Component::n_intern_; public: - MicrogridLine(IdxT id, RealT R, RealT L, NodeT* node_ref, NodeT* bus1, NodeT* bus2); + MicrogridLine( + IdxT id, RealT R, RealT L, NodeT* node_ref, NodeT* bus1, NodeT* bus2 + ); virtual ~MicrogridLine(); int initialize(); diff --git a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp index 1d0e07f63e..8b784235a7 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp @@ -16,15 +16,16 @@ namespace GridKit * * * Model is from paper: " - "Modeling, Analysis and Testing of Autonomous Operation of an Inverter-Based Microgrid" Nagaraju Pogaku, Milan Prodanovic, and Timothy C. Green" + "Modeling, Analysis and Testing of Autonomous Operation of an + Inverter-Based Microgrid" Nagaraju Pogaku, Milan Prodanovic, and Timothy C. + Green" * Section D */ template - MicrogridLoad::MicrogridLoad(IdxT id, RealT R, RealT L, NodeT* node_ref, NodeT* node_bus) - : R_(R), - L_(L), - node_ref_(node_ref), - node_bus_(node_bus) + MicrogridLoad::MicrogridLoad( + IdxT id, RealT R, RealT L, NodeT* node_ref, NodeT* node_bus + ) + : R_(R), L_(L), node_ref_(node_ref), node_bus_(node_bus) { assert(node_ref_->size() == 1); assert(node_bus_->size() == 2); @@ -88,8 +89,10 @@ namespace GridKit template int MicrogridLoad::evaluateInternalResidual() { - f_int_[0] = -yp_int_[0] - (R_ / L_) * y_int_[0] + *y_ext_[0] * y_int_[1] + *y_ext_[1] / L_; - f_int_[1] = -yp_int_[1] - (R_ / L_) * y_int_[1] - *y_ext_[0] * y_int_[0] + *y_ext_[2] / L_; + f_int_[0] = -yp_int_[0] - (R_ / L_) * y_int_[0] + *y_ext_[0] * y_int_[1] + + *y_ext_[1] / L_; + f_int_[1] = -yp_int_[1] - (R_ / L_) * y_int_[1] - *y_ext_[0] * y_int_[0] + + *y_ext_[2] / L_; return 0; } @@ -128,12 +131,22 @@ namespace GridKit std::vector rcord(ccord.size(), 3); std::vector vals{}; - vals = {static_cast(y_int_[1]), (1.0 / L_), -(R_ / L_) - alpha_, static_cast(*y_ext_[0])}; + vals = { + static_cast(y_int_[1]), + (1.0 / L_), + -(R_ / L_) - alpha_, + static_cast(*y_ext_[0]) + }; this->setJacValues(rcord, ccord, vals); std::vector ccor2{0, 2, 3, 4}; std::fill(rcord.begin(), rcord.end(), 4); - vals = {-static_cast(y_int_[0]), (1.0 / L_), -static_cast(*y_ext_[0]), -(R_ / L_) - alpha_}; + vals = { + -static_cast(y_int_[0]), + (1.0 / L_), + -static_cast(*y_ext_[0]), + -(R_ / L_) - alpha_ + }; this->setJacValues(rcord, ccor2, vals); return 0; diff --git a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp index b5759d6098..fe0e0591bd 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp +++ b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp @@ -43,7 +43,9 @@ namespace GridKit using Component::n_intern_; public: - MicrogridLoad(IdxT id, RealT R, RealT L, NodeT* node_ref, NodeT* node_bus); + MicrogridLoad( + IdxT id, RealT R, RealT L, NodeT* node_ref, NodeT* node_bus + ); virtual ~MicrogridLoad(); int initialize(); diff --git a/GridKit/Model/PowerElectronics/Node.hpp b/GridKit/Model/PowerElectronics/Node.hpp index c9cd1b57ba..280d959eac 100644 --- a/GridKit/Model/PowerElectronics/Node.hpp +++ b/GridKit/Model/PowerElectronics/Node.hpp @@ -26,8 +26,7 @@ namespace GridKit size_ = 1; } - Node(ScalarT v0) - : V0_(v0) + Node(ScalarT v0) : V0_(v0) { size_ = 1; } @@ -132,10 +131,11 @@ namespace GridKit } /** - * @brief Node does not compute residuals, so here we just reset residual values. + * @brief Node does not compute residuals, so here we just reset residual + * values. * - * @warning This implementation assumes node residuals are always evaluated - * _before_ component model residuals. + * @warning This implementation assumes node residuals are always + * evaluated _before_ component model residuals. * */ int evaluateResidual() diff --git a/GridKit/Model/PowerElectronics/NodeBase.hpp b/GridKit/Model/PowerElectronics/NodeBase.hpp index 304dbb053c..5f154dcadc 100644 --- a/GridKit/Model/PowerElectronics/NodeBase.hpp +++ b/GridKit/Model/PowerElectronics/NodeBase.hpp @@ -103,17 +103,21 @@ namespace GridKit } /** - * @brief Create the mappings from local to global indices for a node variable (either internal or external), - * to be used from an attached component. \see Component::setExternalConnectionNodes() + * @brief Create the mappings from local to global indices for a node + * variable (either internal or external), to be used from an attached + * component. \see Component::setExternalConnectionNodes() * * @param local_index The index of the local variable * @param connection The necessary connection information for the variable * - * @pre `local_index` *must* be the index of an external variable. As of now, using this method - * to set information for a local variable will silently discard the unnecessary information, but - * this may change in the future. + * @pre `local_index` *must* be the index of an external variable. As of + * now, using this method to set information for a local variable will + * silently discard the unnecessary information, but this may change in + * the future. */ - int setExternalConnectionNodes(IdxT local_index, ExternalConnection connection) + int setExternalConnectionNodes( + IdxT local_index, ExternalConnection connection + ) { y_ext_[local_index] = connection.y_; yp_ext_[local_index] = connection.yp_; @@ -123,10 +127,12 @@ namespace GridKit } /** - * @brief Get connection information for a particular variable, to be consumed by an attached - * component so they can properly access their externals. + * @brief Get connection information for a particular variable, to be + * consumed by an attached component so they can properly access their + * externals. */ - ExternalConnection getNodeConnection(size_t local_index) const + ExternalConnection getNodeConnection(size_t local_index + ) const { return ExternalConnection{ .y_ = y_ext_[local_index], @@ -220,9 +226,11 @@ namespace GridKit size_t n_intern_; size_t n_extern_; - IdxT nnz_{0}; - std::vector variable_indices_; ///< Global (system-level) variable indices - std::vector residual_indices_; ///< Global (system-level) residual indices + IdxT nnz_{0}; + std::vector + variable_indices_; ///< Global (system-level) variable indices + std::vector + residual_indices_; ///< Global (system-level) residual indices std::vector tag_; VectorT abs_tol_; @@ -266,8 +274,7 @@ namespace GridKit VectorT f_; public: - virtual IdxT - sizeQuadrature() final + virtual IdxT sizeQuadrature() final { throw "ERROR: Method not implemented!\n"; return 0; diff --git a/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp b/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp index 7afb8a190a..63a0e431ac 100644 --- a/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp +++ b/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp @@ -15,7 +15,9 @@ namespace GridKit * Calls default ModelEvaluatorImpl constructor. */ template - Resistor::Resistor(IdxT id, RealT R, NodeT* node1, NodeT* node2) + Resistor::Resistor( + IdxT id, RealT R, NodeT* node1, NodeT* node2 + ) : R_(R), node1_(node1), node2_(node2) { assert(node1_->size() == 1); @@ -42,7 +44,8 @@ namespace GridKit return 0; } - /// There are no internal variables in this component, so \ref tag_ can be set arbitrarily. + /// There are no internal variables in this component, so \ref tag_ can be + /// set arbitrarily. template int Resistor::tagDifferentiable() { diff --git a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp index e834320bed..dc98547bee 100644 --- a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp +++ b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp @@ -35,7 +35,22 @@ namespace GridKit * @param[in] mub - rated frequency */ template - SynchronousMachine::SynchronousMachine(IdxT id, RealT Lls, std::tuple Llkq, RealT Llfd, RealT Llkd, RealT Lmq, RealT Lmd, RealT Rs, std::tuple Rkq, RealT Rfd, RealT Rkd, RealT RJ, RealT P, RealT mub) + SynchronousMachine::SynchronousMachine( + IdxT id, + RealT Lls, + std::tuple Llkq, + RealT Llfd, + RealT Llkd, + RealT Lmq, + RealT Lmd, + RealT Rs, + std::tuple Rkq, + RealT Rfd, + RealT Rkd, + RealT RJ, + RealT P, + RealT mub + ) : Lls_(Lls), Llkq_(Llkq), Llfd_(Llfd), @@ -123,11 +138,26 @@ namespace GridKit ScalarT cos23p = std::cos((P_ / 2.0) * y_int_[0] + (2.0 / 3.0) * pi); ScalarT sin23p = std::sin((P_ / 2.0) * y_int_[0] + (2.0 / 3.0) * pi); - f_int_[0] = (-2.0 / 3.0) * (*y_ext_[0] * cos1 + *y_ext_[1] * cos23m + *y_ext_[2] * cos23p) + Rs_ * y_int_[1] + (Lls_ + Lmq_) * yp_int_[1] + Lmq_ * yp_int_[4] + Lmq_ * yp_int_[5] + *y_ext_[4] * (P_ / 2.0) * ((Lls_ + Lmd_) * y_int_[2] + Lmd_ * y_int_[6] + Lmd_ * y_int_[7]); - f_int_[1] = (-2.0 / 3.0) * (*y_ext_[0] * sin1 - *y_ext_[1] * sin23m - *y_ext_[2] * sin23p) + Rs_ * y_int_[2] + (Lls_ + Lmd_) * yp_int_[2] + Lmd_ * yp_int_[6] + Lmd_ * yp_int_[7] - *y_ext_[4] * (P_ / 2.0) * ((Lls_ + Lmq_) * y_int_[1] + Lmq_ * y_int_[4] + Lmq_ * y_int_[5]); - f_int_[2] = (-1.0 / 3.0) * (*y_ext_[0] + *y_ext_[1] + *y_ext_[2]) + Rs_ * y_int_[3] + Lls_ * yp_int_[3]; - f_int_[3] = rkq1 * y_int_[4] + (llkq1 + Lmq_) * yp_int_[4] + Lmq_ * yp_int_[1] + Lmq_ * yp_int_[5]; - f_int_[4] = rkq1 * y_int_[4] + (llkq1 + Lmq_) * yp_int_[4] + Lmq_ * yp_int_[1] + Lmq_ * yp_int_[5]; + f_int_[0] = + (-2.0 / 3.0) + * (*y_ext_[0] * cos1 + *y_ext_[1] * cos23m + *y_ext_[2] * cos23p) + + Rs_ * y_int_[1] + (Lls_ + Lmq_) * yp_int_[1] + Lmq_ * yp_int_[4] + + Lmq_ * yp_int_[5] + + *y_ext_[4] * (P_ / 2.0) + * ((Lls_ + Lmd_) * y_int_[2] + Lmd_ * y_int_[6] + Lmd_ * y_int_[7]); + f_int_[1] = + (-2.0 / 3.0) + * (*y_ext_[0] * sin1 - *y_ext_[1] * sin23m - *y_ext_[2] * sin23p) + + Rs_ * y_int_[2] + (Lls_ + Lmd_) * yp_int_[2] + Lmd_ * yp_int_[6] + + Lmd_ * yp_int_[7] + - *y_ext_[4] * (P_ / 2.0) + * ((Lls_ + Lmq_) * y_int_[1] + Lmq_ * y_int_[4] + Lmq_ * y_int_[5]); + f_int_[2] = (-1.0 / 3.0) * (*y_ext_[0] + *y_ext_[1] + *y_ext_[2]) + + Rs_ * y_int_[3] + Lls_ * yp_int_[3]; + f_int_[3] = rkq1 * y_int_[4] + (llkq1 + Lmq_) * yp_int_[4] + + Lmq_ * yp_int_[1] + Lmq_ * yp_int_[5]; + f_int_[4] = rkq1 * y_int_[4] + (llkq1 + Lmq_) * yp_int_[4] + + Lmq_ * yp_int_[1] + Lmq_ * yp_int_[5]; return 0; } @@ -149,7 +179,10 @@ namespace GridKit *f_ext_[0] += y_int_[1] * cos1 + y_int_[2] * sin1 + y_int_[3]; *f_ext_[1] += y_int_[1] * cos23m + y_int_[2] * sin23m + y_int_[3]; *f_ext_[2] += y_int_[1] * cos23p + y_int_[2] * sin23p + y_int_[3]; - *f_ext_[3] += RJ_ * *yp_ext_[4] - (3.0 / 4.0) * P_ * (Lmd_ * y_int_[1] * (y_int_[2] + y_int_[6] + y_int_[7]) - Lmq_ * y_int_[2] * (y_int_[1] + y_int_[4] + *y_ext_[0])); + *f_ext_[3] += + RJ_ * *yp_ext_[4] + - (3.0 / 4.0) * P_ + * (Lmd_ * y_int_[1] * (y_int_[2] + y_int_[6] + y_int_[7]) - Lmq_ * y_int_[2] * (y_int_[1] + y_int_[4] + *y_ext_[0])); *f_ext_[4] += yp_int_[0] - *y_ext_[4]; return 0; } diff --git a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp index 39c21072e4..c63854b0a4 100644 --- a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp +++ b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp @@ -43,7 +43,22 @@ namespace GridKit using Component::n_intern_; public: - SynchronousMachine(IdxT id, RealT Lls, std::tuple Llkq, RealT Llfd, RealT Llkd, RealT Lmq, RealT Lmd, RealT Rs, std::tuple Rkq, RealT Rfd, RealT Rkd, RealT RJ, RealT P, RealT mub); + SynchronousMachine( + IdxT id, + RealT Lls, + std::tuple Llkq, + RealT Llfd, + RealT Llkd, + RealT Lmq, + RealT Lmd, + RealT Rs, + std::tuple Rkq, + RealT Rfd, + RealT Rkd, + RealT RJ, + RealT P, + RealT mub + ); virtual ~SynchronousMachine(); int initialize(); diff --git a/GridKit/Model/PowerElectronics/SystemModel.hpp b/GridKit/Model/PowerElectronics/SystemModel.hpp index 48629a4e89..b54a0d136e 100644 --- a/GridKit/Model/PowerElectronics/SystemModel.hpp +++ b/GridKit/Model/PowerElectronics/SystemModel.hpp @@ -84,7 +84,8 @@ namespace GridKit } /** - * @brief Will check if each component has jacobian available. If one doesn't have it, return false. + * @brief Will check if each component has jacobian available. If one + * doesn't have it, return false. * * * @return true if all components have jacobian @@ -108,14 +109,17 @@ namespace GridKit /** * @brief Allocate system vectors and construct the system CSR Jacobian * - * @post System model vectors allocated with the computed total number of unknowns + * @post System model vectors allocated with the computed total number of + * unknowns * @post CSR Jacobian sparsity pattern is computed * @post COO->CSR mapping is computed - * @post Every component's \ref Component::y_int_, \ref Component::yp_int_, and \ref Component::f_int_ pointers - * are set to their appropriate offsets in the system vector, allowing them to directly access their internal variables, derivatives, - * and residuals. + * @post Every component's \ref Component::y_int_, \ref + * Component::yp_int_, and \ref Component::f_int_ pointers are set to + * their appropriate offsets in the system vector, allowing them to + * directly access their internal variables, derivatives, and residuals. * - * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable + * @return int 0 if successful, positive if there's a recoverable error, + * negative if unrecoverable */ int allocate() final { @@ -135,7 +139,8 @@ namespace GridKit n_extern_ = 0; size_ = n_intern_ + n_extern_; - // Allocation always rebuilds the system Jacobian and its COO-to-CSR map. + // Allocation always rebuilds the system Jacobian and its COO-to-CSR + // map. delete csr_jac_; csr_jac_ = nullptr; @@ -151,7 +156,8 @@ namespace GridKit tag_.resize(size_); - { // Start node internal indexing after all component internals for proper KLU ordering + { // Start node internal indexing after all component internals for + // proper KLU ordering size_t node_internal_idx = component_internal_size; for (node_type* node : nodes_) { @@ -173,8 +179,8 @@ namespace GridKit } { - // The offset for each component's internal variables in the system vector. - // They start at 0, and are stacked on top of each other. + // The offset for each component's internal variables in the system + // vector. They start at 0, and are stacked on top of each other. size_t component_internal_idx = 0; for (component_type* comp : components_) { @@ -182,7 +188,8 @@ namespace GridKit // Update component internal pointers to their correct offsets comp->setInternalPointer(&y_int_[component_internal_idx]); - comp->setInternalDerivativePointer(&yp_int_[component_internal_idx]); + comp->setInternalDerivativePointer(&yp_int_[component_internal_idx] + ); comp->setInternalResidualPointer(&f_int_[component_internal_idx]); const auto& external_indices = comp->getExternIndices(); @@ -213,14 +220,16 @@ namespace GridKit for (IdxT i = 0; i < nnz; ++i) { - if (component->getNodeConnection(r[i]) != neg1_ && component->getNodeConnection(c[i]) != neg1_) + if (component->getNodeConnection(r[i]) != neg1_ + && component->getNodeConnection(c[i]) != neg1_) { ++nnz_dup; } } } - // Allocate COO triplet arrays (we own these until we hand off to CsrMatrix) + // Allocate COO triplet arrays (we own these until we hand off to + // CsrMatrix) IdxT* rows_dup = new IdxT[nnz_dup]; IdxT* cols_dup = new IdxT[nnz_dup]; RealT* vals_dup = new RealT[nnz_dup]; @@ -235,7 +244,8 @@ namespace GridKit for (IdxT i = 0; i < nnz; ++i) { - if (component->getNodeConnection(r[i]) != neg1_ && component->getNodeConnection(c[i]) != neg1_) + if (component->getNodeConnection(r[i]) != neg1_ + && component->getNodeConnection(c[i]) != neg1_) { rows_dup[counter] = component->getNodeConnection(r[i]); cols_dup[counter] = component->getNodeConnection(c[i]); @@ -246,7 +256,9 @@ namespace GridKit } // Build the system COO Jacobian - LinearAlgebra::CooMatrix jac(size_, size_, nnz_dup, &rows_dup, &cols_dup, &vals_dup); + LinearAlgebra::CooMatrix jac( + size_, size_, nnz_dup, &rows_dup, &cols_dup, &vals_dup + ); // Populate CSR data with sort and deduplicate IdxT* row_ptrs = jac.getCsrRowData(); @@ -281,7 +293,8 @@ namespace GridKit /** * @brief Set initial y and y' of each component * - * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable + * @return int 0 if successful, positive if there's a recoverable error, + * negative if unrecoverable */ int initialize() final { @@ -298,13 +311,16 @@ namespace GridKit * @brief Tags all system variables as differentiable, based on what the * components that own those variables tag them as. * - * Starts by asking all components to tag their differentiables. This implementation - * assumes all node variables are algebraic, and will not ask nodes to tag their differentiables. - * Sets all variables to algebraic (`false`) to start, then loops over all component internal variables. - * Re-creates the same internal variable to system variables mapping as in \ref allocate() - all - * internal variables from the same component are stored contiguously in a block, and blocks are - * stored contiguously in the same order as \ref components_, with node variables at the end. - * Each internal variable's tag in the system is set to its tag in the component. + * Starts by asking all components to tag their differentiables. This + * implementation assumes all node variables are algebraic, and will not + * ask nodes to tag their differentiables. Sets all variables to algebraic + * (`false`) to start, then loops over all component internal variables. + * Re-creates the same internal variable to system variables mapping as in + * \ref allocate() - all internal variables from the same component are + * stored contiguously in a block, and blocks are stored contiguously in + * the same order as \ref components_, with node variables at the end. + * Each internal variable's tag in the system is set to its tag in the + * component. */ int tagDifferentiable() final { @@ -320,10 +336,12 @@ namespace GridKit } } - // Fill tags with a default value (false) for node variables. Assumed to be algebraic here. + // Fill tags with a default value (false) for node variables. Assumed to + // be algebraic here. std::fill(tag_.begin(), tag_.end(), false); - // Copy tags for internal variables from their components - going in the order as described above + // Copy tags for internal variables from their components - going in the + // order as described above size_t idx = 0; for (component_type* comp : components_) { @@ -337,7 +355,8 @@ namespace GridKit { tag_[idx] = comp->tag()[i]; - // Ensures internal variables are contiguous, and in the same order as the component + // Ensures internal variables are contiguous, and in the same + // order as the component idx++; } } @@ -367,7 +386,8 @@ namespace GridKit /** * @brief Evaluate Residuals at each component then collect them * - * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable + * @return int 0 if successful, positive if there's a recoverable error, + * negative if unrecoverable */ int evaluateInternalResidual() final { @@ -378,7 +398,8 @@ namespace GridKit // Update system residual vector - // Evaluate component internal residuals - this is embarrassingly parallel + // Evaluate component internal residuals - this is embarrassingly + // parallel for (component_type* component : components_) { if (int err_code = component->evaluateInternalResidual()) @@ -403,12 +424,14 @@ namespace GridKit } /** - * @brief Creates the system Jacobian representing \f$\alpha dF/dy' + dF/dy\f$ + * @brief Creates the system Jacobian representing \f$\alpha dF/dy' + + * dF/dy\f$ * * Updates the CSR Jacobian values using the per-component mappings * computed during allocate(). * - * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable + * @return int 0 if successful, positive if there's a recoverable error, + * negative if unrecoverable */ int evaluateJacobian() final { @@ -432,7 +455,8 @@ namespace GridKit for (IdxT i = 0; i < nnz; ++i) { - if (component->getNodeConnection(r[i]) != neg1_ && component->getNodeConnection(c[i]) != neg1_) + if (component->getNodeConnection(r[i]) != neg1_ + && component->getNodeConnection(c[i]) != neg1_) { vals[map_to_csr_[counter]] += v[i]; ++counter; diff --git a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp index 9d250e2c02..19d8ab9f55 100644 --- a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp +++ b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp @@ -15,15 +15,16 @@ namespace GridKit * Calls default ModelEvaluatorImpl constructor. * * This is the Medium distance form with the use of the admittance matrix. - * Since the line is of medium length then there is no real part for shunt admittance + * Since the line is of medium length then there is no real part for shunt + * admittance * @todo needs to used in a model * @todo test for correctness */ template - TransmissionLine::TransmissionLine(IdxT id, RealT R, RealT X, RealT B) - : R_(R), - X_(X), - B_(B) + TransmissionLine::TransmissionLine( + IdxT id, RealT R, RealT X, RealT B + ) + : R_(R), X_(X), B_(B) { // internals [Iret1, Iimt1, Iret2, Iimt2] // externals [Vre11, Vim11, Vre12, Vim12, Vre21, Vim21, Vre22, Vim22] @@ -100,7 +101,8 @@ namespace GridKit * Ire = Dre Vre - Dim Vim * Iim = Dre Vim + Dim Vre * - * To express this for Modified Nodal Analysis the Voltages of the admittance matrix are put into voltage drops + * To express this for Modified Nodal Analysis the Voltages of the + * admittance matrix are put into voltage drops */ template int TransmissionLine::evaluateInternalResidual() @@ -113,12 +115,16 @@ namespace GridKit // Internal variables // row 1 - f_int_[0] = YReMat_ * (V1re - V2re) - (YImMatDi_ * V1im + YImMatOff_ * V2im) - y_int_[0]; - f_int_[1] = YReMat_ * (V1im - V2im) + (YImMatDi_ * V1re + YImMatOff_ * V2re) - y_int_[1]; + f_int_[0] = YReMat_ * (V1re - V2re) + - (YImMatDi_ * V1im + YImMatOff_ * V2im) - y_int_[0]; + f_int_[1] = YReMat_ * (V1im - V2im) + + (YImMatDi_ * V1re + YImMatOff_ * V2re) - y_int_[1]; // row2 - f_int_[2] = YReMat_ * (V2re - V1re) - (YImMatOff_ * V1im + YImMatDi_ * V2im) - y_int_[2]; - f_int_[3] = YReMat_ * (V2im - V1im) + (YImMatOff_ * V1re + YImMatDi_ * V2re) - y_int_[3]; + f_int_[2] = YReMat_ * (V2re - V1re) + - (YImMatOff_ * V1im + YImMatDi_ * V2im) - y_int_[2]; + f_int_[3] = YReMat_ * (V2im - V1im) + + (YImMatOff_ * V1re + YImMatDi_ * V2re) - y_int_[3]; return 0; } @@ -157,25 +163,63 @@ namespace GridKit // Create dF/dy std::vector rtemp{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; std::vector ctemp{8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11}; - std::vector vals{1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}; + std::vector vals{ + 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0 + }; this->setJacValues(rtemp, ctemp, vals); std::vector ccord{0, 1, 2, 3, 4, 5, 6, 7}; std::vector rcord(ccord.size(), 8); - vals = {YReMat_, -YImMatDi_, -YReMat_, -YImMatOff_, -YReMat_, YImMatDi_, YReMat_, YImMatOff_}; + vals = { + YReMat_, + -YImMatDi_, + -YReMat_, + -YImMatOff_, + -YReMat_, + YImMatDi_, + YReMat_, + YImMatOff_ + }; this->setJacValues(rtemp, ctemp, vals); std::fill(rcord.begin(), rcord.end(), 9); - vals = {YImMatDi_, YReMat_, YImMatOff_, -YReMat_, -YImMatDi_, -YReMat_, -YImMatOff_, YReMat_}; + vals = { + YImMatDi_, + YReMat_, + YImMatOff_, + -YReMat_, + -YImMatDi_, + -YReMat_, + -YImMatOff_, + YReMat_ + }; this->setJacValues(rtemp, ctemp, vals); std::fill(rcord.begin(), rcord.end(), 10); - vals = {-YReMat_, -YImMatDi_, YReMat_, -YImMatOff_, YReMat_, YImMatDi_, -YReMat_, YImMatOff_}; + vals = { + -YReMat_, + -YImMatDi_, + YReMat_, + -YImMatOff_, + YReMat_, + YImMatDi_, + -YReMat_, + YImMatOff_ + }; this->setJacValues(rtemp, ctemp, vals); std::fill(rcord.begin(), rcord.end(), 11); - vals = {YImMatDi_, -YReMat_, YImMatOff_, YReMat_, -YImMatDi_, YReMat_, -YImMatOff_, -YReMat_}; + vals = { + YImMatDi_, + -YReMat_, + YImMatOff_, + YReMat_, + -YImMatDi_, + YReMat_, + -YImMatOff_, + -YReMat_ + }; this->setJacValues(rtemp, ctemp, vals); return 0; diff --git a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp index 7a21c4bf7b..061e913f70 100644 --- a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp +++ b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp @@ -17,7 +17,8 @@ namespace GridKit * @brief Declaration of a TransmissionLine class. * * Model from Adam Birchfield paper (medium distances < 2km). - * See also textbooks "Power System Analysis" by Grainger and "Power System Dynamics and Stability" by Sauer & Pai + * See also textbooks "Power System Analysis" by Grainger and "Power System + * Dynamics and Stability" by Sauer & Pai * * @note Not used in the Microgrid model. */ diff --git a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp index f941f09f3c..0d567c4b51 100644 --- a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp +++ b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp @@ -15,7 +15,9 @@ namespace GridKit * Calls default ModelEvaluatorImpl constructor. */ template - VoltageSource::VoltageSource(IdxT id, RealT V, NodeT* node1, NodeT* node2) + VoltageSource::VoltageSource( + IdxT id, RealT V, NodeT* node1, NodeT* node2 + ) : V_(V), node1_(node1), node2_(node2) { assert(node1_->size() == 1); diff --git a/GridKit/Model/PowerFlow/Branch/Branch.cpp b/GridKit/Model/PowerFlow/Branch/Branch.cpp index 08e7538cb9..7c2051d9fa 100644 --- a/GridKit/Model/PowerFlow/Branch/Branch.cpp +++ b/GridKit/Model/PowerFlow/Branch/Branch.cpp @@ -36,7 +36,9 @@ namespace GridKit } template - Branch::Branch(RealT R, RealT X, RealT G, RealT B, bus_type* bus1, bus_type* bus2) + Branch::Branch( + RealT R, RealT X, RealT G, RealT B, bus_type* bus1, bus_type* bus2 + ) : R_(R), X_(X), G_(G), @@ -49,7 +51,9 @@ namespace GridKit } template - Branch::Branch(bus_type* bus1, bus_type* bus2, BranchData& data) + Branch::Branch( + bus_type* bus1, bus_type* bus2, BranchData& data + ) : R_(data.r), X_(data.x), G_(0.0), @@ -126,10 +130,14 @@ namespace GridKit RealT g = R_ / (R_ * R_ + X_ * X_); ScalarT dtheta = theta1() - theta2(); - P1() -= (g + 0.5 * G_) * V1() * V1() + V1() * V2() * (-g * std::cos(dtheta) - b * std::sin(dtheta)); - Q1() -= (-b - 0.5 * B_) * V1() * V1() + V1() * V2() * (-g * std::sin(dtheta) + b * std::cos(dtheta)); - P2() -= (g + 0.5 * G_) * V2() * V2() + V1() * V2() * (-g * std::cos(dtheta) + b * std::sin(dtheta)); - Q2() -= (-b - 0.5 * B_) * V2() * V2() + V1() * V2() * (g * std::sin(dtheta) + b * std::cos(dtheta)); + P1() -= (g + 0.5 * G_) * V1() * V1() + + V1() * V2() * (-g * std::cos(dtheta) - b * std::sin(dtheta)); + Q1() -= (-b - 0.5 * B_) * V1() * V1() + + V1() * V2() * (-g * std::sin(dtheta) + b * std::cos(dtheta)); + P2() -= (g + 0.5 * G_) * V2() * V2() + + V1() * V2() * (-g * std::cos(dtheta) + b * std::sin(dtheta)); + Q2() -= (-b - 0.5 * B_) * V2() * V2() + + V1() * V2() * (g * std::sin(dtheta) + b * std::cos(dtheta)); if (bus1_->size() > 0) { @@ -146,7 +154,8 @@ namespace GridKit template int Branch::evaluateJacobian() { - ::GridKit::Utilities::Logger::warning() << "Branch: Jacobian evaluation not implemented!\n"; + ::GridKit::Utilities::Logger::warning() + << "Branch: Jacobian evaluation not implemented!\n"; return 0; } diff --git a/GridKit/Model/PowerFlow/Bus/BaseBus.hpp b/GridKit/Model/PowerFlow/Bus/BaseBus.hpp index 5002f320e3..5b9f616f4a 100644 --- a/GridKit/Model/PowerFlow/Bus/BaseBus.hpp +++ b/GridKit/Model/PowerFlow/Bus/BaseBus.hpp @@ -49,8 +49,7 @@ namespace GridKit Isolated }; - BaseBus(IdxT id) - : busID_(id) + BaseBus(IdxT id) : busID_(id) { } diff --git a/GridKit/Model/PowerFlow/Bus/BusFactory.hpp b/GridKit/Model/PowerFlow/Bus/BusFactory.hpp index 2d12e31e39..7f4dd31dba 100644 --- a/GridKit/Model/PowerFlow/Bus/BusFactory.hpp +++ b/GridKit/Model/PowerFlow/Bus/BusFactory.hpp @@ -34,7 +34,8 @@ namespace GridKit break; default: // Throw exception - ::GridKit::Utilities::Logger::error() << "Bus type " << data.type << " unrecognized.\n"; + ::GridKit::Utilities::Logger::error() + << "Bus type " << data.type << " unrecognized.\n"; } return bus; } diff --git a/GridKit/Model/PowerFlow/Bus/BusPQ.cpp b/GridKit/Model/PowerFlow/Bus/BusPQ.cpp index 1e359f3537..a0b673274f 100644 --- a/GridKit/Model/PowerFlow/Bus/BusPQ.cpp +++ b/GridKit/Model/PowerFlow/Bus/BusPQ.cpp @@ -116,7 +116,8 @@ namespace GridKit } /*! - * @brief PQ bus does not compute residuals, so here we just reset residual values. + * @brief PQ bus does not compute residuals, so here we just reset residual + * values. * * @warning This implementation assumes bus residuals are always evaluated * _before_ component model residuals. diff --git a/GridKit/Model/PowerFlow/Bus/BusPV.cpp b/GridKit/Model/PowerFlow/Bus/BusPV.cpp index e34a173819..d47cd2aa2c 100644 --- a/GridKit/Model/PowerFlow/Bus/BusPV.cpp +++ b/GridKit/Model/PowerFlow/Bus/BusPV.cpp @@ -110,7 +110,8 @@ namespace GridKit } /*! - * @brief PV bus does not compute residuals, so here we just reset residual values. + * @brief PV bus does not compute residuals, so here we just reset residual + * values. * * @warning This implementation assumes bus residuals are always evaluated * _before_ component model residuals. diff --git a/GridKit/Model/PowerFlow/Bus/BusSlack.cpp b/GridKit/Model/PowerFlow/Bus/BusSlack.cpp index 4b27307517..fde110147e 100644 --- a/GridKit/Model/PowerFlow/Bus/BusSlack.cpp +++ b/GridKit/Model/PowerFlow/Bus/BusSlack.cpp @@ -18,7 +18,13 @@ namespace GridKit */ template BusSlack::BusSlack() - : BaseBus(0), V_(0.0), theta_(0.0), P_(0.0), Q_(0.0), PB_(0.0), QB_(0.0) + : BaseBus(0), + V_(0.0), + theta_(0.0), + P_(0.0), + Q_(0.0), + PB_(0.0), + QB_(0.0) { size_ = 0; } @@ -34,7 +40,13 @@ namespace GridKit */ template BusSlack::BusSlack(ScalarT V, ScalarT theta) - : BaseBus(0), V_(V), theta_(theta), P_(0.0), Q_(0.0), PB_(0.0), QB_(0.0) + : BaseBus(0), + V_(V), + theta_(theta), + P_(0.0), + Q_(0.0), + PB_(0.0), + QB_(0.0) { P() = 0.0; Q() = 0.0; diff --git a/GridKit/Model/PowerFlow/Generator/GeneratorFactory.hpp b/GridKit/Model/PowerFlow/Generator/GeneratorFactory.hpp index 54db296ee6..db41568187 100644 --- a/GridKit/Model/PowerFlow/Generator/GeneratorFactory.hpp +++ b/GridKit/Model/PowerFlow/Generator/GeneratorFactory.hpp @@ -19,7 +19,9 @@ namespace GridKit GeneratorFactory() = delete; - static GeneratorBase* create(BaseBus* bus, GenData& data) + static GeneratorBase* create( + BaseBus* bus, GenData& data + ) { GeneratorBase* gen = nullptr; switch (bus->BusType()) @@ -35,7 +37,8 @@ namespace GridKit break; default: // Throw exception - ::GridKit::Utilities::Logger::error() << "Generator type " << bus->BusType() << " unrecognized.\n"; + ::GridKit::Utilities::Logger::error() + << "Generator type " << bus->BusType() << " unrecognized.\n"; } return gen; } diff --git a/GridKit/Model/PowerFlow/Generator/GeneratorPQ.cpp b/GridKit/Model/PowerFlow/Generator/GeneratorPQ.cpp index b5a0e3b683..46be1f2552 100644 --- a/GridKit/Model/PowerFlow/Generator/GeneratorPQ.cpp +++ b/GridKit/Model/PowerFlow/Generator/GeneratorPQ.cpp @@ -18,9 +18,7 @@ namespace GridKit template GeneratorPQ::GeneratorPQ(bus_type* bus, GenData& data) - : P_(data.Pg), - Q_(data.Qg), - bus_(bus) + : P_(data.Pg), Q_(data.Qg), bus_(bus) { size_ = 0; } diff --git a/GridKit/Model/PowerFlow/Generator/GeneratorSlack.cpp b/GridKit/Model/PowerFlow/Generator/GeneratorSlack.cpp index 31eaac6dd3..a28c6dc20f 100644 --- a/GridKit/Model/PowerFlow/Generator/GeneratorSlack.cpp +++ b/GridKit/Model/PowerFlow/Generator/GeneratorSlack.cpp @@ -17,7 +17,8 @@ namespace GridKit */ template - GeneratorSlack::GeneratorSlack(bus_type* bus, GenData& /* data */) + GeneratorSlack:: + GeneratorSlack(bus_type* bus, GenData& /* data */) : bus_(bus) { size_ = 0; diff --git a/GridKit/Model/PowerFlow/Generator2/Generator2.cpp b/GridKit/Model/PowerFlow/Generator2/Generator2.cpp index 42c0308930..69b0ba458c 100644 --- a/GridKit/Model/PowerFlow/Generator2/Generator2.cpp +++ b/GridKit/Model/PowerFlow/Generator2/Generator2.cpp @@ -106,7 +106,10 @@ namespace GridKit const auto* param = param_.getData(); f[0] = -yp[0] + omega_b_ * (y[1] - omega_s_); - f[1] = -yp[1] + omega_s_ / (2.0 * H_) * (param[0] - Eqp_ / Xdp_ * V() * std::sin(y[0] - theta()) - D_ * (y[1] - omega_s_)); + f[1] = + -yp[1] + + omega_s_ / (2.0 * H_) + * (param[0] - Eqp_ / Xdp_ * V() * std::sin(y[0] - theta()) - D_ * (y[1] - omega_s_)); f_.setDataUpdated(); return 0; } @@ -114,7 +117,8 @@ namespace GridKit template int Generator2::evaluateJacobian() { - ::GridKit::Utilities::Logger::warning() << "Generator2: Jacobian evaluation not implemented!\n"; + ::GridKit::Utilities::Logger::warning() + << "Generator2: Jacobian evaluation not implemented!\n"; return 0; } @@ -155,8 +159,11 @@ namespace GridKit const auto* ypB = ypB_.getData(); auto* fB = fB_.getData(); - fB[0] = -ypB[0] + omega_s_ / (2.0 * H_) * Eqp_ / Xdp_ * V() * std::cos(y[0] - theta()) * yB[1]; - fB[1] = -ypB[1] + omega_s_ / (2.0 * H_) * D_ * yB[1] - omega_b_ * yB[0] + frequencyPenaltyDer(y[1]); + fB[0] = -ypB[0] + + omega_s_ / (2.0 * H_) * Eqp_ / Xdp_ * V() + * std::cos(y[0] - theta()) * yB[1]; + fB[1] = -ypB[1] + omega_s_ / (2.0 * H_) * D_ * yB[1] - omega_b_ * yB[0] + + frequencyPenaltyDer(y[1]); fB_.setDataUpdated(); return 0; } @@ -177,17 +184,22 @@ namespace GridKit // /** - * Frequency penalty is used as the objective function for the generator model. + * Frequency penalty is used as the objective function for the generator + * model. */ template ScalarT Generator2::frequencyPenalty(ScalarT omega) { - return c_ * std::pow(std::max(0.0, std::max(omega - omega_up_, omega_lo_ - omega)), beta_); + return c_ + * std::pow( + std::max(0.0, std::max(omega - omega_up_, omega_lo_ - omega)), + beta_ + ); } /** - * Derivative of frequency penalty cannot be written in terms of min/max functions. - * Need to expand conditional statements instead. + * Derivative of frequency penalty cannot be written in terms of min/max + * functions. Need to expand conditional statements instead. */ template ScalarT Generator2::frequencyPenaltyDer(ScalarT omega) diff --git a/GridKit/Model/PowerFlow/Generator4/Generator4.cpp b/GridKit/Model/PowerFlow/Generator4/Generator4.cpp index bc935e1e5c..9a3014e8ac 100644 --- a/GridKit/Model/PowerFlow/Generator4/Generator4.cpp +++ b/GridKit/Model/PowerFlow/Generator4/Generator4.cpp @@ -68,8 +68,10 @@ namespace GridKit * Modeling and Scripting, Federico Milano, Chapter 9, p. 225: * \f{eqnarray*}{ * &~& \omega_0 = 0, \\ - * &~& \delta_0 = \tan^{-1} \left(\frac{X_q P_0 - R_s Q_0}{V_0^2 + R_s P_0 + X_q Q_0} \right) + \theta_0, \\ - * &~& \phi_0 = \delta_0 - \theta_0 + \tan^{-1} \left( \frac{Q_0}{P_0} \right), \\ + * &~& \delta_0 = \tan^{-1} \left(\frac{X_q P_0 - R_s Q_0}{V_0^2 + R_s P_0 + + * X_q Q_0} \right) + \theta_0, \\ + * &~& \phi_0 = \delta_0 - \theta_0 + \tan^{-1} \left( \frac{Q_0}{P_0} + * \right), \\ * &~& I_{d0} = \frac{\sqrt{P_0^2 + Q_0^2}}{V_0} \sin(\phi_0), \\ * &~& I_{q0} = \frac{\sqrt{P_0^2 + Q_0^2}}{V_0} \cos(\phi_0), \\ * &~& E_{d0}' = V_0 \sin(\delta_0 - \theta_0) + R_s I_{d0} - X_q' I_{q0}, \\ @@ -87,12 +89,15 @@ namespace GridKit int Generator4::initialize() { // Compute initial guess for the generator voltage phase - const ScalarT delta = atan((Xq_ * P0_ - Rs_ * Q0_) / (V() * V() + Rs_ * P0_ + Xq_ * Q0_)) + theta(); + const ScalarT delta = + atan((Xq_ * P0_ - Rs_ * Q0_) / (V() * V() + Rs_ * P0_ + Xq_ * Q0_)) + + theta(); // Compute initial guess for the generator current phase const ScalarT phi = theta() - delta - atan(Q0_ / P0_); - // Compute initial guesses for generator currents and potentials in d-q frame + // Compute initial guesses for generator currents and potentials in d-q + // frame const ScalarT Id = std::sqrt(P0_ * P0_ + Q0_ * Q0_) / V() * std::sin(phi); const ScalarT Iq = std::sqrt(P0_ * P0_ + Q0_ * Q0_) / V() * std::cos(phi); const ScalarT Ed = V() * std::sin(theta() - delta) + Rs_ * Id + Xqp_ * Iq; @@ -115,8 +120,9 @@ namespace GridKit yp[5] = 0.0; // Set control parameter values here. - Ef_ = Eq - (Xd_ - Xdp_) * Id; // <~ set to steady state value - Pm_ = Ed * Id + Eq * Iq + (Xdp_ - Xqp_) * Id * Iq; // <~ set to steady state value + Ef_ = Eq - (Xd_ - Xdp_) * Id; // <~ set to steady state value + Pm_ = Ed * Id + Eq * Iq + + (Xdp_ - Xqp_) * Id * Iq; // <~ set to steady state value // Initialize optimization parameters auto* param = param_.getData(); @@ -185,7 +191,8 @@ namespace GridKit * Scripting, Federico Milano, Chapter 15, p. 334: * \f{eqnarray*}{ * f_0: &~& \dot{\delta} -\omega_b (\omega - \omega_s), \\ - * f_1: &~& 2H/\omega_s \dot{\omega} - L_m(P_m) + E_q' I_q + E_d' I_d + (X_q' - X_d')I_d I_q + D (\omega - \omega_s), \\ + * f_1: &~& 2H/\omega_s \dot{\omega} - L_m(P_m) + E_q' I_q + E_d' I_d + (X_q' + * - X_d')I_d I_q + D (\omega - \omega_s), \\ * f_2: &~& T_{q0}' \dot{E}_d' + E_d' - (X_q - X_q')I_q, \\ * f_3: &~& T_{d0}' \dot{E}_q' + E_q' + (X_d - X_d')I_d - E_f, \\ * f_4: &~& R_s I_d - X_q' I_q + V \sin(\delta - \theta) - E_d', \\ @@ -196,13 +203,15 @@ namespace GridKit * * Generator injection active and reactive power are * \f{eqnarray*}{ - * P_g &=& E_d' I_d + E_q' I_q + (X_q' - X_d') I_d I_q - R_s (I_d^2 + I_q^2), \\ + * P_g &=& E_d' I_d + E_q' I_q + (X_q' - X_d') I_d I_q - R_s (I_d^2 + I_q^2), + * \\ * Q_q &=& E_q' I_d - E_d' I_q - X_q' I_q^2 - X_d' I_d^2, \\ * \f} * respectively. * * State variables are: - * \f$ y_0 = \omega \f$, \f$ y_1 = \delta \f$, \f$ y_2 = E_d' \f$, \f$ y_3 = E_q' \f$, + * \f$ y_0 = \omega \f$, \f$ y_1 = \delta \f$, \f$ y_2 = E_d' \f$, \f$ y_3 = + * E_q' \f$, * \f$ y_4 = I_d \f$, \f$ y_5 = I_q \f$. * */ @@ -212,7 +221,9 @@ namespace GridKit auto* f = f_.getData(); f[0] = dotDelta() - omega_b_ * (omega() - omega_s_); - f[1] = (2.0 * H_) / omega_s_ * dotOmega() - Pm() + Eqp() * Iq() + Edp() * Id() + (-Xdp_ + Xqp_) * Id() * Iq() + D_ * (omega() - omega_s_); + f[1] = (2.0 * H_) / omega_s_ * dotOmega() - Pm() + Eqp() * Iq() + + Edp() * Id() + (-Xdp_ + Xqp_) * Id() * Iq() + + D_ * (omega() - omega_s_); f[2] = Tq0p_ * dotEdp() + Edp() - (Xq_ - Xqp_) * Iq(); f[3] = Td0p_ * dotEqp() + Eqp() + (Xd_ - Xdp_) * Id() - Ef(); f[4] = Rs_ * Id() - Xqp_ * Iq() + V() * std::sin(delta() - theta()) - Edp(); @@ -234,7 +245,8 @@ namespace GridKit template int Generator4::evaluateJacobian() { - ::GridKit::Utilities::Logger::warning() << "Generator4: Jacobian evaluation not implemented!\n"; + ::GridKit::Utilities::Logger::warning() + << "Generator4: Jacobian evaluation not implemented!\n"; return 0; } @@ -274,12 +286,20 @@ namespace GridKit * * Adjoint residual equations are given as: * \f{eqnarray*}{ - * f_{B0}: &~& \dot{y}_{B0} - y_{B4} V \cos(\delta - \theta) + y_{B5} V \sin(\delta - \theta), \\ - * f_{B1}: &~& 2H/\omega_s \dot{y}_{B1} + y_{B0} \omega_b - y_{B1} D + y_{B9} (1 - T_2/T_1) - y_{B10} K T_2/T_1 + g_{\omega}(\omega), \\ - * f_{B2}: &~& T_{q0}' \dot{y}_{B2} - y_{B1} I_d - y_{B2} + y_{B4} + y_{B6} I_d - y_{B7} I_q, \\ - * f_{B3}: &~& T_{d0}' \dot{y}_{B3} - y_{B1} I_q - y_{B3} + y_{B5} + y_{B6} I_q + y_{B7} I_d, \\ - * f_{B4}: &~& -y_{B1} (E_d' + (-X_d'+X_q') I_q) - y_{B3} (X_d - X_d') - y_{B4} R_s - y_{B5} X_d' + y_{B6} (E_d' + (X_q' - X_d') I_q - 2 R_s I_d) + y_{B7} (E_q' - 2 X_d' I_d), \\ - * f_{B5}: &~& -y_{B1} (E_q' + (-X_d'+X_q') I_d) + y_{B2} (X_q - X_q') + y_{B4} X_q' - y_{B5} R_s + y_{B6} (E_q' + (X_q' - X_d') I_d - 2 R_s I_q) - y_{B7} (E_d' + 2 X_q' I_q). \\ + * f_{B0}: &~& \dot{y}_{B0} - y_{B4} V \cos(\delta - \theta) + y_{B5} V + * \sin(\delta - \theta), \\ + * f_{B1}: &~& 2H/\omega_s \dot{y}_{B1} + y_{B0} \omega_b - y_{B1} D + y_{B9} + * (1 - T_2/T_1) - y_{B10} K T_2/T_1 + g_{\omega}(\omega), \\ + * f_{B2}: &~& T_{q0}' \dot{y}_{B2} - y_{B1} I_d - y_{B2} + y_{B4} + y_{B6} + * I_d - y_{B7} I_q, \\ + * f_{B3}: &~& T_{d0}' \dot{y}_{B3} - y_{B1} I_q - y_{B3} + y_{B5} + y_{B6} + * I_q + y_{B7} I_d, \\ + * f_{B4}: &~& -y_{B1} (E_d' + (-X_d'+X_q') I_q) - y_{B3} (X_d - X_d') - + * y_{B4} R_s - y_{B5} X_d' + y_{B6} (E_d' + (X_q' - X_d') I_q - 2 R_s I_d) + + * y_{B7} (E_q' - 2 X_d' I_d), \\ + * f_{B5}: &~& -y_{B1} (E_q' + (-X_d'+X_q') I_d) + y_{B2} (X_q - X_q') + + * y_{B4} X_q' - y_{B5} R_s + y_{B6} (E_q' + (X_q' - X_d') I_d - 2 R_s I_q) - + * y_{B7} (E_d' + 2 X_q' I_q). \\ * \f} * */ @@ -295,11 +315,14 @@ namespace GridKit // Generator adjoint fB[0] = ypB[0] - yB[4] * V() * cosPhi + yB[5] * V() * sinPhi; - fB[1] = 2.0 * H_ / omega_s_ * ypB[1] + yB[0] * omega_b_ - yB[1] * D_ + frequencyPenaltyDer(omega()); + fB[1] = 2.0 * H_ / omega_s_ * ypB[1] + yB[0] * omega_b_ - yB[1] * D_ + + frequencyPenaltyDer(omega()); fB[2] = Tq0p_ * ypB[2] - yB[1] * Id() - yB[2] + yB[4]; fB[3] = Td0p_ * ypB[3] - yB[1] * Iq() - yB[3] + yB[5]; - fB[4] = -yB[1] * (Edp() + (Xqp_ - Xdp_) * Iq()) - yB[3] * (Xd_ - Xdp_) - yB[4] * Rs_ - yB[5] * Xdp_; - fB[5] = -yB[1] * (Eqp() + (Xqp_ - Xdp_) * Id()) + yB[2] * (Xq_ - Xqp_) + yB[4] * Xqp_ - yB[5] * Rs_; + fB[4] = -yB[1] * (Edp() + (Xqp_ - Xdp_) * Iq()) - yB[3] * (Xd_ - Xdp_) + - yB[4] * Rs_ - yB[5] * Xdp_; + fB[5] = -yB[1] * (Eqp() + (Xqp_ - Xdp_) * Id()) + yB[2] * (Xq_ - Xqp_) + + yB[4] * Xqp_ - yB[5] * Rs_; fB_.setDataUpdated(); @@ -327,14 +350,16 @@ namespace GridKit /** * Generator active power Pg. * - * \f[ P_g = E_q' I_q + E_d' I_d + (X_q' - X_d') I_q I_d - R_a (I_d^2 + I_q^2) \f] + * \f[ P_g = E_q' I_q + E_d' I_d + (X_q' - X_d') I_q I_d - R_a (I_d^2 + I_q^2) + * \f] * */ template ScalarT Generator4::Pg() { const auto* y = y_.getData(); - return y[5] * V() * std::cos(theta() - y[0]) + y[4] * V() * std::sin(theta() - y[0]); + return y[5] * V() * std::cos(theta() - y[0]) + + y[4] * V() * std::sin(theta() - y[0]); } /** @@ -346,21 +371,27 @@ namespace GridKit ScalarT Generator4::Qg() { const auto* y = y_.getData(); - return y[5] * V() * std::sin(theta() - y[0]) - y[4] * V() * std::cos(theta() - y[0]); + return y[5] * V() * std::sin(theta() - y[0]) + - y[4] * V() * std::cos(theta() - y[0]); } /** - * Frequency penalty is used as the objective function for the generator model. + * Frequency penalty is used as the objective function for the generator + * model. */ template ScalarT Generator4::frequencyPenalty(ScalarT omega) { - return c_ * std::pow(std::max(0.0, std::max(omega - omega_up_, omega_lo_ - omega)), beta_); + return c_ + * std::pow( + std::max(0.0, std::max(omega - omega_up_, omega_lo_ - omega)), + beta_ + ); } /** - * Derivative of frequency penalty cannot be written in terms of min/max functions. - * Need to expand conditional statements instead. + * Derivative of frequency penalty cannot be written in terms of min/max + * functions. Need to expand conditional statements instead. */ template ScalarT Generator4::frequencyPenaltyDer(ScalarT omega) diff --git a/GridKit/Model/PowerFlow/Generator4Governor/Generator4Governor.cpp b/GridKit/Model/PowerFlow/Generator4Governor/Generator4Governor.cpp index 154d380e73..0efeeacfd0 100644 --- a/GridKit/Model/PowerFlow/Generator4Governor/Generator4Governor.cpp +++ b/GridKit/Model/PowerFlow/Generator4Governor/Generator4Governor.cpp @@ -22,7 +22,9 @@ namespace GridKit * */ template - Generator4Governor::Generator4Governor(bus_type* bus, ScalarT P0, ScalarT Q0) + Generator4Governor::Generator4Governor( + bus_type* bus, ScalarT P0, ScalarT Q0 + ) : ModelEvaluatorImpl(9, 1, 2), H_(5.0), D_(0.04), @@ -77,8 +79,10 @@ namespace GridKit * Modeling and Scripting, Federico Milano, Chapter 9, p. 225: * \f{eqnarray*}{ * \omega_0 &=& 0, \\ - * \delta_0 &=& \tan^{-1} \left(\frac{X_q P_0 - R_s Q_0}{V_0^2 + R_s P_0 + X_q Q_0} \right) + \theta_0, \\ - * \phi_0 &=& \delta_0 - \theta_0 + \tan^{-1} \left( \frac{Q_0}{P_0} \right), \\ + * \delta_0 &=& \tan^{-1} \left(\frac{X_q P_0 - R_s Q_0}{V_0^2 + R_s P_0 + + * X_q Q_0} \right) + \theta_0, \\ + * \phi_0 &=& \delta_0 - \theta_0 + \tan^{-1} \left( \frac{Q_0}{P_0} + * \right), \\ * I_{d0} &=& \frac{\sqrt{P_0^2 + Q_0^2}}{V_0} \sin(\phi_0), \\ * I_{q0} &=& \frac{\sqrt{P_0^2 + Q_0^2}}{V_0} \cos(\phi_0), \\ * E_{d0}' &=& V_0 \sin(\delta_0 - \theta_0) + R_s I_{d0} - X_q' I_{q0}, \\ @@ -96,7 +100,9 @@ namespace GridKit int Generator4Governor::initialize() { // Compute generator voltage phase - const ScalarT delta = std::atan((Xq_ * P0_ - Rs_ * Q0_) / (V() * V() + Rs_ * P0_ + Xq_ * Q0_)) + theta(); + const ScalarT delta = + std::atan((Xq_ * P0_ - Rs_ * Q0_) / (V() * V() + Rs_ * P0_ + Xq_ * Q0_)) + + theta(); // Compute generator current phase const ScalarT phi = delta - theta() + std::atan(Q0_ / P0_); @@ -111,8 +117,9 @@ namespace GridKit auto* yp = yp_.getData(); // Initialize generator - y[static_cast(offsetGen_ + 0)] = delta; - y[static_cast(offsetGen_ + 1)] = omega_s_ + 0.2; // <~ this is hack to perturb omega + y[static_cast(offsetGen_ + 0)] = delta; + y[static_cast(offsetGen_ + 1)] = + omega_s_ + 0.2; // <~ this is hack to perturb omega y[static_cast(offsetGen_ + 2)] = Edp; y[static_cast(offsetGen_ + 3)] = Eqp; y[static_cast(offsetGen_ + 4)] = Id; @@ -124,8 +131,9 @@ namespace GridKit yp[static_cast(offsetGen_ + 4)] = 0.0; yp[static_cast(offsetGen_ + 5)] = 0.0; - Pm0_ = Edp * Id + Eqp * Iq + (Xqp_ - Xdp_) * Id * Iq; // <~ set to steady state value - Ef0_ = Eqp + (Xd_ - Xdp_) * Id; // <~ set to steady state value + Pm0_ = Edp * Id + Eqp * Iq + + (Xqp_ - Xdp_) * Id * Iq; // <~ set to steady state value + Ef0_ = Eqp + (Xd_ - Xdp_) * Id; // <~ set to steady state value // Initialize governor y[static_cast(offsetGov_ + 0)] = Pm0_; @@ -189,30 +197,34 @@ namespace GridKit * Residual equations are given as: * \f{eqnarray*}{ * f_0: &~& \dot{\delta} -\omega_b (\omega - \omega_s), \\ - * f_1: &~& 2H/\omega_s \dot{\omega} - L_m(P_m) + E_q' I_q + E_d' I_d + (X_q' - X_d')I_d I_q + D (\omega - \omega_s), \\ + * f_1: &~& 2H/\omega_s \dot{\omega} - L_m(P_m) + E_q' I_q + E_d' I_d + (X_q' + * - X_d')I_d I_q + D (\omega - \omega_s), \\ * f_2: &~& T_{q0}' \dot{E}_d' + E_d' - (X_q - X_q')I_q, \\ * f_3: &~& T_{d0}' \dot{E}_q' + E_q' + (X_d - X_d')I_d - E_f, \\ * f_4: &~& R_s I_d - X_q' I_q + V \sin(\delta - \theta) - E_d', \\ * f_5: &~& R_s I_q + X_d' I_d + V \cos(\delta - \theta) - E_q', \\ * f_6: &~& \dot{P}_m - L_n(P_n), \\ * f_7: &~& T_1 \dot{X} + X - (1 - T_2 / T_1) (\omega - \omega_s), \\ - * f_8: &~& T_3 P_n - P_{m0} + L_m(P_m) + K X + K T_2 / T_1 (\omega - \omega_s) + * f_8: &~& T_3 P_n - P_{m0} + L_m(P_m) + K X + K T_2 / T_1 (\omega - + * \omega_s) * \f} * where \f$ \Omega_b \f$ is the synchronous frequency in [rad/s], and * overdot denotes time derivative. * \f$ \omega \f$ is machine frequency in [p.u.]. - * \f$ L_m() \f$ and \f$ L_n() \f$ are limiter functions, their derivatives will be - * denoted as \f$ dL_m() \f$ and \f$ dL_n() \f$ + * \f$ L_m() \f$ and \f$ L_n() \f$ are limiter functions, their derivatives + * will be denoted as \f$ dL_m() \f$ and \f$ dL_n() \f$ * * Generator injection active and reactive power are * \f{eqnarray*}{ - * P_g &=& E_d' I_d + E_q' I_q + (X_q' - X_d') I_d I_q - R_s (I_d^2 + I_q^2), \\ + * P_g &=& E_d' I_d + E_q' I_q + (X_q' - X_d') I_d I_q - R_s (I_d^2 + I_q^2), + * \\ * Q_g &=& E_q' I_d - E_d' I_q - X_q' I_q^2 - X_d' I_d^2, \\ * \f} * respectively. * * State variables for the generator are: - * \f$ y_0 = \omega \f$, \f$ y_1 = \delta \f$, \f$ y_2 = E_d' \f$, \f$ y_3 = E_q' \f$, + * \f$ y_0 = \omega \f$, \f$ y_1 = \delta \f$, \f$ y_2 = E_d' \f$, \f$ y_3 = + * E_q' \f$, * \f$ y_4 = I_d \f$, \f$ y_5 = I_q \f$, * \f$ y_6 = P_m \f$, \f$ y_7 = X \f$, \f$ y_{8} = P_n \f$ * Bus voltage \f$ V \f$ and bus phase \f$ \theta \f$ are bus state variable. @@ -227,12 +239,20 @@ namespace GridKit auto* f = f_.getData(); // Generator equations - f[static_cast(offsetGen_ + 0)] = dotDelta() - omega_b_ * (omega() - omega_s_); - f[static_cast(offsetGen_ + 1)] = (2.0 * H_) / omega_s_ * dotOmega() - Lm(y[static_cast(offsetGov_ + 0)]) + Eqp() * Iq() + Edp() * Id() + (-Xdp_ + Xqp_) * Id() * Iq() + D_ * (omega() - omega_s_); - f[static_cast(offsetGen_ + 2)] = Tq0p_ * dotEdp() + Edp() - (Xq_ - Xqp_) * Iq(); - f[static_cast(offsetGen_ + 3)] = Td0p_ * dotEqp() + Eqp() + (Xd_ - Xdp_) * Id() - Ef0_; - f[static_cast(offsetGen_ + 4)] = Rs_ * Id() - Xqp_ * Iq() + V() * std::sin(delta() - theta()) - Edp(); - f[static_cast(offsetGen_ + 5)] = Xdp_ * Id() + Rs_ * Iq() + V() * std::cos(delta() - theta()) - Eqp(); + f[static_cast(offsetGen_ + 0)] = + dotDelta() - omega_b_ * (omega() - omega_s_); + f[static_cast(offsetGen_ + 1)] = + (2.0 * H_) / omega_s_ * dotOmega() + - Lm(y[static_cast(offsetGov_ + 0)]) + Eqp() * Iq() + Edp() * Id() + + (-Xdp_ + Xqp_) * Id() * Iq() + D_ * (omega() - omega_s_); + f[static_cast(offsetGen_ + 2)] = + Tq0p_ * dotEdp() + Edp() - (Xq_ - Xqp_) * Iq(); + f[static_cast(offsetGen_ + 3)] = + Td0p_ * dotEqp() + Eqp() + (Xd_ - Xdp_) * Id() - Ef0_; + f[static_cast(offsetGen_ + 4)] = + Rs_ * Id() - Xqp_ * Iq() + V() * std::sin(delta() - theta()) - Edp(); + f[static_cast(offsetGen_ + 5)] = + Xdp_ * Id() + Rs_ * Iq() + V() * std::cos(delta() - theta()) - Eqp(); // Bus equations P() += Pg(); @@ -243,9 +263,18 @@ namespace GridKit } // Governor equations - f[static_cast(offsetGov_ + 0)] = yp[static_cast(offsetGov_ + 0)] - Ln(y[static_cast(offsetGov_ + 2)]); - f[static_cast(offsetGov_ + 1)] = T1() * yp[static_cast(offsetGov_ + 1)] + y[static_cast(offsetGov_ + 1)] - (1.0 - T2() / T1()) * (omega() - omega_s_); - f[static_cast(offsetGov_ + 2)] = T3() * y[static_cast(offsetGov_ + 2)] - Pm0_ + Lm(y[static_cast(offsetGov_ + 0)]) + K() * y[static_cast(offsetGov_ + 1)] + K() * T2() / T1() * (omega() - omega_s_); + f[static_cast(offsetGov_ + 0)] = + yp[static_cast(offsetGov_ + 0)] + - Ln(y[static_cast(offsetGov_ + 2)]); + f[static_cast(offsetGov_ + 1)] = + T1() * yp[static_cast(offsetGov_ + 1)] + + y[static_cast(offsetGov_ + 1)] + - (1.0 - T2() / T1()) * (omega() - omega_s_); + f[static_cast(offsetGov_ + 2)] = + T3() * y[static_cast(offsetGov_ + 2)] - Pm0_ + + Lm(y[static_cast(offsetGov_ + 0)]) + + K() * y[static_cast(offsetGov_ + 1)] + + K() * T2() / T1() * (omega() - omega_s_); f_.setDataUpdated(); @@ -260,7 +289,8 @@ namespace GridKit template int Generator4Governor::evaluateJacobian() { - ::GridKit::Utilities::Logger::warning() << "Generator4Governor: Jacobian evaluation not implemented!\n"; + ::GridKit::Utilities::Logger::warning() + << "Generator4Governor: Jacobian evaluation not implemented!\n"; return 0; } @@ -298,14 +328,20 @@ namespace GridKit * * Adjoint residual equations are given as: * \f{eqnarray*}{ - * f_{B0}: &~& \dot{y}_{B0} - y_{B4} V \cos(\delta - \theta) + y_{B5} V \sin(\delta - \theta), \\ - * f_{B1}: &~& 2H/\omega_s \dot{y}_{B1} + y_{B0} \omega_b - y_{B1} D + y_{B7} (1 - T_2/T_1) - y_{B8} K T_2/T_1 + g_{\omega}(\omega), \\ - * f_{B2}: &~& T_{q0}' \dot{y}_{B2} - y_{B1} I_d - y_{B2} + y_{B4} + \lambda_P I_d - \lambda_Q I_q, \\ - * f_{B3}: &~& T_{d0}' \dot{y}_{B3} - y_{B1} I_q - y_{B3} + y_{B5} + \lambda_P I_q + \lambda_Q I_d, \\ - * f_{B4}: &~& -y_{B1} (E_d' + (-X_d'+X_q') I_q) - y_{B3} (X_d - X_d') - y_{B4} R_s - y_{B5} X_d' - * + \lambda_P (E_d' + (X_q' - X_d') I_q - 2 R_s I_d) + \lambda_Q (E_q' - 2 X_d' I_d), \\ - * f_{B5}: &~& -y_{B1} (E_q' + (-X_d'+X_q') I_d) + y_{B2} (X_q - X_q') + y_{B4} X_q' - y_{B5} R_s - * + \lambda_P (E_q' + (X_q' - X_d') I_d - 2 R_s I_q) - \lambda_Q (E_d' + 2 X_q' I_q), \\ + * f_{B0}: &~& \dot{y}_{B0} - y_{B4} V \cos(\delta - \theta) + y_{B5} V + * \sin(\delta - \theta), \\ + * f_{B1}: &~& 2H/\omega_s \dot{y}_{B1} + y_{B0} \omega_b - y_{B1} D + y_{B7} + * (1 - T_2/T_1) - y_{B8} K T_2/T_1 + g_{\omega}(\omega), \\ + * f_{B2}: &~& T_{q0}' \dot{y}_{B2} - y_{B1} I_d - y_{B2} + y_{B4} + \lambda_P + * I_d - \lambda_Q I_q, \\ + * f_{B3}: &~& T_{d0}' \dot{y}_{B3} - y_{B1} I_q - y_{B3} + y_{B5} + \lambda_P + * I_q + \lambda_Q I_d, \\ f_{B4}: &~& -y_{B1} (E_d' + (-X_d'+X_q') I_q) - + * y_{B3} (X_d - X_d') - y_{B4} R_s - y_{B5} X_d' + * + \lambda_P (E_d' + (X_q' - X_d') I_q - 2 R_s I_d) + \lambda_Q + * (E_q' - 2 X_d' I_d), \\ f_{B5}: &~& -y_{B1} (E_q' + (-X_d'+X_q') I_d) + + * y_{B2} (X_q - X_q') + y_{B4} X_q' - y_{B5} R_s + * + \lambda_P (E_q' + (X_q' - X_d') I_d - 2 R_s I_q) - \lambda_Q + * (E_d' + 2 X_q' I_q), \\ * f_{B6}: &~& \dot{y}_{B6} + y_{B1} dL_m(P_m) - y_{B10} dL_m(P_m), \\ * f_{B7}: &~& T_1 \dot{y}_{B7} - y_{B7} - y_{B8} K, \\ * f_{B8}: &~& y_{B6} dL_n(P_n) - y_{B8} T_3 @@ -313,8 +349,10 @@ namespace GridKit * * Generator adjoint injections are * \f{eqnarray*}{ - * P_g &=& -\lambda_P \sin(\delta - \theta) - \lambda_Q \cos(\delta - \theta), \\ - * Q_g &=& \lambda_P V \cos(\delta - \theta) - \lambda_Q V \sin(\delta - \theta), \\ + * P_g &=& -\lambda_P \sin(\delta - \theta) - \lambda_Q \cos(\delta - + * \theta), \\ + * Q_g &=& \lambda_P V \cos(\delta - \theta) - \lambda_Q V \sin(\delta - + * \theta), \\ * \f} * respectively. * @@ -332,30 +370,71 @@ namespace GridKit auto* fB = fB_.getData(); // Generator adjoint - fB[static_cast(offsetGen_ + 0)] = ypB[static_cast(offsetGen_ + 0)] - yB[static_cast(offsetGen_ + 4)] * V() * cosPhi + yB[static_cast(offsetGen_ + 5)] * V() * sinPhi; - fB[static_cast(offsetGen_ + 1)] = 2.0 * H_ / omega_s_ * ypB[static_cast(offsetGen_ + 1)] + yB[static_cast(offsetGen_ + 0)] * omega_b_ - yB[static_cast(offsetGen_ + 1)] * D_ + frequencyPenaltyDer(omega()) - + yB[static_cast(offsetGov_ + 1)] * (1.0 - T2() / T1()) - yB[static_cast(offsetGov_ + 2)] * K() * T2() / T1(); - fB[static_cast(offsetGen_ + 2)] = Tq0p_ * ypB[static_cast(offsetGen_ + 2)] - yB[static_cast(offsetGen_ + 1)] * Id() - yB[static_cast(offsetGen_ + 2)] + yB[static_cast(offsetGen_ + 4)] - + lambdaP() * Id() - lambdaQ() * Iq(); - fB[static_cast(offsetGen_ + 3)] = Td0p_ * ypB[static_cast(offsetGen_ + 3)] - yB[static_cast(offsetGen_ + 1)] * Iq() - yB[static_cast(offsetGen_ + 3)] + yB[static_cast(offsetGen_ + 5)] - + lambdaP() * Iq() + lambdaQ() * Id(); - fB[static_cast(offsetGen_ + 4)] = -yB[static_cast(offsetGen_ + 1)] * (Edp() + (Xqp_ - Xdp_) * Iq()) - yB[static_cast(offsetGen_ + 3)] * (Xd_ - Xdp_) - yB[static_cast(offsetGen_ + 4)] * Rs_ - yB[static_cast(offsetGen_ + 5)] * Xdp_ - + lambdaP() * (Edp() + (Xqp_ - Xdp_) * Iq() - 2.0 * Rs_ * Id()) + lambdaQ() * (Eqp() - 2.0 * Xdp_ * Id()); - fB[static_cast(offsetGen_ + 5)] = -yB[static_cast(offsetGen_ + 1)] * (Eqp() + (Xqp_ - Xdp_) * Id()) + yB[static_cast(offsetGen_ + 2)] * (Xq_ - Xqp_) + yB[static_cast(offsetGen_ + 4)] * Xqp_ - yB[static_cast(offsetGen_ + 5)] * Rs_ - + lambdaP() * (Eqp() + (Xqp_ - Xdp_) * Id() - 2.0 * Rs_ * Iq()) - lambdaQ() * (Edp() + 2.0 * Xqp_ * Iq()); + fB[static_cast(offsetGen_ + 0)] = + ypB[static_cast(offsetGen_ + 0)] + - yB[static_cast(offsetGen_ + 4)] * V() * cosPhi + + yB[static_cast(offsetGen_ + 5)] * V() * sinPhi; + fB[static_cast(offsetGen_ + 1)] = + 2.0 * H_ / omega_s_ * ypB[static_cast(offsetGen_ + 1)] + + yB[static_cast(offsetGen_ + 0)] * omega_b_ + - yB[static_cast(offsetGen_ + 1)] * D_ + + frequencyPenaltyDer(omega()) + + yB[static_cast(offsetGov_ + 1)] * (1.0 - T2() / T1()) + - yB[static_cast(offsetGov_ + 2)] * K() * T2() / T1(); + fB[static_cast(offsetGen_ + 2)] = + Tq0p_ * ypB[static_cast(offsetGen_ + 2)] + - yB[static_cast(offsetGen_ + 1)] * Id() + - yB[static_cast(offsetGen_ + 2)] + + yB[static_cast(offsetGen_ + 4)] + lambdaP() * Id() + - lambdaQ() * Iq(); + fB[static_cast(offsetGen_ + 3)] = + Td0p_ * ypB[static_cast(offsetGen_ + 3)] + - yB[static_cast(offsetGen_ + 1)] * Iq() + - yB[static_cast(offsetGen_ + 3)] + + yB[static_cast(offsetGen_ + 5)] + lambdaP() * Iq() + + lambdaQ() * Id(); + fB[static_cast(offsetGen_ + 4)] = + -yB[static_cast(offsetGen_ + 1)] * (Edp() + (Xqp_ - Xdp_) * Iq()) + - yB[static_cast(offsetGen_ + 3)] * (Xd_ - Xdp_) + - yB[static_cast(offsetGen_ + 4)] * Rs_ + - yB[static_cast(offsetGen_ + 5)] * Xdp_ + + lambdaP() * (Edp() + (Xqp_ - Xdp_) * Iq() - 2.0 * Rs_ * Id()) + + lambdaQ() * (Eqp() - 2.0 * Xdp_ * Id()); + fB[static_cast(offsetGen_ + 5)] = + -yB[static_cast(offsetGen_ + 1)] * (Eqp() + (Xqp_ - Xdp_) * Id()) + + yB[static_cast(offsetGen_ + 2)] * (Xq_ - Xqp_) + + yB[static_cast(offsetGen_ + 4)] * Xqp_ + - yB[static_cast(offsetGen_ + 5)] * Rs_ + + lambdaP() * (Eqp() + (Xqp_ - Xdp_) * Id() - 2.0 * Rs_ * Iq()) + - lambdaQ() * (Edp() + 2.0 * Xqp_ * Iq()); // Bus adjoint - PB() += (-yB[static_cast(offsetGen_ + 4)] * sinPhi - yB[static_cast(offsetGen_ + 5)] * cosPhi); - QB() += (yB[static_cast(offsetGen_ + 4)] * V() * cosPhi - yB[static_cast(offsetGen_ + 5)] * V() * sinPhi); + PB() += + (-yB[static_cast(offsetGen_ + 4)] * sinPhi + - yB[static_cast(offsetGen_ + 5)] * cosPhi); + QB() += + (yB[static_cast(offsetGen_ + 4)] * V() * cosPhi + - yB[static_cast(offsetGen_ + 5)] * V() * sinPhi); if (bus_->size() > 0) { bus_->getAdjointResidual().setDataUpdated(); } // Governor adjoint - fB[static_cast(offsetGov_ + 0)] = ypB[static_cast(offsetGov_ + 0)] - yB[static_cast(offsetGov_ + 2)] * dLm(y[static_cast(offsetGov_ + 0)]) + yB[static_cast(offsetGen_ + 1)] * dLm(y[static_cast(offsetGov_ + 0)]); - fB[static_cast(offsetGov_ + 1)] = ypB[static_cast(offsetGov_ + 1)] * T1() - yB[static_cast(offsetGov_ + 1)] - yB[static_cast(offsetGov_ + 2)] * K(); - fB[static_cast(offsetGov_ + 2)] = yB[static_cast(offsetGov_ + 0)] * dLn(y[static_cast(offsetGov_ + 2)]) - yB[static_cast(offsetGov_ + 2)] * T3(); + fB[static_cast(offsetGov_ + 0)] = + ypB[static_cast(offsetGov_ + 0)] + - yB[static_cast(offsetGov_ + 2)] + * dLm(y[static_cast(offsetGov_ + 0)]) + + yB[static_cast(offsetGen_ + 1)] + * dLm(y[static_cast(offsetGov_ + 0)]); + fB[static_cast(offsetGov_ + 1)] = + ypB[static_cast(offsetGov_ + 1)] * T1() + - yB[static_cast(offsetGov_ + 1)] + - yB[static_cast(offsetGov_ + 2)] * K(); + fB[static_cast(offsetGov_ + 2)] = + yB[static_cast(offsetGov_ + 0)] + * dLn(y[static_cast(offsetGov_ + 2)]) + - yB[static_cast(offsetGov_ + 2)] * T3(); fB_.setDataUpdated(); @@ -370,10 +449,15 @@ namespace GridKit auto* gB = gB_.getData(); // K adjoint - gB[1] = -yB[static_cast(offsetGov_ + 2)] * (y[static_cast(offsetGov_ + 1)] + T2() / T1() * (omega() - omega_s_)); + gB[1] = + -yB[static_cast(offsetGov_ + 2)] + * (y[static_cast(offsetGov_ + 1)] + T2() / T1() * (omega() - omega_s_)); // T2 adjoint - gB[0] = -yB[static_cast(offsetGov_ + 1)] * (omega() - omega_s_) / T1() - yB[static_cast(offsetGov_ + 2)] * K() / T1() * (omega() - omega_s_); + gB[0] = + -yB[static_cast(offsetGov_ + 1)] * (omega() - omega_s_) / T1() + - yB[static_cast(offsetGov_ + 2)] * K() / T1() + * (omega() - omega_s_); gB_.setDataUpdated(); @@ -387,13 +471,15 @@ namespace GridKit /** * Generator active power Pg. * - * \f[ P_g = E_q' I_q + E_d' I_d + (X_q' - X_d') I_q I_d - R_a (I_d^2 + I_q^2) \f] + * \f[ P_g = E_q' I_q + E_d' I_d + (X_q' - X_d') I_q I_d - R_a (I_d^2 + I_q^2) + * \f] * */ template ScalarT Generator4Governor::Pg() { - return Iq() * Eqp() + Id() * Edp() + (Xqp_ - Xdp_) * Id() * Iq() - Rs_ * (Id() * Id() + Iq() * Iq()); + return Iq() * Eqp() + Id() * Edp() + (Xqp_ - Xdp_) * Id() * Iq() + - Rs_ * (Id() * Id() + Iq() * Iq()); } /** @@ -404,11 +490,13 @@ namespace GridKit template ScalarT Generator4Governor::Qg() { - return -Iq() * Edp() + Id() * Eqp() - Xdp_ * Id() * Id() - Xqp_ * Iq() * Iq(); + return -Iq() * Edp() + Id() * Eqp() - Xdp_ * Id() * Id() + - Xqp_ * Iq() * Iq(); } /** - * Frequency penalty is used as the objective function for the generator model. + * Frequency penalty is used as the objective function for the generator + * model. * * @todo Use smooth penalty function! * @@ -416,12 +504,16 @@ namespace GridKit template ScalarT Generator4Governor::frequencyPenalty(ScalarT omega) { - return c_ * std::pow(std::max(0.0, std::max(omega - omega_up_, omega_lo_ - omega)), beta_); + return c_ + * std::pow( + std::max(0.0, std::max(omega - omega_up_, omega_lo_ - omega)), + beta_ + ); } /** - * Derivative of frequency penalty cannot be written in terms of min/max functions. - * Need to expand conditional statements instead. + * Derivative of frequency penalty cannot be written in terms of min/max + * functions. Need to expand conditional statements instead. * * @todo Use smooth penalty function! * diff --git a/GridKit/Model/PowerFlow/Generator4Param/Generator4Param.cpp b/GridKit/Model/PowerFlow/Generator4Param/Generator4Param.cpp index d2f8d520e7..4c61acd4fb 100644 --- a/GridKit/Model/PowerFlow/Generator4Param/Generator4Param.cpp +++ b/GridKit/Model/PowerFlow/Generator4Param/Generator4Param.cpp @@ -21,7 +21,9 @@ namespace GridKit * - Number of optimization parameters = 1 */ template - Generator4Param::Generator4Param(bus_type* bus, ScalarT P0, ScalarT Q0) + Generator4Param::Generator4Param( + bus_type* bus, ScalarT P0, ScalarT Q0 + ) : ModelEvaluatorImpl(6, 1, 1), H_(5.0), D_(0.04), @@ -65,8 +67,10 @@ namespace GridKit * Modeling and Scripting, Federico Milano, Chapter 9, p. 225: * \f{eqnarray*}{ * &~& \omega_0 = 0, \\ - * &~& \delta_0 = \tan^{-1} \left(\frac{X_q P_0 - R_s Q_0}{V_0^2 + R_s P_0 + X_q Q_0} \right) + \theta_0, \\ - * &~& \phi_0 = \delta_0 - \theta_0 + \tan^{-1} \left( \frac{Q_0}{P_0} \right), \\ + * &~& \delta_0 = \tan^{-1} \left(\frac{X_q P_0 - R_s Q_0}{V_0^2 + R_s P_0 + + * X_q Q_0} \right) + \theta_0, \\ + * &~& \phi_0 = \delta_0 - \theta_0 + \tan^{-1} \left( \frac{Q_0}{P_0} + * \right), \\ * &~& I_{d0} = \frac{\sqrt{P_0^2 + Q_0^2}}{V_0} \sin(\phi_0), \\ * &~& I_{q0} = \frac{\sqrt{P_0^2 + Q_0^2}}{V_0} \cos(\phi_0), \\ * &~& E_{d0}' = V_0 \sin(\delta_0 - \theta_0) + R_s I_{d0} - X_q' I_{q0}, \\ @@ -84,12 +88,15 @@ namespace GridKit int Generator4Param::initialize() { // Compute initial guess for the generator voltage phase - const ScalarT delta = atan((Xq_ * P0_ - Rs_ * Q0_) / (V() * V() + Rs_ * P0_ + Xq_ * Q0_)) + theta(); + const ScalarT delta = + atan((Xq_ * P0_ - Rs_ * Q0_) / (V() * V() + Rs_ * P0_ + Xq_ * Q0_)) + + theta(); // Compute initial guess for the generator current phase const ScalarT phi = theta() - delta - atan(Q0_ / P0_); - // Compute initial guesses for generator currents and potentials in d-q frame + // Compute initial guesses for generator currents and potentials in d-q + // frame const ScalarT Id = std::sqrt(P0_ * P0_ + Q0_ * Q0_) / V() * std::sin(phi); const ScalarT Iq = std::sqrt(P0_ * P0_ + Q0_ * Q0_) / V() * std::cos(phi); const ScalarT Ed = V() * std::sin(theta() - delta) + Rs_ * Id + Xqp_ * Iq; @@ -112,8 +119,9 @@ namespace GridKit yp[5] = 0.0; // Set control parameter values here. - Ef_ = Eq - (Xd_ - Xdp_) * Id; // <~ set to steady state value - Pm_ = Ed * Id + Eq * Iq + (Xdp_ - Xqp_) * Id * Iq; // <~ set to steady state value + Ef_ = Eq - (Xd_ - Xdp_) * Id; // <~ set to steady state value + Pm_ = Ed * Id + Eq * Iq + + (Xdp_ - Xqp_) * Id * Iq; // <~ set to steady state value // Initialize optimization parameters auto* param = param_.getData(); @@ -166,7 +174,8 @@ namespace GridKit * Scripting, Federico Milano, Chapter 15, p. 334: * \f{eqnarray*}{ * f_0: &~& \dot{\delta} -\omega_b (\omega - \omega_s), \\ - * f_1: &~& 2H/\omega_s \dot{\omega} - L_m(P_m) + E_q' I_q + E_d' I_d + (X_q' - X_d')I_d I_q + D (\omega - \omega_s), \\ + * f_1: &~& 2H/\omega_s \dot{\omega} - L_m(P_m) + E_q' I_q + E_d' I_d + (X_q' + * - X_d')I_d I_q + D (\omega - \omega_s), \\ * f_2: &~& T_{q0}' \dot{E}_d' + E_d' - (X_q - X_q')I_q, \\ * f_3: &~& T_{d0}' \dot{E}_q' + E_q' + (X_d - X_d')I_d - E_f, \\ * f_4: &~& R_s I_d - X_q' I_q + V \sin(\delta - \theta) - E_d', \\ @@ -177,13 +186,15 @@ namespace GridKit * * Generator injection active and reactive power are * \f{eqnarray*}{ - * P_g &=& E_d' I_d + E_q' I_q + (X_q' - X_d') I_d I_q - R_s (I_d^2 + I_q^2), \\ + * P_g &=& E_d' I_d + E_q' I_q + (X_q' - X_d') I_d I_q - R_s (I_d^2 + I_q^2), + * \\ * Q_q &=& E_q' I_d - E_d' I_q - X_q' I_q^2 - X_d' I_d^2, \\ * \f} * respectively. * * State variables are: - * \f$ y_0 = \omega \f$, \f$ y_1 = \delta \f$, \f$ y_2 = E_d' \f$, \f$ y_3 = E_q' \f$, + * \f$ y_0 = \omega \f$, \f$ y_1 = \delta \f$, \f$ y_2 = E_d' \f$, \f$ y_3 = + * E_q' \f$, * \f$ y_4 = I_d \f$, \f$ y_5 = I_q \f$. * */ @@ -193,7 +204,9 @@ namespace GridKit auto* f = f_.getData(); f[0] = dotDelta() - omega_b_ * (omega() - omega_s_); - f[1] = (2.0 * H()) / omega_s_ * dotOmega() - Pm() + Eqp() * Iq() + Edp() * Id() + (-Xdp_ + Xqp_) * Id() * Iq() + D_ * (omega() - omega_s_); + f[1] = (2.0 * H()) / omega_s_ * dotOmega() - Pm() + Eqp() * Iq() + + Edp() * Id() + (-Xdp_ + Xqp_) * Id() * Iq() + + D_ * (omega() - omega_s_); f[2] = Tq0p_ * dotEdp() + Edp() - (Xq_ - Xqp_) * Iq(); f[3] = Td0p_ * dotEqp() + Eqp() + (Xd_ - Xdp_) * Id() - Ef(); f[4] = Rs_ * Id() - Xqp_ * Iq() + V() * std::sin(delta() - theta()) - Edp(); @@ -216,7 +229,8 @@ namespace GridKit template int Generator4Param::evaluateJacobian() { - ::GridKit::Utilities::Logger::warning() << "Generator4Param: Jacobian evaluation not implemented!\n"; + ::GridKit::Utilities::Logger::warning() + << "Generator4Param: Jacobian evaluation not implemented!\n"; return 0; } @@ -255,12 +269,20 @@ namespace GridKit * * Adjoint residual equations are given as: * \f{eqnarray*}{ - * f_{B0}: &~& \dot{y}_{B0} - y_{B4} V \cos(\delta - \theta) + y_{B5} V \sin(\delta - \theta), \\ - * f_{B1}: &~& 2H/\omega_s \dot{y}_{B1} + y_{B0} \omega_b - y_{B1} D + y_{B9} (1 - T_2/T_1) - y_{B10} K T_2/T_1 + g_{\omega}(\omega), \\ - * f_{B2}: &~& T_{q0}' \dot{y}_{B2} - y_{B1} I_d - y_{B2} + y_{B4} + y_{B6} I_d - y_{B7} I_q, \\ - * f_{B3}: &~& T_{d0}' \dot{y}_{B3} - y_{B1} I_q - y_{B3} + y_{B5} + y_{B6} I_q + y_{B7} I_d, \\ - * f_{B4}: &~& -y_{B1} (E_d' + (-X_d'+X_q') I_q) - y_{B3} (X_d - X_d') - y_{B4} R_s - y_{B5} X_d' + y_{B6} (E_d' + (X_q' - X_d') I_q - 2 R_s I_d) + y_{B7} (E_q' - 2 X_d' I_d), \\ - * f_{B5}: &~& -y_{B1} (E_q' + (-X_d'+X_q') I_d) + y_{B2} (X_q - X_q') + y_{B4} X_q' - y_{B5} R_s + y_{B6} (E_q' + (X_q' - X_d') I_d - 2 R_s I_q) - y_{B7} (E_d' + 2 X_q' I_q). \\ + * f_{B0}: &~& \dot{y}_{B0} - y_{B4} V \cos(\delta - \theta) + y_{B5} V + * \sin(\delta - \theta), \\ + * f_{B1}: &~& 2H/\omega_s \dot{y}_{B1} + y_{B0} \omega_b - y_{B1} D + y_{B9} + * (1 - T_2/T_1) - y_{B10} K T_2/T_1 + g_{\omega}(\omega), \\ + * f_{B2}: &~& T_{q0}' \dot{y}_{B2} - y_{B1} I_d - y_{B2} + y_{B4} + y_{B6} + * I_d - y_{B7} I_q, \\ + * f_{B3}: &~& T_{d0}' \dot{y}_{B3} - y_{B1} I_q - y_{B3} + y_{B5} + y_{B6} + * I_q + y_{B7} I_d, \\ + * f_{B4}: &~& -y_{B1} (E_d' + (-X_d'+X_q') I_q) - y_{B3} (X_d - X_d') - + * y_{B4} R_s - y_{B5} X_d' + y_{B6} (E_d' + (X_q' - X_d') I_q - 2 R_s I_d) + + * y_{B7} (E_q' - 2 X_d' I_d), \\ + * f_{B5}: &~& -y_{B1} (E_q' + (-X_d'+X_q') I_d) + y_{B2} (X_q - X_q') + + * y_{B4} X_q' - y_{B5} R_s + y_{B6} (E_q' + (X_q' - X_d') I_d - 2 R_s I_q) - + * y_{B7} (E_d' + 2 X_q' I_q). \\ * \f} * */ @@ -276,11 +298,16 @@ namespace GridKit // Generator adjoint fB[0] = ypB[0] - yB[4] * V() * cosPhi + yB[5] * V() * sinPhi; - fB[1] = 2.0 * H() / omega_s_ * ypB[1] + yB[0] * omega_b_ - yB[1] * D_; //+ frequencyPenaltyDer(omega()); - fB[2] = Tq0p_ * ypB[2] - yB[1] * Id() - yB[2] + yB[4] + trajectoryPenaltyDerEdp(time_); - fB[3] = Td0p_ * ypB[3] - yB[1] * Iq() - yB[3] + yB[5] + trajectoryPenaltyDerEqp(time_); - fB[4] = -yB[1] * (Edp() + (Xqp_ - Xdp_) * Iq()) - yB[3] * (Xd_ - Xdp_) - yB[4] * Rs_ - yB[5] * Xdp_; - fB[5] = -yB[1] * (Eqp() + (Xqp_ - Xdp_) * Id()) + yB[2] * (Xq_ - Xqp_) + yB[4] * Xqp_ - yB[5] * Rs_; + fB[1] = 2.0 * H() / omega_s_ * ypB[1] + yB[0] * omega_b_ + - yB[1] * D_; //+ frequencyPenaltyDer(omega()); + fB[2] = Tq0p_ * ypB[2] - yB[1] * Id() - yB[2] + yB[4] + + trajectoryPenaltyDerEdp(time_); + fB[3] = Td0p_ * ypB[3] - yB[1] * Iq() - yB[3] + yB[5] + + trajectoryPenaltyDerEqp(time_); + fB[4] = -yB[1] * (Edp() + (Xqp_ - Xdp_) * Iq()) - yB[3] * (Xd_ - Xdp_) + - yB[4] * Rs_ - yB[5] * Xdp_; + fB[5] = -yB[1] * (Eqp() + (Xqp_ - Xdp_) * Id()) + yB[2] * (Xq_ - Xqp_) + + yB[4] * Xqp_ - yB[5] * Rs_; fB_.setDataUpdated(); @@ -307,14 +334,16 @@ namespace GridKit /** * Generator active power Pg. * - * \f[ P_g = E_q' I_q + E_d' I_d + (X_q' - X_d') I_q I_d - R_a (I_d^2 + I_q^2) \f] + * \f[ P_g = E_q' I_q + E_d' I_d + (X_q' - X_d') I_q I_d - R_a (I_d^2 + I_q^2) + * \f] * */ template ScalarT Generator4Param::Pg() { const auto* y = y_.getData(); - return y[5] * V() * std::cos(theta() - y[0]) + y[4] * V() * std::sin(theta() - y[0]); + return y[5] * V() * std::cos(theta() - y[0]) + + y[4] * V() * std::sin(theta() - y[0]); } /** @@ -326,7 +355,8 @@ namespace GridKit ScalarT Generator4Param::Qg() { const auto* y = y_.getData(); - return y[5] * V() * std::sin(theta() - y[0]) - y[4] * V() * std::cos(theta() - y[0]); + return y[5] * V() * std::sin(theta() - y[0]) + - y[4] * V() * std::cos(theta() - y[0]); } /** @@ -341,7 +371,7 @@ namespace GridKit double ti = table_[0][0]; double tf = table_[N - 1][0]; double dt = (tf - ti) / static_cast(N - 1); - int n = static_cast(std::trunc(t / tf * static_cast(N - 1))); + int n = static_cast(std::trunc(t / tf * static_cast(N - 1))); double Edp_est = 0.0; double Eqp_est = 0.0; @@ -349,21 +379,42 @@ namespace GridKit if (t >= ti && t < tf) { // Interpolate from look-up table - Edp_est = (table_[static_cast(n + 1)][3] - table_[static_cast(n)][3]) / (table_[static_cast(n + 1)][0] - table_[static_cast(n)][0]) * (t - table_[static_cast(n)][0]) + table_[static_cast(n)][3]; - Eqp_est = (table_[static_cast(n + 1)][4] - table_[static_cast(n)][4]) / (table_[static_cast(n + 1)][0] - table_[static_cast(n)][0]) * (t - table_[static_cast(n)][0]) + table_[static_cast(n)][4]; + Edp_est = + (table_[static_cast(n + 1)][3] + - table_[static_cast(n)][3]) + / (table_[static_cast(n + 1)][0] - table_[static_cast(n)][0]) + * (t - table_[static_cast(n)][0]) + + table_[static_cast(n)][3]; + Eqp_est = + (table_[static_cast(n + 1)][4] + - table_[static_cast(n)][4]) + / (table_[static_cast(n + 1)][0] - table_[static_cast(n)][0]) + * (t - table_[static_cast(n)][0]) + + table_[static_cast(n)][4]; } else { if (tf <= t && t < tf + dt) { // Extrapolate from look-up table - Edp_est = (table_[static_cast(n)][3] - table_[static_cast(n - 1)][3]) / (table_[static_cast(n)][0] - table_[static_cast(n - 1)][0]) * (t - table_[static_cast(n - 1)][0]) + table_[static_cast(n - 1)][3]; - Eqp_est = (table_[static_cast(n)][4] - table_[static_cast(n - 1)][4]) / (table_[static_cast(n)][0] - table_[static_cast(n - 1)][0]) * (t - table_[static_cast(n - 1)][0]) + table_[static_cast(n - 1)][4]; + Edp_est = + (table_[static_cast(n)][3] + - table_[static_cast(n - 1)][3]) + / (table_[static_cast(n)][0] - table_[static_cast(n - 1)][0]) + * (t - table_[static_cast(n - 1)][0]) + + table_[static_cast(n - 1)][3]; + Eqp_est = + (table_[static_cast(n)][4] + - table_[static_cast(n - 1)][4]) + / (table_[static_cast(n)][0] - table_[static_cast(n - 1)][0]) + * (t - table_[static_cast(n - 1)][0]) + + table_[static_cast(n - 1)][4]; } else { // Too far away to extrapolate - ::GridKit::Utilities::Logger::warning() << "Trajectory penalty: Out of time bounds at time " << t << "\n"; + ::GridKit::Utilities::Logger::warning() + << "Trajectory penalty: Out of time bounds at time " << t << "\n"; return -1.0; } } @@ -373,28 +424,40 @@ namespace GridKit } template - ScalarT Generator4Param::trajectoryPenaltyDerEdp(ScalarT t) const + ScalarT Generator4Param::trajectoryPenaltyDerEdp(ScalarT t + ) const { - size_t N = table_.size(); - double ti = table_[0][0]; - double tf = table_[N - 1][0]; - double dt = (tf - ti) / static_cast(N - 1); - int n = static_cast(std::trunc(t / tf * static_cast(N - 1))); + size_t N = table_.size(); + double ti = table_[0][0]; + double tf = table_[N - 1][0]; + double dt = (tf - ti) / static_cast(N - 1); + int n = static_cast(std::trunc(t / tf * static_cast(N - 1))); double Edp_est = 0.0; if (t >= ti && t < tf) { - Edp_est = (table_[static_cast(n + 1)][3] - table_[static_cast(n)][3]) / (table_[static_cast(n + 1)][0] - table_[static_cast(n)][0]) * (t - table_[static_cast(n)][0]) + table_[static_cast(n)][3]; + Edp_est = + (table_[static_cast(n + 1)][3] + - table_[static_cast(n)][3]) + / (table_[static_cast(n + 1)][0] - table_[static_cast(n)][0]) + * (t - table_[static_cast(n)][0]) + + table_[static_cast(n)][3]; } else { if (tf <= t && t < tf + dt) { - Edp_est = (table_[static_cast(n)][3] - table_[static_cast(n - 1)][3]) / (table_[static_cast(n)][0] - table_[static_cast(n - 1)][0]) * (t - table_[static_cast(n - 1)][0]) + table_[static_cast(n - 1)][3]; + Edp_est = + (table_[static_cast(n)][3] + - table_[static_cast(n - 1)][3]) + / (table_[static_cast(n)][0] - table_[static_cast(n - 1)][0]) + * (t - table_[static_cast(n - 1)][0]) + + table_[static_cast(n - 1)][3]; } else { - ::GridKit::Utilities::Logger::warning() << "Trajectory penalty: Out of time bounds at time " << t << "\n"; + ::GridKit::Utilities::Logger::warning() + << "Trajectory penalty: Out of time bounds at time " << t << "\n"; return -1.0; } } @@ -404,28 +467,40 @@ namespace GridKit } template - ScalarT Generator4Param::trajectoryPenaltyDerEqp(ScalarT t) const + ScalarT Generator4Param::trajectoryPenaltyDerEqp(ScalarT t + ) const { - size_t N = table_.size(); - double ti = table_[0][0]; - double tf = table_[N - 1][0]; - double dt = (tf - ti) / static_cast(N - 1); - int n = static_cast(std::trunc(t / tf * static_cast(N - 1))); + size_t N = table_.size(); + double ti = table_[0][0]; + double tf = table_[N - 1][0]; + double dt = (tf - ti) / static_cast(N - 1); + int n = static_cast(std::trunc(t / tf * static_cast(N - 1))); double Eqp_est = 0.0; if (t >= ti && t < tf) { - Eqp_est = (table_[static_cast(n + 1)][4] - table_[static_cast(n)][4]) / (table_[static_cast(n + 1)][0] - table_[static_cast(n)][0]) * (t - table_[static_cast(n)][0]) + table_[static_cast(n)][4]; + Eqp_est = + (table_[static_cast(n + 1)][4] + - table_[static_cast(n)][4]) + / (table_[static_cast(n + 1)][0] - table_[static_cast(n)][0]) + * (t - table_[static_cast(n)][0]) + + table_[static_cast(n)][4]; } else { if (tf <= t && t < tf + dt) { - Eqp_est = (table_[static_cast(n)][4] - table_[static_cast(n - 1)][4]) / (table_[static_cast(n)][0] - table_[static_cast(n - 1)][0]) * (t - table_[static_cast(n - 1)][0]) + table_[static_cast(n - 1)][4]; + Eqp_est = + (table_[static_cast(n)][4] + - table_[static_cast(n - 1)][4]) + / (table_[static_cast(n)][0] - table_[static_cast(n - 1)][0]) + * (t - table_[static_cast(n - 1)][0]) + + table_[static_cast(n - 1)][4]; } else { - ::GridKit::Utilities::Logger::warning() << "Trajectory penalty: Out of time bounds at time " << t << "\n"; + ::GridKit::Utilities::Logger::warning() + << "Trajectory penalty: Out of time bounds at time " << t << "\n"; return -1.0; } } diff --git a/GridKit/Model/PowerFlow/Generator4Param/Generator4Param.hpp b/GridKit/Model/PowerFlow/Generator4Param/Generator4Param.hpp index ce441b438e..968acb7569 100644 --- a/GridKit/Model/PowerFlow/Generator4Param/Generator4Param.hpp +++ b/GridKit/Model/PowerFlow/Generator4Param/Generator4Param.hpp @@ -40,7 +40,9 @@ namespace GridKit using bus_type = BaseBus; public: - Generator4Param(BaseBus* bus, ScalarT P0 = 1.0, ScalarT Q0 = 0.0); + Generator4Param( + BaseBus* bus, ScalarT P0 = 1.0, ScalarT Q0 = 0.0 + ); virtual ~Generator4Param(); int allocate(); diff --git a/GridKit/Model/PowerFlow/Load/Load.cpp b/GridKit/Model/PowerFlow/Load/Load.cpp index 8d6bc8cb9a..4008c0a9c7 100644 --- a/GridKit/Model/PowerFlow/Load/Load.cpp +++ b/GridKit/Model/PowerFlow/Load/Load.cpp @@ -18,20 +18,14 @@ namespace GridKit template Load::Load(bus_type* bus, ScalarT P, ScalarT Q) - : P_(P), - Q_(Q), - busID_(0), - bus_(bus) + : P_(P), Q_(Q), busID_(0), bus_(bus) { size_ = 0; } template Load::Load(bus_type* bus, LoadData& data) - : P_(data.Pd), - Q_(data.Qd), - busID_(data.bus_i), - bus_(bus) + : P_(data.Pd), Q_(data.Qd), busID_(data.bus_i), bus_(bus) { size_ = 0; } diff --git a/GridKit/Model/PowerFlow/MatpowerParser.hpp b/GridKit/Model/PowerFlow/MatpowerParser.hpp index ef6cf73d57..564eb26d50 100644 --- a/GridKit/Model/PowerFlow/MatpowerParser.hpp +++ b/GridKit/Model/PowerFlow/MatpowerParser.hpp @@ -49,19 +49,19 @@ namespace GridKit inline void ltrim(std::string& s) { const std::string nothing = ""; - s = std::regex_replace(s, std::regex("^\\s+"), nothing); + s = std::regex_replace(s, std::regex("^\\s+"), nothing); } inline void rtrim(std::string& s) { const std::string nothing = ""; - s = std::regex_replace(s, std::regex("\\s+$"), nothing); + s = std::regex_replace(s, std::regex("\\s+$"), nothing); } inline void trim_matlab_comments(std::string& s) { const std::string nothing = ""; - s = std::regex_replace(s, std::regex("%.+"), nothing); + s = std::regex_replace(s, std::regex("%.+"), nothing); } // Retrieve MATPOWER component from assignment line. @@ -100,7 +100,9 @@ namespace GridKit } template - void readMatPowerBusRow(const std::string& row, BusData& br, LoadData& lr) + void readMatPowerBusRow( + const std::string& row, BusData& br, LoadData& lr + ) { logs() << "Parsing MATPOWER bus row\n"; std::stringstream is(row); @@ -174,7 +176,9 @@ namespace GridKit } else { - throw std::runtime_error(matlab_syntax_error + "\nGot line '" + line + "'"); + throw std::runtime_error( + matlab_syntax_error + "\nGot line '" + line + "'" + ); } } @@ -190,7 +194,9 @@ namespace GridKit } else { - throw std::runtime_error(matlab_syntax_error + "\nGot line '" + line + "'"); + throw std::runtime_error( + matlab_syntax_error + "\nGot line '" + line + "'" + ); } } diff --git a/GridKit/Model/PowerFlow/MiniGrid/MiniGrid.cpp b/GridKit/Model/PowerFlow/MiniGrid/MiniGrid.cpp index 50ffcd10bd..1eb15ee7c3 100644 --- a/GridKit/Model/PowerFlow/MiniGrid/MiniGrid.cpp +++ b/GridKit/Model/PowerFlow/MiniGrid/MiniGrid.cpp @@ -68,9 +68,18 @@ namespace GridKit int MiniGrid::evaluateResidual() { auto* f = f_.getData(); - f[0] = -Pl2_ - V2() * (V1_ * B12_ * std::sin(th2() - th1_) + V3_ * B23_ * std::sin(th2() - th3())); - f[1] = -Ql2_ + V2() * (V1_ * B12_ * std::cos(th2() - th1_) + B22_ * V2() + V3_ * B23_ * std::cos(th2() - th3())); - f[2] = Pg3_ - V3_ * (V1_ * B13_ * std::sin(th3() - th1_) + V2() * B23_ * std::sin(th3() - th2())); + f[0] = + -Pl2_ + - V2() + * (V1_ * B12_ * std::sin(th2() - th1_) + V3_ * B23_ * std::sin(th2() - th3())); + f[1] = + -Ql2_ + + V2() + * (V1_ * B12_ * std::cos(th2() - th1_) + B22_ * V2() + V3_ * B23_ * std::cos(th2() - th3())); + f[2] = + Pg3_ + - V3_ + * (V1_ * B13_ * std::sin(th3() - th1_) + V2() * B23_ * std::sin(th3() - th2())); f_.setDataUpdated(); diff --git a/GridKit/Model/PowerFlow/ModelEvaluatorImpl.hpp b/GridKit/Model/PowerFlow/ModelEvaluatorImpl.hpp index 6c37009c0b..6f6addb9d6 100644 --- a/GridKit/Model/PowerFlow/ModelEvaluatorImpl.hpp +++ b/GridKit/Model/PowerFlow/ModelEvaluatorImpl.hpp @@ -19,10 +19,7 @@ namespace GridKit using RealT = typename Model::Evaluator::RealT; using VectorT = typename Model::Evaluator::VectorT; - ModelEvaluatorImpl() - : size_(0), - size_quad_(0), - size_opt_(0) + ModelEvaluatorImpl() : size_(0), size_quad_(0), size_opt_(0) { } diff --git a/GridKit/Model/PowerFlow/PowerFlowData.hpp b/GridKit/Model/PowerFlow/PowerFlowData.hpp index 5d30c996b4..a916c1f9e4 100644 --- a/GridKit/Model/PowerFlow/PowerFlowData.hpp +++ b/GridKit/Model/PowerFlow/PowerFlowData.hpp @@ -38,16 +38,10 @@ namespace GridKit inline std::string str() const { std::stringstream ss; - ss << std::setw(10) << bus_i - << std::setw(10) << type - << std::setw(10) << Gs - << std::setw(10) << Bs - << std::setw(10) << area - << std::setw(10) << Vm - << std::setw(10) << Va - << std::setw(10) << baseKV - << std::setw(10) << zone - << std::setw(10) << Vmax + ss << std::setw(10) << bus_i << std::setw(10) << type << std::setw(10) + << Gs << std::setw(10) << Bs << std::setw(10) << area + << std::setw(10) << Vm << std::setw(10) << Va << std::setw(10) + << baseKV << std::setw(10) << zone << std::setw(10) << Vmax << std::setw(10) << Vmin; ss << "\n"; return ss.str(); @@ -64,9 +58,8 @@ namespace GridKit inline std::string str() const { std::stringstream ss; - ss << std::setw(10) << bus_i - << std::setw(10) << Pd - << std::setw(10) << Qd; + ss << std::setw(10) << bus_i << std::setw(10) << Pd << std::setw(10) + << Qd; ss << "\n"; return ss.str(); } @@ -100,27 +93,15 @@ namespace GridKit inline std::string str() const { std::stringstream ss; - ss << std::setw(10) << bus - << std::setw(10) << Pg - << std::setw(10) << Qg - << std::setw(10) << Qmax - << std::setw(10) << Qmin - << std::setw(10) << Vg - << std::setw(10) << mBase - << std::setw(10) << status - << std::setw(10) << Pmax - << std::setw(10) << Pmin - << std::setw(10) << Pc1 - << std::setw(10) << Pc2 - << std::setw(10) << Qc1min - << std::setw(10) << Qc1max - << std::setw(10) << Qc2min - << std::setw(10) << Qc2max - << std::setw(10) << ramp_agc - << std::setw(10) << ramp_10 - << std::setw(10) << ramp_30 - << std::setw(10) << ramp_q - << std::setw(10) << apf; + ss << std::setw(10) << bus << std::setw(10) << Pg << std::setw(10) << Qg + << std::setw(10) << Qmax << std::setw(10) << Qmin << std::setw(10) + << Vg << std::setw(10) << mBase << std::setw(10) << status + << std::setw(10) << Pmax << std::setw(10) << Pmin << std::setw(10) + << Pc1 << std::setw(10) << Pc2 << std::setw(10) << Qc1min + << std::setw(10) << Qc1max << std::setw(10) << Qc2min + << std::setw(10) << Qc2max << std::setw(10) << ramp_agc + << std::setw(10) << ramp_10 << std::setw(10) << ramp_30 + << std::setw(10) << ramp_q << std::setw(10) << apf; ss << "\n"; return ss.str(); } @@ -146,19 +127,11 @@ namespace GridKit inline std::string str() const { std::stringstream ss; - ss << std::setw(10) << fbus - << std::setw(10) << tbus - << std::setw(10) << r - << std::setw(10) << x - << std::setw(10) << b - << std::setw(10) << rateA - << std::setw(10) << rateB - << std::setw(10) << rateC - << std::setw(10) << ratio - << std::setw(10) << angle - << std::setw(10) << status - << std::setw(10) << angmin - << std::setw(10) << angmax; + ss << std::setw(10) << fbus << std::setw(10) << tbus << std::setw(10) + << r << std::setw(10) << x << std::setw(10) << b << std::setw(10) + << rateA << std::setw(10) << rateB << std::setw(10) << rateC + << std::setw(10) << ratio << std::setw(10) << angle << std::setw(10) + << status << std::setw(10) << angmin << std::setw(10) << angmax; ss << "\n"; return ss.str(); } @@ -176,10 +149,8 @@ namespace GridKit inline std::string str() const { std::stringstream ss; - ss << std::setw(10) << kind - << std::setw(10) << startup - << std::setw(10) << shutdown - << std::setw(10) << n; + ss << std::setw(10) << kind << std::setw(10) << startup << std::setw(10) + << shutdown << std::setw(10) << n; for (const auto& val : rest) ss << std::setw(10) << val; ss << "\n"; diff --git a/GridKit/Model/PowerFlow/SystemModel.hpp b/GridKit/Model/PowerFlow/SystemModel.hpp index 555828ddec..aad2bd3a3b 100644 --- a/GridKit/Model/PowerFlow/SystemModel.hpp +++ b/GridKit/Model/PowerFlow/SystemModel.hpp @@ -53,8 +53,7 @@ namespace GridKit /** * @brief Constructor for the system model */ - SystemModel() - : ModelEvaluatorImpl(0, 0, 0) + SystemModel() : ModelEvaluatorImpl(0, 0, 0) { } @@ -322,7 +321,8 @@ namespace GridKit component->setAbsoluteTolerance(rel_tol); if (component->size() > 0) { - const auto* component_abs_tol = component->absoluteTolerance().getData(); + const auto* component_abs_tol = + component->absoluteTolerance().getData(); for (IdxT j = 0; j < component->size(); ++j) { abs_tol[offset + j] = component_abs_tol[j]; @@ -968,7 +968,8 @@ namespace GridKit component->evaluateAdjointIntegrand(); if (component->sizeParams() > 0) { - const auto* component_gB = component->getAdjointIntegrand().getData(); + const auto* component_gB = + component->getAdjointIntegrand().getData(); for (IdxT j = 0; j < size_opt_; ++j) { gB[j] = component_gB[j]; diff --git a/GridKit/Model/PowerFlow/SystemModelPowerFlow.hpp b/GridKit/Model/PowerFlow/SystemModelPowerFlow.hpp index 9b03c719cf..0fbafd3eaf 100644 --- a/GridKit/Model/PowerFlow/SystemModelPowerFlow.hpp +++ b/GridKit/Model/PowerFlow/SystemModelPowerFlow.hpp @@ -66,17 +66,19 @@ namespace GridKit /** * @brief Constructor for the system model */ - SystemSteadyStateModel() - : ModelEvaluatorImpl(0, 0, 0) + SystemSteadyStateModel() : ModelEvaluatorImpl(0, 0, 0) { } /** - * @brief Construct a new System Steady State Model object. Allows for simple allocation. + * @brief Construct a new System Steady State Model object. Allows for + * simple allocation. * * @param mp model data */ - SystemSteadyStateModel(GridKit::PowerFlowData::SystemModelData mp) + SystemSteadyStateModel( + GridKit::PowerFlowData::SystemModelData mp + ) : ModelEvaluatorImpl(0, 0, 0) { // add buses @@ -89,21 +91,28 @@ namespace GridKit // add generators for (auto gendata : mp.gen) { - auto* gen = GeneratorFactory::create(this->getBus(gendata.bus), gendata); + auto* gen = GeneratorFactory::create( + this->getBus(gendata.bus), gendata + ); this->addComponent(gen); } // add branches for (auto branchdata : mp.branch) { - auto* branch = new Branch(this->getBus(branchdata.fbus), this->getBus(branchdata.tbus), branchdata); + auto* branch = new Branch( + this->getBus(branchdata.fbus), + this->getBus(branchdata.tbus), + branchdata + ); this->addComponent(branch); } // add loads for (auto loaddata : mp.load) { - auto* loadm = new Load(this->getBus(loaddata.bus_i), loaddata); + auto* loadm = + new Load(this->getBus(loaddata.bus_i), loaddata); this->addComponent(loadm); } diff --git a/GridKit/Model/VariableMonitor.hpp b/GridKit/Model/VariableMonitor.hpp index 906ff6522e..52de3199e5 100644 --- a/GridKit/Model/VariableMonitor.hpp +++ b/GridKit/Model/VariableMonitor.hpp @@ -33,7 +33,7 @@ namespace GridKit void formatReal(std::string& out, RealT value) { std::array buffer{}; - constexpr auto precision = std::numeric_limits::digits10 + 1; + constexpr auto precision = std::numeric_limits::digits10 + 1; auto [ptr, ec] = std::to_chars( buffer.data(), @@ -141,7 +141,9 @@ namespace GridKit virtual void appendEntries(std::vector&) const = 0; }; - template typename model_data_type> + template < + typename eval_type, + template typename model_data_type> class VariableMonitor; } // namespace Model diff --git a/GridKit/Model/VariableMonitorController.hpp b/GridKit/Model/VariableMonitorController.hpp index 944b3df3ee..daee5d536a 100644 --- a/GridKit/Model/VariableMonitorController.hpp +++ b/GridKit/Model/VariableMonitorController.hpp @@ -123,7 +123,9 @@ namespace GridKit buffer_.clear(); appendHeader(buffer_, sink); buffer_ += '\n'; - sink.os->write(buffer_.data(), static_cast(buffer_.size())); + sink.os->write( + buffer_.data(), static_cast(buffer_.size()) + ); } /** @@ -133,9 +135,9 @@ namespace GridKit { for (auto&& sink : sinks_) { - std::visit([this](auto&& sink) - { this->printFullHeader(sink); }, - sink); + std::visit( + [this](auto&& sink) { this->printFullHeader(sink); }, sink + ); } } @@ -161,7 +163,9 @@ namespace GridKit append(buffer_, sink); buffer_ += '\n'; } - sink.os->write(buffer_.data(), static_cast(buffer_.size())); + sink.os->write( + buffer_.data(), static_cast(buffer_.size()) + ); } /** @@ -171,9 +175,7 @@ namespace GridKit { for (auto&& sink : sinks_) { - std::visit([this](auto&& sink) - { this->printFull(sink); }, - sink); + std::visit([this](auto&& sink) { this->printFull(sink); }, sink); } ++sample_; } @@ -186,7 +188,9 @@ namespace GridKit { buffer_.clear(); appendFooter(buffer_, sink); - sink.os->write(buffer_.data(), static_cast(buffer_.size())); + sink.os->write( + buffer_.data(), static_cast(buffer_.size()) + ); } /** @@ -196,9 +200,9 @@ namespace GridKit { for (auto&& sink : sinks_) { - std::visit([this](auto&& sink) - { this->printFullFooter(sink); }, - sink); + std::visit( + [this](auto&& sink) { this->printFullFooter(sink); }, sink + ); } } @@ -209,7 +213,8 @@ namespace GridKit template void appendHeader(std::string& out, const SinkT& sink) const { - if constexpr (SinkT::format == Format::CSV && SinkT::layout == Layout::WIDE) + if constexpr (SinkT::format == Format::CSV + && SinkT::layout == Layout::WIDE) { out += "t"; for (auto&& entry : entries_) @@ -264,7 +269,8 @@ namespace GridKit const Entry* previous = nullptr; for (auto&& entry : entries_) { - if (previous && previous->device_class == entry.device_class && previous->id == entry.id) + if (previous && previous->device_class == entry.device_class + && previous->id == entry.id) { out += ",\n \""; } @@ -301,7 +307,8 @@ namespace GridKit const Entry* previous = nullptr; for (auto&& entry : entries_) { - if (!previous || previous->device_class != entry.device_class || previous->id != entry.id) + if (!previous || previous->device_class != entry.device_class + || previous->id != entry.id) { out += " "; out += entry.device_class; @@ -324,7 +331,13 @@ namespace GridKit * @brief Append one record of the long layout */ template - void appendRecord(std::string& out, const SinkT& sink, const std::string& sample, const std::string& t, const Entry& entry) const + void appendRecord( + std::string& out, + const SinkT& sink, + const std::string& sample, + const std::string& t, + const Entry& entry + ) const { if constexpr (SinkT::format == Format::CSV) { @@ -426,8 +439,7 @@ namespace GridKit * @brief Version for opening an output stream for the given file */ Sink(const std::string& fileName, const std::string& delimiter) - : file_name(fileName), - delim(delimiter) + : file_name(fileName), delim(delimiter) { } @@ -504,9 +516,14 @@ namespace GridKit { for (auto&& sink : sinks_) { - std::visit([this](auto&& sink) - { (void) this; sink.start(); }, - sink); + std::visit( + [this](auto&& sink) + { + (void) this; + sink.start(); + }, + sink + ); } } @@ -517,9 +534,14 @@ namespace GridKit { for (auto&& sink : sinks_) { - std::visit([this](auto&& sink) - { (void) this; sink.stop(); }, - sink); + std::visit( + [this](auto&& sink) + { + (void) this; + sink.stop(); + }, + sink + ); } } diff --git a/GridKit/Model/VariableMonitorImpl.hpp b/GridKit/Model/VariableMonitorImpl.hpp index d05469fb1e..2c016f5569 100644 --- a/GridKit/Model/VariableMonitorImpl.hpp +++ b/GridKit/Model/VariableMonitorImpl.hpp @@ -110,7 +110,12 @@ namespace GridKit { for (auto v : variables_) { - entries.emplace_back(device_class_, id_, enum_name(v), f_[static_cast(enum_integer(v))]); + entries.emplace_back( + device_class_, + id_, + enum_name(v), + f_[static_cast(enum_integer(v))] + ); } } diff --git a/GridKit/Solver/Dynamic/Ida.cpp b/GridKit/Solver/Dynamic/Ida.cpp index 98958e7aa5..f74f1c0e2b 100644 --- a/GridKit/Solver/Dynamic/Ida.cpp +++ b/GridKit/Solver/Dynamic/Ida.cpp @@ -302,7 +302,9 @@ namespace AnalysisManager * repeated time-step arithmetic. */ template - typename Ida::RealT Ida::getMonitorTime(RealT tf, RealT dt_monitor, int step, int nsteps) const + typename Ida::RealT Ida::getMonitorTime( + RealT tf, RealT dt_monitor, int step, int nsteps + ) const { return step == nsteps ? tf : std::fma((RealT) step, dt_monitor, t_init_); } @@ -1269,7 +1271,9 @@ namespace AnalysisManager * @tparam IdxT Index data type */ template - void Ida::setQuadratureTolerance(ScalarT rel_tol, ScalarT abs_tol_override) + void Ida::setQuadratureTolerance( + ScalarT rel_tol, ScalarT abs_tol_override + ) { quadrature_rel_tol_ = rel_tol; quadrature_abs_tol_override_ = abs_tol_override; @@ -1287,7 +1291,9 @@ namespace AnalysisManager * @tparam IdxT Index data type */ template - void Ida::setBackwardQuadratureTolerance(ScalarT rel_tol, ScalarT abs_tol_override) + void Ida::setBackwardQuadratureTolerance( + ScalarT rel_tol, ScalarT abs_tol_override + ) { backward_quadrature_rel_tol_ = rel_tol; backward_quadrature_abs_tol_override_ = abs_tol_override; @@ -1331,7 +1337,9 @@ namespace AnalysisManager * @tparam IdxT Index data type */ template - void Ida::setConsistentICType(IdaConsistentICType consistent_ic_type) + void Ida::setConsistentICType( + IdaConsistentICType consistent_ic_type + ) { consistent_ic_type_ = consistent_ic_type; } diff --git a/GridKit/Solver/Dynamic/Ida.hpp b/GridKit/Solver/Dynamic/Ida.hpp index 9c97523fc6..839339d3ca 100644 --- a/GridKit/Solver/Dynamic/Ida.hpp +++ b/GridKit/Solver/Dynamic/Ida.hpp @@ -152,8 +152,12 @@ namespace AnalysisManager using DynamicSolver::setTolerance; void setTolerance(ScalarT rel_tol, ScalarT abs_tol_override) override; void setBackwardTolerance(ScalarT rel_tol, ScalarT abs_tol_override = 0); - void setQuadratureTolerance(ScalarT rel_tol, ScalarT abs_tol_override = 0); - void setBackwardQuadratureTolerance(ScalarT rel_tol, ScalarT abs_tol_override = 0); + void setQuadratureTolerance( + ScalarT rel_tol, ScalarT abs_tol_override = 0 + ); + void setBackwardQuadratureTolerance( + ScalarT rel_tol, ScalarT abs_tol_override = 0 + ); void setSuppressAlgebraicErrors(bool suppress); void setBackwardSuppressAlgebraicErrors(bool suppress); void setConsistentICType(IdaConsistentICType consistent_ic_type); @@ -165,7 +169,9 @@ namespace AnalysisManager IdaStats getStats() const; private: - static int Residual(RealT t, N_Vector yy, N_Vector yp, N_Vector rr, void* user_data); + static int Residual( + RealT t, N_Vector yy, N_Vector yp, N_Vector rr, void* user_data + ); static int Jac( RealT t, @@ -180,7 +186,9 @@ namespace AnalysisManager N_Vector tmp3 ); - static int Integrand(RealT t, N_Vector yy, N_Vector yp, N_Vector rhsQ, void* user_data); + static int Integrand( + RealT t, N_Vector yy, N_Vector yp, N_Vector rhsQ, void* user_data + ); static int adjointResidual( RealT t, @@ -202,9 +210,10 @@ namespace AnalysisManager void* user_data ); - RealT getMonitorTime(RealT tf, RealT dt_monitor, int step, int nsteps) const; - int getIDAConsistentICType() const; - void updateModelState(RealT t); + RealT getMonitorTime(RealT tf, RealT dt_monitor, int step, int nsteps) + const; + int getIDAConsistentICType() const; + void updateModelState(RealT t); private: static constexpr ScalarT DEFAULT_REL_TOL = 1e-5; @@ -278,7 +287,9 @@ namespace AnalysisManager ScalarT abs_tol_override, ScalarT tol_fac = 1 ); - void setQuadratureTolerance(void* mem, ScalarT rel_tol, ScalarT abs_tol_override); + void setQuadratureTolerance( + void* mem, ScalarT rel_tol, ScalarT abs_tol_override + ); }; } // namespace Sundials diff --git a/GridKit/Solver/Dynamic/Native/AdaptiveStep.cpp b/GridKit/Solver/Dynamic/Native/AdaptiveStep.cpp index 23cc0f3062..03cbf4d140 100644 --- a/GridKit/Solver/Dynamic/Native/AdaptiveStep.cpp +++ b/GridKit/Solver/Dynamic/Native/AdaptiveStep.cpp @@ -10,17 +10,28 @@ namespace AnalysisManager namespace NativeDynamicSolver { /** - * @brief Standard textbook adaptive controller. Accept if `err <= 1` and use + * @brief Standard textbook adaptive controller. Accept if `err <= 1` and + * use * - * \f[h_{new} = h * \min \left\{fac_{max}, \max\left\{fac_{min}, fac_{scale} \cdot e ^{-1/p}\right\}\right\}.\f] + * \f[h_{new} = h * \min \left\{fac_{max}, \max\left\{fac_{min}, fac_{scale} + * \cdot e ^{-1/p}\right\}\right\}.\f] * */ template - StepControl AdaptiveStep::nextStep(RealT err, StepControl prev_step, uint8_t method_order) + StepControl AdaptiveStep::nextStep( + RealT err, StepControl prev_step, uint8_t method_order + ) { StepControl next_step = prev_step; - double h_mult = std::min(params_.fac_max_, std::max(params_.fac_scale_ * std::pow(err, GridKit::MINUS_ONE / method_order), params_.fac_min_)); + double h_mult = std::min( + params_.fac_max_, + std::max( + params_.fac_scale_ + * std::pow(err, GridKit::MINUS_ONE / method_order), + params_.fac_min_ + ) + ); next_step.accept_ = err <= 1; next_step.step_size_ *= h_mult; diff --git a/GridKit/Solver/Dynamic/Native/AdaptiveStep.hpp b/GridKit/Solver/Dynamic/Native/AdaptiveStep.hpp index 11740696b6..c9ee5e8a0f 100644 --- a/GridKit/Solver/Dynamic/Native/AdaptiveStep.hpp +++ b/GridKit/Solver/Dynamic/Native/AdaptiveStep.hpp @@ -8,8 +8,8 @@ namespace AnalysisManager { /** - * @brief A simple textbook adaptive `StepController` which seeks to meet a relative and absolute tolerance - * based on an error estimate. + * @brief A simple textbook adaptive `StepController` which seeks to meet a + * relative and absolute tolerance based on an error estimate. * */ template @@ -22,26 +22,30 @@ namespace AnalysisManager struct Parameters { /** - * @brief The minimum multiple by which the step size can be multiplied to obtain the new step size. - * Increasing this can allow the integrator to be slightly more conservative in selecting the step size - * - decreasing the number of steps taken but increasing the risk of failing the next step. + * @brief The minimum multiple by which the step size can be multiplied + * to obtain the new step size. Increasing this can allow the integrator + * to be slightly more conservative in selecting the step size + * - decreasing the number of steps taken but increasing the risk + * of failing the next step. * * @note Should be between 0 and 1. * */ RealT fac_min_ = 0.2; /** - * @brief The maximum multiple by which the step size can be multiplied to obtain the new step size. - * Decreasing this will make the integrator more conservative in selecting the step size - - * increasing the number of steps taken but decreasing the risk of failing the next step. + * @brief The maximum multiple by which the step size can be multiplied + * to obtain the new step size. Decreasing this will make the integrator + * more conservative in selecting the step size - increasing the number + * of steps taken but decreasing the risk of failing the next step. * * @note Should be greater than 1. * */ RealT fac_max_ = 5.0; /** - * @brief A "fudge factor" introduced to decrease risk of failing a step. The larger the fudge factor, - * the more likely steps will fail, but fewer steps will be taken. + * @brief A "fudge factor" introduced to decrease risk of failing a + * step. The larger the fudge factor, the more likely steps will fail, + * but fewer steps will be taken. * * @note Should be between 0 and 1. * @@ -50,12 +54,13 @@ namespace AnalysisManager } params_; public: - AdaptiveStep(const Parameters& params) - : params_(params) + AdaptiveStep(const Parameters& params) : params_(params) { } - StepControl nextStep(RealT err, StepControl prev_step, uint8_t method_order) final; + StepControl nextStep( + RealT err, StepControl prev_step, uint8_t method_order + ) final; /** * @brief This controller uses error estimates. diff --git a/GridKit/Solver/Dynamic/Native/ErrorNorm.hpp b/GridKit/Solver/Dynamic/Native/ErrorNorm.hpp index 279e9255f9..06ed92c716 100644 --- a/GridKit/Solver/Dynamic/Native/ErrorNorm.hpp +++ b/GridKit/Solver/Dynamic/Native/ErrorNorm.hpp @@ -9,7 +9,8 @@ namespace AnalysisManager namespace NativeDynamicSolver { /** - * @brief Interface for error norms. Used to calculate the `err` parameter in `StepController::nextStep` based on a residual state error vector. + * @brief Interface for error norms. Used to calculate the `err` parameter + * in `StepController::nextStep` based on a residual state error vector. * */ template @@ -20,19 +21,32 @@ namespace AnalysisManager public: /** - * @brief Calculate an error to be used by a step controller. Typically, an error > 1 indicates an error which does not meet tolerances, while - * an error < 1 indicates an error which meets tolerances. For that reason, tolerances should be included in the calculation of the error. + * @brief Calculate an error to be used by a step controller. Typically, + * an error > 1 indicates an error which does not meet tolerances, while + * an error < 1 indicates an error which meets tolerances. For that + * reason, tolerances should be included in the calculation of the error. * * @param err The state error residual being measured. - * @param y The state that the error was calculated from. Can be used for proper relative error normalization. - * @param yprev The state from the previous step. Can be used for proper relative error normalization. - * @param handler A vector handler which can be used to facilitate vector operations. - * @param memspace The memory space which vector operations should be performed in/. + * @param y The state that the error was calculated from. Can be used for + * proper relative error normalization. + * @param yprev The state from the previous step. Can be used for proper + * relative error normalization. + * @param handler A vector handler which can be used to facilitate vector + * operations. + * @param memspace The memory space which vector operations should be + * performed in/. * @return The error. * - * @todo Allow this method to fail, since it will likely involve linear algebra calls. + * @todo Allow this method to fail, since it will likely involve linear + * algebra calls. */ - virtual RealT errorNorm(State& err, State& y, State& yprev, GridKit::LinearAlgebra::VectorHandler& handler, GridKit::memory::MemorySpace memspace) const = 0; + virtual RealT errorNorm( + State& err, + State& y, + State& yprev, + GridKit::LinearAlgebra::VectorHandler& handler, + GridKit::memory::MemorySpace memspace + ) const = 0; }; } // namespace NativeDynamicSolver } // namespace AnalysisManager diff --git a/GridKit/Solver/Dynamic/Native/FixedStep.cpp b/GridKit/Solver/Dynamic/Native/FixedStep.cpp index ee4a571ba9..f81b338cc2 100644 --- a/GridKit/Solver/Dynamic/Native/FixedStep.cpp +++ b/GridKit/Solver/Dynamic/Native/FixedStep.cpp @@ -5,11 +5,16 @@ namespace AnalysisManager namespace NativeDynamicSolver { /** - * @brief Fixed step - accept every step, no matter the error, and keep the step size the same. + * @brief Fixed step - accept every step, no matter the error, and keep the + * step size the same. * */ template - StepControl FixedStep::nextStep([[maybe_unused]] RealT err, StepControl prev_step, [[maybe_unused]] uint8_t method_order) + StepControl FixedStep::nextStep( + [[maybe_unused]] RealT err, + StepControl prev_step, + [[maybe_unused]] uint8_t method_order + ) { return StepControl{ .accept_ = true, diff --git a/GridKit/Solver/Dynamic/Native/FixedStep.hpp b/GridKit/Solver/Dynamic/Native/FixedStep.hpp index 82edda6cf8..1c675a4ff9 100644 --- a/GridKit/Solver/Dynamic/Native/FixedStep.hpp +++ b/GridKit/Solver/Dynamic/Native/FixedStep.hpp @@ -7,17 +7,21 @@ namespace AnalysisManager namespace NativeDynamicSolver { /** - * @brief A fixed step controller which doesn't change the step size and accepts every step. - * Useful if you know what time scale your simulation operates on apriori and you're - * using a method without an embedded error controller. + * @brief A fixed step controller which doesn't change the step size and + * accepts every step. Useful if you know what time scale your simulation + * operates on apriori and you're using a method without an embedded error + * controller. * - * To set the fixed size, set the `Rosenbrock::Parameters::starting_step` parameter. + * To set the fixed size, set the + * `Rosenbrock::Parameters::starting_step` parameter. * */ template class FixedStep : public StepController { - StepControl nextStep(RealT err, StepControl prev_step, uint8_t method_order) final; + StepControl nextStep( + RealT err, StepControl prev_step, uint8_t method_order + ) final; /** * @brief This controller does not use error estimates. diff --git a/GridKit/Solver/Dynamic/Native/InfNorm.cpp b/GridKit/Solver/Dynamic/Native/InfNorm.cpp index 1d75c59dc4..c117373785 100644 --- a/GridKit/Solver/Dynamic/Native/InfNorm.cpp +++ b/GridKit/Solver/Dynamic/Native/InfNorm.cpp @@ -11,43 +11,84 @@ namespace AnalysisManager /** * @brief Calculate the infinity error norm as * - * \f[e = \max_i\frac{|\hat{e}_i|}{Atol_i + Rtol \cdot \max\{|y_{0i}|, |y_{1i}|\}},\f] + * \f[e = \max_i\frac{|\hat{e}_i|}{Atol_i + Rtol \cdot \max\{|y_{0i}|, + * |y_{1i}|\}},\f] * - * where \f(y_0\f) is the initial state, \f(y_1\f) is the next state, and \f(\hat{e}\f) is the estimated error made in calculating - * the next state (typically \f(\hat{e} = y_1 - \hat{y}_1\f) for some different-order approximation \f(\hat{y}_1\f)). + * where \f(y_0\f) is the initial state, \f(y_1\f) is the next state, and + * \f(\hat{e}\f) is the estimated error made in calculating the next state + * (typically \f(\hat{e} = y_1 - \hat{y}_1\f) for some different-order + * approximation \f(\hat{y}_1\f)). * * @param err \f(\hat{e}\f) in the above formula. * @param y \f(y_1\f) in the above formula. * @param yprev \f(y_0\f) in the above formula. - * @param handler The handler to be used for performing linear algebra operations. - * @param memspace The memory space to be used for performing linear algebra operations. + * @param handler The handler to be used for performing linear algebra + * operations. + * @param memspace The memory space to be used for performing linear algebra + * operations. * @see `Rosenbrock::errorEstimate()` */ template - InfNorm::RealT InfNorm::errorNorm(State& err, State& y, State& yprev, GridKit::LinearAlgebra::VectorHandler& handler, GridKit::memory::MemorySpace memspace) const + InfNorm::RealT InfNorm::errorNorm( + State& err, + State& y, + State& yprev, + GridKit::LinearAlgebra::VectorHandler& handler, + GridKit::memory::MemorySpace memspace + ) const { - if (int err_code = workspace_.out_->copyFromExternal(&err, memspace, memspace)) + if (int err_code = + workspace_.out_->copyFromExternal(&err, memspace, memspace)) { - throw std::format("GridKit::LinearAlgebra::Vector::copyFromExternal failed with error code {}", err_code); + throw std::format( + "GridKit::LinearAlgebra::Vector::copyFromExternal failed with error " + "code {}", + err_code + ); } - if (int err_code = workspace_.scale_->copyFromExternal(&y, memspace, memspace)) + if (int err_code = + workspace_.scale_->copyFromExternal(&y, memspace, memspace)) { - throw std::format("GridKit::LinearAlgebra::Vector::copyFromExternal failed with error code {}", err_code); + throw std::format( + "GridKit::LinearAlgebra::Vector::copyFromExternal failed with error " + "code {}", + err_code + ); } - if (int err_code = workspace_.yprev_abs_->copyFromExternal(&yprev, memspace, memspace)) + if (int err_code = + workspace_.yprev_abs_->copyFromExternal(&yprev, memspace, memspace)) { - throw std::format("GridKit::LinearAlgebra::Vector::copyFromExternal failed with error code {}", err_code); + throw std::format( + "GridKit::LinearAlgebra::Vector::copyFromExternal failed with error " + "code {}", + err_code + ); } handler.abs(workspace_.scale_.get(), workspace_.scale_.get(), memspace); - handler.abs(workspace_.yprev_abs_.get(), workspace_.scale_.get(), memspace); - handler.max(workspace_.yprev_abs_.get(), workspace_.scale_.get(), workspace_.scale_.get(), memspace); + handler.abs( + workspace_.yprev_abs_.get(), workspace_.scale_.get(), memspace + ); + handler.max( + workspace_.yprev_abs_.get(), + workspace_.scale_.get(), + workspace_.scale_.get(), + memspace + ); - // TODO: This scal shouldn't be necessary, but axpy doesn't support scaling the y parameter. In the future, - // the scaling should be able to be put on the next axpy. + // TODO: This scal shouldn't be necessary, but axpy doesn't support + // scaling the y parameter. In the future, the scaling should be able to + // be put on the next axpy. handler.scal(params_.rel_tol_, workspace_.scale_.get(), memspace); - handler.axpy(GridKit::ONE, params_.abs_tol_.get(), workspace_.scale_.get(), memspace); - handler.diagSolve(workspace_.scale_.get(), workspace_.out_.get(), memspace); + handler.axpy( + GridKit::ONE, + params_.abs_tol_.get(), + workspace_.scale_.get(), + memspace + ); + handler.diagSolve( + workspace_.scale_.get(), workspace_.out_.get(), memspace + ); return handler.amax(workspace_.out_.get(), memspace); } diff --git a/GridKit/Solver/Dynamic/Native/InfNorm.hpp b/GridKit/Solver/Dynamic/Native/InfNorm.hpp index 1910d53fe6..81606d3bd9 100644 --- a/GridKit/Solver/Dynamic/Native/InfNorm.hpp +++ b/GridKit/Solver/Dynamic/Native/InfNorm.hpp @@ -11,8 +11,8 @@ namespace AnalysisManager { /** - * @brief The infinity error norm, which requires the error in every component in the system - * to meet tolerance. + * @brief The infinity error norm, which requires the error in every + * component in the system to meet tolerance. * */ template @@ -22,7 +22,8 @@ namespace AnalysisManager using RealT = ErrorNorm::RealT; /** - * @brief A workspace for the linear algebra operations required to calculate the norm. + * @brief A workspace for the linear algebra operations required to + * calculate the norm. * */ mutable struct @@ -33,7 +34,8 @@ namespace AnalysisManager */ std::unique_ptr out_; /** - * @brief The vector which will be used to scale the error in accordance with the tolerances. + * @brief The vector which will be used to scale the error in accordance + * with the tolerances. * */ std::unique_ptr scale_; @@ -53,26 +55,32 @@ namespace AnalysisManager struct Parameters { /** - * @brief A vector of absolute tolerances for each component. The norm will attempt to reject errors - * in each component above this tolerance. + * @brief A vector of absolute tolerances for each component. The norm + * will attempt to reject errors in each component above this tolerance. * */ std::unique_ptr abs_tol_; /** - * @brief The relative tolerance. The norm will attempt to reject any error larger in percentage of - * the solution's maximum element than this. + * @brief The relative tolerance. The norm will attempt to reject any + * error larger in percentage of the solution's maximum element than + * this. * */ RealT rel_tol_; } params_; - InfNorm(Parameters&& params) - : params_(std::move(params)) + InfNorm(Parameters&& params) : params_(std::move(params)) { } - RealT errorNorm(State& err, State& y, State& yprev, GridKit::LinearAlgebra::VectorHandler& handler, GridKit::memory::MemorySpace memspace) const final; + RealT errorNorm( + State& err, + State& y, + State& yprev, + GridKit::LinearAlgebra::VectorHandler& handler, + GridKit::memory::MemorySpace memspace + ) const final; }; } // namespace NativeDynamicSolver diff --git a/GridKit/Solver/Dynamic/Native/StepControl.hpp b/GridKit/Solver/Dynamic/Native/StepControl.hpp index 5dc678a4cc..6fa5cb56cb 100644 --- a/GridKit/Solver/Dynamic/Native/StepControl.hpp +++ b/GridKit/Solver/Dynamic/Native/StepControl.hpp @@ -5,15 +5,17 @@ namespace AnalysisManager namespace NativeDynamicSolver { /** - * @brief Define control flow for `StepController`s to be able to control the step size of a `Rosenbrock` integrator. + * @brief Define control flow for `StepController`s to be able to control + * the step size of a `Rosenbrock` integrator. * */ template struct StepControl { /** - * @brief Whether or not the step is accepted. A rejected step will cause the time step controller to discard - * the next state and re-step with the new `step_size`. + * @brief Whether or not the step is accepted. A rejected step will cause + * the time step controller to discard the next state and re-step with the + * new `step_size`. * */ bool accept_; diff --git a/GridKit/Solver/Dynamic/Native/StepController.hpp b/GridKit/Solver/Dynamic/Native/StepController.hpp index 8c8abe5f88..8e42d221c2 100644 --- a/GridKit/Solver/Dynamic/Native/StepController.hpp +++ b/GridKit/Solver/Dynamic/Native/StepController.hpp @@ -9,30 +9,38 @@ namespace AnalysisManager namespace NativeDynamicSolver { /** - * @brief Interface for step size controllers. Used by `Rosenbrock` integrators to decide when to accept/reject steps and - * what size each step should be. + * @brief Interface for step size controllers. Used by `Rosenbrock` + * integrators to decide when to accept/reject steps and what size each step + * should be. * - * @todo It may be best to have \ref usesError() return a reference to the \ref ErrorNorm that should be used. + * @todo It may be best to have \ref usesError() return a reference to the + * \ref ErrorNorm that should be used. */ template class StepController { public: /** - * @brief Decide the control flow for the next step, based on information gathered by the integrator about the current step. + * @brief Decide the control flow for the next step, based on information + * gathered by the integrator about the current step. * - * @param err The estimated error made by the current step. Only calculated if `usesError()` returns true, otherwise it is assumed this + * @param err The estimated error made by the current step. Only + * calculated if `usesError()` returns true, otherwise it is assumed this * value is not used. - * @param prev_step The control flow from before the current step was taken. Can be used to accurately update the step size. + * @param prev_step The control flow from before the current step was + * taken. Can be used to accurately update the step size. * @param method_order The order of the method being used. * @return StepControl */ - virtual StepControl nextStep(RealT err, StepControl prev_step, uint8_t method_order) = 0; + virtual StepControl nextStep( + RealT err, StepControl prev_step, uint8_t method_order + ) = 0; /** - * @brief Return whether or not the `nextStep` method implementation uses the `err` parameter. If `false`, this parameter is not calculated. + * @brief Return whether or not the `nextStep` method implementation uses + * the `err` parameter. If `false`, this parameter is not calculated. * */ - virtual bool usesError() const = 0; + virtual bool usesError() const = 0; }; } // namespace NativeDynamicSolver } // namespace AnalysisManager diff --git a/GridKit/Solver/Dynamic/Rosenbrock.cpp b/GridKit/Solver/Dynamic/Rosenbrock.cpp index 2c641bcb82..d7fdb94e43 100644 --- a/GridKit/Solver/Dynamic/Rosenbrock.cpp +++ b/GridKit/Solver/Dynamic/Rosenbrock.cpp @@ -9,18 +9,19 @@ #include /** - * @brief A small helper macro to "bubble" errors. The Rosenbrock implementations call many - * fallible model and linear algebra functions, and often the only thing that can be - * done when one of these fails is to fail the current function as well. This macro - * wraps a fallible function call and causes the current function to fail as well, - * returning the same error code as the called function. + * @brief A small helper macro to "bubble" errors. The Rosenbrock + * implementations call many fallible model and linear algebra functions, and + * often the only thing that can be done when one of these fails is to fail the + * current function as well. This macro wraps a fallible function call and + * causes the current function to fail as well, returning the same error code as + * the called function. * */ -#define BUBBLE_FAIL(arg) \ - do \ - { \ - if (int err = (arg)) \ - return err; \ +#define BUBBLE_FAIL(arg) \ + do \ + { \ + if (int err = (arg)) \ + return err; \ } while (false) namespace AnalysisManager @@ -28,7 +29,8 @@ namespace AnalysisManager namespace NativeDynamicSolver { /** - * @brief Constructs a single-line report string out of the `StepInfo` object which is suitable to be included in a CSV file. + * @brief Constructs a single-line report string out of the `StepInfo` + * object which is suitable to be included in a CSV file. * * Useful if you would like to plot step info. * @@ -37,21 +39,16 @@ namespace AnalysisManager std::string Rosenbrock::StepInfo::csvReport() const { std::stringstream out; - out << std::scientific << std::setprecision(20) - << sim_time_ << ',' - << step_size_ << ',' - << next_step_size_ << ',' - << err_est_ << ',' - << step_no_ << ',' - << skip_lu_ << ',' - << skip_f_ << ',' - << accepted_; + out << std::scientific << std::setprecision(20) << sim_time_ << ',' + << step_size_ << ',' << next_step_size_ << ',' << err_est_ << ',' + << step_no_ << ',' << skip_lu_ << ',' << skip_f_ << ',' << accepted_; return out.str(); } /** - * @brief Constructs a human-readable report string out of the `StepInfo` object. + * @brief Constructs a human-readable report string out of the `StepInfo` + * object. * * Useful for debug dumps. * @@ -74,7 +71,8 @@ namespace AnalysisManager } /** - * @brief Constructs a human-readable report string out of the `Stats` object. + * @brief Constructs a human-readable report string out of the `Stats` + * object. * * Useful for reporting at the end of a simulation. * @@ -83,11 +81,9 @@ namespace AnalysisManager std::string Rosenbrock::Stats::report() const { std::stringstream out; - out << "Rejections: " << rejections_.size() - << "\nSteps: " << num_steps_ + out << "Rejections: " << rejections_.size() << "\nSteps: " << num_steps_ << "\nSkip LU Steps: " << skip_lu_steps_.size() - << "\nMin Step: " << min_step_ - << "\nMax Step: " << max_step_ + << "\nMin Step: " << min_step_ << "\nMax Step: " << max_step_ << "\nRHS Function Evals: " << f_evals_ << "\nRHS Function Skipped: " << f_skipped_ << "\nJacobian Evals: " << jac_evals_ @@ -97,18 +93,28 @@ namespace AnalysisManager } /** - * @brief Accumulate statistics into one object. Useful to collect statistics over runs of several simulations, such as when - * there is a discrete event. + * @brief Accumulate statistics into one object. Useful to collect + * statistics over runs of several simulations, such as when there is a + * discrete event. * * @param other The other statistics to add to this one. * - * @todo Right now, the step numbers for \ref rejections_ and \ref skip_lu_steps_ are impossible to tell apart from the different simulations. + * @todo Right now, the step numbers for \ref rejections_ and \ref + * skip_lu_steps_ are impossible to tell apart from the different + * simulations. */ template - typename Rosenbrock::Stats& Rosenbrock::Stats::operator+=(const Stats& other) + typename Rosenbrock::Stats& Rosenbrock:: + Stats::operator+=(const Stats& other) { - rejections_.insert(rejections_.end(), other.rejections_.begin(), other.rejections_.end()); - skip_lu_steps_.insert(skip_lu_steps_.end(), other.skip_lu_steps_.begin(), other.skip_lu_steps_.end()); + rejections_.insert( + rejections_.end(), other.rejections_.begin(), other.rejections_.end() + ); + skip_lu_steps_.insert( + skip_lu_steps_.end(), + other.skip_lu_steps_.begin(), + other.skip_lu_steps_.end() + ); num_steps_ += other.num_steps_; f_evals_ += other.f_evals_; @@ -123,20 +129,26 @@ namespace AnalysisManager } /** - * @brief Checks to see if the \ref asum_ variable can be re-used from the previous stage. - * - * Often, a row in the Rosenbrock A matrix is the exact same as the previous row, but with an additional - * non-zero element at the end. In this case, the \ref asum_ variable is the exact same as the previous stage, - * but with one extra additional term. The integrator can take advantage of this and reduce a matmul for computing + * @brief Checks to see if the \ref asum_ variable can be re-used from the + * previous stage. + * + * Often, a row in the Rosenbrock A matrix is the exact same as the previous + * row, but with an additional non-zero element at the end. In this case, + * the \ref asum_ variable is the exact same as the previous stage, but with + * one extra additional term. The integrator can take advantage of this and + * reduce a matmul for computing * \ref asum_ down to a single `axpy`. * - * Typically, \ref asum_ is only initialized if it needs to be re-calculated from scratch. For this reason, this - * function will always return `false` for `stage == 0`, forcing \ref asum_ to be initialized for the first stage. + * Typically, \ref asum_ is only initialized if it needs to be re-calculated + * from scratch. For this reason, this function will always return `false` + * for `stage == 0`, forcing \ref asum_ to be initialized for the first + * stage. * * @param stage The stage being checked. */ template - constexpr bool Rosenbrock::Tableau::canReuseAsum(size_t stage) const + constexpr bool Rosenbrock::Tableau::canReuseAsum(size_t stage + ) const { assert(stage < num_stages_); @@ -156,19 +168,24 @@ namespace AnalysisManager } /** - * @brief Checks to see if the \ref asum_ variable can be re-used from the last stage to compute the output state + * @brief Checks to see if the \ref asum_ variable can be re-used from the + * last stage to compute the output state * - * Often, the Rosenbrock m vector is the exact same as the last row in the A matrix, but with an additional - * non-zero element at the end. In this case, the output state for a step is equal to the \ref asum_ variables from - * the last stage but with a single weighted vector added to it. The integrator can take advantage of this and reduce - * a matmul for computing the final state down to a single `axpy`. + * Often, the Rosenbrock m vector is the exact same as the last row in the A + * matrix, but with an additional non-zero element at the end. In this case, + * the output state for a step is equal to the \ref asum_ variables from the + * last stage but with a single weighted vector added to it. The integrator + * can take advantage of this and reduce a matmul for computing the final + * state down to a single `axpy`. * - * If a method has only a single stage, then \ref asum_ will not have been initialized (as it will just be equal to y0). - * Therefore, this method will return `false`. + * If a method has only a single stage, then \ref asum_ will not have been + * initialized (as it will just be equal to y0). Therefore, this method will + * return `false`. * */ template - constexpr bool Rosenbrock::Tableau::canReuseAsumForOut() const + constexpr bool Rosenbrock::Tableau::canReuseAsumForOut( + ) const { if (num_stages_ == 1) return false; @@ -185,17 +202,21 @@ namespace AnalysisManager } /** - * @brief Returns the index of a stage which can be used as an embedded error estimator, if that stage exists. + * @brief Returns the index of a stage which can be used as an embedded + * error estimator, if that stage exists. * - * Sometimes, Rosenbrock methods are designed in such a way where a stage can be used as an embedded error estimator. - * Typically, the embedded error estimator is a linear combination of the stages, so in this particular case the - * weights will be 1 on the estimator stage and 0 on all other stages. + * Sometimes, Rosenbrock methods are designed in such a way where a stage + * can be used as an embedded error estimator. Typically, the embedded error + * estimator is a linear combination of the stages, so in this particular + * case the weights will be 1 on the estimator stage and 0 on all other + * stages. * - * @pre This function is only valid to call if there is an embedded error estimator and its coefficients - * are included in this tableau. + * @pre This function is only valid to call if there is an embedded error + * estimator and its coefficients are included in this tableau. */ template - constexpr std::optional Rosenbrock::Tableau::errorEstimatorStage() const + constexpr std::optional Rosenbrock::Tableau:: + errorEstimatorStage() const { assert(e_); @@ -217,16 +238,24 @@ namespace AnalysisManager /** * @brief Construct a new Rosenbrock integrator. * - * @param tab The tableau to be used for this integrator. Since tableaus contain `std::unique_ptr`, it must be moved into the integrator. - * @param model The model to be simulated. Despite taking a pointer, this must be a valid pointer to an `Evaluator`. - * Must have \ref GridKit::Model::Evaluator::tag() set, and must be in Hessenberg form (\f(F(\dot y, y) = \dot y - f(y)\f)). - * @param lin_solver The linear solver to be used when constructing stages during simulation. The reference must remain valid for as long - * as the Rosenbrock integrator lives. - * @param vector_handler The vector handler to be used when simulating. The reference must remain valid for as long as the Rosenbrock - * integrator lives. - * @param err_norm The error norm to use in calculating error for the `StepController`. Will not be accessed if the `StepController` - * does not need error (such as `FixedStep`), so `nullptr` can be passed in that circumstance. - * @param memspace The memory space that linear algebra operations should be performed in. + * @param tab The tableau to be used for this integrator. Since tableaus + * contain `std::unique_ptr`, it must be moved into the integrator. + * @param model The model to be simulated. Despite taking a pointer, this + * must be a valid pointer to an `Evaluator`. Must have \ref + * GridKit::Model::Evaluator::tag() set, and must be in Hessenberg form + * (\f(F(\dot y, y) = \dot y - f(y)\f)). + * @param lin_solver The linear solver to be used when constructing stages + * during simulation. The reference must remain valid for as long as the + * Rosenbrock integrator lives. + * @param vector_handler The vector handler to be used when simulating. The + * reference must remain valid for as long as the Rosenbrock integrator + * lives. + * @param err_norm The error norm to use in calculating error for the + * `StepController`. Will not be accessed if the `StepController` does not + * need error (such as `FixedStep`), so `nullptr` can be passed in that + * circumstance. + * @param memspace The memory space that linear algebra operations should be + * performed in. */ template Rosenbrock::Rosenbrock( @@ -247,12 +276,15 @@ namespace AnalysisManager } /** - * @brief Allocates memory based on the the size of \ref model_. Must be called before other methods. + * @brief Allocates memory based on the the size of \ref model_. Must be + * called before other methods. * * @note This method can fail. * - * @pre Allocates the Jacobian matrix, which requires knowledge of the number of nonzero elements. This must be known at this point, - * so `allocate()` must be called beforehand on \ref model_ to count the nonzero elements and allocate the CSR Jacobian. + * @pre Allocates the Jacobian matrix, which requires knowledge of the + * number of nonzero elements. This must be known at this point, so + * `allocate()` must be called beforehand on \ref model_ to count the + * nonzero elements and allocate the CSR Jacobian. * * @return An error code, with 0 as success. */ @@ -293,7 +325,8 @@ namespace AnalysisManager } } - workspace_.stages_ = std::make_unique[]>(tab_.num_stages_); + workspace_.stages_ = + std::make_unique[]>(tab_.num_stages_); for (size_t i = 0; i < tab_.num_stages_; i++) { workspace_.stages_[i] = std::make_unique(size); @@ -303,7 +336,8 @@ namespace AnalysisManager if (tab_.order_ > 2) { - dense_coeff_ = std::make_unique[]>(tab_.order_ - 2); + dense_coeff_ = + std::make_unique[]>(tab_.order_ - 2); for (size_t i = 0; i < static_cast(tab_.order_ - 2); i++) { dense_coeff_[i] = std::make_unique(size); @@ -315,18 +349,21 @@ namespace AnalysisManager } /** - * @brief Initializes the simulation. Must be called before \ref integrate() or \ref timeStep(). Must also be called after - * discrete events. + * @brief Initializes the simulation. Must be called before \ref integrate() + * or \ref timeStep(). Must also be called after discrete events. * - * - Sets the simulation time to `t0` and copies the initial condition from \ref model_. + * - Sets the simulation time to `t0` and copies the initial condition from + * \ref model_. * - Analyzes \ref model_ Jacobian sparsity and runs the preconditioner - * - Generates the mass matrix from \ref GridKit::Model::Evaluator::tag() as described in the class description. - * If the tag is not properly set, then initialization will fail. + * - Generates the mass matrix from \ref GridKit::Model::Evaluator::tag() as + * described in the class description. If the tag is not properly set, then + * initialization will fail. * - Resets \ref stats_. * * @note This method can fail. * - * @pre Must have called \ref allocate(). The `model.tag_` variable must be properly constructed. + * @pre Must have called \ref allocate(). The `model.tag_` variable must be + * properly constructed. * * @todo Document mass matrix construction * @@ -337,23 +374,30 @@ namespace AnalysisManager int Rosenbrock::initializeSimulation(RealT t0) { current_time_ = t0; - BUBBLE_FAIL(y_cur_->copyFromExternal(model_->y().getData(), memspace_, memspace_)); + BUBBLE_FAIL( + y_cur_->copyFromExternal(model_->y().getData(), memspace_, memspace_) + ); workspace_.jacobian_analyzed_ = false; BUBBLE_FAIL(lin_solver_.configureSolver(*model_->getCsrJacobian())); if (model_->tag().size() != static_cast(model_->size())) { - ::GridKit::Utilities::Logger::error() << "Model tag is either unset or does not match the size of the model\n"; + ::GridKit::Utilities::Logger::error() + << "Model tag is either unset or does not match the size of the " + "model\n"; return 1; } - std::unique_ptr mass = std::make_unique(model_->tag().size()); + std::unique_ptr mass = + std::make_unique(model_->tag().size()); for (size_t i = 0; i < static_cast(model_->size()); i++) { mass[i] = model_->tag()[i] ? GridKit::ONE : GridKit::ZERO; } - BUBBLE_FAIL(workspace_.mass_->copyFromExternal(mass.get(), memspace_, memspace_)); + BUBBLE_FAIL( + workspace_.mass_->copyFromExternal(mass.get(), memspace_, memspace_) + ); stats_ = Stats(); @@ -361,46 +405,65 @@ namespace AnalysisManager } /** - * @brief Simulate the given model, producing output at the given output times. + * @brief Simulate the given model, producing output at the given output + * times. * * Implements a simple time stepping algorithm and facilitates output. - * 1. Calls \ref timeStep() to move the simulation forward by \ref step_size_ (starting at `params.starting_step`). - * 2. Consults the `step_controller` to see if the step is accepted, and what the next \ref step_size_ should be. - * 3. If accepted, advance simulation by adding \ref step_size_ to \ref current_time_ using Kahan summation and shifting + * 1. Calls \ref timeStep() to move the simulation forward by \ref + * step_size_ (starting at `params.starting_step`). + * 2. Consults the `step_controller` to see if the step is accepted, and + * what the next \ref step_size_ should be. + * 3. If accepted, advance simulation by adding \ref step_size_ to \ref + * current_time_ using Kahan summation and shifting * \ref y_new_ -> \ref y_cur_ -> \ref y_prev_. - * 4. Any time we step over an output time, calculate dense coefficients if available. - * 5. For each output time stepped over in the last step, interpolate the output at that time and call `out_cb`. - * - * Time is advanced to at least the final output time. The simulation may step over the final time, so if you - * wish to restart simulation from the final output time, make sure to re-initialize the model's state and call + * 4. Any time we step over an output time, calculate dense coefficients if + * available. + * 5. For each output time stepped over in the last step, interpolate the + * output at that time and call `out_cb`. + * + * Time is advanced to at least the final output time. The simulation may + * step over the final time, so if you wish to restart simulation from the + * final output time, make sure to re-initialize the model's state and call * \ref initializeSimulation(). * * @note This method can fail. * * @pre Must have called \ref initializeSimulation(). * - * @todo A higher-order Hermite interpolation can be used as a fallback for interpolation when dense coefficients don't exist. - * Each step needs to sample the residual function at the beginning (and therefore end) of the step, which contains derivative - * information. This derivative information can be re-used for Hermite interpolation. + * @todo A higher-order Hermite interpolation can be used as a fallback for + * interpolation when dense coefficients don't exist. Each step needs to + * sample the residual function at the beginning (and therefore end) of the + * step, which contains derivative information. This derivative information + * can be re-used for Hermite interpolation. * - * @todo It doesn't really make sense to have the error estimator separate from the step controller, since your choice of one will - * affect your choice of the other. The error estimator should probably be inside the step controller, then accessed if needed. + * @todo It doesn't really make sense to have the error estimator separate + * from the step controller, since your choice of one will affect your + * choice of the other. The error estimator should probably be inside the + * step controller, then accessed if needed. * * @todo Return an error when max steps is hit. * - * @todo Check if current time is close enough to output time, and skip interpolation + * @todo Check if current time is close enough to output time, and skip + * interpolation * * @todo Configure upper bound for skip lu step size increase * - * @param out_times The times at which output is wanted. The simulation will stop once the final output time has been reached. - * @param step_controller The step size controller to use during the simulation. + * @param out_times The times at which output is wanted. The simulation will + * stop once the final output time has been reached. + * @param step_controller The step size controller to use during the + * simulation. * @param params The parameters to use during the simulation. - * @param out_cb An optional function which, if provided, will be called once for each time in `out_times`. The simulation time of the - * output is passed as the only argument. Before being called, the model will be updated with the output state and can be queried - * separately by the callback if needed. - * @param step_cb An optional function which, if provided, will be called once for each step the integrator takes. Information about the - * step which was just taken is provided as the argument. Before being called, the model will be updated with the current value of the state - * an can be queried separately by the callback if needed. Useful for debugging simulations. + * @param out_cb An optional function which, if provided, will be called + * once for each time in `out_times`. The simulation time of the output is + * passed as the only argument. Before being called, the model will be + * updated with the output state and can be queried separately by the + * callback if needed. + * @param step_cb An optional function which, if provided, will be called + * once for each step the integrator takes. Information about the step which + * was just taken is provided as the argument. Before being called, the + * model will be updated with the current value of the state an can be + * queried separately by the callback if needed. Useful for debugging + * simulations. * @return An error code, with 0 as success. */ template @@ -423,14 +486,15 @@ namespace AnalysisManager double next_step_size; - // Kahan summation time buffer. The "leftover" time that was lost when trying to add h at some point that needs to be added - // later + // Kahan summation time buffer. The "leftover" time that was lost when + // trying to add h at some point that needs to be added later double time_buffer = 0; // Generate output for each output time for (double out_time : out_times) { - while (current_time_ < out_time && stats_.num_steps_ < params.max_steps_) + while (current_time_ < out_time && stats_.num_steps_ < params.max_steps_ + ) { BUBBLE_FAIL(timeStep(current_time_, step_size_)); @@ -440,13 +504,17 @@ namespace AnalysisManager { if (err_norm_ == nullptr) { - ::GridKit::Utilities::Logger::error() << "The provided step controller requires the use of an error norm, but none was provided!\n"; + ::GridKit::Utilities::Logger::error() + << "The provided step controller requires the use of an error " + "norm, but none was provided!\n"; return -1; } State& err_vec = errorEstimate(); - err = err_norm_->errorNorm(err_vec, *y_new_, *y_cur_, vector_handler_, memspace_); + err = err_norm_->errorNorm( + err_vec, *y_new_, *y_cur_, vector_handler_, memspace_ + ); } StepControl next_step = step_controller.nextStep( @@ -457,8 +525,8 @@ namespace AnalysisManager }, tab_.order_ ); - prev_accept = next_step.accept_; - next_step_size = next_step.step_size_; + prev_accept = next_step.accept_; + next_step_size = next_step.step_size_; if (prev_accept) { @@ -466,30 +534,29 @@ namespace AnalysisManager double step_size_adj = step_size_ + time_buffer; double next_time = current_time_ + step_size_adj; - // Kahan summation - keep track of how much of step_size_adj we weren't able to add to current_time - // due to lack of precision + // Kahan summation - keep track of how much of step_size_adj we + // weren't able to add to current_time due to lack of precision time_buffer = step_size_adj - (next_time - current_time_); current_time_ = next_time; - // Since time is advancing, we need to re-evaluate the residual function and dense coefficients + // Since time is advancing, we need to re-evaluate the residual + // function and dense coefficients skip_f_ = false; dense_coefficients_valid_ = false; stats_.num_steps_++; if (skip_lu_) { - stats_.skip_lu_steps_.push_back( - StepInfo{ - .sim_time_ = current_time_, - .step_size_ = step_size_, - .next_step_size_ = next_step_size, - .err_est_ = err, - .step_no_ = stats_.num_steps_, - .skip_lu_ = skip_lu_, - .skip_f_ = skip_f_, - .accepted_ = prev_accept, - } - ); + stats_.skip_lu_steps_.push_back(StepInfo{ + .sim_time_ = current_time_, + .step_size_ = step_size_, + .next_step_size_ = next_step_size, + .err_est_ = err, + .step_no_ = stats_.num_steps_, + .skip_lu_ = skip_lu_, + .skip_f_ = skip_f_, + .accepted_ = prev_accept, + }); } stats_.min_step_ = std::min(stats_.min_step_, step_size_); stats_.max_step_ = std::max(stats_.max_step_, step_size_); @@ -503,22 +570,21 @@ namespace AnalysisManager { skip_f_ = true; - stats_.rejections_.push_back( - StepInfo{ - .sim_time_ = current_time_, - .step_size_ = step_size_, - .next_step_size_ = next_step_size, - .err_est_ = err, - .step_no_ = stats_.num_steps_, - .skip_lu_ = skip_lu_, - .skip_f_ = skip_f_, - .accepted_ = prev_accept, - } - ); + stats_.rejections_.push_back(StepInfo{ + .sim_time_ = current_time_, + .step_size_ = step_size_, + .next_step_size_ = next_step_size, + .err_est_ = err, + .step_no_ = stats_.num_steps_, + .skip_lu_ = skip_lu_, + .skip_f_ = skip_f_, + .accepted_ = prev_accept, + }); } - // Check if we can use time delay Jacobians. If we would have increased the step size (but not too much), - // instead keep the step size the same and use time-delay Jacobian. + // Check if we can use time delay Jacobians. If we would have + // increased the step size (but not too much), instead keep the step + // size the same and use time-delay Jacobian. // TODO: configure upper bound here double step_gain = next_step_size / step_size_; if (params.skip_lu_ && step_gain >= ONE && step_gain <= 1.2) @@ -535,7 +601,9 @@ namespace AnalysisManager // If there is a step_cb, update the model state and call it if (step_cb) { - BUBBLE_FAIL(y_cur_->copyToExternal(model_->y().getData(), memspace_, memspace_)); + BUBBLE_FAIL(y_cur_->copyToExternal( + model_->y().getData(), memspace_, memspace_ + )); model_->updateTime(current_time_, ZERO); (*step_cb)(StepInfo{ @@ -551,8 +619,9 @@ namespace AnalysisManager } } - // Check to make sure integration was paused because we reached an output time. - // Other reasons, like hitting max step count, shouldn't generate output. + // Check to make sure integration was paused because we reached an + // output time. Other reasons, like hitting max step count, shouldn't + // generate output. if (current_time_ >= out_time) { // Theta = (t - t0) / h = (t - t1) / h + 1 @@ -573,15 +642,21 @@ namespace AnalysisManager else { // TODO: Put code for alternative interpolation (Abdou) here - BUBBLE_FAIL(y_interp_->copyFromExternal(*y_prev_, memspace_, memspace_)); + BUBBLE_FAIL( + y_interp_->copyFromExternal(*y_prev_, memspace_, memspace_) + ); vector_handler_.scal(1 - theta, y_interp_.get(), memspace_); - vector_handler_.axpy(theta, y_cur_.get(), y_interp_.get(), memspace_); + vector_handler_.axpy( + theta, y_cur_.get(), y_interp_.get(), memspace_ + ); } // Update model with output and call out_cb if it exists if (out_cb) { - BUBBLE_FAIL(y_interp_->copyToExternal(model_->y().getData(), memspace_, memspace_)); + BUBBLE_FAIL(y_interp_->copyToExternal( + model_->y().getData(), memspace_, memspace_ + )); model_->updateTime(out_time, ZERO); (*out_cb)(out_time); @@ -589,7 +664,8 @@ namespace AnalysisManager } else { - BUBBLE_FAIL(y_interp_->copyFromExternal(*y_cur_, memspace_, memspace_)); + BUBBLE_FAIL(y_interp_->copyFromExternal(*y_cur_, memspace_, memspace_) + ); break; } } @@ -598,59 +674,94 @@ namespace AnalysisManager } /** - * @brief Advance the simulation forward by one step, storing the new state in \ref y_new_. + * @brief Advance the simulation forward by one step, storing the new state + * in \ref y_new_. * - * Apply the Rosenbrock scheme using the stored tableau. Each stage \f(u_i\f) is calculated as + * Apply the Rosenbrock scheme using the stored tableau. Each stage + * \f(u_i\f) is calculated as * - * \f[\left(J - \frac{1}{h\gamma} M\right)u_i = -f \left(t_0 + \alpha_ih, y_0 + \sum_{j = 1}^{i - 1} a_{ij}u_j\right) - M \sum_{j=1}^{i-1} \left(\frac{c_{ij}}{h}\right)u_j,\f] + * \f[\left(J - \frac{1}{h\gamma} M\right)u_i = -f \left(t_0 + \alpha_ih, + * y_0 + \sum_{j = 1}^{i - 1} a_{ij}u_j\right) - M \sum_{j=1}^{i-1} + * \left(\frac{c_{ij}}{h}\right)u_j,\f] * * and the next state \f(y_1\f) is calculated as * * \f[y_1 = y_0 + \sum_{j = 1}^sm_ju_j\f] * - * where the coefficients \f(\gamma, \alpha_i, a_{ij}, c_{ij}, m_j\f) come from the tableau, and the mass matrix \f(M\f) and Jacobian \f(J\f) come from the model. + * where the coefficients \f(\gamma, \alpha_i, a_{ij}, c_{ij}, m_j\f) come + * from the tableau, and the mass matrix \f(M\f) and Jacobian \f(J\f) come + * from the model. * - * This method uses some state which is maintained between calls for future calls to `timeStep()` and to communicate with \ref integrate(): + * This method uses some state which is maintained between calls for future + * calls to `timeStep()` and to communicate with \ref integrate(): * - \ref y_cur_ is used as \f(y_0\f) and \ref y_new_ is used as \f(y_1\f) - * - \ref asum_ is used as \f(y_0 + \sum_{j = 1}^{i - 1} a_{ij}u_j\f) for every stage except the first. Often, \f(a_{ij} = a_{i-1,j}\f), so this variable - * can be re-used between stages to save computation. Similarly, often \f(a_{ij} = m_j\f), so this variable can be re-used for computing \ref y_new_. - * - \ref csum_ is used as \f(M \sum_{j=1}^{i-1} \left(\frac{c_{ij}}{h}\right)u_j\f) for every stage except the first - * - \ref RHS_ is used as \f(-f \left(t_0 + \alpha_ih, y_0 + \sum_{j = 1}^{i - 1} a_{ij}u_j\right) - M \sum_{j=1}^{i-1} \left(\frac{c_{ij}}{h}\right)u_j\f), i.e. - * the residual evaluated at \ref asum_ plus \ref csum_, for every stage but the first. This is used as the right-hand side vector for the linear solve to solve - * for the stage value \f(u_i\f). - * - \ref RHS_first_stage_ is used as a special \ref RHS_ for the first stage, since it may need to be saved for the next step for the \ref skip_f_ flag. - * Since \f(\alpha_1 = 0\f) always, this will have a value of \f(f \left(t_0, y_0\right)\f). - * - \ref stages_ stores all of the stages \f(u_i\f). These stages are necessary to be used in future calls to \ref errorEstimate() and \ref calcDenseCoeff(). - * - \ref skip_lu_ is used as a flag set by \ref integrate() to indicate that it is appropriate to use a time-delay Jacobian by re-using the factorization - * of the last step. - * - \ref skip_f_ is used as a flag set by \ref integrate() to indicate that \f(t_0, y_0\f) have not changed since the last time `timeStep()` was called, - * so \ref RHS_first_stage_ can be re-used from the previous step. This will only happen when a step was rejected, so \ref skip_lu_ should always be false, - * and the entire first stage can't be re-used. - * - \ref jacobian_analyzed_ keeps track of whether the Jacobian has been factored in a previous call to `timeStep()`. If so, then it can be re-factored - * in a faster way. The first factor must be done on actual data, so it cannot be performed pre-simulation. - * - * @remark On evaluating the Jacobian: GridKit, like IDA, expects to evaluate the Jacobian \f(D = \frac{\partial F}{\partial y} + \alpha \frac{\partial F}{\partial \dot{y}}\f). As seen above, - * we need to evaluate \f(J - \frac{1}{h\gamma} M\f), where \f(J = \frac{\partial F}{\partial y}\f). Since, in the implicit form, \f(F = f(t, y) - M\dot{y}\f), then - * \f(M = - \frac{\partial F}{\partial \dot{y}}\f). So evaluating \f(D\f) with \f(\alpha = \frac{1}{h\gamma}\f) will get us what we want. + * - \ref asum_ is used as \f(y_0 + \sum_{j = 1}^{i - 1} a_{ij}u_j\f) for + * every stage except the first. Often, \f(a_{ij} = a_{i-1,j}\f), so this + * variable can be re-used between stages to save computation. Similarly, + * often \f(a_{ij} = m_j\f), so this variable can be re-used for computing + * \ref y_new_. + * - \ref csum_ is used as \f(M \sum_{j=1}^{i-1} + * \left(\frac{c_{ij}}{h}\right)u_j\f) for every stage except the first + * - \ref RHS_ is used as \f(-f \left(t_0 + \alpha_ih, y_0 + \sum_{j = 1}^{i + * - 1} a_{ij}u_j\right) - M \sum_{j=1}^{i-1} + * \left(\frac{c_{ij}}{h}\right)u_j\f), i.e. the residual evaluated at \ref + * asum_ plus \ref csum_, for every stage but the first. This is used as the + * right-hand side vector for the linear solve to solve for the stage value + * \f(u_i\f). + * - \ref RHS_first_stage_ is used as a special \ref RHS_ for the first + * stage, since it may need to be saved for the next step for the \ref + * skip_f_ flag. Since \f(\alpha_1 = 0\f) always, this will have a value of + * \f(f \left(t_0, y_0\right)\f). + * - \ref stages_ stores all of the stages \f(u_i\f). These stages are + * necessary to be used in future calls to \ref errorEstimate() and \ref + * calcDenseCoeff(). + * - \ref skip_lu_ is used as a flag set by \ref integrate() to indicate + * that it is appropriate to use a time-delay Jacobian by re-using the + * factorization of the last step. + * - \ref skip_f_ is used as a flag set by \ref integrate() to indicate that + * \f(t_0, y_0\f) have not changed since the last time `timeStep()` was + * called, so \ref RHS_first_stage_ can be re-used from the previous step. + * This will only happen when a step was rejected, so \ref skip_lu_ should + * always be false, and the entire first stage can't be re-used. + * - \ref jacobian_analyzed_ keeps track of whether the Jacobian has been + * factored in a previous call to `timeStep()`. If so, then it can be + * re-factored in a faster way. The first factor must be done on actual + * data, so it cannot be performed pre-simulation. + * + * @remark On evaluating the Jacobian: GridKit, like IDA, expects to + * evaluate the Jacobian \f(D = \frac{\partial F}{\partial y} + \alpha + * \frac{\partial F}{\partial \dot{y}}\f). As seen above, we need to + * evaluate \f(J - \frac{1}{h\gamma} M\f), where \f(J = \frac{\partial + * F}{\partial y}\f). Since, in the implicit form, \f(F = f(t, y) - + * M\dot{y}\f), then + * \f(M = - \frac{\partial F}{\partial \dot{y}}\f). So evaluating \f(D\f) + * with \f(\alpha = \frac{1}{h\gamma}\f) will get us what we want. * * @pre Must call \ref initializeSimulation() beforehand. * * @note This method can fail. * - * @todo This currently does not work with non-autonomous models. Some thought needs to be put in for how we want non-autonomous models to work. + * @todo This currently does not work with non-autonomous models. Some + * thought needs to be put in for how we want non-autonomous models to work. * - * @todo It doesn't really make sense to pass `t0` here, which may be inconsistent with \ref current_time_. - * This function should just use \ref current_time_ in place of `t0`. + * @todo It doesn't really make sense to pass `t0` here, which may be + * inconsistent with \ref current_time_. This function should just use \ref + * current_time_ in place of `t0`. * - * @todo It doesn't really make sense for this method to be `public` since it relies on proper setup via \ref integrate(). + * @todo It doesn't really make sense for this method to be `public` since + * it relies on proper setup via \ref integrate(). * - * @todo May be able to move the copying of model jacobian pointers to \ref allocate(). + * @todo May be able to move the copying of model jacobian pointers to \ref + * allocate(). * - * @todo Since \ref csum_ is multiplied by the mass matrix (which is currently diagonal with 0s for algebraic components), we can save some computation - * by only computing the differential parts of \ref csum_ and storing it in the same variable as \ref RHS_. + * @todo Since \ref csum_ is multiplied by the mass matrix (which is + * currently diagonal with 0s for algebraic components), we can save some + * computation by only computing the differential parts of \ref csum_ and + * storing it in the same variable as \ref RHS_. * * @param t0 \f(t_0\f) in the above formula - * @param dt \f(h\f) in the above formula. The next state \f(y_1\f) will be an estimate of the state at \f(t_1 = t_0 + h\f). + * @param dt \f(h\f) in the above formula. The next state \f(y_1\f) will be + * an estimate of the state at \f(t_1 = t_0 + h\f). * @return An error code, with 0 as success. */ template @@ -660,16 +771,20 @@ namespace AnalysisManager constexpr RealT ONE = GridKit::ONE; constexpr RealT MINUS_ONE = GridKit::MINUS_ONE; - // A flag to keep track of if y0 (stored in y_cur_) has been copied in to the model already, to avoid double-copying - // for evaluating the Jacobian and residual on stage 1 (both evaluated at y0). + // A flag to keep track of if y0 (stored in y_cur_) has been copied in to + // the model already, to avoid double-copying for evaluating the Jacobian + // and residual on stage 1 (both evaluated at y0). bool y0_copied = false; // Form the left-hand side of the system. This is constant between stages. - // Can sometimes be skipped if the method allows for time-delay Jacobians (such as w-methods). + // Can sometimes be skipped if the method allows for time-delay Jacobians + // (such as w-methods). [[likely]] if (!tab_.is_w_ || !skip_lu_) { - BUBBLE_FAIL(y_cur_->copyToExternal(model_->y().getData(), memspace_, memspace_)); + BUBBLE_FAIL( + y_cur_->copyToExternal(model_->y().getData(), memspace_, memspace_) + ); y0_copied = true; // See remark on evaluating Jacobian for why this constant is correct. @@ -692,17 +807,23 @@ namespace AnalysisManager // TODO: non-autonomous model if (!y0_copied) { - BUBBLE_FAIL(y_cur_->copyToExternal(model_->y().getData(), memspace_, memspace_)); + BUBBLE_FAIL( + y_cur_->copyToExternal(model_->y().getData(), memspace_, memspace_) + ); y0_copied = true; } model_->updateTime(t0, ZERO); BUBBLE_FAIL(model_->evaluateResidual()); - BUBBLE_FAIL(workspace_.RHS_first_stage_->copyFromExternal(model_->getResidual().getData(), memspace_, memspace_)); + BUBBLE_FAIL(workspace_.RHS_first_stage_->copyFromExternal( + model_->getResidual().getData(), memspace_, memspace_ + )); vector_handler_.scal(-1, workspace_.RHS_first_stage_.get(), memspace_); stats_.f_evals_++; } - BUBBLE_FAIL(lin_solver_.solve(*workspace_.RHS_first_stage_, *workspace_.stages_[0])); + BUBBLE_FAIL( + lin_solver_.solve(*workspace_.RHS_first_stage_, *workspace_.stages_[0]) + ); stats_.decomp_solves_++; // Rest of stages @@ -713,52 +834,85 @@ namespace AnalysisManager if (i > 1 && tab_.canReuseAsum(i)) { if (tab_.A_[tab_.num_stages_ * i + i - 1] != ZERO) - vector_handler_.axpy(tab_.A_[tab_.num_stages_ * i + i - 1], workspace_.stages_[i - 1].get(), workspace_.asum_.get(), memspace_); + vector_handler_.axpy( + tab_.A_[tab_.num_stages_ * i + i - 1], + workspace_.stages_[i - 1].get(), + workspace_.asum_.get(), + memspace_ + ); } else { - BUBBLE_FAIL(workspace_.asum_->copyFromExternal(*y_cur_, memspace_, memspace_)); + BUBBLE_FAIL( + workspace_.asum_->copyFromExternal(*y_cur_, memspace_, memspace_) + ); for (size_t j = 0; j < i; j++) { if (tab_.A_[tab_.num_stages_ * i + j] != ZERO) - vector_handler_.axpy(tab_.A_[tab_.num_stages_ * i + j], workspace_.stages_[j].get(), workspace_.asum_.get(), memspace_); + vector_handler_.axpy( + tab_.A_[tab_.num_stages_ * i + j], + workspace_.stages_[j].get(), + workspace_.asum_.get(), + memspace_ + ); } } // Calculate csum - // TODO: Since csum is multiplied by the mass matrix, we can reduce calculations by just not calculating some indices + // TODO: Since csum is multiplied by the mass matrix, we can reduce + // calculations by just not calculating some indices BUBBLE_FAIL(workspace_.csum_->setToZero(memspace_)); for (size_t j = 0; j < i; j++) { if (tab_.C_[i * tab_.num_stages_ + j] != ZERO) { - vector_handler_.axpy(tab_.C_[i * tab_.num_stages_ + j] / dt, workspace_.stages_[j].get(), workspace_.csum_.get(), memspace_); + vector_handler_.axpy( + tab_.C_[i * tab_.num_stages_ + j] / dt, + workspace_.stages_[j].get(), + workspace_.csum_.get(), + memspace_ + ); } } // TODO: non-autonomous model - BUBBLE_FAIL(workspace_.asum_->copyToExternal(model_->y().getData(), memspace_, memspace_)); + BUBBLE_FAIL(workspace_.asum_->copyToExternal( + model_->y().getData(), memspace_, memspace_ + )); model_->updateTime(t0 + tab_.alpha_sum_[i] * dt, ZERO); BUBBLE_FAIL(model_->evaluateResidual()); - workspace_.RHS_->copyFromExternal(model_->getResidual().getData(), memspace_, memspace_); + workspace_.RHS_->copyFromExternal( + model_->getResidual().getData(), memspace_, memspace_ + ); vector_handler_.scal(MINUS_ONE, workspace_.RHS_.get(), memspace_); - vector_handler_.scal(workspace_.mass_.get(), workspace_.csum_.get(), memspace_); - vector_handler_.axpy(MINUS_ONE, workspace_.csum_.get(), workspace_.RHS_.get(), memspace_); - - BUBBLE_FAIL(lin_solver_.solve(*workspace_.RHS_, *workspace_.stages_[i])); + vector_handler_.scal( + workspace_.mass_.get(), workspace_.csum_.get(), memspace_ + ); + vector_handler_.axpy( + MINUS_ONE, workspace_.csum_.get(), workspace_.RHS_.get(), memspace_ + ); + + BUBBLE_FAIL(lin_solver_.solve(*workspace_.RHS_, *workspace_.stages_[i]) + ); stats_.f_evals_++; stats_.decomp_solves_++; } // Compute the solution at time t + dt // It happens often where the solution is just asum of the last stage - // plus some multiple of the last stage. In that case we can avoid a matmul + // plus some multiple of the last stage. In that case we can avoid a + // matmul if (tab_.canReuseAsumForOut()) { std::swap(workspace_.asum_, y_new_); - vector_handler_.axpy(tab_.m_[tab_.num_stages_ - 1], workspace_.stages_[tab_.num_stages_ - 1].get(), y_new_.get(), memspace_); + vector_handler_.axpy( + tab_.m_[tab_.num_stages_ - 1], + workspace_.stages_[tab_.num_stages_ - 1].get(), + y_new_.get(), + memspace_ + ); } else { @@ -768,7 +922,9 @@ namespace AnalysisManager { if (tab_.m_[j] != ZERO) { - vector_handler_.axpy(tab_.m_[j], workspace_.stages_[j].get(), y_new_.get(), memspace_); + vector_handler_.axpy( + tab_.m_[j], workspace_.stages_[j].get(), y_new_.get(), memspace_ + ); } } } @@ -777,30 +933,38 @@ namespace AnalysisManager } /** - * @brief Calculates an estimation of the error produced by the last call to \ref timeStep() which can be used as the - * `err` argument for \ref ErrorNorm::errorNorm(). + * @brief Calculates an estimation of the error produced by the last call to + * \ref timeStep() which can be used as the `err` argument for \ref + * ErrorNorm::errorNorm(). * * Calculate the embedded error as * * \f[\hat{e} = \sum_{j = 1}^s e_j u_j,\f] * - * where \f(e_j\f) are tableau coefficients and \f(u_j\f) are stages computed by \ref timeStep(). It happens often that - * \f(e_j = 0\f) for all but one stage, where \f(e_j = 1\f). In that case, the stage itself is used as the error estimate, - * and extra calculation can be avoided. For this reason, a reference to the estimate is returned to avoid an unnecessary copy. + * where \f(e_j\f) are tableau coefficients and \f(u_j\f) are stages + * computed by \ref timeStep(). It happens often that + * \f(e_j = 0\f) for all but one stage, where \f(e_j = 1\f). In that case, + * the stage itself is used as the error estimate, and extra calculation can + * be avoided. For this reason, a reference to the estimate is returned to + * avoid an unnecessary copy. * - * @pre Must call \ref timeStep(), and tableau must have coefficients for an embedded error estimator. + * @pre Must call \ref timeStep(), and tableau must have coefficients for an + * embedded error estimator. * @note This method can fail. * - * @todo This function is fallible, but the return type makes it difficult to return an error code. Right now it will throw an - * error, but it should be refactored to allow returning an error code, such as by returning `std::variant`. + * @todo This function is fallible, but the return type makes it difficult + * to return an error code. Right now it will throw an error, but it should + * be refactored to allow returning an error code, such as by returning + * `std::variant`. * * @return A reference to the estimated error. */ template - Rosenbrock::State& Rosenbrock::errorEstimate() const + Rosenbrock::State& Rosenbrock::errorEstimate( + ) const { - // Test to see if the tableau allows us to use a stage as the error estimate, - // avoiding extra computation. + // Test to see if the tableau allows us to use a stage as the error + // estimate, avoiding extra computation. std::optional err_stage = tab_.errorEstimatorStage(); if (err_stage) @@ -809,12 +973,19 @@ namespace AnalysisManager } else { - // TODO: could make this function return recoverable errors by using std::variant - int err_code = workspace_.err_est_->copyFromExternal(*workspace_.stages_[0], memspace_, memspace_); + // TODO: could make this function return recoverable errors by using + // std::variant + int err_code = workspace_.err_est_->copyFromExternal( + *workspace_.stages_[0], memspace_, memspace_ + ); if (err_code) { - throw std::format("ReSolve::vector::Vector::copyFromExternal failed with error code {}", err_code); + throw std::format( + "ReSolve::vector::Vector::copyFromExternal failed with error code " + "{}", + err_code + ); } vector_handler_.scal(tab_.e_[0], workspace_.err_est_.get(), memspace_); @@ -822,7 +993,12 @@ namespace AnalysisManager { if (tab_.e_[j] != GridKit::ZERO) { - vector_handler_.axpy(tab_.e_[j], workspace_.stages_[j].get(), workspace_.err_est_.get(), memspace_); + vector_handler_.axpy( + tab_.e_[j], + workspace_.stages_[j].get(), + workspace_.err_est_.get(), + memspace_ + ); } } @@ -831,10 +1007,12 @@ namespace AnalysisManager } /** - * @brief Calculate the interpolation nodes used by \ref interpDense() based on \ref stages_ computed by - * the last call to \ref timeStep(). Nodes are stored in \ref dense_coeff_. Only needs to be called once, - * but can be invalidated by future calls to \ref timeStep(). \ref integrate() keeps track of \ref dense_coefficients_valid_, - * which tells you if this function is needed to be called. + * @brief Calculate the interpolation nodes used by \ref interpDense() based + * on \ref stages_ computed by the last call to \ref timeStep(). Nodes are + * stored in \ref dense_coeff_. Only needs to be called once, but can be + * invalidated by future calls to \ref timeStep(). \ref integrate() keeps + * track of \ref dense_coefficients_valid_, which tells you if this function + * is needed to be called. * * @pre Must call \ref timeStep() first. * @@ -856,7 +1034,12 @@ namespace AnalysisManager { for (size_t j = 0; j < static_cast(tab_.order_ - 2); j++) { - vector_handler_.axpy(tab_.H_[j * tab_.num_stages_ + i], workspace_.stages_[i].get(), dense_coeff_[j].get(), memspace_); + vector_handler_.axpy( + tab_.H_[j * tab_.num_stages_ + i], + workspace_.stages_[i].get(), + dense_coeff_[j].get(), + memspace_ + ); } } } @@ -865,31 +1048,38 @@ namespace AnalysisManager } /** - * @brief Calculate an interpolated state at \f(\theta = \frac{t - t_0}{h}\f) between the initial state - * \f(y_0\f) and final state \f(y_1\f) of the last step taken using dense interpolation nodes calculated - * by \ref calcDenseCoeff(). + * @brief Calculate an interpolated state at \f(\theta = \frac{t - + * t_0}{h}\f) between the initial state + * \f(y_0\f) and final state \f(y_1\f) of the last step taken using dense + * interpolation nodes calculated by \ref calcDenseCoeff(). * - * For a valid interpolation of appropriate order, \f(\theta\f) must be in \f([0, 1]\f), although values - * beyond 1 can be used for extrapolation if desired. + * For a valid interpolation of appropriate order, \f(\theta\f) must be in + * \f([0, 1]\f), although values beyond 1 can be used for extrapolation if + * desired. * - * Uses a number of interpolation nodes equal to the order. Since \f(y_0\f) and \f(y_1\f) are interpolation - * nodes, this method will only access \ref dense_coeff_ if the method's order is greater than 2. + * Uses a number of interpolation nodes equal to the order. Since \f(y_0\f) + * and \f(y_1\f) are interpolation nodes, this method will only access \ref + * dense_coeff_ if the method's order is greater than 2. * * The interpolation is calculated as * - * \f[y(\theta) = (1 - \theta) y_0 + \theta \left(y_1 + (1 - \theta) \sum_{i = 1}^{p-2} \theta^{i-1} \hat{y}_i\right),\f] + * \f[y(\theta) = (1 - \theta) y_0 + \theta \left(y_1 + (1 - \theta) \sum_{i + * = 1}^{p-2} \theta^{i-1} \hat{y}_i\right),\f] * - * where \f(\hat{y}_i\f) are the dense interpolation nodes calculated in \ref calcDenseCoeff() and \f(p\f) is the order of the method. - * This calculation is carried out using synthetic division. + * where \f(\hat{y}_i\f) are the dense interpolation nodes calculated in + * \ref calcDenseCoeff() and \f(p\f) is the order of the method. This + * calculation is carried out using synthetic division. * * @pre Must call \ref calcDenseCoeff() first. * * @note This method can fail. * - * @note If `theta` is very close to 0 or very close to 1, it might be better to simply use \ref y_prev_ or \ref y_cur_ instead of - * calculating this interpolation. + * @note If `theta` is very close to 0 or very close to 1, it might be + * better to simply use \ref y_prev_ or \ref y_cur_ instead of calculating + * this interpolation. * - * @param theta The fraction of time during the last step taken to calculate the interpolation at. \f(\theta = \frac{t - t_0}{h}\f) + * @param theta The fraction of time during the last step taken to calculate + * the interpolation at. \f(\theta = \frac{t - t_0}{h}\f) * @return An error code, with 0 as success. */ template @@ -899,16 +1089,24 @@ namespace AnalysisManager if (tab_.order_ > 2) { - BUBBLE_FAIL(y_interp_->copyFromExternal(*dense_coeff_[tab_.order_ - 3], memspace_, memspace_)); + BUBBLE_FAIL(y_interp_->copyFromExternal( + *dense_coeff_[tab_.order_ - 3], memspace_, memspace_ + )); for (size_t i = 1; i < static_cast(tab_.order_ - 2); i++) { vector_handler_.scal(theta, y_interp_.get(), memspace_); - vector_handler_.axpy(ONE, dense_coeff_[tab_.order_ - 3 - i].get(), y_interp_.get(), memspace_); + vector_handler_.axpy( + ONE, + dense_coeff_[tab_.order_ - 3 - i].get(), + y_interp_.get(), + memspace_ + ); } - // TODO: This scal can be removed and absorbed into the next axpy, except that it currently isn't possible to put a scalar - // multiple on the y term. + // TODO: This scal can be removed and absorbed into the next axpy, + // except that it currently isn't possible to put a scalar multiple on + // the y term. vector_handler_.scal(ONE - theta, y_interp_.get(), memspace_); } else @@ -918,7 +1116,9 @@ namespace AnalysisManager vector_handler_.axpy(ONE, y_cur_.get(), y_interp_.get(), memspace_); vector_handler_.scal(theta, y_interp_.get(), memspace_); - vector_handler_.axpy(ONE - theta, y_prev_.get(), y_interp_.get(), memspace_); + vector_handler_.axpy( + ONE - theta, y_prev_.get(), y_interp_.get(), memspace_ + ); return 0; } diff --git a/GridKit/Solver/Dynamic/Rosenbrock.hpp b/GridKit/Solver/Dynamic/Rosenbrock.hpp index d9886f3d50..3714c437a3 100644 --- a/GridKit/Solver/Dynamic/Rosenbrock.hpp +++ b/GridKit/Solver/Dynamic/Rosenbrock.hpp @@ -22,22 +22,26 @@ namespace AnalysisManager namespace NativeDynamicSolver { /** - * @brief A Rosenbrock integrator designed to simulate a `GridKit::Model::Evaluator` model. - * Rosenbrock integrators are best for quick medium-accuracy simulation and - * boast a large amount of customization to simulating a given model. + * @brief A Rosenbrock integrator designed to simulate a + * `GridKit::Model::Evaluator` model. Rosenbrock integrators are best for + * quick medium-accuracy simulation and boast a large amount of + * customization to simulating a given model. * - * For the list of available Rosenbrock methods, see `Rosenbrock::Tableau`. + * For the list of available Rosenbrock methods, see + * `Rosenbrock::Tableau`. * - * The Rosenbrock integrator is built to integrate DAEs in semi-explicit form with - * (optional) mass matrix \f(M\f) given by + * The Rosenbrock integrator is built to integrate DAEs in + * semi-explicit form with (optional) mass matrix \f(M\f) given by * \f[M\dot{y} = f(t, y),\f] - * where \f(M\f) is constant and can be singular (\f(M\f) is non-singular only for ODEs). - * GridKit models equations in this semi-explicit form, but evaluates the implicit equation + * where \f(M\f) is constant and can be singular (\f(M\f) is + * non-singular only for ODEs). GridKit models equations in this + * semi-explicit form, but evaluates the implicit equation * \f[F(t, y, \dot{y}) = f(t, y) - M\dot{y}\f] - * whenever \ref GridKit::Model::Evaluator::evaluateResidual() is called. Also, all models currently use - * a diagonal mass matrix with values of only 1 or 0, as indicated by \ref GridKit::Model::Evaluator::tag(). - * We can use this by evaluating \f(F(t, y, 0) = f(t,y)\f) and constructing the mass matrix - * based on the tag. + * whenever \ref GridKit::Model::Evaluator::evaluateResidual() is + * called. Also, all models currently use a diagonal mass matrix with values + * of only 1 or 0, as indicated by \ref GridKit::Model::Evaluator::tag(). We + * can use this by evaluating \f(F(t, y, 0) = f(t,y)\f) and constructing the + * mass matrix based on the tag. */ template class Rosenbrock @@ -63,12 +67,14 @@ namespace AnalysisManager */ RealT step_size_; /** - * @brief The size of the next step, as governed by the current `StepController` in use. + * @brief The size of the next step, as governed by the current + * `StepController` in use. * */ RealT next_step_size_; /** - * @brief The estimated error made by the step, as calculated by the current `ErrorNorm` in use. + * @brief The estimated error made by the step, as calculated by the + * current `ErrorNorm` in use. * */ RealT err_est_; @@ -78,17 +84,20 @@ namespace AnalysisManager */ size_t step_no_; /** - * @brief Whether or not the integrator decided to skip computing the decomposition of the Jacobian on this step. + * @brief Whether or not the integrator decided to skip computing the + * decomposition of the Jacobian on this step. * */ bool skip_lu_; /** - * @brief Whether or not the integrator decided to skip evaluating the residual on the first stage on this step. + * @brief Whether or not the integrator decided to skip evaluating the + * residual on the first stage on this step. * */ bool skip_f_; /** - * @brief Whether or not this step was accepted by the `StepController` in use. + * @brief Whether or not this step was accepted by the `StepController` + * in use. * */ bool accepted_; @@ -98,7 +107,8 @@ namespace AnalysisManager }; /** - * @brief Keeps track of running statistics of the integrator since the last `initializeSimulation()` call. + * @brief Keeps track of running statistics of the integrator since the + * last `initializeSimulation()` call. * */ struct Stats @@ -109,7 +119,8 @@ namespace AnalysisManager */ std::vector rejections_; /** - * @brief Information of each step which the integrator decided to skip re-factoring the Jacobian. + * @brief Information of each step which the integrator decided to skip + * re-factoring the Jacobian. * */ std::vector skip_lu_steps_; @@ -124,7 +135,8 @@ namespace AnalysisManager */ size_t f_evals_ = 0; /** - * @brief Number of model residual function evaluations which have been skipped by the integrator. + * @brief Number of model residual function evaluations which have been + * skipped by the integrator. * */ size_t f_skipped_ = 0; @@ -162,35 +174,42 @@ namespace AnalysisManager /** * @brief What step size the first step should take. * - * @todo Consider adding a starting step size selector to select this automatically. + * @todo Consider adding a starting step size selector to select this + * automatically. */ RealT starting_step_ = 1e-5; /** - * @brief The maximum number of steps the integrator should take. If the integrator has not reached the final time before - * taking this many steps, then integration is stopped. For more details, see `integrate()`. + * @brief The maximum number of steps the integrator should take. If the + * integrator has not reached the final time before taking this many + * steps, then integration is stopped. For more details, see + * `integrate()`. * */ size_t max_steps_ = 2000; /** - * @brief Whether or not the integrator should attempt to skip Jacobian decompositions. + * @brief Whether or not the integrator should attempt to skip Jacobian + * decompositions. * - * @note This feature is only available if the underlying method is a Rosenbrock-W method and can speed up - * the time taken to compute each step. However, the overall number of steps taken will increase. + * @note This feature is only available if the underlying method is a + * Rosenbrock-W method and can speed up the time taken to compute each + * step. However, the overall number of steps taken will increase. * */ bool skip_lu_ = false; }; /** - * @brief A list of the coefficients needed to complete Rosenbrock integration in an accurate way. - * Each tableau can be considered a different method or scheme, and will have different properties, + * @brief A list of the coefficients needed to complete Rosenbrock + * integration in an accurate way. Each tableau can be considered a + * different method or scheme, and will have different properties, * advantages, and disadvantages. * */ struct Tableau { /** - * @brief The number of stages used by the method. Each stage requires one model residual evaluation. + * @brief The number of stages used by the method. Each stage requires + * one model residual evaluation. * */ size_t num_stages_; @@ -200,79 +219,91 @@ namespace AnalysisManager */ RealT gamma_; /** - * @brief A vector of sums of rows of the alpha matrix. These are the classic - * Runge-Kutta 'c' coefficients, or abscissae. The size of this vector - * should be equal to `num_stages`. + * @brief A vector of sums of rows of the alpha matrix. These are the + * classic Runge-Kutta 'c' coefficients, or abscissae. The size of this + * vector should be equal to `num_stages`. * */ std::unique_ptr alpha_sum_; /** - * @brief A vector of sums of rows of the Gamma matrix. The size of this vector - * should be equal to `num_stages`. + * @brief A vector of sums of rows of the Gamma matrix. The size of this + * vector should be equal to `num_stages`. * */ std::unique_ptr gamma_sum_; /** - * @brief A vector of weights for constructing the final solution from the stages. - * The size of this vector should be equal to `num_stages`. + * @brief A vector of weights for constructing the final solution from + * the stages. The size of this vector should be equal to `num_stages`. * */ std::unique_ptr m_; /** - * @brief OPTIONAL vector of coefficients for the embedded error method. If it exists, - * the size of this vector should be equal to `num_stages`. + * @brief OPTIONAL vector of coefficients for the embedded error method. + * If it exists, the size of this vector should be equal to + * `num_stages`. * */ std::unique_ptr e_; /** - * @brief The transformed A coefficient matrix. Strictly lower triangular and stored in dense row-major form. - * Upper triangular terms are not accessed. Should be `num_stages` by `num_stages` large. + * @brief The transformed A coefficient matrix. Strictly lower + * triangular and stored in dense row-major form. Upper triangular terms + * are not accessed. Should be `num_stages` by `num_stages` large. * */ std::unique_ptr A_; /** - * @brief The transformed C coefficient matrix. Strictly lower triangular and stored in dense row-major form. - * Upper triangular terms are not accessed. Should be `num_stages` by `num_stages` large. + * @brief The transformed C coefficient matrix. Strictly lower + * triangular and stored in dense row-major form. Upper triangular terms + * are not accessed. Should be `num_stages` by `num_stages` large. * */ std::unique_ptr C_; /** - * @brief OPTIONAL matrix of dense coefficients. Defines how the stages should be transformed into interpolant - * nodes for computing dense output. The interpolating polynomial has an order one less than the order of - * the method, and two interpolant nodes are already pre-computed, so if this matrix exists it should be - * `order` - 2 by `num_stages` large. + * @brief OPTIONAL matrix of dense coefficients. Defines how the stages + * should be transformed into interpolant nodes for computing dense + * output. The interpolating polynomial has an order one less than the + * order of the method, and two interpolant nodes are already + * pre-computed, so if this matrix exists it should be `order` - 2 by + * `num_stages` large. * */ std::unique_ptr H_; /** - * @brief What ODE order these coefficients satisfy. If `is_dae` is true, then the coefficients must additionally satisfy - * DAE conditions up to this order. If `is_w` is true, then the coefficients must additionally satisfy ROW conditions - * up to this order. If `is_krylov` is true, then the coefficients must additionally satisfy ROK condition up to this order. + * @brief What ODE order these coefficients satisfy. If `is_dae` is + * true, then the coefficients must additionally satisfy DAE conditions + * up to this order. If `is_w` is true, then the coefficients must + * additionally satisfy ROW conditions up to this order. If `is_krylov` + * is true, then the coefficients must additionally satisfy ROK + * condition up to this order. * */ uint8_t order_; /** - * @brief Whether or not these coefficients are appropriate to use in a Rosenbrock-Krylov (ROK) solver. + * @brief Whether or not these coefficients are appropriate to use in a + * Rosenbrock-Krylov (ROK) solver. * */ bool is_krylov_; /** - * @brief Whether or not these coefficients satisfy Rosenbrock-W (ROW) order conditions up to `order`. - * The integrator may take advantage of this fact by e.g. using time-delay Jacobians to speed up computation. + * @brief Whether or not these coefficients satisfy Rosenbrock-W (ROW) + * order conditions up to `order`. The integrator may take advantage of + * this fact by e.g. using time-delay Jacobians to speed up computation. * */ bool is_w_; /** - * @brief Whether or not these coefficients satisfy DAE order conditions up to `order`. If this is not true, - * these coefficients should not be used to solve models with algebraic conditions (indicated by a + * @brief Whether or not these coefficients satisfy DAE order conditions + * up to `order`. If this is not true, these coefficients should not be + * used to solve models with algebraic conditions (indicated by a * `Model::Evaluator::tag_` value of 0). * */ bool is_dae_; /** - * @brief Whether or not this tableau contains an embedded error estimator method. + * @brief Whether or not this tableau contains an embedded error + * estimator method. * */ constexpr bool hasEmbedded() const @@ -281,7 +312,8 @@ namespace AnalysisManager } /** - * @brief Whether or not this tableau contains coefficients which can be used to construct dense output. + * @brief Whether or not this tableau contains coefficients which can be + * used to construct dense output. * */ constexpr bool hasDenseOutput() const @@ -308,43 +340,53 @@ namespace AnalysisManager private: /** - * @brief The current step size of the integrator. If integration is ever stopped and resumed, this value will be used for - * the initial step after resuming. + * @brief The current step size of the integrator. If integration is ever + * stopped and resumed, this value will be used for the initial step after + * resuming. * */ RealT step_size_ = 0; /** - * @brief The step size of the previous step. Used for operations which need to be done on the current step, but step size - * control for the next step has already been performed. + * @brief The step size of the previous step. Used for operations which + * need to be done on the current step, but step size control for the next + * step has already been performed. * */ RealT prev_step_size_ = 0; /** - * @brief Whether or not the integrator should attempt to skip Jacobian decomposition on the next step. Controlled by the - * time stepping algorithm in \link integrate() \endlink . Generally, this should only be set if we suspect the Jacobian for the - * last step is a good enough approximation of the Jacobian on the next step. Non-ROW methods need exact Jacobians, - * so this should only be set for ROW methods, and when the step size for the next step is the same as the step size - * as the previous step. + * @brief Whether or not the integrator should attempt to skip Jacobian + * decomposition on the next step. Controlled by the time stepping + * algorithm in \link integrate() \endlink . Generally, this should only + * be set if we suspect the Jacobian for the last step is a good enough + * approximation of the Jacobian on the next step. Non-ROW methods need + * exact Jacobians, so this should only be set for ROW methods, and when + * the step size for the next step is the same as the step size as the + * previous step. * */ bool skip_lu_ = false; /** - * @brief Whether or not the integrator should attempt to skip the residual function evaluation of the first stage on the - * next step. This should only be used when a step is rejected and the residual function is evaluated at the exact - * same arguments as the previous step. Then \ref RHS_first_stage_ can be re-used rather than re-calculated. + * @brief Whether or not the integrator should attempt to skip the + * residual function evaluation of the first stage on the next step. This + * should only be used when a step is rejected and the residual function + * is evaluated at the exact same arguments as the previous step. Then + * \ref RHS_first_stage_ can be re-used rather than re-calculated. * */ bool skip_f_ = false; /** - * @brief Keeps track of whether or not the integrator currently has valid dense coefficients. - * i.e. they have been computed and haven't been invalidated by taking another step. This can be used to avoid - * re-computing dense coefficients when interpolating states multiple times in one step. + * @brief Keeps track of whether or not the integrator currently has valid + * dense coefficients. i.e. they have been computed and haven't been + * invalidated by taking another step. This can be used to avoid + * re-computing dense coefficients when interpolating states + * multiple times in one step. * */ bool dense_coefficients_valid_ = false; /** - * @brief The tableau of Rosenbrock coefficients currently being used by the integrator. + * @brief The tableau of Rosenbrock coefficients currently being used by + * the integrator. * */ Tableau tab_; @@ -354,25 +396,32 @@ namespace AnalysisManager */ GridKit::Model::Evaluator* model_; /** - * @brief The linear solver to be used during integration in \link timeStep() \endlink. + * @brief The linear solver to be used during integration in \link + * timeStep() \endlink. * */ GridKit::LinearAlgebra::LinearSolver& lin_solver_; /** - * @brief The vector handler to be used for vector operations by the integrator. + * @brief The vector handler to be used for vector operations by the + * integrator. * */ GridKit::LinearAlgebra::VectorHandler& vector_handler_; /** - * @brief The `ErrorNorm` to be used by the `StepController` in \link integrate() \endlink. + * @brief The `ErrorNorm` to be used by the `StepController` in \link + * integrate() \endlink. * - * @note Can be `nullptr` if no `ErrorNorm` is configured, in case the `StepController` does not need an error to be calculated. + * @note Can be `nullptr` if no `ErrorNorm` is configured, in case the + * `StepController` does not need an error to be calculated. * - * @todo Should be removed from the `Rosenbrock` class. Whether or not this is needed is dependent on the `StepController`, so it should be stored there. + * @todo Should be removed from the `Rosenbrock` class. Whether or not + * this is needed is dependent on the `StepController`, so it should be + * stored there. */ const ErrorNorm* err_norm_; /** - * @brief The memory space where linear algebra operations should be done in. + * @brief The memory space where linear algebra operations should be done + * in. * */ GridKit::memory::MemorySpace memspace_; @@ -411,7 +460,8 @@ namespace AnalysisManager Parameters params_; /** - * @brief Running statistics of the integrator. Reset by \link initializeSimulation() \endlink. + * @brief Running statistics of the integrator. Reset by \link + * initializeSimulation() \endlink. * */ Stats stats_; @@ -443,13 +493,15 @@ namespace AnalysisManager private: /** - * @brief A workspace used by `time_step` for the necessary linear algebra computations. + * @brief A workspace used by `time_step` for the necessary linear algebra + * computations. * */ mutable struct { /** - * @brief Sum of A-weighted states used for function evaluation in a stage. + * @brief Sum of A-weighted states used for function evaluation in a + * stage. * */ std::unique_ptr asum_; @@ -467,14 +519,16 @@ namespace AnalysisManager * @brief Right-hand side of linear solve used in the first stage. * Stored separately from * \ref Rosenbrock::RHS_ - * since it can be re-used by future steps if the current step is rejected. + * since it can be re-used by future steps if the current step is + * rejected. * * @see `skip_f_` * */ std::unique_ptr RHS_first_stage_; /** - * @brief Time Jacobian for non-autonomous models. Currently unused, since models are assumed to be autonomous. + * @brief Time Jacobian for non-autonomous models. Currently unused, + * since models are assumed to be autonomous. * */ std::unique_ptr dFdt_; @@ -484,7 +538,8 @@ namespace AnalysisManager */ std::unique_ptr mass_; /** - * @brief Estimated error produced by a step in a method with an embedded error estimator. + * @brief Estimated error produced by a step in a method with an + * embedded error estimator. * * @see `Tableau::e` * @@ -492,10 +547,11 @@ namespace AnalysisManager std::unique_ptr err_est_; /** - * @brief Whether or not the Jacobian has been factorized. Initial factorization is required, - * but pivots can be re-used for a refactorization later. Re-factorization can introduce - * errors when the Jacobian differs significantly, so this flag should be reset when - * a significant event can happen, such as re-initializing the simulation. + * @brief Whether or not the Jacobian has been factorized. Initial + * factorization is required, but pivots can be re-used for a + * refactorization later. Re-factorization can introduce errors when the + * Jacobian differs significantly, so this flag should be reset when a + * significant event can happen, such as re-initializing the simulation. * * @see \link initializeSimulation() \endlink * @@ -503,15 +559,16 @@ namespace AnalysisManager bool jacobian_analyzed_ = false; /** - * @brief Integration stages - each a low-order approximation of the state at the abscissae given by - * the tableau. + * @brief Integration stages - each a low-order approximation of the + * state at the abscissae given by the tableau. * */ std::unique_ptr[]> stages_; } workspace_; /** - * @brief Dense output interpolation nodes. Used to generate output states in-between steps. + * @brief Dense output interpolation nodes. Used to generate output states + * in-between steps. * * @see \link calcDenseCoeff() \endlink, \link interpDense() \endlink * diff --git a/GridKit/Solver/Dynamic/RosenbrockTableaus.cpp b/GridKit/Solver/Dynamic/RosenbrockTableaus.cpp index 5c5e1265f6..db43682a83 100644 --- a/GridKit/Solver/Dynamic/RosenbrockTableaus.cpp +++ b/GridKit/Solver/Dynamic/RosenbrockTableaus.cpp @@ -5,7 +5,8 @@ namespace AnalysisManager namespace NativeDynamicSolver { template - Rosenbrock::Tableau Rosenbrock::Tableau::linImplicitEuler() + Rosenbrock::Tableau Rosenbrock::Tableau:: + linImplicitEuler() { constexpr size_t num_stages = 1; @@ -39,12 +40,14 @@ namespace AnalysisManager } /** - * @brief A 5th order Rosenbrock method suitable for solving parabolic PDEs. Created in \cite steinebach2023construction. + * @brief A 5th order Rosenbrock method suitable for solving parabolic PDEs. + * Created in \cite steinebach2023construction. * * */ template - Rosenbrock::Tableau Rosenbrock::Tableau::rodas5p() + Rosenbrock::Tableau Rosenbrock::Tableau:: + rodas5p() { constexpr size_t num_stages = 8; diff --git a/GridKit/Solver/Optimization/DynamicConstraint.cpp b/GridKit/Solver/Optimization/DynamicConstraint.cpp index 1dbee911c5..31598d3ab0 100644 --- a/GridKit/Solver/Optimization/DynamicConstraint.cpp +++ b/GridKit/Solver/Optimization/DynamicConstraint.cpp @@ -32,7 +32,13 @@ namespace AnalysisManager } template - bool DynamicConstraint::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, Index& nnz_h_lag, IndexStyleEnum& index_style) + bool DynamicConstraint::get_nlp_info( + Index& n, + Index& m, + Index& nnz_jac_g, + Index& nnz_h_lag, + IndexStyleEnum& index_style + ) { // This code handles one objective function assert(model_->sizeQuadrature() == 1); @@ -176,11 +182,13 @@ namespace AnalysisManager status = integrator_->runSimulationQuadrature(t_final_, dt_monitor_); if (status) { - ::GridKit::Utilities::Logger::error() << "Integration failed when using Pm = " << x[0] << "\n"; + ::GridKit::Utilities::Logger::error() + << "Integration failed when using Pm = " << x[0] << "\n"; return false; } - // For now assumes only one forward integrand and multiple optimization parameters. + // For now assumes only one forward integrand and multiple optimization + // parameters. g[0] = (integrator_->getIntegral())[0] - x[model_->sizeParams()]; return true; } @@ -230,7 +238,10 @@ namespace AnalysisManager status = integrator_->runForwardSimulation(t_final_, dt_monitor_); if (status) { - ::GridKit::Utilities::Logger::error() << "Forward integration for adjoint solution failed when using Pm = " << x[0] << "\n"; + ::GridKit::Utilities::Logger::error() + << "Forward integration for adjoint solution failed when using Pm " + "= " + << x[0] << "\n"; return false; } @@ -239,11 +250,15 @@ namespace AnalysisManager status = integrator_->runBackwardSimulation(t_init_); if (status) { - ::GridKit::Utilities::Logger::error() << "Backward integration for adjoint solution failed when using Pm = " << x[0] << "\n"; + ::GridKit::Utilities::Logger::error() + << "Backward integration for adjoint solution failed when using Pm " + "= " + << x[0] << "\n"; return false; } - // For now assumes only one forward integrand and multiple optimization parameters. + // For now assumes only one forward integrand and multiple optimization + // parameters. for (IdxT i = 0; i < model_->sizeParams(); ++i) { values[i] = -((integrator_->getAdjointIntegral())[i]); diff --git a/GridKit/Solver/Optimization/DynamicConstraint.hpp b/GridKit/Solver/Optimization/DynamicConstraint.hpp index 1736200727..419c6e8cec 100644 --- a/GridKit/Solver/Optimization/DynamicConstraint.hpp +++ b/GridKit/Solver/Optimization/DynamicConstraint.hpp @@ -25,7 +25,8 @@ namespace AnalysisManager * */ template - class DynamicConstraint : public Ipopt::TNLP, public OptimizationSolver + class DynamicConstraint : public Ipopt::TNLP, + public OptimizationSolver { using OptimizationSolver::integrator_; using OptimizationSolver::model_; @@ -48,28 +49,73 @@ namespace AnalysisManager virtual ~DynamicConstraint(); /// Returns sizes of the model components - virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, Index& nnz_h_lag, IndexStyleEnum& index_style); + virtual bool get_nlp_info( + Index& n, + Index& m, + Index& nnz_jac_g, + Index& nnz_h_lag, + IndexStyleEnum& index_style + ); /// Returns problem bounds - virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u, Index m, Number* g_l, Number* g_u); + virtual bool get_bounds_info( + Index n, Number* x_l, Number* x_u, Index m, Number* g_l, Number* g_u + ); /// Initialize optimization - virtual bool get_starting_point(Index n, bool init_x, Number* x, bool init_z, Number* z_L, Number* z_U, Index m, bool init_lambda, Number* lambda); + virtual bool get_starting_point( + Index n, + bool init_x, + Number* x, + bool init_z, + Number* z_L, + Number* z_U, + Index m, + bool init_lambda, + Number* lambda + ); /// Evaluate objective - virtual bool eval_f(Index n, const Number* x, bool new_x, Number& obj_value); + virtual bool eval_f( + Index n, const Number* x, bool new_x, Number& obj_value + ); /// Evaluate objective gradient - virtual bool eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f); + virtual bool eval_grad_f( + Index n, const Number* x, bool new_x, Number* grad_f + ); /// Evaluate constraint residuals (not used here) - virtual bool eval_g(Index n, const Number* x, bool new_x, Index m, Number* g); + virtual bool eval_g( + Index n, const Number* x, bool new_x, Index m, Number* g + ); /// Evaluate Jacobian (not used here) - virtual bool eval_jac_g(Index n, const Number* x, bool new_x, Index m, Index nele_jac, Index* iRow, Index* jCol, Number* values); + virtual bool eval_jac_g( + Index n, + const Number* x, + bool new_x, + Index m, + Index nele_jac, + Index* iRow, + Index* jCol, + Number* values + ); /// Evaluate Hessian (have Ipopt estimate Hessian) - virtual bool eval_h(Index n, const Number* x, bool new_x, Number obj_factor, Index m, const Number* lambda, bool new_lambda, Index nele_hess, Index* iRow, Index* jCol, Number* values); + virtual bool eval_h( + Index n, + const Number* x, + bool new_x, + Number obj_factor, + Index m, + const Number* lambda, + bool new_lambda, + Index nele_hess, + Index* iRow, + Index* jCol, + Number* values + ); /// Postprocessing of the results (not used here) virtual void finalize_solution( diff --git a/GridKit/Solver/Optimization/DynamicObjective.cpp b/GridKit/Solver/Optimization/DynamicObjective.cpp index 1eca727afe..b1746987a6 100644 --- a/GridKit/Solver/Optimization/DynamicObjective.cpp +++ b/GridKit/Solver/Optimization/DynamicObjective.cpp @@ -30,7 +30,13 @@ namespace AnalysisManager } template - bool DynamicObjective::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, Index& nnz_h_lag, IndexStyleEnum& index_style) + bool DynamicObjective::get_nlp_info( + Index& n, + Index& m, + Index& nnz_jac_g, + Index& nnz_h_lag, + IndexStyleEnum& index_style + ) { // This code handles one objective function assert(model_->sizeQuadrature() == 1); @@ -159,7 +165,8 @@ namespace AnalysisManager integrator_->initializeBackwardSimulation(t_final_); integrator_->runBackwardSimulation(t_init_); - // For now assumes only one forward integrand and multiple optimization parameters. + // For now assumes only one forward integrand and multiple optimization + // parameters. for (IdxT i = 0; i < model_->sizeParams(); ++i) grad_f[i] = -((integrator_->getAdjointIntegral())[i]); diff --git a/GridKit/Solver/Optimization/DynamicObjective.hpp b/GridKit/Solver/Optimization/DynamicObjective.hpp index 1dd0939b1f..80cfd0bf0e 100644 --- a/GridKit/Solver/Optimization/DynamicObjective.hpp +++ b/GridKit/Solver/Optimization/DynamicObjective.hpp @@ -21,7 +21,8 @@ namespace AnalysisManager * */ template - class DynamicObjective : public Ipopt::TNLP, public OptimizationSolver + class DynamicObjective : public Ipopt::TNLP, + public OptimizationSolver { using OptimizationSolver::integrator_; using OptimizationSolver::model_; @@ -44,28 +45,73 @@ namespace AnalysisManager virtual ~DynamicObjective(); /// Returns sizes of the model components - virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, Index& nnz_h_lag, IndexStyleEnum& index_style); + virtual bool get_nlp_info( + Index& n, + Index& m, + Index& nnz_jac_g, + Index& nnz_h_lag, + IndexStyleEnum& index_style + ); /// Returns problem bounds - virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u, Index m, Number* g_l, Number* g_u); + virtual bool get_bounds_info( + Index n, Number* x_l, Number* x_u, Index m, Number* g_l, Number* g_u + ); /// Initialize optimization - virtual bool get_starting_point(Index n, bool init_x, Number* x, bool init_z, Number* z_L, Number* z_U, Index m, bool init_lambda, Number* lambda); + virtual bool get_starting_point( + Index n, + bool init_x, + Number* x, + bool init_z, + Number* z_L, + Number* z_U, + Index m, + bool init_lambda, + Number* lambda + ); /// Evaluate objective - virtual bool eval_f(Index n, const Number* x, bool new_x, Number& obj_value); + virtual bool eval_f( + Index n, const Number* x, bool new_x, Number& obj_value + ); /// Evaluate objective gradient - virtual bool eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f); + virtual bool eval_grad_f( + Index n, const Number* x, bool new_x, Number* grad_f + ); /// Evaluate constraint residuals (not used here) - virtual bool eval_g(Index n, const Number* x, bool new_x, Index m, Number* g); + virtual bool eval_g( + Index n, const Number* x, bool new_x, Index m, Number* g + ); /// Evaluate Jacobian (not used here) - virtual bool eval_jac_g(Index n, const Number* x, bool new_x, Index m, Index nele_jac, Index* iRow, Index* jCol, Number* values); + virtual bool eval_jac_g( + Index n, + const Number* x, + bool new_x, + Index m, + Index nele_jac, + Index* iRow, + Index* jCol, + Number* values + ); /// Evaluate Hessian (have Ipopt estimate Hessian) - virtual bool eval_h(Index n, const Number* x, bool new_x, Number obj_factor, Index m, const Number* lambda, bool new_lambda, Index nele_hess, Index* iRow, Index* jCol, Number* values); + virtual bool eval_h( + Index n, + const Number* x, + bool new_x, + Number obj_factor, + Index m, + const Number* lambda, + bool new_lambda, + Index nele_hess, + Index* iRow, + Index* jCol, + Number* values + ); /// Postprocessing of the results (not used here) virtual void finalize_solution( diff --git a/GridKit/Solver/Optimization/IpoptInterface.cpp b/GridKit/Solver/Optimization/IpoptInterface.cpp index f30b6be695..e3cf5358ed 100644 --- a/GridKit/Solver/Optimization/IpoptInterface.cpp +++ b/GridKit/Solver/Optimization/IpoptInterface.cpp @@ -28,9 +28,11 @@ namespace AnalysisManager IndexStyleEnum& index_style ) { - if (model_->getCsrJacobian() == nullptr || model_->getCsrHessian() == nullptr) + if (model_->getCsrJacobian() == nullptr + || model_->getCsrHessian() == nullptr) { - GridKit::Utilities::Logger::error() << "IpoptInterface: allocate() the model before solving it\n"; + GridKit::Utilities::Logger::error() + << "IpoptInterface: allocate() the model before solving it\n"; return false; } @@ -230,14 +232,18 @@ namespace AnalysisManager template template - void IpoptInterface::copyInto(VectorT& vector, const ipnumber* values) + void IpoptInterface::copyInto( + VectorT& vector, const ipnumber* values + ) { std::copy_n(values, vector.getSize(), vector.getData()); vector.setDataUpdated(); } template - void IpoptInterface::structure(CsrMatrixT& matrix, ipindex* iRow, ipindex* jCol) + void IpoptInterface::structure( + CsrMatrixT& matrix, ipindex* iRow, ipindex* jCol + ) { const IdxT* row_ptrs = matrix.getRowData(); const IdxT* cols = matrix.getColData(); diff --git a/GridKit/Solver/Optimization/IpoptInterface.hpp b/GridKit/Solver/Optimization/IpoptInterface.hpp index 8f6bce52ef..241b283928 100644 --- a/GridKit/Solver/Optimization/IpoptInterface.hpp +++ b/GridKit/Solver/Optimization/IpoptInterface.hpp @@ -43,10 +43,23 @@ namespace AnalysisManager explicit IpoptInterface(ModelT* model); /// Sizes and nonzero counts, with C-style indices - bool get_nlp_info(ipindex& n, ipindex& m, ipindex& nnz_jac_g, ipindex& nnz_h_lag, IndexStyleEnum& index_style) override; + bool get_nlp_info( + ipindex& n, + ipindex& m, + ipindex& nnz_jac_g, + ipindex& nnz_h_lag, + IndexStyleEnum& index_style + ) override; /// Variable and constraint bounds - bool get_bounds_info(ipindex n, ipnumber* x_l, ipnumber* x_u, ipindex m, ipnumber* g_l, ipnumber* g_u) override; + bool get_bounds_info( + ipindex n, + ipnumber* x_l, + ipnumber* x_u, + ipindex m, + ipnumber* g_l, + ipnumber* g_u + ) override; /// Variables from `x()`, without initial multipliers bool get_starting_point( @@ -62,13 +75,18 @@ namespace AnalysisManager ) override; /// Objective \f$f(x)\f$ - bool eval_f(ipindex n, const ipnumber* x, bool new_x, ipnumber& obj_value) override; + bool eval_f(ipindex n, const ipnumber* x, bool new_x, ipnumber& obj_value) + override; /// Objective gradient \f$\nabla f(x)\f$ - bool eval_grad_f(ipindex n, const ipnumber* x, bool new_x, ipnumber* grad_f) override; + bool eval_grad_f( + ipindex n, const ipnumber* x, bool new_x, ipnumber* grad_f + ) override; /// Constraints \f$g(x)\f$ - bool eval_g(ipindex n, const ipnumber* x, bool new_x, ipindex m, ipnumber* g) override; + bool eval_g( + ipindex n, const ipnumber* x, bool new_x, ipindex m, ipnumber* g + ) override; /// Constraint Jacobian, or its structure when `values` is null bool eval_jac_g( @@ -97,7 +115,8 @@ namespace AnalysisManager ipnumber* values ) override; - /// Leave the final point, its multipliers, its objective, and its constraints in the model + /// Leave the final point, its multipliers, its objective, and its + /// constraints in the model void finalize_solution( SolverReturn status, ipindex n, diff --git a/GridKit/Solver/SteadyState/Kinsol.cpp b/GridKit/Solver/SteadyState/Kinsol.cpp index 9b57f2c110..48f03f69fe 100644 --- a/GridKit/Solver/SteadyState/Kinsol.cpp +++ b/GridKit/Solver/SteadyState/Kinsol.cpp @@ -28,7 +28,9 @@ namespace AnalysisManager namespace Sundials { template - Kinsol::Kinsol(GridKit::Model::Evaluator* model) + Kinsol::Kinsol( + GridKit::Model::Evaluator* model + ) : Kinsol(model->size()) { model_ = model; @@ -215,7 +217,9 @@ namespace AnalysisManager } template - int Kinsol::Residual(N_Vector yy, N_Vector rr, void* user_data) + int Kinsol::Residual( + N_Vector yy, N_Vector rr, void* user_data + ) { auto& self = *static_cast(user_data); try @@ -283,7 +287,9 @@ namespace AnalysisManager } template - void Kinsol::checkAllocation(SUNContext c, void* v, const char* functionName) + void Kinsol::checkAllocation( + SUNContext c, void* v, const char* functionName + ) { if (v == NULL) { @@ -297,7 +303,9 @@ namespace AnalysisManager } template - void Kinsol::checkOutput(int retval, const char* functionName) + void Kinsol::checkOutput( + int retval, const char* functionName + ) { if (retval < 0) { @@ -315,7 +323,9 @@ namespace AnalysisManager } template - void Kinsol::setTolerance(ScalarT residual_tol, ScalarT step_tol) + void Kinsol::setTolerance( + ScalarT residual_tol, ScalarT step_tol + ) { int retval = KINSetFuncNormTol(solver_, residual_tol); checkOutput(retval, "KINSetFuncNormTol"); diff --git a/GridKit/Solver/SteadyState/Kinsol.hpp b/GridKit/Solver/SteadyState/Kinsol.hpp index aafad99a77..73a330e438 100644 --- a/GridKit/Solver/SteadyState/Kinsol.hpp +++ b/GridKit/Solver/SteadyState/Kinsol.hpp @@ -189,7 +189,9 @@ namespace AnalysisManager static void copyVec(const std::vector& x, N_Vector y); // int check_flag(void *flagvalue, const char *funcname, int opt); - static inline void checkAllocation(SUNContext ctx, void* v, const char* functionName); + static inline void checkAllocation( + SUNContext ctx, void* v, const char* functionName + ); static inline void checkOutput(int retval, const char* functionName); }; diff --git a/GridKit/Testing/AggregateErrors.hpp b/GridKit/Testing/AggregateErrors.hpp index 753121391f..f0411f3946 100644 --- a/GridKit/Testing/AggregateErrors.hpp +++ b/GridKit/Testing/AggregateErrors.hpp @@ -78,8 +78,8 @@ namespace GridKit << indent << indent << "max : " << std::format("{:.6e} (at time {:.3e})", max_value, max_value_time) << '\n' - << indent << indent << "L2-norm : " - << std::format("{:.6e}", L2) << '\n'; + << indent << indent << "L2-norm : " << std::format("{:.6e}", L2) + << '\n'; return os; } }; @@ -102,8 +102,7 @@ namespace GridKit * @brief Construct with variable labels */ template - explicit ErrorSet(const C& labels) - : var_errors(std::size(labels)) + explicit ErrorSet(const C& labels) : var_errors(std::size(labels)) { for (std::size_t i = 0; i < std::size(labels); ++i) { @@ -230,7 +229,9 @@ namespace GridKit switch (type) { case ErrorType::RELATIVE: - return std::make_unique>(labels, abs_threshold); + return std::make_unique>( + labels, abs_threshold + ); case ErrorType::ABSOLUTE: return std::make_unique>(labels); default: diff --git a/GridKit/Testing/CSV.cpp b/GridKit/Testing/CSV.cpp index 1ef38265db..c776a07c80 100644 --- a/GridKit/Testing/CSV.cpp +++ b/GridKit/Testing/CSV.cpp @@ -28,8 +28,8 @@ namespace GridKit std::ifstream ifs(f); if (!ifs) { - Log::error() << "\n\tCould not open file \"" << f - << "\" for input." << std::endl; + Log::error() << "\n\tCould not open file \"" << f << "\" for input." + << std::endl; throw std::runtime_error("Failed to open file"); } return ifs; diff --git a/GridKit/Testing/CommandLine.hpp b/GridKit/Testing/CommandLine.hpp index e8b57e30e1..9d2c023950 100644 --- a/GridKit/Testing/CommandLine.hpp +++ b/GridKit/Testing/CommandLine.hpp @@ -16,8 +16,7 @@ namespace GridKit { CommandLine() = default; - CommandLine(const std::array& args) - : args_(args) + CommandLine(const std::array& args) : args_(args) { for (std::size_t i = 0; i < static_cast(argc); ++i) { diff --git a/GridKit/Testing/OutputAtTime.hpp b/GridKit/Testing/OutputAtTime.hpp index 23634daa8a..a9a26f3a35 100644 --- a/GridKit/Testing/OutputAtTime.hpp +++ b/GridKit/Testing/OutputAtTime.hpp @@ -21,20 +21,20 @@ namespace GridKit double t; std::vector data; - OutputAtTime(const std::vector& v) - : t{v[0]} + OutputAtTime(const std::vector& v) : t{v[0]} { std::copy(next(begin(v)), end(v), std::back_inserter(data)); } template - OutputAtTime(double t, TArgs&&... args) - : t{t}, data{args...} + OutputAtTime(double t, TArgs&&... args) : t{t}, data{args...} { } private: - friend OutputAtTime operator-(const OutputAtTime& a, const OutputAtTime& b) + friend OutputAtTime operator-( + const OutputAtTime& a, const OutputAtTime& b + ) { assert(GridKit::Testing::isEqual(a.t, b.t, 1.0e-6)); assert(a.data.size() == b.data.size()); diff --git a/GridKit/Testing/Testing.cpp b/GridKit/Testing/Testing.cpp index cad1c05a6c..2250d19d65 100644 --- a/GridKit/Testing/Testing.cpp +++ b/GridKit/Testing/Testing.cpp @@ -9,8 +9,7 @@ namespace GridKit namespace Testing { - TestStatus::TestStatus() - : outcome_(TestOutcome::PASS) + TestStatus::TestStatus() : outcome_(TestOutcome::PASS) { } @@ -20,8 +19,7 @@ namespace GridKit } TestStatus::TestStatus(const char* funcname) - : outcome_(TestOutcome::PASS), - funcname_(funcname) + : outcome_(TestOutcome::PASS), funcname_(funcname) { } @@ -46,31 +44,29 @@ namespace GridKit switch (outcome_) { case PASS: - std::cout << "--- " << GREEN << "PASS" << CLEAR - << ": Test " << funcname << "\n"; + std::cout << "--- " << GREEN << "PASS" << CLEAR << ": Test " << funcname + << "\n"; break; case FAIL: - std::cout << "--- " << RED << "FAIL" << CLEAR - << ": Test " << funcname << "\n"; + std::cout << "--- " << RED << "FAIL" << CLEAR << ": Test " << funcname + << "\n"; break; case SKIP: - std::cout << "--- " << YELLOW << "SKIP" << CLEAR - << ": Test " << funcname << CLEAR << "\n"; + std::cout << "--- " << YELLOW << "SKIP" << CLEAR << ": Test " + << funcname << CLEAR << "\n"; break; case EXPECTED_FAIL: - std::cout << "--- " << ORANGE << "FAIL" << CLEAR - << " (EXPECTED)" + std::cout << "--- " << ORANGE << "FAIL" << CLEAR << " (EXPECTED)" << ": Test " << funcname << "\n"; break; case UNEXPECTED_PASS: - std::cout << "--- " << BLUE << "PASS" << CLEAR - << " (UNEXPECTED)" + std::cout << "--- " << BLUE << "PASS" << CLEAR << " (UNEXPECTED)" << ": Test " << funcname << "\n"; break; default: std::cout << "--- " << RED << "FAIL" << CLEAR - << "Unrecognized test result " << outcome_ - << " for test " << funcname << "\n"; + << "Unrecognized test result " << outcome_ << " for test " + << funcname << "\n"; } return outcome_; } @@ -132,8 +128,8 @@ namespace GridKit this->unexpected_success++; break; default: - std::cout << "Warning: Unrecognized test outcome code " - << outcome << ". Assuming failure ...\n"; + std::cout << "Warning: Unrecognized test outcome code " << outcome + << ". Assuming failure ...\n"; this->failure++; } return *this; diff --git a/GridKit/Testing/Testing.hpp b/GridKit/Testing/Testing.hpp index f0534a797c..da4b38ff30 100644 --- a/GridKit/Testing/Testing.hpp +++ b/GridKit/Testing/Testing.hpp @@ -112,17 +112,23 @@ namespace GridKit int summary(); }; - inline TestingResults operator+(const TestingResults& lhs, const TestingResults& rhs) + inline TestingResults operator+( + const TestingResults& lhs, const TestingResults& rhs + ) { return TestingResults(lhs) += rhs; } - inline TestingResults operator+(const TestingResults& lhs, const TestOutcome outcome) + inline TestingResults operator+( + const TestingResults& lhs, const TestOutcome outcome + ) { return TestingResults(lhs) += outcome; } - inline TestingResults operator+(const TestOutcome outcome, const TestingResults& rhs) + inline TestingResults operator+( + const TestOutcome outcome, const TestingResults& rhs + ) { return TestingResults(rhs) += outcome; } @@ -139,7 +145,8 @@ namespace GridKit } /** - * @brief Equality comparison between maps with a tolerance for the scalar value + * @brief Equality comparison between maps with a tolerance for the scalar + * value * * @tparam IdxT - Integer data type * @tparam RealT - Real type @@ -176,8 +183,10 @@ namespace GridKit fail++; std::cerr << "Mismatching map values! " << "a.first = " << pair_a.first << ", " - << "a.second = " << std::setprecision(16) << pair_a.second << ", and " - << "b.second = " << std::setprecision(16) << it->second << "\n"; + << "a.second = " << std::setprecision(16) << pair_a.second + << ", and " + << "b.second = " << std::setprecision(16) << it->second + << "\n"; } } else @@ -231,12 +240,10 @@ namespace GridKit } // namespace Detail template - inline bool - throws(TFunc func, TArgs&&... args) + inline bool throws(TFunc func, TArgs&&... args) { - return Detail::ThrowsHelper{}( - [&]() { func(std::forward(args)...); } - ); + return Detail::ThrowsHelper{ + }([&]() { func(std::forward(args)...); }); } /// True when building a model throws `std::invalid_argument` or the @@ -245,8 +252,8 @@ namespace GridKit inline bool configurationRejected(BuildT build) { bool passed = false; - const bool threw = throws([&]() - { passed = build().passed(); }); + const bool threw = + throws([&]() { passed = build().passed(); }); return threw || !passed; } diff --git a/GridKit/Utilities/CliArgs/ArgValue.hpp b/GridKit/Utilities/CliArgs/ArgValue.hpp index 532d16cdb4..a437816469 100644 --- a/GridKit/Utilities/CliArgs/ArgValue.hpp +++ b/GridKit/Utilities/CliArgs/ArgValue.hpp @@ -44,7 +44,8 @@ namespace GridKit * @brief Check that T is not an ArgValue or list of ArgValues */ template - static constexpr bool notArgValue = notAnArgValue && notAnArgValueList; + static constexpr bool notArgValue = + notAnArgValue && notAnArgValueList; public: /** diff --git a/GridKit/Utilities/CliArgs/ArgVector.hpp b/GridKit/Utilities/CliArgs/ArgVector.hpp index 928ba415f7..2758756e74 100644 --- a/GridKit/Utilities/CliArgs/ArgVector.hpp +++ b/GridKit/Utilities/CliArgs/ArgVector.hpp @@ -50,13 +50,11 @@ namespace GridKit * @brief Construct with a single value */ template - ArgVector(T&& val) - : vec_{val} + ArgVector(T&& val) : vec_{val} { } - ArgVector(std::initializer_list vals) - : vec_{vals} + ArgVector(std::initializer_list vals) : vec_{vals} { } diff --git a/GridKit/Utilities/CliArgs/CliArgsImpl.hpp b/GridKit/Utilities/CliArgs/CliArgsImpl.hpp index 9802fa9509..54ab2adbcb 100644 --- a/GridKit/Utilities/CliArgs/CliArgsImpl.hpp +++ b/GridKit/Utilities/CliArgs/CliArgsImpl.hpp @@ -14,8 +14,7 @@ namespace GridKit { /// Construct an @ref OptionArgumentPair with a specification and an empty /// set of values. - explicit OptionArgumentPair(Option opt) - : option(std::move(opt)) + explicit OptionArgumentPair(Option opt) : option(std::move(opt)) { } @@ -138,8 +137,7 @@ namespace GridKit } for (auto&& [key, arg] : args.name_map_) { - os << key << " =>\n" - << *arg << "\n\n"; + os << key << " =>\n" << *arg << "\n\n"; } return os; } @@ -217,19 +215,16 @@ namespace GridKit // add "help" entry on behalf of the user if (!name_map_.count("help") && !name_map_.count("h")) { - auto& help = table_.emplace_back( - Option{ - .name = {"--help", "-h"}, - .help = "Print this help message", - .flag = true - } - ); + auto& help = table_.emplace_back(Option{ + .name = {"--help", "-h"}, + .help = "Print this help message", + .flag = true + }); setupArg(help); } } - const OptionArgumentPair* CliArgsImpl::findByName( - const std::string& name + const OptionArgumentPair* CliArgsImpl::findByName(const std::string& name ) const { auto ret = name_map_.find(name); @@ -282,9 +277,8 @@ namespace GridKit auto* arg = findByRawName(token); if (!arg || arg->option.positional) { - Log::error() << std::format( - "CliArgs: unrecognized option \"{}\"\n", token - ); + Log::error( + ) << std::format("CliArgs: unrecognized option \"{}\"\n", token); status = false; continue; } @@ -334,9 +328,8 @@ namespace GridKit } if (positional == positionals_.size()) { - Log::error() << std::format( - "CliArgs: unexpected argument \"{}\"\n", token - ); + Log::error( + ) << std::format("CliArgs: unexpected argument \"{}\"\n", token); status = false; } else diff --git a/GridKit/Utilities/MapFromCsr.hpp b/GridKit/Utilities/MapFromCsr.hpp index 6a4028f32f..bf340f3bc6 100644 --- a/GridKit/Utilities/MapFromCsr.hpp +++ b/GridKit/Utilities/MapFromCsr.hpp @@ -16,14 +16,18 @@ namespace GridKit namespace Testing { template - std::vector MapFromCsr(LinearAlgebra::CsrMatrix* matrix) + std::vector MapFromCsr( + LinearAlgebra::CsrMatrix* matrix + ) { IdxT* row_data = matrix->getRowData(); IdxT* column_data = matrix->getColData(); RealT* values = matrix->getValues(); IdxT n_rows = matrix->getNumRows(); - std::vector dependencies(n_rows); + std::vector dependencies( + n_rows + ); for (IdxT i = 0; i < n_rows; ++i) { diff --git a/GridKit/Utilities/String.hpp b/GridKit/Utilities/String.hpp index 82ad298b30..8f36b33c78 100644 --- a/GridKit/Utilities/String.hpp +++ b/GridKit/Utilities/String.hpp @@ -10,14 +10,13 @@ namespace GridKit { namespace Utilities { - /// Whether an identifier contains only ASCII letters, digits, spaces, '_', '.' and '-'. + /// Whether an identifier contains only ASCII letters, digits, spaces, '_', + /// '.' and '-'. inline bool isValidIdentifier(std::string_view id) { - return id.find_first_not_of( - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789 _.-" - ) + return id.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789 _.-") == std::string_view::npos; } @@ -26,17 +25,22 @@ namespace GridKit */ inline std::string toUpper(std::string str) { - std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) - { return std::toupper(c); }); + std::transform( + str.begin(), + str.end(), + str.begin(), + [](unsigned char c) { return std::toupper(c); } + ); return str; } inline std::string strip(std::string str) { - auto notspace = [](char c) - { return !std::isspace(c); }; + auto notspace = [](char c) { return !std::isspace(c); }; str.erase(begin(str), std::find_if(begin(str), end(str), notspace)); - str.erase(std::find_if(rbegin(str), rend(str), notspace).base(), end(str)); + str.erase( + std::find_if(rbegin(str), rend(str), notspace).base(), end(str) + ); return str; } diff --git a/application/PhasorDynamics/AnalysisUtilities.hpp b/application/PhasorDynamics/AnalysisUtilities.hpp index 1ea3855e19..6d982338ff 100644 --- a/application/PhasorDynamics/AnalysisUtilities.hpp +++ b/application/PhasorDynamics/AnalysisUtilities.hpp @@ -199,8 +199,9 @@ namespace GridKit using OutputLayout = ::GridKit::Model::VariableMonitorLayout; if (j.contains("output_layout")) { - auto layout_str = j.at("output_layout").get(); - auto layout_wrap = enum_cast(layout_str, case_insensitive); + auto layout_str = j.at("output_layout").get(); + auto layout_wrap = + enum_cast(layout_str, case_insensitive); if (!layout_wrap.has_value()) { Log::error() << "Invalid output layout \"" << layout_str << "\"; " @@ -295,9 +296,12 @@ namespace GridKit } // TODO: Support reference comparison for the long layout - if (data.output_layout == ::GridKit::Model::VariableMonitorLayout::LONG && !data.reference_file.empty()) + if (data.output_layout == ::GridKit::Model::VariableMonitorLayout::LONG + && !data.reference_file.empty()) { - throw std::invalid_argument("reference_file is not supported with the long output_layout"); + throw std::invalid_argument( + "reference_file is not supported with the long output_layout" + ); } auto csv = ::GridKit::Model::VariableMonitorFormat::CSV; @@ -306,7 +310,8 @@ namespace GridKit // Find output file (CSV) specified in model input file for (const auto& sink : data.model_data.monitor_sink) { - if (sink.format == csv && sink.delim == "," && sink.layout == data.output_layout) + if (sink.format == csv && sink.delim == "," + && sink.layout == data.output_layout) { model_output_file = sink.file_name; } @@ -317,7 +322,9 @@ namespace GridKit if (!data.output_file.empty()) { // Add study output file to model if one did not already exist - data.model_data.monitor_sink.emplace_back(csv, data.output_file, ",", data.output_layout); + data.model_data.monitor_sink.emplace_back( + csv, data.output_file, ",", data.output_layout + ); } } else diff --git a/application/PhasorDynamics/CoupledClient.hpp b/application/PhasorDynamics/CoupledClient.hpp index 912619602c..8f2dc8ba95 100644 --- a/application/PhasorDynamics/CoupledClient.hpp +++ b/application/PhasorDynamics/CoupledClient.hpp @@ -242,12 +242,10 @@ namespace GridKit evaluate(values, residual); if (!converged()) { - throw std::runtime_error( - std::format( - "co-simulation interface did not converge at t={}", - simulation_->time() - ) - ); + throw std::runtime_error(std::format( + "co-simulation interface did not converge at t={}", + simulation_->time() + )); } } } diff --git a/examples/Experimental/AdjointSensitivity/AdjointSensitivity.cpp b/examples/Experimental/AdjointSensitivity/AdjointSensitivity.cpp index 9b6a6e6d32..8f9bd9aedd 100644 --- a/examples/Experimental/AdjointSensitivity/AdjointSensitivity.cpp +++ b/examples/Experimental/AdjointSensitivity/AdjointSensitivity.cpp @@ -29,7 +29,8 @@ int main() BaseBus* bus = new BusSlack(1.0, 0.0); // Attach a generator to that bus - Generator4* gen = new Generator4(bus, 0.8, 0.3); + Generator4* gen = + new Generator4(bus, 0.8, 0.3); // Create a system model SystemModel* model = new SystemModel(); diff --git a/examples/Experimental/DynamicConstrainedOpt/DynamicConstrainedOpt.cpp b/examples/Experimental/DynamicConstrainedOpt/DynamicConstrainedOpt.cpp index 6abdda4b6b..cc4520470c 100644 --- a/examples/Experimental/DynamicConstrainedOpt/DynamicConstrainedOpt.cpp +++ b/examples/Experimental/DynamicConstrainedOpt/DynamicConstrainedOpt.cpp @@ -86,7 +86,9 @@ int main() const double tol = 1e-4; // Configure Ipopt application - ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); + ipoptApp->Options()->SetStringValue( + "hessian_approximation", "limited-memory" + ); ipoptApp->Options()->SetNumericValue("tol", tol); ipoptApp->Options()->SetIntegerValue("print_level", 0); @@ -134,7 +136,8 @@ int main() // Solve the problem status = ipoptApp->OptimizeTNLP(ipoptDynamicConstraintInterface); - std::cout << "\n\nProblem formulated as dynamic constraint optimization ...\n"; + std::cout + << "\n\nProblem formulated as dynamic constraint optimization ...\n"; if (status == Ipopt::Solve_Succeeded) { diff --git a/examples/Experimental/GenConstLoad/GenConstLoad.cpp b/examples/Experimental/GenConstLoad/GenConstLoad.cpp index 7ea3d57443..b75a62e35f 100644 --- a/examples/Experimental/GenConstLoad/GenConstLoad.cpp +++ b/examples/Experimental/GenConstLoad/GenConstLoad.cpp @@ -25,10 +25,12 @@ int main() BaseBus* bus = new BusPQ(1.0, 0.0); // Attach a generator to the bus and signal ports - ModelEvaluatorImpl* gen = new Generator4Governor(bus, 0.8, 0.3); + ModelEvaluatorImpl* gen = + new Generator4Governor(bus, 0.8, 0.3); // Attach load to the bus - ModelEvaluatorImpl* load = new Load(bus, 0.8, 0.3); + ModelEvaluatorImpl* load = + new Load(bus, 0.8, 0.3); // Create system model SystemModel* model = new SystemModel(); @@ -80,7 +82,9 @@ int main() const double tol = 1e-4; // Configure Ipopt application - ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); + ipoptApp->Options()->SetStringValue( + "hessian_approximation", "limited-memory" + ); ipoptApp->Options()->SetNumericValue("tol", tol); ipoptApp->Options()->SetIntegerValue("print_level", 5); @@ -104,12 +108,9 @@ int main() { // Print result std::cout << "\nSuccess: The problem solved in " - << ipoptApp->Statistics()->IterationCount() - << " iterations!\n"; - std::cout << "Optimal value: T2 = " - << param[0] - << ", K = " - << param[1] << "\n"; + << ipoptApp->Statistics()->IterationCount() << " iterations!\n"; + std::cout << "Optimal value: T2 = " << param[0] << ", K = " << param[1] + << "\n"; std::cout << "The final value of the objective function G(T2,K) = " << ipoptApp->Statistics()->FinalObjective() << "\n\n"; } diff --git a/examples/Experimental/GenInfiniteBus/GenInfiniteBus.cpp b/examples/Experimental/GenInfiniteBus/GenInfiniteBus.cpp index 0caeef5d28..9eaf0bf82a 100644 --- a/examples/Experimental/GenInfiniteBus/GenInfiniteBus.cpp +++ b/examples/Experimental/GenInfiniteBus/GenInfiniteBus.cpp @@ -82,7 +82,9 @@ int main() const double tol = 1e-4; // Configure Ipopt application - ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); + ipoptApp->Options()->SetStringValue( + "hessian_approximation", "limited-memory" + ); ipoptApp->Options()->SetNumericValue("tol", tol); ipoptApp->Options()->SetIntegerValue("print_level", 0); ipoptApp->Options()->SetIntegerValue("mumps_print_level", 0); @@ -143,7 +145,8 @@ int main() // Solve the problem status = ipoptApp->OptimizeTNLP(ipoptDynamicConstraintInterface); - std::cout << "\n\nProblem formulated as dynamic constraint optimization ...\n"; + std::cout + << "\n\nProblem formulated as dynamic constraint optimization ...\n"; if (status == Ipopt::Solve_Succeeded) { diff --git a/examples/Experimental/ParameterEstimation/ParameterEstimation.cpp b/examples/Experimental/ParameterEstimation/ParameterEstimation.cpp index b7b2ca2fb7..886f8d0a3c 100644 --- a/examples/Experimental/ParameterEstimation/ParameterEstimation.cpp +++ b/examples/Experimental/ParameterEstimation/ParameterEstimation.cpp @@ -101,7 +101,9 @@ int main() } // Configure Ipopt application - ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); + ipoptApp->Options()->SetStringValue( + "hessian_approximation", "limited-memory" + ); ipoptApp->Options()->SetNumericValue("tol", tol); ipoptApp->Options()->SetIntegerValue("print_level", 0); @@ -143,7 +145,8 @@ int main() // Solve the problem status = ipoptApp->OptimizeTNLP(ipoptDynamicConstraintInterface); - std::cout << "\n\nProblem formulated as dynamic constraint optimization ...\n"; + std::cout + << "\n\nProblem formulated as dynamic constraint optimization ...\n"; if (status == Ipopt::Solve_Succeeded) { diff --git a/examples/OptimalPowerFlow/EconomicDispatch/EconomicDispatch.cpp b/examples/OptimalPowerFlow/EconomicDispatch/EconomicDispatch.cpp index 8ef669f44d..8d729b134f 100644 --- a/examples/OptimalPowerFlow/EconomicDispatch/EconomicDispatch.cpp +++ b/examples/OptimalPowerFlow/EconomicDispatch/EconomicDispatch.cpp @@ -40,7 +40,9 @@ int runApplication(int argc, const char* argv[]) }; args.parseArgs(argc, argv); - OPF::SystemModel model(OPF::parseSystemModelData(args["case-file"]())); + OPF::SystemModel model( + OPF::parseSystemModelData(args["case-file"]()) + ); if (model.allocate() != 0 || model.initialize() != 0) { return 1; @@ -48,7 +50,9 @@ int runApplication(int argc, const char* argv[]) // Exact sparse Jacobians and Hessians come from the model Ipopt::SmartPtr app = IpoptApplicationFactory(); - if (!app->Options()->SetNumericValue("tol", args["solver-tolerance"].as())) + if (!app->Options()->SetNumericValue( + "tol", args["solver-tolerance"].as() + )) { return 1; } @@ -57,7 +61,8 @@ int runApplication(int argc, const char* argv[]) return 1; } - Ipopt::SmartPtr problem = new AnalysisManager::SteadyState::IpoptInterface(&model); + Ipopt::SmartPtr problem = + new AnalysisManager::SteadyState::IpoptInterface(&model); if (app->OptimizeTNLP(problem) != Ipopt::Solve_Succeeded) { Log::error() << "Ipopt did not find an optimal solution\n"; @@ -74,7 +79,11 @@ int runApplication(int argc, const char* argv[]) const double error = std::abs(cost - reference) / std::abs(reference); if (error > args["tolerance"].as()) { - Log::error() << std::format("Optimal cost differs from the reference {} $/h by {:.1e}\n", reference, error); + Log::error() << std::format( + "Optimal cost differs from the reference {} $/h by {:.1e}\n", + reference, + error + ); return 1; } } diff --git a/examples/PowerElectronics/DistributedGeneratorTest/DGTest.cpp b/examples/PowerElectronics/DistributedGeneratorTest/DGTest.cpp index 6fbcaf9a48..90bfa0eb10 100644 --- a/examples/PowerElectronics/DistributedGeneratorTest/DGTest.cpp +++ b/examples/PowerElectronics/DistributedGeneratorTest/DGTest.cpp @@ -22,7 +22,8 @@ int main(int /* argc */, char const** /* argv */) { - GridKit::PowerElectronics::DistributedGeneratorParameters parms; + GridKit::PowerElectronics::DistributedGeneratorParameters + parms; // Parameters from MATLAB Microgrid code for first DG parms.wb_ = 2.0 * std::numbers::pi_v * 50.0; parms.wc_ = 31.41; @@ -46,7 +47,9 @@ int main(int /* argc */, char const** /* argv */) using Bus = GridKit::PowerElectronics::MicrogridBus; Bus bus; - GridKit::PowerElectronics::DistributedGenerator dg(0, parms, false, &dg_signal, &bus); + GridKit::PowerElectronics::DistributedGenerator dg( + 0, parms, false, &dg_signal, &bus + ); std::vector t1(16, 0.0); std::vector t2{ diff --git a/examples/PowerElectronics/ExamplesHelper/MicrogridNetwork.hpp b/examples/PowerElectronics/ExamplesHelper/MicrogridNetwork.hpp index 6d840d0721..1bfdc16eb1 100644 --- a/examples/PowerElectronics/ExamplesHelper/MicrogridNetwork.hpp +++ b/examples/PowerElectronics/ExamplesHelper/MicrogridNetwork.hpp @@ -25,13 +25,15 @@ template struct ScaleMicrogridNetwork { - using SignalNode = GridKit::PowerElectronics::SignalNode; - using Bus = GridKit::PowerElectronics::MicrogridBus; - using BusDQ = GridKit::PowerElectronics::MicrogridBusDQ; - using DGGenerator = GridKit::PowerElectronics::DistributedGenerator; - using Line = GridKit::PowerElectronics::MicrogridLine; - using Load = GridKit::PowerElectronics::MicrogridLoad; - using GenParams = GridKit::PowerElectronics::DistributedGeneratorParameters; + using SignalNode = GridKit::PowerElectronics::SignalNode; + using Bus = GridKit::PowerElectronics::MicrogridBus; + using BusDQ = GridKit::PowerElectronics::MicrogridBusDQ; + using DGGenerator = + GridKit::PowerElectronics::DistributedGenerator; + using Line = GridKit::PowerElectronics::MicrogridLine; + using Load = GridKit::PowerElectronics::MicrogridLoad; + using GenParams = + GridKit::PowerElectronics::DistributedGeneratorParameters; size_t model_id_next; size_t N_size; @@ -77,7 +79,8 @@ struct ScaleMicrogridNetwork * @post The network contains @c 2*N_size-1 transmission lines connecting * consecutive buses. * @post The network contains @c N_size loads connected to every other bus. - * @post @c DGParam_list contains the parameters associated with each generator. + * @post @c DGParam_list contains the parameters associated with each + * generator. * @post @c model_id_next is advanced for every component created. * * @note Components are dynamically allocated and their pointers are stored @@ -86,7 +89,8 @@ struct ScaleMicrogridNetwork void buildScaleMicrogridNetwork() { assert(N_size > 0); - // Every Bus has the same virtual resistance. This is due to numerical stability as mentioned in the paper. + // Every Bus has the same virtual resistance. This is due to numerical + // stability as mentioned in the paper. ScalarT RN = 1.0e4; // TODO: add this as parameters @@ -139,7 +143,8 @@ struct ScaleMicrogridNetwork } // line vector params - // Every odd line has the same parameters and every even line has the same parameters + // Every odd line has the same parameters and every even line has the same + // parameters ScalarT rline1 = 0.23; ScalarT Lline1 = 0.1 / (2.0 * M_PI * 50.0); ScalarT rline2 = 0.35; diff --git a/examples/PowerElectronics/Microgrid/Microgrid.cpp b/examples/PowerElectronics/Microgrid/Microgrid.cpp index 2963893dc7..341e916b60 100644 --- a/examples/PowerElectronics/Microgrid/Microgrid.cpp +++ b/examples/PowerElectronics/Microgrid/Microgrid.cpp @@ -11,15 +11,17 @@ int main(int /* argc */, char const** /* argv */) { - /// @todo Needs to be modified. Some components are small relative to others thus - /// there error is high (or could be matlab vector issue) + /// @todo Needs to be modified. Some components are small relative to others + /// thus there error is high (or could be matlab vector issue) double rel_tol = 1.0e-8; size_t max_step_number = 3000; bool use_jac = true; - bool debug_output = false; // set to true to print residuals, Jacobian and final solution + bool debug_output = + false; // set to true to print residuals, Jacobian and final solution // Create model - auto* sysmodel = new GridKit::PowerElectronics::SystemModel(use_jac); + auto* sysmodel = + new GridKit::PowerElectronics::SystemModel(use_jac); // Build the four-generator microgrid network. size_t N_size = 2; @@ -96,14 +98,18 @@ int main(int /* argc */, char const** /* argv */) bool all_internal_diff = true; bool all_external_alg = true; - const size_t num_node_vars = network.buses[0].size() + network.buses[1].size() + network.buses[2].size() + network.buses[3].size() + network.dg_signal.size(); + const size_t num_node_vars = + network.buses[0].size() + network.buses[1].size() + network.buses[2].size() + + network.buses[3].size() + network.dg_signal.size(); for (size_t i = 0; i < sysmodel->size() - num_node_vars; i++) { all_internal_diff = all_internal_diff && sysmodel->tag()[i]; if (!sysmodel->tag()[i]) { - std::cout << "Unexpected algebraic-tagged internal variable found in index " << i << '\n'; + std::cout + << "Unexpected algebraic-tagged internal variable found in index " << i + << '\n'; } } @@ -112,11 +118,16 @@ int main(int /* argc */, char const** /* argv */) all_external_alg = all_external_alg && !sysmodel->tag()[i]; if (sysmodel->tag()[i]) { - std::cout << "Unexpected differential-tagged external variable found in index " << i << '\n'; + std::cout + << "Unexpected differential-tagged external variable found in index " + << i << '\n'; } } - std::cout << "Verify all internal variables are differential: " << all_internal_diff << ", and all external variables are algebraic: " << all_external_alg << '\n'; + std::cout << "Verify all internal variables are differential: " + << all_internal_diff + << ", and all external variables are algebraic: " + << all_external_alg << '\n'; // Create numerical integrator and configure it for the generator model auto* idas = new AnalysisManager::Sundials::Ida(sysmodel); @@ -179,7 +190,8 @@ int main(int /* argc */, char const** /* argv */) double max_error = 0.0; for (size_t i = 0; i < true_vec.size(); i++) { - double error = std::abs(true_vec[i] - yfinal_data[i]) / std::abs(1.0 + true_vec[i]); + double error = + std::abs(true_vec[i] - yfinal_data[i]) / std::abs(1.0 + true_vec[i]); if (error > max_error) max_error = error; if (error > error_allowed) diff --git a/examples/PowerElectronics/RLCircuit/RLCircuit.cpp b/examples/PowerElectronics/RLCircuit/RLCircuit.cpp index ce62838775..68b294d0bf 100644 --- a/examples/PowerElectronics/RLCircuit/RLCircuit.cpp +++ b/examples/PowerElectronics/RLCircuit/RLCircuit.cpp @@ -40,17 +40,23 @@ int main(int /* argc */, char const** /* argv */) sysmodel.addNode(&bus_ir); // inductor - auto* induct = new GridKit::PowerElectronics::Inductor(idoff, linit, &bus_ir, &bus_iv); + auto* induct = new GridKit::PowerElectronics::Inductor( + idoff, linit, &bus_ir, &bus_iv + ); sysmodel.addComponent(induct); // resistor idoff++; - auto* resis = new GridKit::PowerElectronics::Resistor(idoff, rinit, &bus_vr, &bus_ir); + auto* resis = new GridKit::PowerElectronics::Resistor( + idoff, rinit, &bus_vr, &bus_ir + ); sysmodel.addComponent(resis); // voltage source idoff++; - auto* vsource = new GridKit::PowerElectronics::VoltageSource(idoff, vinit, &bus_iv, &bus_vr); + auto* vsource = new GridKit::PowerElectronics::VoltageSource( + idoff, vinit, &bus_iv, &bus_vr + ); sysmodel.addComponent(vsource); sysmodel.allocate(); diff --git a/examples/PowerElectronics/ScaleMicrogrid/ScaleMicrogrid.cpp b/examples/PowerElectronics/ScaleMicrogrid/ScaleMicrogrid.cpp index 7e6a957243..d477f3fc92 100644 --- a/examples/PowerElectronics/ScaleMicrogrid/ScaleMicrogrid.cpp +++ b/examples/PowerElectronics/ScaleMicrogrid/ScaleMicrogrid.cpp @@ -13,13 +13,17 @@ using index_type = size_t; using real_type = double; -// Include solution keys for the three test cases N = (2, 4, 8) plus tolerances here: +// Include solution keys for the three test cases N = (2, 4, 8) plus tolerances +// here: #include "SolutionKeys.hpp" -static int test(index_type Nsize, real_type test_tolerance, bool error_tol = false); +static int test( + index_type Nsize, real_type test_tolerance, bool error_tol = false +); /** - * @brief Run Scale Microgrid test cases of N = (2,4,8) and check for correctness. + * @brief Run Scale Microgrid test cases of N = (2,4,8) and check for + * correctness. * * @param argc unused * @param argv unused @@ -102,7 +106,8 @@ int test(index_type Nsize, real_type error_tol, bool debug_output) auto* y = sys_model->y().getData(); auto* yp = sys_model->yp().getData(); - // Create initial points for states. Every state is to specified to the zero initially + // Create initial points for states. Every state is to specified to the zero + // initially for (index_type i = 0; i < sys_model->size(); i++) { y[i] = 0.0; @@ -119,7 +124,8 @@ int test(index_type Nsize, real_type error_tol, bool debug_output) yp[13 * i - 1 + 6] = (params.Kpc_ * params.Kpv_ * params.Vn_) / params.Lf_; } - // since the initial P_com = 0, the set the initial vector to the reference frame + // since the initial P_com = 0, the set the initial vector to the reference + // frame y[network.dg_signal.getNodeConnection(0).idx_] = network.DGParam_list[0].wb_; sys_model->y().setDataUpdated(); @@ -149,7 +155,8 @@ int test(index_type Nsize, real_type error_tol, bool debug_output) } // Create numerical integrator and configure it for the generator model - auto* idas = new AnalysisManager::Sundials::Ida(sys_model); + auto* idas = + new AnalysisManager::Sundials::Ida(sys_model); // setup simulation idas->setTolerance(rel_tol, abs_tol); @@ -183,9 +190,12 @@ int test(index_type Nsize, real_type error_tol, bool debug_output) { // Print the Elementwise Relative Error if (debug_output) - std::cout << i << " : " << abs(true_vec->at(i) - yfinal_data[i]) / abs(true_vec->at(i)) << "\n"; + std::cout << i << " : " + << abs(true_vec->at(i) - yfinal_data[i]) / abs(true_vec->at(i)) + << "\n"; - sum_top += (true_vec->at(i) - yfinal_data[i]) * (true_vec->at(i) - yfinal_data[i]); + sum_top += + (true_vec->at(i) - yfinal_data[i]) * (true_vec->at(i) - yfinal_data[i]); sum_bottom += (true_vec->at(i) * true_vec->at(i)); } diff --git a/examples/PowerElectronics/ScaleMicrogrid/ScaleMicrogridArbitrary.cpp b/examples/PowerElectronics/ScaleMicrogrid/ScaleMicrogridArbitrary.cpp index 274a9fedb5..ddb1e0d7a6 100644 --- a/examples/PowerElectronics/ScaleMicrogrid/ScaleMicrogridArbitrary.cpp +++ b/examples/PowerElectronics/ScaleMicrogrid/ScaleMicrogridArbitrary.cpp @@ -11,7 +11,8 @@ using index_type = size_t; using real_type = double; -// Include solution keys for the three test cases N = (2, 4, 8) plus tolerances here: +// Include solution keys for the three test cases N = (2, 4, 8) plus tolerances +// here: #include "SolutionKeys.hpp" int printMicrogridSystems(index_type N_size); @@ -39,7 +40,8 @@ int main(int argc, char const* argv[]) } catch (const std::exception& e) { - std::cerr << "Error parsing grid size argument: " << e.what() << std::endl; + std::cerr << "Error parsing grid size argument: " << e.what() + << std::endl; std::cerr << "Using default grid size = " << N_size << std::endl; } } @@ -50,7 +52,8 @@ int main(int argc, char const* argv[]) /** * @brief Tests network of distributed generators. * - * @param[in] N_size - The number of DG line load combinations to generate for scale + * @param[in] N_size - The number of DG line load combinations to generate for + * scale * @return int returns 0 if successful, >0 otherwise */ int printMicrogridSystems(index_type N_size) diff --git a/examples/PowerElectronics/ScaleMicrogrid/SolutionKeys.hpp b/examples/PowerElectronics/ScaleMicrogrid/SolutionKeys.hpp index 5296fe9710..f14ad307da 100644 --- a/examples/PowerElectronics/ScaleMicrogrid/SolutionKeys.hpp +++ b/examples/PowerElectronics/ScaleMicrogrid/SolutionKeys.hpp @@ -16,8 +16,9 @@ /// /** - * The SCALE_MICROGRID_ERROR_TOL is a metric to determine if the error is good enough to pass the test. - * REL_TOL and ABS_TOL determine the amount of error the problem produces. As the tolerance decrease so does the error. + * The SCALE_MICROGRID_ERROR_TOL is a metric to determine if the error is good + * enough to pass the test. REL_TOL and ABS_TOL determine the amount of error + * the problem produces. As the tolerance decrease so does the error. * * For References keys on N=8: * 2-Norm Relative Error: 2.33318e-07 (rel/abs tol = 1e-6) diff --git a/examples/PowerFlow/Grid3Bus/Grid3BusSys.cpp b/examples/PowerFlow/Grid3Bus/Grid3BusSys.cpp index fd61d46608..8af64796ad 100644 --- a/examples/PowerFlow/Grid3Bus/Grid3BusSys.cpp +++ b/examples/PowerFlow/Grid3Bus/Grid3BusSys.cpp @@ -115,9 +115,12 @@ int monolithicCase() double V2 = model->V2(); double th3 = model->th3() * 180.0 / std::numbers::pi_v; std::cout << "Solution:\n"; - std::cout << " theta2 = " << th2 << " deg, expected = " << theta2_ref << " deg\n"; - std::cout << " V2 = " << V2 << " p.u., expected = " << V2_ref << " p.u.\n"; - std::cout << " theta3 = " << th3 << " deg, expected = " << theta3_ref << " deg\n\n"; + std::cout << " theta2 = " << th2 << " deg, expected = " << theta2_ref + << " deg\n"; + std::cout << " V2 = " << V2 << " p.u., expected = " << V2_ref + << " p.u.\n"; + std::cout << " theta3 = " << th3 << " deg, expected = " << theta3_ref + << " deg\n\n"; // Print solver performance statistics kinsol->printFinalStats(); @@ -146,7 +149,8 @@ int monolithicCase() */ int parserCase() { - std::cout << "Solving same problem, but assembled from components via a parser ...\n\n"; + std::cout << "Solving same problem, but assembled from components via a " + "parser ...\n\n"; // Data File Reading GridKit::PowerFlowData::SystemModelData mp; @@ -155,7 +159,8 @@ int parserCase() GridKit::readMatPower(mp, iss); // Create an empty system model and pass the system model data to it - SystemSteadyStateModel* sysmodel = new SystemSteadyStateModel(mp); + SystemSteadyStateModel* sysmodel = + new SystemSteadyStateModel(mp); // allocate model sysmodel->allocate(); @@ -173,14 +178,19 @@ int parserCase() // Compute solution kinsol->runSimulation(); // Print solution - double th2 = sysmodel->getBus(2)->theta() * 180.0 / std::numbers::pi_v; - double V2 = sysmodel->getBus(2)->V(); - double th3 = sysmodel->getBus(3)->theta() * 180.0 / std::numbers::pi_v; + double th2 = + sysmodel->getBus(2)->theta() * 180.0 / std::numbers::pi_v; + double V2 = sysmodel->getBus(2)->V(); + double th3 = + sysmodel->getBus(3)->theta() * 180.0 / std::numbers::pi_v; std::cout << "Solution:\n"; - std::cout << " theta2 = " << th2 << " deg, expected = " << theta2_ref << " deg\n"; - std::cout << " V2 = " << V2 << " p.u., expected = " << V2_ref << " p.u.\n"; - std::cout << " theta3 = " << th3 << " deg, expected = " << theta3_ref << " deg\n\n"; + std::cout << " theta2 = " << th2 << " deg, expected = " << theta2_ref + << " deg\n"; + std::cout << " V2 = " << V2 << " p.u., expected = " << V2_ref + << " p.u.\n"; + std::cout << " theta3 = " << th3 << " deg, expected = " << theta3_ref + << " deg\n\n"; // Print solver performance statistics kinsol->printFinalStats(); @@ -211,10 +221,12 @@ int parserCase() */ int hardwiredCase() { - std::cout << "Solving same problem, but assembled from components manually ...\n\n"; + std::cout + << "Solving same problem, but assembled from components manually ...\n\n"; // First, create an empty system model - SystemSteadyStateModel* sysmodel = new SystemSteadyStateModel(); + SystemSteadyStateModel* sysmodel = + new SystemSteadyStateModel(); // Next create and add buses ... // Create a slack bus, fix V=1, theta=0, bus ID = 1 @@ -235,7 +247,8 @@ int hardwiredCase() auto* bus2 = BusFactory::create(bd2); sysmodel->addBus(bus2); - // Create a PV bus, fix V=1.1, initialize theta=0, and set power injection Pg=2 + // Create a PV bus, fix V=1.1, initialize theta=0, and set power injection + // Pg=2 BusData bd3; bd3.bus_i = 3; bd3.type = 2; @@ -247,15 +260,17 @@ int hardwiredCase() // Create and add generators ... // Create and add slack generator connected to bus1 GenData gd1; - gd1.bus = 1; - auto* gen1 = GeneratorFactory::create(sysmodel->getBus(gd1.bus), gd1); + gd1.bus = 1; + auto* gen1 = + GeneratorFactory::create(sysmodel->getBus(gd1.bus), gd1); sysmodel->addComponent(gen1); // Create and add PV generator connected to bus3 GenData gd3; - gd3.Pg = 2.0; - gd3.bus = 3; - auto* gen3 = GeneratorFactory::create(sysmodel->getBus(gd3.bus), gd3); + gd3.Pg = 2.0; + gd3.bus = 3; + auto* gen3 = + GeneratorFactory::create(sysmodel->getBus(gd3.bus), gd3); sysmodel->addComponent(gen3); // Create and add branches ... @@ -266,7 +281,9 @@ int hardwiredCase() brd12.x = 1.0 / 10.0; brd12.r = 0.0; brd12.b = 0.0; - Branch* branch12 = new Branch(sysmodel->getBus(brd12.fbus), sysmodel->getBus(brd12.tbus), brd12); + Branch* branch12 = new Branch( + sysmodel->getBus(brd12.fbus), sysmodel->getBus(brd12.tbus), brd12 + ); sysmodel->addComponent(branch12); // Branch 1-3 @@ -276,7 +293,9 @@ int hardwiredCase() brd13.x = 1.0 / 15.0; brd13.r = 0.0; brd13.b = 0.0; - Branch* branch13 = new Branch(sysmodel->getBus(brd13.fbus), sysmodel->getBus(brd13.tbus), brd13); + Branch* branch13 = new Branch( + sysmodel->getBus(brd13.fbus), sysmodel->getBus(brd13.tbus), brd13 + ); sysmodel->addComponent(branch13); // Branch 2-3 @@ -286,24 +305,28 @@ int hardwiredCase() brd23.x = 1.0 / 12.0; brd23.r = 0.0; brd23.b = 0.0; - Branch* branch23 = new Branch(sysmodel->getBus(brd23.fbus), sysmodel->getBus(brd23.tbus), brd23); + Branch* branch23 = new Branch( + sysmodel->getBus(brd23.fbus), sysmodel->getBus(brd23.tbus), brd23 + ); sysmodel->addComponent(branch23); // Create and add loads ... // Load on bus1 LoadData ld1; - ld1.bus_i = 1; - ld1.Pd = 2.0; - ld1.Qd = 0.0; - Load* load1 = new Load(sysmodel->getBus(ld1.bus_i), ld1); + ld1.bus_i = 1; + ld1.Pd = 2.0; + ld1.Qd = 0.0; + Load* load1 = + new Load(sysmodel->getBus(ld1.bus_i), ld1); sysmodel->addComponent(load1); // Load on bus2 LoadData ld2; - ld2.bus_i = 2; - ld2.Pd = 2.5; - ld2.Qd = -0.8; - Load* load2 = new Load(sysmodel->getBus(ld2.bus_i), ld2); + ld2.bus_i = 2; + ld2.Pd = 2.5; + ld2.Qd = -0.8; + Load* load2 = + new Load(sysmodel->getBus(ld2.bus_i), ld2); sysmodel->addComponent(load2); // allocate model @@ -327,9 +350,12 @@ int hardwiredCase() double th3 = bus3->theta() * 180.0 / std::numbers::pi_v; std::cout << "Solution:\n"; - std::cout << " theta2 = " << th2 << " deg, expected = " << theta2_ref << " deg\n"; - std::cout << " V2 = " << V2 << " p.u., expected = " << V2_ref << " p.u.\n"; - std::cout << " theta3 = " << th3 << " deg, expected = " << theta3_ref << " deg\n\n"; + std::cout << " theta2 = " << th2 << " deg, expected = " << theta2_ref + << " deg\n"; + std::cout << " V2 = " << V2 << " p.u., expected = " << V2_ref + << " p.u.\n"; + std::cout << " theta3 = " << th3 << " deg, expected = " << theta3_ref + << " deg\n\n"; // Print solver performance statistics kinsol->printFinalStats(); diff --git a/examples/PowerFlow/MatPowerTesting/MatPowerTesting.hpp b/examples/PowerFlow/MatPowerTesting/MatPowerTesting.hpp index aabaf7fbe5..6a4e324ff8 100644 --- a/examples/PowerFlow/MatPowerTesting/MatPowerTesting.hpp +++ b/examples/PowerFlow/MatPowerTesting/MatPowerTesting.hpp @@ -185,13 +185,16 @@ namespace GridKit inline bool isEqual(std::vector a, std::vector b, double tol = tol_) { if (a.size() != b.size()) - throw std::runtime_error([&] - { - std::stringstream errs; - errs << "Containers do not have the same size!\n" - << "\tGot a.size() == " << a.size() << "\n" - << "\tGot b.size() == " << b.size() << "\n"; - return errs.str(); }()); + throw std::runtime_error( + [&] + { + std::stringstream errs; + errs << "Containers do not have the same size!\n" + << "\tGot a.size() == " << a.size() << "\n" + << "\tGot b.size() == " << b.size() << "\n"; + return errs.str(); + }() + ); int fail = 0; for (std::size_t i = 0; i < a.size(); i++) diff --git a/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp b/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp index 31ca622aad..7e3e2b5e88 100644 --- a/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp +++ b/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp @@ -72,8 +72,10 @@ namespace GridKit const auto& abr = a.branch[i]; const auto& bbr = b.branch[i]; - success *= abr.buses.at(BranchBuses::bus1) == bbr.buses.at(BranchBuses::bus1); - success *= abr.buses.at(BranchBuses::bus2) == bbr.buses.at(BranchBuses::bus2); + success *= + abr.buses.at(BranchBuses::bus1) == bbr.buses.at(BranchBuses::bus1); + success *= + abr.buses.at(BranchBuses::bus2) == bbr.buses.at(BranchBuses::bus2); success *= abr.parameters.at(Param::R) == bbr.parameters.at(Param::R); success *= abr.parameters.at(Param::X) == bbr.parameters.at(Param::X); success *= abr.parameters.at(Param::G) == bbr.parameters.at(Param::G); @@ -95,19 +97,29 @@ namespace GridKit success *= ag.parameters.at(Param::H) == bg.parameters.at(Param::H); success *= ag.parameters.at(Param::D) == bg.parameters.at(Param::D); success *= ag.parameters.at(Param::Ra) == bg.parameters.at(Param::Ra); - success *= ag.parameters.at(Param::Tdop) == bg.parameters.at(Param::Tdop); - success *= ag.parameters.at(Param::Tdopp) == bg.parameters.at(Param::Tdopp); - success *= ag.parameters.at(Param::Tqopp) == bg.parameters.at(Param::Tqopp); - success *= ag.parameters.at(Param::Tqop) == bg.parameters.at(Param::Tqop); + success *= + ag.parameters.at(Param::Tdop) == bg.parameters.at(Param::Tdop); + success *= + ag.parameters.at(Param::Tdopp) == bg.parameters.at(Param::Tdopp); + success *= + ag.parameters.at(Param::Tqopp) == bg.parameters.at(Param::Tqopp); + success *= + ag.parameters.at(Param::Tqop) == bg.parameters.at(Param::Tqop); success *= ag.parameters.at(Param::Xd) == bg.parameters.at(Param::Xd); - success *= ag.parameters.at(Param::Xdp) == bg.parameters.at(Param::Xdp); - success *= ag.parameters.at(Param::Xdpp) == bg.parameters.at(Param::Xdpp); + success *= + ag.parameters.at(Param::Xdp) == bg.parameters.at(Param::Xdp); + success *= + ag.parameters.at(Param::Xdpp) == bg.parameters.at(Param::Xdpp); success *= ag.parameters.at(Param::Xq) == bg.parameters.at(Param::Xq); - success *= ag.parameters.at(Param::Xqp) == bg.parameters.at(Param::Xqp); - success *= ag.parameters.at(Param::Xqpp) == bg.parameters.at(Param::Xqpp); + success *= + ag.parameters.at(Param::Xqp) == bg.parameters.at(Param::Xqp); + success *= + ag.parameters.at(Param::Xqpp) == bg.parameters.at(Param::Xqpp); success *= ag.parameters.at(Param::Xl) == bg.parameters.at(Param::Xl); - success *= ag.parameters.at(Param::S10) == bg.parameters.at(Param::S10); - success *= ag.parameters.at(Param::S12) == bg.parameters.at(Param::S12); + success *= + ag.parameters.at(Param::S10) == bg.parameters.at(Param::S10); + success *= + ag.parameters.at(Param::S12) == bg.parameters.at(Param::S12); } success *= a.genclassical.size() == b.genclassical.size(); @@ -125,7 +137,8 @@ namespace GridKit success *= ag.parameters.at(Param::H) == bg.parameters.at(Param::H); success *= ag.parameters.at(Param::D) == bg.parameters.at(Param::D); success *= ag.parameters.at(Param::Ra) == bg.parameters.at(Param::Ra); - success *= ag.parameters.at(Param::Xdp) == bg.parameters.at(Param::Xdp); + success *= + ag.parameters.at(Param::Xdp) == bg.parameters.at(Param::Xdp); } success *= a.gov.size() == b.gov.size(); @@ -138,20 +151,27 @@ namespace GridKit const auto& ag = a.gov[i]; const auto& bg = b.gov[i]; - success *= ag.signal_inputs.count(SignalIn::speed) == bg.signal_inputs.count(SignalIn::speed); + success *= ag.signal_inputs.count(SignalIn::speed) + == bg.signal_inputs.count(SignalIn::speed); if (ag.signal_inputs.count(SignalIn::speed)) { - success *= ag.signal_inputs.at(SignalIn::speed) == bg.signal_inputs.at(SignalIn::speed); + success *= ag.signal_inputs.at(SignalIn::speed) + == bg.signal_inputs.at(SignalIn::speed); } - success *= ag.signal_outputs.count(SignalOut::pmech) == bg.signal_outputs.count(SignalOut::pmech); + success *= ag.signal_outputs.count(SignalOut::pmech) + == bg.signal_outputs.count(SignalOut::pmech); if (ag.signal_outputs.count(SignalOut::pmech)) { - success *= ag.signal_outputs.at(SignalOut::pmech) == bg.signal_outputs.at(SignalOut::pmech); + success *= ag.signal_outputs.at(SignalOut::pmech) + == bg.signal_outputs.at(SignalOut::pmech); } - success *= ag.parameters.at(Param::Trate) == bg.parameters.at(Param::Trate); + success *= + ag.parameters.at(Param::Trate) == bg.parameters.at(Param::Trate); success *= ag.parameters.at(Param::R) == bg.parameters.at(Param::R); - success *= ag.parameters.at(Param::Pvmin) == bg.parameters.at(Param::Pvmin); - success *= ag.parameters.at(Param::Pvmax) == bg.parameters.at(Param::Pvmax); + success *= + ag.parameters.at(Param::Pvmin) == bg.parameters.at(Param::Pvmin); + success *= + ag.parameters.at(Param::Pvmax) == bg.parameters.at(Param::Pvmax); success *= ag.parameters.at(Param::T1) == bg.parameters.at(Param::T1); success *= ag.parameters.at(Param::T2) == bg.parameters.at(Param::T2); success *= ag.parameters.at(Param::T3) == bg.parameters.at(Param::T3); @@ -168,16 +188,21 @@ namespace GridKit const auto& ae = a.exciter[i]; const auto& be = b.exciter[i]; - success *= ae.buses.at(Ieeet1Buses::bus) == be.buses.at(Ieeet1Buses::bus); - success *= ae.signal_inputs.count(SignalIn::speed) == be.signal_inputs.count(SignalIn::speed); + success *= + ae.buses.at(Ieeet1Buses::bus) == be.buses.at(Ieeet1Buses::bus); + success *= ae.signal_inputs.count(SignalIn::speed) + == be.signal_inputs.count(SignalIn::speed); if (ae.signal_inputs.count(SignalIn::speed)) { - success *= ae.signal_inputs.at(SignalIn::speed) == be.signal_inputs.at(SignalIn::speed); + success *= ae.signal_inputs.at(SignalIn::speed) + == be.signal_inputs.at(SignalIn::speed); } - success *= ae.signal_outputs.count(SignalOut::efd) == be.signal_outputs.count(SignalOut::efd); + success *= ae.signal_outputs.count(SignalOut::efd) + == be.signal_outputs.count(SignalOut::efd); if (ae.signal_outputs.count(SignalOut::efd)) { - success *= ae.signal_outputs.at(SignalOut::efd) == be.signal_outputs.at(SignalOut::efd); + success *= ae.signal_outputs.at(SignalOut::efd) + == be.signal_outputs.at(SignalOut::efd); } success *= ae.parameters.at(Param::Tr) == be.parameters.at(Param::Tr); success *= ae.parameters.at(Param::Ka) == be.parameters.at(Param::Ka); @@ -186,13 +211,18 @@ namespace GridKit success *= ae.parameters.at(Param::Te) == be.parameters.at(Param::Te); success *= ae.parameters.at(Param::Kf) == be.parameters.at(Param::Kf); success *= ae.parameters.at(Param::Tf) == be.parameters.at(Param::Tf); - success *= ae.parameters.at(Param::Vrmin) == be.parameters.at(Param::Vrmin); - success *= ae.parameters.at(Param::Vrmax) == be.parameters.at(Param::Vrmax); + success *= + ae.parameters.at(Param::Vrmin) == be.parameters.at(Param::Vrmin); + success *= + ae.parameters.at(Param::Vrmax) == be.parameters.at(Param::Vrmax); success *= ae.parameters.at(Param::E1) == be.parameters.at(Param::E1); success *= ae.parameters.at(Param::E2) == be.parameters.at(Param::E2); - success *= ae.parameters.at(Param::Se1) == be.parameters.at(Param::Se1); - success *= ae.parameters.at(Param::Se2) == be.parameters.at(Param::Se2); - success *= ae.parameters.at(Param::Ispdlim) == be.parameters.at(Param::Ispdlim); + success *= + ae.parameters.at(Param::Se1) == be.parameters.at(Param::Se1); + success *= + ae.parameters.at(Param::Se2) == be.parameters.at(Param::Se2); + success *= ae.parameters.at(Param::Ispdlim) + == be.parameters.at(Param::Ispdlim); } success *= a.loadz.size() == b.loadz.size(); @@ -203,7 +233,8 @@ namespace GridKit const auto& al = a.loadz[i]; const auto& bl = b.loadz[i]; - success *= al.buses.at(LoadZBuses::bus) == bl.buses.at(LoadZBuses::bus); + success *= + al.buses.at(LoadZBuses::bus) == bl.buses.at(LoadZBuses::bus); success *= al.parameters.at(Param::R) == bl.parameters.at(Param::R); success *= al.parameters.at(Param::X) == bl.parameters.at(Param::X); } @@ -219,7 +250,9 @@ namespace GridKit const std::string& ref_file ) { - system_data.monitor_sink.emplace_back(VariableMonitorFormat::CSV, "mon.csv"); + system_data.monitor_sink.emplace_back( + VariableMonitorFormat::CSV, "mon.csv" + ); // Create system model SystemModel sys(system_data); @@ -280,8 +313,8 @@ namespace GridKit set_data.bus[1].Vi0 = 0.0; set_data.branch.resize(1); - set_data.branch[0].buses[BranchBuses::bus1] = set_data.bus[0].bus_id; - set_data.branch[0].buses[BranchBuses::bus2] = set_data.bus[1].bus_id; + set_data.branch[0].buses[BranchBuses::bus1] = set_data.bus[0].bus_id; + set_data.branch[0].buses[BranchBuses::bus2] = set_data.bus[1].bus_id; set_data.branch[0].parameters[BranchParameters::R] = 0.0; set_data.branch[0].parameters[BranchParameters::X] = 0.1; set_data.branch[0].parameters[BranchParameters::G] = 0.0; @@ -314,7 +347,9 @@ namespace GridKit auto success = compare(set_data, file_data); - auto error_set = runSimulation(set_data, 0, 0.0, 1e-3, "TwoBusBasic/reference/TwoBusBasic.ref.csv"); + auto error_set = runSimulation( + set_data, 0, 0.0, 1e-3, "TwoBusBasic/reference/TwoBusBasic.ref.csv" + ); RealT error_V_allowed = 2.01e-4; RealT error_w_allowed = 1e-4; @@ -357,8 +392,8 @@ namespace GridKit set_data.signal[2].signal_id = 2; set_data.branch.resize(1); - set_data.branch[0].buses[BranchBuses::bus1] = set_data.bus[0].bus_id; - set_data.branch[0].buses[BranchBuses::bus2] = set_data.bus[1].bus_id; + set_data.branch[0].buses[BranchBuses::bus1] = set_data.bus[0].bus_id; + set_data.branch[0].buses[BranchBuses::bus2] = set_data.bus[1].bus_id; set_data.branch[0].parameters[BranchParameters::R] = 0.0; set_data.branch[0].parameters[BranchParameters::X] = 0.1; set_data.branch[0].parameters[BranchParameters::G] = 0.0; @@ -458,8 +493,8 @@ namespace GridKit set_data.signal[1].signal_id = 1; set_data.branch.resize(1); - set_data.branch[0].buses[BranchBuses::bus1] = set_data.bus[0].bus_id; - set_data.branch[0].buses[BranchBuses::bus2] = set_data.bus[1].bus_id; + set_data.branch[0].buses[BranchBuses::bus1] = set_data.bus[0].bus_id; + set_data.branch[0].buses[BranchBuses::bus2] = set_data.bus[1].bus_id; set_data.branch[0].parameters[BranchParameters::R] = 0.0; set_data.branch[0].parameters[BranchParameters::X] = 0.1; set_data.branch[0].parameters[BranchParameters::G] = 0.0; @@ -536,20 +571,20 @@ namespace GridKit set_data.bus[2].monitored_variables.insert(BusVar::Vm); set_data.branch.resize(3); - set_data.branch[0].buses[BranchBuses::bus1] = set_data.bus[0].bus_id; - set_data.branch[0].buses[BranchBuses::bus2] = set_data.bus[1].bus_id; + set_data.branch[0].buses[BranchBuses::bus1] = set_data.bus[0].bus_id; + set_data.branch[0].buses[BranchBuses::bus2] = set_data.bus[1].bus_id; set_data.branch[0].parameters[BranchParameters::R] = 0.05; set_data.branch[0].parameters[BranchParameters::X] = 0.21; set_data.branch[0].parameters[BranchParameters::G] = 0.0; set_data.branch[0].parameters[BranchParameters::B] = 0.1; - set_data.branch[1].buses[BranchBuses::bus1] = set_data.bus[0].bus_id; - set_data.branch[1].buses[BranchBuses::bus2] = set_data.bus[2].bus_id; + set_data.branch[1].buses[BranchBuses::bus1] = set_data.bus[0].bus_id; + set_data.branch[1].buses[BranchBuses::bus2] = set_data.bus[2].bus_id; set_data.branch[1].parameters[BranchParameters::R] = 0.06; set_data.branch[1].parameters[BranchParameters::X] = 0.15; set_data.branch[1].parameters[BranchParameters::G] = 0.; set_data.branch[1].parameters[BranchParameters::B] = 0.12; - set_data.branch[2].buses[BranchBuses::bus1] = set_data.bus[1].bus_id; - set_data.branch[2].buses[BranchBuses::bus2] = set_data.bus[2].bus_id; + set_data.branch[2].buses[BranchBuses::bus1] = set_data.bus[1].bus_id; + set_data.branch[2].buses[BranchBuses::bus2] = set_data.bus[2].bus_id; set_data.branch[2].parameters[BranchParameters::R] = 0.08; set_data.branch[2].parameters[BranchParameters::X] = 0.27; set_data.branch[2].parameters[BranchParameters::G] = 0.; @@ -635,37 +670,41 @@ namespace GridKit set_data.bus[2].monitored_variables.insert(BusVar::Vm); set_data.branch.resize(3); - set_data.branch[0].buses[BranchBuses::bus1] = set_data.bus[0].bus_id; - set_data.branch[0].buses[BranchBuses::bus2] = set_data.bus[1].bus_id; + set_data.branch[0].buses[BranchBuses::bus1] = set_data.bus[0].bus_id; + set_data.branch[0].buses[BranchBuses::bus2] = set_data.bus[1].bus_id; set_data.branch[0].parameters[BranchParameters::R] = 0.05; set_data.branch[0].parameters[BranchParameters::X] = 0.21; set_data.branch[0].parameters[BranchParameters::G] = 0.0; set_data.branch[0].parameters[BranchParameters::B] = 0.1; - set_data.branch[1].buses[BranchBuses::bus1] = set_data.bus[0].bus_id; - set_data.branch[1].buses[BranchBuses::bus2] = set_data.bus[2].bus_id; + set_data.branch[1].buses[BranchBuses::bus1] = set_data.bus[0].bus_id; + set_data.branch[1].buses[BranchBuses::bus2] = set_data.bus[2].bus_id; set_data.branch[1].parameters[BranchParameters::R] = 0.06; set_data.branch[1].parameters[BranchParameters::X] = 0.15; set_data.branch[1].parameters[BranchParameters::G] = 0.; set_data.branch[1].parameters[BranchParameters::B] = 0.12; - set_data.branch[2].buses[BranchBuses::bus1] = set_data.bus[1].bus_id; - set_data.branch[2].buses[BranchBuses::bus2] = set_data.bus[2].bus_id; + set_data.branch[2].buses[BranchBuses::bus1] = set_data.bus[1].bus_id; + set_data.branch[2].buses[BranchBuses::bus2] = set_data.bus[2].bus_id; set_data.branch[2].parameters[BranchParameters::R] = 0.08; set_data.branch[2].parameters[BranchParameters::X] = 0.27; set_data.branch[2].parameters[BranchParameters::G] = 0.; set_data.branch[2].parameters[BranchParameters::B] = 0.45; set_data.genclassical.resize(2); - set_data.genclassical[0].buses[GenClassicalBuses::bus] = set_data.bus[1].bus_id; - set_data.genclassical[0].parameters[GenClassicalParameters::p0] = 0.5; - set_data.genclassical[0].parameters[GenClassicalParameters::q0] = -0.07588; + set_data.genclassical[0].buses[GenClassicalBuses::bus] = + set_data.bus[1].bus_id; + set_data.genclassical[0].parameters[GenClassicalParameters::p0] = 0.5; + set_data.genclassical[0].parameters[GenClassicalParameters::q0] = + -0.07588; set_data.genclassical[0].parameters[GenClassicalParameters::H] = 2.7; set_data.genclassical[0].parameters[GenClassicalParameters::D] = 0.; set_data.genclassical[0].parameters[GenClassicalParameters::Ra] = 0.; set_data.genclassical[0].parameters[GenClassicalParameters::Xdp] = 0.17; set_data.genclassical[0].monitored_variables.insert(GenVar::speed); - set_data.genclassical[1].buses[GenClassicalBuses::bus] = set_data.bus[2].bus_id; - set_data.genclassical[1].parameters[GenClassicalParameters::p0] = 0.25; - set_data.genclassical[1].parameters[GenClassicalParameters::q0] = 0.26587; + set_data.genclassical[1].buses[GenClassicalBuses::bus] = + set_data.bus[2].bus_id; + set_data.genclassical[1].parameters[GenClassicalParameters::p0] = 0.25; + set_data.genclassical[1].parameters[GenClassicalParameters::q0] = + 0.26587; set_data.genclassical[1].parameters[GenClassicalParameters::H] = 1.6; set_data.genclassical[1].parameters[GenClassicalParameters::D] = 0.; set_data.genclassical[1].parameters[GenClassicalParameters::Ra] = 0.; @@ -677,7 +716,7 @@ namespace GridKit set_data.loadz[0].parameters[LoadZParameters::R] = 0.4447197839297772; set_data.loadz[0].parameters[LoadZParameters::X] = 0.20330047265361242; - std::string in_file = "ThreeBusClassical/ThreeBusClassical.case.json"; + std::string in_file = "ThreeBusClassical/ThreeBusClassical.case.json"; SystemModelDataT file_data = parseSystemModelData(in_file); auto success = compare(set_data, file_data); @@ -685,14 +724,16 @@ namespace GridKit } /// A finite plant-reference pulse propagates through the public REPCA, - /// REECB, and REGCA signals before the closed loop returns to equilibrium. + /// REECB, and REGCA signals before the closed loop returns to + /// equilibrium. TestOutcome regcaReecbRepca() { using namespace GridKit::PhasorDynamics::Controller; using namespace GridKit::PhasorDynamics::Converter; // Signal IDs are local graph keys. Their enum values only provide a - // compact set of unique identifiers; the numbers carry no model meaning. + // compact set of unique identifiers; the numbers carry no model + // meaning. enum class LoopSignal : size_t { IPCMD, @@ -706,14 +747,12 @@ namespace GridKit PLANT_PREF, }; const auto signalId = [](LoopSignal signal) - { - return static_cast(signal); - }; + { return static_cast(signal); }; - constexpr IdxT RENEWABLE_BUS_ID = static_cast(0); - constexpr RealT SYSTEM_MVA = static_cast(100.0); + constexpr IdxT RENEWABLE_BUS_ID = static_cast(0); + constexpr RealT SYSTEM_MVA = static_cast(100.0); // The 2:1 base ratio exercises each controller power-base conversion. - constexpr RealT COMPONENT_MVA = SYSTEM_MVA / static_cast(2.0); + constexpr RealT COMPONENT_MVA = SYSTEM_MVA / static_cast(2.0); // A nonzero interior operating point stays clear of controller limits. constexpr RealT INITIAL_ACTIVE_POWER = static_cast(0.4); constexpr RealT INITIAL_REACTIVE_POWER = static_cast(0.05); @@ -723,13 +762,16 @@ namespace GridKit // Five fast time constants let the perturbation propagate through the // converter and electrical controller. One fifth of the pulse proves a // material response without pinning an exact transient trajectory. - constexpr RealT PULSE_DURATION = static_cast(5.0) * FAST_TIME_CONSTANT; - constexpr RealT MINIMUM_RESPONSE = REFERENCE_PULSE / static_cast(5.0); + constexpr RealT PULSE_DURATION = + static_cast(5.0) * FAST_TIME_CONSTANT; + constexpr RealT MINIMUM_RESPONSE = + REFERENCE_PULSE / static_cast(5.0); // Preserve the conservative fifty-plant-time-constant recovery window. - constexpr RealT RECOVERY_HORIZON = static_cast(50.0) * PLANT_TIME_CONSTANT; + constexpr RealT RECOVERY_HORIZON = + static_cast(50.0) * PLANT_TIME_CONSTANT; // This is an output cadence; IDA still selects its internal steps. - constexpr RealT OUTPUT_INTERVAL = ONE / static_cast(60.0); - constexpr RealT RECOVERY_TOLERANCE = static_cast(1.0e-6); + constexpr RealT OUTPUT_INTERVAL = ONE / static_cast(60.0); + constexpr RealT RECOVERY_TOLERANCE = static_cast(1.0e-6); TestStatus success = true; @@ -754,76 +796,100 @@ namespace GridKit {"Plant Active Power Reference", signalId(LoopSignal::PLANT_PREF)} }; - auto& converter = data.regca.emplace_back(); - converter.buses[RegcaBuses::bus] = RENEWABLE_BUS_ID; - converter.signal_inputs[RegcaSignalInputs::ipcmd] = signalId(LoopSignal::IPCMD); - converter.signal_inputs[RegcaSignalInputs::iqcmd] = signalId(LoopSignal::IQCMD); - converter.signal_outputs[RegcaSignalOutputs::ir] = signalId(LoopSignal::IR); - converter.signal_outputs[RegcaSignalOutputs::ii] = signalId(LoopSignal::II); - converter.signal_outputs[RegcaSignalOutputs::pbranch] = signalId(LoopSignal::PBRANCH); - converter.signal_outputs[RegcaSignalOutputs::qbranch] = signalId(LoopSignal::QBRANCH); - converter.parameters[RegcaParameters::p0] = INITIAL_ACTIVE_POWER; - converter.parameters[RegcaParameters::q0] = INITIAL_REACTIVE_POWER; - converter.parameters[RegcaParameters::mva] = COMPONENT_MVA; - converter.parameters[RegcaParameters::Tg] = FAST_TIME_CONSTANT; - converter.parameters[RegcaParameters::TM] = FAST_TIME_CONSTANT; - converter.parameters[RegcaParameters::Rqmax] = static_cast(999.0); - converter.parameters[RegcaParameters::Rqmin] = static_cast(-999.0); - converter.parameters[RegcaParameters::Rpmax] = static_cast(999.0); - converter.parameters[RegcaParameters::sL] = true; - converter.parameters[RegcaParameters::IL1] = static_cast(1.1); - converter.parameters[RegcaParameters::VL0] = static_cast(0.4); - converter.parameters[RegcaParameters::VL1] = static_cast(0.9); - converter.parameters[RegcaParameters::VA0] = static_cast(0.4); - converter.parameters[RegcaParameters::VA1] = static_cast(0.9); - converter.parameters[RegcaParameters::Vhvmax] = static_cast(1.2); - - auto& controller = data.reecb.emplace_back(); - controller.buses[ReecbBuses::bus] = RENEWABLE_BUS_ID; - controller.signal_inputs[ReecbSignalInputs::pe] = signalId(LoopSignal::PBRANCH); - controller.signal_inputs[ReecbSignalInputs::qgen] = signalId(LoopSignal::QBRANCH); - controller.signal_inputs[ReecbSignalInputs::qext] = signalId(LoopSignal::QEXT); - controller.signal_inputs[ReecbSignalInputs::pref] = signalId(LoopSignal::PEXT); - controller.signal_outputs[ReecbSignalOutputs::ipcmd] = signalId(LoopSignal::IPCMD); - controller.signal_outputs[ReecbSignalOutputs::iqcmd] = signalId(LoopSignal::IQCMD); - controller.parameters[ReecbParameters::mva] = COMPONENT_MVA; - controller.parameters[ReecbParameters::Trv] = FAST_TIME_CONSTANT; - controller.parameters[ReecbParameters::Tp] = FAST_TIME_CONSTANT; - controller.parameters[ReecbParameters::Kvi] = static_cast(5.0); - controller.parameters[ReecbParameters::QFlag] = true; - controller.parameters[ReecbParameters::VFlag] = true; - - auto& plant = data.repca.emplace_back(); - plant.buses[RepcaBuses::bus] = RENEWABLE_BUS_ID; - plant.signal_inputs[RepcaSignalInputs::ir] = signalId(LoopSignal::IR); - plant.signal_inputs[RepcaSignalInputs::ii] = signalId(LoopSignal::II); - plant.signal_inputs[RepcaSignalInputs::p] = signalId(LoopSignal::PBRANCH); - plant.signal_inputs[RepcaSignalInputs::q] = signalId(LoopSignal::QBRANCH); - plant.signal_inputs[RepcaSignalInputs::pref] = signalId(LoopSignal::PLANT_PREF); - plant.signal_outputs[RepcaSignalOutputs::qext] = signalId(LoopSignal::QEXT); - plant.signal_outputs[RepcaSignalOutputs::pext] = signalId(LoopSignal::PEXT); - plant.parameters[RepcaParameters::mva] = COMPONENT_MVA; - plant.parameters[RepcaParameters::Freqflag] = true; - plant.parameters[RepcaParameters::Ddn] = ZERO; - plant.parameters[RepcaParameters::Dup] = ZERO; - plant.parameters[RepcaParameters::Tp] = FAST_TIME_CONSTANT; - plant.parameters[RepcaParameters::Tlag] = PLANT_TIME_CONSTANT; - - auto& reference = data.constant_source.emplace_back(); - reference.parameters[ConstantSignalSourceParameters::Sr] = INITIAL_ACTIVE_POWER; + auto& converter = data.regca.emplace_back(); + converter.buses[RegcaBuses::bus] = RENEWABLE_BUS_ID; + converter.signal_inputs[RegcaSignalInputs::ipcmd] = + signalId(LoopSignal::IPCMD); + converter.signal_inputs[RegcaSignalInputs::iqcmd] = + signalId(LoopSignal::IQCMD); + converter.signal_outputs[RegcaSignalOutputs::ir] = + signalId(LoopSignal::IR); + converter.signal_outputs[RegcaSignalOutputs::ii] = + signalId(LoopSignal::II); + converter.signal_outputs[RegcaSignalOutputs::pbranch] = + signalId(LoopSignal::PBRANCH); + converter.signal_outputs[RegcaSignalOutputs::qbranch] = + signalId(LoopSignal::QBRANCH); + converter.parameters[RegcaParameters::p0] = INITIAL_ACTIVE_POWER; + converter.parameters[RegcaParameters::q0] = INITIAL_REACTIVE_POWER; + converter.parameters[RegcaParameters::mva] = COMPONENT_MVA; + converter.parameters[RegcaParameters::Tg] = FAST_TIME_CONSTANT; + converter.parameters[RegcaParameters::TM] = FAST_TIME_CONSTANT; + converter.parameters[RegcaParameters::Rqmax] = + static_cast(999.0); + converter.parameters[RegcaParameters::Rqmin] = + static_cast(-999.0); + converter.parameters[RegcaParameters::Rpmax] = + static_cast(999.0); + converter.parameters[RegcaParameters::sL] = true; + converter.parameters[RegcaParameters::IL1] = static_cast(1.1); + converter.parameters[RegcaParameters::VL0] = static_cast(0.4); + converter.parameters[RegcaParameters::VL1] = static_cast(0.9); + converter.parameters[RegcaParameters::VA0] = static_cast(0.4); + converter.parameters[RegcaParameters::VA1] = static_cast(0.9); + converter.parameters[RegcaParameters::Vhvmax] = static_cast(1.2); + + auto& controller = data.reecb.emplace_back(); + controller.buses[ReecbBuses::bus] = RENEWABLE_BUS_ID; + controller.signal_inputs[ReecbSignalInputs::pe] = + signalId(LoopSignal::PBRANCH); + controller.signal_inputs[ReecbSignalInputs::qgen] = + signalId(LoopSignal::QBRANCH); + controller.signal_inputs[ReecbSignalInputs::qext] = + signalId(LoopSignal::QEXT); + controller.signal_inputs[ReecbSignalInputs::pref] = + signalId(LoopSignal::PEXT); + controller.signal_outputs[ReecbSignalOutputs::ipcmd] = + signalId(LoopSignal::IPCMD); + controller.signal_outputs[ReecbSignalOutputs::iqcmd] = + signalId(LoopSignal::IQCMD); + controller.parameters[ReecbParameters::mva] = COMPONENT_MVA; + controller.parameters[ReecbParameters::Trv] = FAST_TIME_CONSTANT; + controller.parameters[ReecbParameters::Tp] = FAST_TIME_CONSTANT; + controller.parameters[ReecbParameters::Kvi] = static_cast(5.0); + controller.parameters[ReecbParameters::QFlag] = true; + controller.parameters[ReecbParameters::VFlag] = true; + + auto& plant = data.repca.emplace_back(); + plant.buses[RepcaBuses::bus] = RENEWABLE_BUS_ID; + plant.signal_inputs[RepcaSignalInputs::ir] = signalId(LoopSignal::IR); + plant.signal_inputs[RepcaSignalInputs::ii] = signalId(LoopSignal::II); + plant.signal_inputs[RepcaSignalInputs::p] = + signalId(LoopSignal::PBRANCH); + plant.signal_inputs[RepcaSignalInputs::q] = + signalId(LoopSignal::QBRANCH); + plant.signal_inputs[RepcaSignalInputs::pref] = + signalId(LoopSignal::PLANT_PREF); + plant.signal_outputs[RepcaSignalOutputs::qext] = + signalId(LoopSignal::QEXT); + plant.signal_outputs[RepcaSignalOutputs::pext] = + signalId(LoopSignal::PEXT); + plant.parameters[RepcaParameters::mva] = COMPONENT_MVA; + plant.parameters[RepcaParameters::Freqflag] = true; + plant.parameters[RepcaParameters::Ddn] = ZERO; + plant.parameters[RepcaParameters::Dup] = ZERO; + plant.parameters[RepcaParameters::Tp] = FAST_TIME_CONSTANT; + plant.parameters[RepcaParameters::Tlag] = PLANT_TIME_CONSTANT; + + auto& reference = data.constant_source.emplace_back(); + reference.parameters[ConstantSignalSourceParameters::Sr] = + INITIAL_ACTIVE_POWER; reference.signal_outputs[ConstantSignalSourceSignalOutputs::sr] = signalId(LoopSignal::PLANT_PREF); SystemModel system(data); success *= system.allocate() == 0; - auto* pref_signal = system.getSignalNode(signalId(LoopSignal::PLANT_PREF)); - auto* pext_signal = system.getSignalNode(signalId(LoopSignal::PEXT)); - auto* qext_signal = system.getSignalNode(signalId(LoopSignal::QEXT)); - auto* ipcmd_signal = system.getSignalNode(signalId(LoopSignal::IPCMD)); - auto* pbranch_signal = system.getSignalNode(signalId(LoopSignal::PBRANCH)); - if (pref_signal == nullptr || pext_signal == nullptr || qext_signal == nullptr - || ipcmd_signal == nullptr || pbranch_signal == nullptr) + auto* pref_signal = + system.getSignalNode(signalId(LoopSignal::PLANT_PREF)); + auto* pext_signal = system.getSignalNode(signalId(LoopSignal::PEXT)); + auto* qext_signal = system.getSignalNode(signalId(LoopSignal::QEXT)); + auto* ipcmd_signal = system.getSignalNode(signalId(LoopSignal::IPCMD)); + auto* pbranch_signal = + system.getSignalNode(signalId(LoopSignal::PBRANCH)); + if (pref_signal == nullptr || pext_signal == nullptr + || qext_signal == nullptr || ipcmd_signal == nullptr + || pbranch_signal == nullptr) { std::cout << "Renewable-control loop is missing a required signal\n"; success = false; @@ -881,8 +947,8 @@ namespace GridKit { if (response.value <= MINIMUM_RESPONSE) { - std::cout << response.label << " responded by only " << response.value - << " during the reference pulse\n"; + std::cout << response.label << " responded by only " + << response.value << " during the reference pulse\n"; success = false; } } diff --git a/tests/IntegrationTests/PhasorDynamics/SystemJacobian/runSystemJacobianTests.cpp b/tests/IntegrationTests/PhasorDynamics/SystemJacobian/runSystemJacobianTests.cpp index 3e942684fc..77f37fac7c 100644 --- a/tests/IntegrationTests/PhasorDynamics/SystemJacobian/runSystemJacobianTests.cpp +++ b/tests/IntegrationTests/PhasorDynamics/SystemJacobian/runSystemJacobianTests.cpp @@ -29,9 +29,11 @@ int main(int argc, const char* argv[]) std::vector case_files; if (std::filesystem::is_directory(path)) { - for (const auto& entry : std::filesystem::recursive_directory_iterator(path)) + for (const auto& entry : + std::filesystem::recursive_directory_iterator(path)) { - if (entry.is_regular_file() && entry.path().filename().string().ends_with(".case.json")) + if (entry.is_regular_file() + && entry.path().filename().string().ends_with(".case.json")) { case_files.push_back(entry.path()); } @@ -49,7 +51,9 @@ int main(int argc, const char* argv[]) } GridKit::Testing::TestingResults result; - GridKit::Testing::SystemJacobianTests test(args["evaluations"].as()); + GridKit::Testing::SystemJacobianTests test( + args["evaluations"].as() + ); for (const auto& case_file : case_files) { diff --git a/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp b/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp index 09e0b40be5..96477aba07 100644 --- a/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp +++ b/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp @@ -28,7 +28,9 @@ using real_type = double; using index_type = size_t; /// Machine data shared by the example generators -GridKit::PhasorDynamics::GenClassicalData genData(real_type p0, real_type q0) +GridKit::PhasorDynamics::GenClassicalData genData( + real_type p0, real_type q0 +) { using Parameter = GridKit::PhasorDynamics::GenClassicalParameters; @@ -91,15 +93,33 @@ int main() Bus bus9(0.938638861502395, 0.344901620288291); Bus bus10(0.937739191669114, 0.347340277548916); - Branch branch12(&bus1, &bus2, branchData(0.001, 0.005, 0, 0)); - Branch branch23(&bus2, &bus3, branchData(0.001, 0.005, 0, 0)); - Branch branch34(&bus3, &bus4, branchData(0.001, 0.005, 0, 0)); - Branch branch45(&bus4, &bus5, branchData(0.001, 0.005, 0, 0)); - Branch branch56(&bus5, &bus6, branchData(0.001, 0.1, 0, 0)); - Branch branch67(&bus6, &bus7, branchData(0.001, 0.005, 0, 0)); - Branch branch78(&bus7, &bus8, branchData(0.001, 0.005, 0, 0)); - Branch branch89(&bus8, &bus9, branchData(0.001, 0.005, 0, 0)); - Branch branch910(&bus9, &bus10, branchData(0.001, 0.005, 0, 0)); + Branch branch12( + &bus1, &bus2, branchData(0.001, 0.005, 0, 0) + ); + Branch branch23( + &bus2, &bus3, branchData(0.001, 0.005, 0, 0) + ); + Branch branch34( + &bus3, &bus4, branchData(0.001, 0.005, 0, 0) + ); + Branch branch45( + &bus4, &bus5, branchData(0.001, 0.005, 0, 0) + ); + Branch branch56( + &bus5, &bus6, branchData(0.001, 0.1, 0, 0) + ); + Branch branch67( + &bus6, &bus7, branchData(0.001, 0.005, 0, 0) + ); + Branch branch78( + &bus7, &bus8, branchData(0.001, 0.005, 0, 0) + ); + Branch branch89( + &bus8, &bus9, branchData(0.001, 0.005, 0, 0) + ); + Branch branch910( + &bus9, &bus10, branchData(0.001, 0.005, 0, 0) + ); GenClassical gen2(&bus2, genData(0.5, -0.00442101)); GenClassical gen3(&bus3, genData(0.5, -0.02510812)); @@ -109,7 +129,9 @@ int main() GenClassical gen7(&bus7, genData(0.5, -0.08318208)); GenClassical gen8(&bus8, genData(0.5, -0.09123614)); GenClassical gen9(&bus9, genData(0.5, -0.09662372)); - GenClassical gen10(&bus10, genData(0.5, -0.09932297)); + GenClassical gen10( + &bus10, genData(0.5, -0.09932297) + ); /* Connect everything together */ SystemModel sys; @@ -226,12 +248,13 @@ int main() ida.initializeSimulation(1.0); ida.runSimulation(1.1, dt, output_cb); - // Pm = 0.5 pu, H = 3 s; neglect electrical output and damping during the fault. + // Pm = 0.5 pu, H = 3 s; neglect electrical output and damping during the + // fault. using Variable = GenClassicalInternalVariables; const auto omega_index = static_cast(Variable::OMEGA); const real_type omega_ref = std::sqrt(1.0 + 0.5 * 0.1 / 3.0) - 1.0; success *= std::hypot(bus10.Vr(), bus10.Vi()) < 1e-3; - success *= isEqual(gen10.y().getData()[omega_index], omega_ref, 5e-5); + success *= isEqual(gen10.y().getData()[omega_index], omega_ref, 5e-5); // Clear fault and run until t = 10s. bus10.clearFault(); @@ -245,7 +268,8 @@ int main() fileout.close(); - Log::summary() << "Complete in " << (stop - start) / CLOCKS_PER_SEC << " seconds\n"; + Log::summary() << "Complete in " << (stop - start) / CLOCKS_PER_SEC + << " seconds\n"; auto error_set = GridKit::Testing::compareCSV( "TenGenClassical_results.csv", @@ -260,7 +284,8 @@ int main() success *= ida.initializeSimulation(10.0) == 0; success *= ida.runSimulation(10.1) == 0; success *= sys.evaluateResidual() == 0; - // Check algebraic consistency at the output time; IDA controls differential solution error. + // Check algebraic consistency at the output time; IDA controls differential + // solution error. for (index_type i = 0; i < sys.size(); ++i) { success *= std::isfinite(sys.getResidual().getData()[i]); diff --git a/tests/IntegrationTests/PhasorDynamics/TenGen/Genrou/TenGenGenrou.cpp b/tests/IntegrationTests/PhasorDynamics/TenGen/Genrou/TenGenGenrou.cpp index 685cff6e72..3c14d46c2c 100644 --- a/tests/IntegrationTests/PhasorDynamics/TenGen/Genrou/TenGenGenrou.cpp +++ b/tests/IntegrationTests/PhasorDynamics/TenGen/Genrou/TenGenGenrou.cpp @@ -27,7 +27,9 @@ using real_type = double; using index_type = size_t; /// Machine data shared by the example generators -GridKit::PhasorDynamics::GenrouData genData(real_type p0, real_type q0) +GridKit::PhasorDynamics::GenrouData genData( + real_type p0, real_type q0 +) { using Parameter = GridKit::PhasorDynamics::GenrouParameters; @@ -86,15 +88,33 @@ int main() Bus bus9(0.938638861502395, 0.344901620288291); Bus bus10(0.937739191669114, 0.347340277548916); - Branch branch12(&bus1, &bus2, branchData(0.001, 0.005, 0, 0)); - Branch branch23(&bus2, &bus3, branchData(0.001, 0.005, 0, 0)); - Branch branch34(&bus3, &bus4, branchData(0.001, 0.005, 0, 0)); - Branch branch45(&bus4, &bus5, branchData(0.001, 0.005, 0, 0)); - Branch branch56(&bus5, &bus6, branchData(0.001, 0.1, 0, 0)); - Branch branch67(&bus6, &bus7, branchData(0.001, 0.005, 0, 0)); - Branch branch78(&bus7, &bus8, branchData(0.001, 0.005, 0, 0)); - Branch branch89(&bus8, &bus9, branchData(0.001, 0.005, 0, 0)); - Branch branch910(&bus9, &bus10, branchData(0.001, 0.005, 0, 0)); + Branch branch12( + &bus1, &bus2, branchData(0.001, 0.005, 0, 0) + ); + Branch branch23( + &bus2, &bus3, branchData(0.001, 0.005, 0, 0) + ); + Branch branch34( + &bus3, &bus4, branchData(0.001, 0.005, 0, 0) + ); + Branch branch45( + &bus4, &bus5, branchData(0.001, 0.005, 0, 0) + ); + Branch branch56( + &bus5, &bus6, branchData(0.001, 0.1, 0, 0) + ); + Branch branch67( + &bus6, &bus7, branchData(0.001, 0.005, 0, 0) + ); + Branch branch78( + &bus7, &bus8, branchData(0.001, 0.005, 0, 0) + ); + Branch branch89( + &bus8, &bus9, branchData(0.001, 0.005, 0, 0) + ); + Branch branch910( + &bus9, &bus10, branchData(0.001, 0.005, 0, 0) + ); Genrou gen2(&bus2, genData(0.5, -0.00442101)); Genrou gen3(&bus3, genData(0.5, -0.02510812)); @@ -207,12 +227,13 @@ int main() ida.initializeSimulation(1.0); ida.runSimulation(1.1, dt, output_cb); - // Pm = 0.5 pu, H = 3 s; neglect electrical output and damping during the fault. + // Pm = 0.5 pu, H = 3 s; neglect electrical output and damping during the + // fault. using Variable = GenrouInternalVariables; const auto omega_index = static_cast(Variable::OMEGA); const real_type omega_ref = std::sqrt(1.0 + 0.5 * 0.1 / 3.0) - 1.0; success *= std::hypot(bus10.Vr(), bus10.Vi()) < 1e-3; - success *= isEqual(gen10.y().getData()[omega_index], omega_ref, 5e-5); + success *= isEqual(gen10.y().getData()[omega_index], omega_ref, 5e-5); // Clear fault and run until t = 10s. bus10.setFault(false, 0.0, 1e-5); @@ -226,7 +247,8 @@ int main() fileout.close(); - Log::summary() << "Complete in " << (stop - start) / CLOCKS_PER_SEC << " seconds\n"; + Log::summary() << "Complete in " << (stop - start) / CLOCKS_PER_SEC + << " seconds\n"; auto error_set = GridKit::Testing::compareCSV( "TenGenGenrou_Results.csv", diff --git a/tests/UnitTests/AutomaticDifferentiation/Enzyme/EnzymeTests.hpp b/tests/UnitTests/AutomaticDifferentiation/Enzyme/EnzymeTests.hpp index 90f75ac21f..5c885b36ef 100644 --- a/tests/UnitTests/AutomaticDifferentiation/Enzyme/EnzymeTests.hpp +++ b/tests/UnitTests/AutomaticDifferentiation/Enzyme/EnzymeTests.hpp @@ -28,7 +28,8 @@ namespace GridKit ~EnzymeTests() = default; /** - * @brief Standalone Enzyme test that computes the derivative of a scalar function (square) + * @brief Standalone Enzyme test that computes the derivative of a scalar + * function (square) * * The function to differentiate is f(x) = x^2 * The expected derivative if f'(x) = 2*x @@ -59,10 +60,12 @@ namespace GridKit } /** - * @brief Standalone Enzyme test that computes the derivative of a vector function + * @brief Standalone Enzyme test that computes the derivative of a vector + * function * * The function to differentiate is f_i(x) = sum(x_j^2) for j <= i - * The expected Jacobian is a lower triangular matrix of f_{i,j}'(x) = 2*x_j if j <= i + * The expected Jacobian is a lower triangular matrix of f_{i,j}'(x) = + * 2*x_j if j <= i * */ TestOutcome vectorFunctionSparse() @@ -118,7 +121,9 @@ namespace GridKit return 2.0 * x; } - __attribute__((always_inline)) static void vectorFunction(IdxT N, ScalarT* x, ScalarT* y) + __attribute__((always_inline)) static void vectorFunction( + IdxT N, ScalarT* x, ScalarT* y + ) { for (IdxT idx = 0; idx < N; ++idx) { @@ -130,7 +135,9 @@ namespace GridKit } } - SparseMatrix* vectorFunctionSparseEnzymeJacobian(const IdxT N, const ScalarT* x) + SparseMatrix* vectorFunctionSparseEnzymeJacobian( + const IdxT N, const ScalarT* x + ) { using namespace GridKit::Enzyme::Sparse; @@ -196,7 +203,9 @@ namespace GridKit return new SparseMatrix(N, N, current_nnz, &rows, &cols, &vals); } - SparseMatrix* vectorFunctionSparseReferenceJacobian(const IdxT N, const ScalarT* x) + SparseMatrix* vectorFunctionSparseReferenceJacobian( + const IdxT N, const ScalarT* x + ) { IdxT nnz = N * (N + 1) / 2; // lower triangular matrix IdxT* rows = new IdxT[static_cast(nnz)]; diff --git a/tests/UnitTests/LinearAlgebra/SparseMatrix/SparseCooTests.hpp b/tests/UnitTests/LinearAlgebra/SparseMatrix/SparseCooTests.hpp index cbebf77543..3247e83e2f 100644 --- a/tests/UnitTests/LinearAlgebra/SparseMatrix/SparseCooTests.hpp +++ b/tests/UnitTests/LinearAlgebra/SparseMatrix/SparseCooTests.hpp @@ -92,12 +92,15 @@ namespace GridKit h_val_data[i] = static_cast(i + 1); } - if (A.setDataPointers(h_row_data, h_col_data, h_val_data, memory::HOST) != 0) + if (A.setDataPointers(h_row_data, h_col_data, h_val_data, memory::HOST) + != 0) { std::cout << "Failed to set data pointers.\n"; success = false; } - else if (A.getRowData(memory::HOST) != h_row_data || A.getColData(memory::HOST) != h_col_data || A.getValues(memory::HOST) != h_val_data) + else if (A.getRowData(memory::HOST) != h_row_data + || A.getColData(memory::HOST) != h_col_data + || A.getValues(memory::HOST) != h_val_data) { std::cout << "Data pointers do not point to expected values.\n"; success = false; diff --git a/tests/UnitTests/LinearAlgebra/SparseMatrix/SparseCsrTests.hpp b/tests/UnitTests/LinearAlgebra/SparseMatrix/SparseCsrTests.hpp index de66bbc5b0..c9ab882854 100644 --- a/tests/UnitTests/LinearAlgebra/SparseMatrix/SparseCsrTests.hpp +++ b/tests/UnitTests/LinearAlgebra/SparseMatrix/SparseCsrTests.hpp @@ -36,7 +36,8 @@ namespace GridKit * @param[in] n - number of rows * @param[in] m - number of columns * @param[in] row_density - number of non-zeros per row - * @param[in] is_symmetric - true if the matrix is symmetric, false otherwise + * @param[in] is_symmetric - true if the matrix is symmetric, false + otherwise * @param[in] is_expanded - true if the matrix is expanded (all non-zeros are stored explicitly, not assumed based on symmetry), false otherwise * @@ -95,12 +96,15 @@ namespace GridKit h_val_data[i] = static_cast(i + 1); } - if (A.setDataPointers(h_row_data, h_col_data, h_val_data, memory::HOST) != 0) + if (A.setDataPointers(h_row_data, h_col_data, h_val_data, memory::HOST) + != 0) { std::cout << "Failed to set data pointers.\n"; success = false; } - else if (A.getRowData(memory::HOST) != h_row_data || A.getColData(memory::HOST) != h_col_data || A.getValues(memory::HOST) != h_val_data) + else if (A.getRowData(memory::HOST) != h_row_data + || A.getColData(memory::HOST) != h_col_data + || A.getValues(memory::HOST) != h_val_data) { std::cout << "Data pointers do not point to expected values.\n"; success = false; @@ -246,10 +250,11 @@ namespace GridKit } /** - * @brief Verify that matrix will not reset data pointers when it currently owns data. + * @brief Verify that matrix will not reset data pointers when it + * currently owns data. * - * Copies values into the sparse matrix and then attempts to set the values - * pointer, which should fail since the matrix owns the data. + * Copies values into the sparse matrix and then attempts to set the + * values pointer, which should fail since the matrix owns the data. * * @param[in] n - number of rows * @param[in] m - number of columns @@ -290,7 +295,8 @@ namespace GridKit if (A.setDataPointers(row_data, col_data, val_data, memspace_) == 0) { - std::cout << "Should not have set data pointers after copying values.\n"; + std::cout + << "Should not have set data pointers after copying values.\n"; success = false; } @@ -303,10 +309,11 @@ namespace GridKit } /** - * @brief Verify that matrix will not reset values pointer when it currently owns data. + * @brief Verify that matrix will not reset values pointer when it + * currently owns data. * - * Copies a data array using `copyValues`, then attempts to set the values pointer, - * and verifies that this results in an error. + * Copies a data array using `copyValues`, then attempts to set the values + * pointer, and verifies that this results in an error. * * @param[in] n - number of rows * @param[in] m - number of columns @@ -336,7 +343,8 @@ namespace GridKit if (A.setValuesPointer(val_data, memspace_) == 0) { - std::cout << "Should not have set values pointer when matrix owns data.\n"; + std::cout + << "Should not have set values pointer when matrix owns data.\n"; success = false; } @@ -372,7 +380,9 @@ namespace GridKit std::cout << "Failed to allocate matrix data.\n"; success = false; } - else if (A.getRowData(memspace_) == nullptr || A.getColData(memspace_) == nullptr || A.getValues(memspace_) == nullptr) + else if (A.getRowData(memspace_) == nullptr + || A.getColData(memspace_) == nullptr + || A.getValues(memspace_) == nullptr) { std::cout << "Matrix data pointers are null after allocation.\n"; success = false; @@ -383,7 +393,9 @@ namespace GridKit std::cout << "Failed to destroy matrix data.\n"; success = false; } - else if (A.getRowData(memspace_) != nullptr || A.getColData(memspace_) != nullptr || A.getValues(memspace_) != nullptr) + else if (A.getRowData(memspace_) != nullptr + || A.getColData(memspace_) != nullptr + || A.getValues(memspace_) != nullptr) { std::cout << "Matrix data pointers are not null after destruction.\n"; success = false; diff --git a/tests/UnitTests/LinearAlgebra/SparseMatrix/runSparseCooTests.cpp b/tests/UnitTests/LinearAlgebra/SparseMatrix/runSparseCooTests.cpp index 5db4b23a7c..54e8283ec4 100644 --- a/tests/UnitTests/LinearAlgebra/SparseMatrix/runSparseCooTests.cpp +++ b/tests/UnitTests/LinearAlgebra/SparseMatrix/runSparseCooTests.cpp @@ -16,7 +16,11 @@ using namespace Testing; * @param[out] result - test results */ template -void runTests(const std::string& backend, memory::MemorySpace memspace, TestingResults& result) +void runTests( + const std::string& backend, + memory::MemorySpace memspace, + TestingResults& result +) { Log::misc() << "Running tests on " << backend << ":\n"; diff --git a/tests/UnitTests/LinearAlgebra/SparseMatrix/runSparseCsrTests.cpp b/tests/UnitTests/LinearAlgebra/SparseMatrix/runSparseCsrTests.cpp index dff6b0abc3..031a2b4897 100644 --- a/tests/UnitTests/LinearAlgebra/SparseMatrix/runSparseCsrTests.cpp +++ b/tests/UnitTests/LinearAlgebra/SparseMatrix/runSparseCsrTests.cpp @@ -15,7 +15,11 @@ using namespace Testing; * @param[out] result - test results */ template -void runTests(const std::string& backend, memory::MemorySpace memspace, TestingResults& result) +void runTests( + const std::string& backend, + memory::MemorySpace memspace, + TestingResults& result +) { Log::misc() << "Running tests on " << backend << ":\n"; diff --git a/tests/UnitTests/LinearAlgebra/Vector/VectorHandlerTests.hpp b/tests/UnitTests/LinearAlgebra/Vector/VectorHandlerTests.hpp index f63de9030c..ea9c39615b 100644 --- a/tests/UnitTests/LinearAlgebra/Vector/VectorHandlerTests.hpp +++ b/tests/UnitTests/LinearAlgebra/Vector/VectorHandlerTests.hpp @@ -22,9 +22,11 @@ namespace GridKit class VectorHandlerTests { public: - VectorHandlerTests(VectorHandler& handler, memory::MemorySpace memspace = memory::HOST) - : handler_(handler), - memspace_(memspace) + VectorHandlerTests( + VectorHandler& handler, + memory::MemorySpace memspace = memory::HOST + ) + : handler_(handler), memspace_(memspace) { } @@ -59,7 +61,8 @@ namespace GridKit x.copyFromExternal(data, memory::HOST, memspace_); ScalarT result = handler_.amax(&x, memspace_); - ScalarT answer = static_cast(N - 1) * static_cast(0.1); + ScalarT answer = + static_cast(N - 1) * static_cast(0.1); if (!isEqual(result, answer)) { @@ -154,7 +157,8 @@ namespace GridKit } /** - * @brief Test mass (bulk) axpy: y = y - x*alpha, where x is [N x K] and alpha is [K x 1]. + * @brief Test mass (bulk) axpy: y = y - x*alpha, where x is [N x K] and + * alpha is [K x 1]. */ TestOutcome axpyMulti(IdxT N, IdxT K) { @@ -254,9 +258,11 @@ namespace GridKit ScalarT alpha = -1.0; ScalarT beta = 1.0; handler_.gemv('N', K, alpha, beta, &V, &yN, &xN, memspace_); - status *= verifyAnswer(xN, static_cast(K) + static_cast(0.5)); + status *= + verifyAnswer(xN, static_cast(K) + static_cast(0.5)); handler_.gemv('T', K, alpha, beta, &V, &yT, &xT, memspace_); - status *= verifyAnswer(xT, static_cast(N) + static_cast(0.5)); + status *= + verifyAnswer(xT, static_cast(N) + static_cast(0.5)); return status.report(__func__); } @@ -295,10 +301,14 @@ namespace GridKit for (IdxT i = 0; i < N; ++i) { - if (!isEqual(vec.getData(memory::HOST)[i], static_cast(i + 1) * 3.0)) + if (!isEqual( + vec.getData(memory::HOST)[i], static_cast(i + 1) * 3.0 + )) { - std::cout << "Solution vector element vec[" << i << "] = " << vec.getData(memory::HOST)[i] - << ", expected: " << static_cast(i + 1) * 3.0 << "\n"; + std::cout << "Solution vector element vec[" << i + << "] = " << vec.getData(memory::HOST)[i] + << ", expected: " << static_cast(i + 1) * 3.0 + << "\n"; status *= false; break; } @@ -344,10 +354,16 @@ namespace GridKit for (IdxT i = 0; i < N; ++i) { - if (!isEqual(vec.getData(memory::HOST)[i], static_cast(3.0) / static_cast(i + 1))) + if (!isEqual( + vec.getData(memory::HOST)[i], + static_cast(3.0) / static_cast(i + 1) + )) { - std::cout << "Solution vector element vec[" << i << "] = " << vec.getData(memory::HOST)[i] - << ", expected: " << static_cast(3.0) / static_cast(i + 1) << "\n"; + std::cout << "Solution vector element vec[" << i + << "] = " << vec.getData(memory::HOST)[i] + << ", expected: " + << static_cast(3.0) / static_cast(i + 1) + << "\n"; status *= false; break; } @@ -405,7 +421,8 @@ namespace GridKit { if (!isEqual(y.getData(memory::HOST)[i], static_cast(i + 1))) { - std::cout << "Solution vector element y[" << i << "] = " << y.getData(memory::HOST)[i] + std::cout << "Solution vector element y[" << i + << "] = " << y.getData(memory::HOST)[i] << ", expected: " << static_cast(i + 1) << "\n"; status *= false; break; @@ -413,7 +430,8 @@ namespace GridKit if (!isEqual(z.getData(memory::HOST)[i], static_cast(i + 1))) { - std::cout << "Solution vector element z[" << i << "] = " << z.getData(memory::HOST)[i] + std::cout << "Solution vector element z[" << i + << "] = " << z.getData(memory::HOST)[i] << ", expected: " << static_cast(i + 1) << "\n"; status *= false; break; @@ -466,7 +484,8 @@ namespace GridKit { if (!isEqual(x.getData(memory::HOST)[i], static_cast(i))) { - std::cout << "Solution vector element x[" << i << "] = " << x.getData(memory::HOST)[i] + std::cout << "Solution vector element x[" << i + << "] = " << x.getData(memory::HOST)[i] << ", expected: " << static_cast(i) << "\n"; status *= false; break; @@ -474,7 +493,8 @@ namespace GridKit if (!isEqual(y.getData(memory::HOST)[i], static_cast(i))) { - std::cout << "Solution vector element y[" << i << "] = " << y.getData(memory::HOST)[i] + std::cout << "Solution vector element y[" << i + << "] = " << y.getData(memory::HOST)[i] << ", expected: " << static_cast(i) << "\n"; status *= false; break; @@ -488,7 +508,8 @@ namespace GridKit VectorHandler& handler_; memory::MemorySpace memspace_{memory::HOST}; - // We could verify through norm but that would defeat the purpose of testing vector handler. + // We could verify through norm but that would defeat the purpose of + // testing vector handler. bool verifyAnswer(Vector& x, ScalarT answer) { bool success = true; @@ -504,7 +525,8 @@ namespace GridKit { std::cout << std::setprecision(16); success = false; - std::cout << "Solution vector element x[" << i << "] = " << x.getData(memory::HOST)[i] + std::cout << "Solution vector element x[" << i + << "] = " << x.getData(memory::HOST)[i] << ", expected: " << answer << "\n"; break; } diff --git a/tests/UnitTests/LinearAlgebra/Vector/VectorTests.hpp b/tests/UnitTests/LinearAlgebra/Vector/VectorTests.hpp index 3edcdc0f88..a0ae6fc015 100644 --- a/tests/UnitTests/LinearAlgebra/Vector/VectorTests.hpp +++ b/tests/UnitTests/LinearAlgebra/Vector/VectorTests.hpp @@ -36,7 +36,8 @@ namespace GridKit } /** - * @brief Test vector constructor with specified size and number of vectors. + * @brief Test vector constructor with specified size and number of + * vectors. * * @param[in] N Number of elements in the vector. * @param[in] k Number of vectors in the multivector. @@ -65,8 +66,8 @@ namespace GridKit if (x.getNumVectors() != k) { - std::cout << "The number of vectors in the multivector is " << x.getNumVectors() - << ", expected: " << k << "\n"; + std::cout << "The number of vectors in the multivector is " + << x.getNumVectors() << ", expected: " << k << "\n"; status *= false; } @@ -74,7 +75,8 @@ namespace GridKit } /** - * @brief Test vector constructor with specified size and default number of vectors (1). + * @brief Test vector constructor with specified size and default number + * of vectors (1). * * @param[in] N Number of elements in the vector. * @return TestOutcome indicating success or failure of the test. @@ -103,8 +105,8 @@ namespace GridKit if (x.getSize() != new_N) { - std::cout << "The size of the vector after resizing is " << x.getSize() - << ", expected: " << new_N << "\n"; + std::cout << "The size of the vector after resizing is " + << x.getSize() << ", expected: " << new_N << "\n"; status *= false; } @@ -112,7 +114,8 @@ namespace GridKit } /** - * @brief Test that resizing an empty vector allocates initialized HOST data. + * @brief Test that resizing an empty vector allocates initialized HOST + * data. */ TestOutcome resizeEmpty(IdxT N) { @@ -166,8 +169,8 @@ namespace GridKit if (!isEqual(x_data[i], data[i])) { std::cout << "The data in the vector is incorrect at index " << i - << ", expected: " << data[i] - << ", got: " << x_data[i] << "\n"; + << ", expected: " << data[i] << ", got: " << x_data[i] + << "\n"; status *= false; break; } @@ -207,14 +210,15 @@ namespace GridKit // Owned vector storage must not be replaced by external storage. const auto previous_verbosity = Log::verbosity(); Log::setVerbosity(Log::Verbosity::EVERYTHING); - Log::misc() << "Testing that owned vector storage cannot be replaced by external storage. " + Log::misc() << "Testing that owned vector storage cannot be replaced " + "by external storage. " << "Logged errors are expected.\n"; Log::setVerbosity(previous_verbosity); Vector owned(N); status *= owned.allocate(memory::HOST) == 0; auto* const owned_data = owned.getData(memory::HOST); - status *= owned.setData(initial_storage, N, memory::HOST) != 0; - status *= owned.getData(memory::HOST) == owned_data; + status *= owned.setData(initial_storage, N, memory::HOST) != 0; + status *= owned.getData(memory::HOST) == owned_data; delete[] initial_storage; delete[] replacement_storage; @@ -224,10 +228,10 @@ namespace GridKit /** * @brief Test copying data between vector-array and vector-vector. * - * This creates an array, copies it to a vector in the current memory space, then - * copies it to another vector in the same memory space, and finally back to a third on the - * HOST. Then, it verifies the content of the final vector. This test only passes if all - * copies are successful. + * This creates an array, copies it to a vector in the current memory + * space, then copies it to another vector in the same memory space, and + * finally back to a third on the HOST. Then, it verifies the content of + * the final vector. This test only passes if all copies are successful. * * @param[in] N Number of elements in the vector. * @return TestOutcome indicating success or failure of the test. @@ -271,9 +275,9 @@ namespace GridKit { if (!isEqual(z_data[i], data[i])) { - std::cout << "The data in the copied vector is incorrect at index " << i - << ", expected: " << data[i] - << ", got: " << z_data[i] << "\n"; + std::cout + << "The data in the copied vector is incorrect at index " << i + << ", expected: " << data[i] << ", got: " << z_data[i] << "\n"; status *= false; break; } @@ -287,9 +291,9 @@ namespace GridKit /** * @brief Test copying data from vector to an array. * - * This creates a vector, copies data to it, and then copies the data to an array - * in the current memory space. Finally, it uses the MemoryManager to copy the data - * to HOST for verification. + * This creates a vector, copies data to it, and then copies the data to + * an array in the current memory space. Finally, it uses the + * MemoryManager to copy the data to HOST for verification. * * @param[in] N Number of elements in the vector. * @return TestOutcome indicating success or failure of the test. @@ -332,9 +336,9 @@ namespace GridKit { if (!isEqual(dest_h[i], data[i])) { - std::cout << "The data in the destination array is incorrect at index " << i - << ", expected: " << data[i] - << ", got: " << dest_h[i] << "\n"; + std::cout + << "The data in the destination array is incorrect at index " << i + << ", expected: " << data[i] << ", got: " << dest_h[i] << "\n"; status *= false; break; } @@ -451,7 +455,8 @@ namespace GridKit { std::cout << std::setprecision(16); success = false; - std::cout << "Solution vector element x[" << i << "] = " << x.getData(memory::HOST)[i] + std::cout << "Solution vector element x[" << i + << "] = " << x.getData(memory::HOST)[i] << ", expected: " << answer << "\n"; break; } diff --git a/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp b/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp index 3a4eb512f8..073ff0c45b 100644 --- a/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp +++ b/tests/UnitTests/Math/SmoothnessIndicatorTests.hpp @@ -17,9 +17,10 @@ namespace GridKit 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 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) { @@ -62,17 +63,25 @@ namespace GridKit const ScalarT tol = scalar(kSmoothTolerance); // Type 1 (no-offset) deadband returns ~0 inside the band ... - const ScalarT inside_input = scalar(0.02); - success *= (std::abs(Math::deadband1(inside_input, lower, upper)) < tol * tol); + const ScalarT inside_input = scalar(0.02); + success *= + (std::abs(Math::deadband1(inside_input, lower, upper)) < tol * tol); - // ... and passes the input through unchanged (no offset) outside the band. + // ... and passes the input through unchanged (no offset) outside the + // band. const ScalarT far_above_input = scalar(4.0); const ScalarT far_below_input = scalar(-4.0); - success *= std::isfinite(Math::deadband1(far_above_input, lower, upper)); - success *= within(Math::deadband1(far_above_input, lower, upper), far_above_input, tol); - success *= std::isfinite(Math::deadband1(far_below_input, lower, upper)); - success *= within(Math::deadband1(far_below_input, lower, upper), far_below_input, tol); + success *= + std::isfinite(Math::deadband1(far_above_input, lower, upper)); + success *= within( + Math::deadband1(far_above_input, lower, upper), far_above_input, tol + ); + success *= + std::isfinite(Math::deadband1(far_below_input, lower, upper)); + success *= within( + Math::deadband1(far_below_input, lower, upper), far_below_input, tol + ); return success.report(__func__); } @@ -91,9 +100,14 @@ namespace GridKit const ScalarT expected_below = below_input - lower; const ScalarT expected_above = above_input - upper; - success *= within(Math::deadband2(below_input, lower, upper), expected_below, tol); - success *= (std::abs(Math::deadband2(inside_input, lower, upper)) < tol * tol); - success *= within(Math::deadband2(above_input, lower, upper), expected_above, tol); + success *= within( + Math::deadband2(below_input, lower, upper), expected_below, tol + ); + success *= + (std::abs(Math::deadband2(inside_input, lower, upper)) < tol * tol); + success *= within( + Math::deadband2(above_input, lower, upper), expected_above, tol + ); const ScalarT lower_breakpoint = Math::deadband2(lower, lower, upper); const ScalarT upper_breakpoint = Math::deadband2(upper, lower, upper); @@ -103,7 +117,7 @@ namespace GridKit success *= (std::abs(lower_breakpoint) < tol); success *= (std::abs(upper_breakpoint) < tol); - const ScalarT x = scalar(-0.4); + const ScalarT x = scalar(-0.4); success *= (std::abs( Math::deadband2(x, lower, upper) @@ -116,14 +130,24 @@ namespace GridKit const ScalarT expected_far_above = far_above_input - upper; const ScalarT expected_far_below = far_below_input - lower; - success *= std::isfinite(Math::deadband2(far_above_input, lower, upper)); - success *= within(Math::deadband2(far_above_input, lower, upper), expected_far_above, tol); - success *= std::isfinite(Math::deadband2(far_below_input, lower, upper)); - success *= within(Math::deadband2(far_below_input, lower, upper), expected_far_below, tol); + success *= + std::isfinite(Math::deadband2(far_above_input, lower, upper)); + success *= within( + Math::deadband2(far_above_input, lower, upper), + expected_far_above, + tol + ); + success *= + std::isfinite(Math::deadband2(far_below_input, lower, upper)); + success *= within( + Math::deadband2(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); + const ScalarT point = scalar(0.25); + const ScalarT above_point = scalar(0.75); + const ScalarT below_point = scalar(-0.25); success *= (std::abs( Math::deadband2(above_point, point, point) - (above_point - point) @@ -153,14 +177,19 @@ namespace GridKit success *= (Math::below(scalar(3.2), limit_max) < near_zero); 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::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(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); + 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 = scalar(1.5); + const ScalarT x = scalar(1.5); success *= (std::abs( Math::inside(x, limit_min, limit_max) @@ -195,17 +224,26 @@ namespace GridKit 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); + 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); + 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__); } @@ -214,17 +252,17 @@ namespace GridKit { TestStatus success = true; - const ScalarT tol = scalar(kSmoothTolerance); - const ScalarT roundoff = scalar(kRoundoffTolerance); - const ScalarT tau = scalar(1.0 / Math::MU); - 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); + const ScalarT tol = scalar(kSmoothTolerance); + const ScalarT roundoff = scalar(kRoundoffTolerance); + const ScalarT tau = scalar(1.0 / Math::MU); + 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); @@ -267,8 +305,10 @@ namespace GridKit 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_state = + Math::max(state_below_bound, parameter_bound); + const auto upper_bounded_state = + Math::min(state_above_bound, parameter_bound); static_assert( std::is_same< @@ -283,11 +323,15 @@ namespace GridKit "Mixed-type min should keep the differentiable scalar type." ); - success *= (std::abs(lower_bounded_state.getValue() - parameter_bound) < kSmoothTolerance); - success *= (std::abs(upper_bounded_state.getValue() - parameter_bound) < kSmoothTolerance); + 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); + 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)) < scalar(kRoundoffTolerance)); @@ -320,20 +364,32 @@ namespace GridKit const ScalarT near_one = scalar(kNearOne); // 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); + 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, increasing dynamics are blocked. - success *= (Math::indicator(above_limit, f_positive, limit_min, limit_max) < near_zero); + success *= + (Math::indicator(above_limit, f_positive, limit_min, limit_max) + < near_zero); // Above the upper limit, decreasing dynamics restore the state. - success *= (Math::indicator(above_limit, f_negative, limit_min, limit_max) > near_one); + success *= + (Math::indicator(above_limit, f_negative, limit_min, limit_max) + > near_one); // Below the lower limit, decreasing dynamics are blocked. - success *= (Math::indicator(below_limit, f_negative, limit_min, limit_max) < near_zero); + success *= + (Math::indicator(below_limit, f_negative, limit_min, limit_max) + < near_zero); // Below the lower limit, increasing dynamics restore the state. - success *= (Math::indicator(below_limit, f_positive, limit_min, limit_max) > near_one); + success *= + (Math::indicator(below_limit, f_positive, limit_min, limit_max) + > near_one); return success.report(__func__); } @@ -360,13 +416,21 @@ namespace GridKit ) < scalar(kRoundoffTolerance)); - success *= (std::abs(Math::antiwindup(above_limit, f_positive, limit_min, limit_max)) < blocked_tolerance); + 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 *= + (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, diff --git a/tests/UnitTests/OptimalPowerFlow/ComponentTests.hpp b/tests/UnitTests/OptimalPowerFlow/ComponentTests.hpp index 2d709c2cd3..74116e9711 100644 --- a/tests/UnitTests/OptimalPowerFlow/ComponentTests.hpp +++ b/tests/UnitTests/OptimalPowerFlow/ComponentTests.hpp @@ -74,7 +74,8 @@ namespace GridKit success *= isEqual(g[BRANCH_BALANCE_ROWS[1]], -3.45, kTol); success *= isEqual(g[BRANCH_BALANCE_ROWS[2]], -7.6, kTol); success *= isEqual(g[BRANCH_BALANCE_ROWS[3]], -7.3, kTol); - success *= isEqual(g[BRANCH_FLOW_ROWS[0]], 3.9 * 3.9 + 3.45 * 3.45, kTol); + success *= + isEqual(g[BRANCH_FLOW_ROWS[0]], 3.9 * 3.9 + 3.45 * 3.45, kTol); success *= isEqual(g[BRANCH_FLOW_ROWS[1]], 7.6 * 7.6 + 7.3 * 7.3, kTol); return success.report(__func__); @@ -85,10 +86,10 @@ namespace GridKit { TestStatus success = true; - auto branch_owner = std::make_unique(branchData()); - auto& branch = *branch_owner; - auto system = branchSystem(std::move(branch_owner)); - success *= system.allocate() == 0 && system.initialize() == 0; + auto branch_owner = std::make_unique(branchData()); + auto& branch = *branch_owner; + auto system = branchSystem(std::move(branch_owner)); + success *= system.allocate() == 0 && system.initialize() == 0; if (!success) { return success.report(__func__); @@ -100,8 +101,10 @@ namespace GridKit return success.report(__func__); } - auto tracked = branchSystem(std::make_unique>(branchData())); - success *= tracked.allocate() == 0 && tracked.initialize() == 0; + auto tracked = branchSystem( + std::make_unique>(branchData()) + ); + success *= tracked.allocate() == 0 && tracked.initialize() == 0; if (!success) { return success.report(__func__); @@ -124,21 +127,23 @@ namespace GridKit { success *= isEqual(enzyme.at(row), g[row].getDependencies(), kTol); } - success *= enzyme.size() == BRANCH_FLOW_ROWS.size() + BRANCH_BALANCE_ROWS.size(); + success *= + enzyme.size() == BRANCH_FLOW_ROWS.size() + BRANCH_BALANCE_ROWS.size(); success *= branch.jacobianEntries().nnz == BRANCH_JACOBIAN_NNZ; return success.report(__func__); } - /// Enzyme Hessian entries equal the closed-form Cartesian second derivatives + /// Enzyme Hessian entries equal the closed-form Cartesian second + /// derivatives TestOutcome branchHessian() { TestStatus success = true; - auto branch_owner = std::make_unique(branchData()); - auto& branch = *branch_owner; - auto system = branchSystem(std::move(branch_owner)); - success *= system.allocate() == 0 && system.initialize() == 0; + auto branch_owner = std::make_unique(branchData()); + auto& branch = *branch_owner; + auto system = branchSystem(std::move(branch_owner)); + success *= system.allocate() == 0 && system.initialize() == 0; if (!success) { return success.report(__func__); @@ -153,12 +158,26 @@ namespace GridKit // Balances: P1, Q1, P2, Q2 EntryMap expected; - addPowerHessian(expected, 0, BUS1_ADMITTANCE, BRANCH_LAMBDA[BRANCH_BALANCE_ROWS[0]], BRANCH_LAMBDA[BRANCH_BALANCE_ROWS[1]]); - addPowerHessian(expected, 1, BUS2_ADMITTANCE, BRANCH_LAMBDA[BRANCH_BALANCE_ROWS[2]], BRANCH_LAMBDA[BRANCH_BALANCE_ROWS[3]]); + addPowerHessian( + expected, + 0, + BUS1_ADMITTANCE, + BRANCH_LAMBDA[BRANCH_BALANCE_ROWS[0]], + BRANCH_LAMBDA[BRANCH_BALANCE_ROWS[1]] + ); + addPowerHessian( + expected, + 1, + BUS2_ADMITTANCE, + BRANCH_LAMBDA[BRANCH_BALANCE_ROWS[2]], + BRANCH_LAMBDA[BRANCH_BALANCE_ROWS[3]] + ); // Flows: |S|^2 = P^2 + Q^2 by the chain rule over tracked gradients - auto tracked = branchSystem(std::make_unique>(branchData())); - success *= tracked.allocate() == 0 && tracked.initialize() == 0; + auto tracked = branchSystem( + std::make_unique>(branchData()) + ); + success *= tracked.allocate() == 0 && tracked.initialize() == 0; if (!success) { return success.report(__func__); @@ -173,16 +192,29 @@ namespace GridKit const VariableT* g = tracked.g().getData(); for (IdxT port = 0; port < 2; ++port) { - const RealT weight = TWO * BRANCH_LAMBDA[BRANCH_FLOW_ROWS[port]]; - const VariableT p = g[BRANCH_BALANCE_ROWS[2 * port]]; - const VariableT q = g[BRANCH_BALANCE_ROWS[1 + 2 * port]]; + const RealT weight = + TWO * BRANCH_LAMBDA[BRANCH_FLOW_ROWS[port]]; + const VariableT p = g[BRANCH_BALANCE_ROWS[2 * port]]; + const VariableT q = g[BRANCH_BALANCE_ROWS[1 + 2 * port]]; addOuterProduct(expected, p.getDependencies(), weight); addOuterProduct(expected, q.getDependencies(), weight); } const RealT weight1 = TWO * BRANCH_LAMBDA[BRANCH_FLOW_ROWS[0]]; const RealT weight2 = TWO * BRANCH_LAMBDA[BRANCH_FLOW_ROWS[1]]; - addPowerHessian(expected, 0, BUS1_ADMITTANCE, weight1 * g[BRANCH_BALANCE_ROWS[0]].getValue(), weight1 * g[BRANCH_BALANCE_ROWS[1]].getValue()); - addPowerHessian(expected, 1, BUS2_ADMITTANCE, weight2 * g[BRANCH_BALANCE_ROWS[2]].getValue(), weight2 * g[BRANCH_BALANCE_ROWS[3]].getValue()); + addPowerHessian( + expected, + 0, + BUS1_ADMITTANCE, + weight1 * g[BRANCH_BALANCE_ROWS[0]].getValue(), + weight1 * g[BRANCH_BALANCE_ROWS[1]].getValue() + ); + addPowerHessian( + expected, + 1, + BUS2_ADMITTANCE, + weight2 * g[BRANCH_BALANCE_ROWS[2]].getValue(), + weight2 * g[BRANCH_BALANCE_ROWS[3]].getValue() + ); success *= matches(sum(branch.hessianEntries()), expected, kTol); success *= branch.hessianEntries().nnz == BRANCH_HESSIAN_NNZ; @@ -196,10 +228,10 @@ namespace GridKit { TestStatus success = true; - auto active_owner = std::make_unique(branchData()); - auto& active_branch = *active_owner; - auto active = branchSystem(std::move(active_owner)); - success *= active.allocate() == 0 && active.initialize() == 0; + auto active_owner = std::make_unique(branchData()); + auto& active_branch = *active_owner; + auto active = branchSystem(std::move(active_owner)); + success *= active.allocate() == 0 && active.initialize() == 0; if (!success) { return success.report(__func__); @@ -215,10 +247,10 @@ namespace GridKit auto data = branchData(); data.parameters[OPF::BranchParameters::in_service] = false; - auto branch_owner = std::make_unique(data); - auto& branch = *branch_owner; - auto system = branchSystem(std::move(branch_owner)); - success *= system.allocate() == 0 && system.initialize() == 0; + auto branch_owner = std::make_unique(data); + auto& branch = *branch_owner; + auto system = branchSystem(std::move(branch_owner)); + success *= system.allocate() == 0 && system.initialize() == 0; if (!success) { return success.report(__func__); @@ -233,8 +265,10 @@ namespace GridKit return success.report(__func__); } - success *= pattern(branch.jacobianEntries()) == pattern(active_branch.jacobianEntries()); - success *= pattern(branch.hessianEntries()) == pattern(active_branch.hessianEntries()); + success *= pattern(branch.jacobianEntries()) + == pattern(active_branch.jacobianEntries()); + success *= pattern(branch.hessianEntries()) + == pattern(active_branch.hessianEntries()); success *= branch.jacobianEntries().nnz == BRANCH_JACOBIAN_NNZ; success *= branch.hessianEntries().nnz == BRANCH_HESSIAN_NNZ; for (const RealT value : values(branch.jacobianEntries())) @@ -254,17 +288,19 @@ namespace GridKit { TestStatus success = true; - auto bus_owner = std::make_unique>(busData(1)); - auto& bus = *bus_owner; - auto generator_owner = std::make_unique>(generatorData()); - auto& generator = *generator_owner; - success *= generator.connect(0, bus) == 0; + auto bus_owner = std::make_unique>(busData(1)); + auto& bus = *bus_owner; + auto generator_owner = + std::make_unique>(generatorData()); + auto& generator = *generator_owner; + success *= generator.connect(0, bus) == 0; if (!success) { return success.report(__func__); } - auto system = makeSystem(std::move(generator_owner), std::move(bus_owner)); - success *= system.allocate() == 0 && system.initialize() == 0; + auto system = + makeSystem(std::move(generator_owner), std::move(bus_owner)); + success *= system.allocate() == 0 && system.initialize() == 0; if (!success) { return success.report(__func__); @@ -300,14 +336,19 @@ namespace GridKit { return success.report(__func__); } - success *= isEqual(system.gradient().getData()[0], C1 + TWO * C2 * p); + success *= + isEqual(system.gradient().getData()[0], C1 + TWO * C2 * p); success *= generator.evaluateJacobian() == 0; if (!success) { return success.report(__func__); } - success *= matches(sum(generator.jacobianEntries()), EntryMap{{{0, 0}, ONE}, {{1, 1}, ONE}}, kTol); + success *= matches( + sum(generator.jacobianEntries()), + EntryMap{{{0, 0}, ONE}, {{1, 1}, ONE}}, + kTol + ); const std::vector lambda(system.sizeConstraints(), ONE); setMultipliers(system, lambda); @@ -316,12 +357,17 @@ namespace GridKit { return success.report(__func__); } - success *= matches(sum(generator.hessianEntries()), EntryMap{{{0, 0}, TWO * C2 * SIGMA}}, kTol); + success *= matches( + sum(generator.hessianEntries()), + EntryMap{{{0, 0}, TWO * C2 * SIGMA}}, + kTol + ); return success.report(__func__); } - /// An out-of-service generator is fixed at zero with no cost and the same entries + /// An out-of-service generator is fixed at zero with no cost and the same + /// entries TestOutcome outOfServiceGenerator() { TestStatus success = true; @@ -329,17 +375,19 @@ namespace GridKit auto data = generatorData(); data.parameters[OPF::GeneratorParameters::in_service] = false; - auto bus_owner = std::make_unique>(busData(1)); - auto& bus = *bus_owner; - auto generator_owner = std::make_unique>(data); - auto& generator = *generator_owner; - success *= generator.connect(0, bus) == 0; + auto bus_owner = std::make_unique>(busData(1)); + auto& bus = *bus_owner; + auto generator_owner = + std::make_unique>(data); + auto& generator = *generator_owner; + success *= generator.connect(0, bus) == 0; if (!success) { return success.report(__func__); } - auto system = makeSystem(std::move(generator_owner), std::move(bus_owner)); - success *= system.allocate() == 0 && system.initialize() == 0; + auto system = + makeSystem(std::move(generator_owner), std::move(bus_owner)); + success *= system.allocate() == 0 && system.initialize() == 0; if (!success) { return success.report(__func__); @@ -348,8 +396,10 @@ namespace GridKit const RealT* lower = system.xLower().getData(); const RealT* upper = system.xUpper().getData(); - success *= isEqual(lower[0], ZERO) && isEqual(upper[0], ZERO); - success *= isEqual(lower[1], ZERO) && isEqual(upper[1], ZERO); + success *= + isEqual(lower[0], ZERO) && isEqual(upper[0], ZERO); + success *= + isEqual(lower[1], ZERO) && isEqual(upper[1], ZERO); setVariables(system, GENERATOR_X); success *= generator.evaluateObjective() == 0; @@ -371,7 +421,8 @@ namespace GridKit return success.report(__func__); } - /// The bus shunt adds its power to the balance, with derivatives in closed form + /// The bus shunt adds its power to the balance, with derivatives in + /// closed form TestOutcome busShunt() { TestStatus success = true; @@ -426,9 +477,14 @@ namespace GridKit { return success.report(__func__); } - const RealT hessian = TWO * (-SHUNT_G * SHUNT_LAMBDA[0] + SHUNT_B * SHUNT_LAMBDA[1]); + const RealT hessian = + TWO * (-SHUNT_G * SHUNT_LAMBDA[0] + SHUNT_B * SHUNT_LAMBDA[1]); - success *= matches(sum(bus.hessianEntries()), EntryMap{{{0, 0}, hessian}, {{1, 1}, hessian}}, kTol); + success *= matches( + sum(bus.hessianEntries()), + EntryMap{{{0, 0}, hessian}, {{1, 1}, hessian}}, + kTol + ); return success.report(__func__); } @@ -461,17 +517,22 @@ namespace GridKit success *= isEqual(x[0], ONE) && isEqual(x[1], ZERO); for (IdxT j = 0; j < system.size(); ++j) { - success *= std::isinf(system.xLower().getData()[j]) && std::isinf(system.xUpper().getData()[j]); + success *= std::isinf(system.xLower().getData()[j]) + && std::isinf(system.xUpper().getData()[j]); } - // The balance is an equality at zero, and the squared magnitude an inequality within the limits + // The balance is an equality at zero, and the squared magnitude an + // inequality within the limits const RealT* g_lower = system.gLower().getData(); const RealT* g_upper = system.gUpper().getData(); success *= system.sizeConstraints() == 3; - success *= system.tag() == std::vector{false, false, true}; - success *= isEqual(g_lower[0], ZERO) && isEqual(g_upper[0], ZERO); - success *= isEqual(g_lower[1], ZERO) && isEqual(g_upper[1], ZERO); - success *= isEqual(g_lower[2], VMIN * VMIN) && isEqual(g_upper[2], VMAX * VMAX); + success *= system.tag() == std::vector{false, false, true}; + success *= + isEqual(g_lower[0], ZERO) && isEqual(g_upper[0], ZERO); + success *= + isEqual(g_lower[1], ZERO) && isEqual(g_upper[1], ZERO); + success *= + isEqual(g_lower[2], VMIN * VMIN) && isEqual(g_upper[2], VMAX * VMAX); setVariables(system, BUS_X); const RealT vr = BUS_X[0]; @@ -482,9 +543,9 @@ namespace GridKit { return success.report(__func__); } - const RealT* g = system.g().getData(); - success *= isEqual(g[0], ZERO) && isEqual(g[1], ZERO); - success *= isEqual(g[2], vr * vr + vi * vi); + const RealT* g = system.g().getData(); + success *= isEqual(g[0], ZERO) && isEqual(g[1], ZERO); + success *= isEqual(g[2], vr * vr + vi * vi); success *= bus.evaluateJacobian() == 0; if (!success) @@ -513,18 +574,26 @@ namespace GridKit } const RealT hessian = TWO * BUS_LAMBDA[2]; - success *= matches(sum(bus.hessianEntries()), EntryMap{{{0, 0}, hessian}, {{1, 1}, hessian}}, kTol); + success *= matches( + sum(bus.hessianEntries()), + EntryMap{{{0, 0}, hessian}, {{1, 1}, hessian}}, + kTol + ); - data.parameters[OPF::BusParameters::reference] = true; - auto reference_owner = std::make_unique>(data); - auto reference_system = makeSystem(std::move(reference_owner)); - success *= reference_system.allocate() == 0 && reference_system.initialize() == 0; + data.parameters[OPF::BusParameters::reference] = true; + auto reference_owner = std::make_unique>(data); + auto reference_system = makeSystem(std::move(reference_owner)); + success *= reference_system.allocate() == 0 + && reference_system.initialize() == 0; if (!success) { return success.report(__func__); } - success *= std::isinf(reference_system.xLower().getData()[0]) && std::isinf(reference_system.xUpper().getData()[0]); - success *= isEqual(reference_system.xLower().getData()[1], ZERO) && isEqual(reference_system.xUpper().getData()[1], ZERO); + success *= std::isinf(reference_system.xLower().getData()[0]) + && std::isinf(reference_system.xUpper().getData()[0]); + success *= + isEqual(reference_system.xLower().getData()[1], ZERO) + && isEqual(reference_system.xUpper().getData()[1], ZERO); return success.report(__func__); } @@ -540,22 +609,27 @@ namespace GridKit data.parameters[OPF::LoadParameters::P] = LOAD_P; data.parameters[OPF::LoadParameters::Q] = LOAD_Q; - auto bus_owner = std::make_unique>(busData(2)); - auto& bus = *bus_owner; - auto load_owner = std::make_unique>(data); - auto& load = *load_owner; - data.id = "load_2_out_of_service"; - data.parameters[OPF::LoadParameters::in_service] = false; - auto out_of_service_owner = std::make_unique>(data); - auto& out_of_service = *out_of_service_owner; - success *= load.connect(0, bus) == 0; - success *= out_of_service.connect(0, bus) == 0; + auto bus_owner = std::make_unique>(busData(2)); + auto& bus = *bus_owner; + auto load_owner = std::make_unique>(data); + auto& load = *load_owner; + data.id = "load_2_out_of_service"; + data.parameters[OPF::LoadParameters::in_service] = false; + auto out_of_service_owner = + std::make_unique>(data); + auto& out_of_service = *out_of_service_owner; + success *= load.connect(0, bus) == 0; + success *= out_of_service.connect(0, bus) == 0; if (!success) { return success.report(__func__); } - auto system = makeSystem(std::move(load_owner), std::move(out_of_service_owner), std::move(bus_owner)); - success *= system.allocate() == 0 && system.initialize() == 0; + auto system = makeSystem( + std::move(load_owner), + std::move(out_of_service_owner), + std::move(bus_owner) + ); + success *= system.allocate() == 0 && system.initialize() == 0; if (!success) { return success.report(__func__); @@ -614,19 +688,29 @@ namespace GridKit { return success.report(__func__); } - const RealT v2 = voltage[0] * voltage[0] + voltage[1] * voltage[1]; - const RealT v = std::sqrt(v2); - const RealT u = status(in_service); - - success *= isEqual(system.g().getData()[0], -u * (LOAD_P + zip.Pi * v + zip.Pz * v2), kTol); - success *= isEqual(system.g().getData()[1], -u * (LOAD_Q + zip.Qi * v + zip.Qz * v2), kTol); + const RealT v2 = + voltage[0] * voltage[0] + voltage[1] * voltage[1]; + const RealT v = std::sqrt(v2); + const RealT u = status(in_service); + + success *= isEqual( + system.g().getData()[0], + -u * (LOAD_P + zip.Pi * v + zip.Pz * v2), + kTol + ); + success *= isEqual( + system.g().getData()[1], + -u * (LOAD_Q + zip.Qi * v + zip.Qz * v2), + kTol + ); } } } return success.report(__func__); } - /// Enzyme Jacobian entries equal the dependency-tracking and closed-form derivatives + /// Enzyme Jacobian entries equal the dependency-tracking and closed-form + /// derivatives TestOutcome loadJacobian() { TestStatus success = true; @@ -634,11 +718,11 @@ namespace GridKit { for (const ZipParts& zip : ZIP_PARTS) { - const auto data = loadData(in_service, zip); - auto system = loadSystem(data); - auto tracked = loadSystem(data); - success *= system.allocate() == 0 && system.initialize() == 0; - success *= tracked.allocate() == 0 && tracked.initialize() == 0; + const auto data = loadData(in_service, zip); + auto system = loadSystem(data); + auto tracked = loadSystem(data); + success *= system.allocate() == 0 && system.initialize() == 0; + success *= tracked.allocate() == 0 && tracked.initialize() == 0; if (!success) { return success.report(__func__); @@ -658,7 +742,8 @@ namespace GridKit const RealT v = std::hypot(voltage[0], voltage[1]); const RealT u = status(in_service); - // Derivative of the demand over each voltage component, divided by that component + // Derivative of the demand over each voltage component, divided + // by that component const std::array slope{ u * (zip.Pi / v + TWO * zip.Pz), u * (zip.Qi / v + TWO * zip.Qz) @@ -666,7 +751,13 @@ namespace GridKit for (IdxT row = 0; row < slope.size(); ++row) { success *= isEqual(actual.at(row), expected.at(row), kTol); - success *= isEqual(actual.at(row), DependencyMap{{0, -slope[row] * voltage[0]}, {1, -slope[row] * voltage[1]}}, kTol); + success *= isEqual( + actual.at(row), + DependencyMap{ + {0, -slope[row] * voltage[0]}, {1, -slope[row] * voltage[1]} + }, + kTol + ); } } } @@ -703,8 +794,13 @@ namespace GridKit const RealT v2 = vr * vr + vi * vi; const RealT v3 = v2 * std::sqrt(v2); - const DependencyMap row0{{0, current * vi * vi / v3 + TWO * impedance}}; - const DependencyMap row1{{0, -current * vr * vi / v3}, {1, current * vr * vr / v3 + TWO * impedance}}; + const DependencyMap row0{ + {0, current * vi * vi / v3 + TWO * impedance} + }; + const DependencyMap row1{ + {0, -current * vr * vi / v3}, + {1, current * vr * vr / v3 + TWO * impedance} + }; const auto actual = MapFromCsr(system.getCsrHessian()); success *= isEqual(actual.at(0), row0, kTol); @@ -715,7 +811,8 @@ namespace GridKit return success.report(__func__); } - /// Demands are finite reals, integers count as reals, and the service status is a boolean + /// Demands are finite reals, integers count as reals, and the service + /// status is a boolean TestOutcome loadConfiguration() { TestStatus success = true; @@ -733,17 +830,21 @@ namespace GridKit OPF::LoadParameters::Pz, OPF::LoadParameters::Qz}) { - data.parameters = {{parameter, std::numeric_limits::infinity()}}; - success *= configurationRejected([&]() - { return OPF::Load(data).verify(); }); + data.parameters = {{parameter, std::numeric_limits::infinity()} + }; + success *= configurationRejected( + [&]() { return OPF::Load(data).verify(); } + ); data.parameters = {{parameter, true}}; - success *= configurationRejected([&]() - { return OPF::Load(data).verify(); }); + success *= configurationRejected( + [&]() { return OPF::Load(data).verify(); } + ); } data.parameters = {{OPF::LoadParameters::in_service, IdxT{1}}}; - success *= configurationRejected([&]() - { return OPF::Load(data).verify(); }); + success *= configurationRejected( + [&]() { return OPF::Load(data).verify(); } + ); return success.report(__func__); } @@ -758,7 +859,8 @@ namespace GridKit RealT Qz; }; - /// Constant power only, constant current, constant impedance, and all three parts + /// Constant power only, constant current, constant impedance, and all + /// three parts static constexpr std::array ZIP_PARTS{ {{0.0, 0.0, 0.0, 0.0}, {0.5, -0.2, 0.0, 0.0}, @@ -766,10 +868,14 @@ namespace GridKit {0.4, 0.15, 0.25, -0.05}} }; - static constexpr std::array, 3> ZIP_VOLTAGES{{{1.1, 0.0}, {0.8, -0.6}, {1.15, 0.2}}}; - static constexpr std::array LOAD_LAMBDA{0.7, -0.4, 0.0}; + static constexpr std::array, 3> ZIP_VOLTAGES{ + {{1.1, 0.0}, {0.8, -0.6}, {1.15, 0.2}} + }; + static constexpr std::array LOAD_LAMBDA{0.7, -0.4, 0.0}; - static OPF::LoadData loadData(bool in_service, const ZipParts& zip) + static OPF::LoadData loadData( + bool in_service, const ZipParts& zip + ) { OPF::LoadData data; data.id = "zip"; @@ -795,8 +901,11 @@ namespace GridKit return ZERO; } - /// Multiplier-weighted constant-current and constant-impedance demands, signed as power into the bus - static std::pair loadWeights(bool in_service, const ZipParts& zip) + /// Multiplier-weighted constant-current and constant-impedance demands, + /// signed as power into the bus + static std::pair loadWeights( + bool in_service, const ZipParts& zip + ) { const RealT u = status(in_service); return { @@ -806,7 +915,9 @@ namespace GridKit } template - static OPF::SystemModel loadSystem(const OPF::LoadData& data) + static OPF::SystemModel loadSystem( + const OPF::LoadData& data + ) { auto bus = std::make_unique>(busData(1)); auto load = std::make_unique>(data); @@ -818,8 +929,9 @@ namespace GridKit } template - static OPF::SystemModel - branchSystem(std::unique_ptr> branch) + static OPF::SystemModel branchSystem( + std::unique_ptr> branch + ) { auto bus1 = std::make_unique>(busData(1)); auto bus2 = std::make_unique>(busData(2)); @@ -827,7 +939,9 @@ namespace GridKit { throw std::invalid_argument("Invalid branch test connections"); } - return makeSystem(std::move(branch), std::move(bus1), std::move(bus2)); + return makeSystem( + std::move(branch), std::move(bus1), std::move(bus2) + ); } static constexpr const char* BRANCH_ID = "branch_1_2"; @@ -844,10 +958,15 @@ namespace GridKit /// Admittances g_k1, b_k1, g_k2, b_k2 of the current into bus k: series /// admittance 5 - j5, tap 2 at 90 degrees, and the shunts - static constexpr std::array BUS1_ADMITTANCE = {-1.4, 0.95, 2.5, 2.5}; - static constexpr std::array BUS2_ADMITTANCE = {-2.5, -2.5, -5.1, 4.8}; + static constexpr std::array BUS1_ADMITTANCE = { + -1.4, 0.95, 2.5, 2.5 + }; + static constexpr std::array BUS2_ADMITTANCE = { + -2.5, -2.5, -5.1, 4.8 + }; - /// Constraints of a branch system: S1 and S2, then P, Q, and VM2 of each bus + /// Constraints of a branch system: S1 and S2, then P, Q, and VM2 of each + /// bus static constexpr std::array BRANCH_FLOW_ROWS{0, 1}; static constexpr std::array BRANCH_BALANCE_ROWS{2, 3, 5, 6}; @@ -874,7 +993,9 @@ namespace GridKit static constexpr std::array POWER_X{1.0, 0.0, 0.0, 1.0}; static constexpr std::array BRANCH_X{1.02, 0.12, 0.96, -0.08}; - static constexpr std::array BRANCH_LAMBDA{0.3, -0.2, 1.5, -0.7, 0.0, 2.1, 0.4, 0.0}; + static constexpr std::array BRANCH_LAMBDA{ + 0.3, -0.2, 1.5, -0.7, 0.0, 2.1, 0.4, 0.0 + }; static constexpr std::array FLAT_START{1.0, 0.0, 1.0, 0.0}; static constexpr std::array GENERATOR_X{0.3, 0.1, 1.01, 0.05}; static constexpr std::array SHUNT_X{0.98, 0.1}; @@ -926,7 +1047,9 @@ namespace GridKit /// Stored values static std::vector values(const CooBufferT& entries) { - return {entries.values.getData(), entries.values.getData() + entries.nnz}; + return { + entries.values.getData(), entries.values.getData() + entries.nnz + }; } /// Entries of each row @@ -946,8 +1069,11 @@ namespace GridKit hessian[{std::max(i, j), std::min(i, j)}] += value; } - /// Add `weight` times the lower triangle of the outer product of `gradient` - static void addOuterProduct(EntryMap& hessian, const DependencyMap& gradient, RealT weight) + /// Add `weight` times the lower triangle of the outer product of + /// `gradient` + static void addOuterProduct( + EntryMap& hessian, const DependencyMap& gradient, RealT weight + ) { for (const auto& [i, di] : gradient) { @@ -984,7 +1110,8 @@ namespace GridKit const RealT g = admittance[2 * m]; const RealT b = admittance[2 * m + 1]; - // Real and imaginary parts of the weighted admittance (w_P + j w_Q)(g + j b) + // Real and imaginary parts of the weighted admittance (w_P + j w_Q)(g + // + j b) const RealT re = weight_p * g - weight_q * b; const RealT im = weight_p * b + weight_q * g; diff --git a/tests/UnitTests/OptimalPowerFlow/CoupledComponent.hpp b/tests/UnitTests/OptimalPowerFlow/CoupledComponent.hpp index 3941dec42d..a4bb663b9b 100644 --- a/tests/UnitTests/OptimalPowerFlow/CoupledComponent.hpp +++ b/tests/UnitTests/OptimalPowerFlow/CoupledComponent.hpp @@ -12,7 +12,8 @@ namespace GridKit { namespace OPF = GridKit::OptimalPowerFlow; - /// Two variables and two equality constraints for other components to read and add to + /// Two variables and two equality constraints for other components to read + /// and add to class EqualityOwner final : public OPF::Component { using RealT = double; @@ -39,8 +40,7 @@ namespace GridKit static constexpr std::array NUM_PORT_VARIABLES{}; static constexpr std::array NUM_PORT_CONSTRAINTS{}; - EqualityOwner() - : Component(std::type_identity{}, "owner") + EqualityOwner() : Component(std::type_identity{}, "owner") { } @@ -49,14 +49,16 @@ namespace GridKit return {}; } - void internalConstraints(const RealT*, const RealT*, RealT* g) const override + void internalConstraints(const RealT*, const RealT*, RealT* g) + const override { g[0] = 10.0; g[1] = -10.0; } }; - /// One internal variable, equality, and inequality, coupled to an owner at three ports + /// One internal variable, equality, and inequality, coupled to an owner at + /// three ports class CoupledComponent final : public OPF::Component { using RealT = double; @@ -115,18 +117,24 @@ namespace GridKit int evaluateJacobian() override; int evaluateHessian(RealT sigma) override; - [[gnu::always_inline]] RealT objective(const RealT* x, const RealT* external) const override + [[gnu::always_inline]] RealT objective( + const RealT* x, const RealT* external + ) const override { return 0.5 * x[0] * x[0] + external[0] * external[1]; } - [[gnu::always_inline]] void internalConstraints(const RealT* x, const RealT* external, RealT* g) const override + [[gnu::always_inline]] void internalConstraints( + const RealT* x, const RealT* external, RealT* g + ) const override { g[0] = x[0] * external[0]; g[1] = x[0] * x[0] + external[0] * external[1]; } - [[gnu::always_inline]] void externalConstraints(const RealT* x, const RealT* external, RealT* g) const override + [[gnu::always_inline]] void externalConstraints( + const RealT* x, const RealT* external, RealT* g + ) const override { g[0] = external[0] * external[1]; g[1] = x[0] * external[1]; diff --git a/tests/UnitTests/OptimalPowerFlow/IpoptTests.hpp b/tests/UnitTests/OptimalPowerFlow/IpoptTests.hpp index cfe108eb23..c0f995c886 100644 --- a/tests/UnitTests/OptimalPowerFlow/IpoptTests.hpp +++ b/tests/UnitTests/OptimalPowerFlow/IpoptTests.hpp @@ -22,8 +22,8 @@ namespace GridKit using SystemT = OPF::SystemModel; public: - // Ipopt stops with the constraints and the stationarity within its tolerance. They reach 5e-13 and 2e-13, - // and the marginal prices 8e-13. + // Ipopt stops with the constraints and the stationarity within its + // tolerance. They reach 5e-13 and 2e-13, and the marginal prices 8e-13. static constexpr RealT kTol = static_cast(1.0e-10); TestOutcome reference() @@ -70,7 +70,11 @@ namespace GridKit { success *= isEqual(g[i], ZERO, kTol); } - success *= isEqual(g[SystemTestData::FLOW_ROWS[0]], SystemTestData::SMAX * SystemTestData::SMAX, kTol); + success *= isEqual( + g[SystemTestData::FLOW_ROWS[0]], + SystemTestData::SMAX * SystemTestData::SMAX, + kTol + ); const RealT p1 = system.getGenerator("gen_1")->P(); const RealT p3 = system.getGenerator("gen_3")->P(); @@ -105,10 +109,18 @@ namespace GridKit return -system.getBus(number)->lambda().getData()[P]; }; const auto marginalCost = [&system](const char* id, RealT c1) - { return c1 + TWO * SystemTestData::C2 * system.getGenerator(id)->P(); }; + { + return c1 + + TWO + * SystemTestData::C2 * system.getGenerator(id)->P(); + }; - success *= isEqual(price(1), marginalCost("gen_1", SystemTestData::C1_GEN_1), kTol); - success *= isEqual(price(3), marginalCost("gen_3", SystemTestData::C1_GEN_3), kTol); + success *= isEqual( + price(1), marginalCost("gen_1", SystemTestData::C1_GEN_1), kTol + ); + success *= isEqual( + price(3), marginalCost("gen_3", SystemTestData::C1_GEN_3), kTol + ); return success.report(__func__); } @@ -126,18 +138,22 @@ namespace GridKit return success.report(__func__); } success *= optimize(system); - success *= system.evaluateGradient() == 0 && system.evaluateJacobian() == 0; + success *= + system.evaluateGradient() == 0 && system.evaluateJacobian() == 0; if (!success) { return success.report(__func__); } - std::vector stationarity(system.gradient().getData(), system.gradient().getData() + system.size()); - auto* jacobian = system.getCsrJacobian(); - const IdxT* row_ptrs = jacobian->getRowData(); - const IdxT* cols = jacobian->getColData(); - const RealT* values = jacobian->getValues(); - const RealT* lambda = system.lambda().getData(); + std::vector stationarity( + system.gradient().getData(), + system.gradient().getData() + system.size() + ); + auto* jacobian = system.getCsrJacobian(); + const IdxT* row_ptrs = jacobian->getRowData(); + const IdxT* cols = jacobian->getColData(); + const RealT* values = jacobian->getValues(); + const RealT* lambda = system.lambda().getData(); for (IdxT row = 0; row < jacobian->getNumRows(); ++row) { for (IdxT k = row_ptrs[row]; k < row_ptrs[row + 1]; ++k) @@ -150,7 +166,9 @@ namespace GridKit const RealT* z_upper = system.zUpper().getData(); for (IdxT j = 0; j < system.size(); ++j) { - success *= isEqual(stationarity[j] - z_lower[j] + z_upper[j], ZERO, kTol); + success *= isEqual( + stationarity[j] - z_lower[j] + z_upper[j], ZERO, kTol + ); } return success.report(__func__); @@ -159,7 +177,8 @@ namespace GridKit private: static bool optimize(SystemT& system) { - Ipopt::SmartPtr app = IpoptApplicationFactory(); + Ipopt::SmartPtr app = + IpoptApplicationFactory(); app->Options()->SetIntegerValue("print_level", 0); app->Options()->SetNumericValue("bound_relax_factor", 0.0); app->Options()->SetNumericValue("tol", kTol); @@ -169,7 +188,9 @@ namespace GridKit return false; } - Ipopt::SmartPtr problem = new AnalysisManager::SteadyState::IpoptInterface(&system); + Ipopt::SmartPtr problem = + new AnalysisManager::SteadyState::IpoptInterface(&system + ); return app->OptimizeTNLP(problem) == Ipopt::Solve_Succeeded; } }; diff --git a/tests/UnitTests/OptimalPowerFlow/SystemTestData.hpp b/tests/UnitTests/OptimalPowerFlow/SystemTestData.hpp index ea8b9a77ec..7ad92d33fd 100644 --- a/tests/UnitTests/OptimalPowerFlow/SystemTestData.hpp +++ b/tests/UnitTests/OptimalPowerFlow/SystemTestData.hpp @@ -33,7 +33,9 @@ namespace GridKit static constexpr std::array UNRATED_ROWS{11, 12, 13, 14}; /// A point away from the flat start - static constexpr std::array POINT{1.02, 0.0, 0.97, -0.07, 1.01, -0.03, 0.8, 0.2, 0.4, -0.1}; + static constexpr std::array POINT{ + 1.02, 0.0, 0.97, -0.07, 1.01, -0.03, 0.8, 0.2, 0.4, -0.1 + }; static OPF::SystemModelData data() { @@ -41,8 +43,8 @@ namespace GridKit for (IdxT number = 1; number <= 3; ++number) { - auto& bus = data.bus.emplace_back(); - bus.number = number; + auto& bus = data.bus.emplace_back(); + bus.number = number; bus.parameters[OPF::BusParameters::reference] = number == 1; bus.parameters[OPF::BusParameters::Vmin] = VMIN; bus.parameters[OPF::BusParameters::Vmax] = VMAX; @@ -76,19 +78,24 @@ namespace GridKit RealT b ) { - auto& branch = data.branch.emplace_back(); - branch.id = id; - branch.ports[OPF::BranchPorts::bus1] = bus1; - branch.ports[OPF::BranchPorts::bus2] = bus2; + auto& branch = data.branch.emplace_back(); + branch.id = id; + branch.ports[OPF::BranchPorts::bus1] = bus1; + branch.ports[OPF::BranchPorts::bus2] = bus2; branch.parameters[OPF::BranchParameters::R] = r; branch.parameters[OPF::BranchParameters::X] = x; branch.parameters[OPF::BranchParameters::B] = b; } - static void addGenerator(OPF::SystemModelData& data, const char* id, IdxT bus, RealT c1) + static void addGenerator( + OPF::SystemModelData& data, + const char* id, + IdxT bus, + RealT c1 + ) { - auto& generator = data.generator.emplace_back(); - generator.id = id; + auto& generator = data.generator.emplace_back(); + generator.id = id; generator.ports[OPF::GeneratorPorts::bus] = bus; generator.parameters[OPF::GeneratorParameters::Pmin] = 0.0; generator.parameters[OPF::GeneratorParameters::Pmax] = 2.0; diff --git a/tests/UnitTests/OptimalPowerFlow/SystemTests.hpp b/tests/UnitTests/OptimalPowerFlow/SystemTests.hpp index ac2d150845..fe9b4a7d8a 100644 --- a/tests/UnitTests/OptimalPowerFlow/SystemTests.hpp +++ b/tests/UnitTests/OptimalPowerFlow/SystemTests.hpp @@ -62,22 +62,32 @@ namespace GridKit // Three buses and two generators with two variables each success *= system.size() == 10; - success *= system.sizeConstraints() == SystemTestData::BALANCE_ROWS.size() + SystemTestData::MAGNITUDE_ROWS.size() + SystemTestData::FLOW_ROWS.size() + SystemTestData::UNRATED_ROWS.size(); + success *= system.sizeConstraints() + == SystemTestData::BALANCE_ROWS.size() + + SystemTestData::MAGNITUDE_ROWS.size() + + SystemTestData::FLOW_ROWS.size() + + SystemTestData::UNRATED_ROWS.size(); const auto& tag = system.tag(); const RealT* g_lower = system.gLower().getData(); const RealT* g_upper = system.gUpper().getData(); for (const IdxT i : SystemTestData::BALANCE_ROWS) { - success *= !tag[i] && isEqual(g_lower[i], ZERO) && isEqual(g_upper[i], ZERO); + success *= !tag[i] && isEqual(g_lower[i], ZERO) + && isEqual(g_upper[i], ZERO); } for (const IdxT i : SystemTestData::MAGNITUDE_ROWS) { - success *= tag[i] && isEqual(g_lower[i], SystemTestData::VMIN * SystemTestData::VMIN) && isEqual(g_upper[i], SystemTestData::VMAX * SystemTestData::VMAX); + success *= + tag[i] + && isEqual(g_lower[i], SystemTestData::VMIN * SystemTestData::VMIN) + && isEqual(g_upper[i], SystemTestData::VMAX * SystemTestData::VMAX); } for (const IdxT i : SystemTestData::FLOW_ROWS) { - success *= tag[i] && std::isinf(g_lower[i]) && isEqual(g_upper[i], SystemTestData::SMAX * SystemTestData::SMAX); + success *= + tag[i] && std::isinf(g_lower[i]) + && isEqual(g_upper[i], SystemTestData::SMAX * SystemTestData::SMAX); } for (const IdxT i : SystemTestData::UNRATED_ROWS) { @@ -85,7 +95,8 @@ namespace GridKit } // The imaginary voltage of reference bus 1 is fixed at zero - success *= isEqual(system.xLower().getData()[1], ZERO) && isEqual(system.xUpper().getData()[1], ZERO); + success *= isEqual(system.xLower().getData()[1], ZERO) + && isEqual(system.xUpper().getData()[1], ZERO); return success.report(__func__); } @@ -191,8 +202,8 @@ namespace GridKit } setVariables(system, SystemTestData::POINT); - const auto expected_pattern = pattern(*system.getCsrHessian()); - const IdxT nnz = system.getCsrHessian()->getNnz(); + const auto expected_pattern = pattern(*system.getCsrHessian()); + const IdxT nnz = system.getCsrHessian()->getNnz(); const std::vector zeros(system.sizeConstraints(), ZERO); std::vector lambda(system.sizeConstraints()); for (IdxT i = 0; i < lambda.size(); ++i) @@ -200,22 +211,27 @@ namespace GridKit lambda[i] = LAMBDA_SCALE * static_cast(i + 1); } - const std::vector objective = hessianValues(system, SIGMA, zeros); - success *= pattern(*system.getCsrHessian()) == expected_pattern; - const std::vector constraints = hessianValues(system, ZERO, lambda); - success *= pattern(*system.getCsrHessian()) == expected_pattern; - const std::vector lagrangian = hessianValues(system, SIGMA, lambda); - success *= pattern(*system.getCsrHessian()) == expected_pattern; + const std::vector objective = + hessianValues(system, SIGMA, zeros); + success *= pattern(*system.getCsrHessian()) == expected_pattern; + const std::vector constraints = + hessianValues(system, ZERO, lambda); + success *= pattern(*system.getCsrHessian()) == expected_pattern; + const std::vector lagrangian = + hessianValues(system, SIGMA, lambda); + success *= pattern(*system.getCsrHessian()) == expected_pattern; success *= system.getCsrHessian()->getNnz() == nnz; - success *= objective.size() == nnz && constraints.size() == nnz && lagrangian.size() == nnz; + success *= objective.size() == nnz && constraints.size() == nnz + && lagrangian.size() == nnz; if (!success) { return success.report(__func__); } for (IdxT k = 0; k < nnz; ++k) { - success *= isEqual(lagrangian[k], objective[k] + constraints[k], kTol); + success *= + isEqual(lagrangian[k], objective[k] + constraints[k], kTol); } return success.report(__func__); @@ -244,14 +260,19 @@ namespace GridKit { return success.report(__func__); } - success *= system.sizeConstraints() == SystemTestData::BALANCE_ROWS.size() + SystemTestData::MAGNITUDE_ROWS.size() + SystemTestData::FLOW_ROWS.size() + SystemTestData::UNRATED_ROWS.size(); + success *= system.sizeConstraints() + == SystemTestData::BALANCE_ROWS.size() + + SystemTestData::MAGNITUDE_ROWS.size() + + SystemTestData::FLOW_ROWS.size() + + SystemTestData::UNRATED_ROWS.size(); const auto& tag = system.tag(); const RealT* g_lower = system.gLower().getData(); const RealT* g_upper = system.gUpper().getData(); for (IdxT i = 0; i < system.sizeConstraints(); ++i) { - success *= !tag[i] || (std::isinf(g_lower[i]) && std::isinf(g_upper[i])); + success *= + !tag[i] || (std::isinf(g_lower[i]) && std::isinf(g_upper[i])); } success *= system.evaluateConstraints() == 0; success *= system.evaluateJacobian() == 0; @@ -259,7 +280,8 @@ namespace GridKit { return success.report(__func__); } - success *= system.getCsrJacobian()->getNumRows() == system.sizeConstraints(); + success *= + system.getCsrJacobian()->getNumRows() == system.sizeConstraints(); TrackedT tracked(unbounded); success *= tracked.allocate() == 0 && tracked.initialize() == 0; @@ -268,7 +290,8 @@ namespace GridKit { return success.report(__func__); } - success *= tracked.getCsrJacobian()->getNumRows() == tracked.sizeConstraints(); + success *= + tracked.getCsrJacobian()->getNumRows() == tracked.sizeConstraints(); return success.report(__func__); } @@ -281,28 +304,28 @@ namespace GridKit auto repeated = SystemTestData::data(); repeated.bus[1].number = 1; - success *= throws([&]() - { SystemT system(repeated); }); + success *= + throws([&]() { SystemT system(repeated); }); - auto invalid = SystemTestData::data(); - invalid.bus[0].number = INVALID_INDEX; - success *= configurationRejected([&]() - { return SystemT(invalid).verify(); }); + auto invalid = SystemTestData::data(); + invalid.bus[0].number = INVALID_INDEX; + success *= + configurationRejected([&]() { return SystemT(invalid).verify(); }); auto missing = SystemTestData::data(); missing.generator[0].ports.clear(); - success *= configurationRejected([&]() - { return SystemT(missing).verify(); }); + success *= + configurationRejected([&]() { return SystemT(missing).verify(); }); - auto duplicate = SystemTestData::data(); - duplicate.branch[1].id = duplicate.branch[0].id; - success *= configurationRejected([&]() - { return SystemT(duplicate).verify(); }); + auto duplicate = SystemTestData::data(); + duplicate.branch[1].id = duplicate.branch[0].id; + success *= + configurationRejected([&]() { return SystemT(duplicate).verify(); }); - auto unknown = SystemTestData::data(); - unknown.load[0].ports[OPF::LoadPorts::bus] = 99; - success *= configurationRejected([&]() - { return SystemT(unknown).verify(); }); + auto unknown = SystemTestData::data(); + unknown.load[0].ports[OPF::LoadPorts::bus] = 99; + success *= + configurationRejected([&]() { return SystemT(unknown).verify(); }); return success.report(__func__); } @@ -315,28 +338,75 @@ namespace GridKit const auto data = parse(jsonCase()); success *= isEqual(data.va_base, 100.0e6); - success *= data.bus.size() == 2 && std::get(data.bus[0].parameters.at(OPF::BusParameters::reference)); - success *= !data.bus[1].parameters.contains(OPF::BusParameters::reference); - success *= isEqual(std::get(data.bus[1].parameters.at(OPF::BusParameters::Vmin)), 0.95); - success *= isEqual(std::get(data.bus[1].parameters.at(OPF::BusParameters::B)), 0.1); - - success *= data.branch.size() == 1 && data.branch[0].ports.at(OPF::BranchPorts::bus2) == 2; - success *= isEqual(std::get(data.branch[0].parameters.at(OPF::BranchParameters::Smax)), 0.6); - success *= !data.branch[0].parameters.contains(OPF::BranchParameters::tap); - - success *= data.generator.size() == 1 && !std::get(data.generator[0].parameters.at(OPF::GeneratorParameters::in_service)); + success *= data.bus.size() == 2 + && std::get( + data.bus[0].parameters.at(OPF::BusParameters::reference) + ); + success *= + !data.bus[1].parameters.contains(OPF::BusParameters::reference); + success *= isEqual( + std::get(data.bus[1].parameters.at(OPF::BusParameters::Vmin)), + 0.95 + ); + success *= isEqual( + std::get(data.bus[1].parameters.at(OPF::BusParameters::B)), 0.1 + ); + + success *= data.branch.size() == 1 + && data.branch[0].ports.at(OPF::BranchPorts::bus2) == 2; + success *= isEqual( + std::get( + data.branch[0].parameters.at(OPF::BranchParameters::Smax) + ), + 0.6 + ); + success *= + !data.branch[0].parameters.contains(OPF::BranchParameters::tap); + + success *= data.generator.size() == 1 + && !std::get(data.generator[0].parameters.at( + OPF::GeneratorParameters::in_service + )); success *= data.load.size() == 1; // An unknown device class, parameter, and port - success *= throws(parse, jsonCase(R"(, {"class": "Transformer", "id": "t", "ports": {}, "params": {}})")); - success *= throws(parse, jsonCase(R"(, {"class": "Load", "id": "l", "ports": {"bus": 2}, "params": {"Pd": 1.0}})")); - success *= throws(parse, jsonCase(R"(, {"class": "Load", "id": "l", "ports": {"node": 2}, "params": {}})")); - - // A boolean real and a numeric service status are read, and rejected by the model - success *= throws([&]() - { SystemT system(parse(jsonCase(R"(, {"class": "Load", "id": "l", "ports": {"bus": 2}, "params": {"P": true}})"))); }); - success *= throws([&]() - { SystemT system(parse(jsonCase(R"(, {"class": "Load", "id": "l", "ports": {"bus": 2}, "params": {"in_service": 1}})"))); }); + success *= throws( + parse, + jsonCase( + R"(, {"class": "Transformer", "id": "t", "ports": {}, "params": {}})" + ) + ); + success *= throws( + parse, + jsonCase( + R"(, {"class": "Load", "id": "l", "ports": {"bus": 2}, "params": {"Pd": 1.0}})" + ) + ); + success *= throws( + parse, + jsonCase( + R"(, {"class": "Load", "id": "l", "ports": {"node": 2}, "params": {}})" + ) + ); + + // A boolean real and a numeric service status are read, and rejected by + // the model + success *= throws( + [&]() + { + SystemT system(parse(jsonCase( + R"(, {"class": "Load", "id": "l", "ports": {"bus": 2}, "params": {"P": true}})" + ))); + } + ); + success *= throws( + [&]() + { + SystemT system(parse(jsonCase( + R"(, {"class": "Load", "id": "l", "ports": {"bus": 2}, "params": {"in_service": 1}})" + ))); + } + ); return success.report(__func__); } @@ -355,14 +425,15 @@ namespace GridKit { return success.report(__func__); } - success *= component.connect(3, owner) != 0; - success *= component.connect(0, owner, {2, 0}) != 0; - success *= component.connect(0, owner, {0, 2}) != 0; - success *= component.connect(0, owner, {INVALID_INDEX, 0}) != 0; - success *= component.ports()[0].offset.variables == 1; - success *= component.ports()[0].offset.constraints == 1; - auto system = makeSystem(std::move(owner_ptr), std::move(component_ptr)); - success *= system.allocate() == 0 && system.initialize() == 0; + success *= component.connect(3, owner) != 0; + success *= component.connect(0, owner, {2, 0}) != 0; + success *= component.connect(0, owner, {0, 2}) != 0; + success *= component.connect(0, owner, {INVALID_INDEX, 0}) != 0; + success *= component.ports()[0].offset.variables == 1; + success *= component.ports()[0].offset.constraints == 1; + auto system = + makeSystem(std::move(owner_ptr), std::move(component_ptr)); + success *= system.allocate() == 0 && system.initialize() == 0; if (!success) { return success.report(__func__); @@ -373,9 +444,9 @@ namespace GridKit TestOutcome objectiveAssembly() { - TestStatus success = true; - auto system = coupledSystem(); - success *= system.allocate() == 0 && system.initialize() == 0; + TestStatus success = true; + auto system = coupledSystem(); + success *= system.allocate() == 0 && system.initialize() == 0; if (!success) { return success.report(__func__); @@ -399,9 +470,9 @@ namespace GridKit /// tagged inequality starts unbounded TestOutcome constraintAssembly() { - TestStatus success = true; - auto system = coupledSystem(); - success *= system.allocate() == 0 && system.initialize() == 0; + TestStatus success = true; + auto system = coupledSystem(); + success *= system.allocate() == 0 && system.initialize() == 0; if (!success) { return success.report(__func__); @@ -409,9 +480,11 @@ namespace GridKit success *= system.tag() == std::vector{false, false, false, true}; for (IdxT i = 0; i < 3; ++i) { - success *= isEqual(system.gLower().getData()[i], ZERO) && isEqual(system.gUpper().getData()[i], ZERO); + success *= isEqual(system.gLower().getData()[i], ZERO) + && isEqual(system.gUpper().getData()[i], ZERO); } - success *= std::isinf(system.gLower().getData()[3]) && std::isinf(system.gUpper().getData()[3]); + success *= std::isinf(system.gLower().getData()[3]) + && std::isinf(system.gUpper().getData()[3]); setVariables(system, COUPLED_X); success *= system.evaluateConstraints() == 0; @@ -426,18 +499,23 @@ namespace GridKit success *= isEqual(g[2], 15.0); success *= isEqual(g[3], 31.0); const auto actual = MapFromCsr(system.getCsrJacobian()); - success *= isEqual(actual.at(0), DependencyMap{{0, 5.0}, {2, 2.0}}, kTol); - success *= isEqual(actual.at(1), DependencyMap{{0, 3.0}, {1, 2.0}}, kTol); - success *= isEqual(actual.at(2), DependencyMap{{1, 5.0}, {2, 3.0}}, kTol); - success *= isEqual(actual.at(3), DependencyMap{{0, 3.0}, {1, 2.0}, {2, 10.0}}, kTol); + success *= + isEqual(actual.at(0), DependencyMap{{0, 5.0}, {2, 2.0}}, kTol); + success *= + isEqual(actual.at(1), DependencyMap{{0, 3.0}, {1, 2.0}}, kTol); + success *= + isEqual(actual.at(2), DependencyMap{{1, 5.0}, {2, 3.0}}, kTol); + success *= isEqual( + actual.at(3), DependencyMap{{0, 3.0}, {1, 2.0}, {2, 10.0}}, kTol + ); return success.report(__func__); } TestOutcome hessianAssembly() { - TestStatus success = true; - auto system = coupledSystem(); - success *= system.allocate() == 0 && system.initialize() == 0; + TestStatus success = true; + auto system = coupledSystem(); + success *= system.allocate() == 0 && system.initialize() == 0; if (!success) { return success.report(__func__); @@ -451,16 +529,18 @@ namespace GridKit } const auto actual = MapFromCsr(system.getCsrHessian()); success *= actual.at(0).empty(); - success *= isEqual(actual.at(1), DependencyMap{{0, 18.0}}, kTol); - success *= isEqual(actual.at(2), DependencyMap{{0, 3.0}, {1, 7.0}, {2, 24.0}}, kTol); + success *= isEqual(actual.at(1), DependencyMap{{0, 18.0}}, kTol); + success *= isEqual( + actual.at(2), DependencyMap{{0, 3.0}, {1, 7.0}, {2, 24.0}}, kTol + ); return success.report(__func__); } TestOutcome repeatedVariables() { - TestStatus success = true; - auto system = coupledSystem(true); - success *= system.allocate() == 0 && system.initialize() == 0; + TestStatus success = true; + auto system = coupledSystem(true); + success *= system.allocate() == 0 && system.initialize() == 0; if (!success) { return success.report(__func__); @@ -479,8 +559,9 @@ namespace GridKit success *= isEqual(gradient[2], 5.0); const auto actual = MapFromCsr(system.getCsrHessian()); success *= actual.at(0).empty(); - success *= isEqual(actual.at(1), DependencyMap{{1, 36.0}}, kTol); - success *= isEqual(actual.at(2), DependencyMap{{1, 10.0}, {2, 24.0}}, kTol); + success *= isEqual(actual.at(1), DependencyMap{{1, 36.0}}, kTol); + success *= + isEqual(actual.at(2), DependencyMap{{1, 10.0}, {2, 24.0}}, kTol); return success.report(__func__); } @@ -489,7 +570,8 @@ namespace GridKit TestStatus success = true; EqualityOwner owner; auto component = std::make_unique(); - for (IdxT port = 0; port < CoupledComponent::NUM_PORT_VARIABLES.size(); ++port) + for (IdxT port = 0; port < CoupledComponent::NUM_PORT_VARIABLES.size(); + ++port) { success *= component->connect(port, owner) == 0; if (!success) @@ -550,8 +632,11 @@ namespace GridKit + extra + "]}"; } - /// Hessian values at `sigma` and `lambda`, or none if the evaluation fails - static std::vector hessianValues(SystemT& system, RealT sigma, const std::vector& lambda) + /// Hessian values at `sigma` and `lambda`, or none if the evaluation + /// fails + static std::vector hessianValues( + SystemT& system, RealT sigma, const std::vector& lambda + ) { setMultipliers(system, lambda); if (system.evaluateHessian(sigma) != 0) @@ -559,7 +644,9 @@ namespace GridKit return {}; } auto* hessian = system.getCsrHessian(); - return std::vector(hessian->getValues(), hessian->getValues() + hessian->getNnz()); + return std::vector( + hessian->getValues(), hessian->getValues() + hessian->getNnz() + ); } }; } // namespace Testing diff --git a/tests/UnitTests/OptimalPowerFlow/TestHelpers.hpp b/tests/UnitTests/OptimalPowerFlow/TestHelpers.hpp index af0d9903a1..1933882c43 100644 --- a/tests/UnitTests/OptimalPowerFlow/TestHelpers.hpp +++ b/tests/UnitTests/OptimalPowerFlow/TestHelpers.hpp @@ -24,7 +24,9 @@ namespace GridKit using EntryMap = std::map, double>; template - OPF::SystemModel makeSystem(std::unique_ptr... models) + OPF::SystemModel makeSystem( + std::unique_ptr... models + ) { std::vector>> components; components.reserve(sizeof...(ModelsT)); @@ -33,7 +35,9 @@ namespace GridKit } template - void setVariables(OPF::SystemModel& system, std::span values) + void setVariables( + OPF::SystemModel& system, std::span values + ) { if (values.size() != system.size()) { @@ -52,7 +56,9 @@ namespace GridKit } template - void setMultipliers(OPF::SystemModel& system, std::span values) + void setMultipliers( + OPF::SystemModel& system, std::span values + ) { if (values.size() != system.sizeConstraints()) { @@ -62,17 +68,20 @@ namespace GridKit system.lambda().setDataUpdated(); } - inline EntryMap sum(const OPF::Component::CooBuffer& entries) + inline EntryMap sum(const OPF::Component::CooBuffer& entries + ) { EntryMap result; for (size_t k = 0; k < entries.nnz; ++k) { - result[{entries.rows.getData()[k], entries.cols.getData()[k]}] += entries.values.getData()[k]; + result[{entries.rows.getData()[k], entries.cols.getData()[k]}] += + entries.values.getData()[k]; } return result; } - inline auto pattern(const OPF::Component::CooBuffer& entries) + inline auto pattern(const OPF::Component::CooBuffer& entries + ) { return std::pair{ std::vector( @@ -96,11 +105,21 @@ namespace GridKit }; } - inline bool matches(const EntryMap& actual, const EntryMap& expected, double tolerance) + inline bool matches( + const EntryMap& actual, const EntryMap& expected, double tolerance + ) { return actual.size() == expected.size() - && std::equal(actual.begin(), actual.end(), expected.begin(), [tolerance](const auto& a, const auto& b) - { return a.first == b.first && isEqual(a.second, b.second, tolerance); }); + && std::equal( + actual.begin(), + actual.end(), + expected.begin(), + [tolerance](const auto& a, const auto& b) + { + return a.first == b.first + && isEqual(a.second, b.second, tolerance); + } + ); } } // namespace Testing } // namespace GridKit diff --git a/tests/UnitTests/PhasorDynamics/BranchTests.hpp b/tests/UnitTests/PhasorDynamics/BranchTests.hpp index 838cfcdc04..ba53b57626 100644 --- a/tests/UnitTests/PhasorDynamics/BranchTests.hpp +++ b/tests/UnitTests/PhasorDynamics/BranchTests.hpp @@ -69,10 +69,12 @@ namespace GridKit ScalarT Vr2{30.0}; ///< Bus-2 real voltage ScalarT Vi2{40.0}; ///< Bus-2 imaginary voltage - const ScalarT Ir1{17.0}; ///< Solution: real current entering bus-1 - const ScalarT Ii1{-10.0}; ///< Solution: imaginary current entering bus-1 - const ScalarT Ir2{15.0}; ///< Solution: real current entering bus-2 - const ScalarT Ii2{-20.0}; ///< Solution: imaginary current entering bus-2 + const ScalarT Ir1{17.0}; ///< Solution: real current entering bus-1 + const ScalarT Ii1{-10.0 + }; ///< Solution: imaginary current entering bus-1 + const ScalarT Ir2{15.0}; ///< Solution: real current entering bus-2 + const ScalarT Ii2{-20.0 + }; ///< Solution: imaginary current entering bus-2 PhasorDynamics::Bus bus1(Vr1, Vi1); PhasorDynamics::Bus bus2(Vr2, Vi2); @@ -83,7 +85,9 @@ namespace GridKit bus2.initialize(); bus2.evaluateResidual(); - PhasorDynamics::Branch branch(&bus1, &bus2, branchData(R, X, G, B)); + PhasorDynamics::Branch branch( + &bus1, &bus2, branchData(R, X, G, B) + ); branch.allocate(); branch.evaluateResidual(); @@ -97,7 +101,8 @@ namespace GridKit TestOutcome offNominalResidual() { - // Verifies tap, phase-shift, line-shunt, and bus-1 magnetizing-shunt contributions. + // Verifies tap, phase-shift, line-shunt, and bus-1 magnetizing-shunt + // contributions. TestStatus success = true; RealT R{2.0}; @@ -181,20 +186,27 @@ namespace GridKit bus2.Vr().setVariableNumber(2); bus2.Vi().setVariableNumber(3); - PhasorDynamics::Branch branch(&bus1, &bus2, branchData(R, X, G, B)); + PhasorDynamics::Branch branch( + &bus1, &bus2, branchData(R, X, G, B) + ); branch.allocate(); - branch.evaluateResidual(); ///< Computes the residual and the Jacobian values by tracking - ///< the dependencies + branch.evaluateResidual(); ///< Computes the residual and the Jacobian + ///< values by tracking the dependencies - std::vector residuals{bus1.Ir(), bus1.Ii(), bus2.Ir(), bus2.Ii()}; - std::vector ref = analyticalJacobian(R, X, G, B); + std::vector residuals{ + bus1.Ir(), bus1.Ii(), bus2.Ir(), bus2.Ii() + }; + std::vector ref = + analyticalJacobian(R, X, G, B); - /// Compare dependencies computed automatically to the ones computed analytically + /// Compare dependencies computed automatically to the ones computed + /// analytically for (size_t i = 0; i < residuals.size(); ++i) { - DependencyTracking::Variable res = residuals[i]; - const DependencyTracking::Variable::DependencyMap& dependencies = res.getDependencies(); - success *= (GridKit::Testing::isEqual(dependencies, ref[i])); + DependencyTracking::Variable res = residuals[i]; + const DependencyTracking::Variable::DependencyMap& dependencies = + res.getDependencies(); + success *= (GridKit::Testing::isEqual(dependencies, ref[i])); } return success.report(__func__); @@ -221,21 +233,31 @@ namespace GridKit Vr2.setVariableNumber(2); Vi2.setVariableNumber(3); - PhasorDynamics::BusInfinite bus1(Vr1, Vi1); - PhasorDynamics::BusInfinite bus2(Vr2, Vi2); + PhasorDynamics::BusInfinite bus1( + Vr1, Vi1 + ); + PhasorDynamics::BusInfinite bus2( + Vr2, Vi2 + ); - PhasorDynamics::Branch branch(&bus1, &bus2, branchData(R, X, G, B, tap, phase)); + PhasorDynamics::Branch branch( + &bus1, &bus2, branchData(R, X, G, B, tap, phase) + ); branch.allocate(); branch.evaluateResidual(); - std::vector residuals{bus1.Ir(), bus1.Ii(), bus2.Ir(), bus2.Ii()}; - std::vector ref = analyticalJacobian(R, X, G, B, tap, phase); + std::vector residuals{ + bus1.Ir(), bus1.Ii(), bus2.Ir(), bus2.Ii() + }; + std::vector ref = + analyticalJacobian(R, X, G, B, tap, phase); for (size_t i = 0; i < residuals.size(); ++i) { - DependencyTracking::Variable res = residuals[i]; - const DependencyTracking::Variable::DependencyMap& dependencies = res.getDependencies(); - success *= (GridKit::Testing::isEqual(dependencies, ref[i])); + DependencyTracking::Variable res = residuals[i]; + const DependencyTracking::Variable::DependencyMap& dependencies = + res.getDependencies(); + success *= (GridKit::Testing::isEqual(dependencies, ref[i])); } return success.report(__func__); @@ -244,7 +266,8 @@ namespace GridKit #ifdef GRIDKIT_ENABLE_ENZYME TestOutcome outOfServiceJacobian() { - // Verify zero currents, fixed sparsity, and restoration after switching. + // Verify zero currents, fixed sparsity, and restoration after + // switching. TestStatus success = true; PhasorDynamics::Bus bus1(10.0, 20.0); @@ -261,15 +284,23 @@ namespace GridKit bus2.setResidualIndex(i, i + 2); } - PhasorDynamics::Branch branch(&bus1, &bus2, branchData(2.0, 4.0, 0.2, 1.2)); + PhasorDynamics::Branch branch( + &bus1, &bus2, branchData(2.0, 4.0, 0.2, 1.2) + ); branch.allocate(); branch.evaluateJacobian(); - const IdxT nnz = branch.nnz(); - success *= nnz > 0; - auto* jacobian = branch.getCooJacobian(); - const std::vector rows(jacobian->getRowData(), jacobian->getRowData() + nnz); - const std::vector cols(jacobian->getColData(), jacobian->getColData() + nnz); - const std::vector values(jacobian->getValues(), jacobian->getValues() + nnz); + const IdxT nnz = branch.nnz(); + success *= nnz > 0; + auto* jacobian = branch.getCooJacobian(); + const std::vector rows( + jacobian->getRowData(), jacobian->getRowData() + nnz + ); + const std::vector cols( + jacobian->getColData(), jacobian->getColData() + nnz + ); + const std::vector values( + jacobian->getValues(), jacobian->getValues() + nnz + ); success *= branch.setInService(false) == 0; bus1.evaluateResidual(); @@ -330,7 +361,9 @@ namespace GridKit ref_bus2.allocate(); ref_bus2.initialize(); ref_bus2.evaluateResidual(); - PhasorDynamics::Branch ref_branch(&ref_bus1, &ref_bus2, branchData(R, X, G, B, tap, phase)); + PhasorDynamics::Branch ref_branch( + &ref_bus1, &ref_bus2, branchData(R, X, G, B, tap, phase) + ); PhasorDynamics::Bus test_bus1(Vr1, Vi1); PhasorDynamics::Bus test_bus2(Vr2, Vi2); @@ -340,7 +373,9 @@ namespace GridKit test_bus2.allocate(); test_bus2.initialize(); test_bus2.evaluateResidual(); - PhasorDynamics::Branch test_branch(&test_bus1, &test_bus2, branchData(1.0, 1.0, 0.0, 0.0)); + PhasorDynamics::Branch test_branch( + &test_bus1, &test_bus2, branchData(1.0, 1.0, 0.0, 0.0) + ); test_branch.setR(R); test_branch.setX(X); @@ -368,21 +403,29 @@ namespace GridKit PhasorDynamics::Bus bus1(1.0, 0.0); PhasorDynamics::Bus bus2(1.0, 0.0); - PhasorDynamics::Branch valid_branch(&bus1, &bus2, branchData(0.0, 0.1, 0.0, 0.0)); + PhasorDynamics::Branch valid_branch( + &bus1, &bus2, branchData(0.0, 0.1, 0.0, 0.0) + ); success *= (valid_branch.verify().passed()); const auto previous_verbosity = Log::verbosity(); - // Suppress expected errors from the invalid branch configurations below. - // Use EVERYTHING to inspect those diagnostics. + // Suppress expected errors from the invalid branch configurations + // below. Use EVERYTHING to inspect those diagnostics. Log::setVerbosity(Log::Verbosity::NONE); - PhasorDynamics::Branch zero_impedance_branch(&bus1, &bus2, branchData(0.0, 0.0, 0.0, 0.0)); + PhasorDynamics::Branch zero_impedance_branch( + &bus1, &bus2, branchData(0.0, 0.0, 0.0, 0.0) + ); success *= (!zero_impedance_branch.verify().passed()); - PhasorDynamics::Branch zero_tap_branch(&bus1, &bus2, branchData(0.0, 0.1, 0.0, 0.0, 0.0, 0.0)); + PhasorDynamics::Branch zero_tap_branch( + &bus1, &bus2, branchData(0.0, 0.1, 0.0, 0.0, 0.0, 0.0) + ); success *= (!zero_tap_branch.verify().passed()); - PhasorDynamics::Branch negative_tap_branch(&bus1, &bus2, branchData(0.0, 0.1, 0.0, 0.0, -1.0, 0.0)); + PhasorDynamics::Branch negative_tap_branch( + &bus1, &bus2, branchData(0.0, 0.1, 0.0, 0.0, -1.0, 0.0) + ); success *= (!negative_tap_branch.verify().passed()); const RealT nan = std::numeric_limits::quiet_NaN(); @@ -446,8 +489,12 @@ namespace GridKit ref_bus2.initialize(); ref_bus2.evaluateResidual(); - PhasorDynamics::Branch data_branch(&data_bus1, &data_bus2, data); - PhasorDynamics::Branch ref_branch(&ref_bus1, &ref_bus2, branchData(R, X, G, B, 1.0, 0.0)); + PhasorDynamics::Branch data_branch( + &data_bus1, &data_bus2, data + ); + PhasorDynamics::Branch ref_branch( + &ref_bus1, &ref_bus2, branchData(R, X, G, B, 1.0, 0.0) + ); data_branch.evaluateResidual(); ref_branch.evaluateResidual(); @@ -502,16 +549,26 @@ namespace GridKit const std::complex rotation{std::cos(phase), std::sin(phase)}; const std::complex ydiag = -ybr; - const std::complex y11 = ydiag * inv_tap * inv_tap - RealT{0.5} * ysh; + const std::complex y11 = + ydiag * inv_tap * inv_tap - RealT{0.5} * ysh; const std::complex y12 = ybr * rotation * inv_tap; const std::complex y21 = ybr * std::conj(rotation) * inv_tap; const std::complex y22 = ydiag - RealT{0.5} * ysh; - std::vector dependencies(4); - dependencies[0] = {{0, y11.real()}, {1, -y11.imag()}, {2, y12.real()}, {3, -y12.imag()}}; - dependencies[1] = {{0, y11.imag()}, {1, y11.real()}, {2, y12.imag()}, {3, y12.real()}}; - dependencies[2] = {{0, y21.real()}, {1, -y21.imag()}, {2, y22.real()}, {3, -y22.imag()}}; - dependencies[3] = {{0, y21.imag()}, {1, y21.real()}, {2, y22.imag()}, {3, y22.real()}}; + std::vector dependencies(4 + ); + dependencies[0] = { + {0, y11.real()}, {1, -y11.imag()}, {2, y12.real()}, {3, -y12.imag()} + }; + dependencies[1] = { + {0, y11.imag()}, {1, y11.real()}, {2, y12.imag()}, {3, y12.real()} + }; + dependencies[2] = { + {0, y21.real()}, {1, -y21.imag()}, {2, y22.real()}, {3, -y22.imag()} + }; + dependencies[3] = { + {0, y21.imag()}, {1, y21.real()}, {2, y22.imag()}, {3, y22.real()} + }; return dependencies; } diff --git a/tests/UnitTests/PhasorDynamics/BusSignalVoltageInTests.hpp b/tests/UnitTests/PhasorDynamics/BusSignalVoltageInTests.hpp index f60401f279..02e03d9ae0 100644 --- a/tests/UnitTests/PhasorDynamics/BusSignalVoltageInTests.hpp +++ b/tests/UnitTests/PhasorDynamics/BusSignalVoltageInTests.hpp @@ -60,7 +60,8 @@ namespace GridKit success *= !bus->verify().passed(); delete bus; - // Initial voltage arguments are accepted for interface uniformity but not used + // Initial voltage arguments are accepted for interface uniformity but + // not used bus = new BusT(Vr, Vi); bus->allocate(); bus->initialize(); @@ -115,7 +116,8 @@ namespace GridKit success *= isEqual(bus.Vr(), 1.17); success *= isEqual(bus.Vi(), 0.41); - // Reading an unconnected voltage inlet is an error, never a default value + // Reading an unconnected voltage inlet is an error, never a default + // value BusT plain; plain.allocate(); plain.initialize(); @@ -191,7 +193,8 @@ namespace GridKit return success.report(__func__); } - /// verify() reports errors for voltage inlets that are unconnected or unlinked + /// verify() reports errors for voltage inlets that are unconnected or + /// unlinked TestOutcome verifyUnlinked() { TestStatus success = true; diff --git a/tests/UnitTests/PhasorDynamics/BusTests.hpp b/tests/UnitTests/PhasorDynamics/BusTests.hpp index dcdb80cc3f..39530a489a 100644 --- a/tests/UnitTests/PhasorDynamics/BusTests.hpp +++ b/tests/UnitTests/PhasorDynamics/BusTests.hpp @@ -120,7 +120,8 @@ namespace GridKit bus.initialize(); // Fault current I = -V / (R + jX) - const std::complex current = -std::complex(Vr, Vi) / std::complex(R, X); + const std::complex current = + -std::complex(Vr, Vi) / std::complex(R, X); success *= bus.setFault(true, R, X) == 0; bus.evaluateResidual(); @@ -144,7 +145,8 @@ namespace GridKit } #ifdef GRIDKIT_ENABLE_ENZYME - /// Fault Jacobian matches DependencyTracking and keeps its pattern when cleared + /// Fault Jacobian matches DependencyTracking and keeps its pattern when + /// cleared TestOutcome jacobian() { TestStatus success = true; @@ -156,7 +158,8 @@ namespace GridKit DependencyTracking::Variable Vr{1.0}; DependencyTracking::Variable Vi{2.0}; - PhasorDynamics::Bus dependency_tracking_bus(Vr, Vi); + PhasorDynamics::Bus + dependency_tracking_bus(Vr, Vi); dependency_tracking_bus.allocate(); dependency_tracking_bus.initialize(); dependency_tracking_bus.setFault(true, R, X); @@ -165,7 +168,8 @@ namespace GridKit const auto* f = dependency_tracking_bus.getResidual().getData(); const auto size = static_cast(dependency_tracking_bus.size()); - std::vector dependency_tracking_jacobian(size); + std::vector + dependency_tracking_jacobian(size); for (size_t row = 0; row < size; ++row) { for (const auto& [number, value] : f[row].getDependencies()) @@ -187,15 +191,19 @@ namespace GridKit const IdxT* cols = jacobian->getColData(); const RealT* vals = jacobian->getValues(); - std::vector bus_jacobian(size); + std::vector bus_jacobian( + size + ); for (IdxT i = 0; i < jacobian->getNnz(); ++i) { - bus_jacobian[static_cast(rows[i])][static_cast(cols[i])] = vals[i]; + bus_jacobian[static_cast(rows[i])] + [static_cast(cols[i])] = vals[i]; } for (size_t row = 0; row < size; ++row) { - success *= isEqual(dependency_tracking_jacobian[row], bus_jacobian[row]); + success *= + isEqual(dependency_tracking_jacobian[row], bus_jacobian[row]); } // Clearing the fault keeps the same entries with zero values diff --git a/tests/UnitTests/PhasorDynamics/ComponentConnectionTests.hpp b/tests/UnitTests/PhasorDynamics/ComponentConnectionTests.hpp index e9794b036e..78267881e1 100644 --- a/tests/UnitTests/PhasorDynamics/ComponentConnectionTests.hpp +++ b/tests/UnitTests/PhasorDynamics/ComponentConnectionTests.hpp @@ -59,16 +59,25 @@ namespace GridKit static_cast(1.0), static_cast(0.0) ); PhasorDynamics::SignalNode efd; - PhasorDynamics::Genrou machine(&bus, PhasorDynamics::GenrouData{}); + PhasorDynamics::Genrou machine( + &bus, PhasorDynamics::GenrouData{} + ); PhasorDynamics::Exciter::Esdc1aData exciter_data; exciter_data.parameters[ExciterParams::Tr] = static_cast(0.02); exciter_data.parameters[ExciterParams::Tb] = static_cast(0.5); - PhasorDynamics::Exciter::Esdc1a exciter(&bus, exciter_data); + PhasorDynamics::Exciter::Esdc1a exciter( + &bus, exciter_data + ); - machine.getPorts().in.template port().connect(&efd); - exciter.getPorts().out.template port().connect(&efd); + machine.getPorts() + .in.template port() + .connect(&efd); + exciter.getPorts() + .out + .template port() + .connect(&efd); system.addBus(&bus); system.addComponent(&machine); @@ -107,16 +116,24 @@ namespace GridKit static_cast(1.0), static_cast(0.0) ); PhasorDynamics::SignalNode pmech; - PhasorDynamics::Genrou machine(&bus, PhasorDynamics::GenrouData{}); + PhasorDynamics::Genrou machine( + &bus, PhasorDynamics::GenrouData{} + ); PhasorDynamics::Governor::HygovData governor_data; - governor_data.parameters[GovernorParams::Trate] = static_cast(100.0); - governor_data.parameters[GovernorParams::Tnp] = static_cast(1.0); + governor_data.parameters[GovernorParams::Trate] = + static_cast(100.0); + governor_data.parameters[GovernorParams::Tnp] = static_cast(1.0); PhasorDynamics::Governor::Hygov governor(governor_data); - machine.getPorts().in.template port().connect(&pmech); - governor.getPorts().out.template port().connect(&pmech); + machine.getPorts() + .in.template port() + .connect(&pmech); + governor.getPorts() + .out + .template port() + .connect(&pmech); system.addBus(&bus); system.addComponent(&machine); @@ -155,16 +172,23 @@ namespace GridKit PhasorDynamics::SignalNode efd; PhasorDynamics::GenClassicalData machine_data; - PhasorDynamics::GenClassical machine(&bus, machine_data); + PhasorDynamics::GenClassical machine(&bus, machine_data); PhasorDynamics::Exciter::Esdc1aData exciter_data; exciter_data.parameters[ExciterParams::Tr] = static_cast(0.02); exciter_data.parameters[ExciterParams::Tb] = static_cast(0.5); - PhasorDynamics::Exciter::Esdc1a exciter(&bus, exciter_data); + PhasorDynamics::Exciter::Esdc1a exciter( + &bus, exciter_data + ); - machine.getPorts().in.template port().connect(&efd); - exciter.getPorts().out.template port().connect(&efd); + machine.getPorts() + .in.template port() + .connect(&efd); + exciter.getPorts() + .out + .template port() + .connect(&efd); system.addBus(&bus); system.addComponent(&machine); @@ -203,16 +227,22 @@ namespace GridKit PhasorDynamics::SignalNode pmech; PhasorDynamics::GenClassicalData machine_data; - PhasorDynamics::GenClassical machine(&bus, machine_data); + PhasorDynamics::GenClassical machine(&bus, machine_data); PhasorDynamics::Governor::HygovData governor_data; - governor_data.parameters[GovernorParams::Trate] = static_cast(100.0); - governor_data.parameters[GovernorParams::Tnp] = static_cast(1.0); + governor_data.parameters[GovernorParams::Trate] = + static_cast(100.0); + governor_data.parameters[GovernorParams::Tnp] = static_cast(1.0); PhasorDynamics::Governor::Hygov governor(governor_data); - machine.getPorts().in.template port().connect(&pmech); - governor.getPorts().out.template port().connect(&pmech); + machine.getPorts() + .in.template port() + .connect(&pmech); + governor.getPorts() + .out + .template port() + .connect(&pmech); system.addBus(&bus); system.addComponent(&machine); @@ -241,8 +271,9 @@ namespace GridKit TestOutcome regcaRepca() { using ConverterParams = PhasorDynamics::Converter::RegcaParameters; - using PlantInternal = PhasorDynamics::Controller::RepcaInternalVariables; - using PlantParams = PhasorDynamics::Controller::RepcaParameters; + using PlantInternal = + PhasorDynamics::Controller::RepcaInternalVariables; + using PlantParams = PhasorDynamics::Controller::RepcaParameters; TestStatus success = true; @@ -256,37 +287,77 @@ namespace GridKit PhasorDynamics::SignalNode q; PhasorDynamics::Converter::RegcaData converter_data; - converter_data.parameters[ConverterParams::p0] = static_cast(0.4); - converter_data.parameters[ConverterParams::q0] = static_cast(0.1); - converter_data.parameters[ConverterParams::mva] = static_cast(100.0); - converter_data.parameters[ConverterParams::Tg] = static_cast(0.02); - converter_data.parameters[ConverterParams::TM] = static_cast(0.02); - converter_data.parameters[ConverterParams::Rqmax] = static_cast(999.0); - converter_data.parameters[ConverterParams::Rqmin] = static_cast(-999.0); - converter_data.parameters[ConverterParams::Rpmax] = static_cast(999.0); - converter_data.parameters[ConverterParams::sL] = true; - converter_data.parameters[ConverterParams::IL1] = static_cast(1.1); - converter_data.parameters[ConverterParams::VL0] = static_cast(0.4); - converter_data.parameters[ConverterParams::VL1] = static_cast(0.9); - converter_data.parameters[ConverterParams::VA0] = static_cast(0.4); - converter_data.parameters[ConverterParams::VA1] = static_cast(0.9); - converter_data.parameters[ConverterParams::Vhvmax] = static_cast(1.2); + converter_data.parameters[ConverterParams::p0] = + static_cast(0.4); + converter_data.parameters[ConverterParams::q0] = + static_cast(0.1); + converter_data.parameters[ConverterParams::mva] = + static_cast(100.0); + converter_data.parameters[ConverterParams::Tg] = + static_cast(0.02); + converter_data.parameters[ConverterParams::TM] = + static_cast(0.02); + converter_data.parameters[ConverterParams::Rqmax] = + static_cast(999.0); + converter_data.parameters[ConverterParams::Rqmin] = + static_cast(-999.0); + converter_data.parameters[ConverterParams::Rpmax] = + static_cast(999.0); + converter_data.parameters[ConverterParams::sL] = true; + converter_data.parameters[ConverterParams::IL1] = + static_cast(1.1); + converter_data.parameters[ConverterParams::VL0] = + static_cast(0.4); + converter_data.parameters[ConverterParams::VL1] = + static_cast(0.9); + converter_data.parameters[ConverterParams::VA0] = + static_cast(0.4); + converter_data.parameters[ConverterParams::VA1] = + static_cast(0.9); + converter_data.parameters[ConverterParams::Vhvmax] = + static_cast(1.2); PhasorDynamics::Controller::RepcaData plant_data; plant_data.parameters[PlantParams::mva] = static_cast(50.0); plant_data.parameters[PlantParams::Tp] = static_cast(0.05); - PhasorDynamics::Converter::Regca converter(&bus, converter_data); - PhasorDynamics::Controller::Repca plant(&bus, plant_data); + PhasorDynamics::Converter::Regca converter( + &bus, converter_data + ); + PhasorDynamics::Controller::Repca plant( + &bus, plant_data + ); - converter.getPorts().out.template port().connect(&ir); - converter.getPorts().out.template port().connect(&ii); - converter.getPorts().out.template port().connect(&p); - converter.getPorts().out.template port().connect(&q); - plant.getPorts().in.template port().connect(&ir); - plant.getPorts().in.template port().connect(&ii); - plant.getPorts().in.template port().connect(&p); - plant.getPorts().in.template port().connect(&q); + converter.getPorts() + .out + .template port() + .connect(&ir); + converter.getPorts() + .out + .template port() + .connect(&ii); + converter.getPorts() + .out + .template port< + PhasorDynamics::Converter::RegcaSignalOutputs::pbranch>() + .connect(&p); + converter.getPorts() + .out + .template port< + PhasorDynamics::Converter::RegcaSignalOutputs::qbranch>() + .connect(&q); + plant.getPorts() + .in.template port() + .connect(&ir); + plant.getPorts() + .in.template port() + .connect(&ii); + plant.getPorts() + .in.template port() + .connect(&p); + plant.getPorts() + .in.template port() + .connect(&q); system.addBus(&bus); system.addComponent(&converter); @@ -350,63 +421,110 @@ namespace GridKit // The operating point is exactly representable, so the pair rests at // an exact steady state. PhasorDynamics::Converter::RegcaData converter_data; - converter_data.parameters[ConverterParams::p0] = static_cast(0.375); - converter_data.parameters[ConverterParams::q0] = static_cast(0.0625); - converter_data.parameters[ConverterParams::mva] = static_cast(100.0); - converter_data.parameters[ConverterParams::Tg] = static_cast(0.02); - converter_data.parameters[ConverterParams::TM] = static_cast(0.02); - converter_data.parameters[ConverterParams::Rqmax] = static_cast(999.0); - converter_data.parameters[ConverterParams::Rqmin] = static_cast(-999.0); - converter_data.parameters[ConverterParams::Rpmax] = static_cast(999.0); - converter_data.parameters[ConverterParams::sL] = true; - converter_data.parameters[ConverterParams::IL1] = static_cast(1.1); - converter_data.parameters[ConverterParams::VL0] = static_cast(0.25); - converter_data.parameters[ConverterParams::VL1] = static_cast(0.75); - converter_data.parameters[ConverterParams::VA0] = static_cast(0.25); - converter_data.parameters[ConverterParams::VA1] = static_cast(0.75); - converter_data.parameters[ConverterParams::Vhvmax] = static_cast(1.5); - - PhasorDynamics::Converter::Regca converter(&bus, converter_data); + converter_data.parameters[ConverterParams::p0] = + static_cast(0.375); + converter_data.parameters[ConverterParams::q0] = + static_cast(0.0625); + converter_data.parameters[ConverterParams::mva] = + static_cast(100.0); + converter_data.parameters[ConverterParams::Tg] = + static_cast(0.02); + converter_data.parameters[ConverterParams::TM] = + static_cast(0.02); + converter_data.parameters[ConverterParams::Rqmax] = + static_cast(999.0); + converter_data.parameters[ConverterParams::Rqmin] = + static_cast(-999.0); + converter_data.parameters[ConverterParams::Rpmax] = + static_cast(999.0); + converter_data.parameters[ConverterParams::sL] = true; + converter_data.parameters[ConverterParams::IL1] = + static_cast(1.1); + converter_data.parameters[ConverterParams::VL0] = + static_cast(0.25); + converter_data.parameters[ConverterParams::VL1] = + static_cast(0.75); + converter_data.parameters[ConverterParams::VA0] = + static_cast(0.25); + converter_data.parameters[ConverterParams::VA1] = + static_cast(0.75); + converter_data.parameters[ConverterParams::Vhvmax] = + static_cast(1.5); + + PhasorDynamics::Converter::Regca converter( + &bus, converter_data + ); PhasorDynamics::Controller::ReecbData controller_data; - controller_data.parameters[ControllerParams::mva] = static_cast(100.0); - controller_data.parameters[ControllerParams::Tp] = static_cast(0.02); + controller_data.parameters[ControllerParams::mva] = + static_cast(100.0); + controller_data.parameters[ControllerParams::Tp] = + static_cast(0.02); controller_data.parameters[ControllerParams::QFlag] = true; controller_data.parameters[ControllerParams::VFlag] = true; controller_data.parameters[ControllerParams::Pqflag] = true; - controller_data.parameters[ControllerParams::Imax] = static_cast(0.625); - controller_data.parameters[ControllerParams::Vmin] = static_cast(0.5); - controller_data.parameters[ControllerParams::Vmax] = static_cast(1.5); - - PhasorDynamics::Controller::Reecb controller(&bus, controller_data); + controller_data.parameters[ControllerParams::Imax] = + static_cast(0.625); + controller_data.parameters[ControllerParams::Vmin] = + static_cast(0.5); + controller_data.parameters[ControllerParams::Vmax] = + static_cast(1.5); + + PhasorDynamics::Controller::Reecb controller( + &bus, controller_data + ); - controller.getPorts().out.template port().connect(&ipcmd); - controller.getPorts().out.template port().connect(&iqcmd); - converter.getPorts().in.template port().connect(&ipcmd); - converter.getPorts().in.template port().connect(&iqcmd); - converter.getPorts().out.template port().connect(&pe); - converter.getPorts().out.template port().connect(&qgen); - controller.getPorts().in.template port().connect(&pe); - controller.getPorts().in.template port().connect(&qgen); + controller.getPorts() + .out + .template port( + ) + .connect(&ipcmd); + controller.getPorts() + .out + .template port( + ) + .connect(&iqcmd); + converter.getPorts() + .in + .template port() + .connect(&ipcmd); + converter.getPorts() + .in + .template port() + .connect(&iqcmd); + converter.getPorts() + .out + .template port< + PhasorDynamics::Converter::RegcaSignalOutputs::pbranch>() + .connect(&pe); + converter.getPorts() + .out + .template port< + PhasorDynamics::Converter::RegcaSignalOutputs::qbranch>() + .connect(&qgen); + controller.getPorts() + .in.template port() + .connect(&pe); + controller.getPorts() + .in + .template port() + .connect(&qgen); system.addBus(&bus); system.addComponent(&converter); system.addComponent(&controller); success *= system.allocate() == 0; - success *= ipcmd.linked() && iqcmd.linked() && pe.linked() && qgen.linked(); + success *= + ipcmd.linked() && iqcmd.linked() && pe.linked() && qgen.linked(); success *= ipcmd.getVariableIndex() - == controller.getVariableIndex( - static_cast( - PhasorDynamics::Controller::ReecbInternalVariables::IPCMD - ) - ); + == controller.getVariableIndex(static_cast( + PhasorDynamics::Controller::ReecbInternalVariables::IPCMD + )); success *= iqcmd.getVariableIndex() - == controller.getVariableIndex( - static_cast( - PhasorDynamics::Controller::ReecbInternalVariables::IQCMD - ) - ); + == controller.getVariableIndex(static_cast( + PhasorDynamics::Controller::ReecbInternalVariables::IQCMD + )); success *= system.initialize() == 0; success *= system.evaluateResidual() == 0; @@ -426,7 +544,8 @@ namespace GridKit } }; - /// Production SystemModel wiring tests for GASTPTI and synchronous machines. + /// Production SystemModel wiring tests for GASTPTI and synchronous + /// machines. template class GastPtiConnectionTests { @@ -488,10 +607,10 @@ namespace GridKit static constexpr IdxT kMachineComponentId = static_cast(0); static constexpr IdxT kGovernorComponentId = static_cast(1); - static constexpr RealT kSystemBaseVa = static_cast(100.0e6); - static constexpr RealT kMachineBaseMva = static_cast(100.0); - static constexpr RealT kTurbineRatingMw = static_cast(100.0); - static constexpr RealT kInitialActivePower = static_cast(0.4); + static constexpr RealT kSystemBaseVa = static_cast(100.0e6); + static constexpr RealT kMachineBaseMva = static_cast(100.0); + static constexpr RealT kTurbineRatingMw = static_cast(100.0); + static constexpr RealT kInitialActivePower = static_cast(0.4); static constexpr RealT kInitialReactivePower = static_cast(0.05); template < @@ -510,11 +629,13 @@ namespace GridKit success *= system.allocate() == 0; - auto* machine = dynamic_cast(system.getComponent(kMachineComponentId)); - auto* governor = dynamic_cast(system.getComponent(kGovernorComponentId)); - auto* speed = system.getSignalNode(kSpeedSignalId); - auto* pmech = system.getSignalNode(kPmechSignalId); - auto* pref = system.getSignalNode(kPrefSignalId); + auto* machine = + dynamic_cast(system.getComponent(kMachineComponentId)); + auto* governor = + dynamic_cast(system.getComponent(kGovernorComponentId)); + auto* speed = system.getSignalNode(kSpeedSignalId); + auto* pmech = system.getSignalNode(kPmechSignalId); + auto* pref = system.getSignalNode(kPrefSignalId); if (machine == nullptr || governor == nullptr || speed == nullptr || pmech == nullptr || pref == nullptr) @@ -523,8 +644,9 @@ namespace GridKit return success.report(test_name); } - const bool signals_linked = speed->linked() && pmech->linked() && pref->linked(); - success *= signals_linked; + const bool signals_linked = + speed->linked() && pmech->linked() && pref->linked(); + success *= signals_linked; if (!signals_linked) { return success.report(test_name); @@ -553,8 +675,9 @@ namespace GridKit const IdxT pref_index = pref->getVariableIndex(); success *= speed_index != pmech_index; - success *= speed_index - == machine->getVariableIndex(static_cast(speed_state_variable)); + success *= + speed_index + == machine->getVariableIndex(static_cast(speed_state_variable)); success *= speed_index == governor_ports.in.template port() @@ -594,15 +717,16 @@ namespace GridKit {"Active Power Reference", kPrefSignalId} }; - auto& governor = data.gastpti.emplace_back(); + auto& governor = data.gastpti.emplace_back(); governor.signal_inputs[GastPtiSignalInputs::speed] = kSpeedSignalId; governor.signal_inputs[GastPtiSignalInputs::pref] = kPrefSignalId; governor.signal_outputs[GastPtiSignalOutputs::pmech] = kPmechSignalId; governor.parameters[GastPtiParameters::Trate] = kTurbineRatingMw; - auto& source = data.constant_source.emplace_back(); - source.signal_outputs[ConstantSignalSourceSignalOutputs::sr] = kPrefSignalId; - source.parameters[ConstantSignalSourceParameters::Sr] = ZERO; + auto& source = data.constant_source.emplace_back(); + source.signal_outputs[ConstantSignalSourceSignalOutputs::sr] = + kPrefSignalId; + source.parameters[ConstantSignalSourceParameters::Sr] = ZERO; return data; } @@ -613,29 +737,29 @@ namespace GridKit auto data = makeGastPtiCase(); - auto& machine = data.genrou.emplace_back(); - machine.buses[GenrouBuses::bus] = kBusId; + auto& machine = data.genrou.emplace_back(); + machine.buses[GenrouBuses::bus] = kBusId; machine.signal_outputs[GenrouSignalOutputs::speed] = kSpeedSignalId; machine.signal_inputs[GenrouSignalInputs::pmech] = kPmechSignalId; - machine.parameters[GenrouParameters::p0] = kInitialActivePower; - machine.parameters[GenrouParameters::q0] = kInitialReactivePower; - machine.parameters[GenrouParameters::H] = RealT{3.0}; - machine.parameters[GenrouParameters::D] = ZERO; - machine.parameters[GenrouParameters::Ra] = ZERO; - machine.parameters[GenrouParameters::Tdop] = RealT{7.0}; - machine.parameters[GenrouParameters::Tdopp] = RealT{0.04}; - machine.parameters[GenrouParameters::Tqop] = RealT{0.75}; - machine.parameters[GenrouParameters::Tqopp] = RealT{0.05}; - machine.parameters[GenrouParameters::Xd] = RealT{2.1}; - machine.parameters[GenrouParameters::Xdp] = RealT{0.2}; - machine.parameters[GenrouParameters::Xdpp] = RealT{0.18}; - machine.parameters[GenrouParameters::Xq] = RealT{0.5}; - machine.parameters[GenrouParameters::Xqp] = RealT{0.5}; - machine.parameters[GenrouParameters::Xqpp] = RealT{0.18}; - machine.parameters[GenrouParameters::Xl] = RealT{0.15}; - machine.parameters[GenrouParameters::S10] = ZERO; - machine.parameters[GenrouParameters::S12] = ZERO; - machine.parameters[GenrouParameters::mva] = kMachineBaseMva; + machine.parameters[GenrouParameters::p0] = kInitialActivePower; + machine.parameters[GenrouParameters::q0] = kInitialReactivePower; + machine.parameters[GenrouParameters::H] = RealT{3.0}; + machine.parameters[GenrouParameters::D] = ZERO; + machine.parameters[GenrouParameters::Ra] = ZERO; + machine.parameters[GenrouParameters::Tdop] = RealT{7.0}; + machine.parameters[GenrouParameters::Tdopp] = RealT{0.04}; + machine.parameters[GenrouParameters::Tqop] = RealT{0.75}; + machine.parameters[GenrouParameters::Tqopp] = RealT{0.05}; + machine.parameters[GenrouParameters::Xd] = RealT{2.1}; + machine.parameters[GenrouParameters::Xdp] = RealT{0.2}; + machine.parameters[GenrouParameters::Xdpp] = RealT{0.18}; + machine.parameters[GenrouParameters::Xq] = RealT{0.5}; + machine.parameters[GenrouParameters::Xqp] = RealT{0.5}; + machine.parameters[GenrouParameters::Xqpp] = RealT{0.18}; + machine.parameters[GenrouParameters::Xl] = RealT{0.15}; + machine.parameters[GenrouParameters::S10] = ZERO; + machine.parameters[GenrouParameters::S12] = ZERO; + machine.parameters[GenrouParameters::mva] = kMachineBaseMva; return data; } @@ -646,13 +770,13 @@ namespace GridKit auto data = makeGastPtiCase(); - auto& machine = data.gensal.emplace_back(); - machine.buses[GensalBuses::bus] = kBusId; + auto& machine = data.gensal.emplace_back(); + machine.buses[GensalBuses::bus] = kBusId; machine.signal_outputs[GensalSignalOutputs::speed] = kSpeedSignalId; machine.signal_inputs[GensalSignalInputs::pmech] = kPmechSignalId; - machine.parameters[GensalParameters::p0] = kInitialActivePower; - machine.parameters[GensalParameters::q0] = kInitialReactivePower; - machine.parameters[GensalParameters::mva] = kMachineBaseMva; + machine.parameters[GensalParameters::p0] = kInitialActivePower; + machine.parameters[GensalParameters::q0] = kInitialReactivePower; + machine.parameters[GensalParameters::mva] = kMachineBaseMva; return data; } @@ -663,13 +787,14 @@ namespace GridKit auto data = makeGastPtiCase(); - auto& machine = data.genclassical.emplace_back(); - machine.buses[GenClassicalBuses::bus] = kBusId; - machine.signal_outputs[GenClassicalSignalOutputs::speed] = kSpeedSignalId; - machine.signal_inputs[GenClassicalSignalInputs::pmech] = kPmechSignalId; - machine.parameters[GenClassicalParameters::p0] = kInitialActivePower; - machine.parameters[GenClassicalParameters::q0] = kInitialReactivePower; - machine.parameters[GenClassicalParameters::mva] = kMachineBaseMva; + auto& machine = data.genclassical.emplace_back(); + machine.buses[GenClassicalBuses::bus] = kBusId; + machine.signal_outputs[GenClassicalSignalOutputs::speed] = + kSpeedSignalId; + machine.signal_inputs[GenClassicalSignalInputs::pmech] = kPmechSignalId; + machine.parameters[GenClassicalParameters::p0] = kInitialActivePower; + machine.parameters[GenClassicalParameters::q0] = kInitialReactivePower; + machine.parameters[GenClassicalParameters::mva] = kMachineBaseMva; return data; } diff --git a/tests/UnitTests/PhasorDynamics/ControllerReecbTests.hpp b/tests/UnitTests/PhasorDynamics/ControllerReecbTests.hpp index a4611187e6..ea8f4cb814 100644 --- a/tests/UnitTests/PhasorDynamics/ControllerReecbTests.hpp +++ b/tests/UnitTests/PhasorDynamics/ControllerReecbTests.hpp @@ -58,7 +58,8 @@ namespace GridKit PhasorDynamics::Bus bus(1.0, 0.0); PhasorDynamics::Controller::Reecb empty(&bus, Data{}); - success *= (empty.size() == static_cast(Utilities::enum_size())); + success *= + (empty.size() == static_cast(Utilities::enum_size())); const std::array()> row_order{{ Vars::VMEAS, Vars::PMEAS, Vars::XPIQ, Vars::XPIV, Vars::QV, @@ -73,7 +74,9 @@ namespace GridKit } Fixture configured(makeData()); - success *= (configured.reecb.size() == static_cast(Utilities::enum_size())); + success *= + (configured.reecb.size() + == static_cast(Utilities::enum_size())); success *= (configured.reecb.getMonitor() != nullptr); success *= (configured.reecb.verify().passed()); success *= (configured.reecb.initialize() != 0); @@ -110,8 +113,8 @@ namespace GridKit success *= (integer_parameter.reecb.verify().passed()); success *= invalidParameterCase(Params::mva, true); - const RealT nan = std::numeric_limits::quiet_NaN(); - const RealT infinity = std::numeric_limits::infinity(); + const RealT nan = std::numeric_limits::quiet_NaN(); + const RealT infinity = std::numeric_limits::infinity(); const std::array real_parameters{{ Params::mva, Params::Trv, Params::Tp, Params::Vref0, Params::Vdip, Params::Vup, Params::dbd1, Params::dbd2, @@ -193,7 +196,9 @@ namespace GridKit } } - PhasorDynamics::Controller::Reecb busless(nullptr, makeData()); + PhasorDynamics::Controller::Reecb busless( + nullptr, makeData() + ); busless.setSystemBase(kNominalFrequency, kSystemBaseVa); success *= (!busless.verify().passed()); @@ -249,18 +254,19 @@ namespace GridKit return success.report(__func__); } - /// Check initialization state, known-input preservation, unknown-reference - /// publication, command aliases, latches, monitors, and the power base. + /// Check initialization state, known-input preservation, + /// unknown-reference publication, command aliases, latches, monitors, and + /// the power base. TestOutcome initializationAndSignals() { TestStatus success = true; Fixture fixture(makeData(), 0.8, 0.6); fixture.attachAllInputs(99.0); - fixture.input(Ext::pe) = kInitialIpcmd; - fixture.input(Ext::qgen) = kInitialIqcmd; - success *= fixture.initialize(kInitialIqcmd, kInitialIpcmd); - success *= (fixture.evaluate() == 0); + fixture.input(Ext::pe) = kInitialIpcmd; + fixture.input(Ext::qgen) = kInitialIqcmd; + success *= fixture.initialize(kInitialIqcmd, kInitialIpcmd); + success *= (fixture.evaluate() == 0); success *= stateMatches( fixture.reecb, @@ -281,19 +287,28 @@ namespace GridKit ); const auto* initial_values = fixture.reecb.y().getData(); - success *= scalarMatches( + success *= scalarMatches( initial_values[index(Vars::IQMAX)], initial_values[index(Vars::ILCAP)], "initial reactive-current limit" ); - success *= scalarPreserved(fixture.iqcmd(), kInitialIqcmd, "preserved iqcmd"); - success *= scalarPreserved(fixture.ipcmd(), kInitialIpcmd, "preserved ipcmd"); - success *= scalarPreserved(fixture.input(Ext::pe), kInitialIpcmd, "preserved pe"); - success *= scalarPreserved(fixture.input(Ext::qgen), kInitialIqcmd, "preserved qgen"); - success *= scalarMatches(fixture.input(Ext::qext), 0.75, "published qext"); - success *= scalarMatches(fixture.input(Ext::pfaref), 0.0, "published pfaref"); - success *= scalarMatches(fixture.input(Ext::pref), 0.75, "published pref"); + success *= + scalarPreserved(fixture.iqcmd(), kInitialIqcmd, "preserved iqcmd"); + success *= + scalarPreserved(fixture.ipcmd(), kInitialIpcmd, "preserved ipcmd"); + success *= scalarPreserved( + fixture.input(Ext::pe), kInitialIpcmd, "preserved pe" + ); + success *= scalarPreserved( + fixture.input(Ext::qgen), kInitialIqcmd, "preserved qgen" + ); + success *= + scalarMatches(fixture.input(Ext::qext), 0.75, "published qext"); + success *= + scalarMatches(fixture.input(Ext::pfaref), 0.0, "published pfaref"); + success *= + scalarMatches(fixture.input(Ext::pref), 0.75, "published pref"); success *= allResidualsWithinInitTolerance(fixture.reecb); success *= monitorMatches( @@ -302,20 +317,25 @@ namespace GridKit "initialization" ); - constexpr RealT absolute_tolerance = 2.5e-7; - success *= (fixture.reecb.setAbsoluteTolerance(absolute_tolerance) == 0); - const auto* tolerances = fixture.reecb.absoluteTolerance().getData(); + constexpr RealT absolute_tolerance = 2.5e-7; + success *= + (fixture.reecb.setAbsoluteTolerance(absolute_tolerance) == 0); + const auto* tolerances = fixture.reecb.absoluteTolerance().getData(); for (size_t row = 0; row < Utilities::enum_size(); ++row) { - success *= valueUnchanged(tolerances[row], absolute_tolerance, "absolute tolerance", row); + success *= valueUnchanged( + tolerances[row], absolute_tolerance, "absolute tolerance", row + ); } // Unassigned command outputs keep the commands in the model vector. Fixture latched(makeData(), 1.0, 0.0, kSystemBaseVa, false); success *= latched.initialize(kInitialIqcmd, kInitialIpcmd); success *= (latched.evaluate() == 0); - success *= scalarPreserved(latched.iqcmd(), kInitialIqcmd, "unassigned iqcmd"); - success *= scalarPreserved(latched.ipcmd(), kInitialIpcmd, "unassigned ipcmd"); + success *= + scalarPreserved(latched.iqcmd(), kInitialIqcmd, "unassigned iqcmd"); + success *= + scalarPreserved(latched.ipcmd(), kInitialIpcmd, "unassigned ipcmd"); success *= allResidualsWithinInitTolerance(latched.reecb); return success.report(__func__); @@ -327,14 +347,21 @@ namespace GridKit TestStatus success = true; const auto previous_verbosity = Log::verbosity(); - // Suppress expected errors and limit-adjustment warnings from the cases below. - // Use EVERYTHING to inspect those diagnostics. + // Suppress expected errors and limit-adjustment warnings from the cases + // below. Use EVERYTHING to inspect those diagnostics. Log::setVerbosity(Log::Verbosity::NONE); const auto data = makeData(); - success *= initializationRejectedAtomically(data, 0.75, -0.1, "negative active-current command"); - success *= initializationRejectedAtomically(data, 0.75, std::numeric_limits::infinity(), "nonfinite active-current command"); + success *= initializationRejectedAtomically( + data, 0.75, -0.1, "negative active-current command" + ); + success *= initializationRejectedAtomically( + data, + 0.75, + std::numeric_limits::infinity(), + "nonfinite active-current command" + ); success *= initializationRejectedAtomically( data, std::numeric_limits::infinity(), @@ -347,29 +374,41 @@ namespace GridKit Fixture adjusted_pmax(pord_above); success *= adjusted_pmax.initialize(0.75, 0.75); success *= (adjusted_pmax.evaluate() == 0); - success *= stateMatches(adjusted_pmax.reecb, {{Vars::PORD, 1.5}}, "adjusted Pmax"); + success *= stateMatches( + adjusted_pmax.reecb, {{Vars::PORD, 1.5}}, "adjusted Pmax" + ); success *= allResidualsWithinInitTolerance(adjusted_pmax.reecb); setState(adjusted_pmax.reecb, {{Vars::PORD, 1.25}, {Vars::RPORD, 1.0}}); success *= (adjusted_pmax.evaluate() == 0); - success *= residualsMatch(adjusted_pmax.reecb, {{Vars::PORD, 1.0}}, "adjusted Pmax"); + success *= residualsMatch( + adjusted_pmax.reecb, {{Vars::PORD, 1.0}}, "adjusted Pmax" + ); auto pord_below = data; pord_below.parameters[Params::Pmin] = 2.0; Fixture adjusted_pmin(pord_below); success *= adjusted_pmin.initialize(0.75, 0.75); success *= (adjusted_pmin.evaluate() == 0); - success *= stateMatches(adjusted_pmin.reecb, {{Vars::PORD, 1.5}}, "adjusted Pmin"); + success *= stateMatches( + adjusted_pmin.reecb, {{Vars::PORD, 1.5}}, "adjusted Pmin" + ); success *= allResidualsWithinInitTolerance(adjusted_pmin.reecb); - setState(adjusted_pmin.reecb, {{Vars::PORD, 1.75}, {Vars::RPORD, -1.0}}); + setState( + adjusted_pmin.reecb, {{Vars::PORD, 1.75}, {Vars::RPORD, -1.0}} + ); success *= (adjusted_pmin.evaluate() == 0); - success *= residualsMatch(adjusted_pmin.reecb, {{Vars::PORD, -1.0}}, "adjusted Pmin"); + success *= residualsMatch( + adjusted_pmin.reecb, {{Vars::PORD, -1.0}}, "adjusted Pmin" + ); auto expanded_current = data; expanded_current.parameters[Params::Imax] = 1.0; Fixture adjusted_imax(expanded_current); success *= adjusted_imax.initialize(0.75, 0.75); success *= (adjusted_imax.evaluate() == 0); - success *= stateMatches(adjusted_imax.reecb, {{Vars::ILCAP, 1.5}}, "adjusted Imax"); + success *= stateMatches( + adjusted_imax.reecb, {{Vars::ILCAP, 1.5}}, "adjusted Imax" + ); success *= allResidualsWithinInitTolerance(adjusted_imax.reecb); auto reactive_pi = data; @@ -385,7 +424,7 @@ namespace GridKit adjusted_q.input(Ext::qgen) = qgen; success *= adjusted_q.initialize(0.75, 0.75); success *= (adjusted_q.evaluate() == 0); - success *= allResidualsWithinInitTolerance(adjusted_q.reecb); + success *= allResidualsWithinInitTolerance(adjusted_q.reecb); } auto voltage_pi = reactive_pi; @@ -411,7 +450,7 @@ namespace GridKit adjusted_v.input(Ext::qgen) = test_case.qgen; success *= adjusted_v.initialize(0.75, 0.75); success *= (adjusted_v.evaluate() == 0); - success *= allResidualsWithinInitTolerance(adjusted_v.reecb); + success *= allResidualsWithinInitTolerance(adjusted_v.reecb); } // Power-factor control needs a representable angle. @@ -426,14 +465,17 @@ namespace GridKit success *= late.prepare(0.75, 0.75); if (late.reecb.initialize() == 0) { - std::cout << "Expected REECB initialization rejection after Pmax adjustment\n"; + std::cout << "Expected REECB initialization rejection after Pmax " + "adjustment\n"; success = false; } late.input(Ext::pref) = 0.75; setState(late.reecb, {{Vars::PORD, 1.25}, {Vars::VT, 1.0}}); setDerivative(late.reecb, {{Vars::PORD, 0.0}}); success *= (late.evaluate() == 0); - success *= residualsMatch(late.reecb, {{Vars::PORD, 0.0}}, "rejected Pmax adjustment"); + success *= residualsMatch( + late.reecb, {{Vars::PORD, 0.0}}, "rejected Pmax adjustment" + ); success *= initializationRejectedAtomically( power_factor, 0.75, @@ -443,7 +485,9 @@ namespace GridKit 0.75 ); - success *= initializationRejectedAtomically(data, 0.75, 0.75, "zero terminal voltage", 0.75, 0.75, 0.0); + success *= initializationRejectedAtomically( + data, 0.75, 0.75, "zero terminal voltage", 0.75, 0.75, 0.0 + ); success *= initializationRejectedAtomically( data, 0.75, @@ -463,11 +507,11 @@ namespace GridKit collapsed.parameters[Params::Vmax] = 1.0; Fixture collapsed_limits(collapsed); collapsed_limits.attachAllInputs(); - collapsed_limits.input(Ext::pe) = 0.6; - collapsed_limits.input(Ext::qgen) = 0.6; - success *= collapsed_limits.initialize(0.75, 0.75); - success *= (collapsed_limits.evaluate() == 0); - success *= allResidualsWithinInitTolerance(collapsed_limits.reecb); + collapsed_limits.input(Ext::pe) = 0.6; + collapsed_limits.input(Ext::qgen) = 0.6; + success *= collapsed_limits.initialize(0.75, 0.75); + success *= (collapsed_limits.evaluate() == 0); + success *= allResidualsWithinInitTolerance(collapsed_limits.reecb); auto collapsed_reactive = collapsed; collapsed_reactive.parameters[Params::Vmin] = 0.5; @@ -475,11 +519,11 @@ namespace GridKit collapsed_reactive.parameters[Params::Kvi] = 0.0; Fixture expanded_reactive(collapsed_reactive); expanded_reactive.attachAllInputs(); - expanded_reactive.input(Ext::pe) = 0.75; - expanded_reactive.input(Ext::qgen) = 0.3; - success *= expanded_reactive.initialize(0.75, 0.75); - success *= (expanded_reactive.evaluate() == 0); - success *= allResidualsWithinInitTolerance(expanded_reactive.reecb); + expanded_reactive.input(Ext::pe) = 0.75; + expanded_reactive.input(Ext::qgen) = 0.3; + success *= expanded_reactive.initialize(0.75, 0.75); + success *= (expanded_reactive.evaluate() == 0); + success *= allResidualsWithinInitTolerance(expanded_reactive.reecb); auto collapsed_voltage = collapsed; collapsed_voltage.parameters[Params::Qmin] = -2.0; @@ -492,11 +536,11 @@ namespace GridKit collapsed_voltage.parameters[Params::VFlag] = voltage_flag; Fixture expanded_voltage(collapsed_voltage); expanded_voltage.attachAllInputs(); - expanded_voltage.input(Ext::pe) = 0.75; - expanded_voltage.input(Ext::qgen) = 0.75; - success *= expanded_voltage.initialize(0.75, 0.75); - success *= (expanded_voltage.evaluate() == 0); - success *= allResidualsWithinInitTolerance(expanded_voltage.reecb); + expanded_voltage.input(Ext::pe) = 0.75; + expanded_voltage.input(Ext::qgen) = 0.75; + success *= expanded_voltage.initialize(0.75, 0.75); + success *= (expanded_voltage.evaluate() == 0); + success *= allResidualsWithinInitTolerance(expanded_voltage.reecb); } // Zero integral gains leave both controllers unconstrained, so any @@ -510,7 +554,7 @@ namespace GridKit unconstrained.input(Ext::qgen) = 4.0; success *= unconstrained.initialize(0.75, 0.75); success *= (unconstrained.evaluate() == 0); - success *= allResidualsWithinInitTolerance(unconstrained.reecb); + success *= allResidualsWithinInitTolerance(unconstrained.reecb); // An invalid configuration is rejected before any state is written. auto invalid_data = data; @@ -523,11 +567,14 @@ namespace GridKit const auto invalid_yp = copyVector(invalid_fixture.reecb.yp()); if (invalid_fixture.reecb.initialize() == 0) { - std::cout << "Expected REECB initialization rejection: invalid configuration\n"; + std::cout << "Expected REECB initialization rejection: invalid " + "configuration\n"; success = false; } - success *= vectorUnchanged(invalid_fixture.reecb.y(), invalid_y, "state"); - success *= vectorUnchanged(invalid_fixture.reecb.yp(), invalid_yp, "derivative"); + success *= + vectorUnchanged(invalid_fixture.reecb.y(), invalid_y, "state"); + success *= + vectorUnchanged(invalid_fixture.reecb.yp(), invalid_yp, "derivative"); Log::setVerbosity(previous_verbosity); return success.report(__func__); @@ -540,8 +587,8 @@ namespace GridKit TestStatus success = true; const auto previous_verbosity = Log::verbosity(); - // Suppress expected limit-adjustment warnings from the boundary cases below. - // Use EVERYTHING to inspect those diagnostics. + // Suppress expected limit-adjustment warnings from the boundary cases + // below. Use EVERYTHING to inspect those diagnostics. Log::setVerbosity(Log::Verbosity::NONE); struct ExactnessCase @@ -567,7 +614,8 @@ namespace GridKit Fixture fixture(exactness_data); success *= fixture.initialize(0.0, test_case.ipcmd); success *= (fixture.evaluate() == 0); - success *= scalarPreserved(fixture.ipcmd(), test_case.ipcmd, test_case.label); + success *= + scalarPreserved(fixture.ipcmd(), test_case.ipcmd, test_case.label); success *= allResidualsWithinInitTolerance(fixture.reecb); } @@ -586,7 +634,8 @@ namespace GridKit Fixture at_limit(limit_data); success *= at_limit.initialize(0.0, 0.75); success *= (at_limit.evaluate() == 0); - success *= stateMatches(at_limit.reecb, {{Vars::PORD, 1.5}}, "order at Pmax"); + success *= + stateMatches(at_limit.reecb, {{Vars::PORD, 1.5}}, "order at Pmax"); success *= allResidualsWithinInitTolerance(at_limit.reecb); struct AsymmetricSlewCase @@ -629,7 +678,9 @@ namespace GridKit Fixture reactive(exactness_data); success *= reactive.initialize(iqcmd, 0.75); success *= (reactive.evaluate() == 0); - success *= scalarPreserved(reactive.iqcmd(), iqcmd, "near-limit reactive command"); + success *= scalarPreserved( + reactive.iqcmd(), iqcmd, "near-limit reactive command" + ); success *= allResidualsWithinInitTolerance(reactive.reecb); } @@ -658,8 +709,10 @@ namespace GridKit Fixture boundary(boundary_data); success *= boundary.initialize(test_case.iqcmd, test_case.ipcmd); success *= (boundary.evaluate() == 0); - success *= scalarPreserved(boundary.iqcmd(), test_case.iqcmd, test_case.label); - success *= scalarPreserved(boundary.ipcmd(), test_case.ipcmd, test_case.label); + success *= + scalarPreserved(boundary.iqcmd(), test_case.iqcmd, test_case.label); + success *= + scalarPreserved(boundary.ipcmd(), test_case.ipcmd, test_case.label); success *= stateMatches( boundary.reecb, {{Vars::ILCAP, test_case.capacity}}, @@ -674,7 +727,9 @@ namespace GridKit Fixture separated(separated_data); success *= separated.initialize(5.0e-13, 0.5); success *= (separated.evaluate() == 0); - success *= scalarPreserved(separated.iqcmd(), 5.0e-13, "scale-separated current command"); + success *= scalarPreserved( + separated.iqcmd(), 5.0e-13, "scale-separated current command" + ); success *= allResidualsWithinInitTolerance(separated.reecb); // A low configured Imax must still be expanded far enough to preserve @@ -691,14 +746,21 @@ namespace GridKit for (const auto& [iqcmd, ipcmd] : capacity_cases) { Fixture capacity_fixture(capacity_data); - success *= capacity_fixture.initialize(iqcmd, ipcmd); - success *= (capacity_fixture.evaluate() == 0); - success *= scalarPreserved(capacity_fixture.iqcmd(), iqcmd, "low-priority command"); - success *= scalarPreserved(capacity_fixture.ipcmd(), ipcmd, "high-priority command"); - const RealT ilcap = static_cast(capacity_fixture.reecb.y().getData()[index(Vars::ILCAP)]); + success *= capacity_fixture.initialize(iqcmd, ipcmd); + success *= (capacity_fixture.evaluate() == 0); + success *= scalarPreserved( + capacity_fixture.iqcmd(), iqcmd, "low-priority command" + ); + success *= scalarPreserved( + capacity_fixture.ipcmd(), ipcmd, "high-priority command" + ); + const RealT ilcap = static_cast( + capacity_fixture.reecb.y().getData()[index(Vars::ILCAP)] + ); if (ilcap < iqcmd) { - std::cout << "REECB low-priority capacity does not include its initial command\n"; + std::cout << "REECB low-priority capacity does not include its " + "initial command\n"; success = false; } success *= @@ -718,9 +780,11 @@ namespace GridKit nested.input(Ext::qgen) = 0.8; success *= nested.initialize(0.8, 0.6); success *= (nested.evaluate() == 0); - success *= scalarPreserved(nested.iqcmd(), 0.8, "nested-clamp reactive command"); - success *= scalarPreserved(nested.ipcmd(), 0.6, "nested-clamp active command"); - success *= allResidualsWithinInitTolerance(nested.reecb); + success *= + scalarPreserved(nested.iqcmd(), 0.8, "nested-clamp reactive command"); + success *= + scalarPreserved(nested.ipcmd(), 0.6, "nested-clamp active command"); + success *= allResidualsWithinInitTolerance(nested.reecb); auto exhausted_data = exactness_data; exhausted_data.parameters[Params::QFlag] = true; @@ -733,7 +797,9 @@ namespace GridKit exhausted.input(Ext::pe) = 1.25; success *= exhausted.initialize(0.0, 1.25); success *= (exhausted.evaluate() == 0); - success *= scalarPreserved(exhausted.iqcmd(), 0.0, "exhausted reactive-current capacity"); + success *= scalarPreserved( + exhausted.iqcmd(), 0.0, "exhausted reactive-current capacity" + ); success *= stateMatches( exhausted.reecb, @@ -759,7 +825,7 @@ namespace GridKit setResidualState(fixture.reecb); success *= (fixture.evaluate() == 0); - const RealT ideal_circle_leg = circleLeg(1.76); + const RealT ideal_circle_leg = circleLeg(1.76); const std::array()> expected_residuals{{ {Vars::VMEAS, 0.99}, {Vars::PMEAS, 0.145}, @@ -782,8 +848,10 @@ namespace GridKit { if (index(expected_residuals[row].variable) != row) { - Log::error() << "REECB residual expectation position " << row << " names row " - << variableName(expected_residuals[row].variable) << '\n'; + Log::error() << "REECB residual expectation position " << row + << " names row " + << variableName(expected_residuals[row].variable) + << '\n'; success = false; } } @@ -816,8 +884,8 @@ namespace GridKit TestStatus success = true; const auto previous_verbosity = Log::verbosity(); - // Suppress expected atypical-control warnings from selector combinations below. - // Use EVERYTHING to inspect those diagnostics. + // Suppress expected atypical-control warnings from selector + // combinations below. Use EVERYTHING to inspect those diagnostics. Log::setVerbosity(Log::Verbosity::NONE); const std::array selector_values{{false, true}}; @@ -858,8 +926,10 @@ namespace GridKit success *= fixture.initialize(0.75, 0.75); success *= (fixture.evaluate() == 0); success *= allResidualsWithinInitTolerance(fixture.reecb); - success *= scalarPreserved(fixture.iqcmd(), 0.75, "selector iqcmd"); - success *= scalarPreserved(fixture.ipcmd(), 0.75, "selector ipcmd"); + success *= + scalarPreserved(fixture.iqcmd(), 0.75, "selector iqcmd"); + success *= + scalarPreserved(fixture.ipcmd(), 0.75, "selector ipcmd"); success *= stateMatches( fixture.reecb, {{Vars::ILCAP, 2.0}}, @@ -884,8 +954,12 @@ namespace GridKit if (attached) { - success *= scalarPreserved(fixture.input(Ext::pe), 0.75, "selector pe"); - success *= scalarPreserved(fixture.input(Ext::qgen), 0.75, "selector qgen"); + success *= scalarPreserved( + fixture.input(Ext::pe), 0.75, "selector pe" + ); + success *= scalarPreserved( + fixture.input(Ext::qgen), 0.75, "selector qgen" + ); RealT expected_qext = 0.75; if (reactive && !voltage) @@ -903,9 +977,17 @@ namespace GridKit expected_pfaref = kUnitSlopeAngle; } - success *= scalarMatches(fixture.input(Ext::qext), expected_qext, "published qext"); - success *= scalarMatches(fixture.input(Ext::pfaref), expected_pfaref, "published pfaref"); - success *= scalarMatches(fixture.input(Ext::pref), 0.75, "published pref"); + success *= scalarMatches( + fixture.input(Ext::qext), expected_qext, "published qext" + ); + success *= scalarMatches( + fixture.input(Ext::pfaref), + expected_pfaref, + "published pfaref" + ); + success *= scalarMatches( + fixture.input(Ext::pref), 0.75, "published pref" + ); } } } @@ -932,7 +1014,9 @@ namespace GridKit Fixture fixture(data); fixture.attachAllInputs(); success *= fixture.initialize(0.75, 0.75); - success *= scalarMatches(fixture.input(Ext::qext), 1.0, "published voltage reference"); + success *= scalarMatches( + fixture.input(Ext::qext), 1.0, "published voltage reference" + ); success *= (fixture.evaluate() == 0); success *= allResidualsWithinInitTolerance(fixture.reecb); @@ -940,14 +1024,14 @@ namespace GridKit // voltage error without power-base conversion. fixture.input(Ext::qext) = 1.2; success *= (fixture.evaluate() == 0); - success *= residualsMatch( + success *= residualsMatch( fixture.reecb, {{Vars::EPIV, 0.2}}, "unconverted voltage reference" ); // A reference beyond Vmax is limited. fixture.input(Ext::qext) = 2.0; success *= (fixture.evaluate() == 0); - success *= residualsMatch( + success *= residualsMatch( fixture.reecb, {{Vars::EPIV, 0.5}}, "limited voltage reference" ); @@ -964,7 +1048,11 @@ namespace GridKit Fixture fixture(makeData()); fixture.attachAllInputs(); success *= fixture.initialize(0.75, 0.75); - success *= scalarMatches(fixture.input(Ext::qext), 0.75, "published system-base reactive power"); + success *= scalarMatches( + fixture.input(Ext::qext), + 0.75, + "published system-base reactive power" + ); success *= (fixture.evaluate() == 0); success *= allResidualsWithinInitTolerance(fixture.reecb); @@ -972,7 +1060,7 @@ namespace GridKit // converted value drives the current-command lag. fixture.input(Ext::qext) = 0.85; success *= (fixture.evaluate() == 0); - success *= residualsMatch( + success *= residualsMatch( fixture.reecb, {{Vars::QREF, 0.2}}, "converted reactive reference" ); @@ -1012,7 +1100,9 @@ namespace GridKit setState(fixture.reecb, {{Vars::QREF, 0.8}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, {{Vars::QV, 1.4}}, "constant-reactive lag"); + success *= residualsMatch( + fixture.reecb, {{Vars::QV, 1.4}}, "constant-reactive lag" + ); setState(fixture.reecb, {{Vars::VT, 0.0}}); success *= (fixture.evaluate() == 0); @@ -1024,11 +1114,14 @@ namespace GridKit setState(fixture.reecb, {{Vars::SDIP, 0.0}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, {{Vars::QV, 0.0}}, "gated constant-reactive lag"); + success *= residualsMatch( + fixture.reecb, {{Vars::QV, 0.0}}, "gated constant-reactive lag" + ); } { - // Cascaded Volt/VAr control runs the reactive PI and bypasses the lag. + // Cascaded Volt/VAr control runs the reactive PI and bypasses the + // lag. auto data = makeResidualData(); data.parameters[Params::QFlag] = true; data.parameters[Params::VFlag] = true; @@ -1069,7 +1162,11 @@ namespace GridKit setState(fixture.reecb, {{Vars::SDIP, 0.0}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, {{Vars::XPIQ, 0.0}}, "gated reactive-power integrator"); + success *= residualsMatch( + fixture.reecb, + {{Vars::XPIQ, 0.0}}, + "gated reactive-power integrator" + ); } { @@ -1104,7 +1201,11 @@ namespace GridKit setState(fixture.reecb, {{Vars::SDIP, 0.0}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.reecb, {{Vars::XPIV, 0.0}}, "gated voltage-control integrator"); + success *= residualsMatch( + fixture.reecb, + {{Vars::XPIV, 0.0}}, + "gated voltage-control integrator" + ); } { @@ -1423,7 +1524,7 @@ namespace GridKit setState(fixture.reecb, {{Vars::VT, test_case.input}}); success *= (fixture.evaluate() == 0); const RealT gate = test_case.expected / static_cast(0.2); - success *= residualsMatch( + success *= residualsMatch( fixture.reecb, {{Vars::SDIP, gate - 1.0}}, "active-power voltage gate" @@ -1453,8 +1554,9 @@ namespace GridKit { Fixture fixture(makeResidualData()); fixture.attachAllInputs(); - fixture.input(Ext::pref) = rampReference(test_case.state, test_case.reference); - success *= fixture.prepare(0.0, 0.2); + fixture.input(Ext::pref) = + rampReference(test_case.state, test_case.reference); + success *= fixture.prepare(0.0, 0.2); setControlState(fixture.reecb); RealT limited_rate = 0.6; if (test_case.reference < ZERO) @@ -1605,10 +1707,10 @@ namespace GridKit success *= allResidualsFinite(fixture.reecb); } - const RealT open_limit = std::sqrt(maximum) / TWO; - auto open_data = makeData(); - open_data.parameters[Params::mva] = 100.0; - open_data.parameters[Params::Imax] = open_limit; + const RealT open_limit = std::sqrt(maximum) / TWO; + auto open_data = makeData(); + open_data.parameters[Params::mva] = 100.0; + open_data.parameters[Params::Imax] = open_limit; open_data.parameters[Params::Pqflag] = true; Fixture open(open_data); success *= open.prepare(0.0, 0.0); @@ -1665,10 +1767,12 @@ namespace GridKit kCircleTol ); - const RealT capacity = fixture.reecb.getResidual().getData()[index(Vars::ILCAP)]; + const RealT capacity = + fixture.reecb.getResidual().getData()[index(Vars::ILCAP)]; if (!std::isfinite(capacity) || capacity < ZERO) { - Log::error() << "REECB current circle produced an invalid capacity\n"; + Log::error( + ) << "REECB current circle produced an invalid capacity\n"; success = false; } @@ -1774,7 +1878,7 @@ namespace GridKit auto data = makeJacobianData(); data.parameters[Params::Pqflag] = probe.p_priority; data.parameters[Params::Imax] = probe.imax; - success *= jacobiansMatch( + success *= jacobiansMatch( dependencyTrackingJacobian( data, kNonunitAlpha, success, probe.capacity ), @@ -1786,7 +1890,7 @@ namespace GridKit auto transition_data = makeJacobianData(); transition_data.parameters[Params::Pqflag] = true; transition_data.parameters[Params::Imax] = 0.4; - success *= jacobiansMatch( + success *= jacobiansMatch( dependencyTrackingJacobian( transition_data, kNonunitAlpha, success, 0.1, 0.2, 0.1 ), @@ -1825,7 +1929,7 @@ namespace GridKit { auto data = makeJacobianData(); data.parameters[Params::mva] = probe.mva; - success *= jacobiansMatch( + success *= jacobiansMatch( dependencyTrackingJacobian( data, kNonunitAlpha, success, probe.capacity, probe.epiv ), @@ -1844,7 +1948,7 @@ namespace GridKit injection_data.parameters[Params::Iql1] = -1.2; injection_data.parameters[Params::Iqh1] = 1.5; injection_data.parameters[Params::Vref0] = 2.2; - success *= jacobiansMatch( + success *= jacobiansMatch( dependencyTrackingJacobian(injection_data, kNonunitAlpha, success), enzymeJacobian(injection_data, kNonunitAlpha, success), "voltage-error current injection" @@ -1899,9 +2003,12 @@ namespace GridKit class Fixture { private: - std::array()> input_values_{}; - std::array()> input_indices_{}; - std::array, Utilities::enum_size()> input_nodes_{}; + std::array()> input_values_{}; + std::array()> input_indices_{}; + std::array< + PhasorDynamics::SignalNode, + Utilities::enum_size()> + input_nodes_{}; PhasorDynamics::SignalNode iqcmd_node_; PhasorDynamics::SignalNode ipcmd_node_; @@ -1922,8 +2029,12 @@ namespace GridKit reecb.setSystemBase(kNominalFrequency, system_va_base); if (commands_assigned_) { - reecb.getPorts().out.template port().connect(&iqcmd_node_); - reecb.getPorts().out.template port().connect(&ipcmd_node_); + reecb.getPorts() + .out.template port() + .connect(&iqcmd_node_); + reecb.getPorts() + .out.template port() + .connect(&ipcmd_node_); } } @@ -1935,17 +2046,30 @@ namespace GridKit const IdxT external_index_base = reecb.size() + bus.size(); for (auto variant : Utilities::enum_values()) { - const auto port = static_cast(variant); - input_values_[port] = static_cast(initial_value); - input_indices_[port] = external_index_base + static_cast(port); - input_nodes_[port].link(&input_values_[port], &input_indices_[port]); + const auto port = static_cast(variant); + input_values_[port] = static_cast(initial_value); + input_indices_[port] = + external_index_base + static_cast(port); + input_nodes_[port].link( + &input_values_[port], &input_indices_[port] + ); } - reecb.getPorts().in.template port().connect(&input_nodes_[index(Ext::pe)]); - reecb.getPorts().in.template port().connect(&input_nodes_[index(Ext::qgen)]); - reecb.getPorts().in.template port().connect(&input_nodes_[index(Ext::qext)]); - reecb.getPorts().in.template port().connect(&input_nodes_[index(Ext::pfaref)]); - reecb.getPorts().in.template port().connect(&input_nodes_[index(Ext::pref)]); + reecb.getPorts().in.template port().connect( + &input_nodes_[index(Ext::pe)] + ); + reecb.getPorts().in.template port().connect( + &input_nodes_[index(Ext::qgen)] + ); + reecb.getPorts().in.template port().connect( + &input_nodes_[index(Ext::qext)] + ); + reecb.getPorts().in.template port().connect( + &input_nodes_[index(Ext::pfaref)] + ); + reecb.getPorts().in.template port().connect( + &input_nodes_[index(Ext::pref)] + ); } void setCommands(RealT iqcmd, RealT ipcmd) @@ -1962,11 +2086,13 @@ namespace GridKit reecb.y().setDataUpdated(); } - /// Arrange the allocation, verification, bus, and command prerequisites. + /// Arrange the allocation, verification, bus, and command + /// prerequisites. bool prepare(RealT iqcmd, RealT ipcmd) { const bool ready = (bus.allocate() == 0) && (reecb.allocate() == 0) - && (reecb.verify().passed()) && (bus.initialize() == 0); + && (reecb.verify().passed()) + && (bus.initialize() == 0); if (!ready) { std::cout << "REECB fixture preparation failed\n"; @@ -2204,7 +2330,8 @@ namespace GridKit /// State shared by the residual and priority-circle checks. Each smooth /// transition retains enough margin to take its ideal value. template - void setResidualState(PhasorDynamics::Controller::Reecb& reecb) const + void setResidualState(PhasorDynamics::Controller::Reecb& reecb + ) const { setState( reecb, @@ -2231,7 +2358,8 @@ namespace GridKit /// A neutral driven state for the control probes: unit voltage, cleared /// controller states, and a rested derivative. template - void setControlState(PhasorDynamics::Controller::Reecb& reecb) const + void setControlState(PhasorDynamics::Controller::Reecb& reecb + ) const { reecb.yp().setToConst(static_cast(ZERO)); setState( @@ -2284,8 +2412,12 @@ namespace GridKit /// from the defaults the README documents, at rest and under load. bool defaultsMatchDocumentedValues() const { - Fixture implicit_defaults(makeMinimalData(), kStateVr, kStateVi); - Fixture explicit_defaults(makeExplicitDefaultData(), kStateVr, kStateVi); + Fixture implicit_defaults( + makeMinimalData(), kStateVr, kStateVi + ); + Fixture explicit_defaults( + makeExplicitDefaultData(), kStateVr, kStateVi + ); implicit_defaults.attachAllInputs(); explicit_defaults.attachAllInputs(); @@ -2293,11 +2425,13 @@ namespace GridKit && explicit_defaults.initialize(0.1, 0.2); if (!success) { - std::cout << "REECB documented-default comparison failed to initialize\n"; + std::cout + << "REECB documented-default comparison failed to initialize\n"; return false; } - if (implicit_defaults.evaluate() != 0 || explicit_defaults.evaluate() != 0) + if (implicit_defaults.evaluate() != 0 + || explicit_defaults.evaluate() != 0) { success = false; } @@ -2344,7 +2478,8 @@ namespace GridKit setResidualInputs(explicit_defaults); setResidualState(implicit_defaults.reecb); setResidualState(explicit_defaults.reecb); - if (implicit_defaults.evaluate() != 0 || explicit_defaults.evaluate() != 0) + if (implicit_defaults.evaluate() != 0 + || explicit_defaults.evaluate() != 0) { success = false; } @@ -2378,13 +2513,16 @@ namespace GridKit { PhasorDynamics::SignalNode unlinked_node; Fixture fixture(makeData()); - fixture.reecb.getPorts().in.template port().connect(&unlinked_node); + fixture.reecb.getPorts().in.template port().connect( + &unlinked_node + ); return !fixture.reecb.verify().passed(); } /// Fill state and derivative with a recognizable ramp, restoring the /// aliased commands, so any write by a rejected initialization shows. - void poisonState(Fixture& fixture, RealT iqcmd, RealT ipcmd) const + void poisonState(Fixture& fixture, RealT iqcmd, RealT ipcmd) + const { auto* y = fixture.reecb.y().getData(); auto* yp = fixture.reecb.yp().getData(); @@ -2419,9 +2557,9 @@ namespace GridKit poisonState(fixture, iqcmd, ipcmd); - const auto y_before = copyVector(fixture.reecb.y()); - const auto yp_before = copyVector(fixture.reecb.yp()); - const auto bus_before = copyVector(fixture.bus.y()); + const auto y_before = copyVector(fixture.reecb.y()); + const auto yp_before = copyVector(fixture.reecb.yp()); + const auto bus_before = copyVector(fixture.bus.y()); std::array()> inputs_before{}; for (auto variable : Utilities::enum_values()) { @@ -2432,15 +2570,20 @@ namespace GridKit bool success = true; if (fixture.reecb.initialize() == 0) { - std::cout << "Expected REECB initialization rejection: " << label << '\n'; + std::cout << "Expected REECB initialization rejection: " << label + << '\n'; success = false; } - if (!scalarPreserved(fixture.iqcmd(), iqcmd, "rejected iqcmd preservation")) + if (!scalarPreserved( + fixture.iqcmd(), iqcmd, "rejected iqcmd preservation" + )) { success = false; } - if (!scalarPreserved(fixture.ipcmd(), ipcmd, "rejected ipcmd preservation")) + if (!scalarPreserved( + fixture.ipcmd(), ipcmd, "rejected ipcmd preservation" + )) { success = false; } @@ -2585,7 +2728,8 @@ namespace GridKit return actual == expected; } - bool scalarPreserved(RealT actual, RealT expected, const char* label) const + bool scalarPreserved(RealT actual, RealT expected, const char* label) + const { if (preserved(actual, expected)) { @@ -2646,7 +2790,9 @@ namespace GridKit RealT tolerance = kTol ) const { - return rowsMatch(reecb.getResidual(), values, "residual", context, tolerance); + return rowsMatch( + reecb.getResidual(), values, "residual", context, tolerance + ); } template @@ -2657,7 +2803,9 @@ namespace GridKit RealT tolerance = kTol ) const { - return rowsMatch(reecb.getResidual(), values, "residual", context, tolerance); + return rowsMatch( + reecb.getResidual(), values, "residual", context, tolerance + ); } bool stateMatches( @@ -2716,7 +2864,8 @@ namespace GridKit { if (!std::isfinite(f[row])) { - std::cout << "REECB residual " << variableName(static_cast(row)) + std::cout << "REECB residual " + << variableName(static_cast(row)) << " is not finite\n"; success = false; } @@ -2744,8 +2893,9 @@ namespace GridKit std::getline(output, header); std::getline(output, values_line); - bool success = header == "t,Reecb_reecb_test_iqcmd,Reecb_reecb_test_ipcmd," - "Reecb_reecb_test_vmeas,Reecb_reecb_test_pmeas"; + bool success = header + == "t,Reecb_reecb_test_iqcmd,Reecb_reecb_test_ipcmd," + "Reecb_reecb_test_vmeas,Reecb_reecb_test_pmeas"; const auto values = Tokenizer(values_line, ',')(); if (values.size() != expected.size() + 1) @@ -2788,7 +2938,9 @@ namespace GridKit const auto* values = vector.getData(); for (size_t row = 0; row < snapshot.size(); ++row) { - if (!valueUnchanged(static_cast(values[row]), snapshot[row], what, row)) + if (!valueUnchanged( + static_cast(values[row]), snapshot[row], what, row + )) { success = false; } @@ -2825,7 +2977,8 @@ namespace GridKit return success; } - /// @todo Remove and setup the test to not rely on explicit variable numbering + /// @todo Remove and setup the test to not rely on explicit variable + /// numbering void numberVariables(Fixture& fixture) const { auto* y = fixture.reecb.y().getData(); @@ -2837,13 +2990,16 @@ namespace GridKit y[row].setVariableNumber(2 * row); yp[row].setVariableNumber(2 * row + 1); } - for (size_t row = 0; row < static_cast(fixture.bus.size()); ++row) + for (size_t row = 0; row < static_cast(fixture.bus.size()); + ++row) { bus_y[row].setVariableNumber(2 * (kBusVrColumn + row)); } for (auto variable : Utilities::enum_values()) { - fixture.input(variable).setVariableNumber(2 * fixture.inputIndex(variable)); + fixture.input(variable).setVariableNumber( + 2 * fixture.inputIndex(variable) + ); } fixture.reecb.y().setDataUpdated(); @@ -2913,7 +3069,8 @@ namespace GridKit { if (dependency.size() != enzyme.size()) { - std::cout << "REECB Jacobian row-count mismatch for " << probe << '\n'; + std::cout << "REECB Jacobian row-count mismatch for " << probe + << '\n'; return false; } diff --git a/tests/UnitTests/PhasorDynamics/ControllerRepcaTests.hpp b/tests/UnitTests/PhasorDynamics/ControllerRepcaTests.hpp index 00f0c25754..46be6024ad 100644 --- a/tests/UnitTests/PhasorDynamics/ControllerRepcaTests.hpp +++ b/tests/UnitTests/PhasorDynamics/ControllerRepcaTests.hpp @@ -55,12 +55,15 @@ namespace GridKit PhasorDynamics::Bus bus(1.0, 0.0); PhasorDynamics::Controller::Repca empty(&bus, Data{}); - success *= (empty.size() == static_cast(Utilities::enum_size())); + success *= + (empty.size() == static_cast(Utilities::enum_size())); success *= (!empty.verify().passed()); Fixture configured(makeData()); configured.attachAllInputs(); - success *= (configured.repca.size() == static_cast(Utilities::enum_size())); + success *= + (configured.repca.size() + == static_cast(Utilities::enum_size())); success *= (configured.repca.getMonitor() != nullptr); success *= (configured.repca.verify().passed()); @@ -82,7 +85,9 @@ namespace GridKit integer_parameter.attachAllInputs(); success *= (integer_parameter.repca.verify().passed()); - PhasorDynamics::Controller::Repca missing_signals(&bus, makeData()); + PhasorDynamics::Controller::Repca missing_signals( + &bus, makeData() + ); success *= (!missing_signals.verify().passed()); success *= invalidParameterCase(Params::mva, 0.0); @@ -108,8 +113,8 @@ namespace GridKit success *= invalidParameterCase(Params::Tp, -0.3); success *= invalidParameterCase(Params::Tlag, -0.4); - const RealT nan = std::numeric_limits::quiet_NaN(); - const RealT infinity = std::numeric_limits::infinity(); + const RealT nan = std::numeric_limits::quiet_NaN(); + const RealT infinity = std::numeric_limits::infinity(); const std::array real_parameters{{ Params::mva, Params::Tfltr, Params::Vfrz, Params::Rc, Params::Xc, Params::Kc, Params::dbdlow, Params::dbdupper, @@ -125,16 +130,20 @@ namespace GridKit success *= invalidParameterCase(parameter, infinity); success *= invalidParameterCase(parameter, -infinity); } - success *= invalidParameterCase(Params::mva, std::numeric_limits::max()); + success *= + invalidParameterCase(Params::mva, std::numeric_limits::max()); { - Fixture nonfinite_system_base(makeData(), 1.0, 0.0, infinity); + Fixture nonfinite_system_base( + makeData(), 1.0, 0.0, infinity + ); nonfinite_system_base.attachAllInputs(); success *= (!nonfinite_system_base.repca.verify().passed()); } { - auto tiny_base_data = makeData(); - tiny_base_data.parameters[Params::mva] = std::numeric_limits::min(); + auto tiny_base_data = makeData(); + tiny_base_data.parameters[Params::mva] = + std::numeric_limits::min(); Fixture overflowing_base_ratio( tiny_base_data, 1.0, 0.0, std::numeric_limits::max() ); @@ -182,7 +191,9 @@ namespace GridKit } } - PhasorDynamics::Controller::Repca busless(nullptr, makeData()); + PhasorDynamics::Controller::Repca busless( + nullptr, makeData() + ); success *= (!busless.verify().passed()); success *= unlinkedSignalRejected(); @@ -229,7 +240,8 @@ namespace GridKit return success.report(__func__); } - /// Check initialization state, signal publication, monitors, and flag modes. + /// Check initialization state, signal publication, monitors, and flag + /// modes. TestOutcome initializationAndSignals() { TestStatus success = true; @@ -269,16 +281,23 @@ namespace GridKit success *= stateMatches(fixture.repca, initial_state, "initialization"); success *= scalarPreserved(fixture.input(Ext::ir), 0.2, "preserved ir"); - success *= scalarPreserved(fixture.input(Ext::ii), -0.1, "preserved ii"); + success *= + scalarPreserved(fixture.input(Ext::ii), -0.1, "preserved ii"); success *= scalarPreserved(fixture.input(Ext::p), 0.4, "preserved p"); success *= scalarPreserved(fixture.input(Ext::q), 0.1, "preserved q"); - success *= scalarPreserved(fixture.input(Ext::freq), 0.99, "preserved freq"); + success *= + scalarPreserved(fixture.input(Ext::freq), 0.99, "preserved freq"); success *= scalarPreserved(fixture.qext(), 0.25, "preserved qext"); success *= scalarPreserved(fixture.pext(), 0.45, "preserved pext"); - success *= scalarMatches(fixture.input(Ext::vref), 0.984002032518226, "published vref"); - success *= scalarMatches(fixture.input(Ext::pref), 0.4, "published pref"); - success *= scalarMatches(fixture.input(Ext::qref), 0.1, "published qref"); - success *= scalarMatches(fixture.input(Ext::freqref), 0.99, "published freqref"); + success *= scalarMatches( + fixture.input(Ext::vref), 0.984002032518226, "published vref" + ); + success *= + scalarMatches(fixture.input(Ext::pref), 0.4, "published pref"); + success *= + scalarMatches(fixture.input(Ext::qref), 0.1, "published qref"); + success *= + scalarMatches(fixture.input(Ext::freqref), 0.99, "published freqref"); for (size_t row = 0; row < Utilities::enum_size(); ++row) { @@ -292,7 +311,8 @@ namespace GridKit constexpr RealT absolute_tolerance = 2.5e-7; - success *= (fixture.repca.setAbsoluteTolerance(absolute_tolerance) == 0); + success *= + (fixture.repca.setAbsoluteTolerance(absolute_tolerance) == 0); const auto* tolerances = fixture.repca.absoluteTolerance().getData(); for (size_t row = 0; row < Utilities::enum_size(); ++row) @@ -309,7 +329,8 @@ namespace GridKit 0.2, 0.8, }}; - success *= monitorMatches(fixture.repca, initial_monitors, "initialization"); + success *= + monitorMatches(fixture.repca, initial_monitors, "initialization"); success *= allResidualsWithinInitTolerance(fixture.repca); @@ -322,9 +343,13 @@ namespace GridKit exact_commands.attachAllInputs(); setInitializationInputs(exact_commands); success *= exact_commands.initialize(0.25, 0.45); - success *= scalarPreserved(exact_commands.qext(), 0.25, "qext signal"); - success *= scalarPreserved(exact_commands.pext(), 0.45, "pext signal"); - success *= scalarPreserved(exact_commands.input(Ext::qref), 0.1, "qref signal"); + success *= + scalarPreserved(exact_commands.qext(), 0.25, "qext signal"); + success *= + scalarPreserved(exact_commands.pext(), 0.45, "pext signal"); + success *= scalarPreserved( + exact_commands.input(Ext::qref), 0.1, "qref signal" + ); success *= (exact_commands.repca.evaluateResidual() == 0); success *= allResidualsWithinInitTolerance(exact_commands.repca); } @@ -333,12 +358,13 @@ namespace GridKit fallback.attachAllInputs(0.0, false); setInitializationInputs(fallback); const auto previous_verbosity = Log::verbosity(); - // Suppress the expected missing-frequency warning for this fallback case. - // Use EVERYTHING to inspect the diagnostic. + // Suppress the expected missing-frequency warning for this fallback + // case. Use EVERYTHING to inspect the diagnostic. Log::setVerbosity(Log::Verbosity::NONE); success *= fallback.initialize(0.25, 0.45); Log::setVerbosity(previous_verbosity); - success *= scalarMatches(fallback.input(Ext::freqref), 1.0, "default frequency"); + success *= + scalarMatches(fallback.input(Ext::freqref), 1.0, "default frequency"); success *= (fallback.repca.evaluateResidual() == 0); success *= allResidualsWithinInitTolerance(fallback.repca); @@ -453,7 +479,8 @@ namespace GridKit success *= stateMatches(scenario.repca, expected_state, test_case.label); success *= scalarMatches(scenario.qext(), 0.25, test_case.label); - success *= scalarMatches(scenario.pext(), test_case.pext, test_case.label); + success *= + scalarMatches(scenario.pext(), test_case.pext, test_case.label); success *= allResidualsWithinInitTolerance(scenario.repca); } @@ -466,8 +493,8 @@ namespace GridKit TestStatus success = true; const auto previous_verbosity = Log::verbosity(); - // Suppress expected errors and limit-adjustment warnings from the cases below. - // Use EVERYTHING to inspect those diagnostics. + // Suppress expected errors and limit-adjustment warnings from the cases + // below. Use EVERYTHING to inspect those diagnostics. Log::setVerbosity(Log::Verbosity::NONE); const auto data = makeInitializationData(); @@ -479,8 +506,8 @@ namespace GridKit RealT pext; }; - const RealT nan = std::numeric_limits::quiet_NaN(); - const RealT infinity = std::numeric_limits::infinity(); + const RealT nan = std::numeric_limits::quiet_NaN(); + const RealT infinity = std::numeric_limits::infinity(); const std::array rejection_cases{{ {"nonfinite qext", infinity, 0.45}, {"nonfinite pext", 0.25, infinity}, @@ -533,11 +560,11 @@ namespace GridKit collapsed_data.parameters[Params::Pmin] = 0.9; collapsed_data.parameters[Params::Pmax] = 0.9; - auto reactive_aw_data = makeInitializationData(); + auto reactive_aw_data = makeInitializationData(); reactive_aw_data.parameters[Params::dbdupper] = 0.03; reactive_aw_data.parameters[Params::emin] = 0.0; - const std::array voltage_reference_values{{false, true}}; + const std::array voltage_reference_values{{false, true}}; const std::array, 2> voltage_cases{{ {0.8, 0.6}, {0.2, 0.0}, @@ -564,7 +591,8 @@ namespace GridKit asymmetric_reactive_state, "asymmetric reactive initialization" ); - success *= allResidualsWithinInitTolerance(asymmetric_reactive.repca); + success *= + allResidualsWithinInitTolerance(asymmetric_reactive.repca); } } @@ -577,7 +605,8 @@ namespace GridKit setInitializationInputs(frozen_reactive_rate); success *= frozen_reactive_rate.initialize(0.25, 0.45); success *= (frozen_reactive_rate.repca.evaluateResidual() == 0); - success *= allResidualsWithinInitTolerance(frozen_reactive_rate.repca); + success *= + allResidualsWithinInitTolerance(frozen_reactive_rate.repca); } { @@ -644,8 +673,9 @@ namespace GridKit success *= allResidualsWithinInitTolerance(asymmetric_active.repca); } - auto overflow_data = makeInitializationData(); - overflow_data.parameters[Params::Rc] = std::numeric_limits::max(); + auto overflow_data = makeInitializationData(); + overflow_data.parameters[Params::Rc] = + std::numeric_limits::max(); success *= initializationRejectedAtomically( overflow_data, 0.25, @@ -666,11 +696,15 @@ namespace GridKit const auto invalid_yp = copyVector(invalid_fixture.repca.yp()); if (invalid_fixture.repca.initialize() == 0) { - std::cout << "Expected REPCA initialization rejection: invalid configuration\n"; + std::cout << "Expected REPCA initialization rejection: invalid " + "configuration\n"; success = false; } - success *= vectorUnchanged(invalid_fixture.repca.y(), invalid_y, "state"); - success *= vectorUnchanged(invalid_fixture.repca.yp(), invalid_yp, "derivative"); + success *= + vectorUnchanged(invalid_fixture.repca.y(), invalid_y, "state"); + success *= vectorUnchanged( + invalid_fixture.repca.yp(), invalid_yp, "derivative" + ); } // A command exactly on a limit is reconstructed through the offset @@ -848,7 +882,8 @@ namespace GridKit } /// Check every residual row against an independent numerical answer key. - /// The expected values are literals, not a second implementation of REPCA. + /// The expected values are literals, not a second implementation of + /// REPCA. TestOutcome residualEquations() { TestStatus success = true; @@ -878,7 +913,7 @@ namespace GridKit success *= (static_cast(fixture.repca.getResidual().getSize()) == expected_residuals.size()); - const auto* residual = fixture.repca.getResidual().getData(); + const auto* residual = fixture.repca.getResidual().getData(); for (size_t row = 0; row < expected_residuals.size(); ++row) { const auto variable = expected_residuals[row].variable; @@ -898,7 +933,8 @@ namespace GridKit return success.report(__func__); } - /// Check reactive modes, smooth limits, antiwindup, and lead-lag behavior. + /// Check reactive modes, smooth limits, antiwindup, and lead-lag + /// behavior. TestOutcome reactiveControl() { TestStatus success = true; @@ -972,7 +1008,9 @@ namespace GridKit }}; for (const auto& test_case : freeze_cases) { - setState(freeze.repca, {{Vars::V, test_case.input}, {Vars::SFRZ, 0.0}}); + setState( + freeze.repca, {{Vars::V, test_case.input}, {Vars::SFRZ, 0.0}} + ); success *= (freeze.repca.evaluateResidual() == 0); success *= residualsMatch( freeze.repca, {{Vars::SFRZ, test_case.expected}}, "freeze gate" @@ -989,7 +1027,9 @@ namespace GridKit }}; for (const auto& test_case : deadband_cases) { - setState(fixture.repca, {{Vars::ERQ, test_case.input}, {Vars::ERQDB, 0.0}}); + setState( + fixture.repca, {{Vars::ERQ, test_case.input}, {Vars::ERQDB, 0.0}} + ); success *= (fixture.repca.evaluateResidual() == 0); success *= residualsMatch( fixture.repca, @@ -1005,7 +1045,9 @@ namespace GridKit }}; for (const auto& test_case : error_limit_cases) { - setState(fixture.repca, {{Vars::ERQDB, test_case.input}, {Vars::ERQLIM, 0.0}}); + setState( + fixture.repca, {{Vars::ERQDB, test_case.input}, {Vars::ERQLIM, 0.0}} + ); success *= (fixture.repca.evaluateResidual() == 0); success *= residualsMatch( fixture.repca, @@ -1199,7 +1241,9 @@ namespace GridKit }}; for (const auto& test_case : error_limit_cases) { - setState(fixture.repca, {{Vars::EP, test_case.input}, {Vars::EPLIM, 0.0}}); + setState( + fixture.repca, {{Vars::EP, test_case.input}, {Vars::EPLIM, 0.0}} + ); success *= (fixture.repca.evaluateResidual() == 0); success *= residualsMatch( fixture.repca, @@ -1217,9 +1261,8 @@ namespace GridKit { setState( fixture.repca, - {{Vars::XPPI, test_case.input}, - {Vars::EPLIM, 0.0}, - {Vars::PPI, 0.0}} + {{Vars::XPPI, test_case.input}, {Vars::EPLIM, 0.0}, {Vars::PPI, 0.0} + } ); success *= (fixture.repca.evaluateResidual() == 0); success *= residualsMatch( @@ -1343,8 +1386,9 @@ namespace GridKit } #ifdef GRIDKIT_ENABLE_ENZYME - /// One rich state, both selector settings, and a non-unit alpha drive both - /// sensitivity paths; every Enzyme CSR row must match dependency tracking. + /// One rich state, both selector settings, and a non-unit alpha drive + /// both sensitivity paths; every Enzyme CSR row must match dependency + /// tracking. TestOutcome jacobian() { TestStatus success = true; @@ -1362,7 +1406,7 @@ namespace GridKit all_flags_off_data.parameters[Params::VcompFlag] = false; all_flags_off_data.parameters[Params::RefFlag] = false; all_flags_off_data.parameters[Params::Freqflag] = false; - success *= jacobianMatches( + success *= jacobianMatches( enzymeJacobian(all_flags_off_data, success), dependencyTrackingJacobian(all_flags_off_data, success), "all-flags-off Enzyme versus dependency tracking", @@ -1426,15 +1470,19 @@ namespace GridKit }; /// Owns the regulated bus, REPCA, assigned command nodes, and attached - /// input nodes. Signal storage precedes the model so every referenced node - /// outlives REPCA; copying would invalidate the model and node pointers. + /// input nodes. Signal storage precedes the model so every referenced + /// node outlives REPCA; copying would invalidate the model and node + /// pointers. template class Fixture { private: - std::array()> input_values_{}; - std::array()> input_indices_{}; - std::array, Utilities::enum_size()> input_nodes_{}; + std::array()> input_values_{}; + std::array()> input_indices_{}; + std::array< + PhasorDynamics::SignalNode, + Utilities::enum_size()> + input_nodes_{}; PhasorDynamics::SignalNode qext_node_; PhasorDynamics::SignalNode pext_node_; @@ -1452,8 +1500,12 @@ namespace GridKit repca.setSystemBase(60.0, system_va_base); if (assign_command_outputs) { - repca.getPorts().out.template port().connect(&qext_node_); - repca.getPorts().out.template port().connect(&pext_node_); + repca.getPorts() + .out.template port() + .connect(&qext_node_); + repca.getPorts() + .out.template port() + .connect(&pext_node_); } } @@ -1465,16 +1517,27 @@ namespace GridKit const IdxT external_index_base = repca.size() + bus.size(); for (auto variant : Utilities::enum_values()) { - const auto port = static_cast(variant); - input_values_[port] = static_cast(initial_value); - input_indices_[port] = external_index_base + static_cast(port); - input_nodes_[port].link(&input_values_[port], &input_indices_[port]); + const auto port = static_cast(variant); + input_values_[port] = static_cast(initial_value); + input_indices_[port] = + external_index_base + static_cast(port); + input_nodes_[port].link( + &input_values_[port], &input_indices_[port] + ); } - repca.getPorts().in.template port().connect(&input_nodes_[index(Ext::ir)]); - repca.getPorts().in.template port().connect(&input_nodes_[index(Ext::ii)]); - repca.getPorts().in.template port().connect(&input_nodes_[index(Ext::p)]); - repca.getPorts().in.template port().connect(&input_nodes_[index(Ext::q)]); + repca.getPorts().in.template port().connect( + &input_nodes_[index(Ext::ir)] + ); + repca.getPorts().in.template port().connect( + &input_nodes_[index(Ext::ii)] + ); + repca.getPorts().in.template port().connect( + &input_nodes_[index(Ext::p)] + ); + repca.getPorts().in.template port().connect( + &input_nodes_[index(Ext::q)] + ); } void attachAllInputs( @@ -1485,12 +1548,22 @@ namespace GridKit if (attach_frequency) { - repca.getPorts().in.template port().connect(&input_nodes_[index(Ext::freq)]); + repca.getPorts() + .in.template port() + .connect(&input_nodes_[index(Ext::freq)]); } - repca.getPorts().in.template port().connect(&input_nodes_[index(Ext::vref)]); - repca.getPorts().in.template port().connect(&input_nodes_[index(Ext::pref)]); - repca.getPorts().in.template port().connect(&input_nodes_[index(Ext::qref)]); - repca.getPorts().in.template port().connect(&input_nodes_[index(Ext::freqref)]); + repca.getPorts().in.template port().connect( + &input_nodes_[index(Ext::vref)] + ); + repca.getPorts().in.template port().connect( + &input_nodes_[index(Ext::pref)] + ); + repca.getPorts().in.template port().connect( + &input_nodes_[index(Ext::qref)] + ); + repca.getPorts() + .in.template port() + .connect(&input_nodes_[index(Ext::freqref)]); } void setCommands(RealT qext, RealT pext) @@ -1501,11 +1574,13 @@ namespace GridKit repca.y().setDataUpdated(); } - /// Arrange the allocation, verification, bus, and command prerequisites. + /// Arrange the allocation, verification, bus, and command + /// prerequisites. bool prepare(RealT qext, RealT pext) { const bool success = (bus.allocate() == 0) && (repca.allocate() == 0) - && (repca.verify().passed()) && (bus.initialize() == 0); + && (repca.verify().passed()) + && (bus.initialize() == 0); if (!success) { std::cout << "REPCA fixture preparation failed\n"; @@ -1557,8 +1632,8 @@ namespace GridKit static constexpr RealT kStateVi = 0.4; static constexpr RealT kNonunitAlpha = 2.5; - static constexpr size_t kBusVrColumn = Utilities::enum_size(); - static constexpr size_t kBusViColumn = kBusVrColumn + 1; + static constexpr size_t kBusVrColumn = Utilities::enum_size(); + static constexpr size_t kBusViColumn = kBusVrColumn + 1; static constexpr size_t kExternalColumnBase = kBusViColumn + 1; static constexpr size_t externalColumn(size_t port) @@ -1700,11 +1775,13 @@ namespace GridKit } template - void setAnswerKeyState(PhasorDynamics::Controller::Repca& repca) const + void setAnswerKeyState(PhasorDynamics::Controller::Repca& repca + ) const { // Every smooth-transition argument keeps a saturation margin, and // every clamp that must pass its input through sits at the midpoint - // of its limits or well inside them, so each row carries its ideal value. + // of its limits or well inside them, so each row carries its ideal + // value. setState( repca, {{Vars::VMEAS, 0.85}, {Vars::QMEAS, 0.45}, {Vars::XQPI, 0.0}, @@ -1746,7 +1823,8 @@ namespace GridKit && explicit_defaults.initialize(0.1, 0.2); if (!success) { - std::cout << "REPCA documented-default comparison failed to initialize\n"; + std::cout + << "REPCA documented-default comparison failed to initialize\n"; return false; } @@ -1842,7 +1920,9 @@ namespace GridKit Fixture fixture(makeData()); fixture.attachAllInputs(); PhasorDynamics::SignalNode unlinked_node; - fixture.repca.getPorts().in.template port().connect(&unlinked_node); + fixture.repca.getPorts().in.template port().connect( + &unlinked_node + ); return !fixture.repca.verify().passed(); } @@ -1893,9 +1973,9 @@ namespace GridKit poisonState(fixture, qext, pext); - const auto y_before = copyVector(fixture.repca.y()); - const auto yp_before = copyVector(fixture.repca.yp()); - const auto bus_before = copyVector(fixture.bus.y()); + const auto y_before = copyVector(fixture.repca.y()); + const auto yp_before = copyVector(fixture.repca.yp()); + const auto bus_before = copyVector(fixture.bus.y()); std::array()> inputs_before{}; for (auto variant : Utilities::enum_values()) { @@ -1906,15 +1986,20 @@ namespace GridKit bool success = true; if (fixture.repca.initialize() == 0) { - std::cout << "Expected REPCA initialization rejection: " << label << '\n'; + std::cout << "Expected REPCA initialization rejection: " << label + << '\n'; success = false; } - if (!scalarPreserved(fixture.qext(), qext, "rejected qext preservation")) + if (!scalarPreserved( + fixture.qext(), qext, "rejected qext preservation" + )) { success = false; } - if (!scalarPreserved(fixture.pext(), pext, "rejected pext preservation")) + if (!scalarPreserved( + fixture.pext(), pext, "rejected pext preservation" + )) { success = false; } @@ -2028,8 +2113,9 @@ namespace GridKit { std::cout << ' ' << context; } - std::cout << " mismatch: " << std::setprecision(std::numeric_limits::max_digits10) << actual - << " != " << expected << '\n'; + std::cout << " mismatch: " + << std::setprecision(std::numeric_limits::max_digits10) + << actual << " != " << expected << '\n'; return false; } @@ -2041,8 +2127,9 @@ namespace GridKit { return true; } - std::cout << label << " mismatch: " << std::setprecision(std::numeric_limits::max_digits10) << actual - << " != " << expected << '\n'; + std::cout << label << " mismatch: " + << std::setprecision(std::numeric_limits::max_digits10) + << actual << " != " << expected << '\n'; return false; } @@ -2100,14 +2187,16 @@ namespace GridKit return actual == expected; } - bool scalarPreserved(RealT actual, RealT expected, const char* label) const + bool scalarPreserved(RealT actual, RealT expected, const char* label) + const { if (preserved(actual, expected)) { return true; } - std::cout << label << " changed: " << std::setprecision(std::numeric_limits::max_digits10) << actual - << " != " << expected << '\n'; + std::cout << label << " changed: " + << std::setprecision(std::numeric_limits::max_digits10) + << actual << " != " << expected << '\n'; return false; } @@ -2119,9 +2208,9 @@ namespace GridKit { return true; } - std::cout << "REPCA " << what << ' ' << index - << " changed: " << std::setprecision(std::numeric_limits::max_digits10) << actual - << " != " << expected << '\n'; + std::cout << "REPCA " << what << ' ' << index << " changed: " + << std::setprecision(std::numeric_limits::max_digits10) + << actual << " != " << expected << '\n'; return false; } @@ -2280,7 +2369,8 @@ namespace GridKit return success; } - std::vector expectedJacobian() const + std::vector expectedJacobian( + ) const { return { {{index(Vars::VMEAS), -6.0}, {index(Vars::VCTRL), 5.0}}, @@ -2336,7 +2426,8 @@ namespace GridKit }; } - std::vector expectedJacobianAllFlagsOff() const + std::vector + expectedJacobianAllFlagsOff() const { auto expected = expectedJacobian(); expected[index(Vars::VCTRL)] = { @@ -2358,7 +2449,8 @@ namespace GridKit return expected; } - std::vector expectedJacobianNonunitAlpha() const + std::vector + expectedJacobianNonunitAlpha() const { auto expected = expectedJacobian(); expected[index(Vars::VMEAS)][index(Vars::VMEAS)] = -7.5; @@ -2406,7 +2498,9 @@ namespace GridKit bool success = true; for (size_t row = 0; row < Utilities::enum_size(); ++row) { - if (!jacobianRowMatches(actual[row], expected[row], row, source, tolerance)) + if (!jacobianRowMatches( + actual[row], expected[row], row, source, tolerance + )) { success = false; } @@ -2414,7 +2508,8 @@ namespace GridKit return success; } - /// @todo Remove and setup the test to not rely on explicit variable numbering + /// @todo Remove and setup the test to not rely on explicit variable + /// numbering void numberVariables(Fixture& fixture) const { auto* y = fixture.repca.y().getData(); @@ -2426,13 +2521,16 @@ namespace GridKit y[row].setVariableNumber(2 * row); yp[row].setVariableNumber(2 * row + 1); } - for (size_t row = 0; row < static_cast(fixture.bus.size()); ++row) + for (size_t row = 0; row < static_cast(fixture.bus.size()); + ++row) { bus_y[row].setVariableNumber(2 * (kBusVrColumn + row)); } for (auto variable : Utilities::enum_values()) { - fixture.input(variable).setVariableNumber(2 * fixture.inputIndex(variable)); + fixture.input(variable).setVariableNumber( + 2 * fixture.inputIndex(variable) + ); } fixture.repca.y().setDataUpdated(); diff --git a/tests/UnitTests/PhasorDynamics/ConverterRegcaTests.hpp b/tests/UnitTests/PhasorDynamics/ConverterRegcaTests.hpp index 0d385419f2..53661fce63 100644 --- a/tests/UnitTests/PhasorDynamics/ConverterRegcaTests.hpp +++ b/tests/UnitTests/PhasorDynamics/ConverterRegcaTests.hpp @@ -50,10 +50,15 @@ namespace GridKit PhasorDynamics::Bus bus(1.0, 0.0); PhasorDynamics::Converter::Regca minimal(&bus, Data{}); - success *= (minimal.size() == static_cast(Utilities::enum_size())); + success *= + (minimal.size() == static_cast(Utilities::enum_size())); - PhasorDynamics::Converter::Regca configured(&bus, makeData()); - success *= (configured.size() == static_cast(Utilities::enum_size())); + PhasorDynamics::Converter::Regca configured( + &bus, makeData() + ); + success *= + (configured.size() == static_cast(Utilities::enum_size()) + ); success *= (configured.getMonitor() != nullptr); success *= (configured.verify().passed()); @@ -81,18 +86,26 @@ namespace GridKit success *= invalidParameterCase(bus, Params::VL1, 0.3); success *= invalidParameterCase(bus, Params::VA1, 0.3); - // Vhvmax must lie strictly above VA1: reject equality and reversed ordering. + // Vhvmax must lie strictly above VA1: reject equality and reversed + // ordering. success *= invalidParameterCase(bus, Params::Vhvmax, kVa1); - success *= invalidParameterCase(bus, Params::Vhvmax, HALF * kVa1); + success *= + invalidParameterCase(bus, Params::Vhvmax, HALF * kVa1); // A null bus and an attached command with no linked source count as // configuration errors on the same footing as bad parameters. - PhasorDynamics::Converter::Regca busless(nullptr, makeData()); + PhasorDynamics::Converter::Regca busless( + nullptr, makeData() + ); success *= (!busless.verify().passed()); PhasorDynamics::SignalNode unlinked_node; - PhasorDynamics::Converter::Regca unlinked(&bus, makeData()); - unlinked.getPorts().in.template port().connect(&unlinked_node); + PhasorDynamics::Converter::Regca unlinked( + &bus, makeData() + ); + unlinked.getPorts() + .in.template port() + .connect(&unlinked_node); success *= (!unlinked.verify().passed()); // Zero time constants are raised to the well-posedness floor with a @@ -131,7 +144,9 @@ namespace GridKit // Outputs alias y directly, so one published port pins the wiring. PhasorDynamics::SignalNode pbranch_node; - fixture.regca.getPorts().out.template port().connect(&pbranch_node); + fixture.regca.getPorts() + .out.template port() + .connect(&pbranch_node); success *= fixture.initialize(); success *= (fixture.evaluate() == 0); @@ -141,19 +156,32 @@ namespace GridKit const auto* y = fixture.regca.y().getData(); success *= scalarMatches(y[index(Vars::VM)], 1.0, "VM"); success *= scalarMatches(y[index(Vars::VT)], 1.0, "VT"); - success *= scalarMatches(y[index(Vars::IQ)] - y[index(Vars::IQEXTRA)], -0.2, "net reactive current"); - success *= scalarMatches(y[index(Vars::IR)], 0.26, "IR"); - success *= scalarMatches(y[index(Vars::II)], 0.32, "II"); - success *= scalarMatches(y[index(Vars::PBR)], 0.4, "PBR"); - success *= scalarMatches(y[index(Vars::QBR)], -0.1, "QBR"); - - success *= scalarMatches(fixture.ipcmd, 0.5 * y[index(Vars::IP)], "published ipcmd base conversion"); - success *= scalarMatches(fixture.iqcmd, 0.5 * y[index(Vars::IQ)], "published iqcmd base conversion"); + success *= scalarMatches( + y[index(Vars::IQ)] - y[index(Vars::IQEXTRA)], + -0.2, + "net reactive current" + ); + success *= scalarMatches(y[index(Vars::IR)], 0.26, "IR"); + success *= scalarMatches(y[index(Vars::II)], 0.32, "II"); + success *= scalarMatches(y[index(Vars::PBR)], 0.4, "PBR"); + success *= scalarMatches(y[index(Vars::QBR)], -0.1, "QBR"); + + success *= scalarMatches( + fixture.ipcmd, + 0.5 * y[index(Vars::IP)], + "published ipcmd base conversion" + ); + success *= scalarMatches( + fixture.iqcmd, + 0.5 * y[index(Vars::IQ)], + "published iqcmd base conversion" + ); success *= scalarMatches(pbranch_node.read(), 0.4, "pbranch signal"); // The accumulated bus injection is the system-base branch current. success *= scalarMatches(fixture.bus.Ir(), 0.26, "bus real injection"); - success *= scalarMatches(fixture.bus.Ii(), 0.32, "bus imaginary injection"); + success *= + scalarMatches(fixture.bus.Ii(), 0.32, "bus imaginary injection"); success *= allResidualsZero(fixture.regca); @@ -168,9 +196,11 @@ namespace GridKit success *= (latched.evaluate() == 0); success *= allResidualsZero(latched.regca); - auto* latched_y = latched.regca.y().getData(); - success *= scalarMatches(latched_y[index(Vars::PBR)], 0.6, "latched PBR"); - success *= scalarMatches(latched_y[index(Vars::QBR)], 0.2, "latched QBR"); + auto* latched_y = latched.regca.y().getData(); + success *= + scalarMatches(latched_y[index(Vars::PBR)], 0.6, "latched PBR"); + success *= + scalarMatches(latched_y[index(Vars::QBR)], 0.2, "latched QBR"); latched_y[index(Vars::IP)] -= 0.1; // arbitrary current displacement latched_y[index(Vars::IQ)] -= 0.06; // arbitrary current displacement @@ -180,8 +210,12 @@ namespace GridKit // The latched commands restore both displaced states at their ideal // interior first-order rates. const auto* f = latched.regca.getResidual().getData(); - success *= scalarMatches(f[index(Vars::IP)], 0.5, "latched active-current rate", kSmoothTol); - success *= scalarMatches(f[index(Vars::IQ)], 0.3, "latched reactive-current rate", kSmoothTol); + success *= scalarMatches( + f[index(Vars::IP)], 0.5, "latched active-current rate", kSmoothTol + ); + success *= scalarMatches( + f[index(Vars::IQ)], 0.3, "latched reactive-current rate", kSmoothTol + ); return success.report(__func__); } @@ -193,8 +227,8 @@ namespace GridKit const RealT vm = 0.65; const auto previous_verbosity = Log::verbosity(); - // Suppress expected errors from the inadmissible initialization cases below. - // Use EVERYTHING to inspect those diagnostics. + // Suppress expected errors from the inadmissible initialization cases + // below. Use EVERYTHING to inspect those diagnostics. Log::setVerbosity(Log::Verbosity::NONE); struct RejectionCase @@ -233,7 +267,8 @@ namespace GridKit success *= fixture.prepare(); if (fixture.regca.initialize() == 0) { - std::cout << "Expected rejection: LVPL ceiling below the active current\n"; + std::cout + << "Expected rejection: LVPL ceiling below the active current\n"; success = false; } } @@ -251,8 +286,12 @@ namespace GridKit success *= allResidualsZero(fixture.regca); const auto* y = fixture.regca.y().getData(); - success *= scalarMatches(y[index(Vars::PBR)], 0.2, "PBR at the LVACM upper breakpoint"); - success *= scalarMatches(y[index(Vars::QBR)], 0.1, "QBR at the LVACM upper breakpoint"); + success *= scalarMatches( + y[index(Vars::PBR)], 0.2, "PBR at the LVACM upper breakpoint" + ); + success *= scalarMatches( + y[index(Vars::QBR)], 0.1, "QBR at the LVACM upper breakpoint" + ); } // Inside the LVPL segment, initialization accepts an active current @@ -274,7 +313,9 @@ namespace GridKit std::cout << "IP is not below the active LVPL limit\n"; success = false; } - success *= scalarMatches(y[index(Vars::PBR)], 0.25, "PBR below the LVPL limit"); + success *= scalarMatches( + y[index(Vars::PBR)], 0.25, "PBR below the LVPL limit" + ); } // Above the upper breakpoint the ceiling releases: an operating point @@ -319,7 +360,8 @@ namespace GridKit std::cout << "Bypassed IP did not exceed the LVPL limit\n"; success = false; } - success *= scalarMatches(y[index(Vars::PBR)], 0.25, "PBR with LVPL bypassed"); + success *= + scalarMatches(y[index(Vars::PBR)], 0.25, "PBR with LVPL bypassed"); } Log::setVerbosity(previous_verbosity); @@ -366,13 +408,15 @@ namespace GridKit {Vars::QBR, "QBR", 0.0}, }}; - const auto& residual = fixture.regca.getResidual(); - success *= (static_cast(residual.getSize()) == expected.size()); + const auto& residual = fixture.regca.getResidual(); + success *= (static_cast(residual.getSize()) == expected.size()); const auto* f = residual.getData(); for (const auto& row : expected) { - success *= scalarMatches(f[index(row.variable)], row.value, row.name, kSmoothTol); + success *= scalarMatches( + f[index(row.variable)], row.value, row.name, kSmoothTol + ); } return success.report(__func__); @@ -423,7 +467,7 @@ namespace GridKit success *= (fixture.evaluate() == 0); const auto* f = fixture.regca.getResidual().getData(); - success *= scalarMatches( + success *= scalarMatches( f[index(Vars::IP)], test_case.expected_rate, test_case.label ); } @@ -466,7 +510,7 @@ namespace GridKit success *= (fixture.evaluate() == 0); const auto* f = fixture.regca.getResidual().getData(); - success *= scalarMatches( + success *= scalarMatches( f[index(Vars::IP)], test_case.expected_rate, test_case.label ); } @@ -491,7 +535,7 @@ namespace GridKit success *= (fixture.evaluate() == 0); const auto* f = fixture.regca.getResidual().getData(); - success *= scalarMatches( + success *= scalarMatches( f[index(Vars::IP)], -1.925, "falling ceiling drags Ip" ); } @@ -512,7 +556,7 @@ namespace GridKit success *= (fixture.evaluate() == 0); const auto* f = fixture.regca.getResidual().getData(); - success *= scalarMatches( + success *= scalarMatches( f[index(Vars::IP)], 0.7, "released ceiling above the breakpoint" ); } @@ -557,14 +601,16 @@ namespace GridKit success *= (fixture.evaluate() == 0); const auto* f = fixture.regca.getResidual().getData(); - success *= scalarMatches(f[index(Vars::IQ)], test_case.expected_rate, test_case.label); + success *= scalarMatches( + f[index(Vars::IQ)], test_case.expected_rate, test_case.label + ); } return success.report(__func__); } - /// High-voltage reactive current management: initialization, compatibility, - /// threshold behavior, and the local derivative. + /// High-voltage reactive current management: initialization, + /// compatibility, threshold behavior, and the local derivative. TestOutcome highVoltageManagement() { TestStatus success = true; @@ -583,7 +629,7 @@ namespace GridKit const auto* y = fixture.regca.y().getData(); const RealT extra_current = y[index(Vars::IQEXTRA)]; - success *= scalarMatches( + success *= scalarMatches( extra_current, hvrcmTransition(), "IQEXTRA at initialization" ); success *= scalarMatches( @@ -601,13 +647,19 @@ namespace GridKit auto data = makeData(); data.parameters[Params::Khv] = gain; - Fixture fixture(data, kHvrcmVoltageLimit - hvrcmTransition()); + Fixture fixture( + data, kHvrcmVoltageLimit - hvrcmTransition() + ); success *= fixture.initialize(); success *= (fixture.evaluate() == 0); success *= allResidualsZero(fixture.regca); const auto* y = fixture.regca.y().getData(); - success *= scalarMatches(y[index(Vars::IQEXTRA)], hvrcmTransition(), "IQEXTRA at a supplied Khv"); + success *= scalarMatches( + y[index(Vars::IQEXTRA)], + hvrcmTransition(), + "IQEXTRA at a supplied Khv" + ); } } @@ -627,18 +679,27 @@ namespace GridKit return fixture.regca.getResidual().getData()[index(Vars::IQEXTRA)]; }; - const RealT below = residualAt(kHvrcmVoltageLimit - kHvrcmOffset, 0.0); - const RealT at = residualAt(kHvrcmVoltageLimit, 0.0); - const RealT above = residualAt(kHvrcmVoltageLimit + kHvrcmOffset, 0.0); + const RealT below = + residualAt(kHvrcmVoltageLimit - kHvrcmOffset, 0.0); + const RealT at = residualAt(kHvrcmVoltageLimit, 0.0); + const RealT above = + residualAt(kHvrcmVoltageLimit + kHvrcmOffset, 0.0); - success *= scalarMatches(at, hvrcmTransition(), "HVRCM residual at the threshold"); - success *= scalarMatches(above - below, kHvrcmOffset, "HVRCM symmetric residual difference"); + success *= scalarMatches( + at, hvrcmTransition(), "HVRCM residual at the threshold" + ); + success *= scalarMatches( + above - below, kHvrcmOffset, "HVRCM symmetric residual difference" + ); const RealT shifted = residualAt(kHvrcmVoltageLimit - 0.1, 0.1); - success *= scalarMatches(shifted - at, -0.1, "HVRCM equal-margin residual shift"); + success *= scalarMatches( + shifted - at, -0.1, "HVRCM equal-margin residual shift" + ); } - // At the threshold, voltage and current sensitivities have magnitude 1/2. + // At the threshold, voltage and current sensitivities have magnitude + // 1/2. { using DepVar = DependencyTracking::Variable; @@ -742,14 +803,18 @@ namespace GridKit { ipcmd = value; ipcmd_node.link(&ipcmd, &ipcmd_index); - regca.getPorts().in.template port().connect(&ipcmd_node); + regca.getPorts() + .in.template port() + .connect(&ipcmd_node); } void attachIqcmd(RealT value) { iqcmd = value; iqcmd_node.link(&iqcmd, &iqcmd_index); - regca.getPorts().in.template port().connect(&iqcmd_node); + regca.getPorts() + .in.template port() + .connect(&iqcmd_node); } /// Everything initialize() requires: allocation, verification, and @@ -757,7 +822,8 @@ namespace GridKit bool prepare() { const bool success = (bus.allocate() == 0) && (regca.allocate() == 0) - && (regca.verify().passed()) && (bus.initialize() == 0); + && (regca.verify().passed()) + && (bus.initialize() == 0); if (!success) { std::cout << "REGCA fixture preparation failed\n"; @@ -921,7 +987,8 @@ namespace GridKit regca.yp().setDataUpdated(); } - /// @todo Remove and setup the test to not rely on explicit variable numbering + /// @todo Remove and setup the test to not rely on explicit variable + /// numbering void numberVariables(Fixture& fixture) { auto* y = fixture.regca.y().getData(); @@ -946,7 +1013,9 @@ namespace GridKit fixture.bus.y().setDataUpdated(); } - bool invalidParameterCase(PhasorDynamics::Bus& bus, Params param, RealT value) + bool invalidParameterCase( + PhasorDynamics::Bus& bus, Params param, RealT value + ) { auto data = makeData(); data.parameters[param] = value; @@ -959,7 +1028,9 @@ namespace GridKit ); } - bool allResidualsZero(PhasorDynamics::Converter::Regca& regca) const + bool allResidualsZero( + PhasorDynamics::Converter::Regca& regca + ) const { bool success = true; const auto* f = regca.getResidual().getData(); @@ -973,7 +1044,8 @@ namespace GridKit } if (!isEqual(yp[i], 0.0, kTol)) { - std::cout << "REGCA derivative row " << i << " is " << yp[i] << "\n"; + std::cout << "REGCA derivative row " << i << " is " << yp[i] + << "\n"; success = false; } } diff --git a/tests/UnitTests/PhasorDynamics/ExciterEsdc1aTests.hpp b/tests/UnitTests/PhasorDynamics/ExciterEsdc1aTests.hpp index cede683730..32cd1386d1 100644 --- a/tests/UnitTests/PhasorDynamics/ExciterEsdc1aTests.hpp +++ b/tests/UnitTests/PhasorDynamics/ExciterEsdc1aTests.hpp @@ -57,11 +57,14 @@ namespace GridKit PhasorDynamics::Bus bus(1.0, 0.0); PhasorDynamics::Exciter::Esdc1a empty(&bus, Data{}); - success *= (empty.size() == static_cast(Utilities::enum_size())); + success *= + (empty.size() == static_cast(Utilities::enum_size())); success *= (!empty.verify().passed()); Fixture configured(makeData()); - success *= (configured.esdc1a.size() == static_cast(Utilities::enum_size())); + success *= + (configured.esdc1a.size() + == static_cast(Utilities::enum_size())); success *= (configured.esdc1a.getMonitor() != nullptr); success *= configured.prepare(1.2); @@ -72,7 +75,9 @@ namespace GridKit success *= defaultsMatchDocumentedValues(); // A model without the required efd output assignment is rejected. - PhasorDynamics::Exciter::Esdc1a unassigned(&bus, makeData()); + PhasorDynamics::Exciter::Esdc1a unassigned( + &bus, makeData() + ); success *= (!unassigned.verify().passed()); success *= invalidParameterCase(Params::Ka, 0.0); @@ -108,8 +113,12 @@ namespace GridKit Params::E2, Params::Se2}) { - success *= invalidParameterCase(parameter, std::numeric_limits::quiet_NaN()); - success *= invalidParameterCase(parameter, std::numeric_limits::infinity()); + success *= invalidParameterCase( + parameter, std::numeric_limits::quiet_NaN() + ); + success *= invalidParameterCase( + parameter, std::numeric_limits::infinity() + ); } // Saturation voltage and coefficient pairs must move in the same @@ -167,8 +176,13 @@ namespace GridKit success *= (!speed_required_fixture.esdc1a.verify().passed()); PhasorDynamics::SignalNode busless_efd_node; - PhasorDynamics::Exciter::Esdc1a busless(nullptr, makeData()); - busless.getPorts().out.template port().connect(&busless_efd_node); + PhasorDynamics::Exciter::Esdc1a busless( + nullptr, makeData() + ); + busless.getPorts() + .out + .template port() + .connect(&busless_efd_node); success *= (!busless.verify().passed()); success *= unlinkedSignalRejected(); @@ -209,24 +223,40 @@ namespace GridKit fixture.input(External::vs) = 0.03; fixture.input(External::vuel) = -0.4; success *= fixture.initialize(1.2); - success *= (fixture.esdc1a.tagDifferentiable() == 0); - success *= (fixture.evaluate() == 0); - - const auto* y = fixture.esdc1a.y().getData(); - success *= scalarMatches(y[static_cast(Internal::EFDP)], 1.2, "EFDP"); - success *= scalarMatches(y[static_cast(Internal::VC)], 1.0, "VC"); - success *= scalarMatches(y[static_cast(Internal::VR)], 0.12, "VR"); - success *= scalarMatches(y[static_cast(Internal::VF)], 0.0, "VF"); - success *= scalarMatches(y[static_cast(Internal::EV)], 0.003, "EV gate input"); - success *= scalarMatches(y[static_cast(Internal::VHV)], 0.003, "VHV"); - success *= scalarMatches(y[static_cast(Internal::SE)], 0.0, "SE"); - success *= scalarMatches(y[static_cast(Internal::VFE)], 0.12, "VFE"); - success *= scalarMatches(fixture.efd(), 1.2, "seeded efd"); - - success *= scalarMatches(fixture.input(External::vref), 0.973, "published vref"); - success *= scalarMatches(fixture.input(External::speed), 0.02, "preserved speed input"); - success *= scalarMatches(fixture.input(External::vs), 0.03, "preserved vs input"); - success *= scalarMatches(fixture.input(External::vuel), -0.4, "preserved vuel input"); + success *= (fixture.esdc1a.tagDifferentiable() == 0); + success *= (fixture.evaluate() == 0); + + const auto* y = fixture.esdc1a.y().getData(); + success *= + scalarMatches(y[static_cast(Internal::EFDP)], 1.2, "EFDP"); + success *= + scalarMatches(y[static_cast(Internal::VC)], 1.0, "VC"); + success *= + scalarMatches(y[static_cast(Internal::VR)], 0.12, "VR"); + success *= + scalarMatches(y[static_cast(Internal::VF)], 0.0, "VF"); + success *= scalarMatches( + y[static_cast(Internal::EV)], 0.003, "EV gate input" + ); + success *= + scalarMatches(y[static_cast(Internal::VHV)], 0.003, "VHV"); + success *= + scalarMatches(y[static_cast(Internal::SE)], 0.0, "SE"); + success *= + scalarMatches(y[static_cast(Internal::VFE)], 0.12, "VFE"); + success *= scalarMatches(fixture.efd(), 1.2, "seeded efd"); + + success *= + scalarMatches(fixture.input(External::vref), 0.973, "published vref"); + success *= scalarMatches( + fixture.input(External::speed), 0.02, "preserved speed input" + ); + success *= scalarMatches( + fixture.input(External::vs), 0.03, "preserved vs input" + ); + success *= scalarMatches( + fixture.input(External::vuel), -0.4, "preserved vuel input" + ); RealT time = 0.0; Model::VariableMonitorController monitor(time); @@ -241,10 +271,12 @@ namespace GridKit std::string monitor_values; std::getline(monitor_output, monitor_header); std::getline(monitor_output, monitor_values); - success *= (monitor_header == "t,Esdc1a_esdc1a_test_efd,Esdc1a_esdc1a_test_vc," - "Esdc1a_esdc1a_test_vr,Esdc1a_esdc1a_test_vf," - "Esdc1a_esdc1a_test_se,Esdc1a_esdc1a_test_vfe"); - const auto monitored = Tokenizer(monitor_values, ',')(); + success *= + (monitor_header + == "t,Esdc1a_esdc1a_test_efd,Esdc1a_esdc1a_test_vc," + "Esdc1a_esdc1a_test_vr,Esdc1a_esdc1a_test_vf," + "Esdc1a_esdc1a_test_se,Esdc1a_esdc1a_test_vfe"); + const auto monitored = Tokenizer(monitor_values, ',')(); if (monitored.size() == 7) { success *= scalarMatches(monitored[1], 1.2, "monitored efd"); @@ -299,8 +331,8 @@ namespace GridKit scenario.input(External::vuel) = -0.4; if (!scenario.initialize(1.2)) { - std::cout << "ESDC1A initialization scenario failed: UEL=" << uel - << ", Spdmlt=" << speed_flag + std::cout << "ESDC1A initialization scenario failed: UEL=" + << uel << ", Spdmlt=" << speed_flag << ", exclim=" << limit_flag << '\n'; success = false; continue; @@ -308,7 +340,8 @@ namespace GridKit success *= (scenario.evaluate() == 0); success *= allResidualsZero(scenario.esdc1a); - success *= scalarMatches(scenario.efd(), 1.2, "scenario efd preservation"); + success *= + scalarMatches(scenario.efd(), 1.2, "scenario efd preservation"); } } } @@ -324,18 +357,18 @@ namespace GridKit TestStatus success = true; const auto previous_verbosity = Log::verbosity(); - // Suppress expected errors from the inadmissible initialization cases below. - // Use EVERYTHING to inspect those diagnostics. + // Suppress expected errors from the inadmissible initialization cases + // below. Use EVERYTHING to inspect those diagnostics. Log::setVerbosity(Log::Verbosity::NONE); // An enabled speed multiplier must remain finite and strictly // positive. Other initialization limits are relaxed so these cases // isolate that domain. - auto speed_data = makeData(); - speed_data.parameters[Params::Spdmlt] = true; - speed_data.parameters[Params::exclim] = false; - speed_data.parameters[Params::Vrmin] = -100.0; - speed_data.parameters[Params::Vrmax] = 100.0; + auto speed_data = makeData(); + speed_data.parameters[Params::Spdmlt] = true; + speed_data.parameters[Params::exclim] = false; + speed_data.parameters[Params::Vrmin] = -100.0; + speed_data.parameters[Params::Vrmax] = 100.0; success *= initializationRejectedAtomically( speed_data, 1.2, @@ -368,9 +401,9 @@ namespace GridKit ); // The seeded field voltage maps to a regulator output above Vrmax. - auto limit_data = makeData(); - limit_data.parameters[Params::Vrmax] = 0.05; - limit_data.parameters[Params::Vrmin] = -0.05; + auto limit_data = makeData(); + limit_data.parameters[Params::Vrmax] = 0.05; + limit_data.parameters[Params::Vrmin] = -0.05; success *= initializationRejectedAtomically( limit_data, 1.2, @@ -399,7 +432,9 @@ namespace GridKit nonfinite.attachAllInputs(77.0); success *= nonfinite.prepare(std::numeric_limits::quiet_NaN()); success *= (nonfinite.esdc1a.initialize() != 0); - success *= scalarMatches(nonfinite.input(External::vref), 77.0, "rejected vref preservation"); + success *= scalarMatches( + nonfinite.input(External::vref), 77.0, "rejected vref preservation" + ); success *= initializationRejectedAtomically( speed_data, @@ -454,11 +489,15 @@ namespace GridKit const auto invalid_yp = copyVector(invalid_fixture.esdc1a.yp()); if (invalid_fixture.esdc1a.initialize() == 0) { - std::cout << "Expected initialization rejection: invalid configuration\n"; + std::cout + << "Expected initialization rejection: invalid configuration\n"; success = false; } - success *= vectorUnchanged(invalid_fixture.esdc1a.y(), invalid_y, "state"); - success *= vectorUnchanged(invalid_fixture.esdc1a.yp(), invalid_yp, "derivative"); + success *= + vectorUnchanged(invalid_fixture.esdc1a.y(), invalid_y, "state"); + success *= vectorUnchanged( + invalid_fixture.esdc1a.yp(), invalid_yp, "derivative" + ); // The zero boundary is admissible, and disabling the limiter admits // the same negative seed rejected above. @@ -467,7 +506,7 @@ namespace GridKit zero_boundary.input(External::vuel) = -0.5; success *= zero_boundary.initialize(0.0); success *= (zero_boundary.evaluate() == 0); - success *= allResidualsZero(zero_boundary.esdc1a); + success *= allResidualsZero(zero_boundary.esdc1a); auto unlimited_data = makeData(); unlimited_data.parameters[Params::exclim] = false; @@ -486,10 +525,10 @@ namespace GridKit speed_fixture.input(External::speed) = -0.5; success *= speed_fixture.initialize(1.2); success *= (speed_fixture.evaluate() == 0); - success *= allResidualsZero(speed_fixture.esdc1a); + success *= allResidualsZero(speed_fixture.esdc1a); success *= scalarMatches( - speed_fixture.esdc1a.y() - .getData()[static_cast(Internal::EFDP)], + speed_fixture.esdc1a.y().getData( + )[static_cast(Internal::EFDP)], 2.4, "rescaled EFDP" ); @@ -543,7 +582,9 @@ namespace GridKit {Internal::EFD, 1.32}, }}; - success *= (static_cast(fixture.esdc1a.getResidual().getSize()) == expected.size()); + success *= + (static_cast(fixture.esdc1a.getResidual().getSize()) + == expected.size()); success *= residualsMatch(fixture.esdc1a, expected); return success.report(__func__); @@ -564,12 +605,19 @@ namespace GridKit setState(fixture.esdc1a, {{Internal::VC, 1.1}}); setDerivative(fixture.esdc1a, {{Internal::VC, 0.2}}); success *= (fixture.evaluate() == 0); - success *= residualsMatch(fixture.esdc1a, {{Internal::VC, -5.2}}, "voltage transducer"); + success *= residualsMatch( + fixture.esdc1a, {{Internal::VC, -5.2}}, "voltage transducer" + ); // The field-voltage state and the stabilizing feedback share the // (VR - VFE) drive. - setState(fixture.esdc1a, {{Internal::VR, 0.6}, {Internal::VFE, 0.2}, {Internal::VF, 0.1}}); - setDerivative(fixture.esdc1a, {{Internal::EFDP, 0.1}, {Internal::VF, 0.05}}); + setState( + fixture.esdc1a, + {{Internal::VR, 0.6}, {Internal::VFE, 0.2}, {Internal::VF, 0.1}} + ); + setDerivative( + fixture.esdc1a, {{Internal::EFDP, 0.1}, {Internal::VF, 0.05}} + ); success *= (fixture.evaluate() == 0); success *= residualsMatch( fixture.esdc1a, @@ -585,7 +633,9 @@ namespace GridKit {Internal::VFE, 0.0}, {Internal::VF, -0.14}} ); - setDerivative(fixture.esdc1a, {{Internal::EFDP, 0.0}, {Internal::VF, 0.2}}); + setDerivative( + fixture.esdc1a, {{Internal::EFDP, 0.0}, {Internal::VF, 0.2}} + ); success *= (fixture.evaluate() == 0); success *= residualsMatch( fixture.esdc1a, @@ -600,9 +650,14 @@ namespace GridKit summing.input(External::vref) = 1.1; summing.input(External::vs) = 0.05; summing.input(External::vuel) = 0.2; - setState(summing.esdc1a, {{Internal::VC, 0.9}, {Internal::VF, 0.02}, {Internal::EV, 0.1}}); + setState( + summing.esdc1a, + {{Internal::VC, 0.9}, {Internal::VF, 0.02}, {Internal::EV, 0.1}} + ); success *= (summing.evaluate() == 0); - success *= residualsMatch(summing.esdc1a, {{Internal::EV, 0.13}}, "summing junction"); + success *= residualsMatch( + summing.esdc1a, {{Internal::EV, 0.13}}, "summing junction" + ); // UEL >= 2 routes the UEL input through the summing junction and // turns the high-value gate into a lead-lag passthrough. @@ -635,7 +690,10 @@ namespace GridKit Fixture lead_lag(lead_lag_data); lead_lag.attachAllInputs(); success *= lead_lag.initialize(1.2); - setState(lead_lag.esdc1a, {{Internal::XLL, 0.4}, {Internal::EV, 0.7}, {Internal::VLL, 0.5}}); + setState( + lead_lag.esdc1a, + {{Internal::XLL, 0.4}, {Internal::EV, 0.7}, {Internal::VLL, 0.5}} + ); setDerivative(lead_lag.esdc1a, {{Internal::XLL, 0.0}}); success *= (lead_lag.evaluate() == 0); success *= residualsMatch( @@ -663,7 +721,10 @@ namespace GridKit for (const auto& test_case : antiwindup_cases) { - setState(fixture.esdc1a, {{Internal::VR, test_case.vr}, {Internal::VHV, test_case.vhv}}); + setState( + fixture.esdc1a, + {{Internal::VR, test_case.vr}, {Internal::VHV, test_case.vhv}} + ); setDerivative(fixture.esdc1a, {{Internal::VR, 0.0}}); success *= (fixture.evaluate() == 0); success *= residualsMatch( @@ -676,9 +737,9 @@ namespace GridKit return success.report(__func__); } - /// High-value gate selection, scaled-quadratic saturation, field-voltage-state - /// limiting, and the speed multiplier at driven states with literal - /// expectations. + /// High-value gate selection, scaled-quadratic saturation, + /// field-voltage-state limiting, and the speed multiplier at driven + /// states with literal expectations. TestOutcome excitationLimits() { TestStatus success = true; @@ -704,7 +765,9 @@ namespace GridKit gate.input(External::vuel) = test_case.vuel; setState(gate.esdc1a, {{Internal::VLL, 0.5}, {Internal::VHV, 0.2}}); success *= (gate.evaluate() == 0); - success *= residualsMatch(gate.esdc1a, {{Internal::VHV, test_case.expected}}, test_case.label); + success *= residualsMatch( + gate.esdc1a, {{Internal::VHV, test_case.expected}}, test_case.label + ); } // Both valid point orderings recover E S_E(E) = 0.25(E - 1)^2, @@ -769,9 +832,13 @@ namespace GridKit Fixture disabled(disabled_data); disabled.attachAllInputs(); success *= disabled.initialize(1.2); - setState(disabled.esdc1a, {{Internal::EFDP, 2.0}, {Internal::SE, 0.05}}); + setState( + disabled.esdc1a, {{Internal::EFDP, 2.0}, {Internal::SE, 0.05}} + ); success *= (disabled.evaluate() == 0); - success *= residualsMatch(disabled.esdc1a, {{Internal::SE, -0.05}}, "saturation disabled"); + success *= residualsMatch( + disabled.esdc1a, {{Internal::SE, -0.05}}, "saturation disabled" + ); // The field-voltage-state lower limit blocks outward motion, admits // restoring motion, and preserves the CommonMath transition at zero. @@ -882,13 +949,13 @@ namespace GridKit .getData()[static_cast(Internal::EFDP)] .getDependencies(); const DepVar::DependencyMap expected{{ - {2 * static_cast(Internal::EFDP), - -12.0}, // @todo Remove these - {2 * static_cast(Internal::EFDP) + 1, - -1.0}, // @todo Remove these + {2 * static_cast(Internal::EFDP), -12.0 + }, // @todo Remove these + {2 * static_cast(Internal::EFDP) + 1, -1.0 + }, // @todo Remove these {2 * static_cast(Internal::VR), 1.0}, // @todo Remove these - {2 * static_cast(Internal::VFE), - -1.0}, // @todo Remove these + {2 * static_cast(Internal::VFE), -1.0 + }, // @todo Remove these }}; success *= isEqual(dependencies, expected, kTol); } @@ -929,11 +996,13 @@ namespace GridKit const auto data = makeResidualData(); - const auto dependency_jacobian = dependencyTrackingJacobian(data, success); - const auto enzyme_jacobian = enzymeJacobian(data, success); + const auto dependency_jacobian = + dependencyTrackingJacobian(data, success); + const auto enzyme_jacobian = enzymeJacobian(data, success); - success *= (dependency_jacobian.size() == enzyme_jacobian.size()); - const auto rows = std::min(dependency_jacobian.size(), enzyme_jacobian.size()); + success *= (dependency_jacobian.size() == enzyme_jacobian.size()); + const auto rows = + std::min(dependency_jacobian.size(), enzyme_jacobian.size()); for (size_t row = 0; row < rows; ++row) { if (!isEqual(dependency_jacobian[row], enzyme_jacobian[row], kTol)) @@ -980,10 +1049,11 @@ namespace GridKit public: explicit Fixture(const Data& data, RealT vr = 0.8, RealT vi = 0.6) - : bus(static_cast(vr), static_cast(vi)), - esdc1a(&bus, data) + : bus(static_cast(vr), static_cast(vi)), esdc1a(&bus, data) { - esdc1a.getPorts().out.template port().connect(&efd_node_); + esdc1a.getPorts() + .out.template port() + .connect(&efd_node_); } Fixture(const Fixture&) = delete; @@ -996,10 +1066,13 @@ namespace GridKit for (auto variant : Utilities::enum_values()) { - const auto port = static_cast(variant); - input_values_[port] = static_cast(initial_value); - input_indices_[port] = external_index_base + static_cast(port); - input_nodes_[port].link(&input_values_[port], &input_indices_[port]); + const auto port = static_cast(variant); + input_values_[port] = static_cast(initial_value); + input_indices_[port] = + external_index_base + static_cast(port); + input_nodes_[port].link( + &input_values_[port], &input_indices_[port] + ); } esdc1a.getPorts().in.template port().connect( @@ -1028,7 +1101,8 @@ namespace GridKit bool prepare(RealT efd) { const bool success = (bus.allocate() == 0) && (esdc1a.allocate() == 0) - && (esdc1a.verify().passed()) && (bus.initialize() == 0); + && (esdc1a.verify().passed()) + && (bus.initialize() == 0); if (!success) { std::cout << "ESDC1A fixture preparation failed\n"; @@ -1187,9 +1261,11 @@ namespace GridKit } /// The rich state shared by the residual answer key and the Jacobian - /// comparison. Every residual row is distinct so a swapped index cannot pass. + /// comparison. Every residual row is distinct so a swapped index cannot + /// pass. template - void setAnswerKeyState(PhasorDynamics::Exciter::Esdc1a& esdc1a) const + void setAnswerKeyState(PhasorDynamics::Exciter::Esdc1a& esdc1a + ) const { setState( esdc1a, @@ -1219,8 +1295,12 @@ namespace GridKit /// defaults the README documents, at rest and under load. bool defaultsMatchDocumentedValues() const { - Fixture implicit_defaults(makeMinimalData(), kStateVr, kStateVi); - Fixture explicit_defaults(makeExplicitDefaultData(), kStateVr, kStateVi); + Fixture implicit_defaults( + makeMinimalData(), kStateVr, kStateVi + ); + Fixture explicit_defaults( + makeExplicitDefaultData(), kStateVr, kStateVi + ); implicit_defaults.attachAllInputs(); explicit_defaults.attachAllInputs(); @@ -1228,7 +1308,8 @@ namespace GridKit && explicit_defaults.initialize(1.2); if (!success) { - std::cout << "ESDC1A documented-default comparison failed to initialize\n"; + std::cout + << "ESDC1A documented-default comparison failed to initialize\n"; return false; } @@ -1307,7 +1388,9 @@ namespace GridKit { PhasorDynamics::SignalNode unlinked_node; Fixture fixture(makeData()); - fixture.esdc1a.getPorts().in.template port().connect(&unlinked_node); + fixture.esdc1a.getPorts().in.template port().connect( + &unlinked_node + ); return !fixture.esdc1a.verify().passed(); } @@ -1332,7 +1415,9 @@ namespace GridKit const auto* values = vector.getData(); for (size_t i = 0; i < snapshot.size(); ++i) { - if (!rowMatches(static_cast(values[i]), snapshot[i], what, i, "changed")) + if (!rowMatches( + static_cast(values[i]), snapshot[i], what, i, "changed" + )) { success = false; } @@ -1354,7 +1439,8 @@ namespace GridKit if (!ret) { std::cout << "ESDC1A " << what << " row " << row - << " changed mismatch: " << actual << " != " << expected << "\n"; + << " changed mismatch: " << actual << " != " << expected + << "\n"; } return ret; } @@ -1366,7 +1452,9 @@ namespace GridKit { auto* y = fixture.esdc1a.y().getData(); auto* yp = fixture.esdc1a.yp().getData(); - for (size_t i = 0; i < static_cast(fixture.esdc1a.y().getSize()); ++i) + for (size_t i = 0; + i < static_cast(fixture.esdc1a.y().getSize()); + ++i) { y[i] = 0.125 + 0.01 * static_cast(i); yp[i] = -0.25 - 0.01 * static_cast(i); @@ -1407,7 +1495,9 @@ namespace GridKit success = false; } - if (!scalarMatches(fixture.efd(), efd_seed, "rejected efd preservation")) + if (!scalarMatches( + fixture.efd(), efd_seed, "rejected efd preservation" + )) { success = false; } @@ -1500,7 +1590,9 @@ namespace GridKit for (const auto& [variable, expected] : rows) { const auto row = static_cast(variable); - if (!rowMatches(static_cast(values[row]), expected, what, row, context)) + if (!rowMatches( + static_cast(values[row]), expected, what, row, context + )) { success = false; } @@ -1534,13 +1626,19 @@ namespace GridKit bool success = true; const auto* f = esdc1a.getResidual().getData(); const auto* yp = esdc1a.yp().getData(); - for (size_t row = 0; row < static_cast(esdc1a.getResidual().getSize()); ++row) + for (size_t row = 0; + row < static_cast(esdc1a.getResidual().getSize()); + ++row) { - if (!rowMatches(static_cast(f[row]), 0.0, "residual", row, "at rest")) + if (!rowMatches( + static_cast(f[row]), 0.0, "residual", row, "at rest" + )) { success = false; } - if (!rowMatches(static_cast(yp[row]), 0.0, "derivative", row, "at rest")) + if (!rowMatches( + static_cast(yp[row]), 0.0, "derivative", row, "at rest" + )) { success = false; } @@ -1564,7 +1662,8 @@ namespace GridKit return false; } - /// @todo Remove and setup the test to not rely on explicit variable numbering + /// @todo Remove and setup the test to not rely on explicit variable + /// numbering void numberVariables(Fixture& fixture) const { auto* y = fixture.esdc1a.y().getData(); diff --git a/tests/UnitTests/PhasorDynamics/ExciterIeeet1Tests.hpp b/tests/UnitTests/PhasorDynamics/ExciterIeeet1Tests.hpp index 05cc50660b..ffea3cd8c3 100644 --- a/tests/UnitTests/PhasorDynamics/ExciterIeeet1Tests.hpp +++ b/tests/UnitTests/PhasorDynamics/ExciterIeeet1Tests.hpp @@ -36,8 +36,9 @@ namespace GridKit TestStatus success = true; PhasorDynamics::Bus bus(3.0, 4.0); - auto data = makeTestData(); - auto* exciter = new PhasorDynamics::Exciter::Ieeet1(&bus, data); + auto data = makeTestData(); + auto* exciter = + new PhasorDynamics::Exciter::Ieeet1(&bus, data); success *= (exciter != nullptr); success *= (exciter->size() == 9); @@ -71,7 +72,8 @@ namespace GridKit { if (!isEqual(residual_data[i], static_cast(0.0))) { - std::cout << "Non-zero Ieeet1 residual at index " << i << ": " << residual_data[i] << "\n"; + std::cout << "Non-zero Ieeet1 residual at index " << i << ": " + << residual_data[i] << "\n"; success = false; } } @@ -101,10 +103,13 @@ namespace GridKit PhasorDynamics::Exciter::Ieeet1 exciter(&bus, data); PhasorDynamics::SignalNode efd_node; ScalarT efd_value{0.0}; - IdxT efd_index = INVALID_INDEX; + IdxT efd_index = INVALID_INDEX; efd_node.link(&efd_value, &efd_index); - exciter.getPorts().out.template port().connect(&efd_node); + exciter.getPorts() + .out + .template port() + .connect(&efd_node); bus.allocate(); exciter.allocate(); @@ -137,7 +142,11 @@ namespace GridKit for (IdxT i = 0; i < exciter.getResidual().getSize(); ++i) { success *= std::isfinite(f[i]); - success *= isEqual(f[i], static_cast(0.0), 100.0 * std::numeric_limits::epsilon()); + success *= isEqual( + f[i], + static_cast(0.0), + 100.0 * std::numeric_limits::epsilon() + ); } y[2] = 4.0; @@ -222,19 +231,28 @@ namespace GridKit ScalarT vref_value{0.0}; ScalarT vuel_value{-0.4}; ScalarT voel_value{0.2}; - IdxT efd_index = INVALID_INDEX; - IdxT vref_index = 11; - IdxT vuel_index = 12; - IdxT voel_index = 13; + IdxT efd_index = INVALID_INDEX; + IdxT vref_index = 11; + IdxT vuel_index = 12; + IdxT voel_index = 13; efd_node.link(&efd_value, &efd_index); vref_node.link(&vref_value, &vref_index); vuel_node.link(&vuel_value, &vuel_index); voel_node.link(&voel_value, &voel_index); - exciter.getPorts().out.template port().connect(&efd_node); - exciter.getPorts().in.template port().connect(&vref_node); - exciter.getPorts().in.template port().connect(&vuel_node); - exciter.getPorts().in.template port().connect(&voel_node); + exciter.getPorts() + .out + .template port() + .connect(&efd_node); + exciter.getPorts() + .in.template port() + .connect(&vref_node); + exciter.getPorts() + .in.template port() + .connect(&vuel_node); + exciter.getPorts() + .in.template port() + .connect(&voel_node); bus.allocate(); exciter.allocate(); @@ -276,37 +294,47 @@ namespace GridKit auto tol = 10 * std::numeric_limits::epsilon(); // Jacobian via DependencyTracking - std::vector dependency_tracking_jacobian = DependencyTrackingJacobian(); + std::vector + dependency_tracking_jacobian = DependencyTrackingJacobian(); // Jacobian via Enzyme - std::vector enzyme_jacobian = EnzymeJacobian(); + std::vector + enzyme_jacobian = EnzymeJacobian(); // Compare DependencyTracking dependencies to Enzyme's for (size_t i = 0; i < dependency_tracking_jacobian.size(); ++i) { - success *= (GridKit::Testing::isEqual(dependency_tracking_jacobian[i], enzyme_jacobian[i], tol)); + success *= (GridKit::Testing::isEqual( + dependency_tracking_jacobian[i], enzyme_jacobian[i], tol + )); } return success.report(__func__); } private: - std::vector DependencyTrackingJacobian() + std::vector + DependencyTrackingJacobian() { auto data = makeTestData(); - DependencyTracking::Variable Vr1{3.0}; - DependencyTracking::Variable Vi1{4.0}; - PhasorDynamics::Bus bus(Vr1, Vi1); - PhasorDynamics::Exciter::Ieeet1 exciter(&bus, data); + DependencyTracking::Variable Vr1{3.0}; + DependencyTracking::Variable Vi1{4.0}; + PhasorDynamics::Bus bus(Vr1, Vi1); + PhasorDynamics::Exciter::Ieeet1 + exciter(&bus, data); bus.allocate(); exciter.allocate(); for (size_t i = 0; i < bus.size(); ++i) { - bus.setVariableIndex(i, i + exciter.size()); // Reset bus variable indices - bus.setResidualIndex(i, i + exciter.size()); // Reset bus residual indices + bus.setVariableIndex( + i, i + exciter.size() + ); // Reset bus variable indices + bus.setResidualIndex( + i, i + exciter.size() + ); // Reset bus residual indices } bus.initialize(); @@ -321,7 +349,8 @@ namespace GridKit exciter.evaluateJacobian(); auto* model_jacobian = exciter.getCsrJacobian(); auto& output_stream = Log::misc(); - output_stream << "Sparse Csr Matrix: Ieeet1 DependencyTracking Jacobian\n"; + output_stream + << "Sparse Csr Matrix: Ieeet1 DependencyTracking Jacobian\n"; model_jacobian->print(output_stream); return GridKit::Testing::MapFromCsr(model_jacobian); @@ -339,8 +368,12 @@ namespace GridKit for (size_t i = 0; i < bus.size(); ++i) { - bus.setVariableIndex(i, i + exciter.size()); // Reset bus variable indices - bus.setResidualIndex(i, i + exciter.size()); // Reset bus residual indices + bus.setVariableIndex( + i, i + exciter.size() + ); // Reset bus variable indices + bus.setResidualIndex( + i, i + exciter.size() + ); // Reset bus residual indices } bus.initialize(); @@ -371,7 +404,9 @@ namespace GridKit PhasorDynamics::Exciter::Ieeet1Data data; data.device_class = "exciter"; data.disambiguation_string = "ieeet1_test"; - data.monitored_variables.insert(PhasorDynamics::Exciter::Ieeet1MonitorableVariables::efd); + data.monitored_variables.insert( + PhasorDynamics::Exciter::Ieeet1MonitorableVariables::efd + ); data.parameters[Params::Tr] = 0.0; data.parameters[Params::Ka] = 50.0; diff --git a/tests/UnitTests/PhasorDynamics/ExciterSexsPtiTests.hpp b/tests/UnitTests/PhasorDynamics/ExciterSexsPtiTests.hpp index 3fc1d561ae..5ab4fb100d 100644 --- a/tests/UnitTests/PhasorDynamics/ExciterSexsPtiTests.hpp +++ b/tests/UnitTests/PhasorDynamics/ExciterSexsPtiTests.hpp @@ -32,15 +32,17 @@ namespace GridKit // Init and saturated-limiter checks are exact algebraic identities // (no iteration, sigmoid underflowed to 0/1 at the depths tested here). - static constexpr ScalarT kTol = 100 * std::numeric_limits::epsilon(); + static constexpr ScalarT kTol = + 100 * std::numeric_limits::epsilon(); TestOutcome constructor() { TestStatus success = true; PhasorDynamics::Bus bus(3.0, 4.0); - auto data = makeTestData(); - auto* exciter = new PhasorDynamics::Exciter::SexsPti(&bus, data); + auto data = makeTestData(); + auto* exciter = + new PhasorDynamics::Exciter::SexsPti(&bus, data); success *= (exciter != nullptr); success *= (exciter->size() == 3); @@ -61,14 +63,16 @@ namespace GridKit PhasorDynamics::SignalNode efd_node; ScalarT efd_value{0.0}; - IdxT efd_index = INVALID_INDEX; + IdxT efd_index = INVALID_INDEX; efd_node.link(&efd_value, &efd_index); using namespace GridKit::PhasorDynamics::Exciter; auto data = makeTestData(); auto exciter = SexsPti(&bus, data); - exciter.getPorts().out.template port().connect(&efd_node); + exciter.getPorts() + .out.template port() + .connect(&efd_node); exciter.allocate(); efd_node.init(1.2); @@ -76,9 +80,9 @@ namespace GridKit exciter.initialize(); exciter.evaluateResidual(); - success *= efd_node.linked(); - success *= (efd_node.getVariableIndex() == 1); - success *= isEqual(efd_node.read(), static_cast(1.2), kTol); + success *= efd_node.linked(); + success *= (efd_node.getVariableIndex() == 1); + success *= isEqual(efd_node.read(), static_cast(1.2), kTol); const auto* y = exciter.y().getData(); success *= isEqual(y[0], static_cast(-0.048), kTol); success *= isEqual(y[1], static_cast(1.2), kTol); @@ -90,7 +94,8 @@ namespace GridKit { if (!isEqual(f_data[i], static_cast(0.0), kTol)) { - std::cout << "Non-zero SEXS-PTI residual at index " << i << ": " << f_data[i] << "\n"; + std::cout << "Non-zero SEXS-PTI residual at index " << i << ": " + << f_data[i] << "\n"; success = false; } } @@ -110,8 +115,8 @@ namespace GridKit PhasorDynamics::SignalNode vs_node; ScalarT efd_value{0.0}; ScalarT vs_value{0.25}; - IdxT efd_index = INVALID_INDEX; - IdxT vs_index = 4; + IdxT efd_index = INVALID_INDEX; + IdxT vs_index = 4; efd_node.link(&efd_value, &efd_index); vs_node.link(&vs_value, &vs_index); @@ -119,8 +124,12 @@ namespace GridKit auto data = makeTestData(); auto exciter = SexsPti(&bus, data); - exciter.getPorts().out.template port().connect(&efd_node); - exciter.getPorts().in.template port().connect(&vs_node); + exciter.getPorts() + .out.template port() + .connect(&efd_node); + exciter.getPorts().in.template port().connect( + &vs_node + ); exciter.allocate(); efd_node.init(1.2); @@ -128,7 +137,8 @@ namespace GridKit exciter.initialize(); exciter.evaluateResidual(); - // vref absorbs the attached vs at initialization; later changes pass through + // vref absorbs the attached vs at initialization; later changes pass + // through const auto* f = exciter.getResidual().getData(); success *= isEqual(f[2], static_cast(0.0), kTol); @@ -155,10 +165,10 @@ namespace GridKit ScalarT vref_value{0.0}; ScalarT vuel_value{-0.4}; ScalarT voel_value{0.2}; - IdxT efd_index = INVALID_INDEX; - IdxT vref_index = 5; - IdxT vuel_index = 6; - IdxT voel_index = 7; + IdxT efd_index = INVALID_INDEX; + IdxT vref_index = 5; + IdxT vuel_index = 6; + IdxT voel_index = 7; efd_node.link(&efd_value, &efd_index); vref_node.link(&vref_value, &vref_index); vuel_node.link(&vuel_value, &vuel_index); @@ -166,10 +176,22 @@ namespace GridKit auto data = makeTestData(); PhasorDynamics::Exciter::SexsPti exciter(&bus, data); - exciter.getPorts().out.template port().connect(&efd_node); - exciter.getPorts().in.template port().connect(&vref_node); - exciter.getPorts().in.template port().connect(&vuel_node); - exciter.getPorts().in.template port().connect(&voel_node); + exciter.getPorts() + .out + .template port() + .connect(&efd_node); + exciter.getPorts() + .in + .template port() + .connect(&vref_node); + exciter.getPorts() + .in + .template port() + .connect(&vuel_node); + exciter.getPorts() + .in + .template port() + .connect(&voel_node); exciter.allocate(); efd_node.init(1.2); @@ -177,9 +199,9 @@ namespace GridKit exciter.evaluateResidual(); // vref absorbs both limiter inputs; later changes enter with unit gain. - const auto* f = exciter.getResidual().getData(); - success *= isEqual(vref_node.read(), static_cast(5.32), kTol); - success *= isEqual(f[2], static_cast(0.0), kTol); + const auto* f = exciter.getResidual().getData(); + success *= isEqual(vref_node.read(), static_cast(5.32), kTol); + success *= isEqual(f[2], static_cast(0.0), kTol); vuel_value = -0.3; exciter.evaluateResidual(); @@ -280,12 +302,16 @@ namespace GridKit auto missing = makeTestData(); missing.parameters.erase(Parameter::K); - PhasorDynamics::Exciter::SexsPti missing_model(&bus, missing); + PhasorDynamics::Exciter::SexsPti missing_model( + &bus, missing + ); success *= (!missing_model.verify().passed()); auto invalid = makeTestData(); invalid.parameters[Parameter::Tb] = 0.0; - PhasorDynamics::Exciter::SexsPti invalid_model(&bus, invalid); + PhasorDynamics::Exciter::SexsPti invalid_model( + &bus, invalid + ); success *= (!invalid_model.verify().passed()); Log::setVerbosity(previous_verbosity); @@ -402,37 +428,47 @@ namespace GridKit auto tol = 10 * std::numeric_limits::epsilon(); // Jacobian via DependencyTracking - std::vector dependency_tracking_jacobian = DependencyTrackingJacobian(); + std::vector + dependency_tracking_jacobian = DependencyTrackingJacobian(); // Jacobian via Enzyme - std::vector enzyme_jacobian = EnzymeJacobian(); + std::vector + enzyme_jacobian = EnzymeJacobian(); /// Compare DependencyTracking dependencies to Enzyme's for (size_t i = 0; i < dependency_tracking_jacobian.size(); ++i) { - success *= (GridKit::Testing::isEqual(dependency_tracking_jacobian[i], enzyme_jacobian[i], tol)); + success *= (GridKit::Testing::isEqual( + dependency_tracking_jacobian[i], enzyme_jacobian[i], tol + )); } return success.report(__func__); } private: - std::vector DependencyTrackingJacobian() + std::vector + DependencyTrackingJacobian() { auto data = makeTestData(); - DependencyTracking::Variable Vr1{3.0}; - DependencyTracking::Variable Vi1{4.0}; - PhasorDynamics::Bus bus(Vr1, Vi1); - PhasorDynamics::Exciter::SexsPti exciter(&bus, data); + DependencyTracking::Variable Vr1{3.0}; + DependencyTracking::Variable Vi1{4.0}; + PhasorDynamics::Bus bus(Vr1, Vi1); + PhasorDynamics::Exciter::SexsPti + exciter(&bus, data); bus.allocate(); exciter.allocate(); for (size_t i = 0; i < bus.size(); ++i) { - bus.setVariableIndex(i, i + exciter.size()); // Reset bus variable indices - bus.setResidualIndex(i, i + exciter.size()); // Reset bus residual indices + bus.setVariableIndex( + i, i + exciter.size() + ); // Reset bus variable indices + bus.setResidualIndex( + i, i + exciter.size() + ); // Reset bus residual indices } bus.initialize(); @@ -447,7 +483,8 @@ namespace GridKit exciter.evaluateJacobian(); auto* model_jacobian = exciter.getCsrJacobian(); auto& output_stream = Log::misc(); - output_stream << "Sparse Csr Matrix: SexsPti DependencyTracking Jacobian\n"; + output_stream + << "Sparse Csr Matrix: SexsPti DependencyTracking Jacobian\n"; model_jacobian->print(output_stream); return GridKit::Testing::MapFromCsr(model_jacobian); @@ -465,8 +502,12 @@ namespace GridKit for (size_t i = 0; i < bus.size(); ++i) { - bus.setVariableIndex(i, i + exciter.size()); // Reset bus variable indices - bus.setResidualIndex(i, i + exciter.size()); // Reset bus residual indices + bus.setVariableIndex( + i, i + exciter.size() + ); // Reset bus variable indices + bus.setResidualIndex( + i, i + exciter.size() + ); // Reset bus residual indices } bus.initialize(); @@ -497,7 +538,9 @@ namespace GridKit PhasorDynamics::Exciter::SexsPtiData data; data.device_class = "exciter"; data.disambiguation_string = "sexspti_test"; - data.monitored_variables.insert(PhasorDynamics::Exciter::SexsPtiMonitorableVariables::efd); + data.monitored_variables.insert( + PhasorDynamics::Exciter::SexsPtiMonitorableVariables::efd + ); data.parameters[Params::Ta] = 0.1; data.parameters[Params::Tb] = 0.5; diff --git a/tests/UnitTests/PhasorDynamics/GenClassicalTests.hpp b/tests/UnitTests/PhasorDynamics/GenClassicalTests.hpp index 0f417d42ec..67ea952708 100644 --- a/tests/UnitTests/PhasorDynamics/GenClassicalTests.hpp +++ b/tests/UnitTests/PhasorDynamics/GenClassicalTests.hpp @@ -31,9 +31,10 @@ namespace GridKit class GenClassicalTests { private: - using RealT = typename PhasorDynamics::Component::RealT; - using GenClassicalDataT = PhasorDynamics::GenClassicalData; - static constexpr ScalarT tol_ = 10 * std::numeric_limits::epsilon(); + using RealT = typename PhasorDynamics::Component::RealT; + using GenClassicalDataT = PhasorDynamics::GenClassicalData; + static constexpr ScalarT tol_ = + 10 * std::numeric_limits::epsilon(); static GenClassicalDataT makeGenClassicalData() { @@ -118,16 +119,15 @@ namespace GridKit { if (!isEqual(y[i], var_answer[i], tol_)) { - std::cout << "Incorrect result: " - << y[i] << " != " << var_answer[i] << "\n"; + std::cout << "Incorrect result: " << y[i] << " != " << var_answer[i] + << "\n"; success = false; break; } if (!isEqual(yp[i], 0.0, tol_)) { - std::cout << "Incorrect result: " - << yp[i] << " != 0\n"; + std::cout << "Incorrect result: " << yp[i] << " != 0\n"; success = false; break; } @@ -143,8 +143,8 @@ namespace GridKit { TestStatus success = true; - PhasorDynamics::Bus bus(1.0, 0.0); - auto data = makeGenClassicalData(); + PhasorDynamics::Bus bus(1.0, 0.0); + auto data = makeGenClassicalData(); PhasorDynamics::GenClassical gen(&bus, data); bus.allocate(); @@ -170,7 +170,8 @@ namespace GridKit } /** - * @brief Checks initialized steady state with nonzero armature resistance. + * @brief Checks initialized steady state with nonzero armature + * resistance. */ TestOutcome residual_nonzero_ra() { @@ -218,8 +219,8 @@ namespace GridKit { TestStatus success = true; - PhasorDynamics::Bus bus(1.0, 0.0); - auto data = makeGenClassicalData(); + PhasorDynamics::Bus bus(1.0, 0.0); + auto data = makeGenClassicalData(); PhasorDynamics::GenClassical gen(&bus, data); bus.allocate(); @@ -432,25 +433,32 @@ namespace GridKit auto tol = 10 * std::numeric_limits::epsilon(); - std::vector dependency_tracking_jacobian = DependencyTrackingJacobian(); - std::vector enzyme_jacobian = EnzymeJacobian(); + std::vector + dependency_tracking_jacobian = DependencyTrackingJacobian(); + std::vector + enzyme_jacobian = EnzymeJacobian(); for (size_t i = 0; i < dependency_tracking_jacobian.size(); ++i) { - success *= (GridKit::Testing::isEqual(dependency_tracking_jacobian[i], enzyme_jacobian[i], tol)); + success *= (GridKit::Testing::isEqual( + dependency_tracking_jacobian[i], enzyme_jacobian[i], tol + )); } return success.report(__func__); } private: - std::vector DependencyTrackingJacobian() + std::vector + DependencyTrackingJacobian() { - DependencyTracking::Variable Vr1{1.0}; - DependencyTracking::Variable Vi1{1.0}; - PhasorDynamics::Bus bus(Vr1, Vi1); - auto data = makeGenClassicalData(); - PhasorDynamics::GenClassical gen(&bus, data); + DependencyTracking::Variable Vr1{1.0}; + DependencyTracking::Variable Vi1{1.0}; + PhasorDynamics::Bus bus(Vr1, Vi1); + auto data = makeGenClassicalData(); + PhasorDynamics::GenClassical gen( + &bus, data + ); bus.allocate(); gen.allocate(); @@ -472,7 +480,8 @@ namespace GridKit gen.evaluateJacobian(); auto* model_jacobian = gen.getCsrJacobian(); auto& output_stream = Log::misc(); - output_stream << "Sparse Csr Matrix: GenClassical DependencyTracking Jacobian\n"; + output_stream + << "Sparse Csr Matrix: GenClassical DependencyTracking Jacobian\n"; model_jacobian->print(output_stream); return GridKit::Testing::MapFromCsr(model_jacobian); @@ -480,10 +489,10 @@ namespace GridKit std::vector EnzymeJacobian() { - ScalarT Vr1{1.0}; - ScalarT Vi1{1.0}; - PhasorDynamics::Bus bus(Vr1, Vi1); - auto data = makeGenClassicalData(); + ScalarT Vr1{1.0}; + ScalarT Vi1{1.0}; + PhasorDynamics::Bus bus(Vr1, Vi1); + auto data = makeGenClassicalData(); PhasorDynamics::GenClassical gen(&bus, data); bus.allocate(); diff --git a/tests/UnitTests/PhasorDynamics/GenrouTests.hpp b/tests/UnitTests/PhasorDynamics/GenrouTests.hpp index c001b5a63f..a0e4feac59 100644 --- a/tests/UnitTests/PhasorDynamics/GenrouTests.hpp +++ b/tests/UnitTests/PhasorDynamics/GenrouTests.hpp @@ -24,9 +24,10 @@ namespace GridKit class GenrouTests { private: - using RealT = typename PhasorDynamics::Component::RealT; - using GenrouDataT = PhasorDynamics::GenrouData; - static constexpr ScalarT tol_ = 10 * std::numeric_limits::epsilon(); + using RealT = typename PhasorDynamics::Component::RealT; + using GenrouDataT = PhasorDynamics::GenrouData; + static constexpr ScalarT tol_ = + 10 * std::numeric_limits::epsilon(); static GenrouDataT makeGenrouData() { @@ -170,8 +171,9 @@ namespace GridKit return success.report(__func__); } - // A test to verify that the hard coded answers match those given by the residual functions - // Hard coded parameters, differential, and algebraic terms + // A test to verify that the hard coded answers match those given by the + // residual functions Hard coded parameters, differential, and algebraic + // terms TestOutcome hard_coded_residual() { TestStatus success = true; @@ -251,9 +253,10 @@ namespace GridKit // Allocate but not initialize generator model gen.allocate(); - // TODO: Set pmech and efd. They are currently not set in this test, as we are not - // calling gen.initialize(). The private members are initialized to 0 as a workaround, - // but this needs to be better handled in the model implementation. + // TODO: Set pmech and efd. They are currently not set in this test, as + // we are not calling gen.initialize(). The private members are + // initialized to 0 as a workaround, but this needs to be better handled + // in the model implementation. // Set variable values matching the answer key auto* y = gen.y().getData(); @@ -326,27 +329,34 @@ namespace GridKit auto tol = 10 * std::numeric_limits::epsilon(); // Jacobian via DependencyTracking - std::vector dependency_tracking_jacobian = DependencyTrackingJacobian(); + std::vector + dependency_tracking_jacobian = DependencyTrackingJacobian(); // Jacobian via Enzyme - std::vector enzyme_jacobian = EnzymeJacobian(); + std::vector + enzyme_jacobian = EnzymeJacobian(); /// Compare DependencyTracking dependencies to Enzyme's for (size_t i = 0; i < dependency_tracking_jacobian.size(); ++i) { - success *= (GridKit::Testing::isEqual(dependency_tracking_jacobian[i], enzyme_jacobian[i], tol)); + success *= (GridKit::Testing::isEqual( + dependency_tracking_jacobian[i], enzyme_jacobian[i], tol + )); } return success.report(__func__); } private: - std::vector DependencyTrackingJacobian() + std::vector + DependencyTrackingJacobian() { - DependencyTracking::Variable Vr1{1.0}; ///< Bus real voltage - DependencyTracking::Variable Vi1{0.0}; ///< Bus imaginary voltage - PhasorDynamics::Bus bus(Vr1, Vi1); - PhasorDynamics::Genrou gen(&bus, makeGenrouData()); + DependencyTracking::Variable Vr1{1.0}; ///< Bus real voltage + DependencyTracking::Variable Vi1{0.0}; ///< Bus imaginary voltage + PhasorDynamics::Bus bus(Vr1, Vi1); + PhasorDynamics::Genrou gen( + &bus, makeGenrouData() + ); bus.allocate(); gen.allocate(); @@ -369,7 +379,8 @@ namespace GridKit gen.evaluateJacobian(); auto* model_jacobian = gen.getCsrJacobian(); auto& output_stream = Log::misc(); - output_stream << "Sparse Csr Matrix: Genrou DependencyTracking Jacobian\n"; + output_stream + << "Sparse Csr Matrix: Genrou DependencyTracking Jacobian\n"; model_jacobian->print(output_stream); return GridKit::Testing::MapFromCsr(model_jacobian); @@ -377,9 +388,9 @@ namespace GridKit std::vector EnzymeJacobian() { - ScalarT Vr1{1.0}; ///< Bus real voltage - ScalarT Vi1{0.0}; ///< Bus imaginary voltage - PhasorDynamics::Bus bus(Vr1, Vi1); + ScalarT Vr1{1.0}; ///< Bus real voltage + ScalarT Vi1{0.0}; ///< Bus imaginary voltage + PhasorDynamics::Bus bus(Vr1, Vi1); PhasorDynamics::Genrou gen(&bus, makeGenrouData()); bus.allocate(); diff --git a/tests/UnitTests/PhasorDynamics/GensalTests.hpp b/tests/UnitTests/PhasorDynamics/GensalTests.hpp index bd0a408758..f9b14b72f0 100644 --- a/tests/UnitTests/PhasorDynamics/GensalTests.hpp +++ b/tests/UnitTests/PhasorDynamics/GensalTests.hpp @@ -22,9 +22,10 @@ namespace GridKit class GensalTests { private: - using RealT = typename PhasorDynamics::Component::RealT; - using GensalDataT = PhasorDynamics::GensalData; - static constexpr ScalarT tol_ = 10 * std::numeric_limits::epsilon(); + using RealT = typename PhasorDynamics::Component::RealT; + using GensalDataT = PhasorDynamics::GensalData; + static constexpr ScalarT tol_ = + 10 * std::numeric_limits::epsilon(); static GensalDataT makeGensalData() { @@ -113,7 +114,8 @@ namespace GridKit } /** - * @brief Checks initialized steady state with nonzero armature resistance. + * @brief Checks initialized steady state with nonzero armature + * resistance. */ TestOutcome residual_nonzero_ra() { @@ -344,25 +346,32 @@ namespace GridKit auto tol = 10 * std::numeric_limits::epsilon(); - std::vector dependency_tracking_jacobian = DependencyTrackingJacobian(); - std::vector enzyme_jacobian = EnzymeJacobian(); + std::vector + dependency_tracking_jacobian = DependencyTrackingJacobian(); + std::vector + enzyme_jacobian = EnzymeJacobian(); for (size_t i = 0; i < dependency_tracking_jacobian.size(); ++i) { - success *= (GridKit::Testing::isEqual(dependency_tracking_jacobian[i], enzyme_jacobian[i], tol)); + success *= (GridKit::Testing::isEqual( + dependency_tracking_jacobian[i], enzyme_jacobian[i], tol + )); } return success.report(__func__); } private: - std::vector DependencyTrackingJacobian() + std::vector + DependencyTrackingJacobian() { - DependencyTracking::Variable Vr1{1.0}; - DependencyTracking::Variable Vi1{0.0}; - PhasorDynamics::Bus bus(Vr1, Vi1); - auto data = makeGensalData(); - PhasorDynamics::Gensal gen(&bus, data); + DependencyTracking::Variable Vr1{1.0}; + DependencyTracking::Variable Vi1{0.0}; + PhasorDynamics::Bus bus(Vr1, Vi1); + auto data = makeGensalData(); + PhasorDynamics::Gensal gen( + &bus, data + ); bus.allocate(); gen.allocate(); @@ -385,7 +394,8 @@ namespace GridKit gen.evaluateJacobian(); auto* model_jacobian = gen.getCsrJacobian(); auto& output_stream = Log::misc(); - output_stream << "Sparse Csr Matrix: Gensal DependencyTracking Jacobian\n"; + output_stream + << "Sparse Csr Matrix: Gensal DependencyTracking Jacobian\n"; model_jacobian->print(output_stream); return GridKit::Testing::MapFromCsr(model_jacobian); diff --git a/tests/UnitTests/PhasorDynamics/GovernorGastPtiTests.hpp b/tests/UnitTests/PhasorDynamics/GovernorGastPtiTests.hpp index 6f5508e7c0..a7cd0ba598 100644 --- a/tests/UnitTests/PhasorDynamics/GovernorGastPtiTests.hpp +++ b/tests/UnitTests/PhasorDynamics/GovernorGastPtiTests.hpp @@ -43,7 +43,8 @@ namespace GridKit static constexpr RealT kTol = static_cast(10.0) * std::numeric_limits::epsilon(); - /// Construction, parameter types and domains, lifecycle, and signal linkage. + /// Construction, parameter types and domains, lifecycle, and signal + /// linkage. TestOutcome validation() { TestStatus success = true; @@ -54,13 +55,18 @@ namespace GridKit Log::setVerbosity(Log::Verbosity::NONE); PhasorDynamics::Governor::GastPti empty(Data{}); - success *= (empty.size() == static_cast(Utilities::enum_size())); - success *= (!empty.verify().passed()); // required pmech assignment is absent + success *= + (empty.size() == static_cast(Utilities::enum_size())); + success *= + (!empty.verify().passed()); // required pmech assignment is absent PhasorDynamics::Governor::GastPti configured(makeData()); - success *= (configured.size() == static_cast(Utilities::enum_size())); + success *= + (configured.size() + == static_cast(Utilities::enum_size())); success *= (configured.getMonitor() != nullptr); - success *= (!configured.verify().passed()); // required pmech assignment is absent + success *= (!configured.verify().passed() + ); // required pmech assignment is absent // Framework binding precedes model allocation; verification must not // inspect index maps until allocate() has sized them. @@ -68,19 +74,26 @@ namespace GridKit typename GastPtiT::VectorT bound_yp; typename GastPtiT::VectorT bound_f; typename GastPtiT::VectorT bound_abs_tol; - const auto bound_size = static_cast(Utilities::enum_size()); + const auto bound_size = + static_cast(Utilities::enum_size()); bound_y.resize(bound_size); bound_yp.resize(bound_size); bound_f.resize(bound_size); bound_abs_tol.resize(bound_size); PhasorDynamics::SignalNode bound_pmech; GastPtiT bound(makeData()); - bound.getPorts().out.template port().connect(&bound_pmech); - success *= (bound.bind(bound_y, bound_yp, bound_f, bound_abs_tol, 0) == 0); + bound.getPorts().out.template port().connect( + &bound_pmech + ); + success *= + (bound.bind(bound_y, bound_yp, bound_f, bound_abs_tol, 0) == 0); success *= (bound.verify().passed()); - PhasorDynamics::Governor::GastPti minimal(makeMinimalData()); - success *= (!minimal.verify().passed()); // required pmech assignment is absent + PhasorDynamics::Governor::GastPti minimal( + makeMinimalData() + ); + success *= + (!minimal.verify().passed()); // required pmech assignment is absent success *= (verifyData(makeData()).passed()); success *= defaultsMatchDocumentedValues(); @@ -114,8 +127,12 @@ namespace GridKit }}; for (const Params parameter : real_parameters) { - success *= invalidParameterCase(parameter, std::numeric_limits::quiet_NaN()); - success *= invalidParameterCase(parameter, std::numeric_limits::infinity()); + success *= invalidParameterCase( + parameter, std::numeric_limits::quiet_NaN() + ); + success *= invalidParameterCase( + parameter, std::numeric_limits::infinity() + ); } // A finite serialized rating that overflows its MW-to-VA conversion is @@ -231,24 +248,39 @@ namespace GridKit Fixture fixture(data); fixture.attachAllInputs(); - fixture.input(index(External::pref)) = 99.0; // stale value the publication must replace - success *= fixture.initialize(0.4); - success *= (fixture.gastpti.tagDifferentiable() == 0); - success *= (fixture.evaluate() == 0); + fixture.input(index(External::pref)) = + 99.0; // stale value the publication must replace + success *= fixture.initialize(0.4); + success *= (fixture.gastpti.tagDifferentiable() == 0); + success *= (fixture.evaluate() == 0); const auto* y = fixture.gastpti.y().getData(); - success *= scalarMatches(y[index(Internal::XVALVE)], 0.8, "XVALVE on component base"); - success *= scalarMatches(y[index(Internal::XFLOW)], 0.8, "XFLOW on component base"); - success *= scalarMatches(y[index(Internal::XTEMP)], 0.8, "XTEMP on component base"); - success *= scalarMatches(y[index(Internal::VLOAD)], 0.8, "VLOAD behind the LV gate"); - success *= scalarMatches(y[index(Internal::VTEMP)], 2.36, "VTEMP at the temperature limit"); - success *= scalarMatches(y[index(Internal::VLV)], 0.8, "VLV at the fuel flow"); - success *= scalarPreserved(fixture.pmech(), 0.4, "preserved pmech seed"); + success *= scalarMatches( + y[index(Internal::XVALVE)], 0.8, "XVALVE on component base" + ); + success *= scalarMatches( + y[index(Internal::XFLOW)], 0.8, "XFLOW on component base" + ); + success *= scalarMatches( + y[index(Internal::XTEMP)], 0.8, "XTEMP on component base" + ); + success *= scalarMatches( + y[index(Internal::VLOAD)], 0.8, "VLOAD behind the LV gate" + ); + success *= scalarMatches( + y[index(Internal::VTEMP)], 2.36, "VTEMP at the temperature limit" + ); + success *= + scalarMatches(y[index(Internal::VLV)], 0.8, "VLV at the fuel flow"); + success *= + scalarPreserved(fixture.pmech(), 0.4, "preserved pmech seed"); success *= scalarPreserved( fixture.input(index(External::speed)), 0.0, "preserved omega input" ); - success *= scalarMatches(fixture.input(index(External::pref)), 0.4, "published pref"); + success *= scalarMatches( + fixture.input(index(External::pref)), 0.4, "published pref" + ); RealT time = 0.0; Model::VariableMonitorController monitor(time); @@ -263,13 +295,15 @@ namespace GridKit std::string monitor_values; std::getline(monitor_output, monitor_header); std::getline(monitor_output, monitor_values); - success *= (monitor_header == "t,GastPti_gastpti_test_pmech," - "GastPti_gastpti_test_xvalve," - "GastPti_gastpti_test_xflow," - "GastPti_gastpti_test_xtemp," - "GastPti_gastpti_test_vload," - "GastPti_gastpti_test_vtemp"); - const auto monitored = Tokenizer(monitor_values, ',')(); + success *= + (monitor_header + == "t,GastPti_gastpti_test_pmech," + "GastPti_gastpti_test_xvalve," + "GastPti_gastpti_test_xflow," + "GastPti_gastpti_test_xtemp," + "GastPti_gastpti_test_vload," + "GastPti_gastpti_test_vtemp"); + const auto monitored = Tokenizer(monitor_values, ',')(); if (monitored.size() == 7) { success *= scalarMatches(monitored[1], 0.4, "monitored pmech"); @@ -299,18 +333,20 @@ namespace GridKit // A system-base reference step lands on the droop row scaled by the // base ratio. - fixture.input(index(External::pref)) = 0.5; // the published 0.4 plus a 0.1 step - success *= (fixture.evaluate() == 0); - success *= residualsMatch( + fixture.input(index(External::pref)) = + 0.5; // the published 0.4 plus a 0.1 step + success *= (fixture.evaluate() == 0); + success *= residualsMatch( fixture.gastpti, {{Internal::VLOAD, 0.01}}, "reference step on the component base" ); // GridKit deliberately leaves references above At uncapped. - fixture.input(index(External::pref)) = 1.1; // 2.2 on component base; At = 2.0 - success *= (fixture.evaluate() == 0); - success *= residualsMatch( + fixture.input(index(External::pref)) = + 1.1; // 2.2 on component base; At = 2.0 + success *= (fixture.evaluate() == 0); + success *= residualsMatch( fixture.gastpti, {{Internal::VLOAD, 0.07}}, "uncapped reference above At" @@ -334,15 +370,15 @@ namespace GridKit const std::array speed_cases{{0.05, -0.05}}; for (const RealT omega : speed_cases) { - const RealT xflow = system_to_component * initial_pmech - + turbine_damping * omega; - const RealT vtemp = temperature_limit - + temperature_gain * (temperature_limit - xflow); + const RealT xflow = + system_to_component * initial_pmech + turbine_damping * omega; + const RealT vtemp = + temperature_limit + temperature_gain * (temperature_limit - xflow); Fixture speed_fixture(data); speed_fixture.attachAllInputs(); - speed_fixture.input(index(External::speed)) = omega; - success *= speed_fixture.initialize(initial_pmech); + speed_fixture.input(index(External::speed)) = omega; + success *= speed_fixture.initialize(initial_pmech); success *= stateMatches( speed_fixture.gastpti, {{Internal::XVALVE, xflow}, @@ -362,16 +398,17 @@ namespace GridKit omega, "signed-speed input preservation" ); - const auto* speed_y = speed_fixture.gastpti.y().getData(); - const RealT vload = static_cast(speed_y[index(Internal::VLOAD)]); - const RealT pref = component_to_system * (vload + omega / droop); - success *= scalarMatches( + const auto* speed_y = speed_fixture.gastpti.y().getData(); + const RealT vload = + static_cast(speed_y[index(Internal::VLOAD)]); + const RealT pref = component_to_system * (vload + omega / droop); + success *= scalarMatches( speed_fixture.input(index(External::pref)), pref, "signed-speed pref publication" ); - success *= (speed_fixture.evaluate() == 0); - success *= allResidualsZero(speed_fixture.gastpti); + success *= (speed_fixture.evaluate() == 0); + success *= allResidualsZero(speed_fixture.gastpti); } return success.report(__func__); @@ -384,8 +421,8 @@ namespace GridKit TestStatus success = true; const auto previous_verbosity = Log::verbosity(); - // Suppress expected errors and response-limit warnings from the cases below. - // Use EVERYTHING to inspect those diagnostics. + // Suppress expected errors and response-limit warnings from the cases + // below. Use EVERYTHING to inspect those diagnostics. Log::setVerbosity(Log::Verbosity::NONE); struct RejectionCase @@ -406,7 +443,7 @@ namespace GridKit { auto data = makeResidualData(); data.parameters[Params::At] = test_case.at; - success *= initializationRejectedAtomically( + success *= initializationRejectedAtomically( data, test_case.pmech, test_case.label ); } @@ -422,11 +459,15 @@ namespace GridKit const auto invalid_yp = copyVector(invalid_fixture.gastpti.yp()); if (invalid_fixture.gastpti.initialize() == 0) { - std::cout << "Expected initialization rejection: invalid configuration\n"; + std::cout + << "Expected initialization rejection: invalid configuration\n"; success = false; } - success *= vectorUnchanged(invalid_fixture.gastpti.y(), invalid_y, "state"); - success *= vectorUnchanged(invalid_fixture.gastpti.yp(), invalid_yp, "derivative"); + success *= + vectorUnchanged(invalid_fixture.gastpti.y(), invalid_y, "state"); + success *= vectorUnchanged( + invalid_fixture.gastpti.yp(), invalid_yp, "derivative" + ); const std::array nonfinite_values{{ std::numeric_limits::quiet_NaN(), @@ -450,27 +491,30 @@ namespace GridKit // Each case starts from finite parameters and finite seeds, then // overflows a different initialization candidate. None may commit. auto power_candidate = makeResidualData(); - success *= initializationRejectedAtomically( + success *= initializationRejectedAtomically( power_candidate, std::numeric_limits::max(), "non-finite component-base power candidate" ); - auto flow_candidate = makeResidualData(); - flow_candidate.parameters[Params::Dturb] = std::numeric_limits::max(); + auto flow_candidate = makeResidualData(); + flow_candidate.parameters[Params::Dturb] = + std::numeric_limits::max(); success *= initializationRejectedAtomically( flow_candidate, 0.4, "non-finite fuel-flow candidate", 2.0 ); - auto temperature_candidate = makeResidualData(); - temperature_candidate.parameters[Params::At] = std::numeric_limits::max(); + auto temperature_candidate = makeResidualData(); + temperature_candidate.parameters[Params::At] = + std::numeric_limits::max(); success *= initializationRejectedAtomically( temperature_candidate, 0.4, "non-finite temperature candidate" ); - auto reference_candidate = makeResidualData(); - reference_candidate.parameters[Params::R] = std::numeric_limits::denorm_min(); - reference_candidate.parameters[Params::Dturb] = ZERO; + auto reference_candidate = makeResidualData(); + reference_candidate.parameters[Params::R] = + std::numeric_limits::denorm_min(); + reference_candidate.parameters[Params::Dturb] = ZERO; success *= initializationRejectedAtomically( reference_candidate, 0.4, @@ -485,9 +529,8 @@ namespace GridKit success *= over_rated.initialize(0.6); // fuel flow 1.2 above Vmax = 1.1 success *= stateMatches( over_rated.gastpti, - {{Internal::XVALVE, 1.2}, - {Internal::XFLOW, 1.2}, - {Internal::VLV, 1.2}}, + {{Internal::XVALVE, 1.2}, {Internal::XFLOW, 1.2}, {Internal::VLV, 1.2} + }, "over-rated dispatch" ); success *= scalarPreserved( @@ -517,8 +560,12 @@ namespace GridKit std::cout << "Expected failed GASTPTI reinitialization\n"; success = false; } - success *= vectorUnchanged(reinitialize.gastpti.y(), y_before, "reinitialized state"); - success *= vectorUnchanged(reinitialize.gastpti.yp(), yp_before, "reinitialized derivative"); + success *= vectorUnchanged( + reinitialize.gastpti.y(), y_before, "reinitialized state" + ); + success *= vectorUnchanged( + reinitialize.gastpti.yp(), yp_before, "reinitialized derivative" + ); success *= scalarPreserved( reinitialize.input(index(External::pref)), pref_before, @@ -628,9 +675,9 @@ namespace GridKit constexpr RealT initial_flow = 0.8; constexpr RealT system_to_component = 2.0; - constexpr RealT initial_pmech = initial_flow / system_to_component; - constexpr RealT temperature_gain = 0.4; - constexpr RealT temperature_margin = 1.0e-4; + constexpr RealT initial_pmech = initial_flow / system_to_component; + constexpr RealT temperature_gain = 0.4; + constexpr RealT temperature_margin = 1.0e-4; auto data = makeResidualData(); data.parameters[Params::Kt] = temperature_gain; @@ -652,7 +699,8 @@ namespace GridKit const RealT vtemp = static_cast(y[index(Internal::VTEMP)]); if (!(vload > vtemp)) { - std::cout << "GASTPTI near-gate initialization selected the wrong demand side\n"; + std::cout << "GASTPTI near-gate initialization selected the wrong " + "demand side\n"; success = false; } success *= (fixture.evaluate() == 0); @@ -692,7 +740,8 @@ namespace GridKit setAnswerKeyState(fixture.gastpti); success *= (fixture.evaluate() == 0); - // The state is chosen so every documented equation has a readable answer. + // The state is chosen so every documented equation has a readable + // answer. const std::array()> expected{{ {Internal::XVALVE, 0.19}, @@ -704,7 +753,9 @@ namespace GridKit {Internal::PMECH, -0.1424}, }}; - success *= (static_cast(fixture.gastpti.getResidual().getSize()) == expected.size()); + success *= + (static_cast(fixture.gastpti.getResidual().getSize()) + == expected.size()); success *= residualsMatch(fixture.gastpti, expected); return success.report(__func__); @@ -754,15 +805,16 @@ namespace GridKit speed_step.attachAllInputs(); success *= speed_step.initialize(0.4); speed_step.input(index(External::speed)) = 0.05; - success *= (speed_step.evaluate() == 0); - success *= residualsMatch( + success *= (speed_step.evaluate() == 0); + success *= residualsMatch( speed_step.gastpti, {{Internal::VLOAD, -0.05}, {Internal::PMECH, -0.006}}, "speed deviation in the droop and damping rows" ); // Normal response expands both sides of the configured interval to - // admit the initialized flow. The derived boundary must be used thereafter. + // admit the initialized flow. The derived boundary must be used + // thereafter. constexpr RealT valve_time_constant = 0.35; constexpr RealT boundary_weight = 0.5; constexpr RealT command_magnitude = 0.25; @@ -784,9 +836,9 @@ namespace GridKit command_magnitude}, {"adjusted lower response boundary", ZERO, -command_magnitude}, }}; - const auto previous_verbosity = Log::verbosity(); - // Suppress expected response-limit adjustment warnings from these cases. - // Use EVERYTHING to inspect those diagnostics. + const auto previous_verbosity = Log::verbosity(); + // Suppress expected response-limit adjustment warnings from these + // cases. Use EVERYTHING to inspect those diagnostics. Log::setVerbosity(Log::Verbosity::NONE); for (const auto& test_case : effective_boundary_cases) { @@ -959,8 +1011,8 @@ namespace GridKit ); const auto adjusted_verbosity = Log::verbosity(); - // Suppress the expected response-limit adjustment warning for this case. - // Use EVERYTHING to inspect the diagnostic. + // Suppress the expected response-limit adjustment warning for this + // case. Use EVERYTHING to inspect the diagnostic. Log::setVerbosity(Log::Verbosity::NONE); Fixture adjusted(data); adjusted.attachAllInputs(); @@ -983,8 +1035,8 @@ namespace GridKit collapsed_data.parameters[Params::Vmax] = collapsed_limit; const auto collapsed_verbosity = Log::verbosity(); - // Suppress the expected response-limit adjustment warning for this case. - // Use EVERYTHING to inspect the diagnostic. + // Suppress the expected response-limit adjustment warning for this + // case. Use EVERYTHING to inspect the diagnostic. Log::setVerbosity(Log::Verbosity::NONE); Fixture collapsed(collapsed_data); collapsed.attachAllInputs(); @@ -1046,9 +1098,12 @@ namespace GridKit class Fixture { private: - std::array()> input_values_{}; - std::array()> input_indices_{}; - std::array, Utilities::enum_size()> input_nodes_{}; + std::array()> input_values_{}; + std::array()> input_indices_{}; + std::array< + PhasorDynamics::SignalNode, + Utilities::enum_size()> + input_nodes_{}; PhasorDynamics::SignalNode pmech_node_; @@ -1057,7 +1112,9 @@ namespace GridKit : gastpti(data) { gastpti.setSystemBase(60.0, system_va_base); - gastpti.getPorts().out.template port().connect(&pmech_node_); + gastpti.getPorts().out.template port().connect( + &pmech_node_ + ); } Fixture(const Fixture&) = delete; @@ -1070,10 +1127,13 @@ namespace GridKit for (auto variant : Utilities::enum_values()) { - const auto port = static_cast(variant); - input_values_[port] = static_cast(initial_value); - input_indices_[port] = external_index_base + static_cast(port); - input_nodes_[port].link(&input_values_[port], &input_indices_[port]); + const auto port = static_cast(variant); + input_values_[port] = static_cast(initial_value); + input_indices_[port] = + external_index_base + static_cast(port); + input_nodes_[port].link( + &input_values_[port], &input_indices_[port] + ); } gastpti.getPorts().in.template port().connect( @@ -1094,7 +1154,8 @@ namespace GridKit /// verification, and a machine-seeded mechanical-power node. bool prepare(RealT pmech) { - const bool success = (gastpti.allocate() == 0) && (gastpti.verify().passed()); + const bool success = + (gastpti.allocate() == 0) && (gastpti.verify().passed()); if (!success) { std::cout << "GASTPTI fixture preparation failed\n"; @@ -1225,7 +1286,8 @@ namespace GridKit /// The rich state shared by the residual answer key and the Jacobian /// comparison. Every row is distinct so a swapped index cannot pass. template - void setAnswerKeyState(PhasorDynamics::Governor::GastPti& gastpti) const + void setAnswerKeyState(PhasorDynamics::Governor::GastPti& gastpti + ) const { setState( gastpti, @@ -1258,7 +1320,8 @@ namespace GridKit && explicit_defaults.initialize(0.3); if (!success) { - std::cout << "GASTPTI documented-default comparison failed to initialize\n"; + std::cout + << "GASTPTI documented-default comparison failed to initialize\n"; return false; } @@ -1323,15 +1386,16 @@ namespace GridKit { auto data = makeData(); data.parameters[parameter] = value; - return configurationRejected([&]() - { return verifyData(data); }); + return configurationRejected([&]() { return verifyData(data); }); } Model::ConfigurationChecks verifyData(const Data& data) const { PhasorDynamics::SignalNode pmech; PhasorDynamics::Governor::GastPti model(data); - model.getPorts().out.template port().connect(&pmech); + model.getPorts().out.template port().connect( + &pmech + ); return model.verify(); } @@ -1341,7 +1405,9 @@ namespace GridKit PhasorDynamics::SignalNode unlinked_node; PhasorDynamics::SignalNode pmech_node; PhasorDynamics::Governor::GastPti model(makeData()); - model.getPorts().out.template port().connect(&pmech_node); + model.getPorts().out.template port().connect( + &pmech_node + ); model.getPorts().in.template port().connect(&unlinked_node); return !model.verify().passed(); } @@ -1355,8 +1421,12 @@ namespace GridKit NodeT pmech_pref; ModelT pref_alias(makeData()); - pref_alias.getPorts().out.template port().connect(&pmech_pref); - pref_alias.getPorts().in.template port().connect(&pmech_pref); + pref_alias.getPorts().out.template port().connect( + &pmech_pref + ); + pref_alias.getPorts().in.template port().connect( + &pmech_pref + ); if (pref_alias.allocate() != 0) { success = false; @@ -1368,8 +1438,12 @@ namespace GridKit NodeT pmech_speed; ModelT speed_alias(makeData()); - speed_alias.getPorts().out.template port().connect(&pmech_speed); - speed_alias.getPorts().in.template port().connect(&pmech_speed); + speed_alias.getPorts() + .out.template port() + .connect(&pmech_speed); + speed_alias.getPorts().in.template port().connect( + &pmech_speed + ); if (speed_alias.allocate() != 0) { success = false; @@ -1386,9 +1460,15 @@ namespace GridKit shared_input.link(&shared_value, &shared_index); ModelT input_alias(makeData()); - input_alias.getPorts().out.template port().connect(&pmech); - input_alias.getPorts().in.template port().connect(&shared_input); - input_alias.getPorts().in.template port().connect(&shared_input); + input_alias.getPorts() + .out.template port() + .connect(&pmech); + input_alias.getPorts().in.template port().connect( + &shared_input + ); + input_alias.getPorts().in.template port().connect( + &shared_input + ); if (input_alias.allocate() != 0) { success = false; @@ -1440,7 +1520,9 @@ namespace GridKit { auto* y = fixture.gastpti.y().getData(); auto* yp = fixture.gastpti.yp().getData(); - for (size_t i = 0; i < static_cast(fixture.gastpti.y().getSize()); ++i) + for (size_t i = 0; + i < static_cast(fixture.gastpti.y().getSize()); + ++i) { y[i] = 0.125 + 0.01 * static_cast(i); yp[i] = -0.25 - 0.01 * static_cast(i); @@ -1450,17 +1532,15 @@ namespace GridKit fixture.gastpti.yp().setDataUpdated(); } - bool initializationRejectedAtomically( - const Data& data, - RealT pmech, - const char* label, - RealT omega = ZERO - ) const + bool + initializationRejectedAtomically(const Data& data, RealT pmech, const char* label, RealT omega = ZERO) + const { Fixture fixture(data); fixture.attachAllInputs(); fixture.input(index(External::speed)) = omega; - fixture.input(index(External::pref)) = 77.0; // must stay untouched on rejection + fixture.input(index(External::pref)) = + 77.0; // must stay untouched on rejection if (!fixture.prepare(pmech)) { return false; @@ -1558,8 +1638,8 @@ namespace GridKit } std::cout << "GASTPTI " << what << " row " << row << ' ' << context << " mismatch: " - << std::setprecision(std::numeric_limits::max_digits10) << actual - << " != " << expected << '\n'; + << std::setprecision(std::numeric_limits::max_digits10) + << actual << " != " << expected << '\n'; return false; } @@ -1577,7 +1657,13 @@ namespace GridKit for (const auto& [variable, expected] : values) { const size_t row = index(variable); - if (!rowMatches(static_cast(vector_values[row]), expected, what, row, context)) + if (!rowMatches( + static_cast(vector_values[row]), + expected, + what, + row, + context + )) { success = false; } @@ -1630,13 +1716,19 @@ namespace GridKit bool success = true; const auto* f = gastpti.getResidual().getData(); const auto* yp = gastpti.yp().getData(); - for (size_t row = 0; row < static_cast(gastpti.getResidual().getSize()); ++row) + for (size_t row = 0; + row < static_cast(gastpti.getResidual().getSize()); + ++row) { - if (!rowMatches(static_cast(f[row]), 0.0, "residual", row, "at rest")) + if (!rowMatches( + static_cast(f[row]), 0.0, "residual", row, "at rest" + )) { success = false; } - if (!rowMatches(static_cast(yp[row]), 0.0, "derivative", row, "at rest")) + if (!rowMatches( + static_cast(yp[row]), 0.0, "derivative", row, "at rest" + )) { success = false; } @@ -1656,8 +1748,8 @@ namespace GridKit return true; } std::cout << label << " mismatch: " - << std::setprecision(std::numeric_limits::max_digits10) << actual - << " != " << expected << "\n"; + << std::setprecision(std::numeric_limits::max_digits10) + << actual << " != " << expected << "\n"; return false; } @@ -1672,7 +1764,8 @@ namespace GridKit return actual == expected; } - bool scalarPreserved(ScalarT actual, ScalarT expected, const char* label) const + bool scalarPreserved(ScalarT actual, ScalarT expected, const char* label) + const { const RealT actual_value = static_cast(actual); const RealT expected_value = static_cast(expected); @@ -1714,15 +1807,18 @@ namespace GridKit { if (actual.size() != expected.size()) { - std::cout << "GASTPTI Jacobian " << context << " row-count mismatch: " - << actual.size() << " != " << expected.size() << '\n'; + std::cout << "GASTPTI Jacobian " << context + << " row-count mismatch: " << actual.size() + << " != " << expected.size() << '\n'; return false; } bool success = true; for (size_t row = 0; row < actual.size(); ++row) { - if (!jacobianRowMatches(actual[row], expected[row], row, context, tolerance)) + if (!jacobianRowMatches( + actual[row], expected[row], row, context, tolerance + )) { success = false; } @@ -1730,7 +1826,8 @@ namespace GridKit return success; } - /// @todo Remove and setup the test to not rely on explicit variable numbering + /// @todo Remove and setup the test to not rely on explicit variable + /// numbering void numberVariables(Fixture& fixture) const { auto* y = fixture.gastpti.y().getData(); diff --git a/tests/UnitTests/PhasorDynamics/GovernorHygovTests.hpp b/tests/UnitTests/PhasorDynamics/GovernorHygovTests.hpp index 3736d2948b..aac6cb4bad 100644 --- a/tests/UnitTests/PhasorDynamics/GovernorHygovTests.hpp +++ b/tests/UnitTests/PhasorDynamics/GovernorHygovTests.hpp @@ -51,10 +51,13 @@ namespace GridKit TestStatus success = true; PhasorDynamics::Governor::Hygov empty(Data{}); - success *= (empty.size() == static_cast(Utilities::enum_size())); + success *= + (empty.size() == static_cast(Utilities::enum_size())); Fixture configured(makeData()); - success *= (configured.hygov.size() == static_cast(Utilities::enum_size())); + success *= + (configured.hygov.size() + == static_cast(Utilities::enum_size())); success *= (configured.hygov.getMonitor() != nullptr); success *= (configured.hygov.verify().passed()); @@ -87,7 +90,7 @@ namespace GridKit Params::Pgv0, Params::Pgv1, Params::Pgv2, Params::Pgv3, Params::Pgv4, Params::Pgv5, }}; - const std::array nonfinite_values{{nan, infinity, -infinity}}; + const std::array nonfinite_values{{nan, infinity, -infinity}}; for (const Params parameter : real_parameters) { @@ -239,14 +242,17 @@ namespace GridKit Fixture fixture(makeData(), {{Params::Trate, 50.0}}); fixture.attachAllInputs(); - fixture.input(External::paux) = 0.02; - fixture.input(External::pref) = 99.0; // stale value the publication must replace - success *= fixture.initialize(0.4); - success *= (fixture.hygov.tagDifferentiable() == 0); - success *= (fixture.evaluate() == 0); + fixture.input(External::paux) = 0.02; + fixture.input(External::pref) = + 99.0; // stale value the publication must replace + success *= fixture.initialize(0.4); + success *= (fixture.hygov.tagDifferentiable() == 0); + success *= (fixture.evaluate() == 0); const auto* y = fixture.hygov.y().getData(); - success *= scalarMatches(y[static_cast(Internal::XF)], 0.0, "XF at rest"); + success *= scalarMatches( + y[static_cast(Internal::XF)], 0.0, "XF at rest" + ); success *= scalarMatches( y[static_cast(Internal::C)], 0.9000000000001573, @@ -257,18 +263,29 @@ namespace GridKit 0.9000000000001573, "G on component base" ); - success *= scalarMatches(y[static_cast(Internal::Q)], 0.9, "Q on component base"); + success *= scalarMatches( + y[static_cast(Internal::Q)], 0.9, "Q on component base" + ); success *= scalarMatches( y[static_cast(Internal::PGV)], 0.9, "PGV on component base" ); - success *= scalarMatches(y[static_cast(Internal::H)], 1.0, "H at the dam head"); - success *= scalarMatches(fixture.pmech(), 0.4, "preserved pmech value"); + success *= scalarMatches( + y[static_cast(Internal::H)], 1.0, "H at the dam head" + ); + success *= scalarMatches(fixture.pmech(), 0.4, "preserved pmech value"); - success *= scalarMatches(fixture.input(External::speed), 0.0, "preserved omega input"); - success *= scalarMatches(fixture.input(External::pref), 0.0025, "published pref"); - success *= scalarMatches(fixture.input(External::paux), 0.02, "preserved paux input"); + success *= scalarMatches( + fixture.input(External::speed), 0.0, "preserved omega input" + ); + success *= scalarMatches( + fixture.input(External::pref), 0.0025, "published pref" + ); + success *= scalarMatches( + fixture.input(External::paux), 0.02, "preserved paux input" + ); - // Verify the six documented outputs through the public monitor controller. + // Verify the six documented outputs through the public monitor + // controller. RealT time = 0.0; Model::VariableMonitorController monitor(time); monitor.addMonitor(fixture.hygov.getMonitor()); @@ -282,16 +299,21 @@ namespace GridKit std::string monitor_values; std::getline(monitor_output, monitor_header); std::getline(monitor_output, monitor_values); - success *= (monitor_header == "t,Hygov_hygov_test_pmech,Hygov_hygov_test_filter," - "Hygov_hygov_test_desiredgate,Hygov_hygov_test_gate," - "Hygov_hygov_test_flow,Hygov_hygov_test_head"); - const auto monitored = Tokenizer(monitor_values, ',')(); + success *= + (monitor_header + == "t,Hygov_hygov_test_pmech,Hygov_hygov_test_filter," + "Hygov_hygov_test_desiredgate,Hygov_hygov_test_gate," + "Hygov_hygov_test_flow,Hygov_hygov_test_head"); + const auto monitored = Tokenizer(monitor_values, ',')(); if (monitored.size() == 7) { success *= scalarMatches(monitored[1], 0.4, "monitored pmech"); success *= scalarMatches(monitored[2], 0.0, "monitored filter"); - success *= scalarMatches(monitored[3], 0.9000000000001573, "monitored desiredgate"); - success *= scalarMatches(monitored[4], 0.9000000000001573, "monitored gate"); + success *= scalarMatches( + monitored[3], 0.9000000000001573, "monitored desiredgate" + ); + success *= + scalarMatches(monitored[4], 0.9000000000001573, "monitored gate"); success *= scalarMatches(monitored[5], 0.9, "monitored flow"); success *= scalarMatches(monitored[6], 1.0, "monitored head"); } @@ -317,9 +339,10 @@ namespace GridKit // A system-base reference step lands on the governor error scaled by // the base ratio. - fixture.input(External::pref) = 0.1025; // the published 0.0025 plus a 0.1 step - success *= (fixture.evaluate() == 0); - success *= residualsMatch( + fixture.input(External::pref) = + 0.1025; // the published 0.0025 plus a 0.1 step + success *= (fixture.evaluate() == 0); + success *= residualsMatch( fixture.hygov, {{Internal::EF, 0.2}}, "reference step on the component base" @@ -343,8 +366,8 @@ namespace GridKit TestStatus success = true; const auto previous_verbosity = Log::verbosity(); - // Suppress expected errors and limit-adjustment warnings from the cases below. - // Use EVERYTHING to inspect those diagnostics. + // Suppress expected errors and limit-adjustment warnings from the cases + // below. Use EVERYTHING to inspect those diagnostics. Log::setVerbosity(Log::Verbosity::NONE); success *= initializationRejectedAtomically( @@ -393,7 +416,9 @@ namespace GridKit {Internal::H, 1.6511654364800423}}, "effective dam head" ); - success *= scalarMatches(effective_fixture.pmech(), 0.045, "preserved pmech value"); + success *= scalarMatches( + effective_fixture.pmech(), 0.045, "preserved pmech value" + ); success *= scalarMatches( effective_fixture.input(External::pref), 0.0009, "published pref" ); @@ -419,15 +444,15 @@ namespace GridKit makeResidualData(), {{test_case.limit_parameter, test_case.limit}} ); success *= fixture.initialize(0.4); - const RealT gate = static_cast( - fixture.hygov.y().getData()[static_cast(Internal::C)] - ); - const bool gate_is_outside = test_case.rate > 0.0 - ? gate > test_case.limit - : gate < test_case.limit; + const RealT gate = static_cast(fixture.hygov.y().getData( + )[static_cast(Internal::C)]); + const bool gate_is_outside = test_case.rate > 0.0 + ? gate > test_case.limit + : gate < test_case.limit; if (!gate_is_outside) { - std::cout << test_case.label << " did not initialize outside the configured limit\n"; + std::cout << test_case.label + << " did not initialize outside the configured limit\n"; success = false; } success *= stateMatches( @@ -446,46 +471,51 @@ namespace GridKit {Internal::RC, test_case.rate}} ); setDerivative(fixture.hygov, {{Internal::C, 0.0}}); - success *= (fixture.evaluate() == 0); + success *= (fixture.evaluate() == 0); const RealT response_rate = - static_cast(fixture.hygov.getResidual() - .getData()[static_cast(Internal::C)]); + static_cast(fixture.hygov.getResidual().getData( + )[static_cast(Internal::C)]); const bool rate_is_admitted = test_case.rate > 0.0 ? response_rate > 0.9 * test_case.rate : response_rate < 0.9 * test_case.rate; if (!rate_is_admitted) { - std::cout << test_case.label << " did not admit the outward desired-gate rate\n"; + std::cout << test_case.label + << " did not admit the outward desired-gate rate\n"; success = false; } } // A failed retry preserves the effective head and response bounds from // the prior success. - const auto effective_y = copyVector(effective_fixture.hygov.y()); - const auto effective_yp = copyVector(effective_fixture.hygov.yp()); - effective_fixture.input(External::speed) = 0.03; - success *= (effective_fixture.hygov.initialize() != 0); - success *= vectorUnchanged(effective_fixture.hygov.y(), effective_y, "state"); - success *= vectorUnchanged(effective_fixture.hygov.yp(), effective_yp, "derivative"); + const auto effective_y = copyVector(effective_fixture.hygov.y()); + const auto effective_yp = copyVector(effective_fixture.hygov.yp()); + effective_fixture.input(External::speed) = 0.03; + success *= (effective_fixture.hygov.initialize() != 0); + success *= + vectorUnchanged(effective_fixture.hygov.y(), effective_y, "state"); + success *= vectorUnchanged( + effective_fixture.hygov.yp(), effective_yp, "derivative" + ); success *= scalarMatches( effective_fixture.input(External::pref), 0.0009, "preserved pref" ); - effective_fixture.input(External::speed) = 0.0; - success *= (effective_fixture.evaluate() == 0); - success *= allResidualsZero(effective_fixture.hygov); + effective_fixture.input(External::speed) = 0.0; + success *= (effective_fixture.evaluate() == 0); + success *= allResidualsZero(effective_fixture.hygov); setState( effective_fixture.hygov, {{Internal::C, 0.75}, {Internal::RC, 0.2}} ); setDerivative(effective_fixture.hygov, {{Internal::C, 0.0}}); - success *= (effective_fixture.evaluate() == 0); + success *= (effective_fixture.evaluate() == 0); const RealT preserved_rate = - static_cast(effective_fixture.hygov.getResidual() - .getData()[static_cast(Internal::C)]); + static_cast(effective_fixture.hygov.getResidual().getData( + )[static_cast(Internal::C)]); if (!(preserved_rate > 0.19)) { - std::cout << "failed initialization did not preserve effective Gmax\n"; + std::cout + << "failed initialization did not preserve effective Gmax\n"; success = false; } @@ -507,8 +537,8 @@ namespace GridKit setDerivative(effective_fixture.hygov, {{Internal::C, 0.0}}); success *= (effective_fixture.evaluate() == 0); success *= scalarMatches( - static_cast(effective_fixture.hygov.getResidual() - .getData()[static_cast(Internal::C)]), + static_cast(effective_fixture.hygov.getResidual().getData( + )[static_cast(Internal::C)]), 0.0, "configured Gmax after reinitialization" ); @@ -525,7 +555,9 @@ namespace GridKit ); // An invalid configuration is rejected before any state is written. - Fixture invalid_fixture(makeResidualData(), {{Params::Rtemp, 0.0}}); + Fixture invalid_fixture( + makeResidualData(), {{Params::Rtemp, 0.0}} + ); invalid_fixture.attachAllInputs(); success *= (invalid_fixture.hygov.allocate() == 0); poisonState(invalid_fixture, 0.4); @@ -533,13 +565,17 @@ namespace GridKit const auto invalid_yp = copyVector(invalid_fixture.hygov.yp()); if (invalid_fixture.hygov.initialize() == 0) { - std::cout << "Expected initialization rejection: invalid configuration\n"; + std::cout + << "Expected initialization rejection: invalid configuration\n"; success = false; } - success *= vectorUnchanged(invalid_fixture.hygov.y(), invalid_y, "state"); - success *= vectorUnchanged(invalid_fixture.hygov.yp(), invalid_yp, "derivative"); + success *= + vectorUnchanged(invalid_fixture.hygov.y(), invalid_y, "state"); + success *= + vectorUnchanged(invalid_fixture.hygov.yp(), invalid_yp, "derivative"); - // Zero mechanical power lands on an in-range root and initializes at rest. + // Zero mechanical power lands on an in-range root and initializes at + // rest. Fixture zero_power_fixture(makeData()); success *= zero_power_fixture.initialize(0.0); success *= stateMatches( @@ -572,7 +608,7 @@ namespace GridKit success *= allResidualsZero(lower_edge.hygov); Fixture effective_edge(makeData()); - success *= effective_edge.initialize(p_max + 0.5 * kTol); + success *= effective_edge.initialize(p_max + 0.5 * kTol); success *= stateMatches( effective_edge.hygov, {{Internal::C, 1.0}, {Internal::G, 1.0}}, @@ -633,7 +669,7 @@ namespace GridKit pmech_fixture.input(External::pref) = 77.0; pmech_fixture.input(External::paux) = 0.02; success *= pmech_fixture.prepare(value); - success *= (pmech_fixture.hygov.initialize() != 0); + success *= (pmech_fixture.hygov.initialize() != 0); success *= scalarPreserved( static_cast(pmech_fixture.input(External::pref)), 77.0, @@ -682,7 +718,8 @@ namespace GridKit { Fixture fixture(makeResidualData()); success *= fixture.initialize(seed.pmech); - success *= stateMatches(fixture.hygov, {{Internal::G, seed.gate}}, seed.label); + success *= + stateMatches(fixture.hygov, {{Internal::G, seed.gate}}, seed.label); success *= (fixture.evaluate() == 0); success *= allResidualsZero(fixture.hygov); } @@ -719,7 +756,9 @@ namespace GridKit {Internal::PMECH, -0.012679999999999934}, }}; - success *= (static_cast(fixture.hygov.getResidual().getSize()) == expected.size()); + success *= + (static_cast(fixture.hygov.getResidual().getSize()) + == expected.size()); success *= residualsMatch(fixture.hygov, expected, "answer key"); return success.report(__func__); @@ -814,8 +853,8 @@ namespace GridKit .getDependencies(); const DepVar::DependencyMap expected{{ {2 * static_cast(Internal::C), 0.0}, // @todo Remove these - {2 * static_cast(Internal::C) + 1, - -1.0}, // @todo Remove these + {2 * static_cast(Internal::C) + 1, -1.0 + }, // @todo Remove these {2 * static_cast(Internal::RC), 0.0}, // @todo Remove these }}; success *= isEqual(dependencies, expected, kTol); @@ -885,8 +924,8 @@ namespace GridKit success *= curve_fixture.initialize(0.33761676); success *= stateMatches( curve_fixture.hygov, - {{Internal::C, 0.5000001394783365}, - {Internal::G, 0.5000001394783365}}, + {{Internal::C, 0.5000001394783365}, {Internal::G, 0.5000001394783365} + }, "nonidentity curve inversion" ); success *= scalarMatches( @@ -894,13 +933,15 @@ namespace GridKit 0.015000004184348527, "nonidentity-curve published pref" ); - success *= scalarMatches(curve_fixture.pmech(), 0.33761676, "preserved pmech value"); + success *= scalarMatches( + curve_fixture.pmech(), 0.33761676, "preserved pmech value" + ); success *= (curve_fixture.evaluate() == 0); success *= allResidualsZero(curve_fixture.hygov); - // A flat source-curve segment must initialize to a gate on that segment. - // makeData() uses equal power bases, At = Hdam = 1, and Qnl = 0.1, - // so a 0.5 plateau maps to pmech = 0.4 without encoding Math::MU. + // A flat source-curve segment must initialize to a gate on that + // segment. makeData() uses equal power bases, At = Hdam = 1, and Qnl = + // 0.1, so a 0.5 plateau maps to pmech = 0.4 without encoding Math::MU. const RealT flat_gate_minimum = static_cast(0.4); const RealT flat_gate_maximum = static_cast(0.6); const RealT plateau_power = static_cast(0.5); @@ -915,9 +956,11 @@ namespace GridKit if (flat_gate < flat_gate_minimum || flat_gate > flat_gate_maximum) { std::cout << "flat-segment plateau gate " - << std::setprecision(std::numeric_limits::max_digits10) - << flat_gate << " is outside [" << flat_gate_minimum - << ", " << flat_gate_maximum << "]\n"; + << std::setprecision( + std::numeric_limits::max_digits10 + ) + << flat_gate << " is outside [" << flat_gate_minimum << ", " + << flat_gate_maximum << "]\n"; success = false; } success *= (flat_fixture.evaluate() == 0); @@ -935,15 +978,19 @@ namespace GridKit TestStatus success = true; const auto data = makeResidualData(); - const std::array gate_points{{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9}}; + const std::array gate_points{ + {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9} + }; for (const RealT gate : gate_points) { - const auto dependency_jacobian = dependencyTrackingJacobian(data, gate, success); - const auto enzyme_jacobian = enzymeJacobian(data, gate, success); + const auto dependency_jacobian = + dependencyTrackingJacobian(data, gate, success); + const auto enzyme_jacobian = enzymeJacobian(data, gate, success); - success *= (dependency_jacobian.size() == enzyme_jacobian.size()); - const auto rows = std::min(dependency_jacobian.size(), enzyme_jacobian.size()); + success *= (dependency_jacobian.size() == enzyme_jacobian.size()); + const auto rows = + std::min(dependency_jacobian.size(), enzyme_jacobian.size()); for (size_t row = 0; row < rows; ++row) { if (!isEqual(dependency_jacobian[row], enzyme_jacobian[row], kTol)) @@ -961,7 +1008,9 @@ namespace GridKit Internal::G, "dependency-tracking" ); - success *= jacobianContains(enzyme_jacobian, Internal::PGV, Internal::G, "Enzyme"); + success *= jacobianContains( + enzyme_jacobian, Internal::PGV, Internal::G, "Enzyme" + ); } return success.report(__func__); @@ -1044,7 +1093,9 @@ namespace GridKit : hygov(withParameters(data, overrides)) { hygov.setSystemBase(60.0, system_va_base); - hygov.getPorts().out.template port().connect(&pmech_node_); + hygov.getPorts() + .out.template port() + .connect(&pmech_node_); } Fixture(const Fixture&) = delete; @@ -1056,9 +1107,12 @@ namespace GridKit for (size_t port = 0; port < input_values_.size(); ++port) { - input_values_[port] = static_cast(initial_value); - input_indices_[port] = external_index_base + static_cast(port); - input_nodes_[port].link(&input_values_[port], &input_indices_[port]); + input_values_[port] = static_cast(initial_value); + input_indices_[port] = + external_index_base + static_cast(port); + input_nodes_[port].link( + &input_values_[port], &input_indices_[port] + ); } hygov.getPorts() @@ -1082,7 +1136,8 @@ namespace GridKit /// verification, and a machine-provided mechanical-power value. bool prepare(RealT pmech) { - const bool success = (hygov.allocate() == 0) && (hygov.verify().passed()); + const bool success = + (hygov.allocate() == 0) && (hygov.verify().passed()); if (!success) { std::cout << "HYGOV fixture preparation failed\n"; @@ -1208,7 +1263,8 @@ namespace GridKit /// The rich state shared by the residual answer key and the Jacobian /// comparison. Every row is distinct so a swapped index cannot pass. template - void setAnswerKeyState(PhasorDynamics::Governor::Hygov& hygov) const + void setAnswerKeyState(PhasorDynamics::Governor::Hygov& hygov + ) const { setState( hygov, @@ -1240,7 +1296,9 @@ namespace GridKit bool defaultsMatchDocumentedValues() const { Fixture implicit_defaults(makeMinimalData(), {}, 200.0e6); - Fixture explicit_defaults(makeExplicitDefaultData(), {}, 200.0e6); + Fixture explicit_defaults( + makeExplicitDefaultData(), {}, 200.0e6 + ); implicit_defaults.attachAllInputs(); explicit_defaults.attachAllInputs(); @@ -1248,7 +1306,8 @@ namespace GridKit && explicit_defaults.initialize(0.3); if (!success) { - std::cout << "HYGOV documented-default comparison failed to initialize\n"; + std::cout + << "HYGOV documented-default comparison failed to initialize\n"; return false; } @@ -1313,7 +1372,9 @@ namespace GridKit { PhasorDynamics::SignalNode unlinked_node; Fixture fixture(makeData()); - fixture.hygov.getPorts().in.template port().connect(&unlinked_node); + fixture.hygov.getPorts().in.template port().connect( + &unlinked_node + ); return !fixture.hygov.verify().passed(); } @@ -1337,7 +1398,9 @@ namespace GridKit const auto* values = vector.getData(); for (size_t i = 0; i < snapshot.size(); ++i) { - if (!rowMatches(static_cast(values[i]), snapshot[i], what, i, "changed")) + if (!rowMatches( + static_cast(values[i]), snapshot[i], what, i, "changed" + )) { success = false; } @@ -1359,7 +1422,8 @@ namespace GridKit if (!ret) { std::cout << "HYGOV " << what << " row " << row - << " changed mismatch: " << actual << " != " << expected << "\n"; + << " changed mismatch: " << actual << " != " << expected + << "\n"; } return ret; } @@ -1371,7 +1435,8 @@ namespace GridKit { auto* y = fixture.hygov.y().getData(); auto* yp = fixture.hygov.yp().getData(); - for (size_t i = 0; i < static_cast(fixture.hygov.y().getSize()); ++i) + for (size_t i = 0; i < static_cast(fixture.hygov.y().getSize()); + ++i) { y[i] = 0.125 + 0.01 * static_cast(i); yp[i] = -0.25 - 0.01 * static_cast(i); @@ -1412,7 +1477,9 @@ namespace GridKit success = false; } - if (!scalarMatches(fixture.pmech(), pmech, "rejected pmech preservation")) + if (!scalarMatches( + fixture.pmech(), pmech, "rejected pmech preservation" + )) { success = false; } @@ -1497,7 +1564,9 @@ namespace GridKit { success = false; } - if (!residualsMatch(fixture.hygov, test_case.expected, test_case.label)) + if (!residualsMatch( + fixture.hygov, test_case.expected, test_case.label + )) { success = false; } @@ -1546,7 +1615,9 @@ namespace GridKit for (const auto& [variable, expected] : rows) { const auto row = static_cast(variable); - if (!rowMatches(static_cast(values[row]), expected, what, row, context)) + if (!rowMatches( + static_cast(values[row]), expected, what, row, context + )) { success = false; } @@ -1585,13 +1656,19 @@ namespace GridKit bool success = true; const auto* f = hygov.getResidual().getData(); const auto* yp = hygov.yp().getData(); - for (size_t row = 0; row < static_cast(hygov.getResidual().getSize()); ++row) + for (size_t row = 0; + row < static_cast(hygov.getResidual().getSize()); + ++row) { - if (!rowMatches(static_cast(f[row]), 0.0, "residual", row, "at rest")) + if (!rowMatches( + static_cast(f[row]), 0.0, "residual", row, "at rest" + )) { success = false; } - if (!rowMatches(static_cast(yp[row]), 0.0, "derivative", row, "at rest")) + if (!rowMatches( + static_cast(yp[row]), 0.0, "derivative", row, "at rest" + )) { success = false; } @@ -1616,7 +1693,8 @@ namespace GridKit return false; } - /// @todo Remove and setup the test to not rely on explicit variable numbering + /// @todo Remove and setup the test to not rely on explicit variable + /// numbering void numberVariables(Fixture& fixture) const { auto* y = fixture.hygov.y().getData(); diff --git a/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp b/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp index 42744a2dcb..45dc04a18d 100644 --- a/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp +++ b/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp @@ -25,9 +25,11 @@ namespace GridKit class GovernorTgov1Tests { private: - using RealT = typename PhasorDynamics::Component::RealT; - using real_type = typename PhasorDynamics::Component::RealT; - static constexpr ScalarT tol_ = 10 * std::numeric_limits::epsilon(); + using RealT = typename PhasorDynamics::Component::RealT; + using real_type = + typename PhasorDynamics::Component::RealT; + static constexpr ScalarT tol_ = + 10 * std::numeric_limits::epsilon(); public: GovernorTgov1Tests() = default; @@ -100,11 +102,23 @@ namespace GridKit PhasorDynamics::SignalNode pmech; PhasorDynamics::SignalNode omega; PhasorDynamics::Genrou gen(&bus, gendata); - PhasorDynamics::Governor::Tgov1 gov(PhasorDynamics::Governor::Tgov1Data{}); - gen.getPorts().in.template port().connect(&pmech); - gen.getPorts().out.template port().connect(&omega); - gov.getPorts().out.template port().connect(&pmech); - gov.getPorts().in.template port().connect(&omega); + PhasorDynamics::Governor::Tgov1 gov( + PhasorDynamics::Governor::Tgov1Data{} + ); + gen.getPorts() + .in.template port() + .connect(&pmech); + gen.getPorts() + .out.template port() + .connect(&omega); + gov.getPorts() + .out + .template port() + .connect(&pmech); + gov.getPorts() + .in + .template port() + .connect(&omega); // Test answer keys const std::vector res_answer = { @@ -134,8 +148,9 @@ namespace GridKit y[2] = static_cast(10.0) / static_cast(15.0); // Pmech // Set derivative values matching the answer key - yp[0] = static_cast(8.0) / static_cast(15.0); // ptx_dot - yp[1] = 2.0; // pv_dot + yp[0] = + static_cast(8.0) / static_cast(15.0); // ptx_dot + yp[1] = 2.0; // pv_dot gov.y().setDataUpdated(); gov.yp().setDataUpdated(); @@ -172,7 +187,8 @@ namespace GridKit { TestStatus success = true; - using BusType = typename PhasorDynamics::BusData::BusType; + using BusType = + typename PhasorDynamics::BusData::BusType; using GenrouDataT = PhasorDynamics::GenrouData; using Parameter = typename GenrouDataT::Parameters; using Buses = typename GenrouDataT::Buses; @@ -210,11 +226,23 @@ namespace GridKit PhasorDynamics::SignalNode omega; PhasorDynamics::Genrou gen(&bus, gendata); // Create governor to be tested - PhasorDynamics::Governor::Tgov1 gov(PhasorDynamics::Governor::Tgov1Data{}); - gen.getPorts().in.template port().connect(&pmech); - gen.getPorts().out.template port().connect(&omega); - gov.getPorts().out.template port().connect(&pmech); - gov.getPorts().in.template port().connect(&omega); + PhasorDynamics::Governor::Tgov1 gov( + PhasorDynamics::Governor::Tgov1Data{} + ); + gen.getPorts() + .in.template port() + .connect(&pmech); + gen.getPorts() + .out.template port() + .connect(&omega); + gov.getPorts() + .out + .template port() + .connect(&pmech); + gov.getPorts() + .in + .template port() + .connect(&omega); bus.allocate(); gov.allocate(); @@ -292,16 +320,21 @@ namespace GridKit gendata.parameters[Parameter::S12] = 0.; /// Jacobian via DependencyTracking - std::vector dependency_tracking_jacobian = DependencyTrackingJacobian(busdata, gendata); + std::vector + dependency_tracking_jacobian = + DependencyTrackingJacobian(busdata, gendata); /// Jacobian via Enzyme - std::vector enzyme_jacobian = EnzymeJacobian(busdata, gendata); + std::vector + enzyme_jacobian = EnzymeJacobian(busdata, gendata); /// Compare DependencyTracking dependencies to Enzyme's auto tol = 10 * std::numeric_limits::epsilon(); for (size_t i = 0; i < dependency_tracking_jacobian.size(); ++i) { - success *= (GridKit::Testing::isEqual(dependency_tracking_jacobian[i], enzyme_jacobian[i], tol)); + success *= (GridKit::Testing::isEqual( + dependency_tracking_jacobian[i], enzyme_jacobian[i], tol + )); } return success.report(__func__); } @@ -313,16 +346,30 @@ namespace GridKit PhasorDynamics::GenrouData gendata ) { - PhasorDynamics::Bus bus(busdata); - PhasorDynamics::SignalNode pmech; - PhasorDynamics::SignalNode omega; - PhasorDynamics::Genrou gen(&bus, gendata); + PhasorDynamics::Bus bus(busdata); + PhasorDynamics::SignalNode pmech; + PhasorDynamics::SignalNode omega; + PhasorDynamics::Genrou gen( + &bus, gendata + ); // Create governor to be tested - PhasorDynamics::Governor::Tgov1 gov(PhasorDynamics::Governor::Tgov1Data{}); - gen.getPorts().in.template port().connect(&pmech); - gen.getPorts().out.template port().connect(&omega); - gov.getPorts().out.template port().connect(&pmech); - gov.getPorts().in.template port().connect(&omega); + PhasorDynamics::Governor::Tgov1 gov( + PhasorDynamics::Governor::Tgov1Data{} + ); + gen.getPorts() + .in.template port() + .connect(&pmech); + gen.getPorts() + .out.template port() + .connect(&omega); + gov.getPorts() + .out + .template port() + .connect(&pmech); + gov.getPorts() + .in + .template port() + .connect(&omega); bus.allocate(); gov.allocate(); @@ -343,7 +390,8 @@ namespace GridKit gov.evaluateJacobian(); auto* model_jacobian = gov.getCsrJacobian(); auto& output_stream = Log::misc(); - output_stream << "Sparse Csr Matrix: Tgov1 DependencyTracking Jacobian\n"; + output_stream + << "Sparse Csr Matrix: Tgov1 DependencyTracking Jacobian\n"; model_jacobian->print(output_stream); return GridKit::Testing::MapFromCsr(model_jacobian); @@ -359,11 +407,23 @@ namespace GridKit PhasorDynamics::SignalNode omega; PhasorDynamics::Genrou gen(&bus, gendata); // Create governor to be tested - PhasorDynamics::Governor::Tgov1 gov(PhasorDynamics::Governor::Tgov1Data{}); - gen.getPorts().in.template port().connect(&pmech); - gen.getPorts().out.template port().connect(&omega); - gov.getPorts().out.template port().connect(&pmech); - gov.getPorts().in.template port().connect(&omega); + PhasorDynamics::Governor::Tgov1 gov( + PhasorDynamics::Governor::Tgov1Data{} + ); + gen.getPorts() + .in.template port() + .connect(&pmech); + gen.getPorts() + .out.template port() + .connect(&omega); + gov.getPorts() + .out + .template port() + .connect(&pmech); + gov.getPorts() + .in + .template port() + .connect(&omega); bus.allocate(); gov.allocate(); diff --git a/tests/UnitTests/PhasorDynamics/LoadZIPTests.hpp b/tests/UnitTests/PhasorDynamics/LoadZIPTests.hpp index 8edfcd759b..da2f33aec2 100644 --- a/tests/UnitTests/PhasorDynamics/LoadZIPTests.hpp +++ b/tests/UnitTests/PhasorDynamics/LoadZIPTests.hpp @@ -48,8 +48,9 @@ namespace GridKit auto data = makeData(); PhasorDynamics::LoadZIP monitored_load(bus, data); - PhasorDynamics::Component& monitored_component = monitored_load; - success *= (monitored_component.getMonitor() != nullptr); + PhasorDynamics::Component& monitored_component = + monitored_load; + success *= (monitored_component.getMonitor() != nullptr); delete bus; @@ -61,7 +62,9 @@ namespace GridKit TestStatus success = true; PhasorDynamics::BusInfinite bus(0.3, 0.4); - PhasorDynamics::LoadZIP load(&bus, loadZIPData(2.0, 0.5, 0.2, 0.4)); + PhasorDynamics::LoadZIP load( + &bus, loadZIPData(2.0, 0.5, 0.2, 0.4) + ); bus.allocate(); load.allocate(); @@ -89,7 +92,9 @@ namespace GridKit const RealT Qnom{0.5}; PhasorDynamics::BusInfinite bus(1.2, 0.9); - PhasorDynamics::LoadZIP load(&bus, loadZIPData(Pnom, Qnom, 0.2, 0.4)); + PhasorDynamics::LoadZIP load( + &bus, loadZIPData(Pnom, Qnom, 0.2, 0.4) + ); bus.allocate(); load.allocate(); @@ -129,7 +134,9 @@ namespace GridKit TestStatus success = true; PhasorDynamics::BusInfinite bus(0.3, 0.4); - PhasorDynamics::LoadZIP load(&bus, loadZIPData(2.0, 0.5, 0.2, 0.4)); + PhasorDynamics::LoadZIP load( + &bus, loadZIPData(2.0, 0.5, 0.2, 0.4) + ); bus.allocate(); load.allocate(); @@ -144,11 +151,11 @@ namespace GridKit bus.evaluateResidual(); load.evaluateResidual(); - const auto* f = load.getResidual().getData(); - success *= isEqual(f[0], static_cast(128.0 / 75.0), tol_); - success *= isEqual(f[1], static_cast(104.0 / 75.0), tol_); - success *= isEqual(bus.Ir(), static_cast(-3.2), tol_); - success *= isEqual(bus.Ii(), static_cast(-2.6), tol_); + const auto* f = load.getResidual().getData(); + success *= isEqual(f[0], static_cast(128.0 / 75.0), tol_); + success *= isEqual(f[1], static_cast(104.0 / 75.0), tol_); + success *= isEqual(bus.Ir(), static_cast(-3.2), tol_); + success *= isEqual(bus.Ii(), static_cast(-2.6), tol_); return success.report(__func__); } @@ -203,12 +210,15 @@ namespace GridKit const RealT alphaI{4.0}; const RealT alphaP{2.0}; - auto dependency_tracking_jacobian = DependencyTrackingJacobian(Pnom, Qnom, alphaI, alphaP); - auto enzyme_jacobian = EnzymeJacobian(Pnom, Qnom, alphaI, alphaP); + auto dependency_tracking_jacobian = + DependencyTrackingJacobian(Pnom, Qnom, alphaI, alphaP); + auto enzyme_jacobian = EnzymeJacobian(Pnom, Qnom, alphaI, alphaP); for (size_t i = 0; i < dependency_tracking_jacobian.size(); ++i) { - success *= GridKit::Testing::isEqual(dependency_tracking_jacobian[i], enzyme_jacobian[i]); + success *= GridKit::Testing::isEqual( + dependency_tracking_jacobian[i], enzyme_jacobian[i] + ); } return success.report(__func__); @@ -227,15 +237,21 @@ namespace GridKit DependencyTracking::Variable Vi{0.4}; PhasorDynamics::Bus bus(Vr, Vi); - PhasorDynamics::LoadZIP load(&bus, loadZIPData(Pnom, Qnom, alphaI, alphaP)); + PhasorDynamics::LoadZIP load( + &bus, loadZIPData(Pnom, Qnom, alphaI, alphaP) + ); bus.allocate(); load.allocate(); for (size_t i = 0; i < bus.size(); ++i) { - bus.setVariableIndex(i, i + load.size()); // Reset bus variable indices - bus.setResidualIndex(i, i + load.size()); // Reset bus residual indices + bus.setVariableIndex( + i, i + load.size() + ); // Reset bus variable indices + bus.setResidualIndex( + i, i + load.size() + ); // Reset bus residual indices } bus.initialize(); @@ -248,7 +264,8 @@ namespace GridKit load.evaluateJacobian(); //< Converts dependencies to CSR auto* model_jacobian = load.getCsrJacobian(); auto& output_stream = Log::misc(); - output_stream << "Sparse Csr Matrix: LoadZIP DependencyTracking Jacobian\n"; + output_stream + << "Sparse Csr Matrix: LoadZIP DependencyTracking Jacobian\n"; model_jacobian->print(output_stream); return GridKit::Testing::MapFromCsr(model_jacobian); @@ -265,15 +282,21 @@ namespace GridKit ScalarT Vi{0.4}; PhasorDynamics::Bus bus(Vr, Vi); - PhasorDynamics::LoadZIP load(&bus, loadZIPData(Pnom, Qnom, alphaI, alphaP)); + PhasorDynamics::LoadZIP load( + &bus, loadZIPData(Pnom, Qnom, alphaI, alphaP) + ); bus.allocate(); load.allocate(); for (size_t i = 0; i < bus.size(); ++i) { - bus.setVariableIndex(i, i + load.size()); // Reset bus variable indices - bus.setResidualIndex(i, i + load.size()); // Reset bus residual indices + bus.setVariableIndex( + i, i + load.size() + ); // Reset bus variable indices + bus.setResidualIndex( + i, i + load.size() + ); // Reset bus residual indices } bus.initialize(); @@ -297,7 +320,8 @@ namespace GridKit #endif private: - static constexpr RealT tol_ = 10 * std::numeric_limits::epsilon(); + static constexpr RealT tol_ = + 10 * std::numeric_limits::epsilon(); auto makeData() -> DataT { @@ -322,7 +346,12 @@ namespace GridKit return data; } - static DataT loadZIPData(const RealT Pnom, const RealT Qnom, const RealT alphaI, const RealT alphaP) + static DataT loadZIPData( + const RealT Pnom, + const RealT Qnom, + const RealT alphaI, + const RealT alphaP + ) { using Params = PhasorDynamics::LoadZIPParameters; diff --git a/tests/UnitTests/PhasorDynamics/LoadZTests.hpp b/tests/UnitTests/PhasorDynamics/LoadZTests.hpp index 8f5811670b..1bcd109e2e 100644 --- a/tests/UnitTests/PhasorDynamics/LoadZTests.hpp +++ b/tests/UnitTests/PhasorDynamics/LoadZTests.hpp @@ -49,8 +49,9 @@ namespace GridKit auto data = makeData(); PhasorDynamics::LoadZ monitored_load(bus, data); - PhasorDynamics::Component& monitored_component = monitored_load; - success *= (monitored_component.getMonitor() != nullptr); + PhasorDynamics::Component& monitored_component = + monitored_load; + success *= (monitored_component.getMonitor() != nullptr); delete bus; @@ -99,15 +100,21 @@ namespace GridKit DependencyTracking::Variable Vi{20.0}; ///< Bus imaginary voltage PhasorDynamics::Bus bus(Vr, Vi); - PhasorDynamics::LoadZ load(&bus, loadZData(R, X)); + PhasorDynamics::LoadZ load( + &bus, loadZData(R, X) + ); bus.allocate(); load.allocate(); for (size_t i = 0; i < bus.size(); ++i) { - bus.setVariableIndex(i, i + load.size()); // Reset bus variable indices - bus.setResidualIndex(i, i + load.size()); // Reset bus residual indices + bus.setVariableIndex( + i, i + load.size() + ); // Reset bus variable indices + bus.setResidualIndex( + i, i + load.size() + ); // Reset bus residual indices } bus.initialize(); @@ -118,7 +125,8 @@ namespace GridKit load.evaluateJacobian(); //< Converts dependencies to CSR auto* model_jacobian = load.getCsrJacobian(); auto& output_stream = Log::misc(); - output_stream << "Sparse Csr Matrix: Load DependencyTracking Jacobian\n"; + output_stream + << "Sparse Csr Matrix: Load DependencyTracking Jacobian\n"; model_jacobian->print(output_stream); // Compare model Jacobian with dependencies computed analytically @@ -188,8 +196,12 @@ namespace GridKit for (size_t i = 0; i < bus.size(); ++i) { - bus.setVariableIndex(i, i + load.size()); // Reset bus variable indices - bus.setResidualIndex(i, i + load.size()); // Reset bus residual indices + bus.setVariableIndex( + i, i + load.size() + ); // Reset bus variable indices + bus.setResidualIndex( + i, i + load.size() + ); // Reset bus residual indices } bus.initialize(); @@ -207,8 +219,10 @@ namespace GridKit model_jacobian->print(output_stream); // Compare model Jacobian with dependencies computed analytically - std::vector ref = analyticalJacobian(R, X); - std::vector model_dependencies = GridKit::Testing::MapFromCsr(model_jacobian); + std::vector ref = + analyticalJacobian(R, X); + std::vector + model_dependencies = GridKit::Testing::MapFromCsr(model_jacobian); for (size_t i = 0; i < ref.size(); ++i) { success *= (GridKit::Testing::isEqual(model_dependencies[i], ref[i])); @@ -219,7 +233,8 @@ namespace GridKit #endif private: - static constexpr RealT tol_ = 10 * std::numeric_limits::epsilon(); + static constexpr RealT tol_ = + 10 * std::numeric_limits::epsilon(); auto makeData() -> DataT { @@ -255,7 +270,8 @@ namespace GridKit const RealT b = -X / (R * R + X * X); const RealT g = R / (R * R + X * X); - std::vector dependencies(2); + std::vector dependencies(2 + ); dependencies[0] = {{0, 1.0}, {2, g}, {3, -b}}; dependencies[1] = {{1, 1.0}, {2, b}, {3, g}}; diff --git a/tests/UnitTests/PhasorDynamics/ModelConfigurationTests.hpp b/tests/UnitTests/PhasorDynamics/ModelConfigurationTests.hpp index 7d5d11b61b..de8c3d900f 100644 --- a/tests/UnitTests/PhasorDynamics/ModelConfigurationTests.hpp +++ b/tests/UnitTests/PhasorDynamics/ModelConfigurationTests.hpp @@ -74,7 +74,8 @@ namespace GridKit success *= !reader.readNonNegative(Params::omitted).has_value(); success *= !reader.readBool(Params::omitted).has_value(); success *= !reader.readInteger(Params::omitted).has_value(); - success *= (reader.readReal(Params::omitted).value_or(ONE) == ONE); + success *= + (reader.readReal(Params::omitted).value_or(ONE) == ONE); success *= reader.readBool(Params::omitted).value_or(true); success *= (reader.readReal(Params::integer) == TWO); @@ -82,27 +83,36 @@ namespace GridKit success *= (reader.readReal(Params::negative) == -ONE); success *= (reader.readNonNegative(Params::zero) == ZERO); success *= (reader.readNonNegative(Params::integer) == TWO); - success *= (reader.readInteger(Params::integer) == static_cast(2)); + success *= + (reader.readInteger(Params::integer) == static_cast(2)); success *= (reader.readBool(Params::false_flag) == false); success *= (reader.readBool(Params::true_flag) == true); success *= !reader.readBool(Params::false_flag).value_or(true); - success *= throws([&]() - { static_cast(reader.readReal(Params::infinite)); }); - success *= throws([&]() - { static_cast(reader.readReal(Params::not_a_number)); }); - success *= throws([&]() - { static_cast(reader.readReal(Params::text)); }); - success *= throws([&]() - { static_cast(reader.readReal(Params::true_flag)); }); - success *= throws([&]() - { static_cast(reader.readInteger(Params::real)); }); - success *= throws([&]() - { static_cast(reader.readInteger(Params::zero)); }); - success *= throws([&]() - { static_cast(reader.readInteger(Params::true_flag)); }); - success *= throws([&]() - { static_cast(reader.readNonNegative(Params::negative)); }); + success *= throws( + [&]() { static_cast(reader.readReal(Params::infinite)); } + ); + success *= throws( + [&]() { static_cast(reader.readReal(Params::not_a_number)); } + ); + success *= throws( + [&]() { static_cast(reader.readReal(Params::text)); } + ); + success *= throws( + [&]() { static_cast(reader.readReal(Params::true_flag)); } + ); + success *= throws( + [&]() { static_cast(reader.readInteger(Params::real)); } + ); + success *= throws( + [&]() { static_cast(reader.readInteger(Params::zero)); } + ); + success *= throws( + [&]() { static_cast(reader.readInteger(Params::true_flag)); } + ); + success *= throws( + [&]() { static_cast(reader.readNonNegative(Params::negative)); } + ); try { @@ -111,7 +121,9 @@ namespace GridKit } catch (const std::invalid_argument& error) { - success *= (std::string_view(error.what()) == "Test: parameter 'integer_flag' must be boolean"); + success *= + (std::string_view(error.what()) + == "Test: parameter 'integer_flag' must be boolean"); } return success.report(__func__); @@ -128,7 +140,9 @@ namespace GridKit checks.check(false, "x must be positive"); success *= !checks.passed(); - success *= (checks.errors() == std::vector{"Test: x must be positive"}); + success *= + (checks.errors() + == std::vector{"Test: x must be positive"}); return success.report(__func__); } diff --git a/tests/UnitTests/PhasorDynamics/StabilizerIeeestTests.hpp b/tests/UnitTests/PhasorDynamics/StabilizerIeeestTests.hpp index 8e684e2557..0074444708 100644 --- a/tests/UnitTests/PhasorDynamics/StabilizerIeeestTests.hpp +++ b/tests/UnitTests/PhasorDynamics/StabilizerIeeestTests.hpp @@ -34,7 +34,8 @@ namespace GridKit TestStatus success = true; auto data = makeTestData(); - auto* stab = new PhasorDynamics::Stabilizer::Ieeest(data); + auto* stab = + new PhasorDynamics::Stabilizer::Ieeest(data); success *= (stab != nullptr); success *= (stab->getMonitor() != nullptr); @@ -56,9 +57,9 @@ namespace GridKit PhasorDynamics::SignalNode u_node; PhasorDynamics::SignalNode vss_node; ScalarT u_value{0.0}; - IdxT u_index = 12; // beyond internal variables - ScalarT vss_value{0.0}; - IdxT vss_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.link(&u_value, &u_index); @@ -70,8 +71,12 @@ namespace GridKit auto stab = Ieeest(data); // Wire: stabilizer reads u_node as input, writes vss_node as output - stab.getPorts().in.template port().connect(&u_node); - stab.getPorts().out.template port().connect(&vss_node); + stab.getPorts().in.template port().connect( + &u_node + ); + stab.getPorts() + .out.template port() + .connect(&vss_node); stab.allocate(); success *= (stab.verify().passed()); @@ -85,7 +90,8 @@ namespace GridKit { if (!isEqual(f_data[i], 0.0, tol)) { - std::cout << "Non-zero residual at index " << i << ": " << f_data[i] << "\n"; + std::cout << "Non-zero residual at index " << i << ": " << f_data[i] + << "\n"; success = false; } } @@ -113,7 +119,7 @@ namespace GridKit ScalarT u_value{0.5}; IdxT u_index = 12; ScalarT vss_value{0.0}; - IdxT vss_index = INVALID_INDEX; + IdxT vss_index = INVALID_INDEX; u_node.link(&u_value, &u_index); vss_node.link(&vss_value, &vss_index); @@ -123,8 +129,12 @@ namespace GridKit auto data = makeTestData(); auto stab = Ieeest(data); - stab.getPorts().in.template port().connect(&u_node); - stab.getPorts().out.template port().connect(&vss_node); + stab.getPorts().in.template port().connect( + &u_node + ); + stab.getPorts() + .out.template port() + .connect(&vss_node); stab.allocate(); stab.initialize(); @@ -147,14 +157,19 @@ namespace GridKit 0.0, // f[11]: limiter (v7=0.05 within [-0.1, 0.1]) }; - // Looser tolerance for f[11] — Math::clamp is a smooth ramp approximation. + // 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(); const auto* residual_data = residual.getData(); 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_data[i], res_answer[i], test_tol)) { std::cout << "Incorrect result for residual " << i << ": " @@ -165,7 +180,8 @@ namespace GridKit } // Verify output signal reads the stabilizer output - success *= isEqual(vss_node.read(), static_cast(0.05), loose_tol); + success *= + isEqual(vss_node.read(), static_cast(0.05), loose_tol); return success.report(__func__); } @@ -190,7 +206,9 @@ namespace GridKit auto tol = 10 * std::numeric_limits::epsilon(); for (size_t i = 0; i < dependency_tracking_jacobian.size(); ++i) { - success *= (GridKit::Testing::isEqual(dependency_tracking_jacobian[i], enzyme_jacobian[i], tol)); + success *= (GridKit::Testing::isEqual( + dependency_tracking_jacobian[i], enzyme_jacobian[i], tol + )); } return success.report(__func__); @@ -210,7 +228,7 @@ namespace GridKit DepVar u_value{0.5}; IdxT u_index = 12; DepVar vss_value{0.0}; - IdxT vss_index = INVALID_INDEX; + IdxT vss_index = INVALID_INDEX; u_node.link(&u_value, &u_index); vss_node.link(&vss_value, &vss_index); @@ -218,14 +236,20 @@ namespace GridKit using namespace GridKit::PhasorDynamics::Stabilizer; auto stab = Ieeest(ieeestdata); - stab.getPorts().in.template port().connect(&u_node); - stab.getPorts().out.template port().connect(&vss_node); + stab.getPorts().in.template port().connect( + &u_node + ); + stab.getPorts() + .out.template port() + .connect(&vss_node); stab.allocate(); stab.initialize(); // Tag external signal u as an additional independent variable - u_value.setVariableNumber(2 * stab.size()); // @todo avoid requiring knowledge of the numbering + u_value.setVariableNumber( + 2 * stab.size() + ); // @todo avoid requiring knowledge of the numbering setStatePointDep(stab); stab.updateTime(0.0, 1.0); // alpha = 1.0 to verify d/dy' term @@ -234,7 +258,8 @@ namespace GridKit stab.evaluateJacobian(); auto model_jacobian = stab.getCsrJacobian(); auto& output_stream = Log::misc(); - output_stream << "Sparse Csr Matrix: Ieeest DependencyTracking Jacobian\n"; + output_stream + << "Sparse Csr Matrix: Ieeest DependencyTracking Jacobian\n"; model_jacobian->print(output_stream); return GridKit::Testing::MapFromCsr(model_jacobian); @@ -249,7 +274,7 @@ namespace GridKit ScalarT u_value{0.5}; IdxT u_index = 12; ScalarT vss_value{0.0}; - IdxT vss_index = INVALID_INDEX; + IdxT vss_index = INVALID_INDEX; u_node.link(&u_value, &u_index); vss_node.link(&vss_value, &vss_index); @@ -257,8 +282,12 @@ namespace GridKit using namespace GridKit::PhasorDynamics::Stabilizer; auto stab = Ieeest(ieeestdata); - stab.getPorts().in.template port().connect(&u_node); - stab.getPorts().out.template port().connect(&vss_node); + stab.getPorts().in.template port().connect( + &u_node + ); + stab.getPorts() + .out.template port() + .connect(&vss_node); stab.allocate(); stab.initialize(); @@ -280,7 +309,8 @@ namespace GridKit #endif private: - static constexpr ScalarT tol_ = 10 * std::numeric_limits::epsilon(); + static constexpr ScalarT tol_ = + 10 * std::numeric_limits::epsilon(); /** * @brief Standard IEEEST parameter set for all tests. @@ -293,7 +323,9 @@ namespace GridKit PhasorDynamics::Stabilizer::IeeestData data; data.device_class = "stabilizer"; data.disambiguation_string = "ieeest_test"; - data.monitored_variables.insert(PhasorDynamics::Stabilizer::IeeestMonitorableVariables::vss); + data.monitored_variables.insert( + PhasorDynamics::Stabilizer::IeeestMonitorableVariables::vss + ); data.parameters[Params::A1] = 0.1; data.parameters[Params::A2] = 0.2; @@ -321,7 +353,8 @@ namespace GridKit * @brief Set a non-trivial operating point for residual/Jacobian tests. * Avoids zeros and ones to catch coefficient errors. */ - void setStatePoint(PhasorDynamics::Stabilizer::Ieeest& stab) + void setStatePoint(PhasorDynamics::Stabilizer::Ieeest& stab + ) { auto* y = stab.y().getData(); auto* yp = stab.yp().getData(); @@ -353,9 +386,13 @@ namespace GridKit /** * @brief Set the same operating point for DependencyTracking variables. - * Uses setValue() to set the numeric value while preserving dependency info. + * Uses setValue() to set the numeric value while preserving dependency + * info. */ - void setStatePointDep(PhasorDynamics::Stabilizer::Ieeest& stab) + void setStatePointDep( + PhasorDynamics::Stabilizer::Ieeest& + stab + ) { auto* y = stab.y().getData(); auto* yp = stab.yp().getData(); diff --git a/tests/UnitTests/PhasorDynamics/SubsystemModelTests.hpp b/tests/UnitTests/PhasorDynamics/SubsystemModelTests.hpp index a32e098ebb..63385d97f1 100644 --- a/tests/UnitTests/PhasorDynamics/SubsystemModelTests.hpp +++ b/tests/UnitTests/PhasorDynamics/SubsystemModelTests.hpp @@ -56,7 +56,8 @@ namespace GridKit const json input = readJson("SubsystemHierarchical.json"); const json& b_input = input["subsystems"][1]; std::vector data; - for (json system : {input, input["subsystems"][0], b_input, b_input["subsystems"][0]}) + for (json system : + {input, input["subsystems"][0], b_input, b_input["subsystems"][0]}) { system.erase("subsystems"); system["header"] = input["header"]; @@ -89,11 +90,13 @@ namespace GridKit { TestStatus success = true; - const DataT top_data = readJson("SubsystemHierarchical.json").template get(); + const DataT top_data = + readJson("SubsystemHierarchical.json").template get(); success *= top_data.subsystems.size() == 2; success *= top_data.subsystems[1].subsystems.size() == 1; - success *= top_data.subsystems[1].subsystems[0].va_base == top_data.va_base; + success *= + top_data.subsystems[1].subsystems[0].va_base == top_data.va_base; success *= top_data.level == 0; success *= top_data.subsystems[1].id == "B"; success *= top_data.subsystems[1].level == 1; @@ -118,7 +121,9 @@ namespace GridKit // Signal in subsystem C, added to any existing ones json input = readJson("SubsystemHierarchical.json"); - input["subsystems"][1]["subsystems"][0]["signals"].push_back({{"signal_id", 5}, {"name", "s"}}); + input["subsystems"][1]["subsystems"][0]["signals"].push_back( + {{"signal_id", 5}, {"name", "s"}} + ); SystemT top(input.template get()); auto* a = top.getSubsystem(0); @@ -172,9 +177,9 @@ namespace GridKit json input; // Device uses a bus of a sibling subsystem - input = hierarchical; - input["subsystems"][0]["devices"][0]["ports"]["bus2"] = 3; - success *= constructionThrows(input); + input = hierarchical; + input["subsystems"][0]["devices"][0]["ports"]["bus2"] = 3; + success *= constructionThrows(input); // Device uses a signal of its parent const json signal_r = {{"signal_id", 1}, {"name", "sr"}}; @@ -185,21 +190,23 @@ namespace GridKit {"id", "1"}, {"params", json::object()} }; - input = hierarchical; - input["signals"] = json::array({signal_r, signal_i}); + input = hierarchical; + input["signals"] = json::array({signal_r, signal_i}); input["subsystems"][0]["devices"].push_back(source); success *= constructionThrows(input); // Devices in a system with subsystems - input = hierarchical; - json load = input["subsystems"][1]["subsystems"][0]["devices"][2]; + input = hierarchical; + json load = input["subsystems"][1]["subsystems"][0]["devices"][2]; load["ports"]["bus"] = 1; input["devices"].push_back(load); success *= constructionThrows(input); // Programmatic hierarchy: devices and subsystems in one system { - SystemT with_device(readJson("SubsystemFlat.json").template get()); + SystemT with_device( + readJson("SubsystemFlat.json").template get() + ); SystemT with_subsystem; SystemT subsystem; SystemT other; @@ -239,9 +246,9 @@ namespace GridKit success *= constructionThrows(input); // Subsystem level not matching the hierarchy (grandchild at level 1) - input = hierarchical; - input["subsystems"][1]["subsystems"][0]["level"] = 1; - success *= constructionThrows(input); + input = hierarchical; + input["subsystems"][1]["subsystems"][0]["level"] = 1; + success *= constructionThrows(input); Log::setVerbosity(previous_verbosity); return success.report(__func__); @@ -303,9 +310,12 @@ namespace GridKit TestStatus success = true; SystemT flat(readJson("SubsystemFlat.json").template get()); - SystemT top(readJson("SubsystemHierarchical.json").template get()); - success *= top.numSubsystems() == 2 && top.getSubsystem(1)->numSubsystems() == 1; - if (top.numSubsystems() != 2 || top.getSubsystem(1)->numSubsystems() != 1) + SystemT top(readJson("SubsystemHierarchical.json").template get() + ); + success *= + top.numSubsystems() == 2 && top.getSubsystem(1)->numSubsystems() == 1; + if (top.numSubsystems() != 2 + || top.getSubsystem(1)->numSubsystems() != 1) { return success.report(__func__); } @@ -345,7 +355,8 @@ namespace GridKit } success *= top_dt.evaluateResidual() == 0; success *= top_dt.evaluateJacobian() == 0; - if (flat.getCsrJacobian() == nullptr || top.getCsrJacobian() == nullptr + if (flat.getCsrJacobian() == nullptr + || top.getCsrJacobian() == nullptr || top_dt.getCsrJacobian() == nullptr) { success *= false; @@ -433,7 +444,9 @@ namespace GridKit } /// Whether looking up component `label` from `system` throws - static bool componentLookupThrows(SystemT& system, const std::string& label) + static bool componentLookupThrows( + SystemT& system, const std::string& label + ) { bool throws = false; try @@ -481,7 +494,9 @@ namespace GridKit * @brief Compare top = [bus 1 | A[bus 2] | B[bus 3 | C[bus 4, load]]] * with the flat system, before and after a fault on bus 4. */ - static void compareSystems(SystemT& flat, SystemT& top, TestStatus& success) + static void compareSystems( + SystemT& flat, SystemT& top, TestStatus& success + ) { for (auto* system : {&flat, &top}) { @@ -510,7 +525,8 @@ namespace GridKit success *= b->offset() == a->offset() + a->size(); success *= b->size() == b->getBus(3)->size() + c->size(); success *= c->offset() == b->offset() + b->getBus(3)->size(); - success *= c->size() == c->getBus(4)->size() + c->getComponent(2)->size(); + success *= + c->size() == c->getBus(4)->size() + c->getComponent(2)->size(); success *= top.size() == top.getBus(1)->size() + a->size() + b->size(); success *= top.size() == flat.size(); if (top.size() != flat.size()) diff --git a/tests/UnitTests/PhasorDynamics/SystemSingleComponentTests.hpp b/tests/UnitTests/PhasorDynamics/SystemSingleComponentTests.hpp index a744fa6f94..63f8296642 100644 --- a/tests/UnitTests/PhasorDynamics/SystemSingleComponentTests.hpp +++ b/tests/UnitTests/PhasorDynamics/SystemSingleComponentTests.hpp @@ -13,8 +13,8 @@ namespace GridKit { using Log = ::GridKit::Utilities::Logger; - /// Smoke test for components (single component connected to an infinite bus) - /// through the system model with the minimal constructors + /// Smoke test for components (single component connected to an infinite + /// bus) through the system model with the minimal constructors template class SystemSingleComponentTests { @@ -29,13 +29,16 @@ namespace GridKit { TestStatus success = true; - PhasorDynamics::SystemModel* system = new PhasorDynamics::SystemModel(); + PhasorDynamics::SystemModel* system = + new PhasorDynamics::SystemModel(); PhasorDynamics::BusInfinite bus1, bus2; system->addBus(&bus1); system->addBus(&bus2); - PhasorDynamics::Branch branch(&bus1, &bus2, PhasorDynamics::BranchData{}); + PhasorDynamics::Branch branch( + &bus1, &bus2, PhasorDynamics::BranchData{} + ); system->addComponent(&branch); success *= system->allocate() == 0; @@ -55,7 +58,8 @@ namespace GridKit { TestStatus success = true; - PhasorDynamics::SystemModel* system = new PhasorDynamics::SystemModel(); + PhasorDynamics::SystemModel* system = + new PhasorDynamics::SystemModel(); PhasorDynamics::Bus bus; system->addBus(&bus); @@ -76,16 +80,19 @@ namespace GridKit { TestStatus success = true; - PhasorDynamics::SystemModel* system = new PhasorDynamics::SystemModel(); + PhasorDynamics::SystemModel* system = + new PhasorDynamics::SystemModel(); PhasorDynamics::BusInfinite bus; system->addBus(&bus); const auto previous_verbosity = Log::verbosity(); - // Suppress the expected time-constant-floor warning from the default parameters. - // Use EVERYTHING to inspect the diagnostic. + // Suppress the expected time-constant-floor warning from the default + // parameters. Use EVERYTHING to inspect the diagnostic. Log::setVerbosity(Log::Verbosity::NONE); - PhasorDynamics::Exciter::Ieeet1 exciter(&bus, PhasorDynamics::Exciter::Ieeet1Data{}); + PhasorDynamics::Exciter::Ieeet1 exciter( + &bus, PhasorDynamics::Exciter::Ieeet1Data{} + ); Log::setVerbosity(previous_verbosity); system->addComponent(&exciter); @@ -119,10 +126,11 @@ namespace GridKit PhasorDynamics::SystemModelData data; data.bus.resize(1); - data.bus[0].bus_id = bus_id; - data.bus[0].bus_type = PhasorDynamics::BusData::BusType::SLACK; - data.bus[0].Vr0 = static_cast(1.0); - data.bus[0].Vi0 = static_cast(0.0); + data.bus[0].bus_id = bus_id; + data.bus[0].bus_type = + PhasorDynamics::BusData::BusType::SLACK; + data.bus[0].Vr0 = static_cast(1.0); + data.bus[0].Vi0 = static_cast(0.0); data.signal.resize(1); data.signal[0].signal_id = efd_id; @@ -145,7 +153,8 @@ namespace GridKit success *= system.tagDifferentiable() == 0; success *= system.evaluateResidual() == 0; success *= system.evaluateJacobian() == 0; - success *= system.size() == static_cast(Utilities::enum_size()); + success *= + system.size() == static_cast(Utilities::enum_size()); auto* efd = system.getSignalNode(efd_id); success *= efd->linked(); @@ -155,8 +164,10 @@ namespace GridKit missing_bus_data.bus[0].bus_id = static_cast(0); missing_bus_data.esdc1a[0].buses.clear(); - PhasorDynamics::SystemModel missing_bus_system(missing_bus_data); - const auto previous_verbosity = Log::verbosity(); + PhasorDynamics::SystemModel missing_bus_system( + missing_bus_data + ); + const auto previous_verbosity = Log::verbosity(); // Suppress the expected missing-bus configuration error below. // Use EVERYTHING to inspect the diagnostic. Log::setVerbosity(Log::Verbosity::NONE); @@ -170,12 +181,15 @@ namespace GridKit { TestStatus success = true; - PhasorDynamics::SystemModel* system = new PhasorDynamics::SystemModel(); + PhasorDynamics::SystemModel* system = + new PhasorDynamics::SystemModel(); PhasorDynamics::BusInfinite bus; system->addBus(&bus); - PhasorDynamics::LoadZ load(&bus, PhasorDynamics::LoadZData{}); + PhasorDynamics::LoadZ load( + &bus, PhasorDynamics::LoadZData{} + ); system->addComponent(&load); success *= system->allocate() == 0; @@ -194,12 +208,15 @@ namespace GridKit { TestStatus success = true; - PhasorDynamics::SystemModel* system = new PhasorDynamics::SystemModel(); + PhasorDynamics::SystemModel* system = + new PhasorDynamics::SystemModel(); PhasorDynamics::BusInfinite bus(1.0, 0.0); system->addBus(&bus); - PhasorDynamics::LoadZIP load(&bus, PhasorDynamics::LoadZIPData{}); + PhasorDynamics::LoadZIP load( + &bus, PhasorDynamics::LoadZIPData{} + ); system->addComponent(&load); success *= system->allocate() == 0; @@ -220,10 +237,11 @@ namespace GridKit PhasorDynamics::SystemModelData data; data.bus.resize(1); - data.bus[0].bus_id = static_cast(1); - data.bus[0].bus_type = PhasorDynamics::BusData::BusType::SLACK; - data.bus[0].Vr0 = static_cast(1.0); - data.bus[0].Vi0 = static_cast(0.0); + data.bus[0].bus_id = static_cast(1); + data.bus[0].bus_type = + PhasorDynamics::BusData::BusType::SLACK; + data.bus[0].Vr0 = static_cast(1.0); + data.bus[0].Vi0 = static_cast(0.0); data.regca.push_back(makeRegcaData()); PhasorDynamics::SystemModel system(data); @@ -234,7 +252,10 @@ namespace GridKit success *= system.evaluateResidual() == 0; success *= system.evaluateJacobian() == 0; success *= system.size() - == static_cast(Utilities::enum_size()); + == static_cast( + Utilities::enum_size< + PhasorDynamics::Converter::RegcaInternalVariables>() + ); return success.report(__func__); } @@ -253,15 +274,17 @@ namespace GridKit PhasorDynamics::SystemModelData data; data.bus.resize(1); - data.bus[0].bus_id = bus_id; - data.bus[0].bus_type = PhasorDynamics::BusData::BusType::SLACK; - data.bus[0].Vr0 = static_cast(1.0); - data.bus[0].Vi0 = static_cast(0.0); + data.bus[0].bus_id = bus_id; + data.bus[0].bus_type = + PhasorDynamics::BusData::BusType::SLACK; + data.bus[0].Vr0 = static_cast(1.0); + data.bus[0].Vi0 = static_cast(0.0); data.signal.resize(1); data.signal[0].signal_id = input_id; - typename PhasorDynamics::SystemModelData::RepcaDataT repca_data; + typename PhasorDynamics::SystemModelData::RepcaDataT + repca_data; repca_data.buses[Buses::bus] = bus_id; repca_data.signal_inputs[Inputs::ir] = input_id; repca_data.signal_inputs[Inputs::ii] = input_id; @@ -281,7 +304,8 @@ namespace GridKit success *= system.tagDifferentiable() == 0; success *= system.evaluateResidual() == 0; success *= system.evaluateJacobian() == 0; - success *= system.size() == static_cast(Utilities::enum_size()); + success *= + system.size() == static_cast(Utilities::enum_size()); return success.report(__func__); } @@ -313,7 +337,8 @@ namespace GridKit success *= system.tagDifferentiable() == 0; success *= system.evaluateResidual() == 0; success *= system.evaluateJacobian() == 0; - success *= system.size() == static_cast(Utilities::enum_size()); + success *= + system.size() == static_cast(Utilities::enum_size()); return success.report(__func__); } @@ -332,10 +357,11 @@ namespace GridKit PhasorDynamics::SystemModelData data; data.bus.resize(1); - data.bus[0].bus_id = bus_id; - data.bus[0].bus_type = PhasorDynamics::BusData::BusType::SLACK; - data.bus[0].Vr0 = static_cast(1.0); - data.bus[0].Vi0 = static_cast(0.0); + data.bus[0].bus_id = bus_id; + data.bus[0].bus_type = + PhasorDynamics::BusData::BusType::SLACK; + data.bus[0].Vr0 = static_cast(1.0); + data.bus[0].Vi0 = static_cast(0.0); Data reecb_data; reecb_data.buses[Buses::bus] = bus_id; @@ -351,7 +377,8 @@ namespace GridKit success *= system.tagDifferentiable() == 0; success *= system.evaluateResidual() == 0; success *= system.evaluateJacobian() == 0; - success *= system.size() == static_cast(Utilities::enum_size()); + success *= + system.size() == static_cast(Utilities::enum_size()); return success.report(__func__); } @@ -360,12 +387,15 @@ namespace GridKit { TestStatus success = true; - PhasorDynamics::SystemModel* system = new PhasorDynamics::SystemModel(); + PhasorDynamics::SystemModel* system = + new PhasorDynamics::SystemModel(); PhasorDynamics::BusInfinite bus; system->addBus(&bus); - PhasorDynamics::Genrou gen(&bus, PhasorDynamics::GenrouData{}); + PhasorDynamics::Genrou gen( + &bus, PhasorDynamics::GenrouData{} + ); system->addComponent(&gen); success *= system->allocate() == 0; @@ -384,7 +414,8 @@ namespace GridKit { TestStatus success = true; - PhasorDynamics::SystemModel* system = new PhasorDynamics::SystemModel(); + PhasorDynamics::SystemModel* system = + new PhasorDynamics::SystemModel(); PhasorDynamics::BusInfinite bus; system->addBus(&bus); @@ -409,11 +440,17 @@ namespace GridKit { TestStatus success = true; - PhasorDynamics::SystemModel* system = new PhasorDynamics::SystemModel(); + PhasorDynamics::SystemModel* system = + new PhasorDynamics::SystemModel(); PhasorDynamics::SignalNode pmech; - PhasorDynamics::Governor::Tgov1 tgov1(PhasorDynamics::Governor::Tgov1Data{}); - tgov1.getPorts().out.template port().connect(&pmech); + PhasorDynamics::Governor::Tgov1 tgov1( + PhasorDynamics::Governor::Tgov1Data{} + ); + tgov1.getPorts() + .out + .template port() + .connect(&pmech); system->addComponent(&tgov1); success *= system->allocate() == 0; @@ -464,17 +501,20 @@ namespace GridKit success *= system.tagDifferentiable() == 0; success *= system.evaluateResidual() == 0; success *= system.evaluateJacobian() == 0; - success *= system.size() == static_cast(Utilities::enum_size()); + success *= + system.size() == static_cast(Utilities::enum_size()); auto* pmech = system.getSignalNode(pmech_id); success *= pmech->linked(); - success *= pmech->getVariableIndex() == static_cast(Vars::PMECH); + success *= pmech->getVariableIndex() == static_cast(Vars::PMECH); auto missing_output_data = data; missing_output_data.hygov[0].signal_outputs.clear(); - PhasorDynamics::SystemModel missing_output_system(missing_output_data); - const auto previous_verbosity = Log::verbosity(); + PhasorDynamics::SystemModel missing_output_system( + missing_output_data + ); + const auto previous_verbosity = Log::verbosity(); // Suppress the expected missing-output configuration error below. // Use EVERYTHING to inspect the diagnostic. Log::setVerbosity(Log::Verbosity::NONE); diff --git a/tests/UnitTests/PhasorDynamics/SystemTests.hpp b/tests/UnitTests/PhasorDynamics/SystemTests.hpp index 434aa7fb48..0c0fca24c1 100644 --- a/tests/UnitTests/PhasorDynamics/SystemTests.hpp +++ b/tests/UnitTests/PhasorDynamics/SystemTests.hpp @@ -59,7 +59,9 @@ namespace GridKit return data; } - static PhasorDynamics::LoadZData loadZData(const RealT R, const RealT X) + static PhasorDynamics::LoadZData loadZData( + const RealT R, const RealT X + ) { using Params = PhasorDynamics::LoadZParameters; @@ -159,16 +161,18 @@ namespace GridKit data.bus.resize(2); // Bus 0 - data.bus[0].bus_id = 0; - data.bus[0].bus_type = PhasorDynamics::BusData::BusType::SLACK; - data.bus[0].Vr0 = 10.0; - data.bus[0].Vi0 = 20.0; + data.bus[0].bus_id = 0; + data.bus[0].bus_type = + PhasorDynamics::BusData::BusType::SLACK; + data.bus[0].Vr0 = 10.0; + data.bus[0].Vi0 = 20.0; // Bus 1 - data.bus[1].bus_id = 1; - data.bus[1].bus_type = PhasorDynamics::BusData::BusType::DEFAULT; - data.bus[1].Vr0 = 30.0; - data.bus[1].Vi0 = 40.0; + data.bus[1].bus_id = 1; + data.bus[1].bus_type = + PhasorDynamics::BusData::BusType::DEFAULT; + data.bus[1].Vr0 = 30.0; + data.bus[1].Vi0 = 40.0; // Set branch data data.branch.resize(1); @@ -188,10 +192,12 @@ namespace GridKit system->evaluateResidual(); // Answer keys - const ScalarT Ir0{17.0}; ///< Solution: real current entering bus-0 - const ScalarT Ii0{-10.0}; ///< Solution: imaginary current entering bus-0 - const ScalarT Ir1{15.0}; ///< Solution: real current entering bus-1 - const ScalarT Ii1{-20.0}; ///< Solution: imaginary current entering bus-1 + const ScalarT Ir0{17.0}; ///< Solution: real current entering bus-0 + const ScalarT Ii0{-10.0 + }; ///< Solution: imaginary current entering bus-0 + const ScalarT Ir1{15.0}; ///< Solution: real current entering bus-1 + const ScalarT Ii1{-20.0 + }; ///< Solution: imaginary current entering bus-1 auto* bus0 = system->getBus(0); auto* bus1 = system->getBus(1); @@ -221,10 +227,12 @@ namespace GridKit ScalarT Vr2{30.0}; ///< Bus-2 real voltage ScalarT Vi2{40.0}; ///< Bus-2 imaginary voltage - const ScalarT Ir1{17.0}; ///< Solution: real current entering bus-1 - const ScalarT Ii1{-10.0}; ///< Solution: imaginary current entering bus-1 - const ScalarT Ir2{15.0}; ///< Solution: real current entering bus-2 - const ScalarT Ii2{-20.0}; ///< Solution: imaginary current entering bus-2 + const ScalarT Ir1{17.0}; ///< Solution: real current entering bus-1 + const ScalarT Ii1{-10.0 + }; ///< Solution: imaginary current entering bus-1 + const ScalarT Ir2{15.0}; ///< Solution: real current entering bus-2 + const ScalarT Ii2{-20.0 + }; ///< Solution: imaginary current entering bus-2 // Create an empty system model PhasorDynamics::SystemModel system; @@ -237,7 +245,9 @@ namespace GridKit PhasorDynamics::Bus bus2(Vr2, Vi2); system.addBus(&bus2); - PhasorDynamics::Branch branch(&bus1, &bus2, branchData(R, X, G, B)); + PhasorDynamics::Branch branch( + &bus1, &bus2, branchData(R, X, G, B) + ); system.addComponent(&branch); system.allocate(); @@ -259,7 +269,9 @@ namespace GridKit PhasorDynamics::BusInfinite source(1.0, 0.0); PhasorDynamics::Bus bus(1.0, 0.0); - PhasorDynamics::Branch branch(&source, &bus, branchData(0.1, 0.2, 0.0, 0.0)); + PhasorDynamics::Branch branch( + &source, &bus, branchData(0.1, 0.2, 0.0, 0.0) + ); PhasorDynamics::SystemModel system; system.addBus(&source); system.addBus(&bus); @@ -278,7 +290,8 @@ namespace GridKit success *= isEqual(bus.Ir(), ScalarT{0.0}); success *= isEqual(bus.Ii(), ScalarT{0.0}); - // Both voltage variables remain, but their KCL rows are identically zero. + // Both voltage variables remain, but their KCL rows are identically + // zero. auto* jacobian = system.getCsrJacobian(); success *= jacobian->getNnz() == nnz; for (IdxT i = 0; i < nnz; ++i) @@ -297,7 +310,9 @@ namespace GridKit PhasorDynamics::SystemModel system; PhasorDynamics::Bus bus1(1.0, 0.0); PhasorDynamics::Bus bus2(1.0, 0.0); - PhasorDynamics::LoadZ load(&bus1, PhasorDynamics::LoadZData{}); + PhasorDynamics::LoadZ load( + &bus1, PhasorDynamics::LoadZData{} + ); system.addBus(&bus1); system.addComponent(&load); @@ -321,7 +336,9 @@ namespace GridKit } #endif - PhasorDynamics::Branch branch(&bus1, &bus2, PhasorDynamics::BranchData{}); + PhasorDynamics::Branch branch( + &bus1, &bus2, PhasorDynamics::BranchData{} + ); system.addComponent(&branch); success *= system.allocate() == 0; success *= system.evaluateJacobian() == 0; @@ -348,8 +365,10 @@ namespace GridKit PhasorDynamics::Bus bus1(1.0, 2.0); PhasorDynamics::BusInfinite infinite_bus; PhasorDynamics::Bus bus2(3.0, 4.0); - PhasorDynamics::Branch branch(&bus1, &bus2, PhasorDynamics::BranchData{}); - PhasorDynamics::LoadZ load(&bus2, loadZData(1.0, 1.0)); + PhasorDynamics::Branch branch( + &bus1, &bus2, PhasorDynamics::BranchData{} + ); + PhasorDynamics::LoadZ load(&bus2, loadZData(1.0, 1.0)); system.addBus(&bus1); system.addBus(&infinite_bus); @@ -357,14 +376,14 @@ namespace GridKit system.addComponent(&branch); system.addComponent(&load); - if (system.allocate() != 0 - || system.setAbsoluteTolerance(1e-4) != 0) + if (system.allocate() != 0 || system.setAbsoluteTolerance(1e-4) != 0) { success = false; return success.report(__func__); } - auto checkAlias = [&](auto& system_vector, auto& model_vector, IdxT offset) + auto checkAlias = + [&](auto& system_vector, auto& model_vector, IdxT offset) { auto* system_data = system_vector.getData(); auto* model_data = model_vector.getData(); @@ -391,7 +410,9 @@ namespace GridKit checkAlias(system.y(), model.y(), offset); checkAlias(system.yp(), model.yp(), offset); checkAlias(system.getResidual(), model.getResidual(), offset); - checkAlias(system.absoluteTolerance(), model.absoluteTolerance(), offset); + checkAlias( + system.absoluteTolerance(), model.absoluteTolerance(), offset + ); }; const IdxT bus2_offset = bus1.size(); @@ -470,7 +491,8 @@ namespace GridKit return status.report(__func__); } - /// SystemModel propagates a statically valid component's initialization error. + /// SystemModel propagates a statically valid component's initialization + /// error. TestOutcome componentInitializationError() { TestStatus success = true; @@ -486,8 +508,7 @@ namespace GridKit if (system.hasJacobian()) { - success *= throws([&]() - { system.allocate(); }); + success *= throws([&]() { system.allocate(); }); } else { @@ -510,16 +531,18 @@ namespace GridKit data.bus.resize(2); // Bus 0 - data.bus[0].bus_id = 0; - data.bus[0].bus_type = PhasorDynamics::BusData::BusType::SLACK; - data.bus[0].Vr0 = 10.0; - data.bus[0].Vi0 = 20.0; + data.bus[0].bus_id = 0; + data.bus[0].bus_type = + PhasorDynamics::BusData::BusType::SLACK; + data.bus[0].Vr0 = 10.0; + data.bus[0].Vi0 = 20.0; // Bus 1 - data.bus[1].bus_id = 1; - data.bus[1].bus_type = PhasorDynamics::BusData::BusType::DEFAULT; - data.bus[1].Vr0 = 30.0; - data.bus[1].Vi0 = 40.0; + data.bus[1].bus_id = 1; + data.bus[1].bus_type = + PhasorDynamics::BusData::BusType::DEFAULT; + data.bus[1].Vr0 = 30.0; + data.bus[1].Vi0 = 40.0; // Set branch data data.branch.resize(1); @@ -533,15 +556,19 @@ namespace GridKit data.branch[0].parameters[BranchParameters::B] = 1.2; // Jacobian via DependencyTracking - std::vector dependency_tracking_jacobian = DependencyTrackingJacobian(data); + std::vector + dependency_tracking_jacobian = DependencyTrackingJacobian(data); // Jacobian via Enzyme - std::vector enzyme_jacobian = EnzymeJacobian(data); + std::vector + enzyme_jacobian = EnzymeJacobian(data); /// Compare DependencyTracking dependencies to Enzyme's for (size_t i = 0; i < dependency_tracking_jacobian.size(); ++i) { - success *= (GridKit::Testing::isEqual(dependency_tracking_jacobian[i], enzyme_jacobian[i])); + success *= (GridKit::Testing::isEqual( + dependency_tracking_jacobian[i], enzyme_jacobian[i] + )); } return success.report(__func__); @@ -554,7 +581,9 @@ namespace GridKit ) { // Create an empty system model - PhasorDynamics::SystemModel system(data); + PhasorDynamics::SystemModel system( + data + ); // Allocate and initialize the system system.allocate(); @@ -565,7 +594,8 @@ namespace GridKit system.evaluateJacobian(); auto* system_jacobian = system.getCsrJacobian(); auto& output_stream = Log::misc(); - output_stream << "Sparse Csr Matrix: System Jacobian with DependencyTracking\n"; + output_stream + << "Sparse Csr Matrix: System Jacobian with DependencyTracking\n"; system_jacobian->print(output_stream); return GridKit::Testing::MapFromCsr(system_jacobian); diff --git a/tests/UnitTests/PhasorDynamics/runSystemSingleComponentTests.cpp b/tests/UnitTests/PhasorDynamics/runSystemSingleComponentTests.cpp index 3ae783bb7a..ce59fcdb58 100644 --- a/tests/UnitTests/PhasorDynamics/runSystemSingleComponentTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runSystemSingleComponentTests.cpp @@ -23,8 +23,8 @@ int main() result += test.tgov1(); result += test.hygov(); - // @todo The following components are not tested here because they require non-trivial constructors - // PhasorDynamics::Exciter::SexsPti + // @todo The following components are not tested here because they require + // non-trivial constructors PhasorDynamics::Exciter::SexsPti // PhasorDynamics::Stabilizer::Ieeest return result.summary(); diff --git a/tests/UnitTests/PowerElectronics/ComponentCloneTests.hpp b/tests/UnitTests/PowerElectronics/ComponentCloneTests.hpp index d9f6d33dac..67ce4d8a89 100644 --- a/tests/UnitTests/PowerElectronics/ComponentCloneTests.hpp +++ b/tests/UnitTests/PowerElectronics/ComponentCloneTests.hpp @@ -15,13 +15,14 @@ namespace GridKit template class ComponentCloneTests { - using SignalNode = PowerElectronics::SignalNode; - using Bus = PowerElectronics::MicrogridBus; - using BusDQ = PowerElectronics::MicrogridBusDQ; - using Generator = PowerElectronics::DistributedGenerator; - using GeneratorParameters = PowerElectronics::DistributedGeneratorParameters; - using Line = PowerElectronics::MicrogridLine; - using Load = PowerElectronics::MicrogridLoad; + using SignalNode = PowerElectronics::SignalNode; + using Bus = PowerElectronics::MicrogridBus; + using BusDQ = PowerElectronics::MicrogridBusDQ; + using Generator = PowerElectronics::DistributedGenerator; + using GeneratorParameters = + PowerElectronics::DistributedGeneratorParameters; + using Line = PowerElectronics::MicrogridLine; + using Load = PowerElectronics::MicrogridLoad; public: ComponentCloneTests() @@ -59,9 +60,12 @@ namespace GridKit * Construct Components **************************************************************************/ - generator_ = new Generator(1, generator_parameters_, true, &signal_, &bus1_); + generator_ = + new Generator(1, generator_parameters_, true, &signal_, &bus1_); - line_ = new Line(2, 0.23, 0.1 / (2.0 * M_PI * 50.0), &signal_, &bus1_, &bus2_); + line_ = new Line( + 2, 0.23, 0.1 / (2.0 * M_PI * 50.0), &signal_, &bus1_, &bus2_ + ); load_ = new Load(3, 3.0, 2.0 / (2.0 * M_PI * 50.0), &signal_, &bus1_); @@ -125,7 +129,8 @@ namespace GridKit template bool verifyComponentClone(ComponentT& component) { - using RealT = typename PowerElectronics::Component::RealT; + using RealT = + typename PowerElectronics::Component::RealT; bool success = true; @@ -197,7 +202,9 @@ namespace GridKit checkVectorIndependence(component.y(), clone->y()); checkVectorIndependence(component.yp(), clone->yp()); checkVectorIndependence(component.getResidual(), clone->getResidual()); - checkVectorIndependence(component.absoluteTolerance(), clone->absoluteTolerance()); + checkVectorIndependence( + component.absoluteTolerance(), clone->absoluteTolerance() + ); checkVectorIndependence(component.param(), clone->param()); /************************************************************************** diff --git a/tests/UnitTests/Solver/Dynamic/IdaTests.hpp b/tests/UnitTests/Solver/Dynamic/IdaTests.hpp index 59a0a127fd..99187228f9 100644 --- a/tests/UnitTests/Solver/Dynamic/IdaTests.hpp +++ b/tests/UnitTests/Solver/Dynamic/IdaTests.hpp @@ -126,7 +126,8 @@ namespace GridKit return 0; } - void updateTime([[maybe_unused]] RealT t, [[maybe_unused]] RealT a) override + void updateTime([[maybe_unused]] RealT t, [[maybe_unused]] RealT a) + override { } @@ -230,7 +231,8 @@ namespace GridKit return f_; } - GridKit::LinearAlgebra::CsrMatrix* getCsrJacobian() const override + GridKit::LinearAlgebra::CsrMatrix* getCsrJacobian( + ) const override { return csr_jac_; } @@ -401,9 +403,12 @@ namespace GridKit auto* abs_tol = abs_tol_.getData(); auto* f = f_.getData(); - y[0] = 0.0; - y[1] = 10.0; - yp[0] = steady_state_ ? 0.0 : 2.0; // Purposefully inconsistent guess for non-steady-state case. + y[0] = 0.0; + y[1] = 10.0; + yp[0] = + steady_state_ + ? 0.0 + : 2.0; // Purposefully inconsistent guess for non-steady-state case. yp[1] = 0.0; tag_ = {true, false}; abs_tol[0] = 0.0; @@ -456,10 +461,7 @@ namespace GridKit ida.configureSimulation(); unsigned observed_steps = 0; - auto output_cb = [&]([[maybe_unused]] double t) - { - observed_steps++; - }; + auto output_cb = [&]([[maybe_unused]] double t) { observed_steps++; }; ida.initializeSimulation(0.0, false); ida.runSimulation(1.0, 1.0 / n_steps, output_cb); @@ -583,16 +585,21 @@ namespace GridKit using RealT = typename ScalarTraits::RealT; - // If the tolerances are too tight, a finite difference approximation to the Jacobian - // cannot be generated, and initialization will fail with bad initial guesses. - static constexpr auto tol = 100.0 * std::numeric_limits::epsilon(); + // If the tolerances are too tight, a finite difference approximation to + // the Jacobian cannot be generated, and initialization will fail with + // bad initial guesses. + static constexpr auto tol = + 100.0 * std::numeric_limits::epsilon(); - // IdaConsistentICType::YA_YDP with non-steady-state initial guess for the derivatives + // IdaConsistentICType::YA_YDP with non-steady-state initial guess for + // the derivatives { Model::ConsistentICTypeEvaluator model(false); Ida ida(&model); - ida.setConsistentICType(AnalysisManager::Sundials::IdaConsistentICType::YA_YDP); + ida.setConsistentICType( + AnalysisManager::Sundials::IdaConsistentICType::YA_YDP + ); ida.setTolerance(tol); ida.configureSimulation(); ida.initializeSimulation(0.0); @@ -603,12 +610,15 @@ namespace GridKit success *= isEqual(model.y().getData()[1], 0.0, tol); } - // IdaConsistentICType::Y with steady-state initial guess for the derivatives + // IdaConsistentICType::Y with steady-state initial guess for the + // derivatives { Model::ConsistentICTypeEvaluator model(true); Ida ida(&model); - ida.setConsistentICType(AnalysisManager::Sundials::IdaConsistentICType::Y); + ida.setConsistentICType( + AnalysisManager::Sundials::IdaConsistentICType::Y + ); ida.setTolerance(tol); ida.configureSimulation(); ida.initializeSimulation(0.0); @@ -623,7 +633,9 @@ namespace GridKit Model::NullEvaluator model; Ida ida(&model); - ida.setConsistentICType(AnalysisManager::Sundials::IdaConsistentICType::Y); + ida.setConsistentICType( + AnalysisManager::Sundials::IdaConsistentICType::Y + ); ida.configureSimulation(); ida.initializeSimulation(0.0); diff --git a/tests/UnitTests/Solver/Dynamic/RosenbrockTests.hpp b/tests/UnitTests/Solver/Dynamic/RosenbrockTests.hpp index 65838e6d45..5ce2a5509f 100644 --- a/tests/UnitTests/Solver/Dynamic/RosenbrockTests.hpp +++ b/tests/UnitTests/Solver/Dynamic/RosenbrockTests.hpp @@ -22,11 +22,13 @@ namespace GridKit namespace Model { /** - * @brief A test DAE (referred to as the "trigonometric DAE") that is useful for evaluating order - * of DAE integrators. The system is 2-dimensional, with one differential variable and one algebraic variable. - * The DAE is index 1 and the derivatives of the model are non-vanishing. + * @brief A test DAE (referred to as the "trigonometric DAE") that is useful + * for evaluating order of DAE integrators. The system is 2-dimensional, + * with one differential variable and one algebraic variable. The DAE is + * index 1 and the derivatives of the model are non-vanishing. * - * The valid simulation time interval is \f([0.5,2]\f) and the model is initialized at \f(t = 0.5\f). + * The valid simulation time interval is \f([0.5,2]\f) and the model is + * initialized at \f(t = 0.5\f). * */ template @@ -67,7 +69,10 @@ namespace GridKit } } - csr_jac_ = std::make_unique>(SIZE, SIZE, NNZ, &row_ptrs, &cols, &vals); + csr_jac_ = + std::make_unique>( + SIZE, SIZE, NNZ, &row_ptrs, &cols, &vals + ); return 0; } @@ -175,7 +180,8 @@ namespace GridKit ScalarT tmp = std::pow(y12 / y22 - 1, 1.5); ScalarT tmp2 = std::pow(y12 + 1, 2); - vals[0] = static_cast(-alpha_ + -(-y13 + 2 * y1 * y22) / (y23 * tmp)); + vals[0] = + static_cast(-alpha_ + -(-y13 + 2 * y1 * y22) / (y23 * tmp)); vals[1] = static_cast(y12 / (y22 * tmp)); vals[2] = static_cast(-2 * y1 * (1 / y22 - 1) - (2 * y1) / tmp2); vals[3] = static_cast((2 * (y12 + y24)) / y23); @@ -333,7 +339,8 @@ namespace GridKit return 0; } - GridKit::LinearAlgebra::CsrMatrix* getCsrJacobian() const override + GridKit::LinearAlgebra::CsrMatrix* getCsrJacobian( + ) const override { return csr_jac_.get(); } @@ -367,28 +374,39 @@ namespace GridKit template class RosenbrockTests { - using Rosenbrock = AnalysisManager::NativeDynamicSolver::Rosenbrock; - using RealT = typename GridKit::ScalarTraits::RealT; - using VectorT = typename Model::Evaluator::VectorT; + using Rosenbrock = + AnalysisManager::NativeDynamicSolver::Rosenbrock; + using RealT = typename GridKit::ScalarTraits::RealT; + using VectorT = typename Model::Evaluator::VectorT; public: /** - * @brief Test a Rosenbrock tableau by verifying its order empirically. Empirical order is calculated - * by running a convergence test on the problem modeled in \ref Model::TrigonometricDaeEvaluator. 21 - * simulations are run on the problem with a fixed-step step size controller with a number of steps - * logarithmically distributed in \f(\left[10^a, 10^b\right]\f) where \f(a\f) is `step_exponent_lower` - * and \f(b\f) is `step_exponent_upper`. The average slope between pairs of simulations is taken to be - * the empirical order. The test succeeds if the empirical order is at least 85% of the expected theoretical order. + * @brief Test a Rosenbrock tableau by verifying its order empirically. + * Empirical order is calculated by running a convergence test on the + * problem modeled in \ref Model::TrigonometricDaeEvaluator. 21 + * simulations are run on the problem with a fixed-step step size + * controller with a number of steps logarithmically distributed in + * \f(\left[10^a, 10^b\right]\f) where \f(a\f) is `step_exponent_lower` + * and \f(b\f) is `step_exponent_upper`. The average slope between pairs + * of simulations is taken to be the empirical order. The test succeeds if + * the empirical order is at least 85% of the expected theoretical order. * * @param tab The tableau to test - * @param step_exponent_lower The exponent describing the smallest number of steps to take during a simulation. - * @param step_exponent_upper The exponent describing the largest number of steps to take during a simulation. + * @param step_exponent_lower The exponent describing the smallest number + * of steps to take during a simulation. + * @param step_exponent_upper The exponent describing the largest number + * of steps to take during a simulation. */ - TestOutcome test_order(Rosenbrock::Tableau&& tab, RealT step_exponent_lower, RealT step_exponent_upper) + TestOutcome test_order( + Rosenbrock::Tableau&& tab, + RealT step_exponent_lower, + RealT step_exponent_upper + ) { TestStatus success = true; - // Tableaus keep track of their theoretical order. We will attempt to match the empirical order to this. + // Tableaus keep track of their theoretical order. We will attempt to + // match the empirical order to this. uint8_t expected_order = tab.order_; // Setup the model, linear solver, and integrator @@ -396,14 +414,20 @@ namespace GridKit model.allocate(); model.initialize(); - ReSolve::LinAlgWorkspaceCpu linear_workspace; - ReSolve::SystemSolver resolve_solver(&linear_workspace, "klu", "klu", "klu"); + ReSolve::LinAlgWorkspaceCpu linear_workspace; + ReSolve::SystemSolver resolve_solver( + &linear_workspace, "klu", "klu", "klu" + ); GridKit::LinearAlgebra::VectorHandler vec_handler; - GridKit::LinearAlgebra::ResolveSystemSolver lin_solver(resolve_solver); + GridKit::LinearAlgebra::ResolveSystemSolver lin_solver( + resolve_solver + ); resolve_solver.initialize(); - Rosenbrock integrator(std::move(tab), &model, lin_solver, vec_handler, nullptr); + Rosenbrock integrator( + std::move(tab), &model, lin_solver, vec_handler, nullptr + ); if (integrator.allocate()) { success = false; @@ -412,18 +436,20 @@ namespace GridKit AnalysisManager::NativeDynamicSolver::FixedStep step_controller; - // The number of simulations to run to calculate empirical order. Must be at least 2, - // since empirical order is calculated pairwise between simulations. + // The number of simulations to run to calculate empirical order. Must + // be at least 2, since empirical order is calculated pairwise between + // simulations. size_t num_samples = 21; - // Output vectors to keep track of data used to calculate empirical order. - // Each simulation will record its step size and final error. + // Output vectors to keep track of data used to calculate empirical + // order. Each simulation will record its step size and final error. std::vector step_sizes; std::vector errors; - // An output callback to populate step_sizes and errors. Each simulation will call this callback - // at the end of the simulation (final_time). It will then calculate the final error by comparing the - // solution of the simulation to the true answer. + // An output callback to populate step_sizes and errors. Each simulation + // will call this callback at the end of the simulation (final_time). It + // will then calculate the final error by comparing the solution of the + // simulation to the true answer. RealT final_time = 2.0; std::vector out_times = {final_time}; auto out_cb = [&]([[maybe_unused]] RealT t) @@ -446,12 +472,20 @@ namespace GridKit errors.push_back(std::sqrt(error) / std::sqrt(sol_norm)); }; - // Perform all of the simulations and populate step_sizes and errors using out_cb + // Perform all of the simulations and populate step_sizes and errors + // using out_cb for (size_t i = 0; i < num_samples; i++) { - // Logarithmically distribute step_size based on step_exponent_lower and step_exponent_upper. - // Round it to ensure num_steps is integral (do not invoke the dense output, which can add additional errors). - RealT step_size = std::pow(10, step_exponent_lower + static_cast(i) * (step_exponent_upper - step_exponent_lower) / static_cast(num_samples - 1)); + // Logarithmically distribute step_size based on step_exponent_lower + // and step_exponent_upper. Round it to ensure num_steps is integral + // (do not invoke the dense output, which can add additional errors). + RealT step_size = std::pow( + 10, + step_exponent_lower + + static_cast(i) + * (step_exponent_upper - step_exponent_lower) + / static_cast(num_samples - 1) + ); RealT num_steps = round((final_time - 0.5) / step_size); step_size = (final_time - 0.5) / num_steps; step_sizes.push_back(step_size); @@ -465,7 +499,8 @@ namespace GridKit typename Rosenbrock::Parameters params; params.starting_step_ = step_size; - params.max_steps_ = static_cast(ceil((final_time - 0.5) / step_size)) + 10; + params.max_steps_ = + static_cast(ceil((final_time - 0.5) / step_size)) + 10; if (integrator.integrate(out_times, step_controller, params, out_cb)) { success = false; @@ -477,29 +512,37 @@ namespace GridKit std::cout << "Step sizes\n"; for (RealT step_size : step_sizes) { - std::cout << std::scientific << std::setprecision(20) << step_size << "\n"; + std::cout << std::scientific << std::setprecision(20) << step_size + << "\n"; } std::cout << "\nErrors\n"; for (RealT error : errors) { - std::cout << std::scientific << std::setprecision(20) << error << "\n"; + std::cout << std::scientific << std::setprecision(20) << error + << "\n"; } std::cout << "\n"; - // Calculate empirical order. Each pairwise order is calculated, then averaged. + // Calculate empirical order. Each pairwise order is calculated, then + // averaged. std::vector pairwise_orders; RealT empirical_order = 0.0; for (size_t i = 1; i < num_samples; i++) { - pairwise_orders.push_back((log(errors[i]) - log(errors[i - 1])) / (log(step_sizes[i]) - log(step_sizes[i - 1]))); + pairwise_orders.push_back( + (log(errors[i]) - log(errors[i - 1])) + / (log(step_sizes[i]) - log(step_sizes[i - 1])) + ); empirical_order += pairwise_orders.back(); } empirical_order /= static_cast(num_samples - 1); // Print test result - observed empirical order and the expected order. - std::cout << "Empirical order: " << std::fixed << std::setprecision(5) << empirical_order << "\n" - << "Expected order: " << static_cast(expected_order) << "\n"; + std::cout << "Empirical order: " << std::fixed << std::setprecision(5) + << empirical_order << "\n" + << "Expected order: " << static_cast(expected_order) + << "\n"; success *= empirical_order > expected_order * 0.85; return success.report(__func__); diff --git a/tests/UnitTests/Solver/Dynamic/runRosenbrockTests.cpp b/tests/UnitTests/Solver/Dynamic/runRosenbrockTests.cpp index c311c2e8ea..28106388ef 100644 --- a/tests/UnitTests/Solver/Dynamic/runRosenbrockTests.cpp +++ b/tests/UnitTests/Solver/Dynamic/runRosenbrockTests.cpp @@ -11,8 +11,11 @@ int main() GridKit::Testing::TestingResults result; GridKit::Testing::RosenbrockTests test; - result += test.test_order(Rosenbrock::Tableau::linImplicitEuler(), -1.0, -5.0); - result += test.test_order(Rosenbrock::Tableau::rodas5p(), -0.5, -2.5); + result += test.test_order( + Rosenbrock::Tableau::linImplicitEuler(), -1.0, -5.0 + ); + result += + test.test_order(Rosenbrock::Tableau::rodas5p(), -0.5, -2.5); return result.summary(); } diff --git a/tests/UnitTests/Solver/KinsolTests.hpp b/tests/UnitTests/Solver/KinsolTests.hpp index c1f7dda0a4..7937ce8263 100644 --- a/tests/UnitTests/Solver/KinsolTests.hpp +++ b/tests/UnitTests/Solver/KinsolTests.hpp @@ -70,8 +70,7 @@ namespace GridKit std::array values{1.0, 1.0}; - outcome *= throws([&] - { solver.runSimulation(values, residual); }); + outcome *= throws([&] { solver.runSimulation(values, residual); }); fail = false; solver.runSimulation(values, residual, false); diff --git a/tests/UnitTests/Utilities/CaseFormatTests.hpp b/tests/UnitTests/Utilities/CaseFormatTests.hpp index 8cbae39ba5..dc52d4905b 100644 --- a/tests/UnitTests/Utilities/CaseFormatTests.hpp +++ b/tests/UnitTests/Utilities/CaseFormatTests.hpp @@ -36,7 +36,8 @@ namespace GridKit CaseFormatTests() = default; ~CaseFormatTests() = default; - /// Identifier restrictions apply during parsing, independently of monitoring. + /// Identifier restrictions apply during parsing, independently of + /// monitoring. TestOutcome identifierParse() { using DataT = PhasorDynamics::SystemModelData; @@ -64,8 +65,8 @@ namespace GridKit {"buses", input["buses"]}, {"devices", input["devices"]}}} ); - input["buses"] = json::array(); - input["devices"] = json::array(); + input["buses"] = json::array(); + input["devices"] = json::array(); } auto& contents = hierarchical ? input["subsystems"][0] : input; auto& bus = contents["buses"][0]; @@ -88,27 +89,39 @@ namespace GridKit device["mon"] = device_mon; } - for (const auto* name : {"", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 _.-"}) + for (const auto* name : + {"", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567" + "89 _.-"}) { bus["name"] = name; device["id"] = name; const auto data = input.template get(); const auto& parsed = hierarchical ? data.subsystems[0] : data; success *= parsed.bus[0].name == name; - success *= parsed.branch[0].disambiguation_string == name; + success *= parsed.branch[0].disambiguation_string == name; } - for (const auto* name : {"bad\"id", "bad\\id", "bad,id", "bad\nid", "bad\tid", "bad\rid", "caf\xc3\xa9"}) + for (const auto* name : + {"bad\"id", + "bad\\id", + "bad,id", + "bad\nid", + "bad\tid", + "bad\rid", + "caf\xc3\xa9"}) { bus["name"] = name; device["id"] = "Branch 1"; - success *= throws([&]() - { (void) input.template get(); }); + success *= throws( + [&]() { (void) input.template get(); } + ); bus["name"] = "Bus 1"; device["id"] = name; - success *= throws([&]() - { (void) input.template get(); }); + success *= throws( + [&]() { (void) input.template get(); } + ); } } } @@ -171,8 +184,12 @@ namespace GridKit success *= result.format_revision == 0; success *= result.case_name == "Two-bus test case 1"; success *= result.case_date_time == std::nullopt; - success *= result.case_description == "A two-bus test case for demonstrating the dynamics format"; - success *= result.case_comments == "This case is set up to monitor the voltage at both buses and the machine angle and speed"; + success *= + result.case_description + == "A two-bus test case for demonstrating the dynamics format"; + success *= result.case_comments + == "This case is set up to monitor the voltage at both " + "buses and the machine angle and speed"; success *= result.freq_base == 50.0; success *= result.va_base == 50.0e6; @@ -194,76 +211,172 @@ namespace GridKit success *= result.bus[0].name == "Bus 1"; success *= result.bus[0].Vr0 == 0.994988; success *= result.bus[0].Vi0 == 0.099997; - success *= std::get(result.bus[0].parameters[BusData::Parameters::kv]) == 115.0; - success *= result.bus[0].monitored_variables.contains(BusData::MonitorableVariables::Vr); - success *= result.bus[0].monitored_variables.contains(BusData::MonitorableVariables::Vi); + success *= + std::get(result.bus[0].parameters[BusData::Parameters::kv]) + == 115.0; + success *= result.bus[0].monitored_variables.contains( + BusData::MonitorableVariables::Vr + ); + success *= result.bus[0].monitored_variables.contains( + BusData::MonitorableVariables::Vi + ); success *= result.bus[1].bus_id == 2; success *= result.bus[1].bus_type == BusType::SLACK; success *= result.bus[1].name == "Bus 2"; success *= result.bus[1].Vr0 == 1.0; success *= result.bus[1].Vi0 == 0.0; - success *= std::get(result.bus[1].parameters[BusData::Parameters::kv]) == 115.0; + success *= + std::get(result.bus[1].parameters[BusData::Parameters::kv]) + == 115.0; success *= result.bus[1].monitored_variables.empty(); - success *= std::get(result.branch[0].parameters[BranchParameters::R]) == 0.0; - success *= std::get(result.branch[0].parameters[BranchParameters::X]) == 0.1; - 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::Gmag]) == 0.01; - success *= std::get(result.branch[0].parameters[BranchParameters::Bmag]) == 0.02; - 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::R]) + == 0.0; + success *= + std::get(result.branch[0].parameters[BranchParameters::X]) + == 0.1; + 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::Gmag]) + == 0.01; + success *= + std::get(result.branch[0].parameters[BranchParameters::Bmag]) + == 0.02; + success *= + std::get(result.branch[0].parameters[BranchParameters::tap]) + == 1.05; + success *= + std::get(result.branch[0].parameters[BranchParameters::phase]) + == 0.1; success *= result.branch[0].buses[BranchBuses::bus1] == 1; success *= result.branch[0].buses[BranchBuses::bus2] == 2; success *= result.branch[0].disambiguation_string == "1"; success *= result.branch[0].monitored_variables.empty(); - success *= std::get(result.genrou[0].parameters[GenrouParameters::p0]) == 1.0; - success *= std::get(result.genrou[0].parameters[GenrouParameters::q0]) == 0.05013; - success *= std::get(result.genrou[0].parameters[GenrouParameters::H]) == 3.0; - success *= std::get(result.genrou[0].parameters[GenrouParameters::D]) == 0.0; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Ra]) == 0.0; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Tdop]) == 7.0; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Tdopp]) == 0.04; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Tqop]) == 0.75; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Tqopp]) == 0.05; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Xd]) == 2.1; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Xdp]) == 0.2; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Xdpp]) == 0.18; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Xq]) == 0.5; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Xqp]) == 0.0; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Xqpp]) == 0.18; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Xl]) == 0.15; - success *= std::get(result.genrou[0].parameters[GenrouParameters::S10]) == 0.0; - success *= std::get(result.genrou[0].parameters[GenrouParameters::S12]) == 0.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::p0]) + == 1.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::q0]) + == 0.05013; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::H]) + == 3.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::D]) + == 0.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Ra]) + == 0.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Tdop]) + == 7.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Tdopp]) + == 0.04; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Tqop]) + == 0.75; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Tqopp]) + == 0.05; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Xd]) + == 2.1; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Xdp]) + == 0.2; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Xdpp]) + == 0.18; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Xq]) + == 0.5; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Xqp]) + == 0.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Xqpp]) + == 0.18; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Xl]) + == 0.15; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::S10]) + == 0.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::S12]) + == 0.0; success *= result.genrou[0].buses[GenrouBuses::bus] == 1; success *= result.genrou[0].disambiguation_string == "1"; - success *= result.genrou[0].monitored_variables.contains(GenrouMonitorableVariables::delta); - success *= result.genrou[0].monitored_variables.contains(GenrouMonitorableVariables::omega); + success *= result.genrou[0].monitored_variables.contains( + GenrouMonitorableVariables::delta + ); + success *= result.genrou[0].monitored_variables.contains( + GenrouMonitorableVariables::omega + ); - success *= std::get(result.gensal[0].parameters[GensalParameters::p0]) == 1.0; - success *= std::get(result.gensal[0].parameters[GensalParameters::q0]) == 0.05013; - success *= std::get(result.gensal[0].parameters[GensalParameters::Xd]) == 2.1; - success *= std::get(result.gensal[0].parameters[GensalParameters::Xq]) == 0.5; + success *= + std::get(result.gensal[0].parameters[GensalParameters::p0]) + == 1.0; + success *= + std::get(result.gensal[0].parameters[GensalParameters::q0]) + == 0.05013; + success *= + std::get(result.gensal[0].parameters[GensalParameters::Xd]) + == 2.1; + success *= + std::get(result.gensal[0].parameters[GensalParameters::Xq]) + == 0.5; success *= result.gensal[0].buses[GensalBuses::bus] == 1; success *= result.gensal[0].disambiguation_string == "2"; - success *= result.gensal[0].monitored_variables.contains(GensalMonitorableVariables::delta); - success *= result.gensal[0].monitored_variables.contains(GensalMonitorableVariables::omega); + success *= result.gensal[0].monitored_variables.contains( + GensalMonitorableVariables::delta + ); + success *= result.gensal[0].monitored_variables.contains( + GensalMonitorableVariables::omega + ); - success *= std::get(result.regca[0].parameters[RegcaData::Parameters::p0]) == 0.0; - success *= std::get(result.regca[0].parameters[RegcaData::Parameters::q0]) == 0.0; - success *= std::get(result.regca[0].parameters[RegcaData::Parameters::mva]) == 100; - success *= std::get(result.regca[0].parameters[RegcaData::Parameters::sL]); + success *= + std::get(result.regca[0].parameters[RegcaData::Parameters::p0]) + == 0.0; + success *= + std::get(result.regca[0].parameters[RegcaData::Parameters::q0]) + == 0.0; + success *= + std::get(result.regca[0].parameters[RegcaData::Parameters::mva]) + == 100; + success *= + std::get(result.regca[0].parameters[RegcaData::Parameters::sL]); success *= result.regca[0].buses[RegcaData::Buses::bus] == 1; success *= result.regca[0].disambiguation_string == "CV1"; success *= result.regca[0].signal_inputs.empty(); success *= result.regca[0].signal_outputs.empty(); - success *= result.regca[0].monitored_variables.contains(RegcaData::MonitorableVariables::ir); - success *= result.regca[0].monitored_variables.contains(RegcaData::MonitorableVariables::ii); - success *= result.regca[0].monitored_variables.contains(RegcaData::MonitorableVariables::p); - success *= result.regca[0].monitored_variables.contains(RegcaData::MonitorableVariables::q); - success *= std::get(result.reecb[0].parameters[ReecbData::Parameters::mva]) == 50.0; - success *= std::get(result.reecb[0].parameters[ReecbData::Parameters::Pqflag]); + success *= result.regca[0].monitored_variables.contains( + RegcaData::MonitorableVariables::ir + ); + success *= result.regca[0].monitored_variables.contains( + RegcaData::MonitorableVariables::ii + ); + success *= result.regca[0].monitored_variables.contains( + RegcaData::MonitorableVariables::p + ); + success *= result.regca[0].monitored_variables.contains( + RegcaData::MonitorableVariables::q + ); + success *= + std::get(result.reecb[0].parameters[ReecbData::Parameters::mva] + ) + == 50.0; + success *= std::get( + result.reecb[0].parameters[ReecbData::Parameters::Pqflag] + ); success *= result.reecb[0].buses[ReecbData::Buses::bus] == 1; success *= result.reecb[0].disambiguation_string == "REE1"; success *= result.reecb[0].monitored_variables.contains( @@ -363,8 +476,12 @@ namespace GridKit success *= result.format_revision == 0; success *= result.case_name == "Two-bus test case 2"; success *= result.case_date_time == std::nullopt; - success *= result.case_description == "A two-bus test case for demonstrating the dynamics format"; - success *= result.case_comments == "This case is set up to monitor the voltage at both buses and the machine angle and speed"; + success *= + result.case_description + == "A two-bus test case for demonstrating the dynamics format"; + success *= result.case_comments + == "This case is set up to monitor the voltage at both " + "buses and the machine angle and speed"; success *= result.freq_base == 60.0; success *= result.va_base == 100.0e6; @@ -387,15 +504,23 @@ namespace GridKit success *= result.bus[0].name == "Bus 1"; success *= result.bus[0].Vr0 == 0.994988; success *= result.bus[0].Vi0 == 0.099997; - success *= std::get(result.bus[0].parameters[BusData::Parameters::kv]) == 115.0; - success *= result.bus[0].monitored_variables.contains(BusData::MonitorableVariables::Vr); - success *= result.bus[0].monitored_variables.contains(BusData::MonitorableVariables::Vi); + success *= + std::get(result.bus[0].parameters[BusData::Parameters::kv]) + == 115.0; + success *= result.bus[0].monitored_variables.contains( + BusData::MonitorableVariables::Vr + ); + success *= result.bus[0].monitored_variables.contains( + BusData::MonitorableVariables::Vi + ); success *= result.bus[1].bus_id == 2; success *= result.bus[1].bus_type == BusType::SLACK; success *= result.bus[1].name == "Bus 2"; success *= result.bus[1].Vr0 == 1.0; success *= result.bus[1].Vi0 == 0.0; - success *= std::get(result.bus[1].parameters[BusData::Parameters::kv]) == 115.0; + success *= + std::get(result.bus[1].parameters[BusData::Parameters::kv]) + == 115.0; success *= result.bus[1].monitored_variables.empty(); success *= result.signal[0].signal_id == 1; @@ -421,273 +546,796 @@ namespace GridKit success *= result.signal[27].signal_id == 28; success *= result.signal[27].name == "Active Current Command"; - success *= std::get(result.branch[0].parameters[BranchParameters::R]) == 0.0; - success *= std::get(result.branch[0].parameters[BranchParameters::X]) == 0.1; - 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::R]) + == 0.0; + success *= + std::get(result.branch[0].parameters[BranchParameters::X]) + == 0.1; + 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 *= result.branch[0].buses[BranchBuses::bus1] == 1; success *= result.branch[0].buses[BranchBuses::bus2] == 2; success *= result.branch[0].disambiguation_string == "BR1"; success *= result.branch[0].monitored_variables.empty(); - success *= std::get(result.genrou[0].parameters[GenrouParameters::p0]) == 1.0; - success *= std::get(result.genrou[0].parameters[GenrouParameters::q0]) == 0.05013; - success *= std::get(result.genrou[0].parameters[GenrouParameters::H]) == 3.0; - success *= std::get(result.genrou[0].parameters[GenrouParameters::D]) == 0.0; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Ra]) == 0.0; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Tdop]) == 7.0; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Tdopp]) == 0.04; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Tqop]) == 0.75; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Tqopp]) == 0.05; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Xd]) == 2.1; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Xdp]) == 0.2; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Xdpp]) == 0.18; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Xq]) == 0.5; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Xqp]) == 0.0; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Xqpp]) == 0.18; - success *= std::get(result.genrou[0].parameters[GenrouParameters::Xl]) == 0.15; - success *= std::get(result.genrou[0].parameters[GenrouParameters::S10]) == 0.0; - success *= std::get(result.genrou[0].parameters[GenrouParameters::S12]) == 0.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::p0]) + == 1.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::q0]) + == 0.05013; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::H]) + == 3.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::D]) + == 0.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Ra]) + == 0.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Tdop]) + == 7.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Tdopp]) + == 0.04; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Tqop]) + == 0.75; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Tqopp]) + == 0.05; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Xd]) + == 2.1; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Xdp]) + == 0.2; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Xdpp]) + == 0.18; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Xq]) + == 0.5; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Xqp]) + == 0.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Xqpp]) + == 0.18; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::Xl]) + == 0.15; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::S10]) + == 0.0; + success *= + std::get(result.genrou[0].parameters[GenrouParameters::S12]) + == 0.0; success *= result.genrou[0].buses[GenrouBuses::bus] == 1; - success *= result.genrou[0].signal_outputs[GenrouSignalOutputs::speed] == 1; - success *= result.genrou[0].signal_inputs[GenrouSignalInputs::pmech] == 2; + success *= + result.genrou[0].signal_outputs[GenrouSignalOutputs::speed] == 1; + success *= + result.genrou[0].signal_inputs[GenrouSignalInputs::pmech] == 2; success *= result.genrou[0].signal_inputs[GenrouSignalInputs::efd] == 3; success *= result.genrou[0].disambiguation_string == "DV1"; - success *= result.genrou[0].monitored_variables.contains(GenrouMonitorableVariables::delta); - success *= result.genrou[0].monitored_variables.contains(GenrouMonitorableVariables::omega); - - success *= std::get(result.gov[0].parameters[Governor::Tgov1Parameters::R]) == 0.05; - success *= std::get(result.gov[0].parameters[Governor::Tgov1Parameters::T1]) == 0.5; - success *= std::get(result.gov[0].parameters[Governor::Tgov1Parameters::T2]) == 2.5; - success *= std::get(result.gov[0].parameters[Governor::Tgov1Parameters::T3]) == 7.5; - success *= std::get(result.gov[0].parameters[Governor::Tgov1Parameters::Pvmax]) == 1; - success *= std::get(result.gov[0].parameters[Governor::Tgov1Parameters::Pvmin]) == 0; - success *= std::get(result.gov[0].parameters[Governor::Tgov1Parameters::Dt]) == 0; - success *= result.gov[0].signal_inputs[Governor::Tgov1SignalInputs::speed] == 1; - success *= result.gov[0].signal_inputs[Governor::Tgov1SignalInputs::pref] == 10; - success *= result.gov[0].signal_outputs[Governor::Tgov1SignalOutputs::pmech] == 2; + success *= result.genrou[0].monitored_variables.contains( + GenrouMonitorableVariables::delta + ); + success *= result.genrou[0].monitored_variables.contains( + GenrouMonitorableVariables::omega + ); + + success *= + std::get(result.gov[0].parameters[Governor::Tgov1Parameters::R] + ) + == 0.05; + success *= std::get( + result.gov[0].parameters[Governor::Tgov1Parameters::T1] + ) + == 0.5; + success *= std::get( + result.gov[0].parameters[Governor::Tgov1Parameters::T2] + ) + == 2.5; + success *= std::get( + result.gov[0].parameters[Governor::Tgov1Parameters::T3] + ) + == 7.5; + success *= std::get( + result.gov[0].parameters[Governor::Tgov1Parameters::Pvmax] + ) + == 1; + success *= std::get( + result.gov[0].parameters[Governor::Tgov1Parameters::Pvmin] + ) + == 0; + success *= std::get( + result.gov[0].parameters[Governor::Tgov1Parameters::Dt] + ) + == 0; + success *= + result.gov[0].signal_inputs[Governor::Tgov1SignalInputs::speed] == 1; + success *= + result.gov[0].signal_inputs[Governor::Tgov1SignalInputs::pref] == 10; + success *= + result.gov[0].signal_outputs[Governor::Tgov1SignalOutputs::pmech] + == 2; success *= result.gov[0].disambiguation_string == "DV2"; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::Tr]) == 0.0; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::Ka]) == 40.0; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::Ta]) == 0.1; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::Tb]) == 0.0; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::Tc]) == 0.0; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::Vrmax]) == 1.0; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::Vrmin]) == -1.0; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::Ke]) == 0.1; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::Te]) == 0.5; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::Kf]) == 0.05; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::Tf1]) == 0.7; - success *= !std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::Spdmlt]); - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::E1]) == 2.8; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::Se1]) == 0.08; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::E2]) == 3.7; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::Se2]) == 0.33; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::UEL]) == 0; - success *= std::get(result.esdc1a[0].parameters[Esdc1aData::Parameters::exclim]); + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::Tr] + ) + == 0.0; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::Ka] + ) + == 40.0; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::Ta] + ) + == 0.1; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::Tb] + ) + == 0.0; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::Tc] + ) + == 0.0; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::Vrmax] + ) + == 1.0; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::Vrmin] + ) + == -1.0; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::Ke] + ) + == 0.1; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::Te] + ) + == 0.5; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::Kf] + ) + == 0.05; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::Tf1] + ) + == 0.7; + success *= !std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::Spdmlt] + ); + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::E1] + ) + == 2.8; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::Se1] + ) + == 0.08; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::E2] + ) + == 3.7; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::Se2] + ) + == 0.33; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::UEL] + ) + == 0; + success *= std::get( + result.esdc1a[0].parameters[Esdc1aData::Parameters::exclim] + ); success *= result.esdc1a[0].buses[Esdc1aData::Buses::bus] == 1; - success *= result.esdc1a[0].signal_inputs[Esdc1aData::SignalInputs::speed] == 1; - success *= result.esdc1a[0].signal_inputs[Esdc1aData::SignalInputs::vref] == 4; - success *= result.esdc1a[0].signal_inputs[Esdc1aData::SignalInputs::vs] == 5; - success *= result.esdc1a[0].signal_inputs[Esdc1aData::SignalInputs::vuel] == 6; - success *= result.esdc1a[0].signal_outputs[Esdc1aData::SignalOutputs::efd] == 3; + success *= + result.esdc1a[0].signal_inputs[Esdc1aData::SignalInputs::speed] == 1; + success *= + result.esdc1a[0].signal_inputs[Esdc1aData::SignalInputs::vref] == 4; + success *= + result.esdc1a[0].signal_inputs[Esdc1aData::SignalInputs::vs] == 5; + success *= + result.esdc1a[0].signal_inputs[Esdc1aData::SignalInputs::vuel] == 6; + success *= + result.esdc1a[0].signal_outputs[Esdc1aData::SignalOutputs::efd] == 3; success *= result.esdc1a[0].disambiguation_string == "DV5"; - success *= result.esdc1a[0].monitored_variables.contains(Esdc1aData::MonitorableVariables::efd); - success *= result.esdc1a[0].monitored_variables.contains(Esdc1aData::MonitorableVariables::vc); - success *= result.esdc1a[0].monitored_variables.contains(Esdc1aData::MonitorableVariables::vr); - success *= result.esdc1a[0].monitored_variables.contains(Esdc1aData::MonitorableVariables::vf); - success *= result.esdc1a[0].monitored_variables.contains(Esdc1aData::MonitorableVariables::se); - success *= result.esdc1a[0].monitored_variables.contains(Esdc1aData::MonitorableVariables::vfe); - - success *= std::get(result.gastpti[0].parameters[GastPtiData::Parameters::R]) == 0.045; - success *= std::get(result.gastpti[0].parameters[GastPtiData::Parameters::T1]) == 0.42; - success *= std::get(result.gastpti[0].parameters[GastPtiData::Parameters::T2]) == 0.12; - success *= std::get(result.gastpti[0].parameters[GastPtiData::Parameters::T3]) == 3.2; - success *= std::get(result.gastpti[0].parameters[GastPtiData::Parameters::At]) == 0.95; - success *= std::get(result.gastpti[0].parameters[GastPtiData::Parameters::Kt]) == 2.2; - success *= std::get(result.gastpti[0].parameters[GastPtiData::Parameters::Vmax]) == 1.05; - success *= std::get(result.gastpti[0].parameters[GastPtiData::Parameters::Vmin]) == 0.15; - success *= std::get(result.gastpti[0].parameters[GastPtiData::Parameters::Dturb]) == 0.02; - success *= std::get(result.gastpti[0].parameters[GastPtiData::Parameters::Trate]) == 120.0; - success *= result.gastpti[0].signal_inputs[GastPtiData::SignalInputs::speed] == 1; - success *= result.gastpti[0].signal_inputs[GastPtiData::SignalInputs::pref] == 10; - success *= result.gastpti[0].signal_outputs[GastPtiData::SignalOutputs::pmech] == 2; + success *= result.esdc1a[0].monitored_variables.contains( + Esdc1aData::MonitorableVariables::efd + ); + success *= result.esdc1a[0].monitored_variables.contains( + Esdc1aData::MonitorableVariables::vc + ); + success *= result.esdc1a[0].monitored_variables.contains( + Esdc1aData::MonitorableVariables::vr + ); + success *= result.esdc1a[0].monitored_variables.contains( + Esdc1aData::MonitorableVariables::vf + ); + success *= result.esdc1a[0].monitored_variables.contains( + Esdc1aData::MonitorableVariables::se + ); + success *= result.esdc1a[0].monitored_variables.contains( + Esdc1aData::MonitorableVariables::vfe + ); + + success *= std::get( + result.gastpti[0].parameters[GastPtiData::Parameters::R] + ) + == 0.045; + success *= std::get( + result.gastpti[0].parameters[GastPtiData::Parameters::T1] + ) + == 0.42; + success *= std::get( + result.gastpti[0].parameters[GastPtiData::Parameters::T2] + ) + == 0.12; + success *= std::get( + result.gastpti[0].parameters[GastPtiData::Parameters::T3] + ) + == 3.2; + success *= std::get( + result.gastpti[0].parameters[GastPtiData::Parameters::At] + ) + == 0.95; + success *= std::get( + result.gastpti[0].parameters[GastPtiData::Parameters::Kt] + ) + == 2.2; + success *= std::get( + result.gastpti[0].parameters[GastPtiData::Parameters::Vmax] + ) + == 1.05; + success *= std::get( + result.gastpti[0].parameters[GastPtiData::Parameters::Vmin] + ) + == 0.15; + success *= + std::get( + result.gastpti[0].parameters[GastPtiData::Parameters::Dturb] + ) + == 0.02; + success *= + std::get( + result.gastpti[0].parameters[GastPtiData::Parameters::Trate] + ) + == 120.0; + success *= + result.gastpti[0].signal_inputs[GastPtiData::SignalInputs::speed] + == 1; + success *= + result.gastpti[0].signal_inputs[GastPtiData::SignalInputs::pref] + == 10; + success *= + result.gastpti[0].signal_outputs[GastPtiData::SignalOutputs::pmech] + == 2; success *= result.gastpti[0].disambiguation_string == "DV7"; - success *= result.gastpti[0].monitored_variables.contains(GastPtiData::MonitorableVariables::pmech); - success *= result.gastpti[0].monitored_variables.contains(GastPtiData::MonitorableVariables::xvalve); - success *= result.gastpti[0].monitored_variables.contains(GastPtiData::MonitorableVariables::xflow); - success *= result.gastpti[0].monitored_variables.contains(GastPtiData::MonitorableVariables::xtemp); - success *= result.gastpti[0].monitored_variables.contains(GastPtiData::MonitorableVariables::vload); - success *= result.gastpti[0].monitored_variables.contains(GastPtiData::MonitorableVariables::vtemp); - - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Trate]) == 80.0; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Rperm]) == 0.05; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Rtemp]) == 0.35; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Tr]) == 5.0; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Tf]) == 0.05; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Tg]) == 0.5; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Velm]) == 0.2; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Gmax]) == 0.98; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Gmin]) == 0.02; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Tw]) == 1.2; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::At]) == 1.1; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Dturb]) == 0.4; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Qnl]) == 0.08; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Tn]) == 0.7; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Tnp]) == 1.4; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::db1]) == 0.01; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::db2]) == 0.02; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Hdam]) == 1.05; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Gv0]) == 0.0; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Gv1]) == 0.2; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Gv2]) == 0.4; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Gv3]) == 0.6; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Gv4]) == 0.8; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Gv5]) == 1.0; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Pgv0]) == 0.0; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Pgv1]) == 0.15; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Pgv2]) == 0.42; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Pgv3]) == 0.66; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Pgv4]) == 0.85; - success *= std::get(result.hygov[0].parameters[HygovData::Parameters::Pgv5]) == 1.0; - success *= result.hygov[0].signal_inputs[HygovData::SignalInputs::speed] == 1; - success *= result.hygov[0].signal_inputs[HygovData::SignalInputs::pref] == 8; - success *= result.hygov[0].signal_inputs[HygovData::SignalInputs::paux] == 9; - success *= result.hygov[0].signal_outputs[HygovData::SignalOutputs::pmech] == 7; + success *= result.gastpti[0].monitored_variables.contains( + GastPtiData::MonitorableVariables::pmech + ); + success *= result.gastpti[0].monitored_variables.contains( + GastPtiData::MonitorableVariables::xvalve + ); + success *= result.gastpti[0].monitored_variables.contains( + GastPtiData::MonitorableVariables::xflow + ); + success *= result.gastpti[0].monitored_variables.contains( + GastPtiData::MonitorableVariables::xtemp + ); + success *= result.gastpti[0].monitored_variables.contains( + GastPtiData::MonitorableVariables::vload + ); + success *= result.gastpti[0].monitored_variables.contains( + GastPtiData::MonitorableVariables::vtemp + ); + + success *= std::get( + result.hygov[0].parameters[HygovData::Parameters::Trate] + ) + == 80.0; + success *= std::get( + result.hygov[0].parameters[HygovData::Parameters::Rperm] + ) + == 0.05; + success *= std::get( + result.hygov[0].parameters[HygovData::Parameters::Rtemp] + ) + == 0.35; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::Tr]) + == 5.0; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::Tf]) + == 0.05; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::Tg]) + == 0.5; + success *= std::get( + result.hygov[0].parameters[HygovData::Parameters::Velm] + ) + == 0.2; + success *= std::get( + result.hygov[0].parameters[HygovData::Parameters::Gmax] + ) + == 0.98; + success *= std::get( + result.hygov[0].parameters[HygovData::Parameters::Gmin] + ) + == 0.02; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::Tw]) + == 1.2; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::At]) + == 1.1; + success *= std::get( + result.hygov[0].parameters[HygovData::Parameters::Dturb] + ) + == 0.4; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::Qnl] + ) + == 0.08; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::Tn]) + == 0.7; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::Tnp] + ) + == 1.4; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::db1] + ) + == 0.01; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::db2] + ) + == 0.02; + success *= std::get( + result.hygov[0].parameters[HygovData::Parameters::Hdam] + ) + == 1.05; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::Gv0] + ) + == 0.0; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::Gv1] + ) + == 0.2; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::Gv2] + ) + == 0.4; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::Gv3] + ) + == 0.6; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::Gv4] + ) + == 0.8; + success *= + std::get(result.hygov[0].parameters[HygovData::Parameters::Gv5] + ) + == 1.0; + success *= std::get( + result.hygov[0].parameters[HygovData::Parameters::Pgv0] + ) + == 0.0; + success *= std::get( + result.hygov[0].parameters[HygovData::Parameters::Pgv1] + ) + == 0.15; + success *= std::get( + result.hygov[0].parameters[HygovData::Parameters::Pgv2] + ) + == 0.42; + success *= std::get( + result.hygov[0].parameters[HygovData::Parameters::Pgv3] + ) + == 0.66; + success *= std::get( + result.hygov[0].parameters[HygovData::Parameters::Pgv4] + ) + == 0.85; + success *= std::get( + result.hygov[0].parameters[HygovData::Parameters::Pgv5] + ) + == 1.0; + success *= + result.hygov[0].signal_inputs[HygovData::SignalInputs::speed] == 1; + success *= + result.hygov[0].signal_inputs[HygovData::SignalInputs::pref] == 8; + success *= + result.hygov[0].signal_inputs[HygovData::SignalInputs::paux] == 9; + success *= + result.hygov[0].signal_outputs[HygovData::SignalOutputs::pmech] == 7; success *= result.hygov[0].disambiguation_string == "DV6"; - success *= result.hygov[0].monitored_variables.contains(HygovData::MonitorableVariables::pmech); - success *= result.hygov[0].monitored_variables.contains(HygovData::MonitorableVariables::filter); + success *= result.hygov[0].monitored_variables.contains( + HygovData::MonitorableVariables::pmech + ); + success *= result.hygov[0].monitored_variables.contains( + HygovData::MonitorableVariables::filter + ); success *= result.hygov[0].monitored_variables.contains( HygovData::MonitorableVariables::desiredgate ); - success *= result.hygov[0].monitored_variables.contains(HygovData::MonitorableVariables::gate); - success *= result.hygov[0].monitored_variables.contains(HygovData::MonitorableVariables::flow); - success *= result.hygov[0].monitored_variables.contains(HygovData::MonitorableVariables::head); - - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::mva]) == 50; - success *= !std::get(result.repca[0].parameters[RepcaData::Parameters::VcompFlag]); - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::RefFlag]); - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Freqflag]); - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Tfltr]) == 0.2; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Vfrz]) == 0.65; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Rc]) == 0.02; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Xc]) == 0.03; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Kc]) == 0.4; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::dbdlow]) == -0.02; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::dbdupper]) == 0.03; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::emax]) == 0.8; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::emin]) == -0.7; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Kp]) == 2.0; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Ki]) == 3.0; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Qmax]) == 0.9; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Qmin]) == -0.8; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Tft]) == 0.2; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Tfv]) == 1.5; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Tp]) == 0.4; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::fdbd1]) == -0.01; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::fdbd2]) == 0.015; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Ddn]) == 2.0; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Dup]) == 1.0; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::femax]) == 0.6; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::femin]) == -0.5; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Kpg]) == 1.7; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Kig]) == 1.8; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Pmax]) == 1.2; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Pmin]) == 0.1; - success *= std::get(result.repca[0].parameters[RepcaData::Parameters::Tlag]) == 0.5; + success *= result.hygov[0].monitored_variables.contains( + HygovData::MonitorableVariables::gate + ); + success *= result.hygov[0].monitored_variables.contains( + HygovData::MonitorableVariables::flow + ); + success *= result.hygov[0].monitored_variables.contains( + HygovData::MonitorableVariables::head + ); + + success *= + std::get(result.repca[0].parameters[RepcaData::Parameters::mva]) + == 50; + success *= !std::get( + result.repca[0].parameters[RepcaData::Parameters::VcompFlag] + ); + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::RefFlag] + ); + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::Freqflag] + ); + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::Tfltr] + ) + == 0.2; + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::Vfrz] + ) + == 0.65; + success *= + std::get(result.repca[0].parameters[RepcaData::Parameters::Rc]) + == 0.02; + success *= + std::get(result.repca[0].parameters[RepcaData::Parameters::Xc]) + == 0.03; + success *= + std::get(result.repca[0].parameters[RepcaData::Parameters::Kc]) + == 0.4; + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::dbdlow] + ) + == -0.02; + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::dbdupper] + ) + == 0.03; + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::emax] + ) + == 0.8; + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::emin] + ) + == -0.7; + success *= + std::get(result.repca[0].parameters[RepcaData::Parameters::Kp]) + == 2.0; + success *= + std::get(result.repca[0].parameters[RepcaData::Parameters::Ki]) + == 3.0; + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::Qmax] + ) + == 0.9; + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::Qmin] + ) + == -0.8; + success *= + std::get(result.repca[0].parameters[RepcaData::Parameters::Tft] + ) + == 0.2; + success *= + std::get(result.repca[0].parameters[RepcaData::Parameters::Tfv] + ) + == 1.5; + success *= + std::get(result.repca[0].parameters[RepcaData::Parameters::Tp]) + == 0.4; + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::fdbd1] + ) + == -0.01; + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::fdbd2] + ) + == 0.015; + success *= + std::get(result.repca[0].parameters[RepcaData::Parameters::Ddn] + ) + == 2.0; + success *= + std::get(result.repca[0].parameters[RepcaData::Parameters::Dup] + ) + == 1.0; + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::femax] + ) + == 0.6; + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::femin] + ) + == -0.5; + success *= + std::get(result.repca[0].parameters[RepcaData::Parameters::Kpg] + ) + == 1.7; + success *= + std::get(result.repca[0].parameters[RepcaData::Parameters::Kig] + ) + == 1.8; + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::Pmax] + ) + == 1.2; + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::Pmin] + ) + == 0.1; + success *= std::get( + result.repca[0].parameters[RepcaData::Parameters::Tlag] + ) + == 0.5; success *= result.repca[0].buses[RepcaData::Buses::bus] == 1; - success *= result.repca[0].signal_inputs[RepcaData::SignalInputs::ir] == 11; - success *= result.repca[0].signal_inputs[RepcaData::SignalInputs::ii] == 12; - success *= result.repca[0].signal_inputs[RepcaData::SignalInputs::p] == 13; - success *= result.repca[0].signal_inputs[RepcaData::SignalInputs::q] == 14; - success *= result.repca[0].signal_inputs[RepcaData::SignalInputs::freq] == 15; - success *= result.repca[0].signal_inputs[RepcaData::SignalInputs::vref] == 16; - success *= result.repca[0].signal_inputs[RepcaData::SignalInputs::pref] == 17; - success *= result.repca[0].signal_inputs[RepcaData::SignalInputs::qref] == 18; - success *= result.repca[0].signal_inputs[RepcaData::SignalInputs::freqref] == 19; - success *= result.repca[0].signal_outputs[RepcaData::SignalOutputs::qext] == 20; - success *= result.repca[0].signal_outputs[RepcaData::SignalOutputs::pext] == 21; + success *= + result.repca[0].signal_inputs[RepcaData::SignalInputs::ir] == 11; + success *= + result.repca[0].signal_inputs[RepcaData::SignalInputs::ii] == 12; + success *= + result.repca[0].signal_inputs[RepcaData::SignalInputs::p] == 13; + success *= + result.repca[0].signal_inputs[RepcaData::SignalInputs::q] == 14; + success *= + result.repca[0].signal_inputs[RepcaData::SignalInputs::freq] == 15; + success *= + result.repca[0].signal_inputs[RepcaData::SignalInputs::vref] == 16; + success *= + result.repca[0].signal_inputs[RepcaData::SignalInputs::pref] == 17; + success *= + result.repca[0].signal_inputs[RepcaData::SignalInputs::qref] == 18; + success *= + result.repca[0].signal_inputs[RepcaData::SignalInputs::freqref] == 19; + success *= + result.repca[0].signal_outputs[RepcaData::SignalOutputs::qext] == 20; + success *= + result.repca[0].signal_outputs[RepcaData::SignalOutputs::pext] == 21; success *= result.repca[0].disambiguation_string == "PC1"; - success *= result.repca[0].monitored_variables.contains(RepcaData::MonitorableVariables::qext); - success *= result.repca[0].monitored_variables.contains(RepcaData::MonitorableVariables::pext); - success *= result.repca[0].monitored_variables.contains(RepcaData::MonitorableVariables::vmeas); - success *= result.repca[0].monitored_variables.contains(RepcaData::MonitorableVariables::qmeas); - success *= result.repca[0].monitored_variables.contains(RepcaData::MonitorableVariables::pmeas); - - success *= std::get(result.exciter[0].parameters[Exciter::Ieeet1Parameters::Tr]) == 0.0; - success *= std::get(result.exciter[0].parameters[Exciter::Ieeet1Parameters::Ka]) == 50.0; - success *= std::get(result.exciter[0].parameters[Exciter::Ieeet1Parameters::Ta]) == 0.04; - success *= std::get(result.exciter[0].parameters[Exciter::Ieeet1Parameters::Ke]) == -0.06; - success *= std::get(result.exciter[0].parameters[Exciter::Ieeet1Parameters::Te]) == 0.6; - success *= std::get(result.exciter[0].parameters[Exciter::Ieeet1Parameters::Kf]) == 0.09; - success *= std::get(result.exciter[0].parameters[Exciter::Ieeet1Parameters::Tf]) == 1.46; - success *= std::get(result.exciter[0].parameters[Exciter::Ieeet1Parameters::Vrmin]) == -1.0; - success *= std::get(result.exciter[0].parameters[Exciter::Ieeet1Parameters::Vrmax]) == 1.0; - success *= std::get(result.exciter[0].parameters[Exciter::Ieeet1Parameters::E1]) == 2.8; - success *= std::get(result.exciter[0].parameters[Exciter::Ieeet1Parameters::E2]) == 3.373; - success *= std::get(result.exciter[0].parameters[Exciter::Ieeet1Parameters::Se1]) == 0.04; - success *= std::get(result.exciter[0].parameters[Exciter::Ieeet1Parameters::Se2]) == 0.33; - success *= std::get(result.exciter[0].parameters[Exciter::Ieeet1Parameters::Ispdlim]) == 0.0; + success *= result.repca[0].monitored_variables.contains( + RepcaData::MonitorableVariables::qext + ); + success *= result.repca[0].monitored_variables.contains( + RepcaData::MonitorableVariables::pext + ); + success *= result.repca[0].monitored_variables.contains( + RepcaData::MonitorableVariables::vmeas + ); + success *= result.repca[0].monitored_variables.contains( + RepcaData::MonitorableVariables::qmeas + ); + success *= result.repca[0].monitored_variables.contains( + RepcaData::MonitorableVariables::pmeas + ); + + success *= std::get( + result.exciter[0].parameters[Exciter::Ieeet1Parameters::Tr] + ) + == 0.0; + success *= std::get( + result.exciter[0].parameters[Exciter::Ieeet1Parameters::Ka] + ) + == 50.0; + success *= std::get( + result.exciter[0].parameters[Exciter::Ieeet1Parameters::Ta] + ) + == 0.04; + success *= std::get( + result.exciter[0].parameters[Exciter::Ieeet1Parameters::Ke] + ) + == -0.06; + success *= std::get( + result.exciter[0].parameters[Exciter::Ieeet1Parameters::Te] + ) + == 0.6; + success *= std::get( + result.exciter[0].parameters[Exciter::Ieeet1Parameters::Kf] + ) + == 0.09; + success *= std::get( + result.exciter[0].parameters[Exciter::Ieeet1Parameters::Tf] + ) + == 1.46; + success *= + std::get( + result.exciter[0].parameters[Exciter::Ieeet1Parameters::Vrmin] + ) + == -1.0; + success *= + std::get( + result.exciter[0].parameters[Exciter::Ieeet1Parameters::Vrmax] + ) + == 1.0; + success *= std::get( + result.exciter[0].parameters[Exciter::Ieeet1Parameters::E1] + ) + == 2.8; + success *= std::get( + result.exciter[0].parameters[Exciter::Ieeet1Parameters::E2] + ) + == 3.373; + success *= + std::get( + result.exciter[0].parameters[Exciter::Ieeet1Parameters::Se1] + ) + == 0.04; + success *= + std::get( + result.exciter[0].parameters[Exciter::Ieeet1Parameters::Se2] + ) + == 0.33; + success *= + std::get( + result.exciter[0].parameters[Exciter::Ieeet1Parameters::Ispdlim] + ) + == 0.0; success *= result.exciter[0].buses[Exciter::Ieeet1Buses::bus] == 1; - success *= result.exciter[0].signal_inputs[Exciter::Ieeet1SignalInputs::speed] == 1; - success *= result.exciter[0].signal_outputs[Exciter::Ieeet1SignalOutputs::efd] == 3; + success *= + result.exciter[0].signal_inputs[Exciter::Ieeet1SignalInputs::speed] + == 1; + success *= + result.exciter[0].signal_outputs[Exciter::Ieeet1SignalOutputs::efd] + == 3; success *= result.exciter[0].disambiguation_string == "DV3"; - success *= std::get(result.sexspti[0].parameters[Exciter::SexsPtiParameters::Ta]) == 0.1; - success *= std::get(result.sexspti[0].parameters[Exciter::SexsPtiParameters::Tb]) == 0.5; - success *= std::get(result.sexspti[0].parameters[Exciter::SexsPtiParameters::Te]) == 0.8; - success *= std::get(result.sexspti[0].parameters[Exciter::SexsPtiParameters::K]) == 10.0; - success *= std::get(result.sexspti[0].parameters[Exciter::SexsPtiParameters::Efdmax]) == 5.0; - success *= std::get(result.sexspti[0].parameters[Exciter::SexsPtiParameters::Efdmin]) == -5.0; + success *= + std::get( + result.sexspti[0].parameters[Exciter::SexsPtiParameters::Ta] + ) + == 0.1; + success *= + std::get( + result.sexspti[0].parameters[Exciter::SexsPtiParameters::Tb] + ) + == 0.5; + success *= + std::get( + result.sexspti[0].parameters[Exciter::SexsPtiParameters::Te] + ) + == 0.8; + success *= std::get( + result.sexspti[0].parameters[Exciter::SexsPtiParameters::K] + ) + == 10.0; + success *= + std::get( + result.sexspti[0].parameters[Exciter::SexsPtiParameters::Efdmax] + ) + == 5.0; + success *= + std::get( + result.sexspti[0].parameters[Exciter::SexsPtiParameters::Efdmin] + ) + == -5.0; success *= result.sexspti[0].buses[Exciter::SexsPtiBuses::bus] == 1; - success *= result.sexspti[0].signal_outputs[Exciter::SexsPtiSignalOutputs::efd] == 3; + success *= + result.sexspti[0].signal_outputs[Exciter::SexsPtiSignalOutputs::efd] + == 3; success *= result.sexspti[0].disambiguation_string == "DV4"; - using ReecbData = Controller::ReecbData; - using ReecbParams = ReecbData::Parameters; - success *= std::get(result.reecb[0].parameters[ReecbParams::mva]) == 100.0; - success *= !std::get(result.reecb[0].parameters[ReecbParams::PfFlag]); - success *= std::get(result.reecb[0].parameters[ReecbParams::VFlag]); - success *= std::get(result.reecb[0].parameters[ReecbParams::QFlag]); - success *= std::get(result.reecb[0].parameters[ReecbParams::Pqflag]); - success *= std::get(result.reecb[0].parameters[ReecbParams::Trv]) == 0.02; - success *= std::get(result.reecb[0].parameters[ReecbParams::Tp]) == 0.05; - success *= std::get(result.reecb[0].parameters[ReecbParams::Vref0]) == 1.0; - success *= std::get(result.reecb[0].parameters[ReecbParams::Vdip]) == 0.85; - success *= std::get(result.reecb[0].parameters[ReecbParams::Vup]) == 1.15; - success *= std::get(result.reecb[0].parameters[ReecbParams::dbd1]) == -0.01; - success *= std::get(result.reecb[0].parameters[ReecbParams::dbd2]) == 0.01; - success *= std::get(result.reecb[0].parameters[ReecbParams::kqv]) == 5.0; - success *= std::get(result.reecb[0].parameters[ReecbParams::Iql1]) == -1.1; - success *= std::get(result.reecb[0].parameters[ReecbParams::Iqh1]) == 1.1; - success *= std::get(result.reecb[0].parameters[ReecbParams::Qmax]) == 0.436; - success *= std::get(result.reecb[0].parameters[ReecbParams::Qmin]) == -0.436; - success *= std::get(result.reecb[0].parameters[ReecbParams::Kqp]) == 0.1; - success *= std::get(result.reecb[0].parameters[ReecbParams::Kqi]) == 0.2; - success *= std::get(result.reecb[0].parameters[ReecbParams::Vmax]) == 1.1; - success *= std::get(result.reecb[0].parameters[ReecbParams::Vmin]) == 0.9; - success *= std::get(result.reecb[0].parameters[ReecbParams::Kvp]) == 18.0; - success *= std::get(result.reecb[0].parameters[ReecbParams::Kvi]) == 5.0; - success *= std::get(result.reecb[0].parameters[ReecbParams::Tiq]) == 0.02; - success *= std::get(result.reecb[0].parameters[ReecbParams::Tpord]) == 0.02; - success *= std::get(result.reecb[0].parameters[ReecbParams::dPmax]) == 99.0; - success *= std::get(result.reecb[0].parameters[ReecbParams::dPmin]) == -99.0; - success *= std::get(result.reecb[0].parameters[ReecbParams::Pmax]) == 1.0; - success *= std::get(result.reecb[0].parameters[ReecbParams::Pmin]) == 0.0; - success *= std::get(result.reecb[0].parameters[ReecbParams::Imax]) == 1.3; - success *= result.reecb[0].buses[ReecbData::Buses::bus] == 1; - success *= result.reecb[0].signal_inputs[ReecbData::SignalInputs::pe] == 22; - success *= result.reecb[0].signal_inputs[ReecbData::SignalInputs::qgen] == 23; - success *= result.reecb[0].signal_inputs[ReecbData::SignalInputs::qext] == 24; - success *= result.reecb[0].signal_inputs[ReecbData::SignalInputs::pfaref] == 25; - success *= result.reecb[0].signal_inputs[ReecbData::SignalInputs::pref] == 26; - success *= result.reecb[0].signal_outputs[ReecbData::SignalOutputs::iqcmd] == 27; - success *= result.reecb[0].signal_outputs[ReecbData::SignalOutputs::ipcmd] == 28; - success *= result.reecb[0].disambiguation_string == "EC1"; - success *= result.reecb[0].monitored_variables.contains( + using ReecbData = Controller::ReecbData; + using ReecbParams = ReecbData::Parameters; + success *= std::get(result.reecb[0].parameters[ReecbParams::mva]) + == 100.0; + success *= + !std::get(result.reecb[0].parameters[ReecbParams::PfFlag]); + success *= + std::get(result.reecb[0].parameters[ReecbParams::VFlag]); + success *= + std::get(result.reecb[0].parameters[ReecbParams::QFlag]); + success *= + std::get(result.reecb[0].parameters[ReecbParams::Pqflag]); + success *= + std::get(result.reecb[0].parameters[ReecbParams::Trv]) == 0.02; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Tp]) == 0.05; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Vref0]) + == 1.0; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Vdip]) + == 0.85; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Vup]) == 1.15; + success *= + std::get(result.reecb[0].parameters[ReecbParams::dbd1]) + == -0.01; + success *= + std::get(result.reecb[0].parameters[ReecbParams::dbd2]) + == 0.01; + success *= + std::get(result.reecb[0].parameters[ReecbParams::kqv]) == 5.0; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Iql1]) + == -1.1; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Iqh1]) == 1.1; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Qmax]) + == 0.436; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Qmin]) + == -0.436; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Kqp]) == 0.1; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Kqi]) == 0.2; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Vmax]) == 1.1; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Vmin]) == 0.9; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Kvp]) == 18.0; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Kvi]) == 5.0; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Tiq]) == 0.02; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Tpord]) + == 0.02; + success *= + std::get(result.reecb[0].parameters[ReecbParams::dPmax]) + == 99.0; + success *= + std::get(result.reecb[0].parameters[ReecbParams::dPmin]) + == -99.0; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Pmax]) == 1.0; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Pmin]) == 0.0; + success *= + std::get(result.reecb[0].parameters[ReecbParams::Imax]) == 1.3; + success *= result.reecb[0].buses[ReecbData::Buses::bus] == 1; + success *= + result.reecb[0].signal_inputs[ReecbData::SignalInputs::pe] == 22; + success *= + result.reecb[0].signal_inputs[ReecbData::SignalInputs::qgen] == 23; + success *= + result.reecb[0].signal_inputs[ReecbData::SignalInputs::qext] == 24; + success *= + result.reecb[0].signal_inputs[ReecbData::SignalInputs::pfaref] == 25; + success *= + result.reecb[0].signal_inputs[ReecbData::SignalInputs::pref] == 26; + success *= + result.reecb[0].signal_outputs[ReecbData::SignalOutputs::iqcmd] == 27; + success *= + result.reecb[0].signal_outputs[ReecbData::SignalOutputs::ipcmd] == 28; + success *= result.reecb[0].disambiguation_string == "EC1"; + success *= result.reecb[0].monitored_variables.contains( ReecbData::MonitorableVariables::iqcmd ); success *= result.reecb[0].monitored_variables.contains( diff --git a/tests/UnitTests/Utilities/CliArgsTests.hpp b/tests/UnitTests/Utilities/CliArgsTests.hpp index 1cf6ec2b72..a253d6bb5a 100644 --- a/tests/UnitTests/Utilities/CliArgsTests.hpp +++ b/tests/UnitTests/Utilities/CliArgsTests.hpp @@ -156,8 +156,7 @@ namespace GridKit Log::misc() << "Expect error while testing that unrecognized options " "are rejected\n"; Log::setVerbosity(previous_verbosity); - status *= throws([&]() - { args.get("bad"); }); + status *= throws([&]() { args.get("bad"); }); return status.report(__func__); } @@ -242,8 +241,10 @@ namespace GridKit }; TestStatus status{true}; status *= argsAreBad(CommandLine{"app"}); - status *= argsAreBad(CommandLine{"app", "a.solver.json", "b.solver.json"}); - status *= argsAreBad(CommandLine{"app", "--solver-file", "a.solver.json"}); + status *= + argsAreBad(CommandLine{"app", "a.solver.json", "b.solver.json"}); + status *= + argsAreBad(CommandLine{"app", "--solver-file", "a.solver.json"}); status *= argsAreBad( CommandLine{"app", "a.solver.json", "--one", "1", "--one", "2"} ); @@ -253,8 +254,10 @@ namespace GridKit status *= argsAreBad( CommandLine{"app", "a.solver.json", "--item", "1", "2", "--item", "3"} ); - status *= argsAreBad(CommandLine{"app", "a.solver.json", "--item", "--flag"}); - status *= argsAreBad(CommandLine{"app", "a.solver.json", "--flag", "--flag"}); + status *= + argsAreBad(CommandLine{"app", "a.solver.json", "--item", "--flag"}); + status *= + argsAreBad(CommandLine{"app", "a.solver.json", "--flag", "--flag"}); status *= throws( [] { diff --git a/tests/UnitTests/Utilities/LoggerTests.hpp b/tests/UnitTests/Utilities/LoggerTests.hpp index a3c674e688..4a60a417ec 100644 --- a/tests/UnitTests/Utilities/LoggerTests.hpp +++ b/tests/UnitTests/Utilities/LoggerTests.hpp @@ -130,8 +130,8 @@ namespace GridKit * * This method tests streaming messages to `Logger::error()` data * stream. The method streams messages to all available output streams, - * however only messages streamed to the error, warning, and result summary - * streams should be logged. + * however only messages streamed to the error, warning, and result + * summary streams should be logged. */ TestOutcome summaryOutput() { @@ -139,7 +139,8 @@ namespace GridKit std::string s1("Test error output ...\n"); std::string s2("Test warning output ...\n"); std::string s3("Test summary output ...\n"); - std::string answer = error_text() + s1 + warning_text() + s2 + summary_ + s3; + std::string answer = + error_text() + s1 + warning_text() + s2 + summary_ + s3; TestStatus status; @@ -172,7 +173,8 @@ namespace GridKit std::string s2("Test warning output ...\n"); std::string s3("Test summary output ...\n"); std::string s4("Test any other output ...\n"); - std::string answer = error_text() + s1 + warning_text() + s2 + summary_ + s3 + message_ + s4; + std::string answer = error_text() + s1 + warning_text() + s2 + summary_ + + s3 + message_ + s4; TestStatus status;