From 6948c35bebaa7cb564167139f0118c38c458e864 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Mon, 3 Mar 2025 21:48:16 -0600 Subject: [PATCH 1/8] Update clang-format rules. --- .clang-format | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..c89dd8f7 --- /dev/null +++ b/.clang-format @@ -0,0 +1,72 @@ +--- +Language: Cpp +BasedOnStyle: Microsoft + +# Indentation +IndentWidth: 2 # 2 spaces per indent +AccessModifierOffset: -2 +IndentAccessModifiers: false # Align access modifiers to braces +NamespaceIndentation: All # Indent namspace contents +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 + AcrossEmptyLines: false + AcrossComments: true + AlignCompound: true + PadOperators: true +AlignConsecutiveBitFields: + Enabled: true + AcrossEmptyLines: false + AcrossComments: true +AlignConsecutiveDeclarations: + Enabled: true + AcrossEmptyLines: false + AcrossComments: true + # For future versions of clang-format + # AlignFunctionDeclarations: false + # AlignFunctionPointers: false +AlignConsecutiveMacros: + Enabled: true + AcrossEmptyLines: false + AcrossComments: true + +# Newlines +ColumnLimit: 0 +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 +AllowShortBlocksOnASingleLine: Never +# On a newer version of clang-format, replace with BinPackArguments: OnePerLine +BinPackArguments: false # Don't allow multiple function arguments on the same line unless they all fit +BinPackParameters: false # Same but for parameters +PackConstructorInitializers: NextLine +AllowShortFunctionsOnASingleLine: None +BreakBeforeBinaryOperators: NonAssignment # Put binary operators after a line break, rather than before +AllowShortIfStatementsOnASingleLine: Never + +# Spaces +SpaceBeforeParens: ControlStatementsExceptControlMacros +SpaceAfterCStyleCast: true +PointerAlignment: Left + +# Includes +IncludeBlocks: Regroup # Regroup includes based on config +IncludeCategories: + - Regex: '(^"|\.hpp)' # 'local' includes + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '\/' # Library includes + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' # Everything else + Priority: 1 + SortPriority: 0 + CaseSensitive: false \ No newline at end of file From 7ed5d726a9d29d5ba811bab63deaf7692e3be46a Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Mon, 3 Mar 2025 23:23:31 -0600 Subject: [PATCH 2/8] Add pre-commit hooks. --- .github/workflows/pre_commit.yaml | 22 ++++++++++++++++++++++ .pre-commit-config.yaml | 12 ++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 .github/workflows/pre_commit.yaml create mode 100644 .pre-commit-config.yaml diff --git a/.github/workflows/pre_commit.yaml b/.github/workflows/pre_commit.yaml new file mode 100644 index 00000000..a6ecfed8 --- /dev/null +++ b/.github/workflows/pre_commit.yaml @@ -0,0 +1,22 @@ +name: gridkit-bot pre-commit + +# Won't run on develop/main directly +on: [pull_request] + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.ref }} + - uses: actions/setup-python@v5.4.0 + - uses: pre-commit/action@v3.0.1 + - uses: EndBug/add-and-commit@v9.1.4 + # Only need to try and commit if the action failed + if: failure() + with: + fetch: false + committer_name: GitHub Actions + committer_email: actions@github.com + message: Apply pre-commmit fixes diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..eda93831 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,12 @@ +repos: + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v19.1.7 + hooks: + - id: clang-format + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: check-toml + - id: forbid-new-submodules + - id: end-of-file-fixer + - id: check-yaml From ea2bf8cccc1a0ffbb429a7fb5a33b78c378c9482 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Mon, 3 Mar 2025 23:29:41 -0600 Subject: [PATCH 3/8] Update CONTRIBUTING.md. --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6f6916d1..c9134cd6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -115,7 +115,7 @@ int & n; // No, the reference symbol is a part of `int&` type ``` ### Indentation -Use only spaces for indentation, not tabs. Indent size is 4 spaces. +Use only spaces for indentation, not tabs. Indent size is 2 spaces. When defining a class, the code blocks after `private`, `public` and `protected` should be aligned with opening/closing braces. There should be an empty line @@ -138,7 +138,7 @@ protected: ### Braces All braces should follow Allman style: ```c++ -namespace someNamespace +namespace SomeNamespace { //some code } From 3b9b82a219052174539d2244d776801cc8f26799 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Mon, 3 Mar 2025 23:31:02 -0600 Subject: [PATCH 4/8] Reformatted code per style guidelines. --- .../AdjointSensitivity/AdjointSensitivity.cpp | 198 ++- examples/DistributedGeneratorTest/DGTest.cpp | 125 +- .../DynamicConstrainedOpt.cpp | 281 ++--- .../Enzyme/Library/Scalar/EnzymeScalar.cpp | 39 +- .../Enzyme/Library/Scalar/EnzymeWrapper.hpp | 10 +- .../Enzyme/Library/Scalar/ScalarModel.cpp | 41 +- .../Enzyme/Library/Scalar/ScalarModel.hpp | 22 +- .../Enzyme/Library/Vector/EnzymeVector.cpp | 114 +- .../Enzyme/Library/Vector/EnzymeWrapper.hpp | 6 +- .../Enzyme/Library/Vector/VectorModel.cpp | 103 +- .../Enzyme/Library/Vector/VectorModel.hpp | 26 +- examples/Enzyme/PowerElectronics/main.cpp | 320 ++--- examples/Enzyme/Standalone/EnzymeScalar.cpp | 35 +- examples/Enzyme/Standalone/EnzymeVector.cpp | 171 ++- examples/GenConstLoad/GenConstLoad.cpp | 227 ++-- examples/GenInfiniteBus/GenInfiniteBus.cpp | 293 +++-- examples/Grid3Bus/Grid3BusSys.cpp | 528 ++++---- .../LinearAlgebra/DenseTest/DenseTest.cpp | 28 +- .../LinearAlgebra/SparseTest/SparseTest.cpp | 150 +-- .../MatPowerTesting/test_parse_branch_row.cpp | 19 +- .../MatPowerTesting/test_parse_bus_row.cpp | 41 +- .../MatPowerTesting/test_parse_gen_row.cpp | 28 +- .../test_parse_gencost_row.cpp | 25 +- .../MatPowerTesting/test_parse_matpower.cpp | 59 +- examples/Microgrid/Microgrid.cpp | 846 +++++++------ .../ParameterEstimation.cpp | 293 +++-- examples/ParameterEstimation/lookup_table.hpp | 2 +- examples/RLCircuit/RLCircuit.cpp | 258 ++-- examples/ScaleMicrogrid/ScaleMicrogrid.cpp | 658 +++++----- examples/ScaleMicrogrid/SolutionKeys.hpp | 29 +- src/CircuitGraph.hpp | 78 +- src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp | 369 +++--- src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp | 1067 ++++++++--------- .../SparsityPattern/Variable.hpp | 519 ++++---- .../VariableImplementation.hpp | 204 ++-- .../SparsityPattern/VariableOperators.hpp | 245 ++-- src/Model/Evaluator.hpp | 120 +- src/Model/PhasorDynamics/Branch/Branch.cpp | 159 +-- src/Model/PhasorDynamics/Branch/Branch.hpp | 246 ++-- src/Model/PhasorDynamics/Bus/Bus.cpp | 421 ++++--- src/Model/PhasorDynamics/Bus/Bus.hpp | 243 ++-- src/Model/PhasorDynamics/Bus/BusInfinite.cpp | 387 +++--- src/Model/PhasorDynamics/Bus/BusInfinite.hpp | 255 ++-- src/Model/PhasorDynamics/BusBase.hpp | 510 ++++---- src/Model/PhasorDynamics/Component.hpp | 466 +++---- src/Model/PhasorDynamics/Load/Load.cpp | 111 +- src/Model/PhasorDynamics/Load/Load.hpp | 158 +-- .../SynchronousMachine/SynchronousMachine.cpp | 109 +- .../SynchronousMachine/SynchronousMachine.hpp | 178 +-- src/Model/PhasorDynamics/SystemModel.hpp | 953 ++++++++------- .../PowerElectronics/Capacitor/Capacitor.cpp | 216 ++-- .../PowerElectronics/Capacitor/Capacitor.hpp | 96 +- .../PowerElectronics/CircuitComponent.hpp | 548 ++++----- .../DistributedGenerator.cpp | 461 +++---- .../DistributedGenerator.hpp | 169 ++- .../InductionMotor/InductionMotor.cpp | 238 ++-- .../InductionMotor/InductionMotor.hpp | 110 +- .../PowerElectronics/Inductor/Inductor.cpp | 214 ++-- .../PowerElectronics/Inductor/Inductor.hpp | 98 +- .../LinearTransformer/LinearTransformer.cpp | 199 ++- .../LinearTransformer/LinearTransformer.hpp | 104 +- .../MicrogridBusDQ/MicrogridBusDQ.cpp | 213 ++-- .../MicrogridBusDQ/MicrogridBusDQ.hpp | 96 +- .../MicrogridLine/MicrogridLine.cpp | 253 ++-- .../MicrogridLine/MicrogridLine.hpp | 97 +- .../MicrogridLoad/MicrogridLoad.cpp | 245 ++-- .../MicrogridLoad/MicrogridLoad.hpp | 98 +- .../PowerElectronics/Resistor/Resistor.cpp | 187 ++- .../PowerElectronics/Resistor/Resistor.hpp | 97 +- .../SynchronousMachine/SynchronousMachine.cpp | 273 ++--- .../SynchronousMachine/SynchronousMachine.hpp | 121 +- .../SystemModelPowerElectronics.hpp | 603 +++++----- .../TransmissionLine/TransmissionLine.cpp | 305 +++-- .../TransmissionLine/TransmissionLine.hpp | 113 +- .../VoltageSource/VoltageSource.cpp | 178 ++- .../VoltageSource/VoltageSource.hpp | 98 +- src/Model/PowerFlow/Branch/Branch.cpp | 257 ++-- src/Model/PowerFlow/Branch/Branch.hpp | 256 ++-- src/Model/PowerFlow/Bus/BaseBus.hpp | 220 ++-- src/Model/PowerFlow/Bus/BusFactory.hpp | 61 +- src/Model/PowerFlow/Bus/BusPQ.cpp | 211 ++-- src/Model/PowerFlow/Bus/BusPQ.hpp | 254 ++-- src/Model/PowerFlow/Bus/BusPV.cpp | 203 ++-- src/Model/PowerFlow/Bus/BusPV.hpp | 281 +++-- src/Model/PowerFlow/Bus/BusSlack.cpp | 121 +- src/Model/PowerFlow/Bus/BusSlack.hpp | 265 ++-- .../PowerFlow/Generator/GeneratorBase.hpp | 149 ++- .../PowerFlow/Generator/GeneratorFactory.hpp | 64 +- src/Model/PowerFlow/Generator/GeneratorPQ.cpp | 165 ++- src/Model/PowerFlow/Generator/GeneratorPQ.hpp | 126 +- src/Model/PowerFlow/Generator/GeneratorPV.cpp | 165 ++- src/Model/PowerFlow/Generator/GeneratorPV.hpp | 132 +- .../PowerFlow/Generator/GeneratorSlack.cpp | 163 ++- .../PowerFlow/Generator/GeneratorSlack.hpp | 127 +- src/Model/PowerFlow/Generator2/Generator2.cpp | 243 ++-- src/Model/PowerFlow/Generator2/Generator2.hpp | 179 +-- src/Model/PowerFlow/Generator4/Generator4.cpp | 502 ++++---- src/Model/PowerFlow/Generator4/Generator4.hpp | 373 +++--- .../Generator4Governor/Generator4Governor.cpp | 673 +++++------ .../Generator4Governor/Generator4Governor.hpp | 497 ++++---- .../Generator4Param/Generator4Param.cpp | 610 +++++----- .../Generator4Param/Generator4Param.hpp | 408 +++---- src/Model/PowerFlow/Load/Load.cpp | 189 ++- src/Model/PowerFlow/Load/Load.hpp | 110 +- src/Model/PowerFlow/MiniGrid/MiniGrid.cpp | 139 ++- src/Model/PowerFlow/MiniGrid/MiniGrid.hpp | 181 +-- src/Model/PowerFlow/ModelEvaluatorImpl.hpp | 488 ++++---- src/Model/PowerFlow/SystemModel.hpp | 778 ++++++------ src/Model/PowerFlow/SystemModelPowerFlow.hpp | 319 ++--- src/PowerSystemData.hpp | 436 +++---- src/ScalarTraits.hpp | 24 +- src/Solver/Dynamic/DynamicSolver.hpp | 102 +- src/Solver/Dynamic/Ida.cpp | 941 +++++++-------- src/Solver/Dynamic/Ida.hpp | 336 +++--- src/Solver/Optimization/DynamicConstraint.cpp | 321 +++-- src/Solver/Optimization/DynamicConstraint.hpp | 168 ++- src/Solver/Optimization/DynamicObjective.cpp | 269 ++--- src/Solver/Optimization/DynamicObjective.hpp | 160 ++- .../Optimization/OptimizationSolver.hpp | 38 +- src/Solver/SteadyState/Kinsol.cpp | 327 +++-- src/Solver/SteadyState/Kinsol.hpp | 284 +++-- src/Solver/SteadyState/SteadyStateSolver.hpp | 102 +- src/Utilities/FileIO.hpp | 601 +++++----- src/Utilities/TestHelpers.hpp | 380 +++--- src/Utilities/Testing.hpp | 346 +++--- .../UnitTests/PhasorDynamics/BranchTests.hpp | 246 ++-- tests/UnitTests/PhasorDynamics/BusTests.hpp | 176 ++- tests/UnitTests/PhasorDynamics/LoadTests.hpp | 80 +- .../SynchronousMachineTests.hpp | 72 +- .../UnitTests/PhasorDynamics/SystemTests.hpp | 120 +- .../PhasorDynamics/runBranchTests.cpp | 16 +- .../UnitTests/PhasorDynamics/runBusTests.cpp | 14 +- .../UnitTests/PhasorDynamics/runLoadTests.cpp | 14 +- .../runSynchronousMachineTests.cpp | 16 +- .../PhasorDynamics/runSystemTests.cpp | 14 +- .../SparsityPattern/SparsityPatternTests.hpp | 139 +-- .../runSparsityPatternTests.cpp | 12 +- 137 files changed, 15934 insertions(+), 15932 deletions(-) diff --git a/examples/AdjointSensitivity/AdjointSensitivity.cpp b/examples/AdjointSensitivity/AdjointSensitivity.cpp index 07af5351..e44ba6c2 100644 --- a/examples/AdjointSensitivity/AdjointSensitivity.cpp +++ b/examples/AdjointSensitivity/AdjointSensitivity.cpp @@ -57,9 +57,8 @@ * */ - -#include #include +#include #include #include @@ -79,124 +78,123 @@ */ int main() { - using namespace GridKit; - using namespace AnalysisManager::Sundials; - using namespace AnalysisManager; - using namespace GridKit::Testing; - - // Create an infinite bus - BaseBus* bus = new BusSlack(1.0, 0.0); - - // Attach a generator to that bus - Generator4* gen = new Generator4(bus, 0.8, 0.3); + using namespace GridKit; + using namespace AnalysisManager::Sundials; + using namespace AnalysisManager; + using namespace GridKit::Testing; - // Create a system model - SystemModel* model = new SystemModel(); - model->addBus(bus); - model->addComponent(gen); + // Create an infinite bus + BaseBus* bus = new BusSlack(1.0, 0.0); - // allocate model components - model->allocate(); + // Attach a generator to that bus + Generator4* gen = new Generator4(bus, 0.8, 0.3); - // Create numerical integrator and configure it for the generator model - Ida* idas = new Ida(model); + // Create a system model + SystemModel* model = new SystemModel(); + model->addBus(bus); + model->addComponent(gen); - double t_init = 0.0; - double t_final = 15.0; + // allocate model components + model->allocate(); - // setup simulation - idas->configureSimulation(); - idas->configureAdjoint(); - idas->getDefaultInitialCondition(); - idas->initializeSimulation(t_init); - idas->configureQuadrature(); - idas->initializeQuadrature(); + // Create numerical integrator and configure it for the generator model + Ida* idas = new Ida(model); + double t_init = 0.0; + double t_final = 15.0; - idas->runSimulation(0.1, 2); - idas->saveInitialCondition(); + // setup simulation + idas->configureSimulation(); + idas->configureAdjoint(); + idas->getDefaultInitialCondition(); + idas->initializeSimulation(t_init); + idas->configureQuadrature(); + idas->initializeQuadrature(); - // create initial condition after a fault - { - idas->getSavedInitialCondition(); - idas->initializeSimulation(t_init); - gen->V() = 0.0; - idas->runSimulation(0.1, 20); - gen->V() = 1.0; - idas->saveInitialCondition(); - } + idas->runSimulation(0.1, 2); + idas->saveInitialCondition(); - // Get pointer the objective function - const double* Q = idas->getIntegral(); - - // Compute the objective function as an integral over the system trajectory + // create initial condition after a fault + { idas->getSavedInitialCondition(); idas->initializeSimulation(t_init); - idas->initializeQuadrature(); - idas->runSimulationQuadrature(t_final, 100); - - std::cout << "\n\nCost of computing objective function:\n\n"; - idas->printFinalStats(); - - const double g1 = Q[0]; - const double eps = 2e-3; + gen->V() = 0.0; + idas->runSimulation(0.1, 20); + gen->V() = 1.0; + idas->saveInitialCondition(); + } - // Compute gradient of the objective function numerically - std::vector dGdp(model->sizeParams()); + // Get pointer the objective function + const double* Q = idas->getIntegral(); - for (unsigned i=0; isizeParams(); ++i) - { - model->param()[i] += eps; - idas->getSavedInitialCondition(); - idas->initializeSimulation(t_init); - idas->initializeQuadrature(); - idas->runSimulationQuadrature(t_final,100); + // Compute the objective function as an integral over the system trajectory + idas->getSavedInitialCondition(); + idas->initializeSimulation(t_init); + idas->initializeQuadrature(); + idas->runSimulationQuadrature(t_final, 100); - std::cout << "\n\nCost of computing derivative with respect to parameter " - << i << ":\n\n"; - idas->printFinalStats(); - double g2 = Q[0]; + std::cout << "\n\nCost of computing objective function:\n\n"; + idas->printFinalStats(); - // restore parameter to original value - model->param()[i] -= eps; + const double g1 = Q[0]; + const double eps = 2e-3; - // Evaluate dG/dp numerically - dGdp[i] = (g2 - g1)/eps; - } + // Compute gradient of the objective function numerically + std::vector dGdp(model->sizeParams()); - // Compute gradient of the objective function using adjoint method - idas->initializeAdjoint(); + for (unsigned i = 0; i < model->sizeParams(); ++i) + { + model->param()[i] += eps; idas->getSavedInitialCondition(); idas->initializeSimulation(t_init); idas->initializeQuadrature(); - idas->runForwardSimulation(t_final, 100); - - std::cout << "\n\nCost of forward simulation for adjoint\n" - << "sensitivity analysis:\n\n"; - idas->printFinalStats(); - - idas->initializeBackwardSimulation(t_final); - idas->runBackwardSimulation(t_init); + idas->runSimulationQuadrature(t_final, 100); - std::cout << "\n\nCost of adjoint sensitivity analysis:\n\n"; + std::cout << "\n\nCost of computing derivative with respect to parameter " + << i << ":\n\n"; idas->printFinalStats(); - - // Compare results - int retval = 0; - std::cout << "\n\nComparison of numerical and adjoint results:\n\n"; - double* neg_dGdp = idas->getAdjointIntegral(); - for (unsigned i=0; isizeParams(); ++i) - { - std::cout << "dG/dp" << i << " (numerical) = " << dGdp[i] << "\n"; - std::cout << "dG/dp" << i << " (adjoint) = " << -neg_dGdp[i] << "\n\n"; - if(!isEqual(dGdp[i], -neg_dGdp[i], 10*eps)) - --retval; - } - - if(retval < 0) - { - std::cout << "The two results differ beyond solver tolerance!\n"; - } - - return retval; + double g2 = Q[0]; + + // restore parameter to original value + model->param()[i] -= eps; + + // Evaluate dG/dp numerically + dGdp[i] = (g2 - g1) / eps; + } + + // Compute gradient of the objective function using adjoint method + idas->initializeAdjoint(); + idas->getSavedInitialCondition(); + idas->initializeSimulation(t_init); + idas->initializeQuadrature(); + idas->runForwardSimulation(t_final, 100); + + std::cout << "\n\nCost of forward simulation for adjoint\n" + << "sensitivity analysis:\n\n"; + idas->printFinalStats(); + + idas->initializeBackwardSimulation(t_final); + idas->runBackwardSimulation(t_init); + + std::cout << "\n\nCost of adjoint sensitivity analysis:\n\n"; + idas->printFinalStats(); + + // Compare results + int retval = 0; + std::cout << "\n\nComparison of numerical and adjoint results:\n\n"; + double* neg_dGdp = idas->getAdjointIntegral(); + for (unsigned i = 0; i < model->sizeParams(); ++i) + { + std::cout << "dG/dp" << i << " (numerical) = " << dGdp[i] << "\n"; + std::cout << "dG/dp" << i << " (adjoint) = " << -neg_dGdp[i] << "\n\n"; + if (!isEqual(dGdp[i], -neg_dGdp[i], 10 * eps)) + --retval; + } + + if (retval < 0) + { + std::cout << "The two results differ beyond solver tolerance!\n"; + } + + return retval; } diff --git a/examples/DistributedGeneratorTest/DGTest.cpp b/examples/DistributedGeneratorTest/DGTest.cpp index 2c35ec7d..10e10c58 100644 --- a/examples/DistributedGeneratorTest/DGTest.cpp +++ b/examples/DistributedGeneratorTest/DGTest.cpp @@ -1,85 +1,84 @@ -#include -#include #include -#include #include +#include +#include +#include #include #include - /** * @brief Testing for the Distributed Generators outputs - * - * @param argc - * @param argv - * @return int + * + * @param argc + * @param argv + * @return int */ -int main(int argc, char const *argv[]) +int main(int argc, char const* argv[]) { - - GridKit::DistributedGeneratorParameters parms; - //Parameters from MATLAB Microgrid code for first DG - parms.wb_ = 2.0*M_PI*50.0; - parms.wc_ = 31.41; - parms.mp_ = 9.4e-5; - parms.Vn_ = 380; - parms.nq_ = 1.3e-3; - parms.F_ = 0.75; - parms.Kiv_ = 420.0; - parms.Kpv_ = 0.1; - parms.Kic_ = 20.0 * 1.0e3; - parms.Kpc_ = 15.0; - parms.Cf_ = 50.0e-6; - parms.rLf_ = 0.1; - parms.Lf_ = 1.35e-3; - parms.rLc_ = 0.03; - parms.Lc_ = 0.35e-3; - GridKit::DistributedGenerator *dg = new GridKit::DistributedGenerator(0, parms, true); + GridKit::DistributedGeneratorParameters parms; + // Parameters from MATLAB Microgrid code for first DG + parms.wb_ = 2.0 * M_PI * 50.0; + parms.wc_ = 31.41; + parms.mp_ = 9.4e-5; + parms.Vn_ = 380; + parms.nq_ = 1.3e-3; + parms.F_ = 0.75; + parms.Kiv_ = 420.0; + parms.Kpv_ = 0.1; + parms.Kic_ = 20.0 * 1.0e3; + parms.Kpc_ = 15.0; + parms.Cf_ = 50.0e-6; + parms.rLf_ = 0.1; + parms.Lf_ = 1.35e-3; + parms.rLc_ = 0.03; + parms.Lc_ = 0.35e-3; + + GridKit::DistributedGenerator* dg = new GridKit::DistributedGenerator(0, parms, true); - std::vector t1(16,0.0); - std::vector t2{0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,1.3,1.4,1.5}; + std::vector t1(16, 0.0); + std::vector t2{0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5}; - dg->allocate(); + dg->allocate(); - dg->y() = t2; - dg->yp() = t1; + dg->y() = t2; + dg->yp() = t1; - dg->evaluateResidual(); + dg->evaluateResidual(); - std::cout << "Output: {"; - for (double i : dg->getResidual()) - { - printf("%e ,", i); - } - std::cout << "}\n"; + std::cout << "Output: {"; + for (double i : dg->getResidual()) + { + printf("%e ,", i); + } + std::cout << "}\n"; - //Generated from matlab code with same parameters and inputs - std::vector true_vec{3.141592277589793e+02, - 8.941907747838389e-01, - 1.846733023014284e+00, - 3.141592277589793e+02, - 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}; + // Generated from matlab code with same parameters and inputs + std::vector true_vec{3.141592277589793e+02, + 8.941907747838389e-01, + 1.846733023014284e+00, + 3.141592277589793e+02, + 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 << "Test the Relative Error\n"; - for (size_t i = 0; i < true_vec.size(); i++) - { - printf("%e ,\n", (true_vec[i] - dg->getResidual()[i]) / true_vec[i]); - } + std::cout << "Test the Relative Error\n"; + for (size_t i = 0; i < true_vec.size(); i++) + { + printf("%e ,\n", (true_vec[i] - dg->getResidual()[i]) / true_vec[i]); + } - return 0; + return 0; } diff --git a/examples/DynamicConstrainedOpt/DynamicConstrainedOpt.cpp b/examples/DynamicConstrainedOpt/DynamicConstrainedOpt.cpp index 3d07650c..1cb1696e 100644 --- a/examples/DynamicConstrainedOpt/DynamicConstrainedOpt.cpp +++ b/examples/DynamicConstrainedOpt/DynamicConstrainedOpt.cpp @@ -57,155 +57,156 @@ * */ - -#include #include +#include +#include +#include #include #include #include #include - -#include -#include -#include #include +#include #include int main() { - using namespace GridKit; - using namespace AnalysisManager::Sundials; - using namespace AnalysisManager; - using namespace GridKit::Testing; - - // Create an infinite bus - BaseBus* bus = new BusSlack(1.0, 0.0); - - // Attach a generator to that bus - Generator2* gen = new Generator2(bus); - - // Create a system model - SystemModel* model = new SystemModel(); - model->addBus(bus); - model->addComponent(gen); - - // allocate model components - model->allocate(); - - // Create numerical integrator and configure it for the generator model - Ida* idas = new Ida(model); - - double t_init = 0.0; - double t_final = 20.0; - - // setup simulation - idas->configureSimulation(); - idas->configureAdjoint(); - idas->getDefaultInitialCondition(); - idas->initializeSimulation(t_init); - idas->configureQuadrature(); - idas->initializeQuadrature(); - - double t_fault = 0.02; - double t_clear = 0.06; - idas->runSimulation(t_fault); - // create initial condition after a fault - { - gen->V() = 0.0; - idas->runSimulation(t_clear, 2); - gen->V() = 1.0; - gen->theta() = -0.01; - idas->saveInitialCondition(); - } - - // Set integration time for dynamic constrained optimization - idas->setIntegrationTime(t_init, t_final, 100); - - // Guess optimization parameter value - double Pm = 0.7; - - // Create an instance of the IpoptApplication - Ipopt::SmartPtr ipoptApp = IpoptApplicationFactory(); - - // Initialize the IpoptApplication and process the options - Ipopt::ApplicationReturnStatus status; - status = ipoptApp->Initialize(); - if (status != Ipopt::Solve_Succeeded) { - std::cout << "\n\n*** Initialization failed! ***\n\n"; - return (int) status; - } - - // Set solver tolerance - const double tol = 1e-4; - - // Configure Ipopt application - ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); - ipoptApp->Options()->SetNumericValue("tol", tol); - ipoptApp->Options()->SetIntegerValue("print_level", 0); - - // Create dynamic objective interface to Ipopt solver - Ipopt::SmartPtr ipoptDynamicObjectiveInterface = - new IpoptInterface::DynamicObjective(idas); - - // Initialize problem - model->param()[0] = Pm; - - // Solve the problem - status = ipoptApp->OptimizeTNLP(ipoptDynamicObjectiveInterface); - std::cout << "\n\nProblem formulated as dynamic objective optimization ...\n"; - - if (status == Ipopt::Solve_Succeeded) { - // Print result - std::cout << "\nSucess:\n The problem solved in " - << ipoptApp->Statistics()->IterationCount() << " iterations!\n" - << " Optimal value of Pm = " << model->param()[0] << "\n" - << " The final value of the objective function G(Pm) = " - << ipoptApp->Statistics()->FinalObjective() << "\n\n"; - } - - // Store dynamic objective optimization results - double* results = new double[model->sizeParams()]; - for(unsigned i=0; i sizeParams(); ++i) - { - results[i] = model->param()[i]; - } - - // Create dynamic constraint interface to Ipopt solver - Ipopt::SmartPtr ipoptDynamicConstraintInterface = - new IpoptInterface::DynamicConstraint(idas); - - // Initialize problem - model->param()[0] = Pm; - - // Solve the problem - status = ipoptApp->OptimizeTNLP(ipoptDynamicConstraintInterface); - std::cout << "\n\nProblem formulated as dynamic constraint optimization ...\n"; - - if (status == Ipopt::Solve_Succeeded) { - // Print result - std::cout << "\nSucess:\n The problem solved in " - << ipoptApp->Statistics()->IterationCount() << " iterations!\n" - << " Optimal value of Pm = " << model->param()[0] << "\n" - << " The final value of the objective function G(Pm) = " - << ipoptApp->Statistics()->FinalObjective() << "\n\n"; - } - - // Compare results of the two optimization methods - int retval = 0; - for(unsigned i=0; i sizeParams(); ++i) - { - if(!isEqual(results[i], model->param()[i], 10*tol)) - --retval; - } - - if(retval < 0) - { - std::cout << "The two results differ beyond solver tolerance!\n"; - } - - delete [] results; - delete idas; - delete model; - return retval; + using namespace GridKit; + using namespace AnalysisManager::Sundials; + using namespace AnalysisManager; + using namespace GridKit::Testing; + + // Create an infinite bus + BaseBus* bus = new BusSlack(1.0, 0.0); + + // Attach a generator to that bus + Generator2* gen = new Generator2(bus); + + // Create a system model + SystemModel* model = new SystemModel(); + model->addBus(bus); + model->addComponent(gen); + + // allocate model components + model->allocate(); + + // Create numerical integrator and configure it for the generator model + Ida* idas = new Ida(model); + + double t_init = 0.0; + double t_final = 20.0; + + // setup simulation + idas->configureSimulation(); + idas->configureAdjoint(); + idas->getDefaultInitialCondition(); + idas->initializeSimulation(t_init); + idas->configureQuadrature(); + idas->initializeQuadrature(); + + double t_fault = 0.02; + double t_clear = 0.06; + idas->runSimulation(t_fault); + // create initial condition after a fault + { + gen->V() = 0.0; + idas->runSimulation(t_clear, 2); + gen->V() = 1.0; + gen->theta() = -0.01; + idas->saveInitialCondition(); + } + + // Set integration time for dynamic constrained optimization + idas->setIntegrationTime(t_init, t_final, 100); + + // Guess optimization parameter value + double Pm = 0.7; + + // Create an instance of the IpoptApplication + Ipopt::SmartPtr ipoptApp = IpoptApplicationFactory(); + + // Initialize the IpoptApplication and process the options + Ipopt::ApplicationReturnStatus status; + status = ipoptApp->Initialize(); + if (status != Ipopt::Solve_Succeeded) + { + std::cout << "\n\n*** Initialization failed! ***\n\n"; + return (int) status; + } + + // Set solver tolerance + const double tol = 1e-4; + + // Configure Ipopt application + ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); + ipoptApp->Options()->SetNumericValue("tol", tol); + ipoptApp->Options()->SetIntegerValue("print_level", 0); + + // Create dynamic objective interface to Ipopt solver + Ipopt::SmartPtr ipoptDynamicObjectiveInterface = + new IpoptInterface::DynamicObjective(idas); + + // Initialize problem + model->param()[0] = Pm; + + // Solve the problem + status = ipoptApp->OptimizeTNLP(ipoptDynamicObjectiveInterface); + std::cout << "\n\nProblem formulated as dynamic objective optimization ...\n"; + + if (status == Ipopt::Solve_Succeeded) + { + // Print result + std::cout << "\nSucess:\n The problem solved in " + << ipoptApp->Statistics()->IterationCount() << " iterations!\n" + << " Optimal value of Pm = " << model->param()[0] << "\n" + << " The final value of the objective function G(Pm) = " + << ipoptApp->Statistics()->FinalObjective() << "\n\n"; + } + + // Store dynamic objective optimization results + double* results = new double[model->sizeParams()]; + for (unsigned i = 0; i < model->sizeParams(); ++i) + { + results[i] = model->param()[i]; + } + + // Create dynamic constraint interface to Ipopt solver + Ipopt::SmartPtr ipoptDynamicConstraintInterface = + new IpoptInterface::DynamicConstraint(idas); + + // Initialize problem + model->param()[0] = Pm; + + // Solve the problem + status = ipoptApp->OptimizeTNLP(ipoptDynamicConstraintInterface); + std::cout << "\n\nProblem formulated as dynamic constraint optimization ...\n"; + + if (status == Ipopt::Solve_Succeeded) + { + // Print result + std::cout << "\nSucess:\n The problem solved in " + << ipoptApp->Statistics()->IterationCount() << " iterations!\n" + << " Optimal value of Pm = " << model->param()[0] << "\n" + << " The final value of the objective function G(Pm) = " + << ipoptApp->Statistics()->FinalObjective() << "\n\n"; + } + + // Compare results of the two optimization methods + int retval = 0; + for (unsigned i = 0; i < model->sizeParams(); ++i) + { + if (!isEqual(results[i], model->param()[i], 10 * tol)) + --retval; + } + + if (retval < 0) + { + std::cout << "The two results differ beyond solver tolerance!\n"; + } + + delete[] results; + delete idas; + delete model; + return retval; } diff --git a/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp b/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp index abc1a9d0..a20f69e1 100644 --- a/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp +++ b/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp @@ -1,32 +1,33 @@ #include #include + #include "ScalarModel.hpp" /** - * @brief Example that computes the derivative of a library function + * @brief Example that computes the derivative of a library function * (implemented as the member function of a class and operating directly on class members) * by automatic differentiation via Enzyme. * * TODO: Convert this into a unit test. */ -int main() +int main() { - int fail = 0; - ScalarModel scalar_model; - double var = 5.0; - scalar_model.setVariable(var); - scalar_model.evalFunction(); - scalar_model.evalDerivative(); - double sq = scalar_model.getFunctionValue(); - double dsq = scalar_model.getDerivativeValue(); - - std::cout << "x = " << var << ", x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; - if (std::abs(dsq - 2.0*var) > std::numeric_limits::epsilon()) - { - fail++; - std::cout << "Result incorrect\n"; - } - std::cout << "Status: " << fail << "\n"; - return fail; + int fail = 0; + ScalarModel scalar_model; + double var = 5.0; + scalar_model.setVariable(var); + scalar_model.evalFunction(); + scalar_model.evalDerivative(); + double sq = scalar_model.getFunctionValue(); + double dsq = scalar_model.getDerivativeValue(); + + std::cout << "x = " << var << ", x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; + if (std::abs(dsq - 2.0 * var) > std::numeric_limits::epsilon()) + { + fail++; + std::cout << "Result incorrect\n"; + } + std::cout << "Status: " << fail << "\n"; + return fail; } diff --git a/examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp b/examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp index 8e659dea..57d58270 100644 --- a/examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp +++ b/examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp @@ -5,12 +5,12 @@ int enzyme_dupnoneed; int enzyme_out; int enzyme_const; -template -return_type __enzyme_fwddiff(return_type*, int, T* ... ); +template +return_type __enzyme_fwddiff(return_type*, int, T*...); template -return_type wrapper(T* obj) +return_type wrapper(T* obj) { - obj->evalFunction(); - return obj->getFunctionValue(); + obj->evalFunction(); + return obj->getFunctionValue(); } diff --git a/examples/Enzyme/Library/Scalar/ScalarModel.cpp b/examples/Enzyme/Library/Scalar/ScalarModel.cpp index 06fb9c1b..0d0a790f 100644 --- a/examples/Enzyme/Library/Scalar/ScalarModel.cpp +++ b/examples/Enzyme/Library/Scalar/ScalarModel.cpp @@ -1,49 +1,50 @@ -#include "EnzymeWrapper.hpp" #include "ScalarModel.hpp" + #include -ScalarModel::ScalarModel() +#include "EnzymeWrapper.hpp" + +ScalarModel::ScalarModel() { } -inline -double ScalarModel::square(double x) +inline double ScalarModel::square(double x) { - return x * x; + return x * x; } -void ScalarModel::setVariable(double x) +void ScalarModel::setVariable(double x) { - x_ = x; + x_ = x; } -void ScalarModel::evalFunction() +void ScalarModel::evalFunction() { - f_ = square(x_); + f_ = square(x_); } -void ScalarModel::evalDerivative() +void ScalarModel::evalDerivative() { - ScalarModel d_scalar_model; - d_scalar_model.setVariable(1.0); - df_dx_ = __enzyme_fwddiff((double*)wrapper, enzyme_dup, this, &d_scalar_model); + ScalarModel d_scalar_model; + d_scalar_model.setVariable(1.0); + df_dx_ = __enzyme_fwddiff((double*) wrapper, enzyme_dup, this, &d_scalar_model); } -double ScalarModel::getVariable() const +double ScalarModel::getVariable() const { - return x_; + return x_; } -double ScalarModel::getFunctionValue() const +double ScalarModel::getFunctionValue() const { - return f_; + return f_; } -double ScalarModel::getDerivativeValue() const +double ScalarModel::getDerivativeValue() const { - return df_dx_; + return df_dx_; } -ScalarModel::~ScalarModel() +ScalarModel::~ScalarModel() { } diff --git a/examples/Enzyme/Library/Scalar/ScalarModel.hpp b/examples/Enzyme/Library/Scalar/ScalarModel.hpp index 2632bf59..09150295 100644 --- a/examples/Enzyme/Library/Scalar/ScalarModel.hpp +++ b/examples/Enzyme/Library/Scalar/ScalarModel.hpp @@ -4,19 +4,19 @@ * @brief Class providing methods to evaluate a function and its derivative. * This is used to test automatic differentiation. */ -class ScalarModel +class ScalarModel { private: - double x_, f_, df_dx_; - inline double square(double); + double x_, f_, df_dx_; + inline double square(double); public: - ScalarModel(); - void setVariable(double); - void evalFunction(); - void evalDerivative(); - double getVariable() const; - double getFunctionValue() const; - double getDerivativeValue() const; - ~ScalarModel(); + ScalarModel(); + void setVariable(double); + void evalFunction(); + void evalDerivative(); + double getVariable() const; + double getFunctionValue() const; + double getDerivativeValue() const; + ~ScalarModel(); }; diff --git a/examples/Enzyme/Library/Vector/EnzymeVector.cpp b/examples/Enzyme/Library/Vector/EnzymeVector.cpp index f18ef3e2..8a3e6925 100644 --- a/examples/Enzyme/Library/Vector/EnzymeVector.cpp +++ b/examples/Enzyme/Library/Vector/EnzymeVector.cpp @@ -1,88 +1,88 @@ #include #include + #include "VectorModel.hpp" /** - * @brief Example that computes the Jacobian of a vector-valued residual + * @brief Example that computes the Jacobian of a vector-valued residual * (implemented as the member function of a class and operating directly on class members) * by automatic differentiation via Enzyme. * * TODO: Convert this into a unit test. */ -inline -double dsquare_ref_scalar(double x) +inline double dsquare_ref_scalar(double x) { - return 2.0 * x; + return 2.0 * x; } // Reference Jacobian -DenseMatrix dsquare_ref(std::vector x, std::vector y) +DenseMatrix dsquare_ref(std::vector x, std::vector y) { - DenseMatrix jac(x.size(), y.size()); - for (int idy = 0; idy < y.size(); ++idy) + DenseMatrix jac(x.size(), y.size()); + for (int idy = 0; idy < y.size(); ++idy) + { + for (int idx = 0; idx < x.size(); ++idx) { - for (int idx = 0; idx < x.size(); ++idx) - { - if (idx == idy) - jac.setValue(idx, idy, dsquare_ref_scalar(x[idx])); - } + if (idx == idy) + jac.setValue(idx, idy, dsquare_ref_scalar(x[idx])); } - return jac; + } + return jac; } -int main() +int main() { - // Size and variable declarations - constexpr int n = 10; - std::vector var(n); + // Size and variable declarations + constexpr int n = 10; + std::vector var(n); - // Random input values - srand(time(NULL)); - for (int idx = 0; idx < var.size(); ++idx) - { - var[idx] = rand(); - } + // Random input values + srand(time(NULL)); + for (int idx = 0; idx < var.size(); ++idx) + { + var[idx] = rand(); + } + + // Model + VectorModel* vector_model = new VectorModel(n); + vector_model->setVariable(var); + vector_model->evalResidual(); + vector_model->evalJacobian(); + std::vector var_temp = vector_model->getVariable(); + std::vector res = vector_model->getResidual(); + DenseMatrix jac = vector_model->getJacobian(); - // Model - VectorModel* vector_model = new VectorModel(n); - vector_model->setVariable(var); - vector_model->evalResidual(); - vector_model->evalJacobian(); - std::vector var_temp = vector_model->getVariable(); - std::vector res = vector_model->getResidual(); - DenseMatrix jac = vector_model->getJacobian(); + // Reference Jacobian + DenseMatrix jac_ref = dsquare_ref(var, res); - // Reference Jacobian - DenseMatrix jac_ref = dsquare_ref(var, res); - - // Check - int fail = 0; - bool verbose = true; - for (int idy = 0; idy < res.size(); ++idy) + // Check + int fail = 0; + bool verbose = true; + for (int idy = 0; idy < res.size(); ++idy) + { + for (int idx = 0; idx < var.size(); ++idx) { - for (int idx = 0; idx < var.size(); ++idx) + if (std::abs(jac.getValue(idx, idy) - jac_ref.getValue(idx, idy)) > std::numeric_limits::epsilon()) + { + fail++; + if (verbose) { - if (std::abs(jac.getValue(idx, idy) - jac_ref.getValue(idx, idy)) > std::numeric_limits::epsilon()) - { - fail++; - if (verbose) - { - std::cout << "Result incorrect at line = " << idy << ", column = " << idx << "\n"; - std::cout << "x = " << var_temp[idx] << ", x^2 = " << res[idx] << ", d(x^2)/dx = " << jac.getValue(idx, idy) << "\n"; - } - } + std::cout << "Result incorrect at line = " << idy << ", column = " << idx << "\n"; + std::cout << "x = " << var_temp[idx] << ", x^2 = " << res[idx] << ", d(x^2)/dx = " << jac.getValue(idx, idy) << "\n"; } + } } - if (verbose) - { - jac.printMatrix("Autodiff Jacobian"); - jac_ref.printMatrix("Reference Jacobian"); - } - std::cout << "Status: " << fail << "\n"; + } + if (verbose) + { + jac.printMatrix("Autodiff Jacobian"); + jac_ref.printMatrix("Reference Jacobian"); + } + std::cout << "Status: " << fail << "\n"; - // Cleanup - delete vector_model; + // Cleanup + delete vector_model; - return fail; + return fail; } diff --git a/examples/Enzyme/Library/Vector/EnzymeWrapper.hpp b/examples/Enzyme/Library/Vector/EnzymeWrapper.hpp index 3306ab95..588436f3 100644 --- a/examples/Enzyme/Library/Vector/EnzymeWrapper.hpp +++ b/examples/Enzyme/Library/Vector/EnzymeWrapper.hpp @@ -11,8 +11,8 @@ template std::vector __enzyme_fwddiff(std::vector*, int, T*, T*); template -std::vector wrapper(T* obj) +std::vector wrapper(T* obj) { - obj->evalResidual(); - return obj->getResidual(); + obj->evalResidual(); + return obj->getResidual(); } diff --git a/examples/Enzyme/Library/Vector/VectorModel.cpp b/examples/Enzyme/Library/Vector/VectorModel.cpp index 33f312cc..cb4d89f5 100644 --- a/examples/Enzyme/Library/Vector/VectorModel.cpp +++ b/examples/Enzyme/Library/Vector/VectorModel.cpp @@ -1,84 +1,87 @@ -#include "EnzymeWrapper.hpp" #include "VectorModel.hpp" + #include -VectorModel::VectorModel(int n) : - x_(n), - f_(n), - df_dx_(n, n) +#include "EnzymeWrapper.hpp" + +VectorModel::VectorModel(int n) + : x_(n), + f_(n), + df_dx_(n, n) { } -inline -double VectorModel::square_scalar(double x) +inline double VectorModel::square_scalar(double x) { - return x * x; + return x * x; } -void VectorModel::square(std::vector& x, std::vector& y) +void VectorModel::square(std::vector& x, std::vector& y) { - for (int idx = 0; idx < x.size(); ++idx) - { - y[idx] = this->square_scalar(x[idx]); - } + for (int idx = 0; idx < x.size(); ++idx) + { + y[idx] = this->square_scalar(x[idx]); + } } -void VectorModel::setVariable(std::vector x) +void VectorModel::setVariable(std::vector x) { - for (int idx = 0; idx < x.size(); ++idx) - { - x_[idx] = x[idx]; - } + for (int idx = 0; idx < x.size(); ++idx) + { + x_[idx] = x[idx]; + } } -void VectorModel::evalResidual() +void VectorModel::evalResidual() { - square(x_, f_); + square(x_, f_); } -void VectorModel::evalJacobian() +void VectorModel::evalJacobian() { - const int n = x_.size(); - std::vector v(n); - VectorModel d_vector_model(n); - for (int idy = 0; idy < n; ++idy) + const int n = x_.size(); + std::vector v(n); + VectorModel d_vector_model(n); + for (int idy = 0; idy < n; ++idy) + { + // Elementary vector for Jacobian-vector product + for (int idx = 0; idx < n; ++idx) + { + v[idx] = 0.0; + } + v[idy] = 1.0; + d_vector_model.setVariable(v); + + // Autodiff + std::vector d_res = __enzyme_fwddiff( + (std::vector*) wrapper, + enzyme_dup, + this, + &d_vector_model); + + // Store result + for (int idx = 0; idx < n; ++idx) { - // Elementary vector for Jacobian-vector product - for (int idx = 0; idx < n; ++idx) - { - v[idx] = 0.0; - } - v[idy] = 1.0; - d_vector_model.setVariable(v); - - // Autodiff - std::vector d_res = __enzyme_fwddiff( - (std::vector*)wrapper, - enzyme_dup, this, &d_vector_model); - - // Store result - for (int idx = 0; idx < n; ++idx) - { - df_dx_.setValue(idx, idy, d_res[idx]); - } + df_dx_.setValue(idx, idy, d_res[idx]); } + } } -std::vector& VectorModel::getVariable() +std::vector& VectorModel::getVariable() { - return x_; + return x_; } -std::vector& VectorModel::getResidual() +std::vector& VectorModel::getResidual() { - return f_; + return f_; } -DenseMatrix& VectorModel::getJacobian() +DenseMatrix& VectorModel::getJacobian() { - return df_dx_; + return df_dx_; } -VectorModel::~VectorModel() +VectorModel::~VectorModel() { } diff --git a/examples/Enzyme/Library/Vector/VectorModel.hpp b/examples/Enzyme/Library/Vector/VectorModel.hpp index 5ff5d87e..da66f696 100644 --- a/examples/Enzyme/Library/Vector/VectorModel.hpp +++ b/examples/Enzyme/Library/Vector/VectorModel.hpp @@ -8,21 +8,21 @@ using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; * @brief Class providing methods to evaluate a vector-valued residual and its Jacobian. * This is used to test automatic differentiation. */ -class VectorModel +class VectorModel { private: - std::vector x_, f_; - DenseMatrix df_dx_; - inline double square_scalar(double); - void square(std::vector&, std::vector&); + std::vector x_, f_; + DenseMatrix df_dx_; + inline double square_scalar(double); + void square(std::vector&, std::vector&); public: - VectorModel(int); - void setVariable(std::vector); - void evalResidual(); - void evalJacobian(); - std::vector& getVariable(); - std::vector& getResidual(); - DenseMatrix& getJacobian(); - ~VectorModel(); + VectorModel(int); + void setVariable(std::vector); + void evalResidual(); + void evalJacobian(); + std::vector& getVariable(); + std::vector& getResidual(); + DenseMatrix& getJacobian(); + ~VectorModel(); }; diff --git a/examples/Enzyme/PowerElectronics/main.cpp b/examples/Enzyme/PowerElectronics/main.cpp index b15b62e5..eff14ddb 100644 --- a/examples/Enzyme/PowerElectronics/main.cpp +++ b/examples/Enzyme/PowerElectronics/main.cpp @@ -1,5 +1,6 @@ #include #include + #include #include #include @@ -13,183 +14,186 @@ * TODO: Move automatic differentiation inside GridKit and convert this into a unit test. */ -using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; +using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; using SparseMatrix = COO_Matrix; -using DG = GridKit::DistributedGenerator; +using DG = GridKit::DistributedGenerator; using DGParameters = GridKit::DistributedGeneratorParameters; -int enzyme_dupnoneed; -int enzyme_dup; -int enzyme_const; -void __enzyme_fwddiff(void*, int, std::vector, std::vector, - int, std::vector, std::vector*); +int enzyme_dupnoneed; +int enzyme_dup; +int enzyme_const; +void __enzyme_fwddiff(void*, int, std::vector, std::vector, int, std::vector, std::vector*); // Copy from DistributedGenerator::evaluateResidual // Need to find a way to differentiate the member function directly -void evaluateResidual(std::vector y_, std::vector f_) +void evaluateResidual(std::vector y_, std::vector f_) { - constexpr double wb_ = 2.0*M_PI*50.0; - constexpr double wc_ = 31.41; - constexpr double mp_ = 9.4e-5; - constexpr double Vn_ = 380.0; - constexpr double nq_ = 1.3e-3; - constexpr double F_ = 0.75; - constexpr double Kiv_ = 420.0; - constexpr double Kpv_ = 0.1; - constexpr double Kic_ = 2.0e4; - constexpr double Kpc_ = 15.0; - constexpr double Cf_ = 5.0e-5; - constexpr double rLf_ = 0.1; - constexpr double Lf_ = 1.35e-3; - constexpr double rLc_ = 0.03; - constexpr double Lc_ = 0.35e-3; - - constexpr bool ref_frame_ = true; - - std::vector yp_(0); - - double omega = wb_ - mp_ * y_[4]; - if (ref_frame_) - { - f_[0] = omega - y_[0]; - } - else - { - f_[0] = 0.0; - } - - f_[1] = cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15]; - f_[2] = sin(y_[3]) * y_[14] + cos(y_[3]) * y_[15]; - - double vbd_in = cos(y_[3]) * y_[1] + sin(y_[3]) * y_[2]; - double vbq_in = -sin(y_[3]) * y_[1] + cos(y_[3]) * y_[2]; - - f_[3] = -yp_[3] + omega - y_[0]; - f_[4] = -yp_[4] + wc_ * (y_[12] * y_[14] + y_[13] * y_[15] - y_[4]); - f_[5] = -yp_[5] + wc_ * (-y_[12] * y_[15] + y_[13] * y_[14] - y_[5]); - - double vod_star = Vn_ - nq_ * y_[5]; - double voq_star = 0.0; - - f_[6] = -yp_[6] + vod_star - y_[12]; - f_[7] = -yp_[7] + voq_star - y_[13]; - - double ild_star = F_ * y_[14] - wb_ * Cf_ * y_[13] + Kpv_ * (vod_star - y_[12]) + Kiv_ * y_[6]; - double ilq_star = F_ * y_[15] + wb_ * Cf_ * y_[12] + Kpv_ * (voq_star - y_[13]) + Kiv_ * y_[7]; - - f_[8] = -yp_[8] + ild_star - y_[10]; - f_[9] = -yp_[9] + ilq_star - y_[11]; - - double vid_star = -wb_ * Lf_ * y_[11] + Kpc_ * (ild_star - y_[10]) + Kic_ * y_[8]; - double viq_star = wb_ * Lf_ * y_[10] + Kpc_ * (ilq_star - y_[11]) + Kic_ * y_[9]; - - f_[10] = -yp_[10] - (rLf_ / Lf_) * y_[10] + omega * y_[11] + (vid_star - y_[12]) / Lf_; - f_[11] = -yp_[11] - (rLf_ / Lf_) * y_[11] - omega * y_[10] + (viq_star - y_[13]) / Lf_; - - f_[12] = -yp_[12] + omega * y_[13] + (y_[10] - y_[14]) / Cf_; - f_[13] = -yp_[13] - omega * y_[12] + (y_[11] - y_[15]) / Cf_; - - f_[14] = -yp_[14] - (rLc_ / Lc_) * y_[14] + omega * y_[15] + (y_[12] - vbd_in) / Lc_; - f_[15] = -yp_[15] - (rLc_ / Lc_) * y_[15] - omega * y_[14] + (y_[13] - vbq_in) / Lc_; + constexpr double wb_ = 2.0 * M_PI * 50.0; + constexpr double wc_ = 31.41; + constexpr double mp_ = 9.4e-5; + constexpr double Vn_ = 380.0; + constexpr double nq_ = 1.3e-3; + constexpr double F_ = 0.75; + constexpr double Kiv_ = 420.0; + constexpr double Kpv_ = 0.1; + constexpr double Kic_ = 2.0e4; + constexpr double Kpc_ = 15.0; + constexpr double Cf_ = 5.0e-5; + constexpr double rLf_ = 0.1; + constexpr double Lf_ = 1.35e-3; + constexpr double rLc_ = 0.03; + constexpr double Lc_ = 0.35e-3; + + constexpr bool ref_frame_ = true; + + std::vector yp_(0); + + double omega = wb_ - mp_ * y_[4]; + if (ref_frame_) + { + f_[0] = omega - y_[0]; + } + else + { + f_[0] = 0.0; + } + + f_[1] = cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15]; + f_[2] = sin(y_[3]) * y_[14] + cos(y_[3]) * y_[15]; + + double vbd_in = cos(y_[3]) * y_[1] + sin(y_[3]) * y_[2]; + double vbq_in = -sin(y_[3]) * y_[1] + cos(y_[3]) * y_[2]; + + f_[3] = -yp_[3] + omega - y_[0]; + f_[4] = -yp_[4] + wc_ * (y_[12] * y_[14] + y_[13] * y_[15] - y_[4]); + f_[5] = -yp_[5] + wc_ * (-y_[12] * y_[15] + y_[13] * y_[14] - y_[5]); + + double vod_star = Vn_ - nq_ * y_[5]; + double voq_star = 0.0; + + f_[6] = -yp_[6] + vod_star - y_[12]; + f_[7] = -yp_[7] + voq_star - y_[13]; + + double ild_star = F_ * y_[14] - wb_ * Cf_ * y_[13] + Kpv_ * (vod_star - y_[12]) + Kiv_ * y_[6]; + double ilq_star = F_ * y_[15] + wb_ * Cf_ * y_[12] + Kpv_ * (voq_star - y_[13]) + Kiv_ * y_[7]; + + f_[8] = -yp_[8] + ild_star - y_[10]; + f_[9] = -yp_[9] + ilq_star - y_[11]; + + double vid_star = -wb_ * Lf_ * y_[11] + Kpc_ * (ild_star - y_[10]) + Kic_ * y_[8]; + double viq_star = wb_ * Lf_ * y_[10] + Kpc_ * (ilq_star - y_[11]) + Kic_ * y_[9]; + + f_[10] = -yp_[10] - (rLf_ / Lf_) * y_[10] + omega * y_[11] + (vid_star - y_[12]) / Lf_; + f_[11] = -yp_[11] - (rLf_ / Lf_) * y_[11] - omega * y_[10] + (viq_star - y_[13]) / Lf_; + + f_[12] = -yp_[12] + omega * y_[13] + (y_[10] - y_[14]) / Cf_; + f_[13] = -yp_[13] - omega * y_[12] + (y_[11] - y_[15]) / Cf_; + + f_[14] = -yp_[14] - (rLc_ / Lc_) * y_[14] + omega * y_[15] + (y_[12] - vbd_in) / Lc_; + f_[15] = -yp_[15] - (rLc_ / Lc_) * y_[15] - omega * y_[14] + (y_[13] - vbq_in) / Lc_; } // Function that computes the Jacobian via automatic differentiation template -void EnzymeModelJacobian(T* model, DenseMatrix& jac) +void EnzymeModelJacobian(T* model, DenseMatrix& jac) { - int N = model->size(); - std::vector y(N); - std::vector v(N); - std::vector res(N); - std::vector d_res(N); - for (int idy = 0; idy < N; ++idy) + int N = model->size(); + std::vector y(N); + std::vector v(N); + std::vector res(N); + std::vector d_res(N); + for (int idy = 0; idy < N; ++idy) + { + // Elementary vector for Jacobian-vector product + for (int idx = 0; idx < N; ++idx) { - // Elementary vector for Jacobian-vector product - for (int idx = 0; idx < N; ++idx) - { - y[idx] = (model->y())[idx]; - res[idx] = (model->getResidual())[idx]; - v[idx] = 0.0; - } - v[idy] = 1.0; - - // Autodiff - __enzyme_fwddiff((void*)evaluateResidual, - enzyme_dup, y, v, - enzyme_dupnoneed, res, &d_res); - - // Store result - for (int idx = 0; idx < N; ++idx) - { - jac.setValue(idx, idy, d_res[idx]); - } + y[idx] = (model->y())[idx]; + res[idx] = (model->getResidual())[idx]; + v[idx] = 0.0; } + v[idy] = 1.0; + + // Autodiff + __enzyme_fwddiff((void*) evaluateResidual, + enzyme_dup, + y, + v, + enzyme_dupnoneed, + res, + &d_res); + + // Store result + for (int idx = 0; idx < N; ++idx) + { + jac.setValue(idx, idy, d_res[idx]); + } + } } -int main() +int main() { - // Model - DGParameters parms; - parms.wb_ = 2.0*M_PI*50.0; - parms.wc_ = 31.41; - parms.mp_ = 9.4e-5; - parms.Vn_ = 380.0; - parms.nq_ = 1.3e-3; - parms.F_ = 0.75; - parms.Kiv_ = 420.0; - parms.Kpv_ = 0.1; - parms.Kic_ = 2.0e4; - parms.Kpc_ = 15.0; - parms.Cf_ = 5.0e-5; - parms.rLf_ = 0.1; - parms.Lf_ = 1.35e-3; - parms.rLc_ = 0.03; - parms.Lc_ = 0.35e-3; - DG *dg = new DG(0, parms, true); - dg->allocate(); - dg->initialize(); - dg->updateTime(0.0, 0.0); - - // Residual evaluation and reference Jacobian - dg->evaluateResidual(); - dg->evaluateJacobian(); - std::vector y = dg->y(); - std::vector yp = dg->yp(); - std::vector res = dg->getResidual(); - SparseMatrix jac_ref = dg->getJacobian(); - DenseMatrix jac_ref_dense(dg->size(), dg->size()); - jac_ref_dense.setValues(jac_ref); - - // Enzyme Jacobian - DenseMatrix jac_autodiff(dg->size(), dg->size()); - EnzymeModelJacobian(dg, jac_autodiff); - - // Check - int fail = 0; - bool verbose = true; - for (int idy = 0; idy < dg->size(); ++idy) + // Model + DGParameters parms; + parms.wb_ = 2.0 * M_PI * 50.0; + parms.wc_ = 31.41; + parms.mp_ = 9.4e-5; + parms.Vn_ = 380.0; + parms.nq_ = 1.3e-3; + parms.F_ = 0.75; + parms.Kiv_ = 420.0; + parms.Kpv_ = 0.1; + parms.Kic_ = 2.0e4; + parms.Kpc_ = 15.0; + parms.Cf_ = 5.0e-5; + parms.rLf_ = 0.1; + parms.Lf_ = 1.35e-3; + parms.rLc_ = 0.03; + parms.Lc_ = 0.35e-3; + DG* dg = new DG(0, parms, true); + dg->allocate(); + dg->initialize(); + dg->updateTime(0.0, 0.0); + + // Residual evaluation and reference Jacobian + dg->evaluateResidual(); + dg->evaluateJacobian(); + std::vector y = dg->y(); + std::vector yp = dg->yp(); + std::vector res = dg->getResidual(); + SparseMatrix jac_ref = dg->getJacobian(); + DenseMatrix jac_ref_dense(dg->size(), dg->size()); + jac_ref_dense.setValues(jac_ref); + + // Enzyme Jacobian + DenseMatrix jac_autodiff(dg->size(), dg->size()); + EnzymeModelJacobian(dg, jac_autodiff); + + // Check + int fail = 0; + bool verbose = true; + for (int idy = 0; idy < dg->size(); ++idy) + { + for (int idx = 0; idx < dg->size(); ++idx) { - for (int idx = 0; idx < dg->size(); ++idx) + if (std::abs(jac_autodiff.getValue(idx, idy) - jac_ref_dense.getValue(idx, idy)) > std::numeric_limits::epsilon()) + { + fail++; + if (verbose) { - if (std::abs(jac_autodiff.getValue(idx, idy) - jac_ref_dense.getValue(idx, idy)) > std::numeric_limits::epsilon()) - { - fail++; - if (verbose) - { - std::cout << "Result incorrect at line = " << idy << ", column = " << idx << "\n"; - } - } + std::cout << "Result incorrect at line = " << idy << ", column = " << idx << "\n"; } + } } - if (verbose) - { - jac_autodiff.printMatrix("Autodiff Jacobian"); - jac_ref_dense.printMatrix("Reference Jacobian"); - } - std::cout << "Status: " << fail << "\n"; - - // Cleanup - delete dg; - - return fail; + } + if (verbose) + { + jac_autodiff.printMatrix("Autodiff Jacobian"); + jac_ref_dense.printMatrix("Reference Jacobian"); + } + std::cout << "Status: " << fail << "\n"; + + // Cleanup + delete dg; + + return fail; } diff --git a/examples/Enzyme/Standalone/EnzymeScalar.cpp b/examples/Enzyme/Standalone/EnzymeScalar.cpp index 99333b1a..d799e9b0 100644 --- a/examples/Enzyme/Standalone/EnzymeScalar.cpp +++ b/examples/Enzyme/Standalone/EnzymeScalar.cpp @@ -8,29 +8,30 @@ * TODO: Convert this into a unit test. */ -double square(double x) +double square(double x) { - return x * x; + return x * x; } -double __enzyme_autodiff(double(*)(double), ...); -double dsquare(double x) +double __enzyme_autodiff(double (*)(double), ...); + +double dsquare(double x) { - return __enzyme_autodiff(square, x); + return __enzyme_autodiff(square, x); } int main() { - int fail = 0; - double var = 5.0; - double sq = square(var); - double dsq = dsquare(var); - std::cout << "x = " << var << ", x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; - if (std::abs(dsq - 2.0*var) > std::numeric_limits::epsilon()) - { - fail++; - std::cout << "Result incorrect\n"; - } - std::cout << "Status: " << fail << "\n"; - return fail; + int fail = 0; + double var = 5.0; + double sq = square(var); + double dsq = dsquare(var); + std::cout << "x = " << var << ", x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; + if (std::abs(dsq - 2.0 * var) > std::numeric_limits::epsilon()) + { + fail++; + std::cout << "Result incorrect\n"; + } + std::cout << "Status: " << fail << "\n"; + return fail; } diff --git a/examples/Enzyme/Standalone/EnzymeVector.cpp b/examples/Enzyme/Standalone/EnzymeVector.cpp index ef6d60c1..94a10f9a 100644 --- a/examples/Enzyme/Standalone/EnzymeVector.cpp +++ b/examples/Enzyme/Standalone/EnzymeVector.cpp @@ -1,6 +1,7 @@ #include #include #include + #include /** @@ -11,120 +12,116 @@ */ using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; -int enzyme_dupnoneed; -int enzyme_dup; -int enzyme_const; -void __enzyme_fwddiff(void*, int, std::vector, std::vector, - int, std::vector, std::vector*); - -inline -double square_scalar(double x) +int enzyme_dupnoneed; +int enzyme_dup; +int enzyme_const; +void __enzyme_fwddiff(void*, int, std::vector, std::vector, int, std::vector, std::vector*); + +inline double square_scalar(double x) { - return x * x; + return x * x; } -inline -double dsquare_ref_scalar(double x) +inline double dsquare_ref_scalar(double x) { - return 2.0 * x; + return 2.0 * x; } // Vector-valued function to differentiate -void square(std::vector x, std::vector& y) +void square(std::vector x, std::vector& y) { - for (int idx = 0; idx < x.size(); ++idx) - { - y[idx] = square_scalar(x[idx]); - } + for (int idx = 0; idx < x.size(); ++idx) + { + y[idx] = square_scalar(x[idx]); + } } // Reference Jacobian -void dsquare_ref(std::vector x, std::vector y, DenseMatrix& dy) +void dsquare_ref(std::vector x, std::vector y, DenseMatrix& dy) { - for (int idy = 0; idy < y.size(); ++idy) + for (int idy = 0; idy < y.size(); ++idy) + { + for (int idx = 0; idx < x.size(); ++idx) { - for (int idx = 0; idx < x.size(); ++idx) - { - if (idx == idy) - dy.setValue(idx, idy, dsquare_ref_scalar(x[idx])); - } + if (idx == idy) + dy.setValue(idx, idy, dsquare_ref_scalar(x[idx])); } + } } // Function that computes the Jacobian via automatic differentiation -void dsquare(std::vector x, std::vector y, DenseMatrix& dy) +void dsquare(std::vector x, std::vector y, DenseMatrix& dy) { - std::vector v(x.size()); - std::vector d_y(y.size()); - for (int idy = 0; idy < y.size(); ++idy) + std::vector v(x.size()); + std::vector d_y(y.size()); + for (int idy = 0; idy < y.size(); ++idy) + { + // Elementary vector for Jacobian-vector product + for (int idx = 0; idx < x.size(); ++idx) { - // Elementary vector for Jacobian-vector product - for (int idx = 0; idx < x.size(); ++idx) - { - v[idx] = 0.0; - } - v[idy] = 1.0; - - // Autodiff - __enzyme_fwddiff((void*)square, enzyme_dup, x, v, - enzyme_dupnoneed, y, &d_y); - - // Store result - for (int idx = 0; idx < x.size(); ++idx) - { - dy.setValue(idx, idy, d_y[idx]); - } + v[idx] = 0.0; } + v[idy] = 1.0; + + // Autodiff + __enzyme_fwddiff((void*) square, enzyme_dup, x, v, enzyme_dupnoneed, y, &d_y); + + // Store result + for (int idx = 0; idx < x.size(); ++idx) + { + dy.setValue(idx, idy, d_y[idx]); + } + } } int main() { - // Vector and matrix declarations - constexpr int N = 10; - std::vector x(N); - std::vector sq(N); - DenseMatrix dsq = DenseMatrix(N, N); - DenseMatrix dsq_ref = DenseMatrix(N, N); - - // Random input values - srand(time(NULL)); + // Vector and matrix declarations + constexpr int N = 10; + std::vector x(N); + std::vector sq(N); + DenseMatrix dsq = DenseMatrix(N, N); + DenseMatrix dsq_ref = DenseMatrix(N, N); + + // Random input values + srand(time(NULL)); + for (int idx = 0; idx < x.size(); ++idx) + { + x[idx] = rand(); + } + + // Function evaluation + square(x, sq); + + // Reference Jacobian + dsquare_ref(x, sq, dsq_ref); + + // Enzyme Jacobian + dsquare(x, sq, dsq); + + // Check + int fail = 0; + bool verbose = true; + for (int idy = 0; idy < sq.size(); ++idy) + { for (int idx = 0; idx < x.size(); ++idx) { - x[idx] = rand(); - } - - // Function evaluation - square(x, sq); - - // Reference Jacobian - dsquare_ref(x, sq, dsq_ref); - - // Enzyme Jacobian - dsquare(x, sq, dsq); - - // Check - int fail = 0; - bool verbose = true; - for (int idy = 0; idy < sq.size(); ++idy) - { - for (int idx = 0; idx < x.size(); ++idx) + if (std::abs(dsq.getValue(idx, idy) - dsq_ref.getValue(idx, idy)) > std::numeric_limits::epsilon()) + { + fail++; + if (verbose) { - if (std::abs(dsq.getValue(idx, idy) - dsq_ref.getValue(idx, idy)) > std::numeric_limits::epsilon()) - { - fail++; - if (verbose) - { - std::cout << "Result incorrect at line = " << idy << ", column = " << idx << "\n"; - std::cout << "x = " << x[idx] << ", x^2 = " << sq[idx] << ", d(x^2)/dx = " << dsq.getValue(idx, idy) << "\n"; - } - } + std::cout << "Result incorrect at line = " << idy << ", column = " << idx << "\n"; + std::cout << "x = " << x[idx] << ", x^2 = " << sq[idx] << ", d(x^2)/dx = " << dsq.getValue(idx, idy) << "\n"; } + } } - if (verbose) - { - dsq.printMatrix("Autodiff Jacobian"); - dsq_ref.printMatrix("Reference Jacobian"); - } - std::cout << "Status: " << fail << "\n"; - return fail; + } + if (verbose) + { + dsq.printMatrix("Autodiff Jacobian"); + dsq_ref.printMatrix("Reference Jacobian"); + } + std::cout << "Status: " << fail << "\n"; + return fail; } diff --git a/examples/GenConstLoad/GenConstLoad.cpp b/examples/GenConstLoad/GenConstLoad.cpp index 2a52677d..b7a0f42a 100644 --- a/examples/GenConstLoad/GenConstLoad.cpp +++ b/examples/GenConstLoad/GenConstLoad.cpp @@ -57,128 +57,127 @@ * */ - -#include #include +#include +#include +#include #include -#include #include -#include +#include #include - -#include -#include -#include +#include #include +#include #include int main() { - using namespace GridKit; - using namespace AnalysisManager::Sundials; - using namespace AnalysisManager; - using namespace GridKit::Testing; - - // Create a bus - 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); - - // Attach load to the bus - ModelEvaluatorImpl* load = new Load(bus, 0.8, 0.3); - - // Create system model - SystemModel* model = new SystemModel(); - model->addBus(bus); - model->addComponent(gen); - model->addComponent(load); - - // Create numerical integrator and configure it for the generator model - Ida* idas = new Ida(model); - - model->allocate(); - - double t_init = 0.0; - double t_final = 15.0; - - // setup simulation - idas->configureSimulation(); - idas->configureAdjoint(); - idas->getDefaultInitialCondition(); - idas->initializeSimulation(t_init, true); - idas->configureQuadrature(); - idas->initializeQuadrature(); - - idas->runSimulationQuadrature(0.1, 2); - idas->saveInitialCondition(); - - // Set integration time for dynamic constrained optimization - idas->setIntegrationTime(t_init, t_final, 250); - - // Guess optimization parameter values - double T2 = 0.15; - double K = 16.0; - - // Create an instance of the IpoptApplication - Ipopt::SmartPtr ipoptApp = IpoptApplicationFactory(); - - // Initialize the IpoptApplication and process the options - Ipopt::ApplicationReturnStatus status; - status = ipoptApp->Initialize(); - if (status != Ipopt::Solve_Succeeded) { - std::cout << "\n\n*** Initialization failed! ***\n\n"; - return (int) status; - } - - // Set solver tolerance - const double tol = 1e-4; - - // Configure Ipopt application - ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); - ipoptApp->Options()->SetNumericValue("tol", tol); - ipoptApp->Options()->SetIntegerValue("print_level", 5); - - // Create interface to Ipopt solver - Ipopt::SmartPtr ipoptDynamicObjectiveInterface = - new IpoptInterface::DynamicObjective(idas); - - // Initialize problem - model->param()[0] = T2; - model->param()[1] = K; - - // Solve the problem - status = ipoptApp->OptimizeTNLP(ipoptDynamicObjectiveInterface); - - if (status == Ipopt::Solve_Succeeded) { - // Print result - std::cout << "\nSucess: The problem solved in " - << ipoptApp->Statistics()->IterationCount() - << " iterations!\n"; - std::cout << "Optimal value: T2 = " - << model->param()[0] - << ", K = " - << model->param()[1] << "\n"; - std::cout << "The final value of the objective function G(T2,K) = " - << ipoptApp->Statistics()->FinalObjective() << "\n\n"; - } - - // Compare results of the two optimization methods - int retval = - isEqual(ipoptApp->Statistics()->FinalObjective(), 1239.0, 10*tol) ? 0 : 1; - - if(retval != 0) - { - std::cout << "The two results differ beyond solver tolerance!\n"; - } - - - delete idas; - delete gen; - delete load; - delete bus; - delete model; - - return 0; + using namespace GridKit; + using namespace AnalysisManager::Sundials; + using namespace AnalysisManager; + using namespace GridKit::Testing; + + // Create a bus + 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); + + // Attach load to the bus + ModelEvaluatorImpl* load = new Load(bus, 0.8, 0.3); + + // Create system model + SystemModel* model = new SystemModel(); + model->addBus(bus); + model->addComponent(gen); + model->addComponent(load); + + // Create numerical integrator and configure it for the generator model + Ida* idas = new Ida(model); + + model->allocate(); + + double t_init = 0.0; + double t_final = 15.0; + + // setup simulation + idas->configureSimulation(); + idas->configureAdjoint(); + idas->getDefaultInitialCondition(); + idas->initializeSimulation(t_init, true); + idas->configureQuadrature(); + idas->initializeQuadrature(); + + idas->runSimulationQuadrature(0.1, 2); + idas->saveInitialCondition(); + + // Set integration time for dynamic constrained optimization + idas->setIntegrationTime(t_init, t_final, 250); + + // Guess optimization parameter values + double T2 = 0.15; + double K = 16.0; + + // Create an instance of the IpoptApplication + Ipopt::SmartPtr ipoptApp = IpoptApplicationFactory(); + + // Initialize the IpoptApplication and process the options + Ipopt::ApplicationReturnStatus status; + status = ipoptApp->Initialize(); + if (status != Ipopt::Solve_Succeeded) + { + std::cout << "\n\n*** Initialization failed! ***\n\n"; + return (int) status; + } + + // Set solver tolerance + const double tol = 1e-4; + + // Configure Ipopt application + ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); + ipoptApp->Options()->SetNumericValue("tol", tol); + ipoptApp->Options()->SetIntegerValue("print_level", 5); + + // Create interface to Ipopt solver + Ipopt::SmartPtr ipoptDynamicObjectiveInterface = + new IpoptInterface::DynamicObjective(idas); + + // Initialize problem + model->param()[0] = T2; + model->param()[1] = K; + + // Solve the problem + status = ipoptApp->OptimizeTNLP(ipoptDynamicObjectiveInterface); + + if (status == Ipopt::Solve_Succeeded) + { + // Print result + std::cout << "\nSucess: The problem solved in " + << ipoptApp->Statistics()->IterationCount() + << " iterations!\n"; + std::cout << "Optimal value: T2 = " + << model->param()[0] + << ", K = " + << model->param()[1] << "\n"; + std::cout << "The final value of the objective function G(T2,K) = " + << ipoptApp->Statistics()->FinalObjective() << "\n\n"; + } + + // Compare results of the two optimization methods + int retval = + isEqual(ipoptApp->Statistics()->FinalObjective(), 1239.0, 10 * tol) ? 0 : 1; + + if (retval != 0) + { + std::cout << "The two results differ beyond solver tolerance!\n"; + } + + delete idas; + delete gen; + delete load; + delete bus; + delete model; + + return 0; } diff --git a/examples/GenInfiniteBus/GenInfiniteBus.cpp b/examples/GenInfiniteBus/GenInfiniteBus.cpp index a5f0e67e..4fed9401 100644 --- a/examples/GenInfiniteBus/GenInfiniteBus.cpp +++ b/examples/GenInfiniteBus/GenInfiniteBus.cpp @@ -57,164 +57,163 @@ * */ - -#include #include +#include +#include +#include #include #include #include #include - -#include -#include -#include #include +#include #include - int main() { - using namespace GridKit; - using namespace AnalysisManager::Sundials; - using namespace AnalysisManager; - using namespace GridKit::Testing; - - // Create an infinite bus - BaseBus* bus = new BusSlack(1.0, 0.0); - - // Attach a generator to that bus - Generator4* gen = new Generator4(bus); - - // Create a system model - SystemModel* model = new SystemModel(); - model->addBus(bus); - model->addComponent(gen); - - // allocate model components - model->allocate(); - - - // Create numerical integrator and configure it for the generator model - Ida* idas = new Ida(model); - - double t_init = 0.0; - double t_final = 15.0; - - // setup simulation - idas->configureSimulation(); - idas->configureAdjoint(); - idas->getDefaultInitialCondition(); + using namespace GridKit; + using namespace AnalysisManager::Sundials; + using namespace AnalysisManager; + using namespace GridKit::Testing; + + // Create an infinite bus + BaseBus* bus = new BusSlack(1.0, 0.0); + + // Attach a generator to that bus + Generator4* gen = new Generator4(bus); + + // Create a system model + SystemModel* model = new SystemModel(); + model->addBus(bus); + model->addComponent(gen); + + // allocate model components + model->allocate(); + + // Create numerical integrator and configure it for the generator model + Ida* idas = new Ida(model); + + double t_init = 0.0; + double t_final = 15.0; + + // setup simulation + idas->configureSimulation(); + idas->configureAdjoint(); + idas->getDefaultInitialCondition(); + idas->initializeSimulation(t_init); + idas->configureQuadrature(); + idas->initializeQuadrature(); + + double t_fault = 0.1; + double t_clear = 0.1; + idas->runSimulation(t_fault); + idas->saveInitialCondition(); + // create initial condition after a fault + { + idas->getSavedInitialCondition(); idas->initializeSimulation(t_init); - idas->configureQuadrature(); - idas->initializeQuadrature(); - - double t_fault = 0.1; - double t_clear = 0.1; - idas->runSimulation(t_fault); + gen->V() = 0.0; + idas->runSimulation(t_clear, 20); + gen->V() = 1.0; idas->saveInitialCondition(); - // create initial condition after a fault - { - idas->getSavedInitialCondition(); - idas->initializeSimulation(t_init); - gen->V() = 0.0; - idas->runSimulation(t_clear, 20); - gen->V() = 1.0; - idas->saveInitialCondition(); - } - - // Set integration time for dynamic constrained optimization - idas->setIntegrationTime(t_init, t_final, 100); - - // Guess initial values of optimization parameters - double Pm = 1.0; - double Ef = 1.45; - - // Create an instance of the IpoptApplication - Ipopt::SmartPtr ipoptApp = IpoptApplicationFactory(); - - // Initialize the IpoptApplication and process the options - Ipopt::ApplicationReturnStatus status; - status = ipoptApp->Initialize(); - if (status != Ipopt::Solve_Succeeded) { - std::cout << "\n\n*** Initialization failed! ***\n\n"; - return (int) status; - } - - // Set solver tolerance - const double tol = 1e-4; - - // Configure Ipopt application - ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); - ipoptApp->Options()->SetNumericValue("tol", tol); - ipoptApp->Options()->SetIntegerValue("print_level", 0); - - // Create dynamic objective interface to Ipopt solver - Ipopt::SmartPtr ipoptDynamicObjectiveInterface = - new IpoptInterface::DynamicObjective(idas); - - // Initialize the problem - model->param()[0] = Pm; - model->param()[1] = Ef; - - // Solve the problem - status = ipoptApp->OptimizeTNLP(ipoptDynamicObjectiveInterface); - std::cout << "\n\nProblem formulated as dynamic objective optimiztion ...\n"; - - if (status == Ipopt::Solve_Succeeded) { - // Print result - std::cout << "\nSucess:\n The problem solved in " - << ipoptApp->Statistics()->IterationCount() << " iterations!\n" - << " Optimal value of Pm = " << model->param()[0] << "\n" - << " Optimal value of Ef = " << model->param()[1] << "\n" - << " The final value of the objective function G(Pm,Ef) = " - << ipoptApp->Statistics()->FinalObjective() << "\n\n"; - } - - // Create dynamic constraint interface to Ipopt solver - Ipopt::SmartPtr ipoptDynamicConstraintInterface = - new IpoptInterface::DynamicConstraint(idas); - - // Store dynamic objective optimization results - double* results = new double[model->sizeParams()]; - for(unsigned i=0; i sizeParams(); ++i) - { - results[i] = model->param()[i]; - } - - // Initialize the problem - model->param()[0] = Pm; - model->param()[1] = Ef; - - // Solve the problem - status = ipoptApp->OptimizeTNLP(ipoptDynamicConstraintInterface); - std::cout << "\n\nProblem formulated as dynamic constraint optimiztion ...\n"; - - if (status == Ipopt::Solve_Succeeded) { - // Print result - std::cout << "\nSucess:\n The problem solved in " - << ipoptApp->Statistics()->IterationCount() << " iterations!\n" - << " Optimal value of Pm = " << model->param()[0] << "\n" - << " Optimal value of Ef = " << model->param()[1] << "\n" - << " The final value of the objective function G(Pm,Ef) = " - << ipoptApp->Statistics()->FinalObjective() << "\n\n"; - } - - // Compare results of the two optimization methods - int retval = 0; - for(unsigned i=0; i sizeParams(); ++i) - { - if(!isEqual(results[i], model->param()[i], 100*tol)) - --retval; - } - - if(retval < 0) - { - std::cout << "The two results differ beyond solver tolerance!\n"; - } - - delete [] results; - delete idas; - delete model; - return 0; + } + + // Set integration time for dynamic constrained optimization + idas->setIntegrationTime(t_init, t_final, 100); + + // Guess initial values of optimization parameters + double Pm = 1.0; + double Ef = 1.45; + + // Create an instance of the IpoptApplication + Ipopt::SmartPtr ipoptApp = IpoptApplicationFactory(); + + // Initialize the IpoptApplication and process the options + Ipopt::ApplicationReturnStatus status; + status = ipoptApp->Initialize(); + if (status != Ipopt::Solve_Succeeded) + { + std::cout << "\n\n*** Initialization failed! ***\n\n"; + return (int) status; + } + + // Set solver tolerance + const double tol = 1e-4; + + // Configure Ipopt application + ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); + ipoptApp->Options()->SetNumericValue("tol", tol); + ipoptApp->Options()->SetIntegerValue("print_level", 0); + + // Create dynamic objective interface to Ipopt solver + Ipopt::SmartPtr ipoptDynamicObjectiveInterface = + new IpoptInterface::DynamicObjective(idas); + + // Initialize the problem + model->param()[0] = Pm; + model->param()[1] = Ef; + + // Solve the problem + status = ipoptApp->OptimizeTNLP(ipoptDynamicObjectiveInterface); + std::cout << "\n\nProblem formulated as dynamic objective optimiztion ...\n"; + + if (status == Ipopt::Solve_Succeeded) + { + // Print result + std::cout << "\nSucess:\n The problem solved in " + << ipoptApp->Statistics()->IterationCount() << " iterations!\n" + << " Optimal value of Pm = " << model->param()[0] << "\n" + << " Optimal value of Ef = " << model->param()[1] << "\n" + << " The final value of the objective function G(Pm,Ef) = " + << ipoptApp->Statistics()->FinalObjective() << "\n\n"; + } + + // Create dynamic constraint interface to Ipopt solver + Ipopt::SmartPtr ipoptDynamicConstraintInterface = + new IpoptInterface::DynamicConstraint(idas); + + // Store dynamic objective optimization results + double* results = new double[model->sizeParams()]; + for (unsigned i = 0; i < model->sizeParams(); ++i) + { + results[i] = model->param()[i]; + } + + // Initialize the problem + model->param()[0] = Pm; + model->param()[1] = Ef; + + // Solve the problem + status = ipoptApp->OptimizeTNLP(ipoptDynamicConstraintInterface); + std::cout << "\n\nProblem formulated as dynamic constraint optimiztion ...\n"; + + if (status == Ipopt::Solve_Succeeded) + { + // Print result + std::cout << "\nSucess:\n The problem solved in " + << ipoptApp->Statistics()->IterationCount() << " iterations!\n" + << " Optimal value of Pm = " << model->param()[0] << "\n" + << " Optimal value of Ef = " << model->param()[1] << "\n" + << " The final value of the objective function G(Pm,Ef) = " + << ipoptApp->Statistics()->FinalObjective() << "\n\n"; + } + + // Compare results of the two optimization methods + int retval = 0; + for (unsigned i = 0; i < model->sizeParams(); ++i) + { + if (!isEqual(results[i], model->param()[i], 100 * tol)) + --retval; + } + + if (retval < 0) + { + std::cout << "The two results differ beyond solver tolerance!\n"; + } + + delete[] results; + delete idas; + delete model; + return 0; } diff --git a/examples/Grid3Bus/Grid3BusSys.cpp b/examples/Grid3Bus/Grid3BusSys.cpp index 10601a43..b083f9e8 100644 --- a/examples/Grid3Bus/Grid3BusSys.cpp +++ b/examples/Grid3Bus/Grid3BusSys.cpp @@ -61,27 +61,26 @@ * @file Grid3BusSys.cpp * @author Slaven Peles * @author Reid Gomillion - * + * * Simple 3-bus grid example. Two models are tested here -- a hard-wired model * and a model assembled using GridKit's system composer. - * + * */ -#include -#include #include -#include #include +#include +#include +#include -#include +#include #include #include -#include #include +#include #include -#include #include - +#include #include #include @@ -133,7 +132,6 @@ mpc.gencost = [ )"; - using namespace GridKit; using namespace AnalysisManager::Sundials; using namespace AnalysisManager; @@ -141,271 +139,295 @@ using namespace GridKit::Testing; using namespace GridKit::PowerSystemData; constexpr double theta2_ref = -4.87979; // [deg] -constexpr double V2_ref = 1.08281; // [p.u.] -constexpr double theta3_ref = 1.46241; // [deg] +constexpr double V2_ref = 1.08281; // [p.u.] +constexpr double theta3_ref = 1.46241; // [deg] /** * Testing the monlithic case via the class MiniGrid * @return returns 0 if pass o.w. fails -*/ + */ int monolithicCase() { - std::cout << "\nSolving power flow for a 3-bus monolithic model ...\n\n"; - // Create a 3-bus model - MiniGrid* model = new MiniGrid(); - - // allocate model - model->allocate(); - model->initialize(); - std::cout << "Model size: " << model->size() << "\n\n"; - - // Create numerical solver and attach the model to it. - // Here we use Kinsol solver from SUNDIALS library - Kinsol* kinsol = new Kinsol(model); - - // setup simulation - kinsol->configureSimulation(); - // initialize simulation with default initial guess V=1, theta=0 - kinsol->getDefaultInitialCondition(); - // Compute solution - kinsol->runSimulation(); - // Print solution - double th2 = model->th2() * 180.0/M_PI; - double V2 = model->V2(); - double th3 = model->th3() * 180.0/M_PI; - 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"; - - // Print solver performance statistics - kinsol->printFinalStats(); - - int retval1 = 0; - retval1 += !isEqual(th2, theta2_ref, 1e-4); - retval1 += !isEqual(V2, V2_ref , 1e-4); - retval1 += !isEqual(th3, theta3_ref, 1e-4); - - if(retval1 == 0) - std::cout << "\nSuccess!\n\n\n"; - else - std::cout << "\nFailed!\n\n\n"; - - // Delete solver and model - delete kinsol; kinsol = nullptr; - delete model; model = nullptr; - return retval1; + std::cout << "\nSolving power flow for a 3-bus monolithic model ...\n\n"; + // Create a 3-bus model + MiniGrid* model = new MiniGrid(); + + // allocate model + model->allocate(); + model->initialize(); + std::cout << "Model size: " << model->size() << "\n\n"; + + // Create numerical solver and attach the model to it. + // Here we use Kinsol solver from SUNDIALS library + Kinsol* kinsol = new Kinsol(model); + + // setup simulation + kinsol->configureSimulation(); + // initialize simulation with default initial guess V=1, theta=0 + kinsol->getDefaultInitialCondition(); + // Compute solution + kinsol->runSimulation(); + // Print solution + double th2 = model->th2() * 180.0 / M_PI; + double V2 = model->V2(); + double th3 = model->th3() * 180.0 / M_PI; + 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"; + + // Print solver performance statistics + kinsol->printFinalStats(); + + int retval1 = 0; + retval1 += !isEqual(th2, theta2_ref, 1e-4); + retval1 += !isEqual(V2, V2_ref, 1e-4); + retval1 += !isEqual(th3, theta3_ref, 1e-4); + + if (retval1 == 0) + std::cout << "\nSuccess!\n\n\n"; + else + std::cout << "\nFailed!\n\n\n"; + + // Delete solver and model + delete kinsol; + kinsol = nullptr; + delete model; + model = nullptr; + return retval1; } /** * Run the Testing case for parser setup * @return returns 0 if pass o.w. fail -*/ + */ int parserCase() { - std::cout << "Solving same problem, but assembled from components via a parser ...\n\n"; - - //Data File Reading - GridKit::PowerSystemData::SystemModelData mp; - - std::istringstream iss(BUS3_DATA_STRING); - GridKit::readMatPower(mp, iss); - - - // Create an empty system model and pass the system model data to it - SystemSteadyStateModel* sysmodel = new SystemSteadyStateModel(mp); - - // allocate model - sysmodel->allocate(); - sysmodel->initialize(); - std::cout << "Model size: " << sysmodel->size() << "\n\n"; - - // Create numerical solver and attach the model to it. - // Here we use Kinsol solver from SUNDIALS library - Kinsol* kinsol = new Kinsol(sysmodel); - - // setup simulation - kinsol->configureSimulation(); - // initialize simulation with default initial guess - kinsol->getDefaultInitialCondition(); - // Compute solution - kinsol->runSimulation(); - // Print solution - double th2 = sysmodel->getBus(2)->theta() * 180.0/M_PI; - double V2 = sysmodel->getBus(2)->V(); - double th3 = sysmodel->getBus(3)->theta() * 180.0/M_PI; - - - 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"; - - // Print solver performance statistics - kinsol->printFinalStats(); - - int retval2 = 0; - retval2 += !isEqual(th2, theta2_ref, 1e-4); - retval2 += !isEqual(V2, V2_ref , 1e-4); - retval2 += !isEqual(th3, theta3_ref, 1e-4); - - if(retval2 == 0) - std::cout << "\nSuccess!\n\n\n"; - else - std::cout << "\nFailed!\n\n\n"; - - - // Delete solver and model - - delete kinsol; kinsol = nullptr; - delete sysmodel; sysmodel = nullptr; - - return retval2; + std::cout << "Solving same problem, but assembled from components via a parser ...\n\n"; + + // Data File Reading + GridKit::PowerSystemData::SystemModelData mp; + + std::istringstream iss(BUS3_DATA_STRING); + GridKit::readMatPower(mp, iss); + + // Create an empty system model and pass the system model data to it + SystemSteadyStateModel* sysmodel = new SystemSteadyStateModel(mp); + + // allocate model + sysmodel->allocate(); + sysmodel->initialize(); + std::cout << "Model size: " << sysmodel->size() << "\n\n"; + + // Create numerical solver and attach the model to it. + // Here we use Kinsol solver from SUNDIALS library + Kinsol* kinsol = new Kinsol(sysmodel); + + // setup simulation + kinsol->configureSimulation(); + // initialize simulation with default initial guess + kinsol->getDefaultInitialCondition(); + // Compute solution + kinsol->runSimulation(); + // Print solution + double th2 = sysmodel->getBus(2)->theta() * 180.0 / M_PI; + double V2 = sysmodel->getBus(2)->V(); + double th3 = sysmodel->getBus(3)->theta() * 180.0 / M_PI; + + 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"; + + // Print solver performance statistics + kinsol->printFinalStats(); + + int retval2 = 0; + retval2 += !isEqual(th2, theta2_ref, 1e-4); + retval2 += !isEqual(V2, V2_ref, 1e-4); + retval2 += !isEqual(th3, theta3_ref, 1e-4); + + if (retval2 == 0) + std::cout << "\nSuccess!\n\n\n"; + else + std::cout << "\nFailed!\n\n\n"; + + // Delete solver and model + + delete kinsol; + kinsol = nullptr; + delete sysmodel; + sysmodel = nullptr; + + return retval2; } /** * Hardwired Test Case * @return 0 if pass otherwise fails -*/ + */ int hardwiredCase() { - std::cout << "Solving same problem, but assembled from components manually ...\n\n"; - - // First, create an empty system model - SystemSteadyStateModel* sysmodel = new SystemSteadyStateModel(); - - // Next create and add buses ... - // Create a slack bus, fix V=1, theta=0, bus ID = 1 - BusData bd1; - bd1.bus_i = 1; bd1.type = 3; bd1.Vm = 1.0; bd1.Va = 0.0; - auto* bus1 = BusFactory::create(bd1); - sysmodel->addBus(bus1); - - //Create a PQ bus, initialize V=1, theta=0, bus ID = 2 - BusData bd2; - bd2.bus_i = 2; bd2.type = 1; bd2.Vm = 1.0; bd2.Va = 0.0; - 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 - BusData bd3; - bd3.bus_i = 3; bd3.type = 2; bd3.Vm = 1.1; bd3.Va = 0.0; - auto* bus3 = BusFactory::create(bd3); - sysmodel->addBus(bus3); - - // 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); - 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); - sysmodel->addComponent(gen3); - - // Create and add branches ... - // Branch 1-2 - BranchData brd12; - brd12.fbus = 1; brd12.tbus = 2; 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); - sysmodel->addComponent(branch12); - - // Branch 1-3 - BranchData brd13; - brd13.fbus = 1; brd13.tbus = 3; 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); - sysmodel->addComponent(branch13); - - // Branch 2-3 - BranchData brd23; - brd23.fbus = 2; brd23.tbus = 3; 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); - 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); - 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); - sysmodel->addComponent(load2); - - // allocate model - sysmodel->allocate(); - sysmodel->initialize(); - std::cout << "Model size: " << sysmodel->size() << "\n\n"; - - // Create numerical solver and attach the model to it. - // Here we use Kinsol solver from SUNDIALS library - Kinsol* kinsol = new Kinsol(sysmodel); - - // setup simulation - kinsol->configureSimulation(); - // initialize simulation with default initial guess - kinsol->getDefaultInitialCondition(); - // Compute solution - kinsol->runSimulation(); - // Print solution - double th2 = bus2->theta() * 180.0/M_PI; - double V2 = bus2->V(); - double th3 = bus3->theta() * 180.0/M_PI; - - - 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"; - - // Print solver performance statistics - kinsol->printFinalStats(); - - int retval2 = 0; - retval2 += !isEqual(th2, theta2_ref, 1e-4); - retval2 += !isEqual(V2, V2_ref , 1e-4); - retval2 += !isEqual(th3, theta3_ref, 1e-4); - - if(retval2 == 0) - std::cout << "\nSuccess!\n\n\n"; - else - std::cout << "\nFailed!\n\n\n"; - - - // Delete solver and model - delete kinsol; kinsol = nullptr; - delete sysmodel; sysmodel = nullptr; - return retval2; + std::cout << "Solving same problem, but assembled from components manually ...\n\n"; + + // First, create an empty system model + SystemSteadyStateModel* sysmodel = new SystemSteadyStateModel(); + + // Next create and add buses ... + // Create a slack bus, fix V=1, theta=0, bus ID = 1 + BusData bd1; + bd1.bus_i = 1; + bd1.type = 3; + bd1.Vm = 1.0; + bd1.Va = 0.0; + auto* bus1 = BusFactory::create(bd1); + sysmodel->addBus(bus1); + + // Create a PQ bus, initialize V=1, theta=0, bus ID = 2 + BusData bd2; + bd2.bus_i = 2; + bd2.type = 1; + bd2.Vm = 1.0; + bd2.Va = 0.0; + 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 + BusData bd3; + bd3.bus_i = 3; + bd3.type = 2; + bd3.Vm = 1.1; + bd3.Va = 0.0; + auto* bus3 = BusFactory::create(bd3); + sysmodel->addBus(bus3); + + // 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); + 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); + sysmodel->addComponent(gen3); + + // Create and add branches ... + // Branch 1-2 + BranchData brd12; + brd12.fbus = 1; + brd12.tbus = 2; + 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); + sysmodel->addComponent(branch12); + + // Branch 1-3 + BranchData brd13; + brd13.fbus = 1; + brd13.tbus = 3; + 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); + sysmodel->addComponent(branch13); + + // Branch 2-3 + BranchData brd23; + brd23.fbus = 2; + brd23.tbus = 3; + 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); + 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); + 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); + sysmodel->addComponent(load2); + + // allocate model + sysmodel->allocate(); + sysmodel->initialize(); + std::cout << "Model size: " << sysmodel->size() << "\n\n"; + + // Create numerical solver and attach the model to it. + // Here we use Kinsol solver from SUNDIALS library + Kinsol* kinsol = new Kinsol(sysmodel); + + // setup simulation + kinsol->configureSimulation(); + // initialize simulation with default initial guess + kinsol->getDefaultInitialCondition(); + // Compute solution + kinsol->runSimulation(); + // Print solution + double th2 = bus2->theta() * 180.0 / M_PI; + double V2 = bus2->V(); + double th3 = bus3->theta() * 180.0 / M_PI; + + 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"; + + // Print solver performance statistics + kinsol->printFinalStats(); + + int retval2 = 0; + retval2 += !isEqual(th2, theta2_ref, 1e-4); + retval2 += !isEqual(V2, V2_ref, 1e-4); + retval2 += !isEqual(th3, theta3_ref, 1e-4); + + if (retval2 == 0) + std::cout << "\nSuccess!\n\n\n"; + else + std::cout << "\nFailed!\n\n\n"; + + // Delete solver and model + delete kinsol; + kinsol = nullptr; + delete sysmodel; + sysmodel = nullptr; + return retval2; } - int main() { - //return the results of each case - int resolve = 0; - std::cout << std::string(32,'-') << std::endl; - resolve |= monolithicCase(); - std::cout << std::string(32,'-') << std::endl; - resolve |= parserCase(); - std::cout << std::string(32,'-') << std::endl; - resolve |= hardwiredCase(); - - if (resolve) - { - std::cout << "Failure!\n"; - } - else - { - std::cout << "Success!\n"; - } - - - return resolve; + // return the results of each case + int resolve = 0; + std::cout << std::string(32, '-') << std::endl; + resolve |= monolithicCase(); + std::cout << std::string(32, '-') << std::endl; + resolve |= parserCase(); + std::cout << std::string(32, '-') << std::endl; + resolve |= hardwiredCase(); + + if (resolve) + { + std::cout << "Failure!\n"; + } + else + { + std::cout << "Success!\n"; + } + + return resolve; } diff --git a/examples/LinearAlgebra/DenseTest/DenseTest.cpp b/examples/LinearAlgebra/DenseTest/DenseTest.cpp index 8b5e27bd..3148ced6 100644 --- a/examples/LinearAlgebra/DenseTest/DenseTest.cpp +++ b/examples/LinearAlgebra/DenseTest/DenseTest.cpp @@ -3,24 +3,24 @@ int main() { - int fail = 0; + int fail = 0; - size_t m = 4; - size_t n = 4; - GridKit::LinearAlgebra::DenseMatrix A = + size_t m = 4; + size_t n = 4; + GridKit::LinearAlgebra::DenseMatrix A = GridKit::LinearAlgebra::DenseMatrix(m, n); - double val = 0.0; - for (size_t j = 0; j < n; ++j) + double val = 0.0; + for (size_t j = 0; j < n; ++j) + { + for (size_t i = 0; i < m; ++i) { - for (size_t i = 0; i < m; ++i) - { - A.setValue(i, j, val); - val += 1.0; - } + A.setValue(i, j, val); + val += 1.0; } - A.printMatrix("Dense matrix test output"); - (A.getValuesCOO())->printMatrix(); + } + A.printMatrix("Dense matrix test output"); + (A.getValuesCOO())->printMatrix(); - return fail; + return fail; } diff --git a/examples/LinearAlgebra/SparseTest/SparseTest.cpp b/examples/LinearAlgebra/SparseTest/SparseTest.cpp index 56a70ea1..3c7fe99e 100644 --- a/examples/LinearAlgebra/SparseTest/SparseTest.cpp +++ b/examples/LinearAlgebra/SparseTest/SparseTest.cpp @@ -1,102 +1,102 @@ -#include -#include #include -#include #include -#include +#include +#include +#include #include +#include #include -int main(int argc, char const *argv[]) +int main(int argc, char const* argv[]) { - std::vector val{0.1, 0.2, 0.3, 0.4}; - std::vector x{2,1,3,1}; - std::vector y{1,3,2,2}; - size_t n = 4; - size_t m = 4; - - COO_Matrix A = COO_Matrix(x,y,val,m,n); + std::vector val{0.1, 0.2, 0.3, 0.4}; + std::vector x{2, 1, 3, 1}; + std::vector y{1, 3, 2, 2}; + size_t n = 4; + size_t m = 4; - std::vector valn(4); - std::vector xn(4); - std::vector yn(4); + COO_Matrix A = COO_Matrix(x, y, val, m, n); - std::tie(xn, yn, valn) = A.getEntries(); + std::vector valn(4); + std::vector xn(4); + std::vector yn(4); - for (size_t i = 0; i < valn.size(); i++) - { - std::cout << valn[i] << "\n"; - } - - std::cout << "A:\n"; - A.printMatrix(); + std::tie(xn, yn, valn) = A.getEntries(); - std::vector val2{0.5, 0.6, 0.7, 0.8, 1.0}; - std::vector x2{0,2,0,2,1}; - std::vector y2{3,3,2,2,3}; - COO_Matrix B = COO_Matrix(x2,y2,val2,m,n); + for (size_t i = 0; i < valn.size(); i++) + { + std::cout << valn[i] << "\n"; + } - std::cout << "B:\n"; - B.printMatrix(); + std::cout << "A:\n"; + A.printMatrix(); - A.axpy(2.0, B); + std::vector val2{0.5, 0.6, 0.7, 0.8, 1.0}; + std::vector x2{0, 2, 0, 2, 1}; + std::vector y2{3, 3, 2, 2, 3}; + COO_Matrix B = COO_Matrix(x2, y2, val2, m, n); - std::cout << "A + 2B:\n"; - A.printMatrix(); + std::cout << "B:\n"; + B.printMatrix(); - std::vector r; - std::vector c; - std::vector v; - std::tie(r,c,v) = A.setDataToCSR(); + A.axpy(2.0, B); - for (size_t i = 0; i < r.size() - 1; i++) - { - std::cout << r[i] << std::endl; - size_t rdiff = r[i+1] - r[i]; - for (size_t j = 0; j < rdiff; j++) - { - std::cout << c[j + r[i]] << ", " << v[j + r[i]] << std::endl; - } - } - std::cout << r[r.size()-1] << std::endl; + std::cout << "A + 2B:\n"; + A.printMatrix(); - //Basic Verification test - std::vector rtest = {0, 2, 4, 7, 8}; - std::vector ctest = {2,3,2,3,1,2,3,2}; - std::vector valtest = {1.4, 1.0, 0.4, 2.2, 0.1, 1.6, 1.2, 0.3}; + std::vector r; + std::vector c; + std::vector v; + std::tie(r, c, v) = A.setDataToCSR(); - assert(rtest.size() == r.size()); - assert(ctest.size() == c.size()); - assert(valtest.size() == v.size()); - - int failval = 0; - for (size_t i = 0; i < rtest.size(); i++) - { - if (r[i] != rtest[i]) - { - failval--; - } - } - for (size_t i = 0; i < ctest.size(); i++) + for (size_t i = 0; i < r.size() - 1; i++) + { + std::cout << r[i] << std::endl; + size_t rdiff = r[i + 1] - r[i]; + for (size_t j = 0; j < rdiff; j++) { - double vdiff = v[i] - valtest[i]; - if (c[i] != ctest[i] || -1e-14 > vdiff || vdiff > 1e-14) - { - failval--; - } + std::cout << c[j + r[i]] << ", " << v[j + r[i]] << std::endl; } - - if (failval == 0) + } + std::cout << r[r.size() - 1] << std::endl; + + // Basic Verification test + std::vector rtest = {0, 2, 4, 7, 8}; + std::vector ctest = {2, 3, 2, 3, 1, 2, 3, 2}; + std::vector valtest = {1.4, 1.0, 0.4, 2.2, 0.1, 1.6, 1.2, 0.3}; + + assert(rtest.size() == r.size()); + assert(ctest.size() == c.size()); + assert(valtest.size() == v.size()); + + int failval = 0; + for (size_t i = 0; i < rtest.size(); i++) + { + if (r[i] != rtest[i]) { - std::cout << "Success!" << std::endl; + failval--; } - else + } + for (size_t i = 0; i < ctest.size(); i++) + { + double vdiff = v[i] - valtest[i]; + if (c[i] != ctest[i] || -1e-14 > vdiff || vdiff > 1e-14) { - std::cout << "Failed!" << std::endl; + failval--; } - - return failval; + } + + if (failval == 0) + { + std::cout << "Success!" << std::endl; + } + else + { + std::cout << "Failed!" << std::endl; + } + + return failval; } diff --git a/examples/MatPowerTesting/test_parse_branch_row.cpp b/examples/MatPowerTesting/test_parse_branch_row.cpp index 8d87d9e8..f6bb3c0d 100644 --- a/examples/MatPowerTesting/test_parse_branch_row.cpp +++ b/examples/MatPowerTesting/test_parse_branch_row.cpp @@ -1,19 +1,21 @@ +#include + #include #include #include -#include using namespace GridKit; using namespace GridKit::Testing; using namespace GridKit::PowerSystemData; -namespace { +namespace +{ -using IdxT = int; -using RealT = double; + using IdxT = int; + using RealT = double; -static const std::string matpower_data{ - R"( + static const std::string matpower_data{ + R"( %% branch data % fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax @@ -31,8 +33,9 @@ mpc.branch = [ } // namespace -int main(int argc, char **argv) { - int fail = 0; +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}, diff --git a/examples/MatPowerTesting/test_parse_bus_row.cpp b/examples/MatPowerTesting/test_parse_bus_row.cpp index 38695c5f..92c1062c 100644 --- a/examples/MatPowerTesting/test_parse_bus_row.cpp +++ b/examples/MatPowerTesting/test_parse_bus_row.cpp @@ -1,19 +1,21 @@ +#include + #include #include #include -#include using namespace GridKit; using namespace GridKit::Testing; using namespace GridKit::PowerSystemData; -namespace { +namespace +{ -using IdxT = int; -using RealT = double; + using IdxT = int; + using RealT = double; -static const std::string matpower_data{ - R"( + static const std::string matpower_data{ + R"( %% bus data mpc.bus = [ 1 2 0 0 0 0 1 1 0 230 1 1.1 0.0; @@ -24,10 +26,11 @@ mpc.bus = [ ]; )"}; -} // namespace +} // namespace -int main(int argc, char** argv) { - int fail = 0; +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}, @@ -37,30 +40,32 @@ int main(int argc, char** argv) { }; std::vector> load_answer{ - {1, 0, 0}, - {2, 300, 98.61}, - {3, 300, 98.61}, + {1, 0, 0}, + {2, 300, 98.61}, + {3, 300, 98.61}, {4, 400, 131.47}, - {5, 0, 0}, + {5, 0, 0}, }; { SystemModelData mp; - std::istringstream iss(matpower_data); + std::istringstream iss(matpower_data); GridKit::readMatPower(mp, iss); - if (!isEqual(mp.bus, bus_answer)) fail++; + if (!isEqual(mp.bus, bus_answer)) + fail++; std::cout << "After reading the bus component, fail == " << fail << "\n"; } { SystemModelData mp; - std::istringstream iss(matpower_data); + std::istringstream iss(matpower_data); GridKit::readMatPower(mp, iss); - if (!isEqual(mp.load, load_answer)) fail++; + if (!isEqual(mp.load, load_answer)) + fail++; std::cout << "After reading the bus component, fail == " << fail << "\n"; } - std::cout << "Tests " << (fail?"FAILED":"PASSED") << "\n"; + std::cout << "Tests " << (fail ? "FAILED" : "PASSED") << "\n"; return fail; } diff --git a/examples/MatPowerTesting/test_parse_gen_row.cpp b/examples/MatPowerTesting/test_parse_gen_row.cpp index b524ae89..63a1d550 100644 --- a/examples/MatPowerTesting/test_parse_gen_row.cpp +++ b/examples/MatPowerTesting/test_parse_gen_row.cpp @@ -1,19 +1,21 @@ +#include + #include #include #include -#include using namespace GridKit; using namespace GridKit::Testing; using namespace GridKit::PowerSystemData; -namespace { +namespace +{ -using IdxT = int; -using RealT = double; + using IdxT = int; + using RealT = double; -static const std::string matpower_data{ - R"( + static const std::string matpower_data{ + 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 = [ @@ -28,17 +30,15 @@ mpc.gen = [ } // namespace -int main(int argc, char **argv) { - int fail = 0; +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}, + {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}}; + {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/MatPowerTesting/test_parse_gencost_row.cpp b/examples/MatPowerTesting/test_parse_gencost_row.cpp index efc409d8..adddc1ed 100644 --- a/examples/MatPowerTesting/test_parse_gencost_row.cpp +++ b/examples/MatPowerTesting/test_parse_gencost_row.cpp @@ -1,19 +1,21 @@ +#include + #include #include #include -#include using namespace GridKit; using namespace GridKit::Testing; using namespace GridKit::PowerSystemData; -namespace { +namespace +{ -using IdxT = int; -using RealT = double; + using IdxT = int; + using RealT = double; -static const std::string matpower_data{ - R"( + static const std::string matpower_data{ + R"( %%----- OPF Data -----%% %% generator cost data @@ -31,11 +33,14 @@ mpc.gencost = [ } // namespace -int main(int argc, char **argv) { - int fail = 0; +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, 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/MatPowerTesting/test_parse_matpower.cpp b/examples/MatPowerTesting/test_parse_matpower.cpp index fa926cad..2994804b 100644 --- a/examples/MatPowerTesting/test_parse_matpower.cpp +++ b/examples/MatPowerTesting/test_parse_matpower.cpp @@ -1,19 +1,21 @@ +#include + #include #include #include -#include using namespace GridKit; using namespace GridKit::Testing; using namespace GridKit::PowerSystemData; -namespace { +namespace +{ -using IdxT = int; -using RealT = double; + using IdxT = int; + using RealT = double; -static const std::string matpower_data{ - R"( + static const std::string matpower_data{ + 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. @@ -81,16 +83,17 @@ mpc.gencost = [ } // namespace -int main(int argc, char **argv) { +int main(int argc, char** argv) +{ int fail = 0; // All types will use the scalar types at the top of the file - using BusDataT = BusData; - using GenDataT = GenData; - using BranchDataT = BranchData; - using GenCostDataT = GenCostData; + using BusDataT = BusData; + using GenDataT = GenData; + using BranchDataT = BranchData; + using GenCostDataT = GenCostData; using SystemModelDataT = SystemModelData; - using LoadDataT = LoadData; + using LoadDataT = LoadData; // Create the struct of expected values std::vector branch_answer{ @@ -110,33 +113,31 @@ int main(int argc, char **argv) { }; 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}, + {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}}; + {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, 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}, + {1, 0, 0}, + {2, 300, 98.61}, + {3, 300, 98.61}, {4, 400, 131.47}, - {5, 0, 0}, + {5, 0, 0}, }; - SystemModelDataT mp_answer; mp_answer.gencost = gencost_answer; - mp_answer.gen = gen_answer; - mp_answer.bus = bus_answer; - mp_answer.branch = branch_answer; - mp_answer.load = load_answer; + mp_answer.gen = gen_answer; + mp_answer.bus = bus_answer; + mp_answer.branch = branch_answer; + mp_answer.load = load_answer; mp_answer.version = "2"; mp_answer.baseMVA = 100; diff --git a/examples/Microgrid/Microgrid.cpp b/examples/Microgrid/Microgrid.cpp index 75c70fdd..a3afb966 100644 --- a/examples/Microgrid/Microgrid.cpp +++ b/examples/Microgrid/Microgrid.cpp @@ -1,445 +1,433 @@ - -#include -#include #include -#include #include - +#include +#include +#include #include +#include #include #include -#include - #include -#include #include +#include - -int main(int argc, char const *argv[]) +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) - double abs_tol = 1.0e-8; - double rel_tol = 1.0e-8; - size_t max_step_amount = 3000; - bool use_jac = true; - - //Create model - GridKit::PowerElectronicsModel* sysmodel = new GridKit::PowerElectronicsModel(rel_tol, abs_tol, use_jac, max_step_amount); - - //Modeled after the problem in the paper - double RN = 1.0e4; - - //DG Params - GridKit::DistributedGeneratorParameters parms1; - parms1.wb_ = 2.0*M_PI*50.0; - parms1.wc_ = 31.41; - parms1.mp_ = 9.4e-5; - parms1.Vn_ = 380.0; - parms1.nq_ = 1.3e-3; - parms1.F_ = 0.75; - parms1.Kiv_ = 420.0; - parms1.Kpv_ = 0.1; - parms1.Kic_ = 2.0e4; - parms1.Kpc_ = 15.0; - parms1.Cf_ = 5.0e-5; - parms1.rLf_ = 0.1; - parms1.Lf_ = 1.35e-3; - parms1.rLc_ = 0.03; - parms1.Lc_ = 0.35e-3; - - GridKit::DistributedGeneratorParameters parms2; - //Parameters from MATLAB Microgrid code for first DG - parms2.wb_ = 2.0*M_PI*50.0; - parms2.wc_ = 31.41; - parms2.mp_ = 12.5e-5; - parms2.Vn_ = 380.0; - parms2.nq_ = 1.5e-3; - parms2.F_ = 0.75; - parms2.Kiv_ = 390.0; - parms2.Kpv_ = 0.05; - parms2.Kic_ = 16.0e3; - parms2.Kpc_ = 10.5; - parms2.Cf_ = 50.0e-6; - parms2.rLf_ = 0.1; - parms2.Lf_ = 1.35e-3; - parms2.rLc_ = 0.03; - parms2.Lc_ = 0.35e-3; - - //Line params - double rline1 = 0.23; - double Lline1 = 0.1 / (2.0 * M_PI * 50.0); - - double rline2 = 0.35; - double Lline2 = 0.58 / (2.0 * M_PI * 50.0); - - double rline3 = 0.23; - double Lline3 = 0.1 / (2.0 * M_PI * 50.0); - - //load parms - double rload1 = 3.0; - double Lload1 = 2.0 / (2.0 * M_PI * 50.0); - - double rload2 = 2.0; - double Lload2 = 1.0 / (2.0 * M_PI * 50.0); - - - //indexing sets - size_t Nsize = 2; - // DGs + - refframe Lines + Loads - size_t vec_size_internals = 13*(2*Nsize) - 1 + (2 + 4*(Nsize - 1)) + 2*Nsize; - // \omegaref + BusDQ - size_t vec_size_externals = 1 + 2*(2*Nsize); - size_t dqbus1 = vec_size_internals + 1; - size_t dqbus2 = vec_size_internals + 3; - size_t dqbus3 = vec_size_internals + 5; - size_t dqbus4 = vec_size_internals + 7; - - size_t vec_size_total = vec_size_internals + vec_size_externals; - - - size_t indexv = 0; - - //dg 1 - GridKit::DistributedGenerator *dg1 = new GridKit::DistributedGenerator(0, parms1, true); - //ref motor - dg1->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg1->setExternalConnectionNodes(1,dqbus1); - dg1->setExternalConnectionNodes(2,dqbus1 + 1); - //"grounding" of the difference - dg1->setExternalConnectionNodes(3,-1); - //internal connections - for (size_t i = 0; i < 12; i++) - { - - dg1->setExternalConnectionNodes(4 + i,indexv + i); - } - indexv += 12; - sysmodel->addComponent(dg1); - - //dg 2 - GridKit::DistributedGenerator *dg2 = new GridKit::DistributedGenerator(1, parms1, false); - //ref motor - dg2->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg2->setExternalConnectionNodes(1,dqbus2); - dg2->setExternalConnectionNodes(2,dqbus2 + 1); - //internal connections - for (size_t i = 0; i < 13; i++) - { - - dg2->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 13; - sysmodel->addComponent(dg2); - - - //dg 3 - GridKit::DistributedGenerator *dg3 = new GridKit::DistributedGenerator(2, parms2, false); - //ref motor - dg3->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg3->setExternalConnectionNodes(1,dqbus3); - dg3->setExternalConnectionNodes(2,dqbus3 + 1); - //internal connections - for (size_t i = 0; i < 13; i++) - { - - dg3->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 13; - sysmodel->addComponent(dg3); - - - //dg 4 - GridKit::DistributedGenerator *dg4 = new GridKit::DistributedGenerator(3, parms2, false); - //ref motor - dg4->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg4->setExternalConnectionNodes(1,dqbus4); - dg4->setExternalConnectionNodes(2,dqbus4 + 1); - - //internal connections - for (size_t i = 0; i < 13; i++) - { - - dg4->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 13; - sysmodel->addComponent(dg4); - - // Lines - - //line 1 - GridKit::MicrogridLine *l1 = new GridKit::MicrogridLine(4, rline1, Lline1); - //ref motor - l1->setExternalConnectionNodes(0,vec_size_internals); - //input connections - l1->setExternalConnectionNodes(1,dqbus1); - l1->setExternalConnectionNodes(2,dqbus1 + 1); - //output connections - l1->setExternalConnectionNodes(3,dqbus2); - l1->setExternalConnectionNodes(4,dqbus2 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - l1->setExternalConnectionNodes(5 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(l1); - - - //line 2 - GridKit::MicrogridLine *l2 = new GridKit::MicrogridLine(5, rline2, Lline2); - //ref motor - l2->setExternalConnectionNodes(0,vec_size_internals); - //input connections - l2->setExternalConnectionNodes(1,dqbus2); - l2->setExternalConnectionNodes(2,dqbus2 + 1); - //output connections - l2->setExternalConnectionNodes(3,dqbus3); - l2->setExternalConnectionNodes(4,dqbus3 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - l2->setExternalConnectionNodes(5 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(l2); - - //line 3 - GridKit::MicrogridLine *l3 = new GridKit::MicrogridLine(6, rline3, Lline3); - //ref motor - l3->setExternalConnectionNodes(0,vec_size_internals); - //input connections - l3->setExternalConnectionNodes(1,dqbus3); - l3->setExternalConnectionNodes(2,dqbus3 + 1); - //output connections - l3->setExternalConnectionNodes(3,dqbus4); - l3->setExternalConnectionNodes(4,dqbus4 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - l3->setExternalConnectionNodes(5 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(l3); - - // loads - - //load 1 - GridKit::MicrogridLoad *load1 = new GridKit::MicrogridLoad(7, rload1, Lload1); - //ref motor - load1->setExternalConnectionNodes(0,vec_size_internals); - //input connections - load1->setExternalConnectionNodes(1,dqbus1); - load1->setExternalConnectionNodes(2,dqbus1 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - load1->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(load1); - - //load 2 - GridKit::MicrogridLoad *load2 = new GridKit::MicrogridLoad(8, rload2, Lload2); - //ref motor - load2->setExternalConnectionNodes(0,vec_size_internals); - //input connections - load2->setExternalConnectionNodes(1,dqbus3); - load2->setExternalConnectionNodes(2,dqbus3 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - load2->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(load2); - - //Virtual PQ Buses - GridKit::MicrogridBusDQ *bus1 = new GridKit::MicrogridBusDQ(9, RN); - - bus1->setExternalConnectionNodes(0,dqbus1); - bus1->setExternalConnectionNodes(1,dqbus1 + 1); - sysmodel->addComponent(bus1); - - GridKit::MicrogridBusDQ *bus2 = new GridKit::MicrogridBusDQ(10, RN); - - bus2->setExternalConnectionNodes(0,dqbus2); - bus2->setExternalConnectionNodes(1,dqbus2 + 1); - sysmodel->addComponent(bus2); - - GridKit::MicrogridBusDQ *bus3 = new GridKit::MicrogridBusDQ(11, RN); - - bus3->setExternalConnectionNodes(0,dqbus3); - bus3->setExternalConnectionNodes(1,dqbus3 + 1); - sysmodel->addComponent(bus3); - - GridKit::MicrogridBusDQ *bus4 = new GridKit::MicrogridBusDQ(12, RN); - - bus4->setExternalConnectionNodes(0,dqbus4); - bus4->setExternalConnectionNodes(1,dqbus4 + 1); - sysmodel->addComponent(bus4); - - sysmodel->allocate(vec_size_total); - - std::cout << sysmodel->y().size() << std::endl; - std::cout << vec_size_internals << ", " << vec_size_externals << "\n"; - - //Create Intial points for states - for (size_t i = 0; i < vec_size_total; i++) - { - sysmodel->y()[i] = 0.0; - sysmodel->yp()[i] = 0.0; - } - - // Create Intial derivatives specifics generated in MATLAB - //DGs 1 - sysmodel->yp()[2] = parms1.Vn_; - sysmodel->yp()[4] = parms1.Kpv_ * parms1.Vn_; - sysmodel->yp()[6] = (parms1.Kpc_ * parms1.Kpv_ * parms1.Vn_) / parms1.Lf_; - sysmodel->yp()[12 + 3] = parms1.Vn_; - sysmodel->yp()[12 + 5] = parms1.Kpv_ * parms1.Vn_; - sysmodel->yp()[12 + 7] = (parms1.Kpc_ * parms1.Kpv_ * parms1.Vn_) / parms1.Lf_; - for (size_t i = 2; i < 4; i++) - { - sysmodel->yp()[13*i - 1 + 3] = parms2.Vn_; - sysmodel->yp()[13*i - 1 + 5] = parms2.Kpv_ * parms2.Vn_; - sysmodel->yp()[13*i - 1 + 7] = (parms2.Kpc_ * parms2.Kpv_ * parms2.Vn_) / parms2.Lf_; - } - - //since the intial P_com = 0 - sysmodel->y()[vec_size_internals] = parms1.wb_; - - - - sysmodel->initialize(); - sysmodel->evaluateResidual(); - - std::vector& fres = sysmodel->getResidual(); - std::cout << "Verify Intial Resisdual is Zero: {\n"; - for (size_t i = 0; i < fres.size(); i++) - { - printf("%lu : %e \n", i, fres[i]); - } - std::cout << "}\n"; - - sysmodel->updateTime(0.0, 1.0e-8); - sysmodel->evaluateJacobian(); - std::cout << "Intial Jacobian with alpha:\n"; - - //Create numerical integrator and configure it for the generator model - AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); - - double t_init = 0.0; - double t_final = 1.0; - - // setup simulation - idas->configureSimulation(); - idas->getDefaultInitialCondition(); - idas->initializeSimulation(t_init); - - idas->runSimulation(t_final); - - std::vector& yfinial = sysmodel->y(); - - std::cout << "Final Vector y\n"; - for (size_t i = 0; i < yfinial.size(); i++) - { - std::cout << yfinial[i] << "\n"; - } - - //Generate from MATLAB code ODE form with tolerances of 1e-12 - std::vectortrue_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, - -7.555954467454730e-03, - 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, - -8.273939686941580e-02, - 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.445727984408551e-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, - -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 << "Test the Relative Error\n"; - for (size_t i = 0; i < true_vec.size(); i++) - { + ///@todo Needs to be modified. Some components are small relative to others thus there error is high (or could be matlab vector issue) + double abs_tol = 1.0e-8; + double rel_tol = 1.0e-8; + size_t max_step_amount = 3000; + bool use_jac = true; + + // Create model + GridKit::PowerElectronicsModel* sysmodel = new GridKit::PowerElectronicsModel(rel_tol, abs_tol, use_jac, max_step_amount); + + // Modeled after the problem in the paper + double RN = 1.0e4; + + // DG Params + GridKit::DistributedGeneratorParameters parms1; + parms1.wb_ = 2.0 * M_PI * 50.0; + parms1.wc_ = 31.41; + parms1.mp_ = 9.4e-5; + parms1.Vn_ = 380.0; + parms1.nq_ = 1.3e-3; + parms1.F_ = 0.75; + parms1.Kiv_ = 420.0; + parms1.Kpv_ = 0.1; + parms1.Kic_ = 2.0e4; + parms1.Kpc_ = 15.0; + parms1.Cf_ = 5.0e-5; + parms1.rLf_ = 0.1; + parms1.Lf_ = 1.35e-3; + parms1.rLc_ = 0.03; + parms1.Lc_ = 0.35e-3; + + GridKit::DistributedGeneratorParameters parms2; + // Parameters from MATLAB Microgrid code for first DG + parms2.wb_ = 2.0 * M_PI * 50.0; + parms2.wc_ = 31.41; + parms2.mp_ = 12.5e-5; + parms2.Vn_ = 380.0; + parms2.nq_ = 1.5e-3; + parms2.F_ = 0.75; + parms2.Kiv_ = 390.0; + parms2.Kpv_ = 0.05; + parms2.Kic_ = 16.0e3; + parms2.Kpc_ = 10.5; + parms2.Cf_ = 50.0e-6; + parms2.rLf_ = 0.1; + parms2.Lf_ = 1.35e-3; + parms2.rLc_ = 0.03; + parms2.Lc_ = 0.35e-3; + + // Line params + double rline1 = 0.23; + double Lline1 = 0.1 / (2.0 * M_PI * 50.0); + + double rline2 = 0.35; + double Lline2 = 0.58 / (2.0 * M_PI * 50.0); + + double rline3 = 0.23; + double Lline3 = 0.1 / (2.0 * M_PI * 50.0); + + // load parms + double rload1 = 3.0; + double Lload1 = 2.0 / (2.0 * M_PI * 50.0); + + double rload2 = 2.0; + double Lload2 = 1.0 / (2.0 * M_PI * 50.0); + + // indexing sets + size_t Nsize = 2; + // DGs + - refframe Lines + Loads + size_t vec_size_internals = 13 * (2 * Nsize) - 1 + (2 + 4 * (Nsize - 1)) + 2 * Nsize; + // \omegaref + BusDQ + size_t vec_size_externals = 1 + 2 * (2 * Nsize); + size_t dqbus1 = vec_size_internals + 1; + size_t dqbus2 = vec_size_internals + 3; + size_t dqbus3 = vec_size_internals + 5; + size_t dqbus4 = vec_size_internals + 7; + + size_t vec_size_total = vec_size_internals + vec_size_externals; + + size_t indexv = 0; + + // dg 1 + GridKit::DistributedGenerator* dg1 = new GridKit::DistributedGenerator(0, parms1, true); + // ref motor + dg1->setExternalConnectionNodes(0, vec_size_internals); + // outputs + dg1->setExternalConnectionNodes(1, dqbus1); + dg1->setExternalConnectionNodes(2, dqbus1 + 1); + //"grounding" of the difference + dg1->setExternalConnectionNodes(3, -1); + // internal connections + for (size_t i = 0; i < 12; i++) + { + + dg1->setExternalConnectionNodes(4 + i, indexv + i); + } + indexv += 12; + sysmodel->addComponent(dg1); + + // dg 2 + GridKit::DistributedGenerator* dg2 = new GridKit::DistributedGenerator(1, parms1, false); + // ref motor + dg2->setExternalConnectionNodes(0, vec_size_internals); + // outputs + dg2->setExternalConnectionNodes(1, dqbus2); + dg2->setExternalConnectionNodes(2, dqbus2 + 1); + // internal connections + for (size_t i = 0; i < 13; i++) + { + + dg2->setExternalConnectionNodes(3 + i, indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg2); + + // dg 3 + GridKit::DistributedGenerator* dg3 = new GridKit::DistributedGenerator(2, parms2, false); + // ref motor + dg3->setExternalConnectionNodes(0, vec_size_internals); + // outputs + dg3->setExternalConnectionNodes(1, dqbus3); + dg3->setExternalConnectionNodes(2, dqbus3 + 1); + // internal connections + for (size_t i = 0; i < 13; i++) + { + + dg3->setExternalConnectionNodes(3 + i, indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg3); + + // dg 4 + GridKit::DistributedGenerator* dg4 = new GridKit::DistributedGenerator(3, parms2, false); + // ref motor + dg4->setExternalConnectionNodes(0, vec_size_internals); + // outputs + dg4->setExternalConnectionNodes(1, dqbus4); + dg4->setExternalConnectionNodes(2, dqbus4 + 1); + + // internal connections + for (size_t i = 0; i < 13; i++) + { + + dg4->setExternalConnectionNodes(3 + i, indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg4); + + // Lines + + // line 1 + GridKit::MicrogridLine* l1 = new GridKit::MicrogridLine(4, rline1, Lline1); + // ref motor + l1->setExternalConnectionNodes(0, vec_size_internals); + // input connections + l1->setExternalConnectionNodes(1, dqbus1); + l1->setExternalConnectionNodes(2, dqbus1 + 1); + // output connections + l1->setExternalConnectionNodes(3, dqbus2); + l1->setExternalConnectionNodes(4, dqbus2 + 1); + // internal connections + for (size_t i = 0; i < 2; i++) + { + + l1->setExternalConnectionNodes(5 + i, indexv + i); + } + indexv += 2; + sysmodel->addComponent(l1); + + // line 2 + GridKit::MicrogridLine* l2 = new GridKit::MicrogridLine(5, rline2, Lline2); + // ref motor + l2->setExternalConnectionNodes(0, vec_size_internals); + // input connections + l2->setExternalConnectionNodes(1, dqbus2); + l2->setExternalConnectionNodes(2, dqbus2 + 1); + // output connections + l2->setExternalConnectionNodes(3, dqbus3); + l2->setExternalConnectionNodes(4, dqbus3 + 1); + // internal connections + for (size_t i = 0; i < 2; i++) + { + + l2->setExternalConnectionNodes(5 + i, indexv + i); + } + indexv += 2; + sysmodel->addComponent(l2); + + // line 3 + GridKit::MicrogridLine* l3 = new GridKit::MicrogridLine(6, rline3, Lline3); + // ref motor + l3->setExternalConnectionNodes(0, vec_size_internals); + // input connections + l3->setExternalConnectionNodes(1, dqbus3); + l3->setExternalConnectionNodes(2, dqbus3 + 1); + // output connections + l3->setExternalConnectionNodes(3, dqbus4); + l3->setExternalConnectionNodes(4, dqbus4 + 1); + // internal connections + for (size_t i = 0; i < 2; i++) + { + + l3->setExternalConnectionNodes(5 + i, indexv + i); + } + indexv += 2; + sysmodel->addComponent(l3); + + // loads + + // load 1 + GridKit::MicrogridLoad* load1 = new GridKit::MicrogridLoad(7, rload1, Lload1); + // ref motor + load1->setExternalConnectionNodes(0, vec_size_internals); + // input connections + load1->setExternalConnectionNodes(1, dqbus1); + load1->setExternalConnectionNodes(2, dqbus1 + 1); + // internal connections + for (size_t i = 0; i < 2; i++) + { + + load1->setExternalConnectionNodes(3 + i, indexv + i); + } + indexv += 2; + sysmodel->addComponent(load1); + + // load 2 + GridKit::MicrogridLoad* load2 = new GridKit::MicrogridLoad(8, rload2, Lload2); + // ref motor + load2->setExternalConnectionNodes(0, vec_size_internals); + // input connections + load2->setExternalConnectionNodes(1, dqbus3); + load2->setExternalConnectionNodes(2, dqbus3 + 1); + // internal connections + for (size_t i = 0; i < 2; i++) + { + + load2->setExternalConnectionNodes(3 + i, indexv + i); + } + indexv += 2; + sysmodel->addComponent(load2); + + // Virtual PQ Buses + GridKit::MicrogridBusDQ* bus1 = new GridKit::MicrogridBusDQ(9, RN); + + bus1->setExternalConnectionNodes(0, dqbus1); + bus1->setExternalConnectionNodes(1, dqbus1 + 1); + sysmodel->addComponent(bus1); + + GridKit::MicrogridBusDQ* bus2 = new GridKit::MicrogridBusDQ(10, RN); + + bus2->setExternalConnectionNodes(0, dqbus2); + bus2->setExternalConnectionNodes(1, dqbus2 + 1); + sysmodel->addComponent(bus2); + + GridKit::MicrogridBusDQ* bus3 = new GridKit::MicrogridBusDQ(11, RN); + + bus3->setExternalConnectionNodes(0, dqbus3); + bus3->setExternalConnectionNodes(1, dqbus3 + 1); + sysmodel->addComponent(bus3); + + GridKit::MicrogridBusDQ* bus4 = new GridKit::MicrogridBusDQ(12, RN); + + bus4->setExternalConnectionNodes(0, dqbus4); + bus4->setExternalConnectionNodes(1, dqbus4 + 1); + sysmodel->addComponent(bus4); + + sysmodel->allocate(vec_size_total); + + std::cout << sysmodel->y().size() << std::endl; + std::cout << vec_size_internals << ", " << vec_size_externals << "\n"; + + // Create Intial points for states + for (size_t i = 0; i < vec_size_total; i++) + { + sysmodel->y()[i] = 0.0; + sysmodel->yp()[i] = 0.0; + } + + // Create Intial derivatives specifics generated in MATLAB + // DGs 1 + sysmodel->yp()[2] = parms1.Vn_; + sysmodel->yp()[4] = parms1.Kpv_ * parms1.Vn_; + sysmodel->yp()[6] = (parms1.Kpc_ * parms1.Kpv_ * parms1.Vn_) / parms1.Lf_; + sysmodel->yp()[12 + 3] = parms1.Vn_; + sysmodel->yp()[12 + 5] = parms1.Kpv_ * parms1.Vn_; + sysmodel->yp()[12 + 7] = (parms1.Kpc_ * parms1.Kpv_ * parms1.Vn_) / parms1.Lf_; + for (size_t i = 2; i < 4; i++) + { + sysmodel->yp()[13 * i - 1 + 3] = parms2.Vn_; + sysmodel->yp()[13 * i - 1 + 5] = parms2.Kpv_ * parms2.Vn_; + sysmodel->yp()[13 * i - 1 + 7] = (parms2.Kpc_ * parms2.Kpv_ * parms2.Vn_) / parms2.Lf_; + } + + // since the intial P_com = 0 + sysmodel->y()[vec_size_internals] = parms1.wb_; + + sysmodel->initialize(); + sysmodel->evaluateResidual(); + + std::vector& fres = sysmodel->getResidual(); + std::cout << "Verify Intial Resisdual is Zero: {\n"; + for (size_t i = 0; i < fres.size(); i++) + { + printf("%lu : %e \n", i, fres[i]); + } + std::cout << "}\n"; + + sysmodel->updateTime(0.0, 1.0e-8); + sysmodel->evaluateJacobian(); + std::cout << "Intial Jacobian with alpha:\n"; + + // Create numerical integrator and configure it for the generator model + AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); + + double t_init = 0.0; + double t_final = 1.0; + + // setup simulation + idas->configureSimulation(); + idas->getDefaultInitialCondition(); + idas->initializeSimulation(t_init); + + idas->runSimulation(t_final); + + std::vector& yfinial = sysmodel->y(); + + std::cout << "Final Vector y\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << yfinial[i] << "\n"; + } + + // Generate 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, + -7.555954467454730e-03, + 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, + -8.273939686941580e-02, + 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.445727984408551e-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, + -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 << "Test the Relative Error\n"; + for (size_t i = 0; i < true_vec.size(); i++) + { printf("%lu : %e ,\n", i, abs(true_vec[i] - yfinial[i]) / abs(true_vec[i])); - } + } - delete idas; - delete sysmodel; + delete idas; + delete sysmodel; - return 0; + return 0; } diff --git a/examples/ParameterEstimation/ParameterEstimation.cpp b/examples/ParameterEstimation/ParameterEstimation.cpp index d8a683c1..704d59bf 100644 --- a/examples/ParameterEstimation/ParameterEstimation.cpp +++ b/examples/ParameterEstimation/ParameterEstimation.cpp @@ -57,169 +57,164 @@ * */ - -#include #include +#include #include +#include "lookup_table.hpp" #include #include - -#include -#include #include #include #include #include - +#include +#include #include #include -#include "lookup_table.hpp" - - int main() { - using namespace GridKit; - using namespace AnalysisManager::Sundials; - using namespace AnalysisManager; - using namespace GridKit::Testing; - - // Create an infinite bus - BaseBus* bus = new BusSlack(1.0, 0.0); - - // Attach a generator to that bus - Generator4Param* gen = new Generator4Param(bus); - - // Create a system model - SystemModel* model = new SystemModel(); - model->addBus(bus); - model->addComponent(gen); - - // allocate model components - model->allocate(); - - // Create numerical integrator and configure it for the generator model - Ida* idas = new Ida(model); - - double t_init = -1.0; - double t_final = -1.0; - - std::istringstream input_data(lookup_table); - GridKit::setLookupTable(gen->getLookupTable(), input_data, t_init, t_final); - - std::cout << "Performing parameter estimation with respect to data\nfrom " - << "t_init = " << t_init << " to t_final = " << t_final << "\n"; - - // setup simulation - idas->configureSimulation(); - idas->configureAdjoint(); - idas->getDefaultInitialCondition(); + using namespace GridKit; + using namespace AnalysisManager::Sundials; + using namespace AnalysisManager; + using namespace GridKit::Testing; + + // Create an infinite bus + BaseBus* bus = new BusSlack(1.0, 0.0); + + // Attach a generator to that bus + Generator4Param* gen = new Generator4Param(bus); + + // Create a system model + SystemModel* model = new SystemModel(); + model->addBus(bus); + model->addComponent(gen); + + // allocate model components + model->allocate(); + + // Create numerical integrator and configure it for the generator model + Ida* idas = new Ida(model); + + double t_init = -1.0; + double t_final = -1.0; + + std::istringstream input_data(lookup_table); + GridKit::setLookupTable(gen->getLookupTable(), input_data, t_init, t_final); + + std::cout << "Performing parameter estimation with respect to data\nfrom " + << "t_init = " << t_init << " to t_final = " << t_final << "\n"; + + // setup simulation + idas->configureSimulation(); + idas->configureAdjoint(); + idas->getDefaultInitialCondition(); + idas->initializeSimulation(t_init); + idas->configureQuadrature(); + idas->initializeQuadrature(); + + double t_fault = 0.1; + double t_clear = 0.1; + idas->runSimulation(t_fault); + idas->saveInitialCondition(); + // create initial condition after a fault + { + idas->getSavedInitialCondition(); idas->initializeSimulation(t_init); - idas->configureQuadrature(); - idas->initializeQuadrature(); - - double t_fault = 0.1; - double t_clear = 0.1; - idas->runSimulation(t_fault); + gen->V() = 0.0; + idas->runSimulation(t_clear, 20); + gen->V() = 1.0; idas->saveInitialCondition(); - // create initial condition after a fault - { - idas->getSavedInitialCondition(); - idas->initializeSimulation(t_init); - gen->V() = 0.0; - idas->runSimulation(t_clear, 20); - gen->V() = 1.0; - idas->saveInitialCondition(); - } - - // Set integration time for dynamic constrained optimization - idas->setIntegrationTime(t_init, t_final, 100); - - // Guess value of inertia coefficient - model->param()[0] = 3.0; - - // Create an instance of the IpoptApplication - Ipopt::SmartPtr ipoptApp = IpoptApplicationFactory(); - - // Set solver tolerance - const double tol = 1e-5; - - // Initialize the IpoptApplication and process the options - Ipopt::ApplicationReturnStatus status; - status = ipoptApp->Initialize(); - if (status != Ipopt::Solve_Succeeded) - { - std::cout << "\n\n*** Initialization failed! ***\n\n"; - return (int) status; - } - - // Configure Ipopt application - ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); - ipoptApp->Options()->SetNumericValue("tol", tol); - ipoptApp->Options()->SetIntegerValue("print_level", 0); - - // Create dynamic objective interface to Ipopt solver - Ipopt::SmartPtr ipoptDynamicObjectiveInterface = - new IpoptInterface::DynamicObjective(idas); - - // Solve the problem - status = ipoptApp->OptimizeTNLP(ipoptDynamicObjectiveInterface); - std::cout << "\n\nProblem formulated as dynamic objective optimiztion ...\n"; - - if (status == Ipopt::Solve_Succeeded) - { - // Print result - std::cout << "\nSucess:\n The problem solved in " - << ipoptApp->Statistics()->IterationCount() << " iterations!\n" - << " Optimal value of H = " << model->param()[0] << "\n" - << " The final value of the objective function G(H) = " - << ipoptApp->Statistics()->FinalObjective() << "\n\n"; - } - - // Store dynamic objective optimization results - double* results = new double[model->sizeParams()]; - for(unsigned i=0; i sizeParams(); ++i) - { - results[i] = model->param()[i]; - } - - // Guess value of inertia coefficient - model->param()[0] = 3.0; - - // Create dynamic constraint interface to Ipopt solver - Ipopt::SmartPtr ipoptDynamicConstraintInterface = - new IpoptInterface::DynamicConstraint(idas); - - // Solve the problem - status = ipoptApp->OptimizeTNLP(ipoptDynamicConstraintInterface); - std::cout << "\n\nProblem formulated as dynamic constraint optimiztion ...\n"; - - if (status == Ipopt::Solve_Succeeded) - { - // Print result - std::cout << "\nSucess:\n The problem solved in " - << ipoptApp->Statistics()->IterationCount() << " iterations!\n" - << " Optimal value of H = " << model->param()[0] << "\n" - << " The final value of the objective function G(H) = " - << ipoptApp->Statistics()->FinalObjective() << "\n\n"; - } - - // Compare results of the two optimization methods - int retval = 0; - for(unsigned i=0; i sizeParams(); ++i) - { - if(!isEqual(results[i], model->param()[i], 100*tol)) - --retval; - } - - if(retval < 0) - { - std::cout << "The two results differ beyond solver tolerance!\n"; - } - - delete [] results; - delete idas; - delete model; - return retval; + } + + // Set integration time for dynamic constrained optimization + idas->setIntegrationTime(t_init, t_final, 100); + + // Guess value of inertia coefficient + model->param()[0] = 3.0; + + // Create an instance of the IpoptApplication + Ipopt::SmartPtr ipoptApp = IpoptApplicationFactory(); + + // Set solver tolerance + const double tol = 1e-5; + + // Initialize the IpoptApplication and process the options + Ipopt::ApplicationReturnStatus status; + status = ipoptApp->Initialize(); + if (status != Ipopt::Solve_Succeeded) + { + std::cout << "\n\n*** Initialization failed! ***\n\n"; + return (int) status; + } + + // Configure Ipopt application + ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); + ipoptApp->Options()->SetNumericValue("tol", tol); + ipoptApp->Options()->SetIntegerValue("print_level", 0); + + // Create dynamic objective interface to Ipopt solver + Ipopt::SmartPtr ipoptDynamicObjectiveInterface = + new IpoptInterface::DynamicObjective(idas); + + // Solve the problem + status = ipoptApp->OptimizeTNLP(ipoptDynamicObjectiveInterface); + std::cout << "\n\nProblem formulated as dynamic objective optimiztion ...\n"; + + if (status == Ipopt::Solve_Succeeded) + { + // Print result + std::cout << "\nSucess:\n The problem solved in " + << ipoptApp->Statistics()->IterationCount() << " iterations!\n" + << " Optimal value of H = " << model->param()[0] << "\n" + << " The final value of the objective function G(H) = " + << ipoptApp->Statistics()->FinalObjective() << "\n\n"; + } + + // Store dynamic objective optimization results + double* results = new double[model->sizeParams()]; + for (unsigned i = 0; i < model->sizeParams(); ++i) + { + results[i] = model->param()[i]; + } + + // Guess value of inertia coefficient + model->param()[0] = 3.0; + + // Create dynamic constraint interface to Ipopt solver + Ipopt::SmartPtr ipoptDynamicConstraintInterface = + new IpoptInterface::DynamicConstraint(idas); + + // Solve the problem + status = ipoptApp->OptimizeTNLP(ipoptDynamicConstraintInterface); + std::cout << "\n\nProblem formulated as dynamic constraint optimiztion ...\n"; + + if (status == Ipopt::Solve_Succeeded) + { + // Print result + std::cout << "\nSucess:\n The problem solved in " + << ipoptApp->Statistics()->IterationCount() << " iterations!\n" + << " Optimal value of H = " << model->param()[0] << "\n" + << " The final value of the objective function G(H) = " + << ipoptApp->Statistics()->FinalObjective() << "\n\n"; + } + + // Compare results of the two optimization methods + int retval = 0; + for (unsigned i = 0; i < model->sizeParams(); ++i) + { + if (!isEqual(results[i], model->param()[i], 100 * tol)) + --retval; + } + + if (retval < 0) + { + std::cout << "The two results differ beyond solver tolerance!\n"; + } + + delete[] results; + delete idas; + delete model; + return retval; } diff --git a/examples/ParameterEstimation/lookup_table.hpp b/examples/ParameterEstimation/lookup_table.hpp index 069ce149..ca694437 100644 --- a/examples/ParameterEstimation/lookup_table.hpp +++ b/examples/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/RLCircuit/RLCircuit.cpp b/examples/RLCircuit/RLCircuit.cpp index b6c2c7da..841395c3 100644 --- a/examples/RLCircuit/RLCircuit.cpp +++ b/examples/RLCircuit/RLCircuit.cpp @@ -1,146 +1,138 @@ -#include -#include #include -#include #include +#include +#include +#include #include #include #include -#include - #include -#include +#include #include +#include - -int main(int argc, char const *argv[]) +int main(int argc, char const* argv[]) { - double abs_tol = 1.0e-8; - double rel_tol = 1.0e-8; - bool use_jac = true; - - //TODO:setup as named parameters - //Create circuit model - auto* sysmodel = new GridKit::PowerElectronicsModel(rel_tol, abs_tol, use_jac); - - size_t idoff = 0; - - //RL circuit parameters - double rinit = 1.0; - double linit = 1.0; - double vinit = 1.0; - - - //inductor - GridKit::Inductor* induct = new GridKit::Inductor(idoff,linit); - //Form index to node uid realations - // input - induct->setExternalConnectionNodes(0,1); - //output - induct->setExternalConnectionNodes(1,-1); - //internal - induct->setExternalConnectionNodes(2,2); - //add component - sysmodel->addComponent(induct); - - - //resistor - idoff++; - GridKit::Resistor* resis = new GridKit::Resistor(idoff, rinit); - //Form index to node uid realations - //input - resis->setExternalConnectionNodes(0,0); - //output - resis->setExternalConnectionNodes(1,1); - //add - sysmodel->addComponent(resis); - - //voltage source - idoff++; - GridKit::VoltageSource* vsource = new GridKit::VoltageSource(idoff, vinit); - //Form index to node uid realations - //input - vsource->setExternalConnectionNodes(0,-1); - //output - vsource->setExternalConnectionNodes(1,0); - //internal - vsource->setExternalConnectionNodes(2,3); - - - sysmodel->addComponent(vsource); - - sysmodel->allocate(4); - - std::cout << sysmodel->y().size() << std::endl; - - //Grounding for IDA. If no grounding then circuit is \mu > 1 - //v_0 (grounded) - //Create Intial points - sysmodel->y()[0] = vinit; //v_1 - sysmodel->y()[1] = vinit; // v_2 - sysmodel->y()[2] = 0.0; // i_L - sysmodel->y()[3] = 0.0; // i_s - - sysmodel->yp()[0] = 0.0; // v'_1 - sysmodel->yp()[1] = 0.0; // v'_2 - sysmodel->yp()[2] = -vinit / linit; // i'_s - sysmodel->yp()[3] = -vinit / linit; // i'_L - - - sysmodel->initialize(); - sysmodel->evaluateResidual(); - - std::cout << "Verify Intial Resisdual is Zero: {"; - for (double i : sysmodel->getResidual()) - { - std::cout << i << ", "; - } - std::cout << "}\n"; - - - sysmodel->updateTime(0.0, 1.0); - sysmodel->evaluateJacobian(); - std::cout << "Intial Jacobian with alpha = 1:\n"; - sysmodel->getJacobian().printMatrix(); - - - // Create numerical integrator and configure it for the generator model - AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); - - double t_init = 0.0; - double t_final = 1.0; - - // setup simulation - idas->configureSimulation(); - idas->getDefaultInitialCondition(); - idas->initializeSimulation(t_init); - - idas->runSimulation(t_final); - - std::vector& yfinial = sysmodel->y(); - - std::cout << "Final Vector y\n"; - for (size_t i = 0; i < yfinial.size(); i++) - { - std::cout << yfinial[i] << "\n"; - } - - std::vector yexact(4); - - //analytical solution to the circuit - yexact[0] = vinit; - yexact[2] = (vinit / rinit) * (exp(-(rinit / linit) * t_final) - 1.0); - yexact[3] = yexact[2]; - yexact[1] = vinit + rinit * yexact[2]; - - std::cout << "Element-wise Relative error at t=" << t_final << "\n"; - for (size_t i = 0; i < yfinial.size(); i++) - { - std::cout << abs((yfinial[i] - yexact[i]) / yexact[i]) << "\n"; - } - - return 0; + double abs_tol = 1.0e-8; + double rel_tol = 1.0e-8; + bool use_jac = true; + + // TODO:setup as named parameters + // Create circuit model + auto* sysmodel = new GridKit::PowerElectronicsModel(rel_tol, abs_tol, use_jac); + + size_t idoff = 0; + + // RL circuit parameters + double rinit = 1.0; + double linit = 1.0; + double vinit = 1.0; + + // inductor + GridKit::Inductor* induct = new GridKit::Inductor(idoff, linit); + // Form index to node uid realations + // input + induct->setExternalConnectionNodes(0, 1); + // output + induct->setExternalConnectionNodes(1, -1); + // internal + induct->setExternalConnectionNodes(2, 2); + // add component + sysmodel->addComponent(induct); + + // resistor + idoff++; + GridKit::Resistor* resis = new GridKit::Resistor(idoff, rinit); + // Form index to node uid realations + // input + resis->setExternalConnectionNodes(0, 0); + // output + resis->setExternalConnectionNodes(1, 1); + // add + sysmodel->addComponent(resis); + + // voltage source + idoff++; + GridKit::VoltageSource* vsource = new GridKit::VoltageSource(idoff, vinit); + // Form index to node uid realations + // input + vsource->setExternalConnectionNodes(0, -1); + // output + vsource->setExternalConnectionNodes(1, 0); + // internal + vsource->setExternalConnectionNodes(2, 3); + + sysmodel->addComponent(vsource); + + sysmodel->allocate(4); + + std::cout << sysmodel->y().size() << std::endl; + + // Grounding for IDA. If no grounding then circuit is \mu > 1 + // v_0 (grounded) + // Create Intial points + sysmodel->y()[0] = vinit; // v_1 + sysmodel->y()[1] = vinit; // v_2 + sysmodel->y()[2] = 0.0; // i_L + sysmodel->y()[3] = 0.0; // i_s + + sysmodel->yp()[0] = 0.0; // v'_1 + sysmodel->yp()[1] = 0.0; // v'_2 + sysmodel->yp()[2] = -vinit / linit; // i'_s + sysmodel->yp()[3] = -vinit / linit; // i'_L + + sysmodel->initialize(); + sysmodel->evaluateResidual(); + + std::cout << "Verify Intial Resisdual is Zero: {"; + for (double i : sysmodel->getResidual()) + { + std::cout << i << ", "; + } + std::cout << "}\n"; + + sysmodel->updateTime(0.0, 1.0); + sysmodel->evaluateJacobian(); + std::cout << "Intial Jacobian with alpha = 1:\n"; + sysmodel->getJacobian().printMatrix(); + + // Create numerical integrator and configure it for the generator model + AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); + + double t_init = 0.0; + double t_final = 1.0; + + // setup simulation + idas->configureSimulation(); + idas->getDefaultInitialCondition(); + idas->initializeSimulation(t_init); + + idas->runSimulation(t_final); + + std::vector& yfinial = sysmodel->y(); + + std::cout << "Final Vector y\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << yfinial[i] << "\n"; + } + + std::vector yexact(4); + + // analytical solution to the circuit + yexact[0] = vinit; + yexact[2] = (vinit / rinit) * (exp(-(rinit / linit) * t_final) - 1.0); + yexact[3] = yexact[2]; + yexact[1] = vinit + rinit * yexact[2]; + + std::cout << "Element-wise Relative error at t=" << t_final << "\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << abs((yfinial[i] - yexact[i]) / yexact[i]) << "\n"; + } + + return 0; } diff --git a/examples/ScaleMicrogrid/ScaleMicrogrid.cpp b/examples/ScaleMicrogrid/ScaleMicrogrid.cpp index 496eb8c0..819c4f76 100644 --- a/examples/ScaleMicrogrid/ScaleMicrogrid.cpp +++ b/examples/ScaleMicrogrid/ScaleMicrogrid.cpp @@ -1,61 +1,58 @@ -#include -#include #include -#include #include - -#include +#include +#include +#include #include +#include #include #include -#include - #include -#include #include +#include +#include using index_type = size_t; -using real_type = double; +using real_type = double; // 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); /** - * @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 unsued - * @return int + * @return int */ -int main(int argc, char const *argv[]) +int main(int argc, char const* argv[]) { - int retval = 0; - bool debug_out = false; - real_type tol = SCALE_MICROGRID_ERROR_TOL; - - retval += test(2, tol, debug_out); - retval += test(4, tol, debug_out); - retval += test(8, tol, debug_out); - if (retval > 0) - { - std::cout << "Some tests fail!!\n"; - } - else - { - std::cout << "All tests pass!!\n"; - } - return retval; + int retval = 0; + bool debug_out = false; + real_type tol = SCALE_MICROGRID_ERROR_TOL; + + retval += test(2, tol, debug_out); + retval += test(4, tol, debug_out); + retval += test(8, tol, debug_out); + if (retval > 0) + { + std::cout << "Some tests fail!!\n"; + } + else + { + std::cout << "All tests pass!!\n"; + } + return retval; } /** * @brief Tests network of distributed generators. - * + * * @param Nsize - The number of DG line load cobinations to generate for scale * @param error_tol - The tolerance for the model to meet to pass * @param debug_output - Enable debug output @@ -64,326 +61,321 @@ int main(int argc, char const *argv[]) */ int test(index_type Nsize, real_type error_tol, bool debug_output) { - using namespace GridKit; - - bool use_jac = true; - - real_type t_init = 0.0; - real_type t_final = 1.0; - - real_type rel_tol = SCALE_MICROGRID_REL_TOL; - real_type abs_tol = SCALE_MICROGRID_ABS_TOL; - - // Create circuit model - auto* sysmodel = new PowerElectronicsModel(rel_tol, - abs_tol, - use_jac, - SCALE_MICROGRID_MAX_STEPS); - - const std::vector* true_vec = &answer_key_N8; - - switch (Nsize) - { - case 2: - true_vec = &answer_key_N2; - break; - case 4: - true_vec = &answer_key_N4; - break; - case 8: - // true_vec = &answer_key_N8; - break; - default: - std::cout << "No reference solution for Nsize = " << Nsize << ".\n"; - std::cout << "Using default Nsize = 8.\n"; - } - - - // Modeled after the problem in the paper - // Every Bus has the same virtual resistance. This is due to the numerical stability as mentioned in the paper. - real_type RN = 1.0e4; - - // DG Params Vector - // All DGs have the same set of parameters except for the first two. - GridKit::DistributedGeneratorParameters DG_parms1; - DG_parms1.wb_ = 2.0*M_PI*50.0; - DG_parms1.wc_ = 31.41; - DG_parms1.mp_ = 9.4e-5; - DG_parms1.Vn_ = 380.0; - DG_parms1.nq_ = 1.3e-3; - DG_parms1.F_ = 0.75; - DG_parms1.Kiv_ = 420.0; - DG_parms1.Kpv_ = 0.1; - DG_parms1.Kic_ = 2.0e4; - DG_parms1.Kpc_ = 15.0; - DG_parms1.Cf_ = 5.0e-5; - DG_parms1.rLf_ = 0.1; - DG_parms1.Lf_ = 1.35e-3; - DG_parms1.rLc_ = 0.03; - DG_parms1.Lc_ = 0.35e-3; - - GridKit::DistributedGeneratorParameters DG_parms2; - DG_parms2.wb_ = 2.0*M_PI*50.0; - DG_parms2.wc_ = 31.41; - DG_parms2.mp_ = 12.5e-5; - DG_parms2.Vn_ = 380.0; - DG_parms2.nq_ = 1.5e-3; - DG_parms2.F_ = 0.75; - DG_parms2.Kiv_ = 390.0; - DG_parms2.Kpv_ = 0.05; - DG_parms2.Kic_ = 16.0e3; - DG_parms2.Kpc_ = 10.5; - DG_parms2.Cf_ = 50.0e-6; - DG_parms2.rLf_ = 0.1; - DG_parms2.Lf_ = 1.35e-3; - DG_parms2.rLc_ = 0.03; - DG_parms2.Lc_ = 0.35e-3; - - std::vector> DGParams_list(2*Nsize, DG_parms2); - - DGParams_list[0] = DG_parms1; - DGParams_list[1] = DG_parms1; - - //line vector params - //Every odd line has the same parameters and every even line has the same parameters - real_type rline1 = 0.23; - real_type Lline1 = 0.1 / (2.0 * M_PI * 50.0); - real_type rline2 = 0.35; - real_type Lline2 = 0.58 / (2.0 * M_PI * 50.0); - std::vector rline_list(2*Nsize-1, 0.0); - std::vector Lline_list(2*Nsize-1, 0.0); - for (index_type i = 0; i < rline_list.size(); i++) - { - rline_list[i] = (i % 2) ? rline2 : rline1; - Lline_list[i] = (i % 2) ? Lline2 : Lline1; - } - - - //load parms - //Only the first load has the same paramaters. - real_type rload1 = 3.0; - real_type Lload1 = 2.0 / (2.0 * M_PI * 50.0); - real_type rload2 = 2.0; - real_type Lload2 = 1.0 / (2.0 * M_PI * 50.0); - - std::vector rload_list(Nsize, rload2); - std::vector Lload_list(Nsize, Lload2); - rload_list[0] = rload1; - Lload_list[0] = Lload1; - - // DGs + - refframe Lines + Loads - index_type vec_size_internals = 13*(2*Nsize) - 1 + (2 + 4*(Nsize - 1)) + 2*Nsize; - // \omegaref + BusDQ - index_type vec_size_externals = 1 + 2*(2*Nsize); - - std::vector vdqbus_index(2*Nsize,0); - vdqbus_index[0] = vec_size_internals + 1; - for (index_type i = 1; i < vdqbus_index.size(); i++) - { - vdqbus_index[i] = vdqbus_index[i-1] + 2; - } - - //Total size of the vector setup - index_type vec_size_total = vec_size_internals + vec_size_externals; - - - //Create the reference DG - auto* dg_ref = new DistributedGenerator(0, - DGParams_list[0], - true); - //ref motor - dg_ref->setExternalConnectionNodes(0, vec_size_internals); - //outputs - dg_ref->setExternalConnectionNodes(1, vdqbus_index[0]); - dg_ref->setExternalConnectionNodes(2, vdqbus_index[0] + 1); - //"grounding" of the difference - dg_ref->setExternalConnectionNodes(3, -1); - //internal connections - for (index_type i = 0; i < 12; i++) - { - dg_ref->setExternalConnectionNodes(4 + i, i); - } - sysmodel->addComponent(dg_ref); - - //Keep track of models and index location - index_type indexv = 12; - index_type model_id = 1; - //Add all other DGs - for (index_type i = 1; i < 2*Nsize; i++) + using namespace GridKit; + + bool use_jac = true; + + real_type t_init = 0.0; + real_type t_final = 1.0; + + real_type rel_tol = SCALE_MICROGRID_REL_TOL; + real_type abs_tol = SCALE_MICROGRID_ABS_TOL; + + // Create circuit model + auto* sysmodel = new PowerElectronicsModel(rel_tol, + abs_tol, + use_jac, + SCALE_MICROGRID_MAX_STEPS); + + const std::vector* true_vec = &answer_key_N8; + + switch (Nsize) + { + case 2: + true_vec = &answer_key_N2; + break; + case 4: + true_vec = &answer_key_N4; + break; + case 8: + // true_vec = &answer_key_N8; + break; + default: + std::cout << "No reference solution for Nsize = " << Nsize << ".\n"; + std::cout << "Using default Nsize = 8.\n"; + } + + // Modeled after the problem in the paper + // Every Bus has the same virtual resistance. This is due to the numerical stability as mentioned in the paper. + real_type RN = 1.0e4; + + // DG Params Vector + // All DGs have the same set of parameters except for the first two. + GridKit::DistributedGeneratorParameters DG_parms1; + DG_parms1.wb_ = 2.0 * M_PI * 50.0; + DG_parms1.wc_ = 31.41; + DG_parms1.mp_ = 9.4e-5; + DG_parms1.Vn_ = 380.0; + DG_parms1.nq_ = 1.3e-3; + DG_parms1.F_ = 0.75; + DG_parms1.Kiv_ = 420.0; + DG_parms1.Kpv_ = 0.1; + DG_parms1.Kic_ = 2.0e4; + DG_parms1.Kpc_ = 15.0; + DG_parms1.Cf_ = 5.0e-5; + DG_parms1.rLf_ = 0.1; + DG_parms1.Lf_ = 1.35e-3; + DG_parms1.rLc_ = 0.03; + DG_parms1.Lc_ = 0.35e-3; + + GridKit::DistributedGeneratorParameters DG_parms2; + DG_parms2.wb_ = 2.0 * M_PI * 50.0; + DG_parms2.wc_ = 31.41; + DG_parms2.mp_ = 12.5e-5; + DG_parms2.Vn_ = 380.0; + DG_parms2.nq_ = 1.5e-3; + DG_parms2.F_ = 0.75; + DG_parms2.Kiv_ = 390.0; + DG_parms2.Kpv_ = 0.05; + DG_parms2.Kic_ = 16.0e3; + DG_parms2.Kpc_ = 10.5; + DG_parms2.Cf_ = 50.0e-6; + DG_parms2.rLf_ = 0.1; + DG_parms2.Lf_ = 1.35e-3; + DG_parms2.rLc_ = 0.03; + DG_parms2.Lc_ = 0.35e-3; + + std::vector> DGParams_list(2 * Nsize, DG_parms2); + + DGParams_list[0] = DG_parms1; + DGParams_list[1] = DG_parms1; + + // line vector params + // Every odd line has the same parameters and every even line has the same parameters + real_type rline1 = 0.23; + real_type Lline1 = 0.1 / (2.0 * M_PI * 50.0); + real_type rline2 = 0.35; + real_type Lline2 = 0.58 / (2.0 * M_PI * 50.0); + std::vector rline_list(2 * Nsize - 1, 0.0); + std::vector Lline_list(2 * Nsize - 1, 0.0); + for (index_type i = 0; i < rline_list.size(); i++) + { + rline_list[i] = (i % 2) ? rline2 : rline1; + Lline_list[i] = (i % 2) ? Lline2 : Lline1; + } + + // load parms + // Only the first load has the same paramaters. + real_type rload1 = 3.0; + real_type Lload1 = 2.0 / (2.0 * M_PI * 50.0); + real_type rload2 = 2.0; + real_type Lload2 = 1.0 / (2.0 * M_PI * 50.0); + + std::vector rload_list(Nsize, rload2); + std::vector Lload_list(Nsize, Lload2); + rload_list[0] = rload1; + Lload_list[0] = Lload1; + + // DGs + - refframe Lines + Loads + index_type vec_size_internals = 13 * (2 * Nsize) - 1 + (2 + 4 * (Nsize - 1)) + 2 * Nsize; + // \omegaref + BusDQ + index_type vec_size_externals = 1 + 2 * (2 * Nsize); + + std::vector vdqbus_index(2 * Nsize, 0); + vdqbus_index[0] = vec_size_internals + 1; + for (index_type i = 1; i < vdqbus_index.size(); i++) + { + vdqbus_index[i] = vdqbus_index[i - 1] + 2; + } + + // Total size of the vector setup + index_type vec_size_total = vec_size_internals + vec_size_externals; + + // Create the reference DG + auto* dg_ref = new DistributedGenerator(0, + DGParams_list[0], + true); + // ref motor + dg_ref->setExternalConnectionNodes(0, vec_size_internals); + // outputs + dg_ref->setExternalConnectionNodes(1, vdqbus_index[0]); + dg_ref->setExternalConnectionNodes(2, vdqbus_index[0] + 1); + //"grounding" of the difference + dg_ref->setExternalConnectionNodes(3, -1); + // internal connections + for (index_type i = 0; i < 12; i++) + { + dg_ref->setExternalConnectionNodes(4 + i, i); + } + sysmodel->addComponent(dg_ref); + + // Keep track of models and index location + index_type indexv = 12; + index_type model_id = 1; + // Add all other DGs + for (index_type i = 1; i < 2 * Nsize; i++) + { + // current DG to add + auto* dg = new DistributedGenerator(model_id++, + DGParams_list[i], + false); + // ref motor + dg->setExternalConnectionNodes(0, vec_size_internals); + // outputs + dg->setExternalConnectionNodes(1, vdqbus_index[i]); + dg->setExternalConnectionNodes(2, vdqbus_index[i] + 1); + // internal connections + for (index_type j = 0; j < 13; j++) { - //current DG to add - auto* dg = new DistributedGenerator(model_id++, - DGParams_list[i], - false); - //ref motor - dg->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg->setExternalConnectionNodes(1,vdqbus_index[i]); - dg->setExternalConnectionNodes(2,vdqbus_index[i] + 1); - //internal connections - for (index_type j = 0; j < 13; j++) - { - dg->setExternalConnectionNodes(3 + j,indexv + j); - } - indexv += 13; - sysmodel->addComponent(dg); + dg->setExternalConnectionNodes(3 + j, indexv + j); } - - // Load all the Line compoenents - for (index_type i = 0; i < 2*Nsize - 1; i++) + indexv += 13; + sysmodel->addComponent(dg); + } + + // Load all the Line compoenents + for (index_type i = 0; i < 2 * Nsize - 1; i++) + { + // line + auto* line_model = new MicrogridLine(model_id++, + rline_list[i], + Lline_list[i]); + // ref motor + line_model->setExternalConnectionNodes(0, vec_size_internals); + // input connections + line_model->setExternalConnectionNodes(1, vdqbus_index[i]); + line_model->setExternalConnectionNodes(2, vdqbus_index[i] + 1); + // output connections + line_model->setExternalConnectionNodes(3, vdqbus_index[i + 1]); + line_model->setExternalConnectionNodes(4, vdqbus_index[i + 1] + 1); + // internal connections + for (index_type j = 0; j < 2; j++) { - //line - auto* line_model = new MicrogridLine(model_id++, - rline_list[i], - Lline_list[i]); - //ref motor - line_model->setExternalConnectionNodes(0, vec_size_internals); - //input connections - line_model->setExternalConnectionNodes(1, vdqbus_index[i]); - line_model->setExternalConnectionNodes(2, vdqbus_index[i] + 1); - //output connections - line_model->setExternalConnectionNodes(3, vdqbus_index[i+1]); - line_model->setExternalConnectionNodes(4, vdqbus_index[i+1] + 1); - //internal connections - for (index_type j = 0; j < 2; j++) - { - line_model->setExternalConnectionNodes(5 + j, indexv + j); - } - indexv += 2; - sysmodel->addComponent(line_model); + line_model->setExternalConnectionNodes(5 + j, indexv + j); } - - // Load all the Load components - for (index_type i = 0; i < Nsize; i++) + indexv += 2; + sysmodel->addComponent(line_model); + } + + // Load all the Load components + for (index_type i = 0; i < Nsize; i++) + { + auto* load_model = new MicrogridLoad(model_id++, + rload_list[i], + Lload_list[i]); + // ref motor + load_model->setExternalConnectionNodes(0, vec_size_internals); + // input connections + load_model->setExternalConnectionNodes(1, vdqbus_index[2 * i]); + load_model->setExternalConnectionNodes(2, vdqbus_index[2 * i] + 1); + // internal connections + for (index_type j = 0; j < 2; j++) { - auto* load_model = new MicrogridLoad(model_id++, - rload_list[i], - Lload_list[i]); - //ref motor - load_model->setExternalConnectionNodes(0, vec_size_internals); - //input connections - load_model->setExternalConnectionNodes(1, vdqbus_index[2*i]); - load_model->setExternalConnectionNodes(2, vdqbus_index[2*i] + 1); - //internal connections - for (index_type j = 0; j < 2; j++) - { - load_model->setExternalConnectionNodes(3 + j, indexv + j); - } - indexv += 2; - sysmodel->addComponent(load_model); + load_model->setExternalConnectionNodes(3 + j, indexv + j); } - - //Add all the microgrid Virtual DQ Buses - for (index_type i = 0; i < 2*Nsize; i++) + indexv += 2; + sysmodel->addComponent(load_model); + } + + // Add all the microgrid Virtual DQ Buses + for (index_type i = 0; i < 2 * Nsize; i++) + { + auto* virDQbus_model = new MicrogridBusDQ(model_id++, RN); + + virDQbus_model->setExternalConnectionNodes(0, vdqbus_index[i]); + virDQbus_model->setExternalConnectionNodes(1, vdqbus_index[i] + 1); + sysmodel->addComponent(virDQbus_model); + } + + // allocate all the intial conditions + sysmodel->allocate(vec_size_total); + + if (debug_output) + { + std::cout << sysmodel->y().size() << std::endl; + std::cout << vec_size_internals << ", " << vec_size_externals << "\n"; + } + + // Create Intial points for states. Every state is to specified to the zero intially + for (index_type i = 0; i < vec_size_total; i++) + { + sysmodel->y()[i] = 0.0; + sysmodel->yp()[i] = 0.0; + } + + // Create Intial derivatives specifics generated in MATLAB + for (index_type i = 0; i < 2 * Nsize; i++) + { + sysmodel->yp()[13 * i - 1 + 3] = DGParams_list[i].Vn_; + sysmodel->yp()[13 * i - 1 + 5] = DGParams_list[i].Kpv_ * DGParams_list[i].Vn_; + sysmodel->yp()[13 * i - 1 + 7] = (DGParams_list[i].Kpc_ * DGParams_list[i].Kpv_ * DGParams_list[i].Vn_) / DGParams_list[i].Lf_; + } + + // since the intial P_com = 0, the set the intial vector to the reference frame + sysmodel->y()[vec_size_internals] = DG_parms1.wb_; + + sysmodel->initialize(); + sysmodel->evaluateResidual(); + + std::vector& fres = sysmodel->getResidual(); + if (debug_output) + { + std::cout << "Verify Intial Resisdual is Zero: {\n"; + for (index_type i = 0; i < fres.size(); i++) { - auto* virDQbus_model = new MicrogridBusDQ(model_id++, RN); - - virDQbus_model->setExternalConnectionNodes(0, vdqbus_index[i]); - virDQbus_model->setExternalConnectionNodes(1, vdqbus_index[i] + 1); - sysmodel->addComponent(virDQbus_model); + std::cout << i << " : " << fres[i] << "\n"; } - - //allocate all the intial conditions - sysmodel->allocate(vec_size_total); + std::cout << "}\n"; + } - if (debug_output) - { - std::cout << sysmodel->y().size() << std::endl; - std::cout << vec_size_internals << ", " << vec_size_externals << "\n"; - } + sysmodel->updateTime(0.0, 1.0e-8); + sysmodel->evaluateJacobian(); + if (debug_output) + std::cout << "Intial Jacobian with alpha:\n"; - //Create Intial points for states. Every state is to specified to the zero intially - for (index_type i = 0; i < vec_size_total; i++) - { - sysmodel->y()[i] = 0.0; - sysmodel->yp()[i] = 0.0; - } + // Create numerical integrator and configure it for the generator model + auto* idas = new AnalysisManager::Sundials::Ida(sysmodel); - // Create Intial derivatives specifics generated in MATLAB - for (index_type i = 0; i < 2*Nsize; i++) - { - sysmodel->yp()[13*i - 1 + 3] = DGParams_list[i].Vn_; - sysmodel->yp()[13*i - 1 + 5] = DGParams_list[i].Kpv_ * DGParams_list[i].Vn_; - sysmodel->yp()[13*i - 1 + 7] = (DGParams_list[i].Kpc_ * DGParams_list[i].Kpv_ * DGParams_list[i].Vn_) / DGParams_list[i].Lf_; - } + // setup simulation + idas->configureSimulation(); + idas->getDefaultInitialCondition(); + idas->initializeSimulation(t_init); - //since the intial P_com = 0, the set the intial vector to the reference frame - sysmodel->y()[vec_size_internals] = DG_parms1.wb_; + idas->runSimulation(t_final); - sysmodel->initialize(); - sysmodel->evaluateResidual(); + std::vector& yfinal = sysmodel->y(); - std::vector& fres = sysmodel->getResidual(); - if (debug_output) + if (debug_output) + { + std::cout << "Final Vector y\n"; + for (index_type i = 0; i < yfinal.size(); i++) { - std::cout << "Verify Intial Resisdual is Zero: {\n"; - for (index_type i = 0; i < fres.size(); i++) - { - std::cout << i << " : " << fres[i] << "\n"; - } - std::cout << "}\n"; + std::cout << i << " : " << yfinal[i] << "\n"; } + } - sysmodel->updateTime(0.0, 1.0e-8); - sysmodel->evaluateJacobian(); - if (debug_output) - std::cout << "Intial Jacobian with alpha:\n"; - - - //Create numerical integrator and configure it for the generator model - auto* idas = new AnalysisManager::Sundials::Ida(sysmodel); + bool test_pass = true; - // setup simulation - idas->configureSimulation(); - idas->getDefaultInitialCondition(); - idas->initializeSimulation(t_init); - - idas->runSimulation(t_final); - - std::vector& yfinal = sysmodel->y(); + real_type sumtop = 0.0; + real_type sumbottom = 0.0; + // check relative error + std::cout << "Test the Relative Error for N = " << Nsize << "\n"; + for (index_type i = 0; i < true_vec->size(); i++) + { + // Print the Elementwise Relative Error if (debug_output) - { - std::cout << "Final Vector y\n"; - for (index_type i = 0; i < yfinal.size(); i++) - { - std::cout << i << " : " << yfinal[i] << "\n"; - } - } - - bool test_pass = true; - - real_type sumtop = 0.0; - real_type sumbottom = 0.0; - - // check relative error - std::cout << "Test the Relative Error for N = " << Nsize << "\n"; - for (index_type i = 0; i < true_vec->size(); i++) - { - //Print the Elementwise Relative Error - if (debug_output) - std::cout << i << " : " << abs(true_vec->at(i) - yfinal[i]) / abs(true_vec->at(i)) << "\n"; - - sumtop += (true_vec->at(i) - yfinal[i]) * (true_vec->at(i) - yfinal[i]); - sumbottom += (true_vec->at(i) * true_vec->at(i)); - } - - real_type norm2error = (sqrt(sumtop) / sqrt(sumbottom)); - std::cout << "2-Norm Relative Error: " << norm2error << std::endl; - test_pass = norm2error < error_tol; - - - delete idas; - delete sysmodel; - - if(test_pass) - { - std::cout << "Test with Nsize = " << Nsize << " passes!\n"; - return 0; - } - else - { - std::cout << "Test with Nsize = " << Nsize << " fails!\n"; - return 1; - } + std::cout << i << " : " << abs(true_vec->at(i) - yfinal[i]) / abs(true_vec->at(i)) << "\n"; + + sumtop += (true_vec->at(i) - yfinal[i]) * (true_vec->at(i) - yfinal[i]); + sumbottom += (true_vec->at(i) * true_vec->at(i)); + } + + real_type norm2error = (sqrt(sumtop) / sqrt(sumbottom)); + std::cout << "2-Norm Relative Error: " << norm2error << std::endl; + test_pass = norm2error < error_tol; + + delete idas; + delete sysmodel; + + if (test_pass) + { + std::cout << "Test with Nsize = " << Nsize << " passes!\n"; + return 0; + } + else + { + std::cout << "Test with Nsize = " << Nsize << " fails!\n"; + return 1; + } } diff --git a/examples/ScaleMicrogrid/SolutionKeys.hpp b/examples/ScaleMicrogrid/SolutionKeys.hpp index 6a74dc0d..f604b5e9 100644 --- a/examples/ScaleMicrogrid/SolutionKeys.hpp +++ b/examples/ScaleMicrogrid/SolutionKeys.hpp @@ -3,35 +3,33 @@ * @author Reid Gomillion (rjg18@vt.edu) * @author Slaven Peles (peless@ornl.gov) * @brief Answer keys for Scaled Microgrid test with Nsize = 2, 4, 8 - * + * * Data generated with Matlab ode23tb solver with tolerances set to * abs_tol = 1e-12 and rel_tol = 1e-12 for the ODE derivation of the model. * No index reduction was preformed to get to the ODE model. - * + * * @note This file is only to be included in ScaleMicrogrid.cpp. It has no * use anywhere else. */ #include - -/// +/// /** * 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) * 2-Norm Relative Error: 8.65796e-08 (rel/abs tol = 1e-7) * 2-Norm Relative Error: 1.1618e-08 (rel/abs tol = 1e-8) - * + * */ -constexpr real_type SCALE_MICROGRID_ERROR_TOL = 1.0e-6; -constexpr real_type SCALE_MICROGRID_REL_TOL = 1.0e-8; -constexpr real_type SCALE_MICROGRID_ABS_TOL = 1.0e-8; +constexpr real_type SCALE_MICROGRID_ERROR_TOL = 1.0e-6; +constexpr real_type SCALE_MICROGRID_REL_TOL = 1.0e-8; +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, @@ -102,8 +100,7 @@ const std::vector answer_key_N2 = { 347.214535767435, -32.7241067379802, 360.411028950125, - -34.9283280833745 -}; + -34.9283280833745}; const std::vector answer_key_N4 = { 27828.3291148094, @@ -247,8 +244,7 @@ const std::vector answer_key_N4 = { 332.2248206198, -103.942854393111, 347.103721199815, - -107.812479611979 -}; + -107.812479611979}; const std::vector answer_key_N8 = { 29266.6517718661, @@ -536,7 +532,4 @@ const std::vector answer_key_N8 = { 306.288884765777, -170.785573848562, 322.018589824395, - -176.179397251772 -}; - - + -176.179397251772}; diff --git a/src/CircuitGraph.hpp b/src/CircuitGraph.hpp index c0dde1a2..26d5d6a2 100644 --- a/src/CircuitGraph.hpp +++ b/src/CircuitGraph.hpp @@ -1,10 +1,10 @@ -#include #include -#include -#include +#include #include +#include +#include /** * @brief A very basic hypergraph setup for circuit representation. @@ -14,7 +14,7 @@ * @todo should replace with something better and more efficent. * Should replace with a libraries setup instead. This would allow * fast and easy partitioning of circuits - * + * * @todo This is to replace inserting vector size for allocating PowerElectronicsModel * * @todo should replace N and E with Node and Component classes respectively. @@ -28,20 +28,20 @@ template class CircuitGraph { private: - std::set hypernodes; - std::set hyperedges; - std::map> edgestonodes; + std::set hypernodes; + std::set hyperedges; + std::map> edgestonodes; public: - CircuitGraph(); - ~CircuitGraph(); - bool addHyperEdge(E he); - bool addHyperNode(N hn); - bool addConnection(N hn, E he); - std::set getHyperEdgeConnections(E he); - size_t amountHyperNodes(); - size_t amountHyperEdges(); - void printBiPartiteGraph(bool verbose = false); + CircuitGraph(); + ~CircuitGraph(); + bool addHyperEdge(E he); + bool addHyperNode(N hn); + bool addConnection(N hn, E he); + std::set getHyperEdgeConnections(E he); + size_t amountHyperNodes(); + size_t amountHyperEdges(); + void printBiPartiteGraph(bool verbose = false); }; template @@ -57,41 +57,41 @@ CircuitGraph::~CircuitGraph() template bool CircuitGraph::addHyperNode(N hn) { - return this->hypernodes.insert(hn).second; + return this->hypernodes.insert(hn).second; } template bool CircuitGraph::addHyperEdge(E he) { - return this->hyperedges.insert(he).second; + return this->hyperedges.insert(he).second; } template bool CircuitGraph::addConnection(N hn, E he) { - if (this->hyperedges.count(he) == 0 || this->hypernodes.count(hn) == 0) - { - return false; - } - return this->edgestonodes[he].insert(hn).second; + if (this->hyperedges.count(he) == 0 || this->hypernodes.count(hn) == 0) + { + return false; + } + return this->edgestonodes[he].insert(hn).second; } template std::set CircuitGraph::getHyperEdgeConnections(E he) { - return this->edgestonodes[he]; + return this->edgestonodes[he]; } template size_t CircuitGraph::amountHyperNodes() { - return this->hypernodes.size(); + return this->hypernodes.size(); } template size_t CircuitGraph::amountHyperEdges() { - return this->hyperedges.size(); + return this->hyperedges.size(); } /** @@ -100,7 +100,7 @@ size_t CircuitGraph::amountHyperEdges() * @todo need to add verbose printing for connections display * * @tparam IdxT - * @param[in] verbose if true will print connections, + * @param[in] verbose if true will print connections, * otherwise just the number of nodes and edges */ @@ -108,16 +108,16 @@ template void CircuitGraph::printBiPartiteGraph(bool verbose) { - std::cout << "Amount of HyperNodes: " << this->amountHyperNodes() << std::endl; - std::cout << "Amount of HyperEdges: " << this->amountHyperEdges() << std::endl; - std::cout << "Connections per Edge:" << std::endl; - for (auto i : this->edgestonodes) - { - std::cout << i.first << " : {"; - for (auto j : i.second) - { - std::cout << j << ", "; - } - std::cout << "}\n"; - } + std::cout << "Amount of HyperNodes: " << this->amountHyperNodes() << std::endl; + std::cout << "Amount of HyperEdges: " << this->amountHyperEdges() << std::endl; + std::cout << "Connections per Edge:" << std::endl; + for (auto i : this->edgestonodes) + { + std::cout << i.first << " : {"; + for (auto j : i.second) + { + std::cout << j << ", "; + } + std::cout << "}\n"; + } } diff --git a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp index 839156f9..264689d6 100644 --- a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp +++ b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp @@ -1,230 +1,229 @@ #pragma once +#include #include #include #include -#include + #include /** - * @brief Class to provide dense matrices. + * @brief Class to provide dense matrices. * - * This is intended for small matrices that store model Jacobians to be subsequently copied + * This is intended for small matrices that store model Jacobians to be subsequently copied * into large sparse matrices. */ namespace GridKit { -namespace LinearAlgebra -{ -template -class DenseMatrix -{ -private: - IdxT rows_size_; - IdxT columns_size_; - std::vector values_; - COO_Matrix values_COO_; - bool values_changed_ = false; - bool sparsified_ = false; -public: - // Constructors and destructors - DenseMatrix(const IdxT rows_size, const IdxT columns_size); - ~DenseMatrix(); - - // Getters and setters - ScalarT getValue(const IdxT i, const IdxT j) const; - void setValue(const IdxT i, const IdxT j, const ScalarT value); - void setValues(COO_Matrix values_COO); - std::vector* getValues(); - COO_Matrix* getValuesCOO(); - - // Utilities - void toCOO(); - void printMatrix(std::string name=""); - - // Purposefully not defining BLAS operations. This class should not be used - // for compute. -}; - -/** - * @brief DenseMatrix constructor - * - * @tparam ScalarT - * @tparam IdxT - * - * @param[in] IdxT - rows_size - * @param[in] IdxT - columns_size - */ -template -DenseMatrix::DenseMatrix(const IdxT rows_size, const IdxT columns_size) : - rows_size_(rows_size), - columns_size_(columns_size), - values_(rows_size*columns_size, 0), - values_COO_(rows_size, columns_size) -{ - -} + namespace LinearAlgebra + { + template + class DenseMatrix + { + private: + IdxT rows_size_; + IdxT columns_size_; + std::vector values_; + COO_Matrix values_COO_; + bool values_changed_ = false; + bool sparsified_ = false; + + public: + // Constructors and destructors + DenseMatrix(const IdxT rows_size, const IdxT columns_size); + ~DenseMatrix(); + + // Getters and setters + ScalarT getValue(const IdxT i, const IdxT j) const; + void setValue(const IdxT i, const IdxT j, const ScalarT value); + void setValues(COO_Matrix values_COO); + std::vector* getValues(); + COO_Matrix* getValuesCOO(); + + // Utilities + void toCOO(); + void printMatrix(std::string name = ""); + + // Purposefully not defining BLAS operations. This class should not be used + // for compute. + }; + + /** + * @brief DenseMatrix constructor + * + * @tparam ScalarT + * @tparam IdxT + * + * @param[in] IdxT - rows_size + * @param[in] IdxT - columns_size + */ + template + DenseMatrix::DenseMatrix(const IdxT rows_size, const IdxT columns_size) + : rows_size_(rows_size), + columns_size_(columns_size), + values_(rows_size * columns_size, 0), + values_COO_(rows_size, columns_size) + { + } -/** - * @brief DenseMatrix single value getter - * - * @tparam ScalarT - * @tparam IdxT - * - * @param[in] IdxT - i row index - * @param[in] IdxT - j column index - * @return ScalarT - value - */ -template -inline ScalarT DenseMatrix::getValue(const IdxT i, const IdxT j) const -{ - assert(i < this->columns_size_); - assert(j < this->rows_size_); - return this->values_[j*rows_size_+i]; -} + /** + * @brief DenseMatrix single value getter + * + * @tparam ScalarT + * @tparam IdxT + * + * @param[in] IdxT - i row index + * @param[in] IdxT - j column index + * @return ScalarT - value + */ + template + inline ScalarT DenseMatrix::getValue(const IdxT i, const IdxT j) const + { + assert(i < this->columns_size_); + assert(j < this->rows_size_); + return this->values_[j * rows_size_ + i]; + } -/** - * @brief DenseMatrix single value setter - * - * @tparam ScalarT - * @tparam IdxT - * - * @param[in] IdxT - i row index - * @param[in] IdxT - j column index - * @param[in] ScalarT - value - */ -template -inline void DenseMatrix::setValue(const IdxT i, const IdxT j, const ScalarT value) -{ - assert(i < this->columns_size_); - assert(j < this->rows_size_); - this->values_[j*rows_size_+i] = value; - values_changed_ = true; -} + /** + * @brief DenseMatrix single value setter + * + * @tparam ScalarT + * @tparam IdxT + * + * @param[in] IdxT - i row index + * @param[in] IdxT - j column index + * @param[in] ScalarT - value + */ + template + inline void DenseMatrix::setValue(const IdxT i, const IdxT j, const ScalarT value) + { + assert(i < this->columns_size_); + assert(j < this->rows_size_); + this->values_[j * rows_size_ + i] = value; + values_changed_ = true; + } -/** - * @brief DenseMatrix value setter from COO - * - * @tparam ScalarT - * @tparam IdxT - * - * @param[in] COO_Matrix - values_COO - */ -template -inline void DenseMatrix::setValues(COO_Matrix values_COO) -{ - std::tuple&, std::vector&, std::vector&> entries = values_COO.getEntries(); - const auto [rcord, ccord, vals] = entries; - for (IdxT idx = 0; idx < values_COO.nnz(); ++idx) + /** + * @brief DenseMatrix value setter from COO + * + * @tparam ScalarT + * @tparam IdxT + * + * @param[in] COO_Matrix - values_COO + */ + template + inline void DenseMatrix::setValues(COO_Matrix values_COO) { + std::tuple&, std::vector&, std::vector&> entries = values_COO.getEntries(); + const auto [rcord, ccord, vals] = entries; + for (IdxT idx = 0; idx < values_COO.nnz(); ++idx) + { this->setValue(rcord[idx], ccord[idx], vals[idx]); + } } -} -/** - * @brief DenseMatrix getter for all values stored as a vector - * - * @tparam ScalarT - * @tparam IdxT - * - * @return Address of the vector containing matrix values - */ -template -inline std::vector* DenseMatrix::getValues() -{ - return &(this->values_); -} + /** + * @brief DenseMatrix getter for all values stored as a vector + * + * @tparam ScalarT + * @tparam IdxT + * + * @return Address of the vector containing matrix values + */ + template + inline std::vector* DenseMatrix::getValues() + { + return &(this->values_); + } -/** - * @brief DenseMatrix getter for all values stored as a COO sparse matrix - * - * @tparam ScalarT - * @tparam IdxT - * - * @return Address of the COO matrix containing the sparsified matrix values - */ -template -inline COO_Matrix* DenseMatrix::getValuesCOO() -{ - if (!sparsified_ || values_changed_) + /** + * @brief DenseMatrix getter for all values stored as a COO sparse matrix + * + * @tparam ScalarT + * @tparam IdxT + * + * @return Address of the COO matrix containing the sparsified matrix values + */ + template + inline COO_Matrix* DenseMatrix::getValuesCOO() { + if (!sparsified_ || values_changed_) + { this->toCOO(); + } + return &(this->values_COO_); } - return &(this->values_COO_); -} -/** - * @brief Dense matrix conversion to COO form - * - * @tparam ScalarT - * @tparam IdxT - */ -template -inline void DenseMatrix::toCOO() -{ - if (!sparsified_ || values_changed_) + /** + * @brief Dense matrix conversion to COO form + * + * @tparam ScalarT + * @tparam IdxT + */ + template + inline void DenseMatrix::toCOO() { - IdxT nnz = 0; - std::vector rcord; - std::vector ccord; + if (!sparsified_ || values_changed_) + { + IdxT nnz = 0; + std::vector rcord; + std::vector ccord; std::vector vals; for (IdxT j = 0; j < this->columns_size_; ++j) { - for (IdxT i = 0; i < this->rows_size_; ++i) + for (IdxT i = 0; i < this->rows_size_; ++i) + { + ScalarT value = this->values_[j * rows_size_ + i]; + if (std::abs(value) > std::numeric_limits::epsilon()) { - ScalarT value = this->values_[j*rows_size_+i]; - if (std::abs(value) > std::numeric_limits::epsilon()) - { - nnz++; - rcord.push_back(i); - ccord.push_back(j); - vals.push_back(value); - } + nnz++; + rcord.push_back(i); + ccord.push_back(j); + vals.push_back(value); } + } } values_COO_.setValues(rcord, ccord, vals); - sparsified_ = true; + sparsified_ = true; values_changed_ = false; + } } -} -/** - * @brief Print matrix - * - * @tparam ScalarT - * @tparam IdxT - * - * @param[in] name to identify the specific matrix printed - */ -template -inline void DenseMatrix::printMatrix(std::string name) -{ - std::cout << "Dense matrix: " << name << "\n"; - for (IdxT i = 0; i < this->rows_size_; ++i) + /** + * @brief Print matrix + * + * @tparam ScalarT + * @tparam IdxT + * + * @param[in] name to identify the specific matrix printed + */ + template + inline void DenseMatrix::printMatrix(std::string name) { + std::cout << "Dense matrix: " << name << "\n"; + for (IdxT i = 0; i < this->rows_size_; ++i) + { for (IdxT j = 0; j < this->columns_size_; ++j) { - std::cout << this->values_[j*rows_size_+i] << " "; + std::cout << this->values_[j * rows_size_ + i] << " "; } std::cout << "\n"; + } } -} -/** - * @brief DenseMatrix destructor - * - * @tparam ScalarT - * @tparam IdxT - */ -template -DenseMatrix::~DenseMatrix() -{ - -} - -// Available template instantiations -template class DenseMatrix; + /** + * @brief DenseMatrix destructor + * + * @tparam ScalarT + * @tparam IdxT + */ + template + DenseMatrix::~DenseMatrix() + { + } -} // LinearAlgebra -} // GridKit + // Available template instantiations + template class DenseMatrix; + } // namespace LinearAlgebra +} // namespace GridKit diff --git a/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp b/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp index ea72e41a..33d28324 100644 --- a/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp +++ b/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp @@ -1,681 +1,680 @@ #ifndef COO_MATRIX_HPP #define COO_MATRIX_HPP -#include -#include -#include -#include -#include #include #include +#include #include +#include +#include +#include +#include /** - * @brief Quick class to provide sparse matrices of COO type. Simplifies data movement - * - * @todo add functionality to keep track of multiple sorted lists. Faster adding of new entries and will have a threshold to sort completely. - * + * @brief Quick class to provide sparse matrices of COO type. + * + * Simplifies data movement + * + * @todo add functionality to keep track of multiple sorted lists. Faster + * adding of new entries and will have a threshold to sort completely. + * * m x n sparse matrix */ template class COO_Matrix { private: - std::vector values_; - std::vector row_indices_; - std::vector column_indices_; - IdxT rows_size_; - IdxT columns_size_; - bool sorted_; -public: - //Constructors - COO_Matrix(std::vector r, std::vector c, std::vector v, IdxT m, IdxT n); - COO_Matrix(IdxT m, IdxT n); - COO_Matrix(); - ~COO_Matrix(); + std::vector values_; + std::vector row_indices_; + std::vector column_indices_; + IdxT rows_size_; + IdxT columns_size_; + bool sorted_; +public: + // Constructors + COO_Matrix(std::vector r, std::vector c, std::vector v, IdxT m, IdxT n); + COO_Matrix(IdxT m, IdxT n); + COO_Matrix(); + ~COO_Matrix(); - //Operations + // Operations - // --- Functions which call sort --- - std::tuple, std::vector> getRowCopy(IdxT r); - std::tuple&, std::vector&, std::vector&> getEntries(); - std::tuple, std::vector, std::vector> getEntryCopies(); - std::tuple, std::vector, std::vector> getEntryCopiesSubMatrix(std::vector submap); + // --- Functions which call sort --- + std::tuple, std::vector> getRowCopy(IdxT r); + std::tuple&, std::vector&, std::vector&> getEntries(); + std::tuple, std::vector, std::vector> getEntryCopies(); + std::tuple, std::vector, std::vector> getEntryCopiesSubMatrix(std::vector submap); - std::tuple, std::vector, std::vector> setDataToCSR(); - std::vector getCSRRowData(); + std::tuple, std::vector, std::vector> setDataToCSR(); + std::vector getCSRRowData(); - // BLAS. Will sort before running - void setValues(std::vector r, std::vector c, std::vector v); - void axpy(ScalarT alpha, COO_Matrix& a); - void axpy(ScalarT alpha, std::vector r, std::vector c, std::vector v); - void scal(ScalarT alpha); - ScalarT frobNorm(); + // BLAS. Will sort before running + void setValues(std::vector r, std::vector c, std::vector v); + void axpy(ScalarT alpha, COO_Matrix& a); + void axpy(ScalarT alpha, std::vector r, std::vector c, std::vector v); + void scal(ScalarT alpha); + ScalarT frobNorm(); - // --- Permutation Operations --- - //Sorting is only done if not already sorted. - void permutation(std::vector row_perm, std::vector col_perm); - void permutationSizeMap(std::vector row_perm, std::vector col_perm, IdxT m, IdxT n); + // --- Permutation Operations --- + // Sorting is only done if not already sorted. + void permutation(std::vector row_perm, std::vector col_perm); + void permutationSizeMap(std::vector row_perm, std::vector col_perm, IdxT m, IdxT n); - void zeroMatrix(); + void zeroMatrix(); - void identityMatrix(IdxT n); + void identityMatrix(IdxT n); - //Resort values_ - void sortSparse(); - bool isSorted(); - IdxT nnz(); + // Resort values_ + void sortSparse(); + bool isSorted(); + IdxT nnz(); - std::tuple getDimensions(); + std::tuple getDimensions(); - void printMatrix(std::string name=""); + void printMatrix(std::string name = ""); - - static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values); + static void sortSparseCOO(std::vector& rows, std::vector& columns, std::vector& values); private: - IdxT indexStartRow(const std::vector &rows, IdxT r); - IdxT sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, IdxT ri, IdxT ci); - bool checkIncreaseSize(IdxT r, IdxT c); - + IdxT indexStartRow(const std::vector& rows, IdxT r); + IdxT sparseCordBinarySearch(const std::vector& rows, const std::vector& columns, IdxT ri, IdxT ci); + bool checkIncreaseSize(IdxT r, IdxT c); }; /** * @brief Get copy of row index - * - * @tparam ScalarT - * @tparam IdxT + * + * @tparam ScalarT + * @tparam IdxT * @param[in] r row index - * @return std::tuple, std::vector> + * @return std::tuple, std::vector> */ template inline std::tuple, std::vector> COO_Matrix::getRowCopy(IdxT r) { - if (!this->sorted_) - { - this->sortSparse(); - } - IdxT row_index = this->indexStartRow(r); - - - if (row_index == -1) - { - return {std::vector(),std::vector()}; - } - - IdxT rsize = row_index; - do - { - rsize++; - } while (rsize < this->values_.size() && this->row_indices_[rsize] == r); - - return {{this->column_indices_.begin() + row_index, this->column_indices_.begin() + rsize},{this->values_.begin() + row_index, this->values_.begin() + rsize}}; + if (!this->sorted_) + { + this->sortSparse(); + } + IdxT row_index = this->indexStartRow(r); + + if (row_index == -1) + { + return {std::vector(), std::vector()}; + } + + IdxT rsize = row_index; + do + { + rsize++; + } while (rsize < this->values_.size() && this->row_indices_[rsize] == r); + + return {{this->column_indices_.begin() + row_index, this->column_indices_.begin() + rsize}, + {this->values_.begin() + row_index, this->values_.begin() + rsize}}; } /** * @brief Get all entry pointers. Will sort before returning - * - * @tparam ScalarT - * @tparam IdxT - * @return std::tuple, std::vector, std::vector> + * + * @tparam ScalarT + * @tparam IdxT + * @return std::tuple, std::vector, std::vector> */ template inline std::tuple&, std::vector&, std::vector&> COO_Matrix::getEntries() { - if (!this->sorted_) - { - this->sortSparse(); - } - return {this->row_indices_, this->column_indices_, this->values_}; + if (!this->sorted_) + { + this->sortSparse(); + } + return {this->row_indices_, this->column_indices_, this->values_}; } /** * @brief Sorts the data if it's not already sorted - * - * @tparam ScalarT - * @tparam IdxT - * @return std::tuple, std::vector, std::vector> + * + * @tparam ScalarT + * @tparam IdxT + * @return std::tuple, std::vector, std::vector> */ template inline std::tuple, std::vector, std::vector> COO_Matrix::getEntryCopies() { - if (!this->sorted_) - { - this->sortSparse(); - } - return {this->row_indices_, this->column_indices_, this->values_}; + if (!this->sorted_) + { + this->sortSparse(); + } + return {this->row_indices_, this->column_indices_, this->values_}; } /** * @brief Returns the data in CSR Format - * - * @tparam ScalarT - * @tparam IdxT - * @return std::tuple, std::vector, std::vector> + * + * @tparam ScalarT + * @tparam IdxT + * @return std::tuple, std::vector, std::vector> */ template inline std::tuple, std::vector, std::vector> COO_Matrix::setDataToCSR() { - if (!this->isSorted()) this->sortSparse(); - std::vector row_size_vec(this->rows_size_ + 1, 0); - IdxT counter = 0; - for (IdxT i = 0; i < static_cast(row_size_vec.size() - 1); i++) + if (!this->isSorted()) + this->sortSparse(); + std::vector row_size_vec(this->rows_size_ + 1, 0); + IdxT counter = 0; + for (IdxT i = 0; i < static_cast(row_size_vec.size() - 1); i++) + { + row_size_vec[i + 1] = row_size_vec[i]; + while (counter < static_cast(this->row_indices_.size()) && i == this->row_indices_[counter]) { - row_size_vec[i + 1] = row_size_vec[i]; - while (counter < static_cast(this->row_indices_.size()) && i == this->row_indices_[counter]) - { - row_size_vec[i+1]++; - counter++; - } + row_size_vec[i + 1]++; + counter++; } - return {row_size_vec, this->column_indices_, this->values_}; + } + return {row_size_vec, this->column_indices_, this->values_}; } /** * @brief Only creates the row data - * + * * @todo swap this with having the matrix store the data and updates. This can then be passed by reference - * - * - * @tparam ScalarT - * @tparam IdxT - * @return std::vector + * + * + * @tparam ScalarT + * @tparam IdxT + * @return std::vector */ template inline std::vector COO_Matrix::getCSRRowData() { - if (!this->isSorted()) this->sortSparse(); - std::vector row_size_vec(this->rows_size_ + 1, 0); - IdxT counter = 0; - for (IdxT i = 0; i < static_cast(row_size_vec.size() - 1); i++) + if (!this->isSorted()) + this->sortSparse(); + std::vector row_size_vec(this->rows_size_ + 1, 0); + IdxT counter = 0; + for (IdxT i = 0; i < static_cast(row_size_vec.size() - 1); i++) + { + row_size_vec[i + 1] = row_size_vec[i]; + while (counter < static_cast(this->row_indices_.size()) && i == this->row_indices_[counter]) { - row_size_vec[i + 1] = row_size_vec[i]; - while (counter < static_cast(this->row_indices_.size()) && i == this->row_indices_[counter]) - { - row_size_vec[i+1]++; - counter++; - } + row_size_vec[i + 1]++; + counter++; } - return row_size_vec; + } + return row_size_vec; } /** - * @brief Set coordinates and values of the matrix. - * + * @brief Set coordinates and values of the matrix. + * * Matrix entries will be sorted in row-major order before the method returns. - * - * @tparam ScalarT - * @tparam IdxT + * + * @tparam ScalarT + * @tparam IdxT * @param[in] r row indices of the matrix * @param[in] c column indices of the matrix * @param[in] v values of the matrix - * + * * @pre r.size() == c.size() == v.size() * @pre r,c,v represent an array in COO format - * + * * @post Coordinates and values are set in the matrix. */ template inline void COO_Matrix::setValues(std::vector r, std::vector c, std::vector v) { - //sort input - this->sortSparseCOO(r, c, v); - - - //Duplicated with axpy. Could replace with function depdent on lambda expression - IdxT a_iter = 0; - //iterate for all current values_ in matrix - for (IdxT i = 0; i < static_cast(this->row_indices_.size()); i++) + // sort input + this->sortSparseCOO(r, c, v); + + // Duplicated with axpy. Could replace with function depdent on lambda expression + IdxT a_iter = 0; + // iterate for all current values_ in matrix + for (IdxT i = 0; i < static_cast(this->row_indices_.size()); i++) + { + // pushback values_ when they are not in current matrix + while (a_iter < static_cast(r.size()) && (r[a_iter] < this->row_indices_[i] || (r[a_iter] == this->row_indices_[i] && c[a_iter] < this->column_indices_[i]))) { - //pushback values_ when they are not in current matrix - while(a_iter < static_cast(r.size()) && (r[a_iter] < this->row_indices_[i] || (r[a_iter] == this->row_indices_[i] && c[a_iter] < this->column_indices_[i]))) - { - this->row_indices_.push_back(r[a_iter]); - this->column_indices_.push_back(c[a_iter]); - this->values_.push_back(v[a_iter]); - this->checkIncreaseSize(r[a_iter], c[a_iter]); - a_iter++; - } - if (a_iter >= static_cast(r.size())) - { - break; - } - - - if (r[a_iter] == this->row_indices_[i] && c[a_iter] == this->column_indices_[i]) - { - this->values_[i] = v[a_iter]; - a_iter++; - } + this->row_indices_.push_back(r[a_iter]); + this->column_indices_.push_back(c[a_iter]); + this->values_.push_back(v[a_iter]); + this->checkIncreaseSize(r[a_iter], c[a_iter]); + a_iter++; } - //push back rest that was not found sorted - for (IdxT i = a_iter; i < static_cast(r.size()); i++) + if (a_iter >= static_cast(r.size())) { - this->row_indices_.push_back(r[i]); - this->column_indices_.push_back(c[i]); - this->values_.push_back(v[i]); - - this->checkIncreaseSize(r[i], c[i]); + break; } - - this->sorted_ = false; + if (r[a_iter] == this->row_indices_[i] && c[a_iter] == this->column_indices_[i]) + { + this->values_[i] = v[a_iter]; + a_iter++; + } + } + // push back rest that was not found sorted + for (IdxT i = a_iter; i < static_cast(r.size()); i++) + { + this->row_indices_.push_back(r[i]); + this->column_indices_.push_back(c[i]); + this->values_.push_back(v[i]); + + this->checkIncreaseSize(r[i], c[i]); + } + + this->sorted_ = false; } /** * @brief Implements axpy this += alpha * a. Will sort before running - * - * @tparam ScalarT - * @tparam IdxT + * + * @tparam ScalarT + * @tparam IdxT * @param[in] alpha matrix to be added * @param[in] a scalar to multiply by - * + * * @post this = this + alpha * a */ template inline void COO_Matrix::axpy(ScalarT alpha, COO_Matrix& a) { - if (alpha == 0) - { - return; - } - - if (!this->sorted_) + if (alpha == 0) + { + return; + } + + if (!this->sorted_) + { + this->sortSparse(); + } + if (!a.isSorted()) + { + a.sortSparse(); + } + IdxT m = 0; + IdxT n = 0; + std::tuple&, std::vector&, std::vector&> tpm = a.getEntries(); + const auto& [r, c, val] = tpm; + std::tie(m, n) = a.getDimensions(); + + // Increase size as necessary + this->rows_size_ = this->rows_size_ > m ? this->rows_size_ : m; + this->columns_size_ = this->columns_size_ > n ? this->columns_size_ : n; + + IdxT a_iter = 0; + // iterate for all current values in matrix + for (IdxT i = 0; i < static_cast(this->row_indices_.size()); i++) + { + // pushback values when they are not in current matrix + while (a_iter < static_cast(r.size()) && (r[a_iter] < this->row_indices_[i] || (r[a_iter] == this->row_indices_[i] && c[a_iter] < this->column_indices_[i]))) { - this->sortSparse(); - } - if (!a.isSorted()) - { - a.sortSparse(); + this->row_indices_.push_back(r[a_iter]); + this->column_indices_.push_back(c[a_iter]); + this->values_.push_back(alpha * val[a_iter]); + + this->checkIncreaseSize(r[a_iter], c[a_iter]); + a_iter++; } - IdxT m = 0; - IdxT n = 0; - std::tuple&, std::vector&, std::vector&> tpm = a.getEntries(); - const auto& [r, c, val] = tpm; - std::tie(m,n) = a.getDimensions(); - - //Increase size as necessary - this->rows_size_ = this->rows_size_ > m ? this->rows_size_ : m; - this->columns_size_ = this->columns_size_ > n ? this->columns_size_ : n; - - IdxT a_iter = 0; - //iterate for all current values in matrix - for (IdxT i = 0; i < static_cast(this->row_indices_.size()); i++) + if (a_iter >= static_cast(r.size())) { - //pushback values when they are not in current matrix - while(a_iter < static_cast(r.size()) && (r[a_iter] < this->row_indices_[i] || (r[a_iter] == this->row_indices_[i] && c[a_iter] < this->column_indices_[i]))) - { - this->row_indices_.push_back(r[a_iter]); - this->column_indices_.push_back(c[a_iter]); - this->values_.push_back(alpha * val[a_iter]); - - this->checkIncreaseSize(r[a_iter], c[a_iter]); - a_iter++; - } - if (a_iter >= static_cast(r.size())) - { - break; - } - - - if (r[a_iter] == this->row_indices_[i] && c[a_iter] == this->column_indices_[i]) - { - this->values_[i] += alpha * val[a_iter]; - a_iter++; - } + break; } - //push back rest that was not found sorted_ - for (IdxT i = a_iter; i < static_cast(r.size()); i++) + + if (r[a_iter] == this->row_indices_[i] && c[a_iter] == this->column_indices_[i]) { - this->row_indices_.push_back(r[i]); - this->column_indices_.push_back(c[i]); - this->values_.push_back(alpha * val[i]); - - this->checkIncreaseSize(r[i], c[i]); + this->values_[i] += alpha * val[a_iter]; + a_iter++; } - - this->sorted_ = false; + } + // push back rest that was not found sorted_ + for (IdxT i = a_iter; i < static_cast(r.size()); i++) + { + this->row_indices_.push_back(r[i]); + this->column_indices_.push_back(c[i]); + this->values_.push_back(alpha * val[i]); + + this->checkIncreaseSize(r[i], c[i]); + } + + this->sorted_ = false; } /** * @brief axpy on a COO representation of a matrix. Will sort before running - * - * @tparam ScalarT - * @tparam IdxT - * @param alpha scalar to multiply by + * + * @tparam ScalarT + * @tparam IdxT + * @param alpha scalar to multiply by * @param r row indices * @param c column indices * @param v values - * + * * @pre r.size() == c.size() == v.size() * @pre r,c,v represent an array a in COO format - * + * * @post this = this + alpha * a */ template inline void COO_Matrix::axpy(ScalarT alpha, std::vector r, std::vector c, std::vector v) { - if (alpha == 0) return; - - if (!this->sorted_) + if (alpha == 0) + return; + + if (!this->sorted_) + { + this->sortSparse(); + } + + // sort input + this->sortSparseCOO(r, c, v); + + IdxT a_iter = 0; + // iterate for all current values_ in matrix + for (IdxT i = 0; i < static_cast(this->row_indices_.size()); i++) + { + // pushback values_ when they are not in current matrix + while (a_iter < static_cast(r.size()) && (r[a_iter] < this->row_indices_[i] || (r[a_iter] == this->row_indices_[i] && c[a_iter] < this->column_indices_[i]))) { - this->sortSparse(); - } - - //sort input - this->sortSparseCOO(r, c, v); + this->row_indices_.push_back(r[a_iter]); + this->column_indices_.push_back(c[a_iter]); + this->values_.push_back(alpha * v[a_iter]); - IdxT a_iter = 0; - //iterate for all current values_ in matrix - for (IdxT i = 0; i < static_cast(this->row_indices_.size()); i++) + this->checkIncreaseSize(r[a_iter], c[a_iter]); + a_iter++; + } + if (a_iter >= static_cast(r.size())) { - //pushback values_ when they are not in current matrix - while(a_iter < static_cast(r.size()) && (r[a_iter] < this->row_indices_[i] || (r[a_iter] == this->row_indices_[i] && c[a_iter] < this->column_indices_[i]))) - { - this->row_indices_.push_back(r[a_iter]); - this->column_indices_.push_back(c[a_iter]); - this->values_.push_back(alpha * v[a_iter]); - - this->checkIncreaseSize(r[a_iter], c[a_iter]); - a_iter++; - } - if (a_iter >= static_cast(r.size())) - { - break; - } - - - if (r[a_iter] == this->row_indices_[i] && c[a_iter] == this->column_indices_[i]) - { - this->values_[i] += alpha * v[a_iter]; - a_iter++; - } + break; } - //push back rest that was not found sorted_ - for (IdxT i = a_iter; i < static_cast(r.size()); i++) + + if (r[a_iter] == this->row_indices_[i] && c[a_iter] == this->column_indices_[i]) { - this->row_indices_.push_back(r[i]); - this->column_indices_.push_back(c[i]); - this->values_.push_back(alpha * v[i]); - - this->checkIncreaseSize(r[i], c[i]); + this->values_[i] += alpha * v[a_iter]; + a_iter++; } - - this->sorted_ = false; + } + // push back rest that was not found sorted_ + for (IdxT i = a_iter; i < static_cast(r.size()); i++) + { + this->row_indices_.push_back(r[i]); + this->column_indices_.push_back(c[i]); + this->values_.push_back(alpha * v[i]); + + this->checkIncreaseSize(r[i], c[i]); + } + + this->sorted_ = false; } /** * @brief Scale all values by alpha - * - * @tparam ScalarT - * @tparam IdxT + * + * @tparam ScalarT + * @tparam IdxT * @param[in] alpha scalar to scale by */ template inline void COO_Matrix::scal(ScalarT alpha) { - for (auto i = this->values_.begin(); i < this->values_.end(); i++) - { - *i *= alpha; - } + for (auto i = this->values_.begin(); i < this->values_.end(); i++) + { + *i *= alpha; + } } /** * @brief Calculates the Frobenius Norm of the matrix - * - * @tparam ScalarT - * @tparam IdxT + * + * @tparam ScalarT + * @tparam IdxT * @return ScalarT - Frobenius Norm of the matrix */ template inline ScalarT COO_Matrix::frobNorm() { - ScalarT totsum = 0.0; - for (auto i = this->values_.begin(); i < this->values_.end(); i++) - { - totsum += abs(*i)^2; - } - return totsum; + ScalarT totsum = 0.0; + for (auto i = this->values_.begin(); i < this->values_.end(); i++) + { + totsum += abs(*i) ^ 2; + } + return totsum; } /** * @brief Permutate the matrix to a different one. Only changes the coordinates - * - * @tparam ScalarT - * @param[in] row_perm - * @param[out] col_perm - * + * + * @tparam ScalarT + * @param[in] row_perm + * @param[out] col_perm + * * @pre row_perm.size() == this->rows_size_ = col_perm.size() == this->columns_size_ - * + * * @post this = this(row_perm, col_perm) */ template inline void COO_Matrix::permutation(std::vector row_perm, std::vector col_perm) { - assert(row_perm.size() = this->rows_size_); - assert(col_perm.size() = this->columns_size_); - - for (int i = 0; i < this->values_.size(); i++) - { - this->row_indices_[i] = row_perm[this->row_indices_[i]]; - this->column_indices_[i] = col_perm[this->column_indices_[i]]; - } - this->sorted_ = false; - //cycle sorting maybe useful since permutations are already known + assert(row_perm.size() = this->rows_size_); + assert(col_perm.size() = this->columns_size_); + + for (int i = 0; i < this->values_.size(); i++) + { + this->row_indices_[i] = row_perm[this->row_indices_[i]]; + this->column_indices_[i] = col_perm[this->column_indices_[i]]; + } + this->sorted_ = false; + // cycle sorting maybe useful since permutations are already known } /** * @brief Permutes the matrix and can change its size efficently - * - * @tparam ScalarT - * @tparam IdxT + * + * @tparam ScalarT + * @tparam IdxT * @param[in] row_perm row permutation * @param[in] col_perm column permutation * @param[in] m number of rows * @param[in] n number of columns - * - * @pre row_perm.size() == this->rows_size_ - * @pre col_perm.size() == this->columns_size_ + * + * @pre row_perm.size() == this->rows_size_ + * @pre col_perm.size() == this->columns_size_ * @pre indices are set to -1 if they are to be removed - * + * * @post this = this(row_perm, col_perm) and removed indices have corresponding values set to 0 */ template inline void COO_Matrix::permutationSizeMap(std::vector row_perm, std::vector col_perm, IdxT m, IdxT n) { - assert(row_perm.size() == this->rows_size_); - assert(col_perm.size() == this->columns_size_); - - this->rows_size_ = m; - this->columns_size_ = n; + assert(row_perm.size() == this->rows_size_); + assert(col_perm.size() == this->columns_size_); + + this->rows_size_ = m; + this->columns_size_ = n; - for (int i = 0; i < this->values_.size(); i++) + for (int i = 0; i < this->values_.size(); i++) + { + if (row_perm[this->row_indices_[i]] == -1 || col_perm[this->column_indices_[i]] == -1) + { + this->values_[i] = 0; + } + else { - if (row_perm[this->row_indices_[i]] == -1 || col_perm[this->column_indices_[i]] == -1) - { - this->values_[i] = 0; - } - else - { - this->row_indices_[i] = row_perm[this->row_indices_[i]]; - this->column_indices_[i] = col_perm[this->column_indices_[i]]; - } + this->row_indices_[i] = row_perm[this->row_indices_[i]]; + this->column_indices_[i] = col_perm[this->column_indices_[i]]; } - this->sorted_ = false; + } + this->sorted_ = false; } /** * @brief Turn matrix into the zero matrix. Does not actually delete memory - * - * @tparam ScalarT - * @tparam IdxT - * + * + * @tparam ScalarT + * @tparam IdxT + * */ template inline void COO_Matrix::zeroMatrix() { - //resize doesn't effect capacity if smaller - this->column_indices_.resize(0); - this->row_indices_.resize(0); - this->values_.resize(0); - this->sorted_ = true; + // resize doesn't effect capacity if smaller + this->column_indices_.resize(0); + this->row_indices_.resize(0); + this->values_.resize(0); + this->sorted_ = true; } /** * @brief Turn matrix into the identity matrix - * + * * @tparam ScalarT * @tparam IdxT - * + * * @param[in] n size of the identity matrix - * + * * @post this = I_n - * + * * @todo - it might be better to explicitly zero out the matrix and require to be so in preconditions */ template inline void COO_Matrix::identityMatrix(IdxT n) { - //Reset Matrix - this->zeroMatrix(); - for (IdxT i = 0; i < n; i++) - { - this->column_indices_[i] = i; - this->row_indices_[i] = i; - this->values_[i] = 1.0; - } - this->sorted_ = true; + // Reset Matrix + this->zeroMatrix(); + for (IdxT i = 0; i < n; i++) + { + this->column_indices_[i] = i; + this->row_indices_[i] = i; + this->values_[i] = 1.0; + } + this->sorted_ = true; } /** * @brief Restructure the sparse matrix for faster accesses and modifications - * - * @tparam ScalarT - * @tparam IdxT + * + * @tparam ScalarT + * @tparam IdxT */ template inline void COO_Matrix::sortSparse() { - this->sortSparseCOO(this->row_indices_, this->column_indices_, this->values_); - this->sorted_ = true; + this->sortSparseCOO(this->row_indices_, this->column_indices_, this->values_); + this->sorted_ = true; } /** * @brief Check if the matrix is sorted - * + * * @tparam ScalarT * @tparam IdxT - * + * * @param[out] bool - true if sorted, false otherwise */ template inline bool COO_Matrix::isSorted() { - return this->sorted_; + return this->sorted_; } /** * @brief Get the number of non-zero elements in the matrix - * + * * @tparam ScalarT * @tparam IdxT - * + * * @param[out] IdxT - number of non-zero elements in the matrix */ template inline IdxT COO_Matrix::nnz() { - return static_cast(this->values_.size()); + return static_cast(this->values_.size()); } template inline std::tuple COO_Matrix::getDimensions() { - return std::tuple(this->rows_size_, this->columns_size_); + return std::tuple(this->rows_size_, this->columns_size_); } /** * @brief Print matrix in sorted order - * - * @tparam ScalarT - * @tparam IdxT - * + * + * @tparam ScalarT + * @tparam IdxT + * * @param[in] name to identify the specific matrix printed */ template inline void COO_Matrix::printMatrix(std::string name) { - if (this->sorted_ == false) - { - this->sortSparse(); - } - - std::cout << "Sparse COO Matrix: " << name << "\n"; - std::cout << "(x , y, value)\n"; - for (size_t i = 0; i < this->values_.size(); i++) - { - std::cout << "(" << this->row_indices_[i] - << ", " << this->column_indices_[i] - << ", " << this->values_[i] << ")\n"; - } - std::cout << std::flush; + if (this->sorted_ == false) + { + this->sortSparse(); + } + + std::cout << "Sparse COO Matrix: " << name << "\n"; + std::cout << "(x , y, value)\n"; + for (size_t i = 0; i < this->values_.size(); i++) + { + std::cout << "(" << this->row_indices_[i] + << ", " << this->column_indices_[i] + << ", " << this->values_[i] << ")\n"; + } + std::cout << std::flush; } /** * @brief Find the lowest row cordinate from set of provided coordinates - * + * * Assumes rows and columns are sorted - * @tparam ScalarT - * @tparam IdxT - * + * @tparam ScalarT + * @tparam IdxT + * * @param[in] rows - row indices * @param[in] r - row index - * + * * @return IdxT - index of lowest row */ template -inline IdxT COO_Matrix::indexStartRow(const std::vector &rows, IdxT r) +inline IdxT COO_Matrix::indexStartRow(const std::vector& rows, IdxT r) { - //Specialized Binary Search for Lowest Row - IdxT i1 = 0; - IdxT i2 = rows->size()-1; - IdxT m_smallest = -1; - IdxT m = -1; - while (i1 <= i2) + // Specialized Binary Search for Lowest Row + IdxT i1 = 0; + IdxT i2 = rows->size() - 1; + IdxT m_smallest = -1; + IdxT m = -1; + while (i1 <= i2) + { + m = (i2 + i1) / 2; + // rows + if (rows[m] < r) + { + i1 = m + 1; + } + else if (r < rows[m]) { - m = (i2 + i1) / 2; - //rows - if (rows[m] < r) - { - i1 = m + 1; - } - else if (r < rows[m]) - { - i2 = m - 1; - } - else - { - if (i1 == i2) - { - return m_smallest; - } - - //Keep track of smallest cordinate - m_smallest = m; - i2 = m - 1; - } + i2 = m - 1; } - return m_smallest; + else + { + if (i1 == i2) + { + return m_smallest; + } + + // Keep track of smallest cordinate + m_smallest = m; + i2 = m - 1; + } + } + return m_smallest; } /** * @brief Basic binary search - * - * @tparam ScalarT - * @tparam IdxT + * + * @tparam ScalarT + * @tparam IdxT * @param[in] rows - row indices * @param[in] columns - column indices * @param[in] ri - row index @@ -683,47 +682,47 @@ inline IdxT COO_Matrix::indexStartRow(const std::vector &ro * @return IdxT - returns the index of the coordinate */ template -inline IdxT COO_Matrix::sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, IdxT ri, IdxT ci) +inline IdxT COO_Matrix::sparseCordBinarySearch(const std::vector& rows, const std::vector& columns, IdxT ri, IdxT ci) { - assert(rows.size() == columns.size()); - //basic binary search - IdxT i1 = 0; - IdxT i2 = rows.size()-1; - IdxT m = 0; - while (i1 <= i2) + assert(rows.size() == columns.size()); + // basic binary search + IdxT i1 = 0; + IdxT i2 = rows.size() - 1; + IdxT m = 0; + while (i1 <= i2) + { + m = (i2 + i1) / 2; + // rows + if (rows[m] < ri) + { + i1 = m + 1; + } + else if (ri < rows[m]) { - m = (i2 + i1) / 2; - //rows - if (rows[m] < ri) - { - i1 = m + 1; - } - else if (ri < rows[m]) - { - i2 = m - 1; - } - else - { - if (columns[m] < ci) - { - i1 = m + 1; - } - else if (ci < columns[m]) - { - i2 = m - 1; - } - break; - } + i2 = m - 1; } - - return m; + else + { + if (columns[m] < ci) + { + i1 = m + 1; + } + else if (ci < columns[m]) + { + i2 = m - 1; + } + break; + } + } + + return m; } /** * @brief Check if the size of the matrix needs to be increased - * - * @tparam ScalarT - * @tparam IdxT + * + * @tparam ScalarT + * @tparam IdxT * @param[in] r row index * @param[in] c column index * @return true if size was increased @@ -732,152 +731,150 @@ inline IdxT COO_Matrix::sparseCordBinarySearch(const std::vector< template inline bool COO_Matrix::checkIncreaseSize(IdxT r, IdxT c) { - bool changed = false; - if (r + 1 > this->rows_size_) - { - this->rows_size_ = r + 1; - changed = true; - } - if (c + 1 > this->columns_size_) - { - this->columns_size_ = c + 1; - changed = true; - } - - return changed; + bool changed = false; + if (r + 1 > this->rows_size_) + { + this->rows_size_ = r + 1; + changed = true; + } + if (c + 1 > this->columns_size_) + { + this->columns_size_ = c + 1; + changed = true; + } + + return changed; } /** * @brief Sorts unordered COO matrix - * - * Matrix entries can appear in arbitrary order and will be sorted in + * + * Matrix entries can appear in arbitrary order and will be sorted in * row-major order before the method returns. * Duplicate entries are not allowed and should be pre-summed. - * + * * @pre rows, columns, and values are of the same size and represent a COO matrix with no duplicates * @post Matrix entries are sorted in row-major order - * - * @todo simple setup. Should add stable sorting since lists are pre-sorted_ - * - * @tparam ScalarT - * @tparam IdxT - * @param rows - * @param columns + * + * @todo simple setup. Should add stable sorting since lists are pre-sorted_ + * + * @tparam ScalarT + * @tparam IdxT + * @param rows + * @param columns * @param values */ template -inline void COO_Matrix::sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values) +inline void COO_Matrix::sortSparseCOO(std::vector& rows, std::vector& columns, std::vector& values) { - - //index based sort code - // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted_-vector - //cannot call sort since two arrays are used instead - std::vector ordervec(rows.size()); - std::size_t n(0); - std::generate(std::begin(ordervec), std::end(ordervec), [&]{ return n++; }); - - //Sort by row first then column. - std::sort( std::begin(ordervec), - std::end(ordervec), - [&](int i1, int i2) { return (rows[i1] < rows[i2]) || - (rows[i1] == rows[i2] && columns[i1] < columns[i2]); } ); - - - //reorder based of index-sorting. Only swap cost no extra memory. - // @todo see if extra memory creation is fine - // https://stackoverflow.com/a/22183350 - for (size_t i = 0; i < ordervec.size(); i++) + + // index based sort code + // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted_-vector + // cannot call sort since two arrays are used instead + std::vector ordervec(rows.size()); + std::size_t n(0); + std::generate(std::begin(ordervec), std::end(ordervec), [&] + { return n++; }); + + // Sort by row first then column. + std::sort(std::begin(ordervec), + std::end(ordervec), + [&](int i1, int i2) + { return (rows[i1] < rows[i2]) || (rows[i1] == rows[i2] && columns[i1] < columns[i2]); }); + + // reorder based of index-sorting. Only swap cost no extra memory. + // @todo see if extra memory creation is fine + // https://stackoverflow.com/a/22183350 + for (size_t i = 0; i < ordervec.size(); i++) + { + // permutation swap + while (ordervec[i] != ordervec[ordervec[i]]) { - //permutation swap - while (ordervec[i] != ordervec[ordervec[i]]) - { - std::swap(rows[ordervec[i]], rows[ordervec[ordervec[i]]]); - std::swap(columns[ordervec[i]], columns[ordervec[ordervec[i]]]); - std::swap(values[ordervec[i]], values[ordervec[ordervec[i]]]); - - //swap orderings - std::swap(ordervec[i], ordervec[ordervec[i]]); - } - + std::swap(rows[ordervec[i]], rows[ordervec[ordervec[i]]]); + std::swap(columns[ordervec[i]], columns[ordervec[ordervec[i]]]); + std::swap(values[ordervec[i]], values[ordervec[ordervec[i]]]); + + // swap orderings + std::swap(ordervec[i], ordervec[ordervec[i]]); } + } } /** * @brief Constructor for COO Matrix with given cooridnates and values - * + * * @tparam ScalarT * @tparam IdxT - * + * * @param[in] r row indices * @param[in] c column indices * @param[in] v values * @param[in] m number of rows * @param[in] n number of columns - * + * * @pre r.size() == c.size() == v.size() * @pre r,c,v represent an array in COO format - * + * * @post COO_Matrix is created with given coordinates and values */ template inline COO_Matrix::COO_Matrix(std::vector r, std::vector c, std::vector v, IdxT m, IdxT n) { - this->values_ = v; - this->row_indices_ = r; - this->column_indices_ = c; - this->rows_size_ = m; - this->columns_size_ = n; - this->sorted_ = false; // Set to false until explicitly sorted, though logically it is sorted. + this->values_ = v; + this->row_indices_ = r; + this->column_indices_ = c; + this->rows_size_ = m; + this->columns_size_ = n; + this->sorted_ = false; // Set to false until explicitly sorted, though logically it is sorted. } /** * @brief Constructor for empty COO Matrix of a given size - * + * * @tparam ScalarT * @tparam IdxT - * + * * @param[in] m number of rows * @param[in] n number of columns - * + * * @post empty COO Matrix is created with given size */ template inline COO_Matrix::COO_Matrix(IdxT m, IdxT n) { - this->rows_size_ = m; - this->columns_size_ = n; - this->values_ = std::vector(); - this->row_indices_ = std::vector(); - this->column_indices_ = std::vector(); - this->sorted_ = false; // Set to false until explicitly sorted, though logically it is sorted. + this->rows_size_ = m; + this->columns_size_ = n; + this->values_ = std::vector(); + this->row_indices_ = std::vector(); + this->column_indices_ = std::vector(); + this->sorted_ = false; // Set to false until explicitly sorted, though logically it is sorted. } /** * @brief Constructor for empty COO Matrix of size 0 - * + * * @tparam ScalarT * @tparam IdxT - * + * * @post empty COO Matrix of size 0 is created */ template inline COO_Matrix::COO_Matrix() { - this->rows_size_ = 0; - this->columns_size_ = 0; - this->values_ = std::vector(); - this->row_indices_ = std::vector(); - this->column_indices_ = std::vector(); - this->sorted_ = false; // Set to false until explicitly sorted, though logically it is sorted. + this->rows_size_ = 0; + this->columns_size_ = 0; + this->values_ = std::vector(); + this->row_indices_ = std::vector(); + this->column_indices_ = std::vector(); + this->sorted_ = false; // Set to false until explicitly sorted, though logically it is sorted. } template COO_Matrix::~COO_Matrix() { - } #endif diff --git a/src/LinearAlgebra/SparsityPattern/Variable.hpp b/src/LinearAlgebra/SparsityPattern/Variable.hpp index cb132139..4015f65a 100644 --- a/src/LinearAlgebra/SparsityPattern/Variable.hpp +++ b/src/LinearAlgebra/SparsityPattern/Variable.hpp @@ -3,335 +3,328 @@ */ #pragma once -#include -#include -#include +#include #include +#include #include - -#include -#include -#include #include +#include +#include +#include #include +#include namespace GridKit { -namespace Sparse -{ - + namespace Sparse + { + /** - @brief The Variable class is used to store the unknowns of the + @brief The Variable class is used to store the unknowns of the system and define abstract elementary algebra. - + \author Stefan Klus \author Slaven Peles */ class Variable { public: - /** - @brief Default constructor. - */ - Variable() - : value_(0.0), - variable_number_(INVALID_VAR_NUMBER), - is_fixed_(false), - dependencies_(new DependencyMap) - { - } - - /** - @brief Constructor which initializes the value. - */ - explicit Variable(double value) - : value_(value), - variable_number_(INVALID_VAR_NUMBER), - is_fixed_(false), - dependencies_(new DependencyMap) - { - } - - /** - @brief Constructor which initializes the value and variable - number. - - */ - Variable(double value, size_t variable_number) - : value_(value), - variable_number_(variable_number), - is_fixed_(false), - dependencies_(new DependencyMap) - { - (*dependencies_)[variable_number_] = 1.0; - } - - /** - @brief Copy constructor. - */ - Variable(const Variable& v) - : value_(v.value_), - variable_number_(INVALID_VAR_NUMBER), - is_fixed_(false), - dependencies_(new DependencyMap(*v.dependencies_)) - { - } - - /** - @brief Destructor deletes the dependency map. - */ - ~Variable() - { - delete dependencies_; - } - - /** - @brief Assignment operator. Assigning double value to - Variable removes its dependencies. Use only if you know - what you are doing. - */ - Variable& operator=(const double& rhs) - { - value_ = rhs; - - dependencies_->clear(); - return *this; - } - - /** - @brief Assignment operator. - - This operator: - - assigns value from the right hand side - - leaves variable ID unchanged - - clears any existing and adds new dependencies from rhs - */ - Variable& operator=(const Variable& rhs) - { - if (this == &rhs) // self-assignment - return *this; - - // set value from rhs - value_ = rhs.value_; - - // if rhs is a constant so is *this - setFixed(rhs.is_fixed()); - - // set dependencies from rhs - dependencies_->clear(); // clear map just in case - addDependencies(rhs); // use only dependencies from the rhs - - return *this; - } - - - /** - @brief Operator () returns the value of a variable. - - This is just short notation to avoid using - getValue and setValue. - */ - double& operator()() - { - return value_; - } - - /** - @brief Operator() returns the value of a variable - (const version). - - This is just short notation to avoid using getValue. - */ - const double& operator()() const - { - return value_; - } - - /** - @brief Return the current value of the variable. - */ - double getValue() const - { - return value_; - } - - /** - @brief Overwrite the current value of the variable. - */ - void setValue(double value) - { - value_ = value; - } - - /** - @brief Return derivative of *this with respect to - dependency i. - */ - double der(size_t i) const - { - return (*dependencies_)[i]; - } - - - /** - @brief Returns the variable number. - - This number is assigned to state variables (variables - updated directly by the solver) only. - */ - size_t getVariableNumber() const - { - return variable_number_; - } - - /** - @brief Sets the variable number. - */ - void setVariableNumber(size_t variable_number) - { - dependencies_->clear(); - variable_number_ = variable_number; - (*dependencies_)[variable_number_] = 1.0; - } - - /** - @brief Checks whether the variable was registered as - an unknown of the system. - - INVALID_VAR_NUMBER is used to mark parameters and - temporary variables - */ - bool isRegistered() const - { - return variable_number_ != INVALID_VAR_NUMBER; - } - - /** - @brief Checks whether the variable is fixed or not. - */ - bool is_fixed() const - { - return is_fixed_; - } - - /** - @brief Turns variable into parameter, or vice versa. - */ - void setFixed(bool b = false) - { - is_fixed_ = b; - } - - - // get the 'input set' of a variable - using DependencyMap = std::map; - inline const DependencyMap& getDependencies() const; - - // set as the independent state variable and assign ID to it - inline void registerVariable(std::vector& x, - const size_t& offset); - - // adds all dependencies of v to *this - inline void addDependencies(const Variable& v); - - // scale dependencies (derivatives) by scalar @a c. - inline void scaleDependencies(double c); - - // print to output stream - inline void print(std::ostream& os) const; - - // += - inline Variable& operator+=(const double& rhs); - inline Variable& operator+=(const Variable& rhs); - - // -= - inline Variable& operator-=(const double& rhs); - inline Variable& operator-=(const Variable& rhs); - - // *= - inline Variable& operator*=(const double& rhs); - inline Variable& operator*=(const Variable& rhs); - - // /= - inline Variable& operator/=(const double& rhs); - inline Variable& operator/=(const Variable& rhs); - - + /** + @brief Default constructor. + */ + Variable() + : value_(0.0), + variable_number_(INVALID_VAR_NUMBER), + is_fixed_(false), + dependencies_(new DependencyMap) + { + } + + /** + @brief Constructor which initializes the value. + */ + explicit Variable(double value) + : value_(value), + variable_number_(INVALID_VAR_NUMBER), + is_fixed_(false), + dependencies_(new DependencyMap) + { + } + + /** + @brief Constructor which initializes the value and variable + number. + + */ + Variable(double value, size_t variable_number) + : value_(value), + variable_number_(variable_number), + is_fixed_(false), + dependencies_(new DependencyMap) + { + (*dependencies_)[variable_number_] = 1.0; + } + + /** + @brief Copy constructor. + */ + Variable(const Variable& v) + : value_(v.value_), + variable_number_(INVALID_VAR_NUMBER), + is_fixed_(false), + dependencies_(new DependencyMap(*v.dependencies_)) + { + } + + /** + @brief Destructor deletes the dependency map. + */ + ~Variable() + { + delete dependencies_; + } + + /** + @brief Assignment operator. Assigning double value to + Variable removes its dependencies. Use only if you know + what you are doing. + */ + Variable& operator=(const double& rhs) + { + value_ = rhs; + + dependencies_->clear(); + return *this; + } + + /** + @brief Assignment operator. + + This operator: + - assigns value from the right hand side + - leaves variable ID unchanged + - clears any existing and adds new dependencies from rhs + */ + Variable& operator=(const Variable& rhs) + { + if (this == &rhs) // self-assignment + return *this; + + // set value from rhs + value_ = rhs.value_; + + // if rhs is a constant so is *this + setFixed(rhs.is_fixed()); + + // set dependencies from rhs + dependencies_->clear(); // clear map just in case + addDependencies(rhs); // use only dependencies from the rhs + + return *this; + } + + /** + @brief Operator () returns the value of a variable. + + This is just short notation to avoid using + getValue and setValue. + */ + double& operator()() + { + return value_; + } + + /** + @brief Operator() returns the value of a variable + (const version). + + This is just short notation to avoid using getValue. + */ + const double& operator()() const + { + return value_; + } + + /** + @brief Return the current value of the variable. + */ + double getValue() const + { + return value_; + } + + /** + @brief Overwrite the current value of the variable. + */ + void setValue(double value) + { + value_ = value; + } + + /** + @brief Return derivative of *this with respect to + dependency i. + */ + double der(size_t i) const + { + return (*dependencies_)[i]; + } + + /** + @brief Returns the variable number. + + This number is assigned to state variables (variables + updated directly by the solver) only. + */ + size_t getVariableNumber() const + { + return variable_number_; + } + + /** + @brief Sets the variable number. + */ + void setVariableNumber(size_t variable_number) + { + dependencies_->clear(); + variable_number_ = variable_number; + (*dependencies_)[variable_number_] = 1.0; + } + + /** + @brief Checks whether the variable was registered as + an unknown of the system. + + INVALID_VAR_NUMBER is used to mark parameters and + temporary variables + */ + bool isRegistered() const + { + return variable_number_ != INVALID_VAR_NUMBER; + } + + /** + @brief Checks whether the variable is fixed or not. + */ + bool is_fixed() const + { + return is_fixed_; + } + + /** + @brief Turns variable into parameter, or vice versa. + */ + void setFixed(bool b = false) + { + is_fixed_ = b; + } + + // get the 'input set' of a variable + using DependencyMap = std::map; + inline const DependencyMap& getDependencies() const; + + // set as the independent state variable and assign ID to it + inline void registerVariable(std::vector& x, + const size_t& offset); + + // adds all dependencies of v to *this + inline void addDependencies(const Variable& v); + + // scale dependencies (derivatives) by scalar @a c. + inline void scaleDependencies(double c); + + // print to output stream + inline void print(std::ostream& os) const; + + // += + inline Variable& operator+=(const double& rhs); + inline Variable& operator+=(const Variable& rhs); + + // -= + inline Variable& operator-=(const double& rhs); + inline Variable& operator-=(const Variable& rhs); + + // *= + inline Variable& operator*=(const double& rhs); + inline Variable& operator*=(const Variable& rhs); + + // /= + inline Variable& operator/=(const double& rhs); + inline Variable& operator/=(const Variable& rhs); + private: - double value_; ///< Value of the variable. - size_t variable_number_; ///< Independent variable ID - bool is_fixed_; ///< Constant parameter flag. - - mutable DependencyMap* dependencies_; - static const size_t INVALID_VAR_NUMBER = static_cast(-1); + double value_; ///< Value of the variable. + size_t variable_number_; ///< Independent variable ID + bool is_fixed_; ///< Constant parameter flag. + + mutable DependencyMap* dependencies_; + static const size_t INVALID_VAR_NUMBER = static_cast(-1); }; - + //------------------------------------ // non-member operators and functions //------------------------------------ - + // unary - inline const Variable operator-(const Variable& v); - + // + inline const Variable operator+(const Variable& lhs, const Variable& rhs); inline const Variable operator+(const Variable& lhs, const double& rhs); inline const Variable operator+(const double& lhs, const Variable& rhs); - + // - inline const Variable operator-(const Variable& lhs, const Variable& rhs); inline const Variable operator-(const Variable& lhs, const double& rhs); inline const Variable operator-(const double& lhs, const Variable& rhs); - + // * inline const Variable operator*(const Variable& lhs, const Variable& rhs); inline const Variable operator*(const Variable& lhs, const double& rhs); inline const Variable operator*(const double& lhs, const Variable& rhs); - + // / inline const Variable operator/(const Variable& lhs, const Variable& rhs); inline const Variable operator/(const Variable& lhs, const double& rhs); inline const Variable operator/(const double& lhs, const Variable& rhs); - + // == inline bool operator==(const Variable& lhs, const Variable& rhs); inline bool operator==(const Variable& lhs, const double& rhs); inline bool operator==(const double& lhs, const Variable& rhs); - + // != inline bool operator!=(const Variable& lhs, const Variable& rhs); inline bool operator!=(const Variable& lhs, const double& rhs); inline bool operator!=(const double& lhs, const Variable& rhs); - + // < inline bool operator<(const Variable& lhs, const Variable& rhs); inline bool operator<(const Variable& lhs, const double& rhs); inline bool operator<(const double& lhs, const Variable& rhs); - + // > inline bool operator>(const Variable& lhs, const Variable& rhs); inline bool operator>(const Variable& lhs, const double& rhs); inline bool operator>(const double& lhs, const Variable& rhs); - + // <= inline bool operator<=(const Variable& lhs, const Variable& rhs); inline bool operator<=(const Variable& lhs, const double& rhs); inline bool operator<=(const double& lhs, const Variable& rhs); - + // >= inline bool operator>=(const Variable& lhs, const Variable& rhs); inline bool operator>=(const Variable& lhs, const double& rhs); inline bool operator>=(const double& lhs, const Variable& rhs); - + inline std::ostream& operator<<(std::ostream& os, const Variable& v); - inline Variable& operator<<(Variable& u, const Variable& v); - + inline Variable& operator<<(Variable& u, const Variable& v); + inline std::istream& operator>>(std::istream& is, Variable& v); - -} // namespace Sparse + } // namespace Sparse } // namespace GridKit #include "VariableImplementation.hpp" #include "VariableOperators.hpp" - diff --git a/src/LinearAlgebra/SparsityPattern/VariableImplementation.hpp b/src/LinearAlgebra/SparsityPattern/VariableImplementation.hpp index f001546a..30661e4b 100644 --- a/src/LinearAlgebra/SparsityPattern/VariableImplementation.hpp +++ b/src/LinearAlgebra/SparsityPattern/VariableImplementation.hpp @@ -6,209 +6,203 @@ namespace GridKit { -namespace Sparse -{ + namespace Sparse + { /** @brief Returns the list of derivatives. */ const Variable::DependencyMap& Variable::getDependencies() const { - assert(dependencies_ != 0); - return *dependencies_; + assert(dependencies_ != 0); + return *dependencies_; } - /** - @brief Registers a variable as an unknown of the system and + @brief Registers a variable as an unknown of the system and adds a pointer to the global @a x vector. */ - void Variable::registerVariable(std::vector& x, - const size_t& offset) + void Variable::registerVariable(std::vector& x, + const size_t& offset) { - setVariableNumber(offset); // define global variable number - setFixed(false); // not a constant + setVariableNumber(offset); // define global variable number + setFixed(false); // not a constant - x[offset] = this; + x[offset] = this; } - /** @brief Adds all dependencies of v to *this. */ void Variable::addDependencies(const Variable& v) { - for (auto& p : *(v.dependencies_)) - (*dependencies_)[p.first] = p.second; + for (auto& p : *(v.dependencies_)) + (*dependencies_)[p.first] = p.second; } - /** - @brief Multiplies each partial derivative of @a this by @a c. + @brief Multiplies each partial derivative of @a this by @a c. */ void Variable::scaleDependencies(double c) { - for (auto& p : *dependencies_) - (*dependencies_)[p.first] *= c; + for (auto& p : *dependencies_) + (*dependencies_)[p.first] *= c; } - - + /** @brief Prints the value and input set of the variable. */ void Variable::print(std::ostream& os) const { - os << value_; - - if (is_fixed_) - { - os << " (fixed)"; - return; - } - - if (variable_number_ != INVALID_VAR_NUMBER) - { - os << " (variable " << variable_number_ << ")"; - return; - } - - if (dependencies_!= NULL && !dependencies_->empty()) - { - os << " dependencies: [ "; - for (auto& p : *dependencies_) - os << "(" << p.first << ", " << p.second << ") "; - os << "]"; - } + os << value_; + + if (is_fixed_) + { + os << " (fixed)"; + return; + } + + if (variable_number_ != INVALID_VAR_NUMBER) + { + os << " (variable " << variable_number_ << ")"; + return; + } + + if (dependencies_ != NULL && !dependencies_->empty()) + { + os << " dependencies: [ "; + for (auto& p : *dependencies_) + os << "(" << p.first << ", " << p.second << ") "; + os << "]"; + } } - - + //------------------------------------ // compound assignment operators //------------------------------------ - + /** - @brief Compound addition-assignment operator. Right hand + @brief Compound addition-assignment operator. Right hand side is a built-in double type. */ Variable& Variable::operator+=(const double& rhs) { - value_ += rhs; - return *this; + value_ += rhs; + return *this; } - + /** - @brief Compound addition-assignment operator. Right hand side + @brief Compound addition-assignment operator. Right hand side is Variable type. */ Variable& Variable::operator+=(const Variable& rhs) { - // compute partial derivatives of *this - for (auto& p : *(rhs.dependencies_)) - (*dependencies_)[p.first] += (p.second); + // compute partial derivatives of *this + for (auto& p : *(rhs.dependencies_)) + (*dependencies_)[p.first] += (p.second); - // compute value of *this - value_ += rhs.value_; + // compute value of *this + value_ += rhs.value_; - return *this; + return *this; } - + // -= /** - @brief Compound subtraction-assignment operator. Right hand + @brief Compound subtraction-assignment operator. Right hand side is a built-in double type. */ Variable& Variable::operator-=(const double& rhs) { - value_ -= rhs; - return *this; + value_ -= rhs; + return *this; } - + /** - @brief Compound subtraction-assignment operator. Right hand + @brief Compound subtraction-assignment operator. Right hand side is a Variable type. */ Variable& Variable::operator-=(const Variable& rhs) { - // compute partial derivatives of *this - for (auto& p : *(rhs.dependencies_)) - (*dependencies_)[p.first] -= (p.second); + // compute partial derivatives of *this + for (auto& p : *(rhs.dependencies_)) + (*dependencies_)[p.first] -= (p.second); - // compute value of *this - value_ -= rhs.value_; + // compute value of *this + value_ -= rhs.value_; - return *this; + return *this; } - + // *= /** - @brief Compound multiplication-assignment operator. Right hand + @brief Compound multiplication-assignment operator. Right hand side is a built-in double type. */ Variable& Variable::operator*=(const double& rhs) { - // Compute derivatives of this - scaleDependencies(rhs); + // Compute derivatives of this + scaleDependencies(rhs); - // compute value - value_ *= rhs; + // compute value + value_ *= rhs; - return *this; + return *this; } - + /** - @brief Compound multiplication-assignment operator. Right + @brief Compound multiplication-assignment operator. Right hand side is a Variable type. */ Variable& Variable::operator*=(const Variable& rhs) { - // derivation by parts of @ *this - scaleDependencies(rhs.value_); + // derivation by parts of @ *this + scaleDependencies(rhs.value_); - // compute partial derivatives of rhs and add them to *this - for (auto& p : *(rhs.dependencies_)) - (*dependencies_)[p.first] += (p.second * value_); + // compute partial derivatives of rhs and add them to *this + for (auto& p : *(rhs.dependencies_)) + (*dependencies_)[p.first] += (p.second * value_); - // compute value of this - value_ *= rhs.value_; + // compute value of this + value_ *= rhs.value_; - return *this; + return *this; } - + // /= /** - @brief Compound division-assignment operator. Right hand side + @brief Compound division-assignment operator. Right hand side is a built-in double type. */ Variable& Variable::operator/=(const double& rhs) { - double inverseRhs = 1.0/rhs; + double inverseRhs = 1.0 / rhs; - // compute derivatives of @a *this - scaleDependencies(inverseRhs); + // compute derivatives of @a *this + scaleDependencies(inverseRhs); - value_ *= inverseRhs; - return *this; + value_ *= inverseRhs; + return *this; } - + /** - @brief Compound division-assignment operator. Right hand + @brief Compound division-assignment operator. Right hand side is a Variable type. */ Variable& Variable::operator/=(const Variable& rhs) { - double inverseRhs = 1.0/rhs.value_; - double inverseRhsSq = inverseRhs * inverseRhs; + double inverseRhs = 1.0 / rhs.value_; + double inverseRhsSq = inverseRhs * inverseRhs; - // derivation by parts of @a *this - scaleDependencies(inverseRhs); - for (auto& p : *(rhs.dependencies_)) - (*dependencies_)[p.first] -= (p.second * value_ * inverseRhsSq); + // derivation by parts of @a *this + scaleDependencies(inverseRhs); + for (auto& p : *(rhs.dependencies_)) + (*dependencies_)[p.first] -= (p.second * value_ * inverseRhsSq); - // compute value of this - value_ *= inverseRhs; + // compute value of this + value_ *= inverseRhs; - return *this; + return *this; } - -} // namespace Sparse -} // namespace GridKit + } // namespace Sparse +} // namespace GridKit diff --git a/src/LinearAlgebra/SparsityPattern/VariableOperators.hpp b/src/LinearAlgebra/SparsityPattern/VariableOperators.hpp index b97b3e27..ce572724 100644 --- a/src/LinearAlgebra/SparsityPattern/VariableOperators.hpp +++ b/src/LinearAlgebra/SparsityPattern/VariableOperators.hpp @@ -1,359 +1,356 @@ /** \file VariableOperators.hpp - + */ #pragma once namespace GridKit { -namespace Sparse -{ + namespace Sparse + { //------------------------------------ // non-member operators and functions //------------------------------------ - + // unary - const Variable operator-(const Variable& v) { - return -1.0*v; + return -1.0 * v; } - + // + const Variable operator+(const Variable& lhs, const Variable& rhs) { - return Variable(lhs) += rhs; + return Variable(lhs) += rhs; } - + const Variable operator+(const Variable& lhs, const double& rhs) { - return Variable(lhs) += rhs; + return Variable(lhs) += rhs; } - + const Variable operator+(const double& lhs, const Variable& rhs) { - return Variable(rhs) += lhs; + return Variable(rhs) += lhs; } - + // - const Variable operator-(const Variable& lhs, const Variable& rhs) { - return Variable(lhs) -= rhs; + return Variable(lhs) -= rhs; } - + const Variable operator-(const Variable& lhs, const double& rhs) { - return Variable(lhs) -= rhs; + return Variable(lhs) -= rhs; } - + const Variable operator-(const double& lhs, const Variable& rhs) { - return Variable(lhs) -= rhs; + return Variable(lhs) -= rhs; } - + // * const Variable operator*(const Variable& lhs, const Variable& rhs) { - return Variable(lhs) *= rhs; + return Variable(lhs) *= rhs; } - + const Variable operator*(const Variable& lhs, const double& rhs) { - return Variable(lhs) *= rhs; + return Variable(lhs) *= rhs; } - + const Variable operator*(const double& lhs, const Variable& rhs) { - return Variable(lhs) *= rhs; + return Variable(lhs) *= rhs; } - + // / const Variable operator/(const Variable& lhs, const Variable& rhs) { - return Variable(lhs) /= rhs; + return Variable(lhs) /= rhs; } - + const Variable operator/(const Variable& lhs, const double& rhs) { - return Variable(lhs) /= rhs; + return Variable(lhs) /= rhs; } - + const Variable operator/(const double& lhs, const Variable& rhs) { - return Variable(lhs) /= rhs; + return Variable(lhs) /= rhs; } - + // == bool operator==(const Variable& lhs, const Variable& rhs) { - return lhs.getValue() == rhs.getValue(); + return lhs.getValue() == rhs.getValue(); } - + bool operator==(const Variable& lhs, const double& rhs) { - return lhs.getValue() == rhs; + return lhs.getValue() == rhs; } - + bool operator==(const double& lhs, const Variable& rhs) { - return lhs == rhs.getValue(); + return lhs == rhs.getValue(); } - + // != bool operator!=(const Variable& lhs, const Variable& rhs) { - return !(lhs.getValue() == rhs.getValue()); + return !(lhs.getValue() == rhs.getValue()); } - + bool operator!=(const Variable& lhs, const double& rhs) { - return !(lhs.getValue() == rhs); + return !(lhs.getValue() == rhs); } - + bool operator!=(const double& lhs, const Variable& rhs) { - return !(lhs == rhs.getValue()); + return !(lhs == rhs.getValue()); } - + // < bool operator<(const Variable& lhs, const Variable& rhs) { - return lhs.getValue() < rhs.getValue(); + return lhs.getValue() < rhs.getValue(); } - + bool operator<(const Variable& lhs, const double& rhs) { - return lhs.getValue() < rhs; + return lhs.getValue() < rhs; } - + bool operator<(const double& lhs, const Variable& rhs) { - return lhs < rhs.getValue(); + return lhs < rhs.getValue(); } - + // > bool operator>(const Variable& lhs, const Variable& rhs) { - return lhs.getValue() > rhs.getValue(); + return lhs.getValue() > rhs.getValue(); } - + bool operator>(const Variable& lhs, const double& rhs) { - return lhs.getValue() > rhs; + return lhs.getValue() > rhs; } - + bool operator>(const double& lhs, const Variable& rhs) { - return lhs > rhs.getValue(); + return lhs > rhs.getValue(); } - + // <= bool operator<=(const Variable& lhs, const Variable& rhs) { - return lhs < rhs || lhs == rhs; + return lhs < rhs || lhs == rhs; } - + bool operator<=(const Variable& lhs, const double& rhs) { - return lhs < rhs || lhs == rhs; + return lhs < rhs || lhs == rhs; } - + bool operator<=(const double& lhs, const Variable& rhs) { - return lhs < rhs || lhs == rhs; + return lhs < rhs || lhs == rhs; } - + // >= bool operator>=(const Variable& lhs, const Variable& rhs) { - return lhs > rhs || lhs == rhs; + return lhs > rhs || lhs == rhs; } - + bool operator>=(const Variable& lhs, const double& rhs) { - return lhs > rhs || lhs == rhs; + return lhs > rhs || lhs == rhs; } - + bool operator>=(const double& lhs, const Variable& rhs) { - return lhs > rhs || lhs == rhs; + return lhs > rhs || lhs == rhs; } - + //------------------------------------ // non-member operators //------------------------------------ - + /** @brief Stream insertion operator for variables. */ std::ostream& operator<<(std::ostream& os, const Variable& v) { - v.print(os); - return os; + v.print(os); + return os; } - + /** - @brief Adds all dependencies of a variable, i.e. v << u means + @brief Adds all dependencies of a variable, i.e. v << u means that v depends on u. \attention Use only if you know what you are doing! */ Variable& operator<<(Variable& u, const Variable& v) { - u.addDependencies(v); - return u; + u.addDependencies(v); + return u; } - + /** @brief Stream extraction operator for variables. */ std::istream& operator>>(std::istream& is, Variable& v) { - return is >> v(); + return is >> v(); } - //------------------------------------------- // definitions of cmath functions derivatives //------------------------------------------- - /// Derivative of sine inline double sin_derivative(double x) { - return std::cos(x); + return std::cos(x); } /// Derivative of cosine inline double cos_derivative(double x) { - return -std::sin(x); + return -std::sin(x); } /// Derivative of tangent inline double tan_derivative(double x) { - return 1.0/(std::cos(x)*std::cos(x)); + return 1.0 / (std::cos(x) * std::cos(x)); } /// Derivative of arc sine inline double asin_derivative(double x) { - return std::sqrt(1.0 - x*x); + return std::sqrt(1.0 - x * x); } /// Derivative of arc cosine inline double acos_derivative(double x) { - return -std::sqrt(1.0 - x*x); + return -std::sqrt(1.0 - x * x); } /// Derivative of arc tangent inline double atan_derivative(double x) { - return 1.0/(1.0 + x*x); + return 1.0 / (1.0 + x * x); } /// Derivative of hyperbolic sine inline double sinh_derivative(double x) { - return std::cosh(x); + return std::cosh(x); } /// Derivative of hyperbolic cosine inline double cosh_derivative(double x) { - return std::sinh(x); + return std::sinh(x); } /// Derivative of hyperbolic tangent inline double tanh_derivative(double x) { - return 1.0/(std::cosh(x)*std::cosh(x)); + return 1.0 / (std::cosh(x) * std::cosh(x)); } /// Derivative of hyperbolic arc sine inline double asinh_derivative(double x) { - return std::sqrt(1.0 + x*x); + return std::sqrt(1.0 + x * x); } /// Derivative of hyperbolic arc cosine inline double acosh_derivative(double x) { - return std::sqrt(x*x - 1.0); + return std::sqrt(x * x - 1.0); } /// Derivative of hyperbolic arc tangent inline double atanh_derivative(double x) { - return 1.0/(1.0 - x*x); + return 1.0 / (1.0 - x * x); } /// Derivative of exponential function. inline double exp_derivative(double x) { - return std::exp(x); + return std::exp(x); } /// Derivative of natural logarithm function. inline double log_derivative(double x) { - return 1.0/x; + return 1.0 / x; } /// Derivative of logarithm to base 10 function: 1/(x*log(10)). inline double log10_derivative(double x) { - return 0.4342944819032518/x; + return 0.4342944819032518 / x; } /// Derivative of square root function. inline double sqrt_derivative(double x) { - return 0.5/std::sqrt(x); + return 0.5 / std::sqrt(x); } /// Derivative of absolute value function. inline double abs_derivative(double x) { - return x > 0.0 ? 1.0 : -1.0; + return x > 0.0 ? 1.0 : -1.0; } -} // namespace Sparse + } // namespace Sparse } // namespace GridKit -// Add all mathematical functions to the namespace std so that, +// Add all mathematical functions to the namespace std so that, // for instance, std::sin(x) also works with objects of type Variable. namespace std { - -#define IMPL_FUN_1(FUN,DER) \ - inline GridKit::Sparse::Variable FUN(const GridKit::Sparse::Variable& x) \ - { \ - double val = FUN(x()); \ - double der = DER(x()); \ - GridKit::Sparse::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; \ - } - - IMPL_FUN_1(sin, GridKit::Sparse::sin_derivative) - IMPL_FUN_1(cos, GridKit::Sparse::cos_derivative) - IMPL_FUN_1(tan, GridKit::Sparse::tan_derivative) - IMPL_FUN_1(asin, GridKit::Sparse::asin_derivative) - IMPL_FUN_1(acos, GridKit::Sparse::acos_derivative) - IMPL_FUN_1(atan, GridKit::Sparse::atan_derivative) - IMPL_FUN_1(sinh, GridKit::Sparse::sinh_derivative) - IMPL_FUN_1(cosh, GridKit::Sparse::cosh_derivative) - IMPL_FUN_1(tanh, GridKit::Sparse::tanh_derivative) - IMPL_FUN_1(exp, GridKit::Sparse::exp_derivative) - IMPL_FUN_1(log, GridKit::Sparse::log_derivative) - IMPL_FUN_1(log10, GridKit::Sparse::log10_derivative) - IMPL_FUN_1(sqrt, GridKit::Sparse::sqrt_derivative) - IMPL_FUN_1(abs, GridKit::Sparse::abs_derivative) - + +#define IMPL_FUN_1(FUN, DER) \ + inline GridKit::Sparse::Variable FUN(const GridKit::Sparse::Variable& x) \ + { \ + double val = FUN(x()); \ + double der = DER(x()); \ + GridKit::Sparse::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; \ + } + + IMPL_FUN_1(sin, GridKit::Sparse::sin_derivative) + IMPL_FUN_1(cos, GridKit::Sparse::cos_derivative) + IMPL_FUN_1(tan, GridKit::Sparse::tan_derivative) + IMPL_FUN_1(asin, GridKit::Sparse::asin_derivative) + IMPL_FUN_1(acos, GridKit::Sparse::acos_derivative) + IMPL_FUN_1(atan, GridKit::Sparse::atan_derivative) + IMPL_FUN_1(sinh, GridKit::Sparse::sinh_derivative) + IMPL_FUN_1(cosh, GridKit::Sparse::cosh_derivative) + IMPL_FUN_1(tanh, GridKit::Sparse::tanh_derivative) + IMPL_FUN_1(exp, GridKit::Sparse::exp_derivative) + IMPL_FUN_1(log, GridKit::Sparse::log_derivative) + IMPL_FUN_1(log10, GridKit::Sparse::log10_derivative) + IMPL_FUN_1(sqrt, GridKit::Sparse::sqrt_derivative) + IMPL_FUN_1(abs, GridKit::Sparse::abs_derivative) + #undef IMPL_FUN_1 } // namespace std - diff --git a/src/Model/Evaluator.hpp b/src/Model/Evaluator.hpp index 7a374d97..b4a447dd 100644 --- a/src/Model/Evaluator.hpp +++ b/src/Model/Evaluator.hpp @@ -1,13 +1,14 @@ #pragma once #include -#include + #include +#include namespace GridKit { -namespace Model -{ + namespace Model + { /*! * @brief Abstract class describing a model. * @@ -16,81 +17,84 @@ namespace Model class Evaluator { public: - typedef typename GridKit::ScalarTraits::real_type real_type; + typedef typename GridKit::ScalarTraits::real_type real_type; - Evaluator(){} - virtual ~Evaluator(){} + Evaluator() + { + } - virtual int allocate() = 0; - virtual int initialize() = 0; - virtual int tagDifferentiable() = 0; - virtual int evaluateResidual() = 0; - virtual int evaluateJacobian() = 0; - virtual int evaluateIntegrand() = 0; + virtual ~Evaluator() + { + } - virtual int initializeAdjoint() = 0; - virtual int evaluateAdjointResidual() = 0; - // virtual int evaluateAdjointJacobian() = 0; - virtual int evaluateAdjointIntegrand() = 0; + virtual int allocate() = 0; + virtual int initialize() = 0; + virtual int tagDifferentiable() = 0; + virtual int evaluateResidual() = 0; + virtual int evaluateJacobian() = 0; + virtual int evaluateIntegrand() = 0; - virtual IdxT size() = 0; - virtual IdxT nnz() = 0; + virtual int initializeAdjoint() = 0; + virtual int evaluateAdjointResidual() = 0; + // virtual int evaluateAdjointJacobian() = 0; + virtual int evaluateAdjointIntegrand() = 0; - /** - * @brief Is the Jacobian defined. Used in IDA to determine wether DQ is used or not - * - * @return true - * @return false - */ - virtual bool hasJacobian() = 0; - - virtual IdxT sizeQuadrature() = 0; - virtual IdxT sizeParams() = 0; - virtual void updateTime(real_type t, real_type a) = 0; - virtual void setTolerances(real_type& rtol, real_type& atol) const = 0; - virtual void setMaxSteps(IdxT& msa) const = 0; + virtual IdxT size() = 0; + virtual IdxT nnz() = 0; - virtual std::vector& y() = 0; - virtual const std::vector& y() const = 0; + /** + * @brief Is the Jacobian defined. Used in IDA to determine wether DQ is used or not + * + * @return true + * @return false + */ + virtual bool hasJacobian() = 0; - virtual std::vector& yp() = 0; - virtual const std::vector& yp() const = 0; + virtual IdxT sizeQuadrature() = 0; + virtual IdxT sizeParams() = 0; + virtual void updateTime(real_type t, real_type a) = 0; + virtual void setTolerances(real_type& rtol, real_type& atol) const = 0; + virtual void setMaxSteps(IdxT& msa) const = 0; - virtual std::vector& tag() = 0; - virtual const std::vector& tag() const = 0; + virtual std::vector& y() = 0; + virtual const std::vector& y() const = 0; - virtual std::vector& yB() = 0; - virtual const std::vector& yB() const = 0; + virtual std::vector& yp() = 0; + virtual const std::vector& yp() const = 0; - virtual std::vector& ypB() = 0; - virtual const std::vector& ypB() const = 0; + virtual std::vector& tag() = 0; + virtual const std::vector& tag() const = 0; - virtual std::vector& param() = 0; - virtual const std::vector& param() const = 0; + virtual std::vector& yB() = 0; + virtual const std::vector& yB() const = 0; - virtual std::vector& param_up() = 0; - virtual const std::vector& param_up() const = 0; + virtual std::vector& ypB() = 0; + virtual const std::vector& ypB() const = 0; - virtual std::vector& param_lo() = 0; - virtual const std::vector& param_lo() const = 0; + virtual std::vector& param() = 0; + virtual const std::vector& param() const = 0; - virtual std::vector& getResidual() = 0; - virtual const std::vector& getResidual() const = 0; + virtual std::vector& param_up() = 0; + virtual const std::vector& param_up() const = 0; + virtual std::vector& param_lo() = 0; + virtual const std::vector& param_lo() const = 0; - virtual COO_Matrix& getJacobian() = 0; - virtual const COO_Matrix& getJacobian() const = 0; + virtual std::vector& getResidual() = 0; + virtual const std::vector& getResidual() const = 0; - virtual std::vector& getIntegrand() = 0; - virtual const std::vector& getIntegrand() const = 0; + virtual COO_Matrix& getJacobian() = 0; + virtual const COO_Matrix& getJacobian() const = 0; - virtual std::vector& getAdjointResidual() = 0; - virtual const std::vector& getAdjointResidual() const = 0; + virtual std::vector& getIntegrand() = 0; + virtual const std::vector& getIntegrand() const = 0; - virtual std::vector& getAdjointIntegrand() = 0; - virtual const std::vector& getAdjointIntegrand() const = 0; + virtual std::vector& getAdjointResidual() = 0; + virtual const std::vector& getAdjointResidual() const = 0; + virtual std::vector& getAdjointIntegrand() = 0; + virtual const std::vector& getAdjointIntegrand() const = 0; }; -} // namespace Model + } // namespace Model } // namespace GridKit diff --git a/src/Model/PhasorDynamics/Branch/Branch.cpp b/src/Model/PhasorDynamics/Branch/Branch.cpp index 522e7990..75ccb8d7 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.cpp +++ b/src/Model/PhasorDynamics/Branch/Branch.cpp @@ -2,48 +2,49 @@ * @file Branch.hpp * @author Slaven Peles (peless@ornl.gov) * @brief Definition of a phasor dynamics branch model. - * + * * The model uses Cartesian coordinates. - * + * */ -#include +#include "Branch.hpp" + #include +#include + #include #include -#include "Branch.hpp" - namespace GridKit { -namespace PhasorDynamics -{ + namespace PhasorDynamics + { /*! - * @brief Constructor for a pi-model branch - * - * Arguments passed to ModelEvaluatorImpl: - * - Number of equations = 0 - * - Number of independent variables = 0 - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ + * @brief Constructor for a pi-model branch + * + * Arguments passed to ModelEvaluatorImpl: + * - Number of equations = 0 + * - Number of independent variables = 0 + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ template Branch::Branch(bus_type* bus1, bus_type* bus2) - : bus1_(bus1), - bus2_(bus2), - R_(0.0), - X_(0.01), - G_(0.0), - B_(0.0), - bus1ID_(0), - bus2ID_(0) + : bus1_(bus1), + bus2_(bus2), + R_(0.0), + X_(0.01), + G_(0.0), + B_(0.0), + bus1ID_(0), + bus2ID_(0) { - size_ = 0; + size_ = 0; } /** * @brief Construct a new Branch - * + * * @tparam ScalarT - scalar type * @tparam IdxT - matrix/vector index type * @param bus1 - pointer to bus-1 @@ -60,51 +61,51 @@ namespace PhasorDynamics real_type X, real_type G, real_type B) - : bus1_(bus1), - bus2_(bus2), - R_(R), - X_(X), - G_(G), - B_(B), - bus1ID_(0), - bus2ID_(0) + : bus1_(bus1), + bus2_(bus2), + R_(R), + X_(X), + G_(G), + B_(B), + bus1ID_(0), + bus2ID_(0) { } template Branch::Branch(bus_type* bus1, bus_type* bus2, BranchData& data) - : bus1_(bus1), - bus2_(bus2), - R_(data.r), - X_(data.x), - G_(0.0), - B_(data.b), - bus1ID_(data.fbus), - bus2ID_(data.tbus) + : bus1_(bus1), + bus2_(bus2), + R_(data.r), + X_(data.x), + G_(0.0), + B_(data.b), + bus1ID_(data.fbus), + bus2ID_(data.tbus) { - size_ = 0; + size_ = 0; } /** * @brief Destroy the Branch - * - * @tparam ScalarT - * @tparam IdxT + * + * @tparam ScalarT + * @tparam IdxT */ template Branch::~Branch() { - //std::cout << "Destroy Branch..." << std::endl; + // std::cout << "Destroy Branch..." << std::endl; } /*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ + * @brief allocate method computes sparsity pattern of the Jacobian. + */ template int Branch::allocate() { - //std::cout << "Allocate Branch..." << std::endl; - return 0; + // std::cout << "Allocate Branch..." << std::endl; + return 0; } /** @@ -114,7 +115,7 @@ namespace PhasorDynamics template int Branch::initialize() { - return 0; + return 0; } /** @@ -123,32 +124,32 @@ namespace PhasorDynamics template int Branch::tagDifferentiable() { - return 0; + return 0; } /** * \brief Residual contribution of the branch is pushed to the * two terminal buses. - * + * */ template int Branch::evaluateResidual() { - // std::cout << "Evaluating branch residual ...\n"; - real_type b = -X_/(R_*R_ + X_*X_); - real_type g = R_/(R_*R_ + X_*X_); + // std::cout << "Evaluating branch residual ...\n"; + real_type b = -X_ / (R_ * R_ + X_ * X_); + real_type g = R_ / (R_ * R_ + X_ * X_); - Ir1() += -(g + 0.5*G_)*Vr1() + (b + 0.5*B_)*Vi1() + g*Vr2() - b*Vi2(); - Ii1() += -(b + 0.5*B_)*Vr1() - (g + 0.5*G_)*Vi1() + b*Vr2() + g*Vi2(); - Ir2() += g*Vr1() - b*Vi1() - (g + 0.5*G_)*Vr2() + (b + 0.5*B_)*Vi2(); - Ii2() += b*Vr1() + g*Vi1() - (b + 0.5*B_)*Vr2() - (g + 0.5*G_)*Vi2(); + Ir1() += -(g + 0.5 * G_) * Vr1() + (b + 0.5 * B_) * Vi1() + g * Vr2() - b * Vi2(); + Ii1() += -(b + 0.5 * B_) * Vr1() - (g + 0.5 * G_) * Vi1() + b * Vr2() + g * Vi2(); + Ir2() += g * Vr1() - b * Vi1() - (g + 0.5 * G_) * Vr2() + (b + 0.5 * B_) * Vi2(); + Ii2() += b * Vr1() + g * Vi1() - (b + 0.5 * B_) * Vr2() - (g + 0.5 * G_) * Vi2(); - return 0; + return 0; } /** * @brief Jacobian evaluation not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -156,14 +157,14 @@ namespace PhasorDynamics template int Branch::evaluateJacobian() { - std::cout << "Evaluate Jacobian for Branch..." << std::endl; - std::cout << "Jacobian evaluation not implemented!" << std::endl; - return 0; + std::cout << "Evaluate Jacobian for Branch..." << std::endl; + std::cout << "Jacobian evaluation not implemented!" << std::endl; + return 0; } /** * @brief Integrand (objective) evaluation not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -171,13 +172,13 @@ namespace PhasorDynamics template int Branch::evaluateIntegrand() { - // std::cout << "Evaluate Integrand for Branch..." << std::endl; - return 0; + // std::cout << "Evaluate Integrand for Branch..." << std::endl; + return 0; } /** * @brief Adjoint initialization not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -185,13 +186,13 @@ namespace PhasorDynamics template int Branch::initializeAdjoint() { - //std::cout << "Initialize adjoint for Branch..." << std::endl; - return 0; + // std::cout << "Initialize adjoint for Branch..." << std::endl; + return 0; } /** * @brief Adjoint residual evaluation not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -199,13 +200,13 @@ namespace PhasorDynamics template int Branch::evaluateAdjointResidual() { - // std::cout << "Evaluate adjoint residual for Branch..." << std::endl; - return 0; + // std::cout << "Evaluate adjoint residual for Branch..." << std::endl; + return 0; } /** * @brief Adjoint integrand (objective) evaluation not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -213,13 +214,13 @@ namespace PhasorDynamics template int Branch::evaluateAdjointIntegrand() { - // std::cout << "Evaluate adjoint Integrand for Branch..." << std::endl; - return 0; + // std::cout << "Evaluate adjoint Integrand for Branch..." << std::endl; + return 0; } // Available template instantiations template class Branch; template class Branch; -} //namespace PhasorDynamics -} //namespace GridKit + } // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/Branch/Branch.hpp b/src/Model/PhasorDynamics/Branch/Branch.hpp index 983a85ef..67ed8d31 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.hpp +++ b/src/Model/PhasorDynamics/Branch/Branch.hpp @@ -2,9 +2,9 @@ * @file Branch.hpp * @author Slaven Peles (peless@ornl.gov) * @brief Declaration of a phasor dynamics branch model. - * + * * The model uses Cartesian coordinates. - * + * */ #pragma once @@ -13,148 +13,150 @@ // Forward declarations. namespace GridKit { -namespace PowerSystemData -{ - template struct BranchData; -} -} + namespace PowerSystemData + { + template + struct BranchData; + } +} // namespace GridKit namespace GridKit { -namespace PhasorDynamics -{ - template class Bus; -} -} + namespace PhasorDynamics + { + template + class Bus; + } +} // namespace GridKit namespace GridKit { -namespace PhasorDynamics -{ + namespace PhasorDynamics + { /** * @brief Implementation of a pi-model branch between two buses. - * + * * The model is implemented in Cartesian coordinates. Positive current * direction is into the busses. * */ - template + template class Branch : public Component { - using Component::size_; - using Component::nnz_; - using Component::time_; - using Component::alpha_; - using Component::y_; - using Component::yp_; - using Component::tag_; - using Component::f_; - using Component::g_; - using Component::yB_; - using Component::ypB_; - using Component::fB_; - using Component::gB_; - using Component::param_; - - using bus_type = BusBase; - using real_type = typename Component::real_type; - using BranchData = GridKit::PowerSystemData::BranchData; + using Component::size_; + using Component::nnz_; + using Component::time_; + using Component::alpha_; + using Component::y_; + using Component::yp_; + using Component::tag_; + using Component::f_; + using Component::g_; + using Component::yB_; + using Component::ypB_; + using Component::fB_; + using Component::gB_; + using Component::param_; + + using bus_type = BusBase; + using real_type = typename Component::real_type; + using BranchData = GridKit::PowerSystemData::BranchData; public: - Branch(bus_type* bus1, bus_type* bus2); - Branch(bus_type* bus1, bus_type* bus2, real_type R, real_type X, real_type G, real_type B); - Branch(bus_type* bus1, bus_type* bus2, BranchData& data); - virtual ~Branch(); - - virtual int allocate() override; - virtual int initialize() override; - virtual int tagDifferentiable() override; - virtual int evaluateResidual() override; - virtual int evaluateJacobian() override; - virtual int evaluateIntegrand() override; - - virtual int initializeAdjoint() override; - virtual int evaluateAdjointResidual() override; - // virtual int evaluateAdjointJacobian() override; - virtual int evaluateAdjointIntegrand() override; - - virtual void updateTime(real_type /* t */, real_type /* a */) override - { - } + Branch(bus_type* bus1, bus_type* bus2); + Branch(bus_type* bus1, bus_type* bus2, real_type R, real_type X, real_type G, real_type B); + Branch(bus_type* bus1, bus_type* bus2, BranchData& data); + virtual ~Branch(); + + virtual int allocate() override; + virtual int initialize() override; + virtual int tagDifferentiable() override; + virtual int evaluateResidual() override; + virtual int evaluateJacobian() override; + virtual int evaluateIntegrand() override; + + virtual int initializeAdjoint() override; + virtual int evaluateAdjointResidual() override; + // virtual int evaluateAdjointJacobian() override; + virtual int evaluateAdjointIntegrand() override; + + virtual void updateTime(real_type /* t */, real_type /* a */) override + { + } public: - void setR(real_type R) - { - R_ = R; - } - - void setX(real_type X) - { - // std::cout << "Setting X ...\n"; - X_ = X; - } - - void setG(real_type G) - { - G_ = G; - } - - void setB(real_type B) - { - B_ = B; - } + void setR(real_type R) + { + R_ = R; + } + + void setX(real_type X) + { + // std::cout << "Setting X ...\n"; + X_ = X; + } + + void setG(real_type G) + { + G_ = G; + } + + void setB(real_type B) + { + B_ = B; + } private: - ScalarT& Vr1() - { - return bus1_->Vr(); - } - - ScalarT& Vi1() - { - return bus1_->Vi(); - } - - ScalarT& Ir1() - { - return bus1_->Ir(); - } - - ScalarT& Ii1() - { - return bus1_->Ii(); - } - - ScalarT& Vr2() - { - return bus2_->Vr(); - } - - ScalarT& Vi2() - { - return bus2_->Vi(); - } - - ScalarT& Ir2() - { - return bus2_->Ir(); - } - - ScalarT& Ii2() - { - return bus2_->Ii(); - } + ScalarT& Vr1() + { + return bus1_->Vr(); + } + + ScalarT& Vi1() + { + return bus1_->Vi(); + } + + ScalarT& Ir1() + { + return bus1_->Ir(); + } + + ScalarT& Ii1() + { + return bus1_->Ii(); + } + + ScalarT& Vr2() + { + return bus2_->Vr(); + } + + ScalarT& Vi2() + { + return bus2_->Vi(); + } + + ScalarT& Ir2() + { + return bus2_->Ir(); + } + + ScalarT& Ii2() + { + return bus2_->Ii(); + } private: - bus_type* bus1_; - bus_type* bus2_; - real_type R_; - real_type X_; - real_type G_; - real_type B_; - const IdxT bus1ID_; - const IdxT bus2ID_; + bus_type* bus1_; + bus_type* bus2_; + real_type R_; + real_type X_; + real_type G_; + real_type B_; + const IdxT bus1ID_; + const IdxT bus2ID_; }; -} // namespace PhasorDynamics + } // namespace PhasorDynamics } // namespace GridKit diff --git a/src/Model/PhasorDynamics/Bus/Bus.cpp b/src/Model/PhasorDynamics/Bus/Bus.cpp index f085b13a..b7a60422 100644 --- a/src/Model/PhasorDynamics/Bus/Bus.cpp +++ b/src/Model/PhasorDynamics/Bus/Bus.cpp @@ -1,220 +1,217 @@ -#include +#include "Bus.hpp" + #include +#include #include -#include "Bus.hpp" namespace GridKit { -namespace PhasorDynamics -{ - -/*! - * @brief Constructor for a phasor dynamics bus. - * - * The model is using current balance in Cartesian coordinates. - * - * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: - * - Number of equations = 2 (size_) - * - Number of variables = 2 (size_) - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ -template -Bus::Bus() - : Vr0_(0.0), Vi0_(0.0) -{ - //std::cout << "Create Bus..." << std::endl; - //std::cout << "Number of equations is " << size_ << std::endl; - - size_ = 2; -} - -/*! - * @brief Bus constructor. - * - * This constructor sets initial values for active and reactive voltage. - * - * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: - * - Number of equations = 2 (size_) - * - Number of variables = 2 (size_) - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ -template -Bus::Bus(ScalarT Vr, ScalarT Vi) - : Vr0_(Vr), Vi0_(Vi) -{ - //std::cout << "Create Bus..." << std::endl; - //std::cout << "Number of equations is " << size_ << std::endl; - - size_ = 2; -} - -/** - * @brief Construct a new Bus - * - * @tparam ScalarT - type of scalar variables - * @tparam IdxT - type for vector/matrix indices - * @param[in] data - structure with bus data - */ -template -Bus::Bus(BusData& data) - : BusBase(data.bus_i), - Vr0_(data.Vm * cos(data.Va)), - Vi0_(data.Vm * sin(data.Va)) -{ - //std::cout << "Create Bus..." << std::endl; - //std::cout << "Number of equations is " << size_ << std::endl; - - size_ = 2; -} - -template -Bus::~Bus() -{ - //std::cout << "Destroy PQ bus ..." << std::endl; -} - -/*! - * @brief allocate method resizes local solution and residual vectors. - */ -template -int Bus::allocate() -{ - //std::cout << "Allocate PQ bus ..." << std::endl; - f_.resize(size_); - y_.resize(size_); - yp_.resize(size_); - tag_.resize(size_); - - fB_.resize(size_); - yB_.resize(size_); - ypB_.resize(size_); - - return 0; -} - - -/*! - * @brief Bus variables are algebraic. - */ -template -int Bus::tagDifferentiable() -{ - tag_[0] = false; - tag_[1] = false; - return 0; -} - - -/*! - * @brief initialize method sets bus variables to stored initial values. - */ -template -int Bus::initialize() -{ - // std::cout << "Initialize Bus..." << std::endl; - y_[0] = Vr0_; - y_[1] = Vi0_; - yp_[0] = 0.0; - yp_[1] = 0.0; - - return 0; -} - -/*! - * @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. - * - */ -template -int Bus::evaluateResidual() -{ - // std::cout << "Evaluating residual of a PQ bus ...\n"; - f_[0] = 0.0; - f_[1] = 0.0; - return 0; -} - -/** - * @brief Jacobian evaluation not implemented - * - * @tparam ScalarT - data type for Jacobian elements - * @tparam IdxT - data type for matrix indices - * @return int - error code - */ -template -int Bus::evaluateJacobian() -{ - return 0; -} - - -/*! - * @brief initialize method sets bus variables to stored initial values. - */ -template -int Bus::initializeAdjoint() -{ - // std::cout << "Initialize Bus..." << std::endl; - yB_[0] = 0.0; - yB_[1] = 0.0; - ypB_[0] = 0.0; - ypB_[1] = 0.0; - - return 0; -} - -/** - * @brief Bus only initializes adjoint residual elements to zero. - * - * @tparam ScalarT - data type for the integrand - * @tparam IdxT - data type for matrix/vector indices - * @return int - error code - */ -template -int Bus::evaluateAdjointResidual() -{ - fB_[0] = 0.0; - fB_[1] = 0.0; - - return 0; -} - -/** - * @brief Quadrature evaluation not implemented - * - * @tparam ScalarT - data type for the integrand - * @tparam IdxT - data type for matrix/vector indices - * @return int - error code - */ -template -int Bus::evaluateIntegrand() -{ - return 0; -} - -/** - * @brief Adjoint quadrature evaluation not implemented - * - * @tparam ScalarT - data type for the integrand - * @tparam IdxT - data type for matrix/vector indices - * @return int - error code - */ -template -int Bus::evaluateAdjointIntegrand() -{ - return 0; -} - -// Available template instantiations -template class Bus; -template class Bus; - -} // namespace PhasorDynamic + namespace PhasorDynamics + { + + /*! + * @brief Constructor for a phasor dynamics bus. + * + * The model is using current balance in Cartesian coordinates. + * + * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: + * - Number of equations = 2 (size_) + * - Number of variables = 2 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ + template + Bus::Bus() + : Vr0_(0.0), Vi0_(0.0) + { + // std::cout << "Create Bus..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; + + size_ = 2; + } + + /*! + * @brief Bus constructor. + * + * This constructor sets initial values for active and reactive voltage. + * + * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: + * - Number of equations = 2 (size_) + * - Number of variables = 2 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ + template + Bus::Bus(ScalarT Vr, ScalarT Vi) + : Vr0_(Vr), Vi0_(Vi) + { + // std::cout << "Create Bus..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; + + size_ = 2; + } + + /** + * @brief Construct a new Bus + * + * @tparam ScalarT - type of scalar variables + * @tparam IdxT - type for vector/matrix indices + * @param[in] data - structure with bus data + */ + template + Bus::Bus(BusData& data) + : BusBase(data.bus_i), + Vr0_(data.Vm * cos(data.Va)), + Vi0_(data.Vm * sin(data.Va)) + { + // std::cout << "Create Bus..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; + + size_ = 2; + } + + template + Bus::~Bus() + { + // std::cout << "Destroy PQ bus ..." << std::endl; + } + + /*! + * @brief allocate method resizes local solution and residual vectors. + */ + template + int Bus::allocate() + { + // std::cout << "Allocate PQ bus ..." << std::endl; + f_.resize(size_); + y_.resize(size_); + yp_.resize(size_); + tag_.resize(size_); + + fB_.resize(size_); + yB_.resize(size_); + ypB_.resize(size_); + + return 0; + } + + /*! + * @brief Bus variables are algebraic. + */ + template + int Bus::tagDifferentiable() + { + tag_[0] = false; + tag_[1] = false; + return 0; + } + + /*! + * @brief initialize method sets bus variables to stored initial values. + */ + template + int Bus::initialize() + { + // std::cout << "Initialize Bus..." << std::endl; + y_[0] = Vr0_; + y_[1] = Vi0_; + yp_[0] = 0.0; + yp_[1] = 0.0; + + return 0; + } + + /*! + * @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. + * + */ + template + int Bus::evaluateResidual() + { + // std::cout << "Evaluating residual of a PQ bus ...\n"; + f_[0] = 0.0; + f_[1] = 0.0; + return 0; + } + + /** + * @brief Jacobian evaluation not implemented + * + * @tparam ScalarT - data type for Jacobian elements + * @tparam IdxT - data type for matrix indices + * @return int - error code + */ + template + int Bus::evaluateJacobian() + { + return 0; + } + + /*! + * @brief initialize method sets bus variables to stored initial values. + */ + template + int Bus::initializeAdjoint() + { + // std::cout << "Initialize Bus..." << std::endl; + yB_[0] = 0.0; + yB_[1] = 0.0; + ypB_[0] = 0.0; + ypB_[1] = 0.0; + + return 0; + } + + /** + * @brief Bus only initializes adjoint residual elements to zero. + * + * @tparam ScalarT - data type for the integrand + * @tparam IdxT - data type for matrix/vector indices + * @return int - error code + */ + template + int Bus::evaluateAdjointResidual() + { + fB_[0] = 0.0; + fB_[1] = 0.0; + + return 0; + } + + /** + * @brief Quadrature evaluation not implemented + * + * @tparam ScalarT - data type for the integrand + * @tparam IdxT - data type for matrix/vector indices + * @return int - error code + */ + template + int Bus::evaluateIntegrand() + { + return 0; + } + + /** + * @brief Adjoint quadrature evaluation not implemented + * + * @tparam ScalarT - data type for the integrand + * @tparam IdxT - data type for matrix/vector indices + * @return int - error code + */ + template + int Bus::evaluateAdjointIntegrand() + { + return 0; + } + + // Available template instantiations + template class Bus; + template class Bus; + + } // namespace PhasorDynamics } // namespace GridKit - diff --git a/src/Model/PhasorDynamics/Bus/Bus.hpp b/src/Model/PhasorDynamics/Bus/Bus.hpp index 1f34a492..aedaa2a8 100644 --- a/src/Model/PhasorDynamics/Bus/Bus.hpp +++ b/src/Model/PhasorDynamics/Bus/Bus.hpp @@ -3,21 +3,20 @@ #include - // Forward declaration of BusData structure namespace GridKit { -namespace PowerSystemData -{ + namespace PowerSystemData + { template struct BusData; -} -} + } +} // namespace GridKit namespace GridKit { -namespace PhasorDynamics -{ + namespace PhasorDynamics + { /*! * @brief Implementation of a PQ bus. * @@ -26,128 +25,126 @@ namespace PhasorDynamics * * */ - template + template class Bus : public BusBase { - using BusBase::size_; - using BusBase::y_; - using BusBase::yp_; - using BusBase::yB_; - using BusBase::ypB_; - using BusBase::f_; - using BusBase::fB_; - using BusBase::tag_; + using BusBase::size_; + using BusBase::y_; + using BusBase::yp_; + using BusBase::yB_; + using BusBase::ypB_; + using BusBase::f_; + using BusBase::fB_; + using BusBase::tag_; public: - using real_type = typename BusBase::real_type; - using BusData = GridKit::PowerSystemData::BusData; - - Bus(); - Bus(ScalarT Vr, ScalarT Vi); - Bus(BusData& data); - virtual ~Bus(); - - virtual int allocate() override; - virtual int tagDifferentiable() override; - virtual int initialize() override; - virtual int evaluateResidual() override; - virtual int evaluateIntegrand() override; - virtual int evaluateJacobian() override; - virtual int initializeAdjoint() override; - virtual int evaluateAdjointIntegrand() override; - virtual int evaluateAdjointResidual() override; - - - virtual int BusType() const override - { - return BusBase::BusType::DEFAULT; - } - - virtual ScalarT& Vr() override - { - return y_[0]; - } - - virtual const ScalarT& Vr() const override - { - return y_[0]; - } - - virtual ScalarT& Vi() override - { - return y_[1]; - } - - virtual const ScalarT& Vi() const override - { - return y_[1]; - } - - virtual ScalarT& Ir() override - { - return f_[0]; - } - - virtual const ScalarT& Ir() const override - { - return f_[0]; - } - - virtual ScalarT& Ii() override - { - return f_[1]; - } - - virtual const ScalarT& Ii() const override - { - return f_[1]; - } - - // virtual ScalarT& VrB() override - // { - // return yB_[0]; - // } - - // virtual const ScalarT& VrB() const override - // { - // return yB_[0]; - // } - - // virtual ScalarT& ViB() override - // { - // return yB_[1]; - // } - - // virtual const ScalarT& ViB() const override - // { - // return yB_[1]; - // } - - // virtual ScalarT& IrB() override - // { - // return fB_[0]; - // } - - // virtual const ScalarT& IrB() const override - // { - // return fB_[0]; - // } - - // virtual ScalarT& IiB() override - // { - // return fB_[1]; - // } - - // virtual const ScalarT& IiB() const override - // { - // return fB_[1]; - // } + using real_type = typename BusBase::real_type; + using BusData = GridKit::PowerSystemData::BusData; + + Bus(); + Bus(ScalarT Vr, ScalarT Vi); + Bus(BusData& data); + virtual ~Bus(); + + virtual int allocate() override; + virtual int tagDifferentiable() override; + virtual int initialize() override; + virtual int evaluateResidual() override; + virtual int evaluateIntegrand() override; + virtual int evaluateJacobian() override; + virtual int initializeAdjoint() override; + virtual int evaluateAdjointIntegrand() override; + virtual int evaluateAdjointResidual() override; + + virtual int BusType() const override + { + return BusBase::BusType::DEFAULT; + } + + virtual ScalarT& Vr() override + { + return y_[0]; + } + + virtual const ScalarT& Vr() const override + { + return y_[0]; + } + + virtual ScalarT& Vi() override + { + return y_[1]; + } + + virtual const ScalarT& Vi() const override + { + return y_[1]; + } + + virtual ScalarT& Ir() override + { + return f_[0]; + } + + virtual const ScalarT& Ir() const override + { + return f_[0]; + } + + virtual ScalarT& Ii() override + { + return f_[1]; + } + + virtual const ScalarT& Ii() const override + { + return f_[1]; + } + + // virtual ScalarT& VrB() override + // { + // return yB_[0]; + // } + + // virtual const ScalarT& VrB() const override + // { + // return yB_[0]; + // } + + // virtual ScalarT& ViB() override + // { + // return yB_[1]; + // } + + // virtual const ScalarT& ViB() const override + // { + // return yB_[1]; + // } + + // virtual ScalarT& IrB() override + // { + // return fB_[0]; + // } + + // virtual const ScalarT& IrB() const override + // { + // return fB_[0]; + // } + + // virtual ScalarT& IiB() override + // { + // return fB_[1]; + // } + + // virtual const ScalarT& IiB() const override + // { + // return fB_[1]; + // } private: - ScalarT Vr0_{0.0}; - ScalarT Vi0_{0.0}; - + ScalarT Vr0_{0.0}; + ScalarT Vi0_{0.0}; }; -} // PhasorDynamics + } // namespace PhasorDynamics } // namespace GridKit diff --git a/src/Model/PhasorDynamics/Bus/BusInfinite.cpp b/src/Model/PhasorDynamics/Bus/BusInfinite.cpp index ee8e6b2d..6206813d 100644 --- a/src/Model/PhasorDynamics/Bus/BusInfinite.cpp +++ b/src/Model/PhasorDynamics/Bus/BusInfinite.cpp @@ -1,203 +1,200 @@ -#include +#include "BusInfinite.hpp" + #include +#include #include -#include "BusInfinite.hpp" namespace GridKit { -namespace PhasorDynamics -{ - -/*! - * @brief Constructor for an infinite (slack) bus. - * - * The model is using current balance in Cartesian coordinates. - * - * Arguments to be passed to BusBase: - * - Number of equations = 0 (size_) - * - Number of variables = 0 (size_) - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ -template -BusInfinite::BusInfinite() -{ - //std::cout << "Create BusInfinite..." << std::endl; - //std::cout << "Number of equations is " << size_ << std::endl; - - size_ = 0; -} - -/*! - * @brief BusInfinite constructor. - * - * This constructor sets initial values for active and reactive voltage. - * - * Arguments to be passed to BusBase: - * - Number of equations = 0 (size_) - * - Number of variables = 0 (size_) - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ -template -BusInfinite::BusInfinite(ScalarT Vr, ScalarT Vi) - : Vr_(Vr), Vi_(Vi) -{ - //std::cout << "Create BusInfinite..." << std::endl; - //std::cout << "Number of equations is " << size_ << std::endl; - - size_ = 0; -} - -/** - * @brief Construct a new BusInfinite - * - * Arguments to be set in BusBase: - * - Number of equations = 0 (size_) - * - Number of variables = 0 (size_) - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - - * @tparam ScalarT - type of scalar variables - * @tparam IdxT - type for vector/matrix indices - * @param[in] data - structure with bus data - */ -template -BusInfinite::BusInfinite(BusData& data) - : BusBase(data.bus_i), - Vr_(data.Vm * cos(data.Va)), - Vi_(data.Vm * sin(data.Va)) -{ - size_ = 0; -} - -template -BusInfinite::~BusInfinite() -{ - //std::cout << "Destroy PQ bus ..." << std::endl; -} - -/*! - * @brief allocate method resizes local solution and residual vectors. - */ -template -int BusInfinite::allocate() -{ - //std::cout << "Nothing to allocate for infinite bus ..." << std::endl; - - return 0; -} - - -template -int BusInfinite::tagDifferentiable() -{ - return 0; -} - - -/*! - * @brief initialize method sets bus variables to stored initial values. - */ -template -int BusInfinite::initialize() -{ - // std::cout << "Initialize BusInfinite..." << std::endl; - - return 0; -} - -/*! - * @brief Reset slack currents to zero. - * - * Infinite bus does not compute residuals, so here we just reset - * current values to zero. Components connected to the infinite bus - * will add their currents to Ir_ and Ii_. The resultant will be slack - * current that the infinite bus has to pick up. - * - * @warning This implementation assumes bus residuals are always evaluated - * _before_ component model residuals. - * - */ -template -int BusInfinite::evaluateResidual() -{ - // std::cout << "Evaluating residual of a PQ bus ...\n"; - Ir_ = 0.0; - Ii_ = 0.0; - return 0; -} - -/** - * @brief Jacobian evaluation not implemented - * - * @tparam ScalarT - data type for Jacobian elements - * @tparam IdxT - data type for matrix indices - * @return int - error code - */ -template -int BusInfinite::evaluateJacobian() -{ - return 0; -} - -/*! - * @brief initialize method sets bus variables to stored initial values. - */ -template -int BusInfinite::initializeAdjoint() -{ - // std::cout << "Initialize BusInfinite..." << std::endl; - - return 0; -} - -/** - * @brief BusInfinite only initializes adjoint residual elements to zero. - * - * @tparam ScalarT - data type for the integrand - * @tparam IdxT - data type for matrix/vector indices - * @return int - error code - */ -template -int BusInfinite::evaluateAdjointResidual() -{ - return 0; -} - -/** - * @brief Quadrature evaluation not implemented - * - * @tparam ScalarT - data type for the integrand - * @tparam IdxT - data type for matrix/vector indices - * @return int - error code - */ -template -int BusInfinite::evaluateIntegrand() -{ - return 0; -} - -/** - * @brief Adjoint quadrature evaluation not implemented - * - * @tparam ScalarT - data type for the integrand - * @tparam IdxT - data type for matrix/vector indices - * @return int - error code - */ -template -int BusInfinite::evaluateAdjointIntegrand() -{ - return 0; -} - - -// Available template instantiations -template class BusInfinite; -template class BusInfinite; - -} // namespace PhasorDynamic + namespace PhasorDynamics + { + + /*! + * @brief Constructor for an infinite (slack) bus. + * + * The model is using current balance in Cartesian coordinates. + * + * Arguments to be passed to BusBase: + * - Number of equations = 0 (size_) + * - Number of variables = 0 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ + template + BusInfinite::BusInfinite() + { + // std::cout << "Create BusInfinite..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; + + size_ = 0; + } + + /*! + * @brief BusInfinite constructor. + * + * This constructor sets initial values for active and reactive voltage. + * + * Arguments to be passed to BusBase: + * - Number of equations = 0 (size_) + * - Number of variables = 0 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ + template + BusInfinite::BusInfinite(ScalarT Vr, ScalarT Vi) + : Vr_(Vr), Vi_(Vi) + { + // std::cout << "Create BusInfinite..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; + + size_ = 0; + } + + /** + * @brief Construct a new BusInfinite + * + * Arguments to be set in BusBase: + * - Number of equations = 0 (size_) + * - Number of variables = 0 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + + * @tparam ScalarT - type of scalar variables + * @tparam IdxT - type for vector/matrix indices + * @param[in] data - structure with bus data + */ + template + BusInfinite::BusInfinite(BusData& data) + : BusBase(data.bus_i), + Vr_(data.Vm * cos(data.Va)), + Vi_(data.Vm * sin(data.Va)) + { + size_ = 0; + } + + template + BusInfinite::~BusInfinite() + { + // std::cout << "Destroy PQ bus ..." << std::endl; + } + + /*! + * @brief allocate method resizes local solution and residual vectors. + */ + template + int BusInfinite::allocate() + { + // std::cout << "Nothing to allocate for infinite bus ..." << std::endl; + + return 0; + } + + template + int BusInfinite::tagDifferentiable() + { + return 0; + } + + /*! + * @brief initialize method sets bus variables to stored initial values. + */ + template + int BusInfinite::initialize() + { + // std::cout << "Initialize BusInfinite..." << std::endl; + + return 0; + } + + /*! + * @brief Reset slack currents to zero. + * + * Infinite bus does not compute residuals, so here we just reset + * current values to zero. Components connected to the infinite bus + * will add their currents to Ir_ and Ii_. The resultant will be slack + * current that the infinite bus has to pick up. + * + * @warning This implementation assumes bus residuals are always evaluated + * _before_ component model residuals. + * + */ + template + int BusInfinite::evaluateResidual() + { + // std::cout << "Evaluating residual of a PQ bus ...\n"; + Ir_ = 0.0; + Ii_ = 0.0; + return 0; + } + + /** + * @brief Jacobian evaluation not implemented + * + * @tparam ScalarT - data type for Jacobian elements + * @tparam IdxT - data type for matrix indices + * @return int - error code + */ + template + int BusInfinite::evaluateJacobian() + { + return 0; + } + + /*! + * @brief initialize method sets bus variables to stored initial values. + */ + template + int BusInfinite::initializeAdjoint() + { + // std::cout << "Initialize BusInfinite..." << std::endl; + + return 0; + } + + /** + * @brief BusInfinite only initializes adjoint residual elements to zero. + * + * @tparam ScalarT - data type for the integrand + * @tparam IdxT - data type for matrix/vector indices + * @return int - error code + */ + template + int BusInfinite::evaluateAdjointResidual() + { + return 0; + } + + /** + * @brief Quadrature evaluation not implemented + * + * @tparam ScalarT - data type for the integrand + * @tparam IdxT - data type for matrix/vector indices + * @return int - error code + */ + template + int BusInfinite::evaluateIntegrand() + { + return 0; + } + + /** + * @brief Adjoint quadrature evaluation not implemented + * + * @tparam ScalarT - data type for the integrand + * @tparam IdxT - data type for matrix/vector indices + * @return int - error code + */ + template + int BusInfinite::evaluateAdjointIntegrand() + { + return 0; + } + + // Available template instantiations + template class BusInfinite; + template class BusInfinite; + + } // namespace PhasorDynamics } // namespace GridKit - diff --git a/src/Model/PhasorDynamics/Bus/BusInfinite.hpp b/src/Model/PhasorDynamics/Bus/BusInfinite.hpp index 56aa6064..6acdd7c6 100644 --- a/src/Model/PhasorDynamics/Bus/BusInfinite.hpp +++ b/src/Model/PhasorDynamics/Bus/BusInfinite.hpp @@ -3,154 +3,153 @@ #include - // Forward declaration of BusData structure namespace GridKit { -namespace PowerSystemData -{ + namespace PowerSystemData + { template struct BusData; -} -} + } +} // namespace GridKit namespace GridKit { -namespace PhasorDynamics -{ + namespace PhasorDynamics + { /*! * @brief Implementation of an "infinite" bus. * * * */ - template + template class BusInfinite : public BusBase { - using BusBase::size_; - using BusBase::y_; - using BusBase::yp_; - using BusBase::yB_; - using BusBase::ypB_; - using BusBase::f_; - using BusBase::fB_; - using BusBase::tag_; + using BusBase::size_; + using BusBase::y_; + using BusBase::yp_; + using BusBase::yB_; + using BusBase::ypB_; + using BusBase::f_; + using BusBase::fB_; + using BusBase::tag_; public: - using real_type = typename BusBase::real_type; - using BusData = GridKit::PowerSystemData::BusData; - - BusInfinite(); - BusInfinite(ScalarT Vr, ScalarT Vi); - BusInfinite(BusData& data); - virtual ~BusInfinite(); - - virtual int allocate() override; - virtual int tagDifferentiable() override; - virtual int initialize() override; - virtual int evaluateResidual() override; - virtual int evaluateIntegrand() override; - virtual int evaluateJacobian() override; - virtual int initializeAdjoint() override; - virtual int evaluateAdjointIntegrand() override; - virtual int evaluateAdjointResidual() override; - - virtual int BusType() const override - { - return BusBase::BusType::SLACK; - } - - virtual ScalarT& Vr() override - { - return Vr_; - } - - virtual const ScalarT& Vr() const override - { - return Vr_; - } - - virtual ScalarT& Vi() override - { - return Vi_; - } - - virtual const ScalarT& Vi() const override - { - return Vi_; - } - - virtual ScalarT& Ir() override - { - return Ir_; - } - - virtual const ScalarT& Ir() const override - { - return Ir_; - } - - virtual ScalarT& Ii() override - { - return Ii_; - } - - virtual const ScalarT& Ii() const override - { - return Ii_; - } - - // virtual ScalarT& VrB() override - // { - // return VrB_; - // } - - // virtual const ScalarT& VrB() const override - // { - // return VrB_; - // } - - // virtual ScalarT& ViB() override - // { - // return ViB_; - // } - - // virtual const ScalarT& ViB() const override - // { - // return ViB_; - // } - - // virtual ScalarT& IrB() override - // { - // return IrB_; - // } - - // virtual const ScalarT& IrB() const override - // { - // return IrB_; - // } - - // virtual ScalarT& IiB() override - // { - // return IiB_; - // } - - // virtual const ScalarT& IiB() const override - // { - // return IiB_; - // } + using real_type = typename BusBase::real_type; + using BusData = GridKit::PowerSystemData::BusData; + + BusInfinite(); + BusInfinite(ScalarT Vr, ScalarT Vi); + BusInfinite(BusData& data); + virtual ~BusInfinite(); + + virtual int allocate() override; + virtual int tagDifferentiable() override; + virtual int initialize() override; + virtual int evaluateResidual() override; + virtual int evaluateIntegrand() override; + virtual int evaluateJacobian() override; + virtual int initializeAdjoint() override; + virtual int evaluateAdjointIntegrand() override; + virtual int evaluateAdjointResidual() override; + + virtual int BusType() const override + { + return BusBase::BusType::SLACK; + } + + virtual ScalarT& Vr() override + { + return Vr_; + } + + virtual const ScalarT& Vr() const override + { + return Vr_; + } + + virtual ScalarT& Vi() override + { + return Vi_; + } + + virtual const ScalarT& Vi() const override + { + return Vi_; + } + + virtual ScalarT& Ir() override + { + return Ir_; + } + + virtual const ScalarT& Ir() const override + { + return Ir_; + } + + virtual ScalarT& Ii() override + { + return Ii_; + } + + virtual const ScalarT& Ii() const override + { + return Ii_; + } + + // virtual ScalarT& VrB() override + // { + // return VrB_; + // } + + // virtual const ScalarT& VrB() const override + // { + // return VrB_; + // } + + // virtual ScalarT& ViB() override + // { + // return ViB_; + // } + + // virtual const ScalarT& ViB() const override + // { + // return ViB_; + // } + + // virtual ScalarT& IrB() override + // { + // return IrB_; + // } + + // virtual const ScalarT& IrB() const override + // { + // return IrB_; + // } + + // virtual ScalarT& IiB() override + // { + // return IiB_; + // } + + // virtual const ScalarT& IiB() const override + // { + // return IiB_; + // } private: - ScalarT Vr_{0.0}; - ScalarT Vi_{0.0}; - ScalarT Ir_{0.0}; - ScalarT Ii_{0.0}; - - ScalarT VrB_{0.0}; - ScalarT ViB_{0.0}; - ScalarT IrB_{0.0}; - ScalarT IiB_{0.0}; + ScalarT Vr_{0.0}; + ScalarT Vi_{0.0}; + ScalarT Ir_{0.0}; + ScalarT Ii_{0.0}; + + ScalarT VrB_{0.0}; + ScalarT ViB_{0.0}; + ScalarT IrB_{0.0}; + ScalarT IiB_{0.0}; }; -} // PhasorDynamics + } // namespace PhasorDynamics } // namespace GridKit diff --git a/src/Model/PhasorDynamics/BusBase.hpp b/src/Model/PhasorDynamics/BusBase.hpp index 30f1b687..9f18d067 100644 --- a/src/Model/PhasorDynamics/BusBase.hpp +++ b/src/Model/PhasorDynamics/BusBase.hpp @@ -1,12 +1,13 @@ #pragma once #include + #include namespace GridKit { -namespace PhasorDynamics -{ + namespace PhasorDynamics + { /*! * @brief BusBase model implementation base class. * @@ -15,267 +16,270 @@ namespace PhasorDynamics class BusBase : public Model::Evaluator { public: - using real_type = typename Model::Evaluator::real_type; - - enum BusType{DEFAULT=1, SLACK}; - - BusBase() - : size_(0), - size_quad_(0), - size_param_(0) - { - } - - BusBase(IdxT bus_id) : bus_id_(bus_id) - { - } - - BusBase(IdxT size, IdxT size_quad, IdxT size_param) - : size_(size), - size_quad_(size_quad), - size_param_(size_param), - y_(size_), - yp_(size_), - f_(size_), - g_(size_quad_), - yB_(size_), - ypB_(size_), - fB_(size_), - gB_(size_param_), - J_(COO_Matrix()), - param_(size_param_), - param_up_(size_param_), - param_lo_(size_param_) - { - } - - virtual ~BusBase() - { - } - - /// Pure virtual function, returns bus type (DEFAULT or SLACK). - virtual int BusType() const = 0; - - virtual IdxT size() override - { - return size_; - } - - virtual IdxT nnz() - { - return nnz_; - } - - virtual bool hasJacobian() - { - return false; - } - - virtual IdxT sizeQuadrature() override - { - return size_quad_; - } - - virtual IdxT sizeParams() override - { - return size_param_; - } - - virtual void updateTime(real_type /* t */, real_type /* a */) - { - // No time to update in bus models - } - - virtual void setTolerances(real_type& rtol, real_type& atol) const - { - rtol = rtol_; - atol = atol_; - } - - virtual void setMaxSteps(IdxT& msa) const - { - msa = max_steps_; - } - - virtual ScalarT& Vr() = 0; - virtual const ScalarT& Vr() const = 0; - virtual ScalarT& Vi() = 0; - virtual const ScalarT& Vi() const = 0; - virtual ScalarT& Ir() = 0; - virtual const ScalarT& Ir() const = 0; - virtual ScalarT& Ii() = 0; - virtual const ScalarT& Ii() const = 0; - - - std::vector& y() override - { - return y_; - } - - const std::vector& y() const override - { - return y_; - } - - std::vector& yp() override - { - return yp_; - } - - const std::vector& yp() const override - { - return yp_; - } - - std::vector& tag() override - { - return tag_; - } - - const std::vector& tag() const override - { - return tag_; - } - - std::vector& yB() override - { - return yB_; - } - - const std::vector& yB() const override - { - return yB_; - } - - std::vector& ypB() override - { - return ypB_; - } - - const std::vector& ypB() const override - { - return ypB_; - } - - std::vector& param() override - { - return param_; - } - - const std::vector& param() const override - { - return param_; - } - - std::vector& param_up() override - { - return param_up_; - } - - const std::vector& param_up() const override - { - return param_up_; - } - - std::vector& param_lo() override - { - return param_lo_; - } - - const std::vector& param_lo() const override - { - return param_lo_; - } - - std::vector& getResidual() override - { - return f_; - } - - const std::vector& getResidual() const override - { - return f_; - } - - COO_Matrix& getJacobian() - { - return J_; - } - - const COO_Matrix& getJacobian() const - { - return J_; - } - - std::vector& getIntegrand() override - { - return g_; - } - - const std::vector& getIntegrand() const override - { - return g_; - } - - std::vector& getAdjointResidual() override - { - return fB_; - } - - const std::vector& getAdjointResidual() const override - { - return fB_; - } - - std::vector& getAdjointIntegrand() override - { - return gB_; - } - - const std::vector& getAdjointIntegrand() const override - { - return gB_; - } - - virtual const IdxT busID() const - { - return bus_id_; - } - + using real_type = typename Model::Evaluator::real_type; + + enum BusType + { + DEFAULT = 1, + SLACK + }; + + BusBase() + : size_(0), + size_quad_(0), + size_param_(0) + { + } + + BusBase(IdxT bus_id) + : bus_id_(bus_id) + { + } + + BusBase(IdxT size, IdxT size_quad, IdxT size_param) + : size_(size), + size_quad_(size_quad), + size_param_(size_param), + y_(size_), + yp_(size_), + f_(size_), + g_(size_quad_), + yB_(size_), + ypB_(size_), + fB_(size_), + gB_(size_param_), + J_(COO_Matrix()), + param_(size_param_), + param_up_(size_param_), + param_lo_(size_param_) + { + } + + virtual ~BusBase() + { + } + + /// Pure virtual function, returns bus type (DEFAULT or SLACK). + virtual int BusType() const = 0; + + virtual IdxT size() override + { + return size_; + } + + virtual IdxT nnz() + { + return nnz_; + } + + virtual bool hasJacobian() + { + return false; + } + + virtual IdxT sizeQuadrature() override + { + return size_quad_; + } + + virtual IdxT sizeParams() override + { + return size_param_; + } + + virtual void updateTime(real_type /* t */, real_type /* a */) + { + // No time to update in bus models + } + + virtual void setTolerances(real_type& rtol, real_type& atol) const + { + rtol = rtol_; + atol = atol_; + } + + virtual void setMaxSteps(IdxT& msa) const + { + msa = max_steps_; + } + + virtual ScalarT& Vr() = 0; + virtual const ScalarT& Vr() const = 0; + virtual ScalarT& Vi() = 0; + virtual const ScalarT& Vi() const = 0; + virtual ScalarT& Ir() = 0; + virtual const ScalarT& Ir() const = 0; + virtual ScalarT& Ii() = 0; + virtual const ScalarT& Ii() const = 0; + + std::vector& y() override + { + return y_; + } + + const std::vector& y() const override + { + return y_; + } + + std::vector& yp() override + { + return yp_; + } + + const std::vector& yp() const override + { + return yp_; + } + + std::vector& tag() override + { + return tag_; + } + + const std::vector& tag() const override + { + return tag_; + } + + std::vector& yB() override + { + return yB_; + } + + const std::vector& yB() const override + { + return yB_; + } + + std::vector& ypB() override + { + return ypB_; + } + + const std::vector& ypB() const override + { + return ypB_; + } + + std::vector& param() override + { + return param_; + } + + const std::vector& param() const override + { + return param_; + } + + std::vector& param_up() override + { + return param_up_; + } + + const std::vector& param_up() const override + { + return param_up_; + } + + std::vector& param_lo() override + { + return param_lo_; + } + + const std::vector& param_lo() const override + { + return param_lo_; + } + + std::vector& getResidual() override + { + return f_; + } + + const std::vector& getResidual() const override + { + return f_; + } + + COO_Matrix& getJacobian() + { + return J_; + } + + const COO_Matrix& getJacobian() const + { + return J_; + } + + std::vector& getIntegrand() override + { + return g_; + } + + const std::vector& getIntegrand() const override + { + return g_; + } + + std::vector& getAdjointResidual() override + { + return fB_; + } + + const std::vector& getAdjointResidual() const override + { + return fB_; + } + + std::vector& getAdjointIntegrand() override + { + return gB_; + } + + const std::vector& getAdjointIntegrand() const override + { + return gB_; + } + + virtual const IdxT busID() const + { + return bus_id_; + } protected: - const IdxT bus_id_{static_cast(-1)}; + const IdxT bus_id_{static_cast(-1)}; - IdxT size_{0}; - IdxT nnz_{0}; - IdxT size_quad_{0}; - IdxT size_param_{0}; + IdxT size_{0}; + IdxT nnz_{0}; + IdxT size_quad_{0}; + IdxT size_param_{0}; - std::vector y_; - std::vector yp_; - std::vector tag_; - std::vector f_; - std::vector g_; + std::vector y_; + std::vector yp_; + std::vector tag_; + std::vector f_; + std::vector g_; - std::vector yB_; - std::vector ypB_; - std::vector fB_; - std::vector gB_; + std::vector yB_; + std::vector ypB_; + std::vector fB_; + std::vector gB_; - COO_Matrix J_; + COO_Matrix J_; - std::vector param_; - std::vector param_up_; - std::vector param_lo_; + std::vector param_; + std::vector param_up_; + std::vector param_lo_; - real_type time_; - real_type alpha_; + real_type time_; + real_type alpha_; - real_type rtol_; - real_type atol_; + real_type rtol_; + real_type atol_; - IdxT max_steps_; + IdxT max_steps_; }; -} // namespace BusBase + } // namespace PhasorDynamics } // namespace GridKit diff --git a/src/Model/PhasorDynamics/Component.hpp b/src/Model/PhasorDynamics/Component.hpp index 25e328ef..63d65a44 100644 --- a/src/Model/PhasorDynamics/Component.hpp +++ b/src/Model/PhasorDynamics/Component.hpp @@ -1,12 +1,13 @@ #pragma once #include + #include namespace GridKit { -namespace PhasorDynamics -{ + namespace PhasorDynamics + { /*! * @brief Component model implementation base class. @@ -16,247 +17,246 @@ namespace PhasorDynamics class Component : public Model::Evaluator { public: - using real_type = typename Model::Evaluator::real_type; - - Component() - : size_(0), - size_quad_(0), - size_param_(0) - {} - - Component(IdxT size, IdxT size_quad, IdxT size_param) - : size_(size), - size_quad_(size_quad), - size_param_(size_param), - y_(size_), - yp_(size_), - f_(size_), - g_(size_quad_), - yB_(size_), - ypB_(size_), - fB_(size_), - gB_(size_param_), - J_(COO_Matrix()), - param_(size_param_), - param_up_(size_param_), - param_lo_(size_param_) - { - } - - virtual IdxT size() override - { - return size_; - } - - virtual IdxT nnz() - { - return nnz_; - } - - virtual bool hasJacobian() - { - return false; - } - - virtual IdxT sizeQuadrature() override - { - return size_quad_; - } - - virtual IdxT sizeParams() override - { - return size_param_; - } - - // virtual void updateTime(real_type t, real_type a) - // { - // time_ = t; - // alpha_ = a; - // std::cout << "updateTime: t = " << time_ << "\n"; - // } - - virtual void setTolerances(real_type& rtol, real_type& atol) const - { - rtol = rel_tol_; - atol = abs_tol_; - } - - virtual void setMaxSteps(IdxT& msa) const - { - msa = max_steps_; - } - - std::vector& y() override - { - return y_; - } - - const std::vector& y() const override - { - return y_; - } - - std::vector& yp() override - { - return yp_; - } - - const std::vector& yp() const override - { - return yp_; - } - - std::vector& tag() override - { - return tag_; - } - - const std::vector& tag() const override - { - return tag_; - } - - std::vector& yB() override - { - return yB_; - } - - const std::vector& yB() const override - { - return yB_; - } - - std::vector& ypB() override - { - return ypB_; - } - - const std::vector& ypB() const override - { - return ypB_; - } - - std::vector& param() override - { - return param_; - } - - const std::vector& param() const override - { - return param_; - } - - std::vector& param_up() override - { - return param_up_; - } - - const std::vector& param_up() const override - { - return param_up_; - } - - std::vector& param_lo() override - { - return param_lo_; - } - - const std::vector& param_lo() const override - { - return param_lo_; - } - - std::vector& getResidual() override - { - return f_; - } - - const std::vector& getResidual() const override - { - return f_; - } - - COO_Matrix& getJacobian() - { - return J_; - } - - const COO_Matrix& getJacobian() const - { - return J_; - } - - std::vector& getIntegrand() override - { - return g_; - } - - const std::vector& getIntegrand() const override - { - return g_; - } - - std::vector& getAdjointResidual() override - { - return fB_; - } - - const std::vector& getAdjointResidual() const override - { - return fB_; - } - - std::vector& getAdjointIntegrand() override - { - return gB_; - } - - const std::vector& getAdjointIntegrand() const override - { - return gB_; - } - - //@todo Fix ID naming - IdxT getComponentID() const - { - return component_id_; - } - - + using real_type = typename Model::Evaluator::real_type; + + Component() + : size_(0), + size_quad_(0), + size_param_(0) + { + } + + Component(IdxT size, IdxT size_quad, IdxT size_param) + : size_(size), + size_quad_(size_quad), + size_param_(size_param), + y_(size_), + yp_(size_), + f_(size_), + g_(size_quad_), + yB_(size_), + ypB_(size_), + fB_(size_), + gB_(size_param_), + J_(COO_Matrix()), + param_(size_param_), + param_up_(size_param_), + param_lo_(size_param_) + { + } + + virtual IdxT size() override + { + return size_; + } + + virtual IdxT nnz() + { + return nnz_; + } + + virtual bool hasJacobian() + { + return false; + } + + virtual IdxT sizeQuadrature() override + { + return size_quad_; + } + + virtual IdxT sizeParams() override + { + return size_param_; + } + + // virtual void updateTime(real_type t, real_type a) + // { + // time_ = t; + // alpha_ = a; + // std::cout << "updateTime: t = " << time_ << "\n"; + // } + + virtual void setTolerances(real_type& rtol, real_type& atol) const + { + rtol = rel_tol_; + atol = abs_tol_; + } + + virtual void setMaxSteps(IdxT& msa) const + { + msa = max_steps_; + } + + std::vector& y() override + { + return y_; + } + + const std::vector& y() const override + { + return y_; + } + + std::vector& yp() override + { + return yp_; + } + + const std::vector& yp() const override + { + return yp_; + } + + std::vector& tag() override + { + return tag_; + } + + const std::vector& tag() const override + { + return tag_; + } + + std::vector& yB() override + { + return yB_; + } + + const std::vector& yB() const override + { + return yB_; + } + + std::vector& ypB() override + { + return ypB_; + } + + const std::vector& ypB() const override + { + return ypB_; + } + + std::vector& param() override + { + return param_; + } + + const std::vector& param() const override + { + return param_; + } + + std::vector& param_up() override + { + return param_up_; + } + + const std::vector& param_up() const override + { + return param_up_; + } + + std::vector& param_lo() override + { + return param_lo_; + } + + const std::vector& param_lo() const override + { + return param_lo_; + } + + std::vector& getResidual() override + { + return f_; + } + + const std::vector& getResidual() const override + { + return f_; + } + + COO_Matrix& getJacobian() + { + return J_; + } + + const COO_Matrix& getJacobian() const + { + return J_; + } + + std::vector& getIntegrand() override + { + return g_; + } + + const std::vector& getIntegrand() const override + { + return g_; + } + + std::vector& getAdjointResidual() override + { + return fB_; + } + + const std::vector& getAdjointResidual() const override + { + return fB_; + } + + std::vector& getAdjointIntegrand() override + { + return gB_; + } + + const std::vector& getAdjointIntegrand() const override + { + return gB_; + } + + //@todo Fix ID naming + IdxT getComponentID() const + { + return component_id_; + } protected: - IdxT size_; - IdxT nnz_; - IdxT size_quad_; - IdxT size_param_; + IdxT size_; + IdxT nnz_; + IdxT size_quad_; + IdxT size_param_; - std::vector y_; - std::vector yp_; - std::vector tag_; - std::vector f_; - std::vector g_; + std::vector y_; + std::vector yp_; + std::vector tag_; + std::vector f_; + std::vector g_; - std::vector yB_; - std::vector ypB_; - std::vector fB_; - std::vector gB_; + std::vector yB_; + std::vector ypB_; + std::vector fB_; + std::vector gB_; - COO_Matrix J_; + COO_Matrix J_; - std::vector param_; - std::vector param_up_; - std::vector param_lo_; + std::vector param_; + std::vector param_up_; + std::vector param_lo_; - real_type time_; - real_type alpha_; + real_type time_; + real_type alpha_; - real_type rel_tol_; - real_type abs_tol_; + real_type rel_tol_; + real_type abs_tol_; - IdxT max_steps_; + IdxT max_steps_; - IdxT component_id_; + IdxT component_id_; }; -} // namespace PhasorDynamics + } // namespace PhasorDynamics } // namespace GridKit diff --git a/src/Model/PhasorDynamics/Load/Load.cpp b/src/Model/PhasorDynamics/Load/Load.cpp index 5afb76ca..84763e3d 100644 --- a/src/Model/PhasorDynamics/Load/Load.cpp +++ b/src/Model/PhasorDynamics/Load/Load.cpp @@ -1,66 +1,67 @@ -#include +#include "Load.hpp" + #include +#include + #include #include -#include "Load.hpp" - namespace GridKit { -namespace PhasorDynamics -{ + namespace PhasorDynamics + { /*! - * @brief Constructor for a pi-model load - * - * Arguments passed to ModelEvaluatorImpl: - * - Number of equations = 0 - * - Number of independent variables = 0 - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ + * @brief Constructor for a pi-model load + * + * Arguments passed to ModelEvaluatorImpl: + * - Number of equations = 0 + * - Number of independent variables = 0 + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ template - Load::Load(bus_type* bus) : bus_(bus) + Load::Load(bus_type* bus) + : bus_(bus) { - size_ = 0; + size_ = 0; } template Load::Load(bus_type* bus, real_type R, real_type X) - : bus_(bus), - R_(R), - X_(X) - + : bus_(bus), + R_(R), + X_(X) + { } template Load::Load(bus_type* bus, IdxT component_id) - : bus_(bus) - + : bus_(bus) + { - size_ = 0; - component_id_ = component_id; + size_ = 0; + component_id_ = component_id; } - template Load::~Load() { - //std::cout << "Destroy Load..." << std::endl; + // std::cout << "Destroy Load..." << std::endl; } /*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ + * @brief allocate method computes sparsity pattern of the Jacobian. + */ template int Load::allocate() { - //std::cout << "Allocate Load..." << std::endl; - return 0; + // std::cout << "Allocate Load..." << std::endl; + return 0; } /** @@ -70,7 +71,7 @@ namespace PhasorDynamics template int Load::initialize() { - return 0; + return 0; } /** @@ -79,28 +80,28 @@ namespace PhasorDynamics template int Load::tagDifferentiable() { - return 0; + return 0; } /** * \brief Residual contribution of the load is pushed to the bus. - * + * */ template int Load::evaluateResidual() { - real_type b = -X_/(R_*R_ + X_*X_); - real_type g = R_/(R_*R_ + X_*X_); + real_type b = -X_ / (R_ * R_ + X_ * X_); + real_type g = R_ / (R_ * R_ + X_ * X_); - Ir() += -g*Vr() - b*Vi(); - Ii() += b*Vr() - g*Vi(); + Ir() += -g * Vr() - b * Vi(); + Ii() += b * Vr() - g * Vi(); - return 0; + return 0; } /** * @brief Jacobian evaluation not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -108,14 +109,14 @@ namespace PhasorDynamics template int Load::evaluateJacobian() { - std::cout << "Evaluate Jacobian for Load..." << std::endl; - std::cout << "Jacobian evaluation not implemented!" << std::endl; - return 0; + std::cout << "Evaluate Jacobian for Load..." << std::endl; + std::cout << "Jacobian evaluation not implemented!" << std::endl; + return 0; } /** * @brief Integrand (objective) evaluation not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -123,13 +124,13 @@ namespace PhasorDynamics template int Load::evaluateIntegrand() { - // std::cout << "Evaluate Integrand for Load..." << std::endl; - return 0; + // std::cout << "Evaluate Integrand for Load..." << std::endl; + return 0; } /** * @brief Adjoint initialization not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -137,13 +138,13 @@ namespace PhasorDynamics template int Load::initializeAdjoint() { - //std::cout << "Initialize adjoint for Load..." << std::endl; - return 0; + // std::cout << "Initialize adjoint for Load..." << std::endl; + return 0; } /** * @brief Adjoint residual evaluation not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -151,13 +152,13 @@ namespace PhasorDynamics template int Load::evaluateAdjointResidual() { - // std::cout << "Evaluate adjoint residual for Load..." << std::endl; - return 0; + // std::cout << "Evaluate adjoint residual for Load..." << std::endl; + return 0; } /** * @brief Adjoint integrand (objective) evaluation not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -165,13 +166,13 @@ namespace PhasorDynamics template int Load::evaluateAdjointIntegrand() { - // std::cout << "Evaluate adjoint Integrand for Load..." << std::endl; - return 0; + // std::cout << "Evaluate adjoint Integrand for Load..." << std::endl; + return 0; } // Available template instantiations template class Load; template class Load; -} //namespace PhasorDynamics -} //namespace GridKit + } // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/Load/Load.hpp b/src/Model/PhasorDynamics/Load/Load.hpp index 31f1d048..cc183028 100644 --- a/src/Model/PhasorDynamics/Load/Load.hpp +++ b/src/Model/PhasorDynamics/Load/Load.hpp @@ -7,103 +7,103 @@ // Forward declarations. namespace GridKit { -namespace PhasorDynamics -{ - template class Bus; -} -} + namespace PhasorDynamics + { + template + class Bus; + } +} // namespace GridKit namespace GridKit { -namespace PhasorDynamics -{ + namespace PhasorDynamics + { /*! * @brief Implementation of a constant load. * */ - template + template class Load : public Component { - using Component::size_; - using Component::nnz_; - using Component::time_; - using Component::alpha_; - using Component::y_; - using Component::yp_; - using Component::tag_; - using Component::f_; - using Component::g_; - using Component::yB_; - using Component::ypB_; - using Component::fB_; - using Component::gB_; - using Component::param_; - using Component::component_id_; - - using bus_type = BusBase; - using real_type = typename Component::real_type; + using Component::size_; + using Component::nnz_; + using Component::time_; + using Component::alpha_; + using Component::y_; + using Component::yp_; + using Component::tag_; + using Component::f_; + using Component::g_; + using Component::yB_; + using Component::ypB_; + using Component::fB_; + using Component::gB_; + using Component::param_; + using Component::component_id_; + + using bus_type = BusBase; + using real_type = typename Component::real_type; public: - Load(bus_type* bus); - Load(bus_type* bus, real_type R, real_type X); - Load(bus_type* bus, IdxT component_id); - virtual ~Load(); - - virtual int allocate() override; - virtual int initialize() override; - virtual int tagDifferentiable() override; - virtual int evaluateResidual() override; - virtual int evaluateJacobian() override; - virtual int evaluateIntegrand() override; - - virtual int initializeAdjoint() override; - virtual int evaluateAdjointResidual() override; - // virtual int evaluateAdjointJacobian() override; - virtual int evaluateAdjointIntegrand() override; - - virtual void updateTime(real_type /* t */, real_type /* a */) override - { - } + Load(bus_type* bus); + Load(bus_type* bus, real_type R, real_type X); + Load(bus_type* bus, IdxT component_id); + virtual ~Load(); + + virtual int allocate() override; + virtual int initialize() override; + virtual int tagDifferentiable() override; + virtual int evaluateResidual() override; + virtual int evaluateJacobian() override; + virtual int evaluateIntegrand() override; + + virtual int initializeAdjoint() override; + virtual int evaluateAdjointResidual() override; + // virtual int evaluateAdjointJacobian() override; + virtual int evaluateAdjointIntegrand() override; + + virtual void updateTime(real_type /* t */, real_type /* a */) override + { + } public: - void setR(real_type R) - { - R_ = R; - } + void setR(real_type R) + { + R_ = R; + } - void setX(real_type X) - { - // std::cout << "Setting X ...\n"; - X_ = X; - } + void setX(real_type X) + { + // std::cout << "Setting X ...\n"; + X_ = X; + } private: - ScalarT& Vr() - { - return bus_->Vr(); - } - - ScalarT& Vi() - { - return bus_->Vi(); - } - - ScalarT& Ir() - { - return bus_->Ir(); - } - - ScalarT& Ii() - { - return bus_->Ii(); - } - + ScalarT& Vr() + { + return bus_->Vr(); + } + + ScalarT& Vi() + { + return bus_->Vi(); + } + + ScalarT& Ir() + { + return bus_->Ir(); + } + + ScalarT& Ii() + { + return bus_->Ii(); + } private: - bus_type* bus_{nullptr}; - real_type R_{0.1}; - real_type X_{0.01}; + bus_type* bus_{nullptr}; + real_type R_{0.1}; + real_type X_{0.01}; }; -} // namespace PhasorDynamics + } // namespace PhasorDynamics } // namespace GridKit diff --git a/src/Model/PhasorDynamics/SynchronousMachine/SynchronousMachine.cpp b/src/Model/PhasorDynamics/SynchronousMachine/SynchronousMachine.cpp index e30adb28..519223cf 100644 --- a/src/Model/PhasorDynamics/SynchronousMachine/SynchronousMachine.cpp +++ b/src/Model/PhasorDynamics/SynchronousMachine/SynchronousMachine.cpp @@ -2,62 +2,63 @@ * @file SynchronousMachine.hpp * @author Slaven Peles (peless@ornl.gov) * @brief Definition of a phasor dynamics branch model. - * + * * The model uses Cartesian coordinates. - * + * */ -#include +#include "SynchronousMachine.hpp" + #include +#include + #include #include -#include "SynchronousMachine.hpp" - namespace GridKit { -namespace PhasorDynamics -{ + namespace PhasorDynamics + { /*! - * @brief Constructor for a pi-model branch - * - * Arguments passed to ModelEvaluatorImpl: - * - Number of equations = 0 - * - Number of independent variables = 0 - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ + * @brief Constructor for a pi-model branch + * + * Arguments passed to ModelEvaluatorImpl: + * - Number of equations = 0 + * - Number of independent variables = 0 + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ template SynchronousMachine::SynchronousMachine(bus_type* bus) - : bus_(bus), - R_(0.0), - X_(0.01), - G_(0.0), - B_(0.0) + : bus_(bus), + R_(0.0), + X_(0.01), + G_(0.0), + B_(0.0) { - size_ = 0; + size_ = 0; } /** * @brief Destroy the SynchronousMachine - * - * @tparam ScalarT - * @tparam IdxT + * + * @tparam ScalarT + * @tparam IdxT */ template SynchronousMachine::~SynchronousMachine() { - //std::cout << "Destroy SynchronousMachine..." << std::endl; + // std::cout << "Destroy SynchronousMachine..." << std::endl; } /*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ + * @brief allocate method computes sparsity pattern of the Jacobian. + */ template int SynchronousMachine::allocate() { - //std::cout << "Allocate SynchronousMachine..." << std::endl; - return 0; + // std::cout << "Allocate SynchronousMachine..." << std::endl; + return 0; } /** @@ -67,7 +68,7 @@ namespace PhasorDynamics template int SynchronousMachine::initialize() { - return 0; + return 0; } /** @@ -76,27 +77,27 @@ namespace PhasorDynamics template int SynchronousMachine::tagDifferentiable() { - return 0; + return 0; } /** * \brief Residual contribution of the branch is pushed to the * two terminal buses. - * + * */ template int SynchronousMachine::evaluateResidual() { - // std::cout << "Evaluating branch residual ...\n"; - // real_type b = -X_/(R_*R_ + X_*X_); - // real_type g = R_/(R_*R_ + X_*X_); + // std::cout << "Evaluating branch residual ...\n"; + // real_type b = -X_/(R_*R_ + X_*X_); + // real_type g = R_/(R_*R_ + X_*X_); - return 0; + return 0; } /** * @brief Jacobian evaluation not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -104,14 +105,14 @@ namespace PhasorDynamics template int SynchronousMachine::evaluateJacobian() { - std::cout << "Evaluate Jacobian for SynchronousMachine..." << std::endl; - std::cout << "Jacobian evaluation not implemented!" << std::endl; - return 0; + std::cout << "Evaluate Jacobian for SynchronousMachine..." << std::endl; + std::cout << "Jacobian evaluation not implemented!" << std::endl; + return 0; } /** * @brief Integrand (objective) evaluation not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -119,13 +120,13 @@ namespace PhasorDynamics template int SynchronousMachine::evaluateIntegrand() { - // std::cout << "Evaluate Integrand for SynchronousMachine..." << std::endl; - return 0; + // std::cout << "Evaluate Integrand for SynchronousMachine..." << std::endl; + return 0; } /** * @brief Adjoint initialization not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -133,13 +134,13 @@ namespace PhasorDynamics template int SynchronousMachine::initializeAdjoint() { - //std::cout << "Initialize adjoint for SynchronousMachine..." << std::endl; - return 0; + // std::cout << "Initialize adjoint for SynchronousMachine..." << std::endl; + return 0; } /** * @brief Adjoint residual evaluation not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -147,13 +148,13 @@ namespace PhasorDynamics template int SynchronousMachine::evaluateAdjointResidual() { - // std::cout << "Evaluate adjoint residual for SynchronousMachine..." << std::endl; - return 0; + // std::cout << "Evaluate adjoint residual for SynchronousMachine..." << std::endl; + return 0; } /** * @brief Adjoint integrand (objective) evaluation not implemented yet - * + * * @tparam ScalarT - scalar data type * @tparam IdxT - matrix index data type * @return int - error code, 0 = success @@ -161,13 +162,13 @@ namespace PhasorDynamics template int SynchronousMachine::evaluateAdjointIntegrand() { - // std::cout << "Evaluate adjoint Integrand for SynchronousMachine..." << std::endl; - return 0; + // std::cout << "Evaluate adjoint Integrand for SynchronousMachine..." << std::endl; + return 0; } // Available template instantiations template class SynchronousMachine; template class SynchronousMachine; -} //namespace PhasorDynamics -} //namespace GridKit + } // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/SynchronousMachine/SynchronousMachine.hpp b/src/Model/PhasorDynamics/SynchronousMachine/SynchronousMachine.hpp index c3818cc5..2777cf17 100644 --- a/src/Model/PhasorDynamics/SynchronousMachine/SynchronousMachine.hpp +++ b/src/Model/PhasorDynamics/SynchronousMachine/SynchronousMachine.hpp @@ -2,9 +2,9 @@ * @file SynchronousMachine.hpp * @author Slaven Peles (peless@ornl.gov) * @brief Declaration of a phasor dynamics branch model. - * + * * The model uses Cartesian coordinates. - * + * */ #pragma once @@ -13,115 +13,115 @@ // Forward declarations. namespace GridKit { -namespace PhasorDynamics -{ - template class BusBase; -} -} + namespace PhasorDynamics + { + template + class BusBase; + } +} // namespace GridKit namespace GridKit { -namespace PhasorDynamics -{ + namespace PhasorDynamics + { /** * @brief Implementation of a pi-model branch between two buses. - * + * * The model is implemented in Cartesian coordinates. Positive current * direction is into the busses. * */ - template + template class SynchronousMachine : public Component { - using Component::size_; - using Component::nnz_; - using Component::time_; - using Component::alpha_; - using Component::y_; - using Component::yp_; - using Component::tag_; - using Component::f_; - using Component::g_; - using Component::yB_; - using Component::ypB_; - using Component::fB_; - using Component::gB_; - using Component::param_; - - using bus_type = BusBase; - using real_type = typename Component::real_type; + using Component::size_; + using Component::nnz_; + using Component::time_; + using Component::alpha_; + using Component::y_; + using Component::yp_; + using Component::tag_; + using Component::f_; + using Component::g_; + using Component::yB_; + using Component::ypB_; + using Component::fB_; + using Component::gB_; + using Component::param_; + + using bus_type = BusBase; + using real_type = typename Component::real_type; public: - SynchronousMachine(bus_type* bus); - virtual ~SynchronousMachine(); + SynchronousMachine(bus_type* bus); + virtual ~SynchronousMachine(); - virtual int allocate() override; - virtual int initialize() override; - virtual int tagDifferentiable() override; - virtual int evaluateResidual() override; - virtual int evaluateJacobian() override; - virtual int evaluateIntegrand() override; + virtual int allocate() override; + virtual int initialize() override; + virtual int tagDifferentiable() override; + virtual int evaluateResidual() override; + virtual int evaluateJacobian() override; + virtual int evaluateIntegrand() override; - virtual int initializeAdjoint() override; - virtual int evaluateAdjointResidual() override; - // virtual int evaluateAdjointJacobian() override; - virtual int evaluateAdjointIntegrand() override; + virtual int initializeAdjoint() override; + virtual int evaluateAdjointResidual() override; + // virtual int evaluateAdjointJacobian() override; + virtual int evaluateAdjointIntegrand() override; - virtual void updateTime(real_type /* t */, real_type /* a */) override - { - } + virtual void updateTime(real_type /* t */, real_type /* a */) override + { + } public: - void setR(real_type R) - { - R_ = R; - } - - void setX(real_type X) - { - // std::cout << "Setting X ...\n"; - X_ = X; - } - - void setG(real_type G) - { - G_ = G; - } - - void setB(real_type B) - { - B_ = B; - } + void setR(real_type R) + { + R_ = R; + } + + void setX(real_type X) + { + // std::cout << "Setting X ...\n"; + X_ = X; + } + + void setG(real_type G) + { + G_ = G; + } + + void setB(real_type B) + { + B_ = B; + } private: - ScalarT& Vr() - { - return bus_->Vr(); - } - - ScalarT& Vi() - { - return bus_->Vi(); - } - - ScalarT& Ir() - { - return bus_->Ir(); - } - - ScalarT& Ii() - { - return bus_->Ii(); - } - + ScalarT& Vr() + { + return bus_->Vr(); + } + + ScalarT& Vi() + { + return bus_->Vi(); + } + + ScalarT& Ir() + { + return bus_->Ir(); + } + + ScalarT& Ii() + { + return bus_->Ii(); + } private: - bus_type* bus_; - real_type R_; - real_type X_; - real_type G_; - real_type B_; + bus_type* bus_; + real_type R_; + real_type X_; + real_type G_; + real_type B_; }; -} // namespace PhasorDynamics + } // namespace PhasorDynamics } // namespace GridKit diff --git a/src/Model/PhasorDynamics/SystemModel.hpp b/src/Model/PhasorDynamics/SystemModel.hpp index b6a4f3af..03347b22 100644 --- a/src/Model/PhasorDynamics/SystemModel.hpp +++ b/src/Model/PhasorDynamics/SystemModel.hpp @@ -1,109 +1,109 @@ #pragma once +#include #include #include -#include -#include #include #include +#include namespace GridKit { -namespace PhasorDynamics -{ - -/** - * @brief Prototype for a system model class - * - * This class maps component data to system data and implements - * Model::Evaluator for the system model. This is still work in - * progress and code is not optimized. - * - * @todo Address thread safety for the system model methods. - * - */ -template -class SystemModel : public PhasorDynamics::Component -{ - using bus_type = PhasorDynamics::BusBase; - using component_type = PhasorDynamics::Component; - using real_type = typename Model::Evaluator::real_type; - - using PhasorDynamics::Component::size_; - using PhasorDynamics::Component::size_quad_; - using PhasorDynamics::Component::size_param_; - using PhasorDynamics::Component::nnz_; - using PhasorDynamics::Component::time_; - using PhasorDynamics::Component::alpha_; - using PhasorDynamics::Component::y_; - using PhasorDynamics::Component::yp_; - using PhasorDynamics::Component::yB_; - using PhasorDynamics::Component::ypB_; - using PhasorDynamics::Component::tag_; - using PhasorDynamics::Component::f_; - using PhasorDynamics::Component::fB_; - using PhasorDynamics::Component::g_; - using PhasorDynamics::Component::gB_; - using PhasorDynamics::Component::rel_tol_; - using PhasorDynamics::Component::abs_tol_; - using PhasorDynamics::Component::param_; - using PhasorDynamics::Component::param_up_; - using PhasorDynamics::Component::param_lo_; - -public: - /** - * @brief Constructor for the system model - */ - SystemModel() - { - // Set system model tolerances - rel_tol_ = 1e-7; - abs_tol_ = 1e-9; - this->max_steps_=2000; - } + namespace PhasorDynamics + { /** - * @brief Destructor for the system model - */ - virtual ~SystemModel() - { - } - - /** - * @brief Allocate buses, components, and system objects. + * @brief Prototype for a system model class * - * This method first allocates bus objects, then component objects, - * and computes system size (number of unknowns). Once the size is - * computed, system global objects are allocated. + * This class maps component data to system data and implements + * Model::Evaluator for the system model. This is still work in + * progress and code is not optimized. * - * @post size_quad_ == 0 or 1 - * @post size_ >= 1 - * @post size_param_ >= 0 + * @todo Address thread safety for the system model methods. * */ - int allocate() + template + class SystemModel : public PhasorDynamics::Component { - size_ = 0; - size_quad_ = 0; - size_param_ = 0; + using bus_type = PhasorDynamics::BusBase; + using component_type = PhasorDynamics::Component; + using real_type = typename Model::Evaluator::real_type; + + using PhasorDynamics::Component::size_; + using PhasorDynamics::Component::size_quad_; + using PhasorDynamics::Component::size_param_; + using PhasorDynamics::Component::nnz_; + using PhasorDynamics::Component::time_; + using PhasorDynamics::Component::alpha_; + using PhasorDynamics::Component::y_; + using PhasorDynamics::Component::yp_; + using PhasorDynamics::Component::yB_; + using PhasorDynamics::Component::ypB_; + using PhasorDynamics::Component::tag_; + using PhasorDynamics::Component::f_; + using PhasorDynamics::Component::fB_; + using PhasorDynamics::Component::g_; + using PhasorDynamics::Component::gB_; + using PhasorDynamics::Component::rel_tol_; + using PhasorDynamics::Component::abs_tol_; + using PhasorDynamics::Component::param_; + using PhasorDynamics::Component::param_up_; + using PhasorDynamics::Component::param_lo_; + + public: + /** + * @brief Constructor for the system model + */ + SystemModel() + { + // Set system model tolerances + rel_tol_ = 1e-7; + abs_tol_ = 1e-9; + this->max_steps_ = 2000; + } + + /** + * @brief Destructor for the system model + */ + virtual ~SystemModel() + { + } + + /** + * @brief Allocate buses, components, and system objects. + * + * This method first allocates bus objects, then component objects, + * and computes system size (number of unknowns). Once the size is + * computed, system global objects are allocated. + * + * @post size_quad_ == 0 or 1 + * @post size_ >= 1 + * @post size_param_ >= 0 + * + */ + int allocate() + { + size_ = 0; + size_quad_ = 0; + size_param_ = 0; // Allocate all buses - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - bus->allocate(); - size_ += bus->size(); - size_quad_ += bus->sizeQuadrature(); - size_param_ += bus->sizeParams(); + bus->allocate(); + size_ += bus->size(); + size_quad_ += bus->sizeQuadrature(); + size_param_ += bus->sizeParams(); } // Allocate all components - for(const auto& component : components_) + for (const auto& component : components_) { - component->allocate(); - size_ += component->size(); - size_quad_ += component->sizeQuadrature(); - size_param_ += component->sizeParams(); + component->allocate(); + size_ += component->size(); + size_quad_ += component->sizeQuadrature(); + size_param_ += component->sizeParams(); } // Allocate global vectors @@ -116,7 +116,7 @@ class SystemModel : public PhasorDynamics::Component tag_.resize(size_); g_.resize(size_quad_); - gB_.resize(size_quad_*size_param_); + gB_.resize(size_quad_ * size_param_); param_.resize(size_param_); param_lo_.resize(size_param_); @@ -125,535 +125,534 @@ class SystemModel : public PhasorDynamics::Component assert(size_quad_ == 1 or size_quad_ == 0); return 0; - } - - /** - * @brief Assume that jacobian is not avalible - * - * @return true - * @return false - */ - bool hasJacobian() - { + } + + /** + * @brief Assume that jacobian is not avalible + * + * @return true + * @return false + */ + bool hasJacobian() + { return false; - } - - /** - * @brief Initialize buses first, then all the other components. - * - * @pre All buses and components must be allocated at this point. - * @pre Bus variables are written before component variables in the - * system variable vector. - * - * Buses must be initialized before other components, because other - * components may write to buses during the initialization. - * - * Also, generators may write to control devices (e.g. governors, - * exciters, etc.) during the initialization. - * - * @todo Implement writting to system vectors in a thread-safe way. - */ - int initialize() - { + } + + /** + * @brief Initialize buses first, then all the other components. + * + * @pre All buses and components must be allocated at this point. + * @pre Bus variables are written before component variables in the + * system variable vector. + * + * Buses must be initialized before other components, because other + * components may write to buses during the initialization. + * + * Also, generators may write to control devices (e.g. governors, + * exciters, etc.) during the initialization. + * + * @todo Implement writting to system vectors in a thread-safe way. + */ + int initialize() + { // Set initial values for global solution vectors IdxT varOffset = 0; IdxT optOffset = 0; - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - bus->initialize(); + bus->initialize(); } - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) - { - y_[varOffset + j] = bus->y()[j]; - yp_[varOffset + j] = bus->yp()[j]; - } - varOffset += bus->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - param_[optOffset + j] = bus->param()[j]; - param_lo_[optOffset + j] = bus->param_lo()[j]; - param_up_[optOffset + j] = bus->param_up()[j]; - } - optOffset += bus->sizeParams(); + for (IdxT j = 0; j < bus->size(); ++j) + { + y_[varOffset + j] = bus->y()[j]; + yp_[varOffset + j] = bus->yp()[j]; + } + varOffset += bus->size(); + + for (IdxT j = 0; j < bus->sizeParams(); ++j) + { + param_[optOffset + j] = bus->param()[j]; + param_lo_[optOffset + j] = bus->param_lo()[j]; + param_up_[optOffset + j] = bus->param_up()[j]; + } + optOffset += bus->sizeParams(); } // Initialize components - for(const auto& component : components_) + for (const auto& component : components_) { - component->initialize(); + component->initialize(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize(); ++j) - { - y_[varOffset + j] = component->y()[j]; - yp_[varOffset + j] = component->yp()[j]; - } - varOffset += component->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - param_[optOffset + j] = component->param()[j]; - param_lo_[optOffset + j] = component->param_lo()[j]; - param_up_[optOffset + j] = component->param_up()[j]; - } - optOffset += component->sizeParams(); + for (IdxT j = 0; j < component->size(); ++j) + { + y_[varOffset + j] = component->y()[j]; + yp_[varOffset + j] = component->yp()[j]; + } + varOffset += component->size(); + + for (IdxT j = 0; j < component->sizeParams(); ++j) + { + param_[optOffset + j] = component->param()[j]; + param_lo_[optOffset + j] = component->param_lo()[j]; + param_up_[optOffset + j] = component->param_up()[j]; + } + optOffset += component->sizeParams(); } return 0; - } - - /** - * @todo Tagging differential variables - * - * Identify what variables in the system of differential-algebraic - * equations are differential variables, i.e. their derivatives - * appear in the equations. - */ - int tagDifferentiable() - { + } + + /** + * @todo Tagging differential variables + * + * Identify what variables in the system of differential-algebraic + * equations are differential variables, i.e. their derivatives + * appear in the equations. + */ + int tagDifferentiable() + { // Set initial values for global solution vectors IdxT offset = 0; - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - bus->tagDifferentiable(); - for(IdxT j=0; jsize(); ++j) - { - tag_[offset + j] = bus->tag()[j]; - } - offset += bus->size(); + bus->tagDifferentiable(); + for (IdxT j = 0; j < bus->size(); ++j) + { + tag_[offset + j] = bus->tag()[j]; + } + offset += bus->size(); } - for(const auto& component: components_) + for (const auto& component : components_) { - component->tagDifferentiable(); - for(IdxT j=0; jsize(); ++j) - { - tag_[offset + j] = component->tag()[j]; - } - offset += component->size(); + component->tagDifferentiable(); + for (IdxT j = 0; j < component->size(); ++j) + { + tag_[offset + j] = component->tag()[j]; + } + offset += component->size(); } return 0; - } - - /** - * @brief Compute system residual vector - * - * First, update bus and component variables from the system solution - * vector. Next, evaluate residuals in buses and components, and - * then copy values to the global residual vector. - * - * @warning Residuals must be computed for buses, before component - * residuals are computed. Buses own residuals for active and - * power P and Q, but the contributions to these residuals come - * from components. Buses assign their residual values, while components - * add to those values by in-place adition. This is why bus residuals - * need to be computed first. - * - * @todo Here, components write to local values, which are then copied - * to global system vectors. Make components write to the system - * vectors directly. - */ - int evaluateResidual() - { + } + + /** + * @brief Compute system residual vector + * + * First, update bus and component variables from the system solution + * vector. Next, evaluate residuals in buses and components, and + * then copy values to the global residual vector. + * + * @warning Residuals must be computed for buses, before component + * residuals are computed. Buses own residuals for active and + * power P and Q, but the contributions to these residuals come + * from components. Buses assign their residual values, while components + * add to those values by in-place adition. This is why bus residuals + * need to be computed first. + * + * @todo Here, components write to local values, which are then copied + * to global system vectors. Make components write to the system + * vectors directly. + */ + int evaluateResidual() + { // Update variables IdxT varOffset = 0; IdxT optOffset = 0; - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) - { - bus->y()[j] = y_[varOffset + j]; - bus->yp()[j] = yp_[varOffset + j]; - } - varOffset += bus->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - bus->param()[j] = param_[optOffset + j]; - } - optOffset += bus->sizeParams(); - - bus->evaluateResidual(); + for (IdxT j = 0; j < bus->size(); ++j) + { + bus->y()[j] = y_[varOffset + j]; + bus->yp()[j] = yp_[varOffset + j]; + } + varOffset += bus->size(); + + for (IdxT j = 0; j < bus->sizeParams(); ++j) + { + bus->param()[j] = param_[optOffset + j]; + } + optOffset += bus->sizeParams(); + + bus->evaluateResidual(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize(); ++j) - { - component->y()[j] = y_[varOffset + j]; - component->yp()[j] = yp_[varOffset + j]; - } - varOffset += component->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - component->param()[j] = param_[optOffset + j]; - } - optOffset += component->sizeParams(); - - component->evaluateResidual(); + for (IdxT j = 0; j < component->size(); ++j) + { + component->y()[j] = y_[varOffset + j]; + component->yp()[j] = yp_[varOffset + j]; + } + varOffset += component->size(); + + for (IdxT j = 0; j < component->sizeParams(); ++j) + { + component->param()[j] = param_[optOffset + j]; + } + optOffset += component->sizeParams(); + + component->evaluateResidual(); } // Update residual vector IdxT resOffset = 0; - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) - { - f_[resOffset + j] = bus->getResidual()[j]; - } - resOffset += bus->size(); + for (IdxT j = 0; j < bus->size(); ++j) + { + f_[resOffset + j] = bus->getResidual()[j]; + } + resOffset += bus->size(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize(); ++j) - { - f_[resOffset + j] = component->getResidual()[j]; - } - resOffset += component->size(); + for (IdxT j = 0; j < component->size(); ++j) + { + f_[resOffset + j] = component->getResidual()[j]; + } + resOffset += component->size(); } return 0; - } - - /** - * @brief Evaluate system Jacobian. - * - * @todo Need to implement Jacobian. For now, using finite difference - * approximation provided by IDA. This works for dense Jacobian matrix - * only. - * - */ - int evaluateJacobian(){return 0;} + } + + /** + * @brief Evaluate system Jacobian. + * + * @todo Need to implement Jacobian. For now, using finite difference + * approximation provided by IDA. This works for dense Jacobian matrix + * only. + * + */ + int evaluateJacobian() + { + return 0; + } - /** - * @brief Evaluate integrands for the system quadratures. - */ - int evaluateIntegrand() - { + /** + * @brief Evaluate integrands for the system quadratures. + */ + int evaluateIntegrand() + { // Update variables IdxT varOffset = 0; IdxT optOffset = 0; - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) - { - bus->y()[j] = y_[varOffset + j]; - bus->yp()[j] = yp_[varOffset + j]; - } - varOffset += bus->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - bus->param()[j] = param_[optOffset + j]; - } - optOffset += bus->sizeParams(); - - bus->evaluateIntegrand(); + for (IdxT j = 0; j < bus->size(); ++j) + { + bus->y()[j] = y_[varOffset + j]; + bus->yp()[j] = yp_[varOffset + j]; + } + varOffset += bus->size(); + + for (IdxT j = 0; j < bus->sizeParams(); ++j) + { + bus->param()[j] = param_[optOffset + j]; + } + optOffset += bus->sizeParams(); + + bus->evaluateIntegrand(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize(); ++j) - { - component->y()[j] = y_[varOffset + j]; - component->yp()[j] = yp_[varOffset + j]; - } - varOffset += component->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - component->param()[j] = param_[optOffset + j]; - } - optOffset += component->sizeParams(); - - component->evaluateIntegrand(); + for (IdxT j = 0; j < component->size(); ++j) + { + component->y()[j] = y_[varOffset + j]; + component->yp()[j] = yp_[varOffset + j]; + } + varOffset += component->size(); + + for (IdxT j = 0; j < component->sizeParams(); ++j) + { + component->param()[j] = param_[optOffset + j]; + } + optOffset += component->sizeParams(); + + component->evaluateIntegrand(); } // Update integrand vector IdxT intOffset = 0; - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsizeQuadrature(); ++j) - { - g_[intOffset + j] = bus->getIntegrand()[j]; - } - intOffset += bus->sizeQuadrature(); + for (IdxT j = 0; j < bus->sizeQuadrature(); ++j) + { + g_[intOffset + j] = bus->getIntegrand()[j]; + } + intOffset += bus->sizeQuadrature(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsizeQuadrature(); ++j) - { - g_[intOffset + j] = component->getIntegrand()[j]; - } - intOffset += component->sizeQuadrature(); + for (IdxT j = 0; j < component->sizeQuadrature(); ++j) + { + g_[intOffset + j] = component->getIntegrand()[j]; + } + intOffset += component->sizeQuadrature(); } return 0; - } - - /** - * @brief Initialize system adjoint. - * - * Updates variables and optimization parameters, then initializes - * adjoints locally and copies them to the system adjoint vector. - */ - int initializeAdjoint() - { - IdxT offset = 0; + } + + /** + * @brief Initialize system adjoint. + * + * Updates variables and optimization parameters, then initializes + * adjoints locally and copies them to the system adjoint vector. + */ + int initializeAdjoint() + { + IdxT offset = 0; IdxT optOffset = 0; // Update bus variables and optimization parameters - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) - { - bus->y()[j] = y_[offset + j]; - bus->yp()[j] = yp_[offset + j]; - } - offset += bus->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - bus->param()[j] = param_[optOffset + j]; - } - optOffset += bus->sizeParams(); + for (IdxT j = 0; j < bus->size(); ++j) + { + bus->y()[j] = y_[offset + j]; + bus->yp()[j] = yp_[offset + j]; + } + offset += bus->size(); + + for (IdxT j = 0; j < bus->sizeParams(); ++j) + { + bus->param()[j] = param_[optOffset + j]; + } + optOffset += bus->sizeParams(); } // Update component variables and optimization parameters - for(const auto& component: components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize(); ++j) - { - component->y()[j] = y_[offset + j]; - component->yp()[j] = yp_[offset + j]; - } - offset += component->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - component->param()[j] = param_[optOffset + j]; - } - optOffset += component->sizeParams(); + for (IdxT j = 0; j < component->size(); ++j) + { + component->y()[j] = y_[offset + j]; + component->yp()[j] = yp_[offset + j]; + } + offset += component->size(); + + for (IdxT j = 0; j < component->sizeParams(); ++j) + { + component->param()[j] = param_[optOffset + j]; + } + optOffset += component->sizeParams(); } // Reset counter offset = 0; // Initialize bus adjoints - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - bus->initializeAdjoint(); - - for(IdxT j=0; jsize(); ++j) - { - yB_[offset + j] = bus->yB()[j]; - ypB_[offset + j] = bus->ypB()[j]; - } - offset += bus->size(); + bus->initializeAdjoint(); + + for (IdxT j = 0; j < bus->size(); ++j) + { + yB_[offset + j] = bus->yB()[j]; + ypB_[offset + j] = bus->ypB()[j]; + } + offset += bus->size(); } // Initialize component adjoints - for(const auto& component: components_) + for (const auto& component : components_) { - component->initializeAdjoint(); - - for(IdxT j=0; jsize(); ++j) - { - yB_[offset + j] = component->yB()[j]; - ypB_[offset + j] = component->ypB()[j]; - } - offset += component->size(); + component->initializeAdjoint(); + + for (IdxT j = 0; j < component->size(); ++j) + { + yB_[offset + j] = component->yB()[j]; + ypB_[offset + j] = component->ypB()[j]; + } + offset += component->size(); } return 0; - } - - /** - * @brief Compute adjoint residual for the system model. - * - * @warning Components write to bus residuals. Do not copy bus residuals - * to system vectors before components computed their residuals. - * - */ - int evaluateAdjointResidual() - { + } + + /** + * @brief Compute adjoint residual for the system model. + * + * @warning Components write to bus residuals. Do not copy bus residuals + * to system vectors before components computed their residuals. + * + */ + int evaluateAdjointResidual() + { IdxT varOffset = 0; IdxT optOffset = 0; // Update variables in component models - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) - { - bus->y()[j] = y_[varOffset + j]; - bus->yp()[j] = yp_[varOffset + j]; - bus->yB()[j] = yB_[varOffset + j]; - bus->ypB()[j] = ypB_[varOffset + j]; - } - varOffset += bus->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - bus->param()[j] = param_[optOffset + j]; - } - optOffset += bus->sizeParams(); - + for (IdxT j = 0; j < bus->size(); ++j) + { + bus->y()[j] = y_[varOffset + j]; + bus->yp()[j] = yp_[varOffset + j]; + bus->yB()[j] = yB_[varOffset + j]; + bus->ypB()[j] = ypB_[varOffset + j]; + } + varOffset += bus->size(); + + for (IdxT j = 0; j < bus->sizeParams(); ++j) + { + bus->param()[j] = param_[optOffset + j]; + } + optOffset += bus->sizeParams(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize(); ++j) - { - component->y()[j] = y_[varOffset + j]; - component->yp()[j] = yp_[varOffset + j]; - component->yB()[j] = yB_[varOffset + j]; - component->ypB()[j] = ypB_[varOffset + j]; - } - varOffset += component->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - component->param()[j] = param_[optOffset + j]; - } - optOffset += component->sizeParams(); - + for (IdxT j = 0; j < component->size(); ++j) + { + component->y()[j] = y_[varOffset + j]; + component->yp()[j] = yp_[varOffset + j]; + component->yB()[j] = yB_[varOffset + j]; + component->ypB()[j] = ypB_[varOffset + j]; + } + varOffset += component->size(); + + for (IdxT j = 0; j < component->sizeParams(); ++j) + { + component->param()[j] = param_[optOffset + j]; + } + optOffset += component->sizeParams(); } - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - bus->evaluateAdjointResidual(); + bus->evaluateAdjointResidual(); } - for(const auto& component : components_) + for (const auto& component : components_) { - component->evaluateAdjointResidual(); + component->evaluateAdjointResidual(); } // Update residual vector IdxT resOffset = 0; - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) - { - fB_[resOffset + j] = bus->getAdjointResidual()[j]; - } - resOffset += bus->size(); + for (IdxT j = 0; j < bus->size(); ++j) + { + fB_[resOffset + j] = bus->getAdjointResidual()[j]; + } + resOffset += bus->size(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize(); ++j) - { - fB_[resOffset + j] = component->getAdjointResidual()[j]; - } - resOffset += component->size(); + for (IdxT j = 0; j < component->size(); ++j) + { + fB_[resOffset + j] = component->getAdjointResidual()[j]; + } + resOffset += component->size(); } return 0; - } - - //int evaluateAdjointJacobian(){return 0;} - - /** - * @brief Evaluate adjoint integrand for the system model. - * - * @pre Assumes there are no integrands in bus models. - * @pre Assumes integrand is implemented in only _one_ component. - * - */ - int evaluateAdjointIntegrand() - { + } + + // int evaluateAdjointJacobian(){return 0;} + + /** + * @brief Evaluate adjoint integrand for the system model. + * + * @pre Assumes there are no integrands in bus models. + * @pre Assumes integrand is implemented in only _one_ component. + * + */ + int evaluateAdjointIntegrand() + { // First, update variables IdxT varOffset = 0; IdxT optOffset = 0; - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) - { - bus->y()[j] = y_[varOffset + j]; - bus->yp()[j] = yp_[varOffset + j]; - bus->yB()[j] = yB_[varOffset + j]; - bus->ypB()[j] = ypB_[varOffset + j]; - } - varOffset += bus->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - bus->param()[j] = param_[optOffset + j]; - } - optOffset += bus->sizeParams(); + for (IdxT j = 0; j < bus->size(); ++j) + { + bus->y()[j] = y_[varOffset + j]; + bus->yp()[j] = yp_[varOffset + j]; + bus->yB()[j] = yB_[varOffset + j]; + bus->ypB()[j] = ypB_[varOffset + j]; + } + varOffset += bus->size(); + + for (IdxT j = 0; j < bus->sizeParams(); ++j) + { + bus->param()[j] = param_[optOffset + j]; + } + optOffset += bus->sizeParams(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize(); ++j) - { - component->y()[j] = y_[varOffset + j]; - component->yp()[j] = yp_[varOffset + j]; - component->yB()[j] = yB_[varOffset + j]; - component->ypB()[j] = ypB_[varOffset + j]; - } - varOffset += component->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - component->param()[j] = param_[optOffset + j]; - } - optOffset += component->sizeParams(); + for (IdxT j = 0; j < component->size(); ++j) + { + component->y()[j] = y_[varOffset + j]; + component->yp()[j] = yp_[varOffset + j]; + component->yB()[j] = yB_[varOffset + j]; + component->ypB()[j] = ypB_[varOffset + j]; + } + varOffset += component->size(); + + for (IdxT j = 0; j < component->sizeParams(); ++j) + { + component->param()[j] = param_[optOffset + j]; + } + optOffset += component->sizeParams(); } // Evaluate integrand and update global vector - for(const auto& component : components_) + for (const auto& component : components_) { - if(component->sizeQuadrature() == 1) + if (component->sizeQuadrature() == 1) + { + component->evaluateAdjointIntegrand(); + for (IdxT j = 0; j < size_param_; ++j) { - component->evaluateAdjointIntegrand(); - for(IdxT j=0; jgetAdjointIntegrand()[j]; - } - break; + gB_[j] = component->getAdjointIntegrand()[j]; } + break; + } } return 0; - } + } - void updateTime(real_type t, real_type a) - { - for(const auto& component : components_) + void updateTime(real_type t, real_type a) + { + for (const auto& component : components_) { - component->updateTime(t, a); + component->updateTime(t, a); } - } + } - void addBus(bus_type* bus) - { + void addBus(bus_type* bus) + { buses_.push_back(bus); - } + } - void addComponent(component_type* component) - { + void addComponent(component_type* component) + { components_.push_back(component); - } - -private: - std::vector buses_; - std::vector components_; - + } + private: + std::vector buses_; + std::vector components_; -}; // class SystemModel + }; // class SystemModel -} // namespace PhasorDynamics + } // namespace PhasorDynamics } // namespace GridKit diff --git a/src/Model/PowerElectronics/Capacitor/Capacitor.cpp b/src/Model/PowerElectronics/Capacitor/Capacitor.cpp index ca09e389..497c3b19 100644 --- a/src/Model/PowerElectronics/Capacitor/Capacitor.cpp +++ b/src/Model/PowerElectronics/Capacitor/Capacitor.cpp @@ -1,145 +1,141 @@ +#include "Capacitor.hpp" -#include #include +#include #include -#include "Capacitor.hpp" -namespace GridKit { - -/*! - * @brief Constructor for Capacitor - * - * @todo this needs to be tested on some circuit - * - * Calls default ModelEvaluatorImpl constructor. - */ - -template -Capacitor::Capacitor(IdxT id, ScalarT C) - : C_(C) -{ - size_ = 3; - n_intern_ = 1; - n_extern_ = 2; - extern_indices_ = {0,1}; - idc_ = id; -} - -template -Capacitor::~Capacitor() +namespace GridKit { -} -/*! - * @brief allocate method creates memory for vectors - */ -template -int Capacitor::allocate() -{ + /*! + * @brief Constructor for Capacitor + * + * @todo this needs to be tested on some circuit + * + * Calls default ModelEvaluatorImpl constructor. + */ + + template + Capacitor::Capacitor(IdxT id, ScalarT C) + : C_(C) + { + size_ = 3; + n_intern_ = 1; + n_extern_ = 2; + extern_indices_ = {0, 1}; + idc_ = id; + } + + template + Capacitor::~Capacitor() + { + } + + /*! + * @brief allocate method creates memory for vectors + */ + template + int Capacitor::allocate() + { y_.resize(size_); yp_.resize(size_); f_.resize(size_); - - return 0; -} -/** - * Initialization of the grid model - */ -template -int Capacitor::initialize() -{ return 0; -} - -/* - * \brief Identify differential variables - */ -template -int Capacitor::tagDifferentiable() -{ + } + + /** + * Initialization of the grid model + */ + template + int Capacitor::initialize() + { return 0; -} - -/** - * @brief Evaluate the resisdual of the Capcitor - * - */ -template -int Capacitor::evaluateResidual() -{ - //input + } + + /* + * \brief Identify differential variables + */ + template + int Capacitor::tagDifferentiable() + { + return 0; + } + + /** + * @brief Evaluate the resisdual of the Capcitor + * + */ + template + int Capacitor::evaluateResidual() + { + // input f_[0] = C_ * yp_[2]; - //output + // output f_[1] = -C_ * yp_[2]; - //internal - f_[2] = -C_ * yp_[2] + y_[0] - y_[1] - y_[2]; + // internal + f_[2] = -C_ * yp_[2] + y_[0] - y_[1] - y_[2]; return 0; -} - -/** - * @brief Compute the Jacobian dF/dy - a dF/dy' - * - * @tparam ScalarT - * @tparam IdxT - * @return int - */ -template -int Capacitor::evaluateJacobian() -{ + } + + /** + * @brief Compute the Jacobian dF/dy - a dF/dy' + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ + template + int Capacitor::evaluateJacobian() + { jac_.zeroMatrix(); - //Create dF/dy - std::vector rcord{2,2,2}; - std::vector ccord{0,1,2}; + // Create dF/dy + std::vector rcord{2, 2, 2}; + std::vector ccord{0, 1, 2}; std::vector vals{1.0, -1.0, -1.0}; jac_.setValues(rcord, ccord, vals); - //Create dF/dy' - std::vector rcordder{0,1,2}; - std::vector ccordder{2,2,2}; - std::vector valsder{C_, -C_, -C_}; - COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); - - //Perform dF/dy + \alpha dF/dy' + // Create dF/dy' + std::vector rcordder{0, 1, 2}; + std::vector ccordder{2, 2, 2}; + std::vector valsder{C_, -C_, -C_}; + COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder, 3, 3); + + // Perform dF/dy + \alpha dF/dy' jac_.axpy(alpha_, Jacder); return 0; -} + } -template -int Capacitor::evaluateIntegrand() -{ + template + int Capacitor::evaluateIntegrand() + { return 0; -} + } -template -int Capacitor::initializeAdjoint() -{ + template + int Capacitor::initializeAdjoint() + { return 0; -} + } -template -int Capacitor::evaluateAdjointResidual() -{ + template + int Capacitor::evaluateAdjointResidual() + { return 0; -} + } -template -int Capacitor::evaluateAdjointIntegrand() -{ + template + int Capacitor::evaluateAdjointIntegrand() + { return 0; -} - - - - -// Available template instantiations -template class Capacitor; -template class Capacitor; - + } -} //namespace GridKit + // Available template instantiations + template class Capacitor; + template class Capacitor; +} // namespace GridKit diff --git a/src/Model/PowerElectronics/Capacitor/Capacitor.hpp b/src/Model/PowerElectronics/Capacitor/Capacitor.hpp index b40e2f2a..b86ed913 100644 --- a/src/Model/PowerElectronics/Capacitor/Capacitor.hpp +++ b/src/Model/PowerElectronics/Capacitor/Capacitor.hpp @@ -3,66 +3,64 @@ #ifndef _CAP_HPP_ #define _CAP_HPP_ - -#include #include - +#include namespace GridKit { - template class BaseBus; + template + class BaseBus; } - namespace GridKit { - /*! - * @brief Declaration of a Capacitor class. - * - */ - template - class Capacitor : public CircuitComponent - { - using CircuitComponent::size_; - using CircuitComponent::nnz_; - using CircuitComponent::time_; - using CircuitComponent::alpha_; - using CircuitComponent::y_; - using CircuitComponent::yp_; - using CircuitComponent::tag_; - using CircuitComponent::f_; - using CircuitComponent::g_; - using CircuitComponent::yB_; - using CircuitComponent::ypB_; - using CircuitComponent::fB_; - using CircuitComponent::gB_; - using CircuitComponent::jac_; - using CircuitComponent::param_; - using CircuitComponent::idc_; + /*! + * @brief Declaration of a Capacitor class. + * + */ + template + class Capacitor : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::jac_; + using CircuitComponent::param_; + using CircuitComponent::idc_; - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; - public: - Capacitor(IdxT id, ScalarT C); - virtual ~Capacitor(); + public: + Capacitor(IdxT id, ScalarT C); + virtual ~Capacitor(); - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - private: - ScalarT C_; - }; -} + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT C_; + }; +} // namespace GridKit #endif diff --git a/src/Model/PowerElectronics/CircuitComponent.hpp b/src/Model/PowerElectronics/CircuitComponent.hpp index 1513c86d..56e0d4c5 100644 --- a/src/Model/PowerElectronics/CircuitComponent.hpp +++ b/src/Model/PowerElectronics/CircuitComponent.hpp @@ -2,284 +2,286 @@ #pragma once -#include -#include #include #include +#include +#include namespace GridKit { - /*! - * @brief Declaration of a CircuitComponent class. + /*! + * @brief Declaration of a CircuitComponent class. + * + */ + template + class CircuitComponent : public Model::Evaluator + { + public: + typedef typename Model::Evaluator::real_type real_type; + + CircuitComponent() = default; + ~CircuitComponent() = default; + + void updateTime(ScalarT t, ScalarT a) + { + this->time_ = t; + this->alpha_ = a; + } + + bool hasJacobian() + { + return true; + } + + size_t getExternSize() + { + return n_extern_; + } + + size_t getInternalSize() + { + return this->n_intern_; + } + + std::set getExternIndices() + { + return this->extern_indices_; + } + + /** + * @brief Create the mappings from local to global indices + * + * @param local_index + * @param global_index + * @return int + */ + int setExternalConnectionNodes(IdxT local_index, IdxT global_index) + { + connection_nodes_[local_index] = global_index; + return 0; + } + + /** + * @brief Given the location of value in the local vector map to global index + * + * f(local_index) = global_index * + * @param local_index index of local value in vector + * @return IdxT Index of the same value in the global vector */ - template - class CircuitComponent : public Model::Evaluator - { - public: - typedef typename Model::Evaluator::real_type real_type; - - CircuitComponent() = default; - ~CircuitComponent() = default; - - void updateTime(ScalarT t, ScalarT a) - { - this->time_ = t; - this->alpha_ = a; - } - - bool hasJacobian() { return true;} - - size_t getExternSize() - { - return n_extern_; - } - - size_t getInternalSize() - { - return this->n_intern_; - } - - std::set getExternIndices() - { - return this->extern_indices_; - } - - /** - * @brief Create the mappings from local to global indices - * - * @param local_index - * @param global_index - * @return int - */ - int setExternalConnectionNodes(IdxT local_index, IdxT global_index) - { - connection_nodes_[local_index] = global_index; - return 0; - } - - /** - * @brief Given the location of value in the local vector map to global index - * - * f(local_index) = global_index - * - * @param local_index index of local value in vector - * @return IdxT Index of the same value in the global vector - */ - IdxT getNodeConnection(IdxT local_index) - { - return connection_nodes_.at(local_index); - } - - public: - virtual IdxT size() - { - return size_; - } - - virtual IdxT nnz() - { - return nnz_; - } - - virtual IdxT sizeQuadrature() - { - return size_quad_; - } - - virtual IdxT sizeParams() - { - return size_opt_; - } - - virtual void setTolerances(real_type& rel_tol, real_type& abs_tol) const - { - rel_tol = rel_tol_; - abs_tol = abs_tol_; - } - - virtual void setMaxSteps(IdxT& msa) const - { - msa = max_steps_; - } - - std::vector& y() - { - return y_; - } - - const std::vector& y() const - { - return y_; - } - - std::vector& yp() - { - return yp_; - } - - const std::vector& yp() const - { - return yp_; - } - - std::vector& tag() - { - return tag_; - } - - const std::vector& tag() const - { - return tag_; - } - - std::vector& yB() - { - return yB_; - } - - const std::vector& yB() const - { - return yB_; - } - - std::vector& ypB() - { - return ypB_; - } - - const std::vector& ypB() const - { - return ypB_; - } - - std::vector& param() - { - return param_; - } - - const std::vector& param() const - { - return param_; - } - - std::vector& param_up() - { - return param_up_; - } - - const std::vector& param_up() const - { - return param_up_; - } - - std::vector& param_lo() - { - return param_lo_; - } - - const std::vector& param_lo() const - { - return param_lo_; - } - - std::vector& getResidual() - { - return f_; - } - - const std::vector& getResidual() const - { - return f_; - } - - COO_Matrix& getJacobian() - { - return jac_; - } - - const COO_Matrix& getJacobian() const - { - return jac_; - } - - std::vector& getIntegrand() - { - return g_; - } - - const std::vector& getIntegrand() const - { - return g_; - } - - std::vector& getAdjointResidual() - { - return fB_; - } - - const std::vector& getAdjointResidual() const - { - return fB_; - } - - std::vector& getAdjointIntegrand() - { - return gB_; - } - - const std::vector& getAdjointIntegrand() const - { - return gB_; - } - - //@todo Fix ID naming - IdxT getIDcomponent() - { - return idc_; - } - - protected: - size_t n_extern_; - size_t n_intern_; - std::set extern_indices_; - ///@todo may want to replace the mapping of connection_nodes to Node objects instead of IdxT. Allows for container free setup - std::map connection_nodes_; - - protected: - IdxT size_{0}; - IdxT nnz_{0}; - IdxT size_quad_{0}; - IdxT size_opt_{0}; - - std::vector y_; - std::vector yp_; - std::vector tag_; - std::vector f_; - std::vector g_; - - std::vector yB_; - std::vector ypB_; - std::vector fB_; - std::vector gB_; - - COO_Matrix jac_; - - std::vector param_; - std::vector param_up_; - std::vector param_lo_; - - real_type time_; - real_type alpha_; - - real_type rel_tol_; - real_type abs_tol_; - - IdxT max_steps_; - - IdxT idc_; - }; - - -} + IdxT getNodeConnection(IdxT local_index) + { + return connection_nodes_.at(local_index); + } + + public: + virtual IdxT size() + { + return size_; + } + + virtual IdxT nnz() + { + return nnz_; + } + + virtual IdxT sizeQuadrature() + { + return size_quad_; + } + + virtual IdxT sizeParams() + { + return size_opt_; + } + + virtual void setTolerances(real_type& rel_tol, real_type& abs_tol) const + { + rel_tol = rel_tol_; + abs_tol = abs_tol_; + } + + virtual void setMaxSteps(IdxT& msa) const + { + msa = max_steps_; + } + + std::vector& y() + { + return y_; + } + + const std::vector& y() const + { + return y_; + } + + std::vector& yp() + { + return yp_; + } + + const std::vector& yp() const + { + return yp_; + } + + std::vector& tag() + { + return tag_; + } + + const std::vector& tag() const + { + return tag_; + } + + std::vector& yB() + { + return yB_; + } + + const std::vector& yB() const + { + return yB_; + } + + std::vector& ypB() + { + return ypB_; + } + + const std::vector& ypB() const + { + return ypB_; + } + + std::vector& param() + { + return param_; + } + + const std::vector& param() const + { + return param_; + } + + std::vector& param_up() + { + return param_up_; + } + + const std::vector& param_up() const + { + return param_up_; + } + + std::vector& param_lo() + { + return param_lo_; + } + + const std::vector& param_lo() const + { + return param_lo_; + } + + std::vector& getResidual() + { + return f_; + } + + const std::vector& getResidual() const + { + return f_; + } + + COO_Matrix& getJacobian() + { + return jac_; + } + + const COO_Matrix& getJacobian() const + { + return jac_; + } + + std::vector& getIntegrand() + { + return g_; + } + + const std::vector& getIntegrand() const + { + return g_; + } + + std::vector& getAdjointResidual() + { + return fB_; + } + + const std::vector& getAdjointResidual() const + { + return fB_; + } + + std::vector& getAdjointIntegrand() + { + return gB_; + } + + const std::vector& getAdjointIntegrand() const + { + return gB_; + } + + //@todo Fix ID naming + IdxT getIDcomponent() + { + return idc_; + } + + protected: + size_t n_extern_; + size_t n_intern_; + std::set extern_indices_; + ///@todo may want to replace the mapping of connection_nodes to Node objects instead of IdxT. Allows for container free setup + std::map connection_nodes_; + + protected: + IdxT size_{0}; + IdxT nnz_{0}; + IdxT size_quad_{0}; + IdxT size_opt_{0}; + + std::vector y_; + std::vector yp_; + std::vector tag_; + std::vector f_; + std::vector g_; + + std::vector yB_; + std::vector ypB_; + std::vector fB_; + std::vector gB_; + + COO_Matrix jac_; + + std::vector param_; + std::vector param_up_; + std::vector param_lo_; + + real_type time_; + real_type alpha_; + + real_type rel_tol_; + real_type abs_tol_; + + IdxT max_steps_; + + IdxT idc_; + }; + +} // namespace GridKit diff --git a/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp b/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp index 68cd9ae2..5be1802d 100644 --- a/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp +++ b/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp @@ -1,117 +1,118 @@ +#include "DistributedGenerator.hpp" -#include #include +#include #include -#include "DistributedGenerator.hpp" -namespace GridKit { - - -/*! - * @brief Constructor for a Distributed Generator - * @todo Maybe have parameters be templated in. Variables cannot be changed and are unlikely to. Allows for compile time optimizations - * - * Calls default ModelEvaluatorImpl constructor. - */ - -template -DistributedGenerator::DistributedGenerator(IdxT id, DistributedGeneratorParameters parm, bool reference_frame) - : wb_(parm.wb_), - wc_(parm.wc_), - mp_(parm.mp_), - Vn_(parm.Vn_), - nq_(parm.nq_), - F_(parm.F_), - Kiv_(parm.Kiv_), - Kpv_(parm.Kpv_), - Kic_(parm.Kic_), - Kpc_(parm.Kpc_), - Cf_(parm.Cf_), - rLf_(parm.rLf_), - Lf_(parm.Lf_), - rLc_(parm.rLc_), - Lc_(parm.Lc_), - refframe_(reference_frame) +namespace GridKit { + + /*! + * @brief Constructor for a Distributed Generator + * @todo Maybe have parameters be templated in. Variables cannot be changed + * and are unlikely to. Allows for compile time optimizations + * + * Calls default ModelEvaluatorImpl constructor. + */ + template + DistributedGenerator::DistributedGenerator(IdxT id, + DistributedGeneratorParameters parm, + bool reference_frame) + : wb_(parm.wb_), + wc_(parm.wc_), + mp_(parm.mp_), + Vn_(parm.Vn_), + nq_(parm.nq_), + F_(parm.F_), + Kiv_(parm.Kiv_), + Kpv_(parm.Kpv_), + Kic_(parm.Kic_), + Kpc_(parm.Kpc_), + Cf_(parm.Cf_), + rLf_(parm.rLf_), + Lf_(parm.Lf_), + rLc_(parm.rLc_), + Lc_(parm.Lc_), + refframe_(reference_frame) + { // internals [\delta_i, Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi] // externals [\omega_ref, vba_out, vbb_out] - size_ = 16; - n_intern_ = 13; - n_extern_ = 3; - extern_indices_ = {0,1,2}; - idc_ = id; -} - -template -DistributedGenerator::~DistributedGenerator() -{ -} - -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int DistributedGenerator::allocate() -{ + size_ = 16; + n_intern_ = 13; + n_extern_ = 3; + extern_indices_ = {0, 1, 2}; + idc_ = id; + } + + template + DistributedGenerator::~DistributedGenerator() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int DistributedGenerator::allocate() + { y_.resize(size_); yp_.resize(size_); f_.resize(size_); - - return 0; -} -/** - * Initialization of the grid model - */ -template -int DistributedGenerator::initialize() -{ return 0; -} - -/* - * \brief Identify differential variables - */ -template -int DistributedGenerator::tagDifferentiable() -{ + } + + /** + * Initialization of the grid model + */ + template + int DistributedGenerator::initialize() + { return 0; -} - -/** - * @brief Contributes to the resisdual of the Distributed Generator - * - */ -template -int DistributedGenerator::evaluateResidual() -{ + } + + /* + * \brief Identify differential variables + */ + template + int DistributedGenerator::tagDifferentiable() + { + return 0; + } + + /** + * @brief Contributes to the resisdual of the Distributed Generator + * + */ + template + int DistributedGenerator::evaluateResidual() + { // ### Externals Componenets ### ScalarT omega = wb_ - mp_ * y_[4]; - //ref common ref motor angle + // ref common ref motor angle /// @todo fix boolian conditional, unclear result if (refframe_) { - f_[0] = omega - y_[0]; + f_[0] = omega - y_[0]; } else { - f_[0] = 0.0; + f_[0] = 0.0; } - - //output - //current transformed to common frame + // output + // current transformed to common frame f_[1] = cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15]; f_[2] = sin(y_[3]) * y_[14] + cos(y_[3]) * y_[15]; - //Take incoming voltages to current rotator reference frame + // Take incoming voltages to current rotator reference frame ScalarT vbd_in = cos(y_[3]) * y_[1] + sin(y_[3]) * y_[2]; ScalarT vbq_in = -sin(y_[3]) * y_[1] + cos(y_[3]) * y_[2]; - // ### Internal Componenets ## + // ### Internal Componenets ## // Rotor difference angle f_[3] = -yp_[3] + omega - y_[0]; @@ -119,245 +120,275 @@ int DistributedGenerator::evaluateResidual() f_[4] = -yp_[4] + wc_ * (y_[12] * y_[14] + y_[13] * y_[15] - y_[4]); f_[5] = -yp_[5] + wc_ * (-y_[12] * y_[15] + y_[13] * y_[14] - y_[5]); - //Voltage control + // Voltage control ScalarT vod_star = Vn_ - nq_ * y_[5]; ScalarT voq_star = 0.0; f_[6] = -yp_[6] + vod_star - y_[12]; f_[7] = -yp_[7] + voq_star - y_[13]; - ScalarT ild_star = F_ * y_[14] - wb_ * Cf_ * y_[13] + Kpv_ * (vod_star - y_[12]) + Kiv_ * y_[6]; ScalarT ilq_star = F_ * y_[15] + wb_ * Cf_ * y_[12] + Kpv_ * (voq_star - y_[13]) + Kiv_ * y_[7]; - //Current control + // Current control f_[8] = -yp_[8] + ild_star - y_[10]; f_[9] = -yp_[9] + ilq_star - y_[11]; ScalarT vid_star = -wb_ * Lf_ * y_[11] + Kpc_ * (ild_star - y_[10]) + Kic_ * y_[8]; - ScalarT viq_star = wb_ * Lf_ * y_[10] + Kpc_ * (ilq_star - y_[11]) + Kic_ * y_[9]; - - //Output LC Filter - f_[10] = -yp_[10] - (rLf_ / Lf_) * y_[10] + omega * y_[11] + (vid_star - y_[12]) / Lf_; - f_[11] = -yp_[11] - (rLf_ / Lf_) * y_[11] - omega * y_[10] + (viq_star - y_[13]) / Lf_; + ScalarT viq_star = wb_ * Lf_ * y_[10] + Kpc_ * (ilq_star - y_[11]) + Kic_ * y_[9]; + + // Output LC Filter + f_[10] = -yp_[10] - (rLf_ / Lf_) * y_[10] + omega * y_[11] + (vid_star - y_[12]) / Lf_; + f_[11] = -yp_[11] - (rLf_ / Lf_) * y_[11] - omega * y_[10] + (viq_star - y_[13]) / Lf_; f_[12] = -yp_[12] + omega * y_[13] + (y_[10] - y_[14]) / Cf_; f_[13] = -yp_[13] - omega * y_[12] + (y_[11] - y_[15]) / Cf_; - //Output Connector + // Output Connector f_[14] = -yp_[14] - (rLc_ / Lc_) * y_[14] + omega * y_[15] + (y_[12] - vbd_in) / Lc_; f_[15] = -yp_[15] - (rLc_ / Lc_) * y_[15] - omega * y_[14] + (y_[13] - vbq_in) / Lc_; return 0; -} - -/** - * @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] - * 'Generated from MATLAB symbolic' - * - * @tparam ScalarT - * @tparam IdxT - * @return int - */ -template -int DistributedGenerator::evaluateJacobian() -{ + } + + /** + * @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] + * 'Generated from MATLAB symbolic' + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ + template + int DistributedGenerator::evaluateJacobian() + { jac_.zeroMatrix(); - //Create dF/dy' - std::vector rcordder(13); + // Create dF/dy' + std::vector rcordder(13); std::vector valsder(13, -1.0); for (int i = 0; i < 13; i++) { - rcordder[i] = i + 3; + rcordder[i] = i + 3; } - COO_Matrix Jacder = COO_Matrix(rcordder, rcordder, valsder,16,16); + COO_Matrix Jacder = COO_Matrix(rcordder, rcordder, valsder, 16, 16); - std::vector ctemp{}; - std::vector rtemp{}; + std::vector ctemp{}; + std::vector rtemp{}; std::vector valtemp{}; - - - //Create dF/dy - //r = 1 + // Create dF/dy + // r = 1 ctemp = {3, 14, 15}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(1); - valtemp = { - sin(y_[3]) * y_[14] - cos(y_[3]) * y_[15], cos(y_[3]),-sin(y_[3])}; + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(1); + valtemp = {-sin(y_[3]) * y_[14] - cos(y_[3]) * y_[15], cos(y_[3]), -sin(y_[3])}; jac_.setValues(rtemp, ctemp, valtemp); - //r = 2 + // r = 2 ctemp = {3, 14, 15}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(2); - valtemp = { cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15], sin(y_[3]),cos(y_[3])}; + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(2); + valtemp = {cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15], sin(y_[3]), cos(y_[3])}; jac_.setValues(rtemp, ctemp, valtemp); - //r = 3 - + // r = 3 + ctemp = {0, 4}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(3); + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(3); valtemp = {-1.0, -mp_}; jac_.setValues(rtemp, ctemp, valtemp); - - //r = 0 + + // r = 0 if (refframe_) { - ctemp = {0, 4}; - rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(0); - valtemp = {-1.0, -mp_}; - jac_.setValues(rtemp, ctemp, valtemp); + ctemp = {0, 4}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(0); + valtemp = {-1.0, -mp_}; + jac_.setValues(rtemp, ctemp, valtemp); } - - //r = 4 + // r = 4 ctemp = {4, 12, 13, 14, 15}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(4); - valtemp = {-wc_, wc_*y_[14], wc_*y_[15], wc_*y_[12], wc_*y_[13]}; + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(4); + valtemp = {-wc_, wc_ * y_[14], wc_ * y_[15], wc_ * y_[12], wc_ * y_[13]}; jac_.setValues(rtemp, ctemp, valtemp); - //r = 5 + // r = 5 ctemp = {5, 12, 13, 14, 15}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(5); - valtemp = {-wc_, -wc_*y_[15], wc_*y_[14], wc_*y_[13], -wc_*y_[12]}; + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(5); + valtemp = {-wc_, -wc_ * y_[15], wc_ * y_[14], wc_ * y_[13], -wc_ * y_[12]}; jac_.setValues(rtemp, ctemp, valtemp); - //r = 6 + // r = 6 ctemp = {5, 12}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(6); + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(6); valtemp = {-nq_, -1.0}; jac_.setValues(rtemp, ctemp, valtemp); - - //r = 7 + + // r = 7 ctemp = {13}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(7); + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(7); valtemp = {-1.0}; jac_.setValues(rtemp, ctemp, valtemp); - //r = 8 - ctemp = {5,6,10,12,13,14}; + // r = 8 + ctemp = {5, 6, 10, 12, 13, 14}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(8); - valtemp = {-Kpv_*nq_, Kiv_, -1.0, -Kpv_, -Cf_*wb_, F_}; + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(8); + valtemp = {-Kpv_ * nq_, Kiv_, -1.0, -Kpv_, -Cf_ * wb_, F_}; jac_.setValues(rtemp, ctemp, valtemp); - //r = 9 + // r = 9 ctemp = {7, 11, 12, 13, 15}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(9); - valtemp = {Kiv_, -1.0, Cf_*wb_,-Kpv_,F_}; + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(9); + valtemp = {Kiv_, -1.0, Cf_ * wb_, -Kpv_, F_}; jac_.setValues(rtemp, ctemp, valtemp); - - //r = 10 + + // r = 10 ctemp = {4, 5, 6, 8, 10, 11, 12, 13, 14}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(10); - valtemp = {-mp_ * y_[11], -(Kpc_ * Kpv_ * nq_) / Lf_, (Kpc_ * Kiv_) / Lf_, Kic_ / Lf_, -(Kpc_ + rLf_) / Lf_, -mp_ * y_[4], -(Kpc_ * Kpv_ + 1.0) / Lf_, -(Cf_ * Kpc_ * wb_) / Lf_, (F_ * Kpc_) / Lf_}; + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(10); + valtemp = {-mp_ * y_[11], + -(Kpc_ * Kpv_ * nq_) / Lf_, + (Kpc_ * Kiv_) / Lf_, + Kic_ / Lf_, + -(Kpc_ + rLf_) / Lf_, + -mp_ * y_[4], + -(Kpc_ * Kpv_ + 1.0) / Lf_, + -(Cf_ * Kpc_ * wb_) / Lf_, + (F_ * Kpc_) / Lf_}; jac_.setValues(rtemp, ctemp, valtemp); - //r = 11 + // r = 11 ctemp = {4, 7, 9, 10, 11, 12, 13, 15}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(11); - valtemp = {mp_ * y_[10], (Kiv_ * Kpc_) / Lf_, Kic_ / Lf_, mp_ * y_[4], -(Kpc_ + rLf_) / Lf_, (Cf_ * Kpc_ * wb_) / Lf_, -(Kpc_ * Kpv_ + 1.0) / Lf_, (F_ * Kpc_) / Lf_}; + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(11); + valtemp = {mp_ * y_[10], + (Kiv_ * Kpc_) / Lf_, + Kic_ / Lf_, + mp_ * y_[4], + -(Kpc_ + rLf_) / Lf_, + (Cf_ * Kpc_ * wb_) / Lf_, + -(Kpc_ * Kpv_ + 1.0) / Lf_, + (F_ * Kpc_) / Lf_}; jac_.setValues(rtemp, ctemp, valtemp); - //r = 12 + // r = 12 ctemp = {4, 10, 13, 14}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(12); + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(12); valtemp = {-mp_ * y_[13], 1.0 / Cf_, wb_ - mp_ * y_[4], -1.0 / Cf_}; jac_.setValues(rtemp, ctemp, valtemp); - - //r = 13 + // r = 13 ctemp = {4, 11, 12, 15}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(13); + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(13); valtemp = {mp_ * y_[12], 1.0 / Cf_, -wb_ + mp_ * y_[4], -1.0 / Cf_}; jac_.setValues(rtemp, ctemp, valtemp); - - //r = 14 + // r = 14 ctemp = {1, 2, 3, 4, 12, 14, 15}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(14); - valtemp = {(1.0/Lc_) * -cos(y_[3]) , (1.0/Lc_) * -sin(y_[3]) , (1.0/Lc_) * (sin(y_[3]) * y_[1] - cos(y_[3]) * y_[2]), -mp_ * y_[15], 1.0 / Lc_, -rLc_ / Lc_, wb_ - mp_ * y_[4]}; + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(14); + valtemp = {(1.0 / Lc_) * -cos(y_[3]), + (1.0 / Lc_) * -sin(y_[3]), + (1.0 / Lc_) * (sin(y_[3]) * y_[1] - cos(y_[3]) * y_[2]), + -mp_ * y_[15], + 1.0 / Lc_, + -rLc_ / Lc_, + wb_ - mp_ * y_[4]}; jac_.setValues(rtemp, ctemp, valtemp); - - //r = 15 + // r = 15 ctemp = {1, 2, 3, 4, 13, 14, 15}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(15); - valtemp = {(1.0/Lc_) * sin(y_[3]) , (1.0/Lc_) * -cos(y_[3]), (1.0/Lc_) * (cos(y_[3]) * y_[1] + sin(y_[3]) * y_[2]), mp_ * y_[14], 1.0 / Lc_, -wb_ + mp_ * y_[4], -rLc_ / Lc_}; + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(15); + valtemp = {(1.0 / Lc_) * sin(y_[3]), + (1.0 / Lc_) * -cos(y_[3]), + (1.0 / Lc_) * (cos(y_[3]) * y_[1] + sin(y_[3]) * y_[2]), + mp_ * y_[14], + 1.0 / Lc_, + -wb_ + mp_ * y_[4], + -rLc_ / Lc_}; jac_.setValues(rtemp, ctemp, valtemp); - - //Perform dF/dy + \alpha dF/dy' + // Perform dF/dy + \alpha dF/dy' jac_.axpy(alpha_, Jacder); return 0; -} + } -template -int DistributedGenerator::evaluateIntegrand() -{ + template + int DistributedGenerator::evaluateIntegrand() + { return 0; -} + } -template -int DistributedGenerator::initializeAdjoint() -{ + template + int DistributedGenerator::initializeAdjoint() + { return 0; -} + } -template -int DistributedGenerator::evaluateAdjointResidual() -{ + template + int DistributedGenerator::evaluateAdjointResidual() + { return 0; -} + } -template -int DistributedGenerator::evaluateAdjointIntegrand() -{ + template + int DistributedGenerator::evaluateAdjointIntegrand() + { return 0; -} - - - - -// Available template instantiations -template class DistributedGenerator; -template class DistributedGenerator; - + } -} //namespace GridKit + // Available template instantiations + template class DistributedGenerator; + template class DistributedGenerator; +} // namespace GridKit diff --git a/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp b/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp index d9f7b005..96654cf6 100644 --- a/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp +++ b/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp @@ -3,101 +3,100 @@ #ifndef _CAP_HPP_ #define _CAP_HPP_ - -#include #include - +#include namespace GridKit { - template class BaseBus; - - template - struct DistributedGeneratorParameters - { - ScalarT wb_; - ScalarT wc_; - ScalarT mp_; - ScalarT Vn_; - ScalarT nq_; - ScalarT F_; - ScalarT Kiv_; - ScalarT Kpv_; - ScalarT Kic_; - ScalarT Kpc_; - ScalarT Cf_; - ScalarT rLf_; - ScalarT Lf_; - ScalarT rLc_; - ScalarT Lc_; - }; -} + template + class BaseBus; + template + struct DistributedGeneratorParameters + { + ScalarT wb_; + ScalarT wc_; + ScalarT mp_; + ScalarT Vn_; + ScalarT nq_; + ScalarT F_; + ScalarT Kiv_; + ScalarT Kpv_; + ScalarT Kic_; + ScalarT Kpc_; + ScalarT Cf_; + ScalarT rLf_; + ScalarT Lf_; + ScalarT rLc_; + ScalarT Lc_; + }; +} // namespace GridKit namespace GridKit { - /*! - * @brief Declaration of a DistributedGenerator class. - * - */ - template - class DistributedGenerator : public CircuitComponent - { - using CircuitComponent::size_; - using CircuitComponent::nnz_; - using CircuitComponent::time_; - using CircuitComponent::alpha_; - using CircuitComponent::y_; - using CircuitComponent::yp_; - using CircuitComponent::tag_; - using CircuitComponent::f_; - using CircuitComponent::g_; - using CircuitComponent::yB_; - using CircuitComponent::ypB_; - using CircuitComponent::fB_; - using CircuitComponent::gB_; - using CircuitComponent::jac_; - using CircuitComponent::param_; - using CircuitComponent::idc_; - - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + /*! + * @brief Declaration of a DistributedGenerator class. + * + */ + template + class DistributedGenerator : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::jac_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; + public: + DistributedGenerator(IdxT id, + DistributedGeneratorParameters parm, + bool reference_frame); + virtual ~DistributedGenerator(); - public: - DistributedGenerator(IdxT id, DistributedGeneratorParameters parm, bool reference_frame); - virtual ~DistributedGenerator(); + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - private: - ScalarT wb_; - ScalarT wc_; - ScalarT mp_; - ScalarT Vn_; - ScalarT nq_; - ScalarT F_; - ScalarT Kiv_; - ScalarT Kpv_; - ScalarT Kic_; - ScalarT Kpc_; - ScalarT Cf_; - ScalarT rLf_; - ScalarT Lf_; - ScalarT rLc_; - ScalarT Lc_; - bool refframe_; - }; -} + private: + ScalarT wb_; + ScalarT wc_; + ScalarT mp_; + ScalarT Vn_; + ScalarT nq_; + ScalarT F_; + ScalarT Kiv_; + ScalarT Kpv_; + ScalarT Kic_; + ScalarT Kpc_; + ScalarT Cf_; + ScalarT rLf_; + ScalarT Lf_; + ScalarT rLc_; + ScalarT Lc_; + bool refframe_; + }; +} // namespace GridKit #endif diff --git a/src/Model/PowerElectronics/InductionMotor/InductionMotor.cpp b/src/Model/PowerElectronics/InductionMotor/InductionMotor.cpp index b5791014..34e1f743 100644 --- a/src/Model/PowerElectronics/InductionMotor/InductionMotor.cpp +++ b/src/Model/PowerElectronics/InductionMotor/InductionMotor.cpp @@ -1,151 +1,143 @@ +#include "InductionMotor.hpp" -#include #include +#include #include -#include "InductionMotor.hpp" - -namespace GridKit { - - - -/*! - * @brief Constructor for a constant InductionMotor model - * - * Calls default ModelEvaluatorImpl constructor. - * @todo create a test case utilizing the component. - * @todo create a unit test to check correctness of component - * - * @tparam ScalarT - data type for scalar variables in the model - * @tparam IdxT - integer index type for the model - * - * @param[in] id - unique identifier for the component - * @param[in] Lls - stator leakage inductance - */ - -template -InductionMotor::InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, ScalarT Llr, ScalarT Rr, ScalarT Lms, ScalarT RJ, ScalarT P) - : Lls_(Lls), - Rs_(Rs), - Llr_(Llr), - Rr_(Rr), - Lms_(Lms), - RJ_(RJ), - P_(P) -{ - size_ = 10; - n_intern_ = 5; - n_extern_ = 5; - extern_indices_ = {0,1,2,3,4}; - idc_ = id; -} - -template -InductionMotor::~InductionMotor() +namespace GridKit { -} -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int InductionMotor::allocate() -{ + /*! + * @brief Constructor for a constant InductionMotor model + * + * Calls default ModelEvaluatorImpl constructor. + * @todo create a test case utilizing the component. + * @todo create a unit test to check correctness of component + * + * @tparam ScalarT - data type for scalar variables in the model + * @tparam IdxT - integer index type for the model + * + * @param[in] id - unique identifier for the component + * @param[in] Lls - stator leakage inductance + */ + + template + InductionMotor::InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, ScalarT Llr, ScalarT Rr, ScalarT Lms, ScalarT RJ, ScalarT P) + : Lls_(Lls), + Rs_(Rs), + Llr_(Llr), + Rr_(Rr), + Lms_(Lms), + RJ_(RJ), + P_(P) + { + size_ = 10; + n_intern_ = 5; + n_extern_ = 5; + extern_indices_ = {0, 1, 2, 3, 4}; + idc_ = id; + } + + template + InductionMotor::~InductionMotor() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int InductionMotor::allocate() + { y_.resize(size_); yp_.resize(size_); f_.resize(size_); return 0; -} - -/** - * Initialization of the grid model - */ -template -int InductionMotor::initialize() -{ + } + + /** + * Initialization of the grid model + */ + template + int InductionMotor::initialize() + { return 0; -} - -/* - * \brief Identify differential variables - */ -template -int InductionMotor::tagDifferentiable() -{ + } + + /* + * \brief Identify differential variables + */ + template + int InductionMotor::tagDifferentiable() + { return 0; -} - -/** - * @brief Contributes to the resisdual - * - */ -template -int InductionMotor::evaluateResidual() -{ - + } + + /** + * @brief Contributes to the resisdual + * + */ + template + int InductionMotor::evaluateResidual() + { + f_[0] = y_[5] + y_[7]; - f_[1] = (-1.0/2.0) * y_[5] - (sqrt(3.0)/2.0)*y_[6] + y_[7]; - f_[2] = (-1.0/2.0) * y_[5] + (sqrt(3.0)/2.0)*y_[6] + y_[7]; - f_[3] = RJ_ * yp_[3] - (3.0/4.0)*P_*Lms_ * (y_[5]*y_[9] - y_[6]*y_[8]); + f_[1] = (-1.0 / 2.0) * y_[5] - (sqrt(3.0) / 2.0) * y_[6] + y_[7]; + f_[2] = (-1.0 / 2.0) * y_[5] + (sqrt(3.0) / 2.0) * y_[6] + y_[7]; + f_[3] = RJ_ * yp_[3] - (3.0 / 4.0) * P_ * Lms_ * (y_[5] * y_[9] - y_[6] * y_[8]); f_[4] = yp_[4] - y_[3]; - f_[5] = (1.0/3.0)*(2.0* y_[0] - y_[1] - y_[2]) - Rs_*y_[5] - (Lls_ + Lms_) * yp_[5] - Lms_ * yp_[6]; - f_[6] = (1.0/sqrt(3.0))*(-y_[1] + y_[2]) - Rs_*y_[6] - (Lls_ + Lms_) * yp_[6] - Lms_ * yp_[5]; - f_[7] = (y_[0] + y_[1] + y_[2])/3.0 - Rs_*y_[7] - Lls_ * yp_[7]; - f_[8] = Rr_*y_[8] + (Llr_ + Lms_)*yp_[8] + Lms_ * yp_[5] - (P_/2)*y_[3]*((Llr_+Lms_)*y_[9] + Lms_*y_[6]); - f_[9] = Rr_*y_[9] + (Llr_ + Lms_)*yp_[9] + Lms_ * yp_[6] + (P_/2)*y_[3]*((Llr_+Lms_)*y_[8] + Lms_*y_[5]); - return 0; -} - -/** - * @brief Compute component Jacobian - * - * @todo need to implement - * - * @tparam ScalarT - * @tparam IdxT - * @return int - */ -template -int InductionMotor::evaluateJacobian() -{ - + f_[5] = (1.0 / 3.0) * (2.0 * y_[0] - y_[1] - y_[2]) - Rs_ * y_[5] - (Lls_ + Lms_) * yp_[5] - Lms_ * yp_[6]; + f_[6] = (1.0 / sqrt(3.0)) * (-y_[1] + y_[2]) - Rs_ * y_[6] - (Lls_ + Lms_) * yp_[6] - Lms_ * yp_[5]; + f_[7] = (y_[0] + y_[1] + y_[2]) / 3.0 - Rs_ * y_[7] - Lls_ * yp_[7]; + f_[8] = Rr_ * y_[8] + (Llr_ + Lms_) * yp_[8] + Lms_ * yp_[5] - (P_ / 2) * y_[3] * ((Llr_ + Lms_) * y_[9] + Lms_ * y_[6]); + f_[9] = Rr_ * y_[9] + (Llr_ + Lms_) * yp_[9] + Lms_ * yp_[6] + (P_ / 2) * y_[3] * ((Llr_ + Lms_) * y_[8] + Lms_ * y_[5]); return 0; -} + } + + /** + * @brief Compute component Jacobian + * + * @todo need to implement + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ + template + int InductionMotor::evaluateJacobian() + { -template -int InductionMotor::evaluateIntegrand() -{ return 0; -} + } -template -int InductionMotor::initializeAdjoint() -{ + template + int InductionMotor::evaluateIntegrand() + { return 0; -} + } -template -int InductionMotor::evaluateAdjointResidual() -{ + template + int InductionMotor::initializeAdjoint() + { return 0; -} + } -template -int InductionMotor::evaluateAdjointIntegrand() -{ + template + int InductionMotor::evaluateAdjointResidual() + { return 0; -} - - - - - -// Available template instantiations -template class InductionMotor; -template class InductionMotor; + } + template + int InductionMotor::evaluateAdjointIntegrand() + { + return 0; + } -} //namespace GridKit + // Available template instantiations + template class InductionMotor; + template class InductionMotor; +} // namespace GridKit diff --git a/src/Model/PowerElectronics/InductionMotor/InductionMotor.hpp b/src/Model/PowerElectronics/InductionMotor/InductionMotor.hpp index 3223352c..007e7fd5 100644 --- a/src/Model/PowerElectronics/InductionMotor/InductionMotor.hpp +++ b/src/Model/PowerElectronics/InductionMotor/InductionMotor.hpp @@ -3,72 +3,70 @@ #ifndef _IMOTOR_HPP_ #define _IMOTOR_HPP_ - -#include #include - +#include namespace GridKit { - template class BaseBus; + template + class BaseBus; } - namespace GridKit { - /*! - * @brief Declaration of a InductionMotor class. - * - */ - template - class InductionMotor : public CircuitComponent - { - using CircuitComponent::size_; - using CircuitComponent::nnz_; - using CircuitComponent::time_; - using CircuitComponent::alpha_; - using CircuitComponent::y_; - using CircuitComponent::yp_; - using CircuitComponent::tag_; - using CircuitComponent::f_; - using CircuitComponent::g_; - using CircuitComponent::yB_; - using CircuitComponent::ypB_; - using CircuitComponent::fB_; - using CircuitComponent::gB_; - using CircuitComponent::jac_; - using CircuitComponent::param_; - using CircuitComponent::idc_; - - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + /*! + * @brief Declaration of a InductionMotor class. + * + */ + template + class InductionMotor : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::jac_; + using CircuitComponent::param_; + using CircuitComponent::idc_; - public: - InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, ScalarT Llr, ScalarT Rr, ScalarT Lms, ScalarT RJ, ScalarT P); - virtual ~InductionMotor(); + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + public: + InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, ScalarT Llr, ScalarT Rr, ScalarT Lms, ScalarT RJ, ScalarT P); + virtual ~InductionMotor(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - private: - ScalarT Lls_; - ScalarT Rs_; - ScalarT Llr_; - ScalarT Rr_; - ScalarT Lms_; - ScalarT RJ_; - ScalarT P_; - }; -} + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT Lls_; + ScalarT Rs_; + ScalarT Llr_; + ScalarT Rr_; + ScalarT Lms_; + ScalarT RJ_; + ScalarT P_; + }; +} // namespace GridKit #endif diff --git a/src/Model/PowerElectronics/Inductor/Inductor.cpp b/src/Model/PowerElectronics/Inductor/Inductor.cpp index 6da117fc..fa9d0732 100644 --- a/src/Model/PowerElectronics/Inductor/Inductor.cpp +++ b/src/Model/PowerElectronics/Inductor/Inductor.cpp @@ -1,144 +1,140 @@ +#include "Inductor.hpp" -#include #include +#include #include -#include "Inductor.hpp" -namespace GridKit { - -/*! - * @brief Constructor for a inductor - * - * Calls default ModelEvaluatorImpl constructor. - */ - -template -Inductor::Inductor(IdxT id, ScalarT L) - : L_(L) -{ - size_ = 3; - n_intern_ = 1; - n_extern_ = 2; - extern_indices_ = {0,1}; - idc_ = id; -} - -template -Inductor::~Inductor() +namespace GridKit { -} -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int Inductor::allocate() -{ - + /*! + * @brief Constructor for a inductor + * + * Calls default ModelEvaluatorImpl constructor. + */ + + template + Inductor::Inductor(IdxT id, ScalarT L) + : L_(L) + { + size_ = 3; + n_intern_ = 1; + n_extern_ = 2; + extern_indices_ = {0, 1}; + idc_ = id; + } + + template + Inductor::~Inductor() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int Inductor::allocate() + { + y_.resize(size_); yp_.resize(size_); f_.resize(size_); - - return 0; -} -/** - * Initialization of the grid model - */ -template -int Inductor::initialize() -{ return 0; -} - -/* - * \brief Identify differential variables - */ -template -int Inductor::tagDifferentiable() -{ + } + + /** + * Initialization of the grid model + */ + template + int Inductor::initialize() + { return 0; -} - -/** - * @brief Compute the resisdual of the component - * - */ -template -int Inductor::evaluateResidual() -{ - //input + } + + /* + * \brief Identify differential variables + */ + template + int Inductor::tagDifferentiable() + { + return 0; + } + + /** + * @brief Compute the resisdual of the component + * + */ + template + int Inductor::evaluateResidual() + { + // input f_[0] = -y_[2]; - //output + // output f_[1] = y_[2]; - //internal - f_[2] = -L_ * yp_[2] + y_[1] - y_[0] ; + // internal + f_[2] = -L_ * yp_[2] + y_[1] - y_[0]; return 0; -} - -/** - * @brief Evaluate the jacobian of the component - * - * @tparam ScalarT - * @tparam IdxT - * @return int - */ -template -int Inductor::evaluateJacobian() -{ + } + + /** + * @brief Evaluate the jacobian of the component + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ + template + int Inductor::evaluateJacobian() + { jac_.zeroMatrix(); - //Create dF/dy - std::vector rcord{0,1,2,2}; - std::vector ccord{2,2,0,1}; + // Create dF/dy + std::vector rcord{0, 1, 2, 2}; + std::vector ccord{2, 2, 0, 1}; std::vector vals{-1.0, 1.0, -1.0, 1.0}; jac_.setValues(rcord, ccord, vals); - //Create dF/dy' - std::vector rcordder{2}; - std::vector ccordder{2}; - std::vector valsder{-L_}; - COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); - - //Perform dF/dy + \alpha dF/dy' + // Create dF/dy' + std::vector rcordder{2}; + std::vector ccordder{2}; + std::vector valsder{-L_}; + COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder, 3, 3); + + // Perform dF/dy + \alpha dF/dy' jac_.axpy(alpha_, Jacder); return 0; -} + } -template -int Inductor::evaluateIntegrand() -{ + template + int Inductor::evaluateIntegrand() + { return 0; -} + } -template -int Inductor::initializeAdjoint() -{ + template + int Inductor::initializeAdjoint() + { return 0; -} + } -template -int Inductor::evaluateAdjointResidual() -{ + template + int Inductor::evaluateAdjointResidual() + { return 0; -} + } -template -int Inductor::evaluateAdjointIntegrand() -{ + template + int Inductor::evaluateAdjointIntegrand() + { return 0; -} - - - - -// Available template instantiations -template class Inductor; -template class Inductor; - + } -} //namespace GridKit + // Available template instantiations + template class Inductor; + template class Inductor; +} // namespace GridKit diff --git a/src/Model/PowerElectronics/Inductor/Inductor.hpp b/src/Model/PowerElectronics/Inductor/Inductor.hpp index fc459e90..c40920b0 100644 --- a/src/Model/PowerElectronics/Inductor/Inductor.hpp +++ b/src/Model/PowerElectronics/Inductor/Inductor.hpp @@ -3,70 +3,64 @@ #ifndef _IND_HPP_ #define _IND_HPP_ - -#include #include - +#include namespace GridKit { - template class BaseBus; + template + class BaseBus; } - namespace GridKit { - /*! - * @brief Declaration of a Inductor class. - * - */ - template - class Inductor : public CircuitComponent - { - using CircuitComponent::size_; - using CircuitComponent::nnz_; - using CircuitComponent::time_; - using CircuitComponent::alpha_; - using CircuitComponent::y_; - using CircuitComponent::yp_; - using CircuitComponent::tag_; - using CircuitComponent::f_; - using CircuitComponent::g_; - using CircuitComponent::yB_; - using CircuitComponent::ypB_; - using CircuitComponent::fB_; - using CircuitComponent::gB_; - using CircuitComponent::jac_; - using CircuitComponent::param_; - using CircuitComponent::idc_; - - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; - + /*! + * @brief Declaration of a Inductor class. + * + */ + template + class Inductor : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::jac_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; + public: + Inductor(IdxT id, ScalarT L); + virtual ~Inductor(); - public: - Inductor(IdxT id, ScalarT L); - virtual ~Inductor(); - - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); - - private: - ScalarT L_; - }; -} + private: + ScalarT L_; + }; +} // namespace GridKit #endif diff --git a/src/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp b/src/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp index 9e42482e..189dc1d6 100644 --- a/src/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp +++ b/src/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp @@ -1,133 +1,128 @@ +#include "LinearTransformer.hpp" -#include #include +#include #include -#include "LinearTransformer.hpp" -namespace GridKit { - -/*! - * @brief Constructor for a LinearTransformer model - * - * Calls default ModelEvaluatorImpl constructor. - * @todo Not tested in any model yet. Should be - * @todo Has not been tested for correctness - * - * @tparam ScalarT - floating point type for the model - * @tparam IdxT - integer index type for the model - * - * @param[in] id - unique identifier for the component - * @param[in] L0 - inductance 0 - * @param[in] L1 - inductance 1 - * @param[in] R0 - resistance 0 - * @param[in] R1 - resistance 1 - * @param[in] M - mutual inductance - */ - -template -LinearTransformer::LinearTransformer(IdxT id, ScalarT L0, ScalarT L1, ScalarT R0, ScalarT R1, ScalarT M) - : L0_(L0), - L1_(L1), - R0_(R0), - R1_(R1), - M_(M) -{ - size_ = 4; - n_intern_ = 2; - n_extern_ = 2; - extern_indices_ = {0,1}; - idc_ = id; -} - -template -LinearTransformer::~LinearTransformer() +namespace GridKit { -} -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int LinearTransformer::allocate() -{ + /*! + * @brief Constructor for a LinearTransformer model + * + * Calls default ModelEvaluatorImpl constructor. + * @todo Not tested in any model yet. Should be + * @todo Has not been tested for correctness + * + * @tparam ScalarT - floating point type for the model + * @tparam IdxT - integer index type for the model + * + * @param[in] id - unique identifier for the component + * @param[in] L0 - inductance 0 + * @param[in] L1 - inductance 1 + * @param[in] R0 - resistance 0 + * @param[in] R1 - resistance 1 + * @param[in] M - mutual inductance + */ + + template + LinearTransformer::LinearTransformer(IdxT id, ScalarT L0, ScalarT L1, ScalarT R0, ScalarT R1, ScalarT M) + : L0_(L0), + L1_(L1), + R0_(R0), + R1_(R1), + M_(M) + { + size_ = 4; + n_intern_ = 2; + n_extern_ = 2; + extern_indices_ = {0, 1}; + idc_ = id; + } + + template + LinearTransformer::~LinearTransformer() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int LinearTransformer::allocate() + { y_.resize(size_); yp_.resize(size_); f_.resize(size_); return 0; -} - -/** - * Initialization of the grid model - */ -template -int LinearTransformer::initialize() -{ + } + + /** + * Initialization of the grid model + */ + template + int LinearTransformer::initialize() + { return 0; -} - -/* - * \brief Identify differential variables - */ -template -int LinearTransformer::tagDifferentiable() -{ + } + + /* + * \brief Identify differential variables + */ + template + int LinearTransformer::tagDifferentiable() + { return 0; -} - -/** - * @brief Computes the component resisdual - * - */ -template -int LinearTransformer::evaluateResidual() -{ + } + + /** + * @brief Computes the component resisdual + * + */ + template + int LinearTransformer::evaluateResidual() + { f_[0] = y_[2]; f_[1] = y_[3]; f_[2] = y_[0] - R0_ * y_[2] - L0_ * yp_[2] - M_ * yp_[3]; f_[2] = y_[1] - R1_ * y_[3] - M_ * yp_[2] - L1_ * yp_[3]; return 0; -} + } -template -int LinearTransformer::evaluateJacobian() -{ + template + int LinearTransformer::evaluateJacobian() + { return 0; -} + } -template -int LinearTransformer::evaluateIntegrand() -{ + template + int LinearTransformer::evaluateIntegrand() + { return 0; -} + } -template -int LinearTransformer::initializeAdjoint() -{ + template + int LinearTransformer::initializeAdjoint() + { return 0; -} + } -template -int LinearTransformer::evaluateAdjointResidual() -{ + template + int LinearTransformer::evaluateAdjointResidual() + { return 0; -} + } -template -int LinearTransformer::evaluateAdjointIntegrand() -{ + template + int LinearTransformer::evaluateAdjointIntegrand() + { return 0; -} - - - - - -// Available template instantiations -template class LinearTransformer; -template class LinearTransformer; - + } -} //namespace GridKit + // Available template instantiations + template class LinearTransformer; + template class LinearTransformer; +} // namespace GridKit diff --git a/src/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp b/src/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp index 3d0324ae..b1e9c57c 100644 --- a/src/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp +++ b/src/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp @@ -3,70 +3,68 @@ #ifndef _LTRANS_HPP_ #define _LTRANS_HPP_ - -#include #include - +#include namespace GridKit { - template class BaseBus; + template + class BaseBus; } - namespace GridKit { - /*! - * @brief Declaration of a LinearTransformer class. - * - */ - template - class LinearTransformer : public CircuitComponent - { - using CircuitComponent::size_; - using CircuitComponent::nnz_; - using CircuitComponent::time_; - using CircuitComponent::alpha_; - using CircuitComponent::y_; - using CircuitComponent::yp_; - using CircuitComponent::tag_; - using CircuitComponent::f_; - using CircuitComponent::g_; - using CircuitComponent::yB_; - using CircuitComponent::ypB_; - using CircuitComponent::fB_; - using CircuitComponent::gB_; - using CircuitComponent::jac_; - using CircuitComponent::param_; - using CircuitComponent::idc_; + /*! + * @brief Declaration of a LinearTransformer class. + * + */ + template + class LinearTransformer : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::jac_; + using CircuitComponent::param_; + using CircuitComponent::idc_; - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; - public: - LinearTransformer(IdxT id, ScalarT L0, ScalarT L1, ScalarT R0, ScalarT R1, ScalarT M); - virtual ~LinearTransformer(); + public: + LinearTransformer(IdxT id, ScalarT L0, ScalarT L1, ScalarT R0, ScalarT R1, ScalarT M); + virtual ~LinearTransformer(); - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - private: - ScalarT L0_; - ScalarT L1_; - ScalarT R0_; - ScalarT R1_; - ScalarT M_; - }; -} + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT L0_; + ScalarT L1_; + ScalarT R0_; + ScalarT R1_; + ScalarT M_; + }; +} // namespace GridKit #endif diff --git a/src/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp b/src/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp index 75c41be9..3de0b9e1 100644 --- a/src/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/src/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -1,138 +1,137 @@ -#include +#include "MicrogridBusDQ.hpp" + #include +#include #include -#include "MicrogridBusDQ.hpp" -namespace GridKit { - -/*! - * @brief Constructor for a constant MicrogridBusDQ model - * - * Calls default ModelEvaluatorImpl constructor. - * - * 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 - */ -template -MicrogridBusDQ::MicrogridBusDQ(IdxT id, ScalarT RN) - : RN_(RN) -{ - // externals [vbus_d, vbus_q] - size_ = 2; - n_intern_ = 0; - n_extern_ = 2; - extern_indices_ = {0,1}; - idc_ = id; -} - -template -MicrogridBusDQ::~MicrogridBusDQ() +namespace GridKit { -} -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int MicrogridBusDQ::allocate() -{ + /*! + * @brief Constructor for a constant MicrogridBusDQ model + * + * Calls default ModelEvaluatorImpl constructor. + * + * 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 + */ + template + MicrogridBusDQ::MicrogridBusDQ(IdxT id, ScalarT RN) + : RN_(RN) + { + // externals [vbus_d, vbus_q] + size_ = 2; + n_intern_ = 0; + n_extern_ = 2; + extern_indices_ = {0, 1}; + idc_ = id; + } + + template + MicrogridBusDQ::~MicrogridBusDQ() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int MicrogridBusDQ::allocate() + { y_.resize(size_); yp_.resize(size_); f_.resize(size_); - - return 0; -} -/** - * Initialization of the grid model - */ -template -int MicrogridBusDQ::initialize() -{ return 0; -} - -/* - * \brief Identify differential variables - */ -template -int MicrogridBusDQ::tagDifferentiable() -{ + } + + /** + * Initialization of the grid model + */ + template + int MicrogridBusDQ::initialize() + { return 0; -} - -/** - * @brief Evaluate residual of microgrid line - * 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. - * - * refernce to equations in class header - * - */ -template -int MicrogridBusDQ::evaluateResidual() -{ - //bus voltage + } + + /* + * \brief Identify differential variables + */ + template + int MicrogridBusDQ::tagDifferentiable() + { + return 0; + } + + /** + * @brief Evaluate residual of microgrid line + * 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. + * + * refernce to equations in class header + * + */ + template + int MicrogridBusDQ::evaluateResidual() + { + // bus voltage f_[0] = -y_[0] / RN_; f_[1] = -y_[1] / RN_; return 0; -} - -/** - * @brief Generate Jacobian - * - * @tparam ScalarT - * @tparam IdxT - * @return int - */ -template -int MicrogridBusDQ::evaluateJacobian() -{ + } + + /** + * @brief Generate Jacobian + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ + template + int MicrogridBusDQ::evaluateJacobian() + { jac_.zeroMatrix(); - //Create dF/dy - std::vector rtemp{0,1}; - std::vector ctemp{0,1}; - std::vector vals{-1.0 / RN_,-1.0 / RN_}; + // Create dF/dy + std::vector rtemp{0, 1}; + std::vector ctemp{0, 1}; + std::vector vals{-1.0 / RN_, -1.0 / RN_}; jac_.setValues(rtemp, ctemp, vals); return 0; -} + } -template -int MicrogridBusDQ::evaluateIntegrand() -{ + template + int MicrogridBusDQ::evaluateIntegrand() + { return 0; -} + } -template -int MicrogridBusDQ::initializeAdjoint() -{ + template + int MicrogridBusDQ::initializeAdjoint() + { return 0; -} + } -template -int MicrogridBusDQ::evaluateAdjointResidual() -{ + template + int MicrogridBusDQ::evaluateAdjointResidual() + { return 0; -} + } -template -int MicrogridBusDQ::evaluateAdjointIntegrand() -{ + template + int MicrogridBusDQ::evaluateAdjointIntegrand() + { return 0; -} - - -// Available template instantiations -template class MicrogridBusDQ; -template class MicrogridBusDQ; - + } -} //namespace GridKit + // Available template instantiations + template class MicrogridBusDQ; + template class MicrogridBusDQ; +} // namespace GridKit diff --git a/src/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp b/src/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp index dcbca2e9..46173c5a 100644 --- a/src/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp +++ b/src/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp @@ -3,68 +3,64 @@ #ifndef _VIRBUSDQ_HPP_ #define _VIRBUSDQ_HPP_ - -#include #include - +#include namespace GridKit { - template class BaseBus; + template + class BaseBus; } - namespace GridKit { - /*! - * @brief Declaration of a MicrogridBusDQ class. - * - */ - template - class MicrogridBusDQ : public CircuitComponent - { - using CircuitComponent::size_; - using CircuitComponent::nnz_; - using CircuitComponent::time_; - using CircuitComponent::alpha_; - using CircuitComponent::y_; - using CircuitComponent::yp_; - using CircuitComponent::tag_; - using CircuitComponent::f_; - using CircuitComponent::g_; - using CircuitComponent::yB_; - using CircuitComponent::ypB_; - using CircuitComponent::fB_; - using CircuitComponent::gB_; - using CircuitComponent::jac_; - using CircuitComponent::param_; - using CircuitComponent::idc_; - - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + /*! + * @brief Declaration of a MicrogridBusDQ class. + * + */ + template + class MicrogridBusDQ : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::jac_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; - public: - MicrogridBusDQ(IdxT id, ScalarT RN); - virtual ~MicrogridBusDQ(); + public: + MicrogridBusDQ(IdxT id, ScalarT RN); + virtual ~MicrogridBusDQ(); - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); - - private: - ScalarT RN_; - }; -} + private: + ScalarT RN_; + }; +} // namespace GridKit #endif diff --git a/src/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp b/src/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp index 222b8871..030668ea 100644 --- a/src/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp +++ b/src/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp @@ -1,175 +1,168 @@ -#include +#include "MicrogridLine.hpp" + #include +#include #include -#include "MicrogridLine.hpp" -namespace GridKit { - -/*! - * @brief Constructor for a constant MicrogridLine model - * - * 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 - * - * @todo Consider having \omegaref as a global constant, not a node variable. - */ - -template -MicrogridLine::MicrogridLine(IdxT id, ScalarT R,ScalarT L) - : R_(R), - L_(L) +namespace GridKit { + + /*! + * @brief Constructor for a constant MicrogridLine model + * + * 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 + * + * @todo Consider having \omegaref as a global constant, not a node variable. + */ + + template + MicrogridLine::MicrogridLine(IdxT id, ScalarT R, ScalarT L) + : R_(R), + L_(L) + { // internals [id, iq] // externals [\omegaref, vbd_in, vbq_in, vbd_out, vbq_out] - size_ = 7; - n_intern_ = 2; - n_extern_ = 5; - extern_indices_ = {0,1,2,3,4}; - idc_ = id; -} - -template -MicrogridLine::~MicrogridLine() -{ -} - -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int MicrogridLine::allocate() -{ + size_ = 7; + n_intern_ = 2; + n_extern_ = 5; + extern_indices_ = {0, 1, 2, 3, 4}; + idc_ = id; + } + + template + MicrogridLine::~MicrogridLine() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int MicrogridLine::allocate() + { y_.resize(size_); yp_.resize(size_); f_.resize(size_); - - return 0; -} -/** - * Initialization of the grid model - */ -template -int MicrogridLine::initialize() -{ return 0; -} - -/* - * \brief Identify differential variables - */ -template -int MicrogridLine::tagDifferentiable() -{ + } + + /** + * Initialization of the grid model + */ + template + int MicrogridLine::initialize() + { return 0; -} - -/** - * @brief Evaluate residual of microgrid line - * - */ -template -int MicrogridLine::evaluateResidual() -{ - //ref motor + } + + /* + * \brief Identify differential variables + */ + template + int MicrogridLine::tagDifferentiable() + { + return 0; + } + + /** + * @brief Evaluate residual of microgrid line + * + */ + template + int MicrogridLine::evaluateResidual() + { + // ref motor f_[0] = 0.0; - //input - f_[1] = -y_[5] ; - f_[2] = -y_[6] ; + // input + f_[1] = -y_[5]; + f_[2] = -y_[6]; - //output - f_[3] = y_[5] ; - f_[4] = y_[6] ; - - //Internal variables - f_[5] = -yp_[5] - (R_ / L_) * y_[5] + y_[0]*y_[6] + (y_[1] - y_[3])/L_; - f_[6] = -yp_[6] - (R_ / L_) * y_[6] - y_[0]*y_[5] + (y_[2] - y_[4])/L_; + // output + f_[3] = y_[5]; + f_[4] = y_[6]; + // Internal variables + f_[5] = -yp_[5] - (R_ / L_) * y_[5] + y_[0] * y_[6] + (y_[1] - y_[3]) / L_; + f_[6] = -yp_[6] - (R_ / L_) * y_[6] - y_[0] * y_[5] + (y_[2] - y_[4]) / L_; return 0; -} - -/** - * @brief Generate Jacobian for Microgrid Line - * - * @tparam ScalarT - * @tparam IdxT - * @return int - */ -template -int MicrogridLine::evaluateJacobian() -{ + } + + /** + * @brief Generate Jacobian for Microgrid Line + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ + template + int MicrogridLine::evaluateJacobian() + { jac_.zeroMatrix(); - //Create dF/dy - std::vector rtemp{1,2,3,4}; - std::vector ctemp{5,6,5,6}; - std::vector vals{-1.0,-1.0,1.0,1.0}; + // Create dF/dy + std::vector rtemp{1, 2, 3, 4}; + std::vector ctemp{5, 6, 5, 6}; + std::vector vals{-1.0, -1.0, 1.0, 1.0}; jac_.setValues(rtemp, ctemp, vals); - std::vector ccord{0, 1, 3, 5, 6}; - std::vector rcord(ccord.size(),5); - vals = {y_[6], (1.0 / L_) , -(1.0 / L_), - (R_ / L_) , y_[0]}; + std::vector rcord(ccord.size(), 5); + vals = {y_[6], (1.0 / L_), -(1.0 / L_), -(R_ / L_), y_[0]}; jac_.setValues(rcord, ccord, vals); - std::vector ccor2{0, 2, 4, 5, 6}; std::fill(rcord.begin(), rcord.end(), 6); - vals = {-y_[5], (1.0 / L_) , -(1.0 / L_), -y_[0], - (R_ / L_)}; + vals = {-y_[5], (1.0 / L_), -(1.0 / L_), -y_[0], -(R_ / L_)}; jac_.setValues(rcord, ccor2, vals); + // Create -dF/dy' + std::vector rcordder{5, 6}; + std::vector ccordder{5, 6}; + std::vector valsder{-1.0, -1.0}; + COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder, 7, 7); - //Create -dF/dy' - std::vector rcordder{5,6}; - std::vector ccordder{5,6}; - std::vector valsder{-1.0, -1.0}; - COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,7,7); - - //Perform dF/dy + \alpha dF/dy' + // Perform dF/dy + \alpha dF/dy' jac_.axpy(alpha_, Jacder); - return 0; -} + } -template -int MicrogridLine::evaluateIntegrand() -{ + template + int MicrogridLine::evaluateIntegrand() + { return 0; -} + } -template -int MicrogridLine::initializeAdjoint() -{ + template + int MicrogridLine::initializeAdjoint() + { return 0; -} + } -template -int MicrogridLine::evaluateAdjointResidual() -{ + template + int MicrogridLine::evaluateAdjointResidual() + { return 0; -} + } -template -int MicrogridLine::evaluateAdjointIntegrand() -{ + template + int MicrogridLine::evaluateAdjointIntegrand() + { return 0; -} - - - -// Available template instantiations -template class MicrogridLine; -template class MicrogridLine; - + } -} //namespace GridKit + // Available template instantiations + template class MicrogridLine; + template class MicrogridLine; +} // namespace GridKit diff --git a/src/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp b/src/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp index 21e95178..14d29b85 100644 --- a/src/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp +++ b/src/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp @@ -3,66 +3,65 @@ #ifndef _TRANLINE_HPP_ #define _TRANLINE_HPP_ - -#include #include +#include namespace GridKit { - template - class BaseBus; + template + class BaseBus; } namespace GridKit { - /*! - * @brief Declaration of a MicrogridLine class. - * - */ - template - class MicrogridLine : public CircuitComponent - { - using CircuitComponent::size_; - using CircuitComponent::nnz_; - using CircuitComponent::time_; - using CircuitComponent::alpha_; - using CircuitComponent::y_; - using CircuitComponent::yp_; - using CircuitComponent::tag_; - using CircuitComponent::f_; - using CircuitComponent::g_; - using CircuitComponent::yB_; - using CircuitComponent::ypB_; - using CircuitComponent::fB_; - using CircuitComponent::gB_; - using CircuitComponent::jac_; - using CircuitComponent::param_; - using CircuitComponent::idc_; - - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + /*! + * @brief Declaration of a MicrogridLine class. + * + */ + template + class MicrogridLine : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::jac_; + using CircuitComponent::param_; + using CircuitComponent::idc_; - public: - MicrogridLine(IdxT id, ScalarT R, ScalarT L); - virtual ~MicrogridLine(); + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + public: + MicrogridLine(IdxT id, ScalarT R, ScalarT L); + virtual ~MicrogridLine(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); - private: - ScalarT R_; - ScalarT L_; - }; -} + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT R_; + ScalarT L_; + }; +} // namespace GridKit #endif diff --git a/src/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp b/src/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp index 9b4b8643..f36dd889 100644 --- a/src/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp +++ b/src/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp @@ -1,172 +1,163 @@ -#include +#include "MicrogridLoad.hpp" + #include +#include #include -#include "MicrogridLoad.hpp" -namespace GridKit { - -/*! - * @brief Constructor for a constant MicrogridLoad model - * - * 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 D - */ - -template -MicrogridLoad::MicrogridLoad(IdxT id, ScalarT R,ScalarT L) - : R_(R), - L_(L) +namespace GridKit { + + /*! + * @brief Constructor for a constant MicrogridLoad model + * + * 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 D + */ + + template + MicrogridLoad::MicrogridLoad(IdxT id, ScalarT R, ScalarT L) + : R_(R), + L_(L) + { // internals [id, iq] // externals [\omegaref, vbd_out, vbq_out] - size_ = 5; - n_intern_ = 2; - n_extern_ = 3; - extern_indices_ = {0,1,2}; - idc_ = id; - -} - -template -MicrogridLoad::~MicrogridLoad() -{ -} - -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int MicrogridLoad::allocate() -{ + size_ = 5; + n_intern_ = 2; + n_extern_ = 3; + extern_indices_ = {0, 1, 2}; + idc_ = id; + } + + template + MicrogridLoad::~MicrogridLoad() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int MicrogridLoad::allocate() + { y_.resize(size_); yp_.resize(size_); f_.resize(size_); - - return 0; -} -/** - * Initialization of the grid model - */ -template -int MicrogridLoad::initialize() -{ return 0; -} - -/* - * \brief Identify differential variables - */ -template -int MicrogridLoad::tagDifferentiable() -{ + } + + /** + * Initialization of the grid model + */ + template + int MicrogridLoad::initialize() + { return 0; -} - -/** - * @brief Eval Micro Load - */ -template -int MicrogridLoad::evaluateResidual() -{ - //ref motor + } + + /* + * \brief Identify differential variables + */ + template + int MicrogridLoad::tagDifferentiable() + { + return 0; + } + + /** + * @brief Eval Micro Load + */ + template + int MicrogridLoad::evaluateResidual() + { + // ref motor f_[0] = 0.0; - //only input for loads - - //input - f_[1] = -y_[3] ; - f_[2] = -y_[4] ; + // only input for loads - //Internal variables - f_[3] = -yp_[3] - (R_ / L_) * y_[3] + y_[0]*y_[4] + y_[1] / L_; - f_[4] = -yp_[4] - (R_ / L_) * y_[4] - y_[0]*y_[3] + y_[2] / L_; + // input + f_[1] = -y_[3]; + f_[2] = -y_[4]; + // Internal variables + f_[3] = -yp_[3] - (R_ / L_) * y_[3] + y_[0] * y_[4] + y_[1] / L_; + f_[4] = -yp_[4] - (R_ / L_) * y_[4] - y_[0] * y_[3] + y_[2] / L_; return 0; -} - -/** - * @brief Generate Jacobian for Micro Load - * - * @tparam ScalarT - * @tparam IdxT - * @return int - */ -template -int MicrogridLoad::evaluateJacobian() -{ + } + + /** + * @brief Generate Jacobian for Micro Load + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ + template + int MicrogridLoad::evaluateJacobian() + { jac_.zeroMatrix(); - //Create dF/dy - std::vector rtemp{1,2}; - std::vector ctemp{3,4}; - std::vector vals{-1.0,-1.0}; + // Create dF/dy + std::vector rtemp{1, 2}; + std::vector ctemp{3, 4}; + std::vector vals{-1.0, -1.0}; jac_.setValues(rtemp, ctemp, vals); - std::vector ccord{0, 1, 3, 4}; - std::vector rcord(ccord.size(),3); - vals = {y_[4], (1.0 / L_) , - (R_ / L_) , y_[0]}; + std::vector rcord(ccord.size(), 3); + vals = {y_[4], (1.0 / L_), -(R_ / L_), y_[0]}; jac_.setValues(rcord, ccord, vals); - std::vector ccor2{0, 2, 3, 4}; std::fill(rcord.begin(), rcord.end(), 4); - vals = {-y_[3], (1.0 / L_) , -y_[0], - (R_ / L_)}; + vals = {-y_[3], (1.0 / L_), -y_[0], -(R_ / L_)}; jac_.setValues(rcord, ccor2, vals); + // Create -dF/dy' + std::vector rcordder{3, 4}; + std::vector ccordder{3, 4}; + std::vector valsder{-1.0, -1.0}; + COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder, 5, 5); - //Create -dF/dy' - std::vector rcordder{3,4}; - std::vector ccordder{3,4}; - std::vector valsder{-1.0, -1.0}; - COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,5,5); - - //Perform dF/dy + \alpha dF/dy' + // Perform dF/dy + \alpha dF/dy' jac_.axpy(alpha_, Jacder); return 0; -} + } -template -int MicrogridLoad::evaluateIntegrand() -{ + template + int MicrogridLoad::evaluateIntegrand() + { return 0; -} + } -template -int MicrogridLoad::initializeAdjoint() -{ + template + int MicrogridLoad::initializeAdjoint() + { return 0; -} + } -template -int MicrogridLoad::evaluateAdjointResidual() -{ + template + int MicrogridLoad::evaluateAdjointResidual() + { return 0; -} + } -template -int MicrogridLoad::evaluateAdjointIntegrand() -{ + template + int MicrogridLoad::evaluateAdjointIntegrand() + { return 0; -} - - - - - -// Available template instantiations -template class MicrogridLoad; -template class MicrogridLoad; - + } -} //namespace GridKit + // Available template instantiations + template class MicrogridLoad; + template class MicrogridLoad; +} // namespace GridKit diff --git a/src/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp b/src/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp index 53d98e6d..685a0504 100644 --- a/src/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp +++ b/src/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp @@ -3,69 +3,65 @@ #ifndef _TRANLOAD_HPP_ #define _TRANLOAD_HPP_ - -#include #include - +#include namespace GridKit { - template class BaseBus; + template + class BaseBus; } - namespace GridKit { - /*! - * @brief Declaration of a passive MicrogridLoad class. - * - */ - template - class MicrogridLoad : public CircuitComponent - { - using CircuitComponent::size_; - using CircuitComponent::nnz_; - using CircuitComponent::time_; - using CircuitComponent::alpha_; - using CircuitComponent::y_; - using CircuitComponent::yp_; - using CircuitComponent::tag_; - using CircuitComponent::f_; - using CircuitComponent::g_; - using CircuitComponent::yB_; - using CircuitComponent::ypB_; - using CircuitComponent::fB_; - using CircuitComponent::gB_; - using CircuitComponent::jac_; - using CircuitComponent::param_; - using CircuitComponent::idc_; - - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + /*! + * @brief Declaration of a passive MicrogridLoad class. + * + */ + template + class MicrogridLoad : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::jac_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; - public: - MicrogridLoad(IdxT id, ScalarT R, ScalarT L); - virtual ~MicrogridLoad(); + public: + MicrogridLoad(IdxT id, ScalarT R, ScalarT L); + virtual ~MicrogridLoad(); - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); - - private: - ScalarT R_; - ScalarT L_; - }; -} + private: + ScalarT R_; + ScalarT L_; + }; +} // namespace GridKit #endif diff --git a/src/Model/PowerElectronics/Resistor/Resistor.cpp b/src/Model/PowerElectronics/Resistor/Resistor.cpp index 843d161d..6549ec12 100644 --- a/src/Model/PowerElectronics/Resistor/Resistor.cpp +++ b/src/Model/PowerElectronics/Resistor/Resistor.cpp @@ -1,126 +1,121 @@ +#include "Resistor.hpp" -#include #include +#include #include -#include "Resistor.hpp" -namespace GridKit { - -/*! - * @brief Constructor for a resistor model - * - * Calls default ModelEvaluatorImpl constructor. - */ - -template -Resistor::Resistor(IdxT id, ScalarT R) - : R_(R) -{ - size_ = 2; - n_intern_ = 0; - n_extern_ = 2; - extern_indices_ = {0,1}; - idc_ = id; -} - -template -Resistor::~Resistor() +namespace GridKit { -} -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int Resistor::allocate() -{ + /*! + * @brief Constructor for a resistor model + * + * Calls default ModelEvaluatorImpl constructor. + */ + + template + Resistor::Resistor(IdxT id, ScalarT R) + : R_(R) + { + size_ = 2; + n_intern_ = 0; + n_extern_ = 2; + extern_indices_ = {0, 1}; + idc_ = id; + } + + template + Resistor::~Resistor() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int Resistor::allocate() + { y_.resize(size_); yp_.resize(size_); f_.resize(size_); - - return 0; -} -/** - * Initialization of the grid model - */ -template -int Resistor::initialize() -{ return 0; -} - -/* - * \brief Identify differential variables - */ -template -int Resistor::tagDifferentiable() -{ + } + + /** + * Initialization of the grid model + */ + template + int Resistor::initialize() + { return 0; -} - -/** - * @brief Computes the resistors resisdual - * - */ -template -int Resistor::evaluateResidual() -{ - //input - f_[0] = (y_[0] - y_[1])/R_ ; - //ouput - f_[1] = (y_[1] - y_[0])/R_ ; + } + + /* + * \brief Identify differential variables + */ + template + int Resistor::tagDifferentiable() + { return 0; -} + } + + /** + * @brief Computes the resistors resisdual + * + */ + template + int Resistor::evaluateResidual() + { + // input + f_[0] = (y_[0] - y_[1]) / R_; + // ouput + f_[1] = (y_[1] - y_[0]) / R_; + return 0; + } -template -int Resistor::evaluateJacobian() -{ - - //Create dF/dy - //does compiler make constant??? - std::vector rcord{0,0,1,1}; - std::vector ccord{0,1,0,1}; + template + int Resistor::evaluateJacobian() + { + + // Create dF/dy + // does compiler make constant??? + std::vector rcord{0, 0, 1, 1}; + std::vector ccord{0, 1, 0, 1}; std::vector vals{1.0 / R_, -1.0 / R_, -1.0 / R_, 1.0 / R_}; jac_.setValues(rcord, ccord, vals); return 0; -} + } -template -int Resistor::evaluateIntegrand() -{ + template + int Resistor::evaluateIntegrand() + { return 0; -} + } -template -int Resistor::initializeAdjoint() -{ + template + int Resistor::initializeAdjoint() + { return 0; -} + } -template -int Resistor::evaluateAdjointResidual() -{ + template + int Resistor::evaluateAdjointResidual() + { return 0; -} + } -template -int Resistor::evaluateAdjointIntegrand() -{ + template + int Resistor::evaluateAdjointIntegrand() + { return 0; -} - - - - - -// Available template instantiations -template class Resistor; -template class Resistor; - + } -} //namespace GridKit + // Available template instantiations + template class Resistor; + template class Resistor; +} // namespace GridKit diff --git a/src/Model/PowerElectronics/Resistor/Resistor.hpp b/src/Model/PowerElectronics/Resistor/Resistor.hpp index 942ec24b..0821b992 100644 --- a/src/Model/PowerElectronics/Resistor/Resistor.hpp +++ b/src/Model/PowerElectronics/Resistor/Resistor.hpp @@ -3,69 +3,64 @@ #ifndef _RES_HPP_ #define _RES_HPP_ - -#include #include - +#include namespace GridKit { - template class BaseBus; + template + class BaseBus; } - namespace GridKit { - /*! - * @brief Declaration of a Resistor class. - * - */ - template - class Resistor : public CircuitComponent - { - using CircuitComponent::size_; - using CircuitComponent::nnz_; - using CircuitComponent::time_; - using CircuitComponent::alpha_; - using CircuitComponent::y_; - using CircuitComponent::yp_; - using CircuitComponent::tag_; - using CircuitComponent::f_; - using CircuitComponent::g_; - using CircuitComponent::yB_; - using CircuitComponent::ypB_; - using CircuitComponent::fB_; - using CircuitComponent::gB_; - using CircuitComponent::jac_; - using CircuitComponent::param_; - using CircuitComponent::idc_; - - - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + /*! + * @brief Declaration of a Resistor class. + * + */ + template + class Resistor : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::jac_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; - public: - Resistor(IdxT id, ScalarT R); - virtual ~Resistor(); + public: + Resistor(IdxT id, ScalarT R); + virtual ~Resistor(); - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); - - private: - ScalarT R_; - }; -} + private: + ScalarT R_; + }; +} // namespace GridKit #endif diff --git a/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp b/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp index 6a3e6b52..c34db3b9 100644 --- a/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp +++ b/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp @@ -1,168 +1,161 @@ -#include -#include -#include #include "SynchronousMachine.hpp" +#include +#include +#include -namespace GridKit { - - - -/*! - * @brief Constructor for a constant SynchronousMachine model - * - * Calls default ModelEvaluatorImpl constructor. - * @todo This model's equations are not finished - * @todo needs to be tested for correctness - * - * @tparam ScalarT - floating point type for the model - * @tparam IdxT - integer index type for the model - * - * @param[in] id - unique identifier for the component - * @param[in] Lls - stator leakage inductance - * @param[in] Llkq - tuple of damper leakage reactances - * @param[in] Llfd - field leakage reactance - * @param[in] Llkd - damper leakage reactance - * @param[in] Lmq - quadrature axis magnetizing reactance - * @param[in] Lmd - direct axis magnetizing reactance - * @param[in] Rs - stator resistance - * @param[in] Rkq - tuple of damper resistances - * @param[in] Rfd - field resistance - * @param[in] Rkd - damper resistance - * @param[in] RJ - rotor moment of inertia - * @param[in] P - number of poles - * @param[in] mub - rated frequency - */ - -template -SynchronousMachine::SynchronousMachine(IdxT id, ScalarT Lls, std::tuple Llkq, ScalarT Llfd, ScalarT Llkd, ScalarT Lmq, ScalarT Lmd, ScalarT Rs, std::tuple Rkq, ScalarT Rfd, ScalarT Rkd, ScalarT RJ, ScalarT P, ScalarT mub) - : Lls_(Lls), - Llkq_(Llkq), - Llfd_(Llfd), - Llkd_(Llkd), - Lmq_(Lmq), - Lmd_(Lmd), - Rs_(Rs), - Rkq_(Rkq), - Rfd_(Rfd), - Rkd_(Rkd), - RJ_(RJ), - P_(P), - mub_(mub) +namespace GridKit { - size_ = 13; - n_intern_ = 6; - n_extern_ = 7; - extern_indices_ = {0,1,2,3,4}; - idc_ = id; -} - -template -SynchronousMachine::~SynchronousMachine() -{ -} -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int SynchronousMachine::allocate() -{ + /*! + * @brief Constructor for a constant SynchronousMachine model + * + * Calls default ModelEvaluatorImpl constructor. + * @todo This model's equations are not finished + * @todo needs to be tested for correctness + * + * @tparam ScalarT - floating point type for the model + * @tparam IdxT - integer index type for the model + * + * @param[in] id - unique identifier for the component + * @param[in] Lls - stator leakage inductance + * @param[in] Llkq - tuple of damper leakage reactances + * @param[in] Llfd - field leakage reactance + * @param[in] Llkd - damper leakage reactance + * @param[in] Lmq - quadrature axis magnetizing reactance + * @param[in] Lmd - direct axis magnetizing reactance + * @param[in] Rs - stator resistance + * @param[in] Rkq - tuple of damper resistances + * @param[in] Rfd - field resistance + * @param[in] Rkd - damper resistance + * @param[in] RJ - rotor moment of inertia + * @param[in] P - number of poles + * @param[in] mub - rated frequency + */ + + template + SynchronousMachine::SynchronousMachine(IdxT id, ScalarT Lls, std::tuple Llkq, ScalarT Llfd, ScalarT Llkd, ScalarT Lmq, ScalarT Lmd, ScalarT Rs, std::tuple Rkq, ScalarT Rfd, ScalarT Rkd, ScalarT RJ, ScalarT P, ScalarT mub) + : Lls_(Lls), + Llkq_(Llkq), + Llfd_(Llfd), + Llkd_(Llkd), + Lmq_(Lmq), + Lmd_(Lmd), + Rs_(Rs), + Rkq_(Rkq), + Rfd_(Rfd), + Rkd_(Rkd), + RJ_(RJ), + P_(P), + mub_(mub) + { + size_ = 13; + n_intern_ = 6; + n_extern_ = 7; + extern_indices_ = {0, 1, 2, 3, 4}; + idc_ = id; + } + + template + SynchronousMachine::~SynchronousMachine() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int SynchronousMachine::allocate() + { y_.resize(size_); yp_.resize(size_); f_.resize(size_); return 0; -} - -/** - * Initialization of the grid model - */ -template -int SynchronousMachine::initialize() -{ + } + + /** + * Initialization of the grid model + */ + template + int SynchronousMachine::initialize() + { return 0; -} - -/* - * \brief Identify differential variables - */ -template -int SynchronousMachine::tagDifferentiable() -{ + } + + /* + * \brief Identify differential variables + */ + template + int SynchronousMachine::tagDifferentiable() + { return 0; -} - -/** - * @brief Compute the resisdual of the component. - * - * @todo not finished - */ -template -int SynchronousMachine::evaluateResidual() -{ - ScalarT rkq1 = std::get<0>(Rkq_); - ScalarT rkq2 = std::get<1>(Rkq_); + } + + /** + * @brief Compute the resisdual of the component. + * + * @todo not finished + */ + template + int SynchronousMachine::evaluateResidual() + { + ScalarT rkq1 = std::get<0>(Rkq_); + ScalarT rkq2 = std::get<1>(Rkq_); ScalarT llkq1 = std::get<0>(Llkq_); ScalarT llkq2 = std::get<1>(Llkq_); - ScalarT cos1 = cos((P_/2.0)*y_[5]); - ScalarT sin1 = sin((P_/2.0)*y_[5]); - ScalarT cos23m = cos((P_/2.0)*y_[5] - (2.0/3.0)*M_PI); - ScalarT sin23m = sin((P_/2.0)*y_[5] - (2.0/3.0)*M_PI); - ScalarT cos23p = cos((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); - ScalarT sin23p = sin((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); - - f_[0] = y_[6]*cos1 + y_[7]*sin1 + y_[8]; - f_[1] = y_[6]*cos23m + y_[7]*sin23m + y_[8]; - f_[2] = y_[6]*cos23p + y_[7]*sin23p + y_[8]; - f_[3] = RJ_ * yp_[4] - (3.0/4.0)*P_*(Lmd_ *y_[6]* (y_[7] + y_[11] + y_[12]) - Lmq_*y_[7]*(y_[6] + y_[9] + y_[0])); + ScalarT cos1 = cos((P_ / 2.0) * y_[5]); + ScalarT sin1 = sin((P_ / 2.0) * y_[5]); + ScalarT cos23m = cos((P_ / 2.0) * y_[5] - (2.0 / 3.0) * M_PI); + ScalarT sin23m = sin((P_ / 2.0) * y_[5] - (2.0 / 3.0) * M_PI); + ScalarT cos23p = cos((P_ / 2.0) * y_[5] + (2.0 / 3.0) * M_PI); + ScalarT sin23p = sin((P_ / 2.0) * y_[5] + (2.0 / 3.0) * M_PI); + + f_[0] = y_[6] * cos1 + y_[7] * sin1 + y_[8]; + f_[1] = y_[6] * cos23m + y_[7] * sin23m + y_[8]; + f_[2] = y_[6] * cos23p + y_[7] * sin23p + y_[8]; + f_[3] = RJ_ * yp_[4] - (3.0 / 4.0) * P_ * (Lmd_ * y_[6] * (y_[7] + y_[11] + y_[12]) - Lmq_ * y_[7] * (y_[6] + y_[9] + y_[0])); f_[4] = yp_[5] - y_[4]; - f_[5] = (-2.0/3.0)*(y_[0]*cos1 +y_[1]*cos23m + y_[2]*cos23p) + Rs_*y_[6] + (Lls_ + Lmq_)*yp_[6] + Lmq_*yp_[9] + Lmq_*yp_[10] + y_[4]*(P_/2.0)*((Lls_ + Lmd_)*y_[7] + Lmd_*y_[11] + Lmd_*y_[12]); - f_[6] = (-2.0/3.0)*(y_[0]*sin1 -y_[1]*sin23m - y_[2]*sin23p) + Rs_*y_[7] + (Lls_ + Lmd_)*yp_[7] + Lmd_*yp_[11] + Lmd_*yp_[12] - y_[4]*(P_/2.0)*((Lls_ + Lmq_)*y_[6] + Lmq_*y_[9] + Lmq_*y_[10]); - f_[7] = (-1.0/3.0)*(y_[0] + y_[1] + y_[2]) + Rs_*y_[8] + Lls_*yp_[8]; - f_[8] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; - f_[9] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; + f_[5] = (-2.0 / 3.0) * (y_[0] * cos1 + y_[1] * cos23m + y_[2] * cos23p) + Rs_ * y_[6] + (Lls_ + Lmq_) * yp_[6] + Lmq_ * yp_[9] + Lmq_ * yp_[10] + y_[4] * (P_ / 2.0) * ((Lls_ + Lmd_) * y_[7] + Lmd_ * y_[11] + Lmd_ * y_[12]); + f_[6] = (-2.0 / 3.0) * (y_[0] * sin1 - y_[1] * sin23m - y_[2] * sin23p) + Rs_ * y_[7] + (Lls_ + Lmd_) * yp_[7] + Lmd_ * yp_[11] + Lmd_ * yp_[12] - y_[4] * (P_ / 2.0) * ((Lls_ + Lmq_) * y_[6] + Lmq_ * y_[9] + Lmq_ * y_[10]); + f_[7] = (-1.0 / 3.0) * (y_[0] + y_[1] + y_[2]) + Rs_ * y_[8] + Lls_ * yp_[8]; + f_[8] = rkq1 * y_[9] + (llkq1 + Lmq_) * yp_[9] + Lmq_ * yp_[6] + Lmq_ * yp_[10]; + f_[9] = rkq1 * y_[9] + (llkq1 + Lmq_) * yp_[9] + Lmq_ * yp_[6] + Lmq_ * yp_[10]; return 0; -} + } -template -int SynchronousMachine::evaluateJacobian() -{ + template + int SynchronousMachine::evaluateJacobian() + { return 0; -} + } -template -int SynchronousMachine::evaluateIntegrand() -{ + template + int SynchronousMachine::evaluateIntegrand() + { return 0; -} + } -template -int SynchronousMachine::initializeAdjoint() -{ + template + int SynchronousMachine::initializeAdjoint() + { return 0; -} + } -template -int SynchronousMachine::evaluateAdjointResidual() -{ + template + int SynchronousMachine::evaluateAdjointResidual() + { return 0; -} + } -template -int SynchronousMachine::evaluateAdjointIntegrand() -{ + template + int SynchronousMachine::evaluateAdjointIntegrand() + { return 0; -} - - - - - -// Available template instantiations -template class SynchronousMachine; -template class SynchronousMachine; - + } -} //namespace GridKit + // Available template instantiations + template class SynchronousMachine; + template class SynchronousMachine; +} // namespace GridKit diff --git a/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp b/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp index 08401004..74766d15 100644 --- a/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp +++ b/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp @@ -3,79 +3,78 @@ #ifndef _SYNMACH_HPP_ #define _SYNMACH_HPP_ - -#include -#include #include +#include +#include namespace GridKit { - template class BaseBus; + template + class BaseBus; } - namespace GridKit { - /*! - * @brief Declaration of a SynchronousMachine class. - * - */ - template - class SynchronousMachine : public CircuitComponent - { - using CircuitComponent::size_; - using CircuitComponent::nnz_; - using CircuitComponent::time_; - using CircuitComponent::alpha_; - using CircuitComponent::y_; - using CircuitComponent::yp_; - using CircuitComponent::tag_; - using CircuitComponent::f_; - using CircuitComponent::g_; - using CircuitComponent::yB_; - using CircuitComponent::ypB_; - using CircuitComponent::fB_; - using CircuitComponent::gB_; - using CircuitComponent::jac_; - using CircuitComponent::param_; - using CircuitComponent::idc_; + /*! + * @brief Declaration of a SynchronousMachine class. + * + */ + template + class SynchronousMachine : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::jac_; + using CircuitComponent::param_; + using CircuitComponent::idc_; - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; - public: - SynchronousMachine(IdxT id, ScalarT Lls, std::tuple Llkq, ScalarT Llfd, ScalarT Llkd, ScalarT Lmq, ScalarT Lmd, ScalarT Rs, std::tuple Rkq, ScalarT Rfd, ScalarT Rkd, ScalarT RJ, ScalarT P, ScalarT mub); - virtual ~SynchronousMachine(); + public: + SynchronousMachine(IdxT id, ScalarT Lls, std::tuple Llkq, ScalarT Llfd, ScalarT Llkd, ScalarT Lmq, ScalarT Lmd, ScalarT Rs, std::tuple Rkq, ScalarT Rfd, ScalarT Rkd, ScalarT RJ, ScalarT P, ScalarT mub); + virtual ~SynchronousMachine(); - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - private: - ScalarT Lls_; - std::tuple Llkq_; - ScalarT Llfd_; - ScalarT Llkd_; - ScalarT Lmq_; - ScalarT Lmd_; - ScalarT Rs_; - std::tuple Rkq_; - ScalarT Rfd_; - ScalarT Rkd_; - ScalarT RJ_; - ScalarT P_; - ScalarT mub_; - }; -} + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT Lls_; + std::tuple Llkq_; + ScalarT Llfd_; + ScalarT Llkd_; + ScalarT Lmq_; + ScalarT Lmd_; + ScalarT Rs_; + std::tuple Rkq_; + ScalarT Rfd_; + ScalarT Rkd_; + ScalarT RJ_; + ScalarT P_; + ScalarT mub_; + }; +} // namespace GridKit #endif diff --git a/src/Model/PowerElectronics/SystemModelPowerElectronics.hpp b/src/Model/PowerElectronics/SystemModelPowerElectronics.hpp index 66edae0d..10548309 100644 --- a/src/Model/PowerElectronics/SystemModelPowerElectronics.hpp +++ b/src/Model/PowerElectronics/SystemModelPowerElectronics.hpp @@ -2,340 +2,339 @@ #pragma once +#include #include #include -#include -#include #include #include +#include namespace GridKit { - template - class PowerElectronicsModel : public CircuitComponent + template + class PowerElectronicsModel : public CircuitComponent + { + typedef CircuitComponent component_type; + + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::f_; + using CircuitComponent::jac_; + using CircuitComponent::rel_tol_; + using CircuitComponent::abs_tol_; + + public: + /** + * @brief Default constructor for the system model + * + * @post System model parameters set as default + */ + PowerElectronicsModel() { - typedef CircuitComponent component_type; - - using CircuitComponent::size_; - using CircuitComponent::nnz_; - using CircuitComponent::time_; - using CircuitComponent::alpha_; - using CircuitComponent::y_; - using CircuitComponent::yp_; - using CircuitComponent::f_; - using CircuitComponent::jac_; - using CircuitComponent::rel_tol_; - using CircuitComponent::abs_tol_; - - public: - /** - * @brief Default constructor for the system model - * - * @post System model parameters set as default - */ - PowerElectronicsModel() - { - // Set system model parameters as default - rel_tol_ = 1e-4; - abs_tol_ = 1e-4; - this->max_steps_ = 2000; - // By default don't use the jacobian - use_jac_ = false; - } - - /** - * @brief Constructor for the system model - * - * @param[in] rel_tol Relative tolerance for the system model - * @param[in] abs_tol Absolute tolerance for the system model - * @param[in] use_jac Boolean to choose if to use jacobian - * @param[in] max_steps Maximum number of steps for the system model - * - * @post System model parameters set as input - */ - PowerElectronicsModel(double rel_tol = 1e-4, - double abs_tol = 1e-4, - bool use_jac = false, - IdxT max_steps = 2000) - { - // Set system model tolerances from input - rel_tol_ = rel_tol; - abs_tol_ = abs_tol; - this->max_steps_ = max_steps; - // Can choose if to use jacobian - use_jac_ = use_jac; - } - - /** - * @brief Destructor for the system model - * - * @pre System components are allocated - * - * @post System components are deallocated - * - */ - virtual ~PowerElectronicsModel() - { - for (auto comp : this->components_) - delete comp; - } - - /** - * @brief allocator default - * - * @todo this should throw an exception as no allocation without a graph is allowed. - * Or needs to be removed from the base class - * - * @return int - */ - int allocate() - { - return 1; - } - - /** - * @brief Will check if each component has jacobian avalible. If one doesn't have it, return false. - * - * - * @return true if all components have jacobian - * @return false otherwise - */ - bool hasJacobian() - { - if (!this->use_jac_) - return false; - - for (const auto &component : components_) - { - if (!component->hasJacobian()) - { - return false; - } - } - return true; - } + // Set system model parameters as default + rel_tol_ = 1e-4; + abs_tol_ = 1e-4; + this->max_steps_ = 2000; + // By default don't use the jacobian + use_jac_ = false; + } + + /** + * @brief Constructor for the system model + * + * @param[in] rel_tol Relative tolerance for the system model + * @param[in] abs_tol Absolute tolerance for the system model + * @param[in] use_jac Boolean to choose if to use jacobian + * @param[in] max_steps Maximum number of steps for the system model + * + * @post System model parameters set as input + */ + PowerElectronicsModel(double rel_tol = 1e-4, + double abs_tol = 1e-4, + bool use_jac = false, + IdxT max_steps = 2000) + { + // Set system model tolerances from input + rel_tol_ = rel_tol; + abs_tol_ = abs_tol; + this->max_steps_ = max_steps; + // Can choose if to use jacobian + use_jac_ = use_jac; + } + + /** + * @brief Destructor for the system model + * + * @pre System components are allocated + * + * @post System components are deallocated + * + */ + virtual ~PowerElectronicsModel() + { + for (auto comp : this->components_) + delete comp; + } + + /** + * @brief allocator default + * + * @todo this should throw an exception as no allocation without a graph is allowed. + * Or needs to be removed from the base class + * + * @return int + */ + int allocate() + { + return 1; + } + + /** + * @brief Will check if each component has jacobian avalible. If one doesn't have it, return false. + * + * + * @return true if all components have jacobian + * @return false otherwise + */ + bool hasJacobian() + { + if (!this->use_jac_) + return false; - /** - * @brief Allocate the vector data with size amount - * @todo Add capability to go through component model connection to get the size of the actual vector - * - * @param[in] s size of the vector - * - * @post System model vectors allocated with size s - * - * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable - */ - int allocate(IdxT s) + for (const auto& component : components_) + { + if (!component->hasJacobian()) { - // Allocate all components - size_ = s; - for (const auto &component : components_) - { - component->allocate(); - } - - // Allocate global vectors - y_.resize(size_); - yp_.resize(size_); - f_.resize(size_); - - return 0; + return false; } - - /** - * @brief Set intial y and y' of each component - * - * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable - */ - int initialize() + } + return true; + } + + /** + * @brief Allocate the vector data with size amount + * @todo Add capability to go through component model connection to get the size of the actual vector + * + * @param[in] s size of the vector + * + * @post System model vectors allocated with size s + * + * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable + */ + int allocate(IdxT s) + { + // Allocate all components + size_ = s; + for (const auto& component : components_) + { + component->allocate(); + } + + // Allocate global vectors + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); + + return 0; + } + + /** + * @brief Set intial y and y' of each component + * + * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable + */ + int initialize() + { + // Initialize components + for (const auto& component : components_) + { + component->initialize(); + } + this->distributeVectors(); + + return 0; + } + + /** + * @brief Distribute y and y' to each component based of node connection graph + * + * @post Each component has y and y' set + * + * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable + */ + int distributeVectors() + { + for (const auto& component : components_) + { + for (IdxT j = 0; j < component->size(); ++j) { - // Initialize components - for (const auto &component : components_) - { - component->initialize(); - } - this->distributeVectors(); - - return 0; + if (component->getNodeConnection(j) != neg1_) + { + component->y()[j] = y_[component->getNodeConnection(j)]; + component->yp()[j] = yp_[component->getNodeConnection(j)]; + } + else + { + component->y()[j] = 0.0; + component->yp()[j] = 0.0; + } } + } + return 0; + } - /** - * @brief Distribute y and y' to each component based of node connection graph - * - * @post Each component has y and y' set - * - * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable - */ - int distributeVectors() - { - for (const auto &component : components_) - { - for (IdxT j = 0; j < component->size(); ++j) - { - if (component->getNodeConnection(j) != neg1_) - { - component->y()[j] = y_[component->getNodeConnection(j)]; - component->yp()[j] = yp_[component->getNodeConnection(j)]; - } - else - { - component->y()[j] = 0.0; - component->yp()[j] = 0.0; - } - } - } - return 0; - } + int tagDifferentiable() + { + return 0; + } + + /** + * @brief Evaluate Residuals at each component then collect them + * + * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable + */ + int evaluateResidual() + { + for (IdxT i = 0; i < this->f_.size(); i++) + { + f_[i] = 0.0; + } - int tagDifferentiable() - { - return 0; - } + this->distributeVectors(); - /** - * @brief Evaluate Residuals at each component then collect them - * - * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable - */ - int evaluateResidual() - { - for (IdxT i = 0; i < this->f_.size(); i++) - { - f_[i] = 0.0; - } - - this->distributeVectors(); - - // Update system residual vector - - for (const auto &component : components_) - { - // TODO:check return type - component->evaluateResidual(); - for (IdxT j = 0; j < component->size(); ++j) - { - //@todo should do a different grounding check - if (component->getNodeConnection(j) != neg1_) - { - f_[component->getNodeConnection(j)] += component->getResidual()[j]; - } - } - } - - return 0; - } + // Update system residual vector - /** - * @brief Creates the Sparse COO Jacobian representing \alpha dF/dy' + dF/dy - * - * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable - */ - int evaluateJacobian() + for (const auto& component : components_) + { + // TODO:check return type + component->evaluateResidual(); + for (IdxT j = 0; j < component->size(); ++j) { - jac_.zeroMatrix(); - distributeVectors(); - - // Evaluate component jacs - for (const auto &component : components_) - { - component->evaluateJacobian(); - - // get references to local jacobian - std::tuple&, std::vector&, std::vector&> tpm = component->getJacobian().getEntries(); - const auto& [r, c, v] = tpm; - - // Create copies of data to handle groundings - std::vector rgr; - std::vector cgr; - std::vector vgr; - for (IdxT i = 0; i < static_cast(r.size()); i++) - { - if (component->getNodeConnection(r[i]) != neg1_ && component->getNodeConnection(c[i]) != neg1_) - { - rgr.push_back(component->getNodeConnection(r[i])); - cgr.push_back(component->getNodeConnection(c[i])); - vgr.push_back(v[i]); - } - } - - // AXPY to Global Jacobian - // elementwise jac_(rgr, cgr) += vgr - jac_.axpy(1.0, rgr, cgr, vgr); - } - - return 0; + //@todo should do a different grounding check + if (component->getNodeConnection(j) != neg1_) + { + f_[component->getNodeConnection(j)] += component->getResidual()[j]; + } } + } - /** - * @brief Evaluate integrands for the system quadratures. - */ - int evaluateIntegrand() - { - - return 0; - } + return 0; + } - /** - * @brief Initialize system adjoint. - * - * Updates variables and optimization parameters, then initializes - * adjoints locally and copies them to the system adjoint vector. - */ - int initializeAdjoint() + /** + * @brief Creates the Sparse COO Jacobian representing \alpha dF/dy' + dF/dy + * + * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable + */ + int evaluateJacobian() + { + jac_.zeroMatrix(); + distributeVectors(); + + // Evaluate component jacs + for (const auto& component : components_) + { + component->evaluateJacobian(); + + // get references to local jacobian + std::tuple&, std::vector&, std::vector&> tpm = component->getJacobian().getEntries(); + const auto& [r, c, v] = tpm; + + // Create copies of data to handle groundings + std::vector rgr; + std::vector cgr; + std::vector vgr; + for (IdxT i = 0; i < static_cast(r.size()); i++) { - return 0; + if (component->getNodeConnection(r[i]) != neg1_ && component->getNodeConnection(c[i]) != neg1_) + { + rgr.push_back(component->getNodeConnection(r[i])); + cgr.push_back(component->getNodeConnection(c[i])); + vgr.push_back(v[i]); + } } - /** - * @brief Compute adjoint residual for the system model. - * - * - */ - int evaluateAdjointResidual() - { - return 0; - } + // AXPY to Global Jacobian + // elementwise jac_(rgr, cgr) += vgr + jac_.axpy(1.0, rgr, cgr, vgr); + } - /** - * @brief Evaluate adjoint integrand for the system model. - * - * - */ - int evaluateAdjointIntegrand() - { - return 0; - } + return 0; + } - /** - * @brief Distribute time and time scaling for each component - * - * @param t - * @param a - */ - void updateTime(ScalarT t, ScalarT a) - { - for (const auto &component : components_) - { - component->updateTime(t, a); - } - time_ = t; - alpha_ = a; - } + /** + * @brief Evaluate integrands for the system quadratures. + */ + int evaluateIntegrand() + { - void addComponent(component_type *component) - { - components_.push_back(component); - } + return 0; + } - private: + /** + * @brief Initialize system adjoint. + * + * Updates variables and optimization parameters, then initializes + * adjoints locally and copies them to the system adjoint vector. + */ + int initializeAdjoint() + { + return 0; + } + + /** + * @brief Compute adjoint residual for the system model. + * + * + */ + int evaluateAdjointResidual() + { + return 0; + } + + /** + * @brief Evaluate adjoint integrand for the system model. + * + * + */ + int evaluateAdjointIntegrand() + { + return 0; + } + + /** + * @brief Distribute time and time scaling for each component + * + * @param t + * @param a + */ + void updateTime(ScalarT t, ScalarT a) + { + for (const auto& component : components_) + { + component->updateTime(t, a); + } + time_ = t; + alpha_ = a; + } + + void addComponent(component_type* component) + { + components_.push_back(component); + } - static constexpr IdxT neg1_ = static_cast(-1); + private: + static constexpr IdxT neg1_ = static_cast(-1); - std::vector components_; - bool use_jac_; + std::vector components_; + bool use_jac_; - }; // class PowerElectronicsModel + }; // class PowerElectronicsModel } // namespace GridKit diff --git a/src/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp b/src/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp index b836217a..85ec9151 100644 --- a/src/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp +++ b/src/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp @@ -1,205 +1,196 @@ -#include +#include "TransmissionLine.hpp" + #include +#include #include -#include "TransmissionLine.hpp" -namespace GridKit { - -/*! - * @brief Constructor for a TransmissionLine model - * - * 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 - * @todo needs to used in a model - * @todo test for correctness - */ - -template -TransmissionLine::TransmissionLine(IdxT id, ScalarT R,ScalarT X, ScalarT B) - : R_(R), - X_(X), - B_(B) +namespace GridKit { + + /*! + * @brief Constructor for a TransmissionLine model + * + * 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 + * @todo needs to used in a model + * @todo test for correctness + */ + + template + TransmissionLine::TransmissionLine(IdxT id, ScalarT R, ScalarT X, ScalarT B) + : R_(R), + X_(X), + B_(B) + { // internals [Iret1, Iimt1, Iret2, Iimt2] // externals [Vre11, Vim11, Vre12, Vim12, Vre21, Vim21, Vre22, Vim22] - size_ = 12; - n_intern_ = 4; - n_extern_ = 8; - extern_indices_ = {0,1,2,3,4,5,6,7}; - idc_ = id; - - ScalarT magImpendence = 1 / (R_*R_ + X_*X_); - YReMat_ = magImpendence * R_; - YImMatOff_ = magImpendence * X_; - YImMatDi_ = B_ / (2.0) - YImMatOff_; -} - -template -TransmissionLine::~TransmissionLine() -{ -} - -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int TransmissionLine::allocate() -{ + size_ = 12; + n_intern_ = 4; + n_extern_ = 8; + extern_indices_ = {0, 1, 2, 3, 4, 5, 6, 7}; + idc_ = id; + + ScalarT magImpendence = 1 / (R_ * R_ + X_ * X_); + YReMat_ = magImpendence * R_; + YImMatOff_ = magImpendence * X_; + YImMatDi_ = B_ / (2.0) - YImMatOff_; + } + + template + TransmissionLine::~TransmissionLine() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int TransmissionLine::allocate() + { y_.resize(size_); yp_.resize(size_); f_.resize(size_); - - return 0; -} -/** - * Initialization of the grid model - */ -template -int TransmissionLine::initialize() -{ return 0; -} - -/* - * \brief Identify differential variables - */ -template -int TransmissionLine::tagDifferentiable() -{ + } + + /** + * Initialization of the grid model + */ + template + int TransmissionLine::initialize() + { return 0; -} - -/** - * @brief Evaluate residual of transmission line - * - * The complex admittance matrix is: - * [[ Y/2 + 1/Z, -1/Z]; - * [ -1/Z, Y/2 + 1/Z]] = - * [[R/|Z|, -R/|Z|]; - * [-R/|Z|, R/|Z|]] + - * i [[B/2 - X/|Z|, X/|Z|]; - * [X/|Z|, B/2 - X/|Z|]] - * = Dre + i Dim - * - * Then - * 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 - */ -template -int TransmissionLine::evaluateResidual() -{ - //input - f_[0] = y_[8] ; - f_[1] = y_[9] ; - - f_[2] = y_[10] ; - f_[3] = y_[11] ; - //ouput - f_[4] = -y_[8] ; - f_[5] = -y_[9] ; - - f_[6] = -y_[10] ; - f_[7] = -y_[11] ; - - //Voltage drop accross terminals + } + + /* + * \brief Identify differential variables + */ + template + int TransmissionLine::tagDifferentiable() + { + return 0; + } + + /** + * @brief Evaluate residual of transmission line + * + * The complex admittance matrix is: + * [[ Y/2 + 1/Z, -1/Z]; + * [ -1/Z, Y/2 + 1/Z]] = + * [[R/|Z|, -R/|Z|]; + * [-R/|Z|, R/|Z|]] + + * i [[B/2 - X/|Z|, X/|Z|]; + * [X/|Z|, B/2 - X/|Z|]] + * = Dre + i Dim + * + * Then + * 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 + */ + template + int TransmissionLine::evaluateResidual() + { + // input + f_[0] = y_[8]; + f_[1] = y_[9]; + + f_[2] = y_[10]; + f_[3] = y_[11]; + // ouput + f_[4] = -y_[8]; + f_[5] = -y_[9]; + + f_[6] = -y_[10]; + f_[7] = -y_[11]; + + // Voltage drop accross terminals ScalarT V1re = y_[0] - y_[4]; ScalarT V1im = y_[1] - y_[5]; ScalarT V2re = y_[2] - y_[6]; ScalarT V2im = y_[3] - y_[7]; - //Internal variables - //row 1 - f_[8] = YReMat_ * (V1re - V2re) - (YImMatDi_ * V1im + YImMatOff_ * V2im) - y_[8] ; - f_[9] = YReMat_ * (V1im - V2im) + (YImMatDi_ * V1re + YImMatOff_ * V2re) - y_[9] ; + // Internal variables + // row 1 + f_[8] = YReMat_ * (V1re - V2re) - (YImMatDi_ * V1im + YImMatOff_ * V2im) - y_[8]; + f_[9] = YReMat_ * (V1im - V2im) + (YImMatDi_ * V1re + YImMatOff_ * V2re) - y_[9]; - //row2 + // row2 f_[10] = YReMat_ * (V2re - V1re) - (YImMatOff_ * V1im + YImMatDi_ * V2im) - y_[10]; f_[11] = YReMat_ * (V2im - V1im) + (YImMatOff_ * V1re + YImMatDi_ * V2re) - y_[11]; - return 0; -} - -/** - * @brief Generate Jacobian for Transmission Line - * - * @tparam ScalarT - * @tparam IdxT - * @return int - */ -template -int TransmissionLine::evaluateJacobian() -{ - - //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}; + } + + /** + * @brief Generate Jacobian for Transmission Line + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ + template + int TransmissionLine::evaluateJacobian() + { + + // 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}; jac_.setValues(rtemp, ctemp, vals); - - std::vector ccord{0,1,2,3,4,5,6,7}; + 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_}; + std::vector rcord(ccord.size(), 8); + vals = {YReMat_, -YImMatDi_, -YReMat_, -YImMatOff_, -YReMat_, YImMatDi_, YReMat_, YImMatOff_}; jac_.setValues(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_}; jac_.setValues(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_}; jac_.setValues(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_}; jac_.setValues(rtemp, ctemp, vals); return 0; -} + } -template -int TransmissionLine::evaluateIntegrand() -{ + template + int TransmissionLine::evaluateIntegrand() + { return 0; -} + } -template -int TransmissionLine::initializeAdjoint() -{ + template + int TransmissionLine::initializeAdjoint() + { return 0; -} + } -template -int TransmissionLine::evaluateAdjointResidual() -{ + template + int TransmissionLine::evaluateAdjointResidual() + { return 0; -} + } -template -int TransmissionLine::evaluateAdjointIntegrand() -{ + template + int TransmissionLine::evaluateAdjointIntegrand() + { return 0; -} - - - - - -// Available template instantiations -template class TransmissionLine; -template class TransmissionLine; - + } -} //namespace GridKit + // Available template instantiations + template class TransmissionLine; + template class TransmissionLine; +} // namespace GridKit diff --git a/src/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp b/src/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp index 2dd6f33a..badd0cf9 100644 --- a/src/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp +++ b/src/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp @@ -3,76 +3,73 @@ #ifndef _TRANLINE_HPP_ #define _TRANLINE_HPP_ - -#include #include - +#include namespace GridKit { - template class BaseBus; + template + class BaseBus; } - 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 - * - * @note Not used in the Microgrid model. - */ - template - class TransmissionLine : public CircuitComponent - { - using CircuitComponent::size_; - using CircuitComponent::nnz_; - using CircuitComponent::time_; - using CircuitComponent::alpha_; - using CircuitComponent::y_; - using CircuitComponent::yp_; - using CircuitComponent::tag_; - using CircuitComponent::f_; - using CircuitComponent::g_; - using CircuitComponent::yB_; - using CircuitComponent::ypB_; - using CircuitComponent::fB_; - using CircuitComponent::gB_; - using CircuitComponent::jac_; - using CircuitComponent::param_; - using CircuitComponent::idc_; + /*! + * @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 + * + * @note Not used in the Microgrid model. + */ + template + class TransmissionLine : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::jac_; + using CircuitComponent::param_; + using CircuitComponent::idc_; - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; - public: - TransmissionLine(IdxT id, ScalarT R, ScalarT X, ScalarT B); - virtual ~TransmissionLine(); + public: + TransmissionLine(IdxT id, ScalarT R, ScalarT X, ScalarT B); + virtual ~TransmissionLine(); - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); - - private: - ScalarT R_; - ScalarT X_; - ScalarT B_; - ScalarT YReMat_; - ScalarT YImMatDi_; - ScalarT YImMatOff_; - }; -} + private: + ScalarT R_; + ScalarT X_; + ScalarT B_; + ScalarT YReMat_; + ScalarT YImMatDi_; + ScalarT YImMatOff_; + }; +} // namespace GridKit #endif diff --git a/src/Model/PowerElectronics/VoltageSource/VoltageSource.cpp b/src/Model/PowerElectronics/VoltageSource/VoltageSource.cpp index cddb777b..8a2adaeb 100644 --- a/src/Model/PowerElectronics/VoltageSource/VoltageSource.cpp +++ b/src/Model/PowerElectronics/VoltageSource/VoltageSource.cpp @@ -1,122 +1,120 @@ +#include "VoltageSource.hpp" -#include #include +#include #include -#include "VoltageSource.hpp" - -namespace GridKit { - -/*! - * @brief Constructor for a constant VoltageSource model - * - * Calls default ModelEvaluatorImpl constructor. - */ -template -VoltageSource::VoltageSource(IdxT id, ScalarT V) - : V_(V) +namespace GridKit { - size_ = 3; - n_intern_ = 1; - n_extern_ = 2; - extern_indices_ = {0,1}; - idc_ = id; -} - -template -VoltageSource::~VoltageSource() -{ -} -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int VoltageSource::allocate() -{ + /*! + * @brief Constructor for a constant VoltageSource model + * + * Calls default ModelEvaluatorImpl constructor. + */ + + template + VoltageSource::VoltageSource(IdxT id, ScalarT V) + : V_(V) + { + size_ = 3; + n_intern_ = 1; + n_extern_ = 2; + extern_indices_ = {0, 1}; + idc_ = id; + } + + template + VoltageSource::~VoltageSource() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int VoltageSource::allocate() + { y_.resize(size_); yp_.resize(size_); f_.resize(size_); - - return 0; -} -/** - * Initialization of the grid model - */ -template -int VoltageSource::initialize() -{ return 0; -} - -/* - * \brief Identify differential variables - */ -template -int VoltageSource::tagDifferentiable() -{ + } + + /** + * Initialization of the grid model + */ + template + int VoltageSource::initialize() + { return 0; -} - -/** - * @brief Evaluate resisdual of component - */ -template -int VoltageSource::evaluateResidual() -{ - //input + } + + /* + * \brief Identify differential variables + */ + template + int VoltageSource::tagDifferentiable() + { + return 0; + } + + /** + * @brief Evaluate resisdual of component + */ + template + int VoltageSource::evaluateResidual() + { + // input f_[0] = -y_[2]; - //ouput + // ouput f_[1] = y_[2]; - //internal + // internal f_[2] = y_[1] - y_[0] - V_; return 0; -} - -template -int VoltageSource::evaluateJacobian() -{ - //Create dF/dy - std::vector rcord{0,1,2,2}; - std::vector ccord{2,2,0,1}; + } + + template + int VoltageSource::evaluateJacobian() + { + // Create dF/dy + std::vector rcord{0, 1, 2, 2}; + std::vector ccord{2, 2, 0, 1}; std::vector vals{-1.0, 1.0, -1.0, 1.0}; jac_.setValues(rcord, ccord, vals); return 0; -} + } -template -int VoltageSource::evaluateIntegrand() -{ + template + int VoltageSource::evaluateIntegrand() + { return 0; -} + } -template -int VoltageSource::initializeAdjoint() -{ + template + int VoltageSource::initializeAdjoint() + { return 0; -} + } -template -int VoltageSource::evaluateAdjointResidual() -{ + template + int VoltageSource::evaluateAdjointResidual() + { return 0; -} + } -template -int VoltageSource::evaluateAdjointIntegrand() -{ + template + int VoltageSource::evaluateAdjointIntegrand() + { return 0; -} - - -// Available template instantiations -template class VoltageSource; -template class VoltageSource; - + } -} //namespace GridKit + // Available template instantiations + template class VoltageSource; + template class VoltageSource; +} // namespace GridKit diff --git a/src/Model/PowerElectronics/VoltageSource/VoltageSource.hpp b/src/Model/PowerElectronics/VoltageSource/VoltageSource.hpp index 972f4c46..d3b630a0 100644 --- a/src/Model/PowerElectronics/VoltageSource/VoltageSource.hpp +++ b/src/Model/PowerElectronics/VoltageSource/VoltageSource.hpp @@ -3,66 +3,64 @@ #ifndef _VOSO_HPP_ #define _VOSO_HPP_ - -#include #include - +#include namespace GridKit { - template class BaseBus; + template + class BaseBus; } - namespace GridKit { - /*! - * @brief Declaration of a VoltageSource class. - * - */ - template - class VoltageSource : public CircuitComponent - { - using CircuitComponent::size_; - using CircuitComponent::nnz_; - using CircuitComponent::time_; - using CircuitComponent::alpha_; - using CircuitComponent::y_; - using CircuitComponent::yp_; - using CircuitComponent::tag_; - using CircuitComponent::f_; - using CircuitComponent::g_; - using CircuitComponent::yB_; - using CircuitComponent::ypB_; - using CircuitComponent::fB_; - using CircuitComponent::gB_; - using CircuitComponent::jac_; - using CircuitComponent::param_; - using CircuitComponent::idc_; - - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + /*! + * @brief Declaration of a VoltageSource class. + * + */ + template + class VoltageSource : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::jac_; + using CircuitComponent::param_; + using CircuitComponent::idc_; - public: - VoltageSource(IdxT id, ScalarT V); - virtual ~VoltageSource(); + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + public: + VoltageSource(IdxT id, ScalarT V); + virtual ~VoltageSource(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - private: - ScalarT V_; - }; -} + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT V_; + }; +} // namespace GridKit #endif diff --git a/src/Model/PowerFlow/Branch/Branch.cpp b/src/Model/PowerFlow/Branch/Branch.cpp index d2ff225f..a95874e6 100644 --- a/src/Model/PowerFlow/Branch/Branch.cpp +++ b/src/Model/PowerFlow/Branch/Branch.cpp @@ -57,162 +57,163 @@ * */ -#include -#include -#include -#include - #include "Branch.hpp" -namespace GridKit { +#include +#include -/*! - * @brief Constructor for a pi-model branch - * - * Arguments passed to ModelEvaluatorImpl: - * - Number of equations = 0 - * - Number of independent variables = 0 - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ +#include +#include -template -Branch::Branch(bus_type* bus1, bus_type* bus2) - : R_(0.0), - X_(0.01), - G_(0.0), - B_(0.0), - fbusID_(0), - tbusID_(0), - bus1_(bus1), - bus2_(bus2) +namespace GridKit { + + /*! + * @brief Constructor for a pi-model branch + * + * Arguments passed to ModelEvaluatorImpl: + * - Number of equations = 0 + * - Number of independent variables = 0 + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ + + template + Branch::Branch(bus_type* bus1, bus_type* bus2) + : R_(0.0), + X_(0.01), + G_(0.0), + B_(0.0), + fbusID_(0), + tbusID_(0), + bus1_(bus1), + bus2_(bus2) + { size_ = 0; -} - -template -Branch::Branch(real_type R, real_type X, real_type G, real_type B, bus_type* bus1, bus_type* bus2) - : R_(R), - X_(X), - G_(G), - B_(B), - fbusID_(0), - tbusID_(0), - bus1_(bus1), - bus2_(bus2) -{ -} - -template -Branch::Branch(bus_type* bus1, bus_type* bus2, BranchData& data) - : R_(data.r), - X_(data.x), - G_(0.0), - B_(data.b), - fbusID_(data.fbus), - tbusID_(data.tbus), - bus1_(bus1), - bus2_(bus2) -{ + } + + template + Branch::Branch(real_type R, real_type X, real_type G, real_type B, bus_type* bus1, bus_type* bus2) + : R_(R), + X_(X), + G_(G), + B_(B), + fbusID_(0), + tbusID_(0), + bus1_(bus1), + bus2_(bus2) + { + } + + template + Branch::Branch(bus_type* bus1, bus_type* bus2, BranchData& data) + : R_(data.r), + X_(data.x), + G_(0.0), + B_(data.b), + fbusID_(data.fbus), + tbusID_(data.tbus), + bus1_(bus1), + bus2_(bus2) + { size_ = 0; -} - - -template -Branch::~Branch() -{ - //std::cout << "Destroy Branch..." << std::endl; -} - -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int Branch::allocate() -{ - //std::cout << "Allocate Branch..." << std::endl; + } + + template + Branch::~Branch() + { + // std::cout << "Destroy Branch..." << std::endl; + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int Branch::allocate() + { + // std::cout << "Allocate Branch..." << std::endl; return 0; -} - -/** - * Initialization of the branch model - * - */ -template -int Branch::initialize() -{ + } + + /** + * Initialization of the branch model + * + */ + template + int Branch::initialize() + { return 0; -} - -/** - * \brief Identify differential variables. - */ -template -int Branch::tagDifferentiable() -{ + } + + /** + * \brief Identify differential variables. + */ + template + int Branch::tagDifferentiable() + { return 0; -} - -/** - * \brief Residual contribution of the branch is pushed to the - * two terminal buses. - * - * @todo Add and verify conductance to ground (B and G) - */ -template -int Branch::evaluateResidual() -{ + } + + /** + * \brief Residual contribution of the branch is pushed to the + * two terminal buses. + * + * @todo Add and verify conductance to ground (B and G) + */ + template + int Branch::evaluateResidual() + { // std::cout << "Evaluating branch residual ...\n"; - real_type b = -X_/(R_*R_ + X_*X_); - real_type g = R_/(R_*R_ + X_*X_); - ScalarT dtheta = theta1() - theta2(); + real_type b = -X_ / (R_ * R_ + X_ * X_); + real_type g = R_ / (R_ * R_ + X_ * X_); + ScalarT dtheta = theta1() - theta2(); - P1() -= ( g + 0.5*G_)*V1()*V1() + V1()*V2()*(-g*cos(dtheta) - b*sin(dtheta)); - Q1() -= (-b - 0.5*B_)*V1()*V1() + V1()*V2()*(-g*sin(dtheta) + b*cos(dtheta)); - P2() -= ( g + 0.5*G_)*V2()*V2() + V1()*V2()*(-g*cos(dtheta) + b*sin(dtheta)); - Q2() -= (-b - 0.5*B_)*V2()*V2() + V1()*V2()*( g*sin(dtheta) + b*cos(dtheta)); + P1() -= (g + 0.5 * G_) * V1() * V1() + V1() * V2() * (-g * cos(dtheta) - b * sin(dtheta)); + Q1() -= (-b - 0.5 * B_) * V1() * V1() + V1() * V2() * (-g * sin(dtheta) + b * cos(dtheta)); + P2() -= (g + 0.5 * G_) * V2() * V2() + V1() * V2() * (-g * cos(dtheta) + b * sin(dtheta)); + Q2() -= (-b - 0.5 * B_) * V2() * V2() + V1() * V2() * (g * sin(dtheta) + b * cos(dtheta)); return 0; -} + } -template -int Branch::evaluateJacobian() -{ + template + int Branch::evaluateJacobian() + { std::cout << "Evaluate Jacobian for Branch..." << std::endl; std::cout << "Jacobian evaluation not implemented!" << std::endl; return 0; -} + } -template -int Branch::evaluateIntegrand() -{ + template + int Branch::evaluateIntegrand() + { // std::cout << "Evaluate Integrand for Branch..." << std::endl; return 0; -} + } -template -int Branch::initializeAdjoint() -{ - //std::cout << "Initialize adjoint for Branch..." << std::endl; + template + int Branch::initializeAdjoint() + { + // std::cout << "Initialize adjoint for Branch..." << std::endl; return 0; -} + } -template -int Branch::evaluateAdjointResidual() -{ + template + int Branch::evaluateAdjointResidual() + { // std::cout << "Evaluate adjoint residual for Branch..." << std::endl; return 0; -} + } -template -int Branch::evaluateAdjointIntegrand() -{ + template + int Branch::evaluateAdjointIntegrand() + { // std::cout << "Evaluate adjoint Integrand for Branch..." << std::endl; return 0; -} + } -// Available template instantiations -template class Branch; -template class Branch; + // Available template instantiations + template class Branch; + template class Branch; -} //namespace GridKit +} // namespace GridKit diff --git a/src/Model/PowerFlow/Branch/Branch.hpp b/src/Model/PowerFlow/Branch/Branch.hpp index 1b977881..36def6bf 100644 --- a/src/Model/PowerFlow/Branch/Branch.hpp +++ b/src/Model/PowerFlow/Branch/Branch.hpp @@ -65,137 +65,139 @@ // Forward declarations. namespace GridKit { - template class BaseBus; + template + class BaseBus; - namespace PowerSystemData { - template - struct BranchData; - } -} + namespace PowerSystemData + { + template + struct BranchData; + } +} // namespace GridKit namespace GridKit { - /*! - * @brief Implementation of a pi-model branch between two buses. - * - */ - template - class Branch : public ModelEvaluatorImpl + /*! + * @brief Implementation of a pi-model branch between two buses. + * + */ + template + class Branch : public ModelEvaluatorImpl + { + using ModelEvaluatorImpl::size_; + using ModelEvaluatorImpl::nnz_; + using ModelEvaluatorImpl::time_; + using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::yp_; + using ModelEvaluatorImpl::tag_; + using ModelEvaluatorImpl::f_; + using ModelEvaluatorImpl::g_; + using ModelEvaluatorImpl::yB_; + using ModelEvaluatorImpl::ypB_; + using ModelEvaluatorImpl::fB_; + using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::param_; + + using bus_type = BaseBus; + using real_type = typename ModelEvaluatorImpl::real_type; + using BranchData = GridKit::PowerSystemData::BranchData; + + public: + Branch(bus_type* bus1, bus_type* bus2); + Branch(real_type R, real_type X, real_type G, real_type B, bus_type* bus1, bus_type* bus2); + Branch(bus_type* bus1, bus_type* bus2, BranchData& data); + virtual ~Branch(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + void updateTime(real_type t, real_type a) + { + } + + public: + void setR(real_type R) + { + R_ = R; + } + + void setX(real_type X) + { + // std::cout << "Setting X ...\n"; + X_ = X; + } + + void setG(real_type G) { - using ModelEvaluatorImpl::size_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::alpha_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::yp_; - using ModelEvaluatorImpl::tag_; - using ModelEvaluatorImpl::f_; - using ModelEvaluatorImpl::g_; - using ModelEvaluatorImpl::yB_; - using ModelEvaluatorImpl::ypB_; - using ModelEvaluatorImpl::fB_; - using ModelEvaluatorImpl::gB_; - using ModelEvaluatorImpl::param_; - - using bus_type = BaseBus; - using real_type = typename ModelEvaluatorImpl::real_type; - using BranchData = GridKit::PowerSystemData::BranchData; - - public: - Branch(bus_type* bus1, bus_type* bus2); - Branch(real_type R, real_type X, real_type G, real_type B, bus_type* bus1, bus_type* bus2); - Branch(bus_type* bus1, bus_type* bus2, BranchData& data); - virtual ~Branch(); - - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); - - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - void updateTime(real_type t, real_type a) - { - } - - public: - void setR(real_type R) - { - R_ = R; - } - - void setX(real_type X) - { - // std::cout << "Setting X ...\n"; - X_ = X; - } - - void setG(real_type G) - { - G_ = G; - } - - void setB(real_type B) - { - B_ = B; - } - - private: - ScalarT& V1() - { - return bus1_->V(); - } - - ScalarT& theta1() - { - return bus1_->theta(); - } - - ScalarT& P1() - { - return bus1_->P(); - } - - ScalarT& Q1() - { - return bus1_->Q(); - } - - ScalarT& V2() - { - return bus2_->V(); - } - - ScalarT& theta2() - { - return bus2_->theta(); - } - - ScalarT& P2() - { - return bus2_->P(); - } - - ScalarT& Q2() - { - return bus2_->Q(); - } - - private: - real_type R_; - real_type X_; - real_type G_; - real_type B_; - const IdxT fbusID_; - const IdxT tbusID_; - bus_type* bus1_; - bus_type* bus2_; - }; -} + G_ = G; + } + + void setB(real_type B) + { + B_ = B; + } + + private: + ScalarT& V1() + { + return bus1_->V(); + } + + ScalarT& theta1() + { + return bus1_->theta(); + } + + ScalarT& P1() + { + return bus1_->P(); + } + + ScalarT& Q1() + { + return bus1_->Q(); + } + + ScalarT& V2() + { + return bus2_->V(); + } + + ScalarT& theta2() + { + return bus2_->theta(); + } + + ScalarT& P2() + { + return bus2_->P(); + } + + ScalarT& Q2() + { + return bus2_->Q(); + } + + private: + real_type R_; + real_type X_; + real_type G_; + real_type B_; + const IdxT fbusID_; + const IdxT tbusID_; + bus_type* bus1_; + bus_type* bus2_; + }; +} // namespace GridKit #endif // _BRANCH_H diff --git a/src/Model/PowerFlow/Bus/BaseBus.hpp b/src/Model/PowerFlow/Bus/BaseBus.hpp index e63347aa..1050c8bd 100644 --- a/src/Model/PowerFlow/Bus/BaseBus.hpp +++ b/src/Model/PowerFlow/Bus/BaseBus.hpp @@ -64,94 +64,142 @@ namespace GridKit { - /*! - * @brief Base class for all power flow buses. - * - * Derived bus types: - * 0 - swing bus (V and theta are constants) - * 1 - PV bus (P and V are constants) - * 2 - PQ bus (P and Q are constants) - * - * @todo Consider static instead of dynamic polymorphism for - * bus types. Create Bus class that takes template parameter - * BusType. - */ - template - class BaseBus : public ModelEvaluatorImpl + /*! + * @brief Base class for all power flow buses. + * + * Derived bus types: + * 0 - swing bus (V and theta are constants) + * 1 - PV bus (P and V are constants) + * 2 - PQ bus (P and Q are constants) + * + * @todo Consider static instead of dynamic polymorphism for + * bus types. Create Bus class that takes template parameter + * BusType. + */ + template + class BaseBus : public ModelEvaluatorImpl + { + protected: + using ModelEvaluatorImpl::size_; + using ModelEvaluatorImpl::nnz_; + using ModelEvaluatorImpl::time_; + using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::rel_tol_; + using ModelEvaluatorImpl::abs_tol_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::yp_; + using ModelEvaluatorImpl::tag_; + using ModelEvaluatorImpl::f_; + using ModelEvaluatorImpl::g_; + using ModelEvaluatorImpl::yB_; + using ModelEvaluatorImpl::ypB_; + using ModelEvaluatorImpl::fB_; + using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::param_; + using ModelEvaluatorImpl::param_up_; + using ModelEvaluatorImpl::param_lo_; + + public: + typedef typename ModelEvaluatorImpl::real_type real_type; + + enum BusType { - protected: - using ModelEvaluatorImpl::size_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::alpha_; - using ModelEvaluatorImpl::rel_tol_; - using ModelEvaluatorImpl::abs_tol_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::yp_; - using ModelEvaluatorImpl::tag_; - using ModelEvaluatorImpl::f_; - using ModelEvaluatorImpl::g_; - using ModelEvaluatorImpl::yB_; - using ModelEvaluatorImpl::ypB_; - using ModelEvaluatorImpl::fB_; - using ModelEvaluatorImpl::gB_; - using ModelEvaluatorImpl::param_; - using ModelEvaluatorImpl::param_up_; - using ModelEvaluatorImpl::param_lo_; - - public: - typedef typename ModelEvaluatorImpl::real_type real_type; - - enum BusType{PQ=1, PV, Slack, Isolated}; - - BaseBus(IdxT id) : busID_(id) {} - virtual ~BaseBus(){} - - // Set defaults for ModelEvaluator methods - virtual int allocate() { return 0;} - virtual int initialize() { return 0;} - virtual int tagDifferentiable() { return 0;} - virtual int evaluateResidual() { return 0;} - virtual int evaluateJacobian() { return 0;} - virtual int evaluateIntegrand() { return 0;} - - virtual int initializeAdjoint() { return 0;} - virtual int evaluateAdjointResidual() { return 0;} - //virtual int evaluateAdjointJacobian() { return 0;} - virtual int evaluateAdjointIntegrand() { return 0;} - virtual void updateTime(real_type, real_type) {} // <- throw exception here - - // Pure virtual methods specific to Bus types - virtual ScalarT& V() = 0; - virtual const ScalarT& V() const = 0; - virtual ScalarT& theta() = 0; - virtual const ScalarT& theta() const = 0; - virtual ScalarT& P() = 0; - virtual const ScalarT& P() const = 0; - virtual ScalarT& Q() = 0; - virtual const ScalarT& Q() const = 0; - - virtual ScalarT& lambdaP() = 0; - virtual const ScalarT& lambdaP() const = 0; - virtual ScalarT& lambdaQ() = 0; - virtual const ScalarT& lambdaQ() const = 0; - virtual ScalarT& PB() = 0; - virtual const ScalarT& PB() const = 0; - virtual ScalarT& QB() = 0; - virtual const ScalarT& QB() const = 0; - - virtual int BusType() const = 0; - - virtual const IdxT BusID() const - { - return busID_; - } - - protected: - const IdxT busID_; - }; // class BaseBus + PQ = 1, + PV, + Slack, + Isolated + }; + + BaseBus(IdxT id) + : busID_(id) + { + } -} // namespace GridKit + virtual ~BaseBus() + { + } + + // Set defaults for ModelEvaluator methods + virtual int allocate() + { + return 0; + } + + virtual int initialize() + { + return 0; + } + + virtual int tagDifferentiable() + { + return 0; + } + + virtual int evaluateResidual() + { + return 0; + } + + virtual int evaluateJacobian() + { + return 0; + } + virtual int evaluateIntegrand() + { + return 0; + } + + virtual int initializeAdjoint() + { + return 0; + } + + virtual int evaluateAdjointResidual() + { + return 0; + } + + // virtual int evaluateAdjointJacobian() { return 0;} + virtual int evaluateAdjointIntegrand() + { + return 0; + } + + virtual void updateTime(real_type, real_type) + { + } // <- throw exception here + + // Pure virtual methods specific to Bus types + virtual ScalarT& V() = 0; + virtual const ScalarT& V() const = 0; + virtual ScalarT& theta() = 0; + virtual const ScalarT& theta() const = 0; + virtual ScalarT& P() = 0; + virtual const ScalarT& P() const = 0; + virtual ScalarT& Q() = 0; + virtual const ScalarT& Q() const = 0; + + virtual ScalarT& lambdaP() = 0; + virtual const ScalarT& lambdaP() const = 0; + virtual ScalarT& lambdaQ() = 0; + virtual const ScalarT& lambdaQ() const = 0; + virtual ScalarT& PB() = 0; + virtual const ScalarT& PB() const = 0; + virtual ScalarT& QB() = 0; + virtual const ScalarT& QB() const = 0; + + virtual int BusType() const = 0; + + virtual const IdxT BusID() const + { + return busID_; + } + + protected: + const IdxT busID_; + }; // class BaseBus + +} // namespace GridKit #endif // _BASE_BUS_HPP_ diff --git a/src/Model/PowerFlow/Bus/BusFactory.hpp b/src/Model/PowerFlow/Bus/BusFactory.hpp index 66ff943f..f9b62f7d 100644 --- a/src/Model/PowerFlow/Bus/BusFactory.hpp +++ b/src/Model/PowerFlow/Bus/BusFactory.hpp @@ -59,42 +59,43 @@ #pragma once -#include #include #include #include +#include -namespace GridKit { +namespace GridKit +{ - template - class BusFactory - { - public: - using real_type = typename ModelEvaluatorImpl::real_type; - using BusData = GridKit::PowerSystemData::BusData; + template + class BusFactory + { + public: + using real_type = typename ModelEvaluatorImpl::real_type; + using BusData = GridKit::PowerSystemData::BusData; - BusFactory() = delete; + BusFactory() = delete; - static BaseBus* create(BusData& data) - { - BaseBus* bus = nullptr; - switch(data.type) - { - case 1: - bus = new BusPQ(data); - break; - case 2: - bus = new BusPV(data); - break; - case 3: - bus = new BusSlack(data); - break; - default: - // Throw exception - std::cout << "Bus type " << data.type << " unrecognized.\n"; - } - return bus; - } - }; + static BaseBus* create(BusData& data) + { + BaseBus* bus = nullptr; + switch (data.type) + { + case 1: + bus = new BusPQ(data); + break; + case 2: + bus = new BusPV(data); + break; + case 3: + bus = new BusSlack(data); + break; + default: + // Throw exception + std::cout << "Bus type " << data.type << " unrecognized.\n"; + } + return bus; + } + }; } // namespace GridKit \ No newline at end of file diff --git a/src/Model/PowerFlow/Bus/BusPQ.cpp b/src/Model/PowerFlow/Bus/BusPQ.cpp index 07627e0a..6485eab1 100644 --- a/src/Model/PowerFlow/Bus/BusPQ.cpp +++ b/src/Model/PowerFlow/Bus/BusPQ.cpp @@ -57,75 +57,77 @@ * */ -#include -#include #include "BusPQ.hpp" -namespace GridKit { +#include +#include -/*! - * @brief Constructor for a PQ bus - * - * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: - * - Number of equations = 2 (size_) - * - Number of variables = 2 (size_) - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ -template -BusPQ::BusPQ() - : BaseBus(0), V0_(0.0), theta0_(0.0) +namespace GridKit { - //std::cout << "Create BusPQ..." << std::endl; - //std::cout << "Number of equations is " << size_ << std::endl; - - size_ = 2; -} -/*! - * @brief BusPQ constructor. - * - * This constructor sets initial values for voltage and phase angle. - * - * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: - * - Number of equations = 2 (size_) - * - Number of variables = 2 (size_) - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ -template -BusPQ::BusPQ(ScalarT V, ScalarT theta) - : BaseBus(0), V0_(V), theta0_(theta) -{ - //std::cout << "Create BusPQ..." << std::endl; - //std::cout << "Number of equations is " << size_ << std::endl; + /*! + * @brief Constructor for a PQ bus + * + * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: + * - Number of equations = 2 (size_) + * - Number of variables = 2 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ + template + BusPQ::BusPQ() + : BaseBus(0), V0_(0.0), theta0_(0.0) + { + // std::cout << "Create BusPQ..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; size_ = 2; -} - -template -BusPQ::BusPQ(BusData& data) - : BaseBus(data.bus_i), V0_(data.Vm), theta0_(data.Va) -{ - //std::cout << "Create BusPQ..." << std::endl; - //std::cout << "Number of equations is " << size_ << std::endl; + } + + /*! + * @brief BusPQ constructor. + * + * This constructor sets initial values for voltage and phase angle. + * + * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: + * - Number of equations = 2 (size_) + * - Number of variables = 2 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ + template + BusPQ::BusPQ(ScalarT V, ScalarT theta) + : BaseBus(0), V0_(V), theta0_(theta) + { + // std::cout << "Create BusPQ..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; size_ = 2; -} + } -template -BusPQ::~BusPQ() -{ - //std::cout << "Destroy PQ bus ..." << std::endl; -} + template + BusPQ::BusPQ(BusData& data) + : BaseBus(data.bus_i), V0_(data.Vm), theta0_(data.Va) + { + // std::cout << "Create BusPQ..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; -/*! - * @brief allocate method resizes local solution and residual vectors. - */ -template -int BusPQ::allocate() -{ - //std::cout << "Allocate PQ bus ..." << std::endl; + size_ = 2; + } + + template + BusPQ::~BusPQ() + { + // std::cout << "Destroy PQ bus ..." << std::endl; + } + + /*! + * @brief allocate method resizes local solution and residual vectors. + */ + template + int BusPQ::allocate() + { + // std::cout << "Allocate PQ bus ..." << std::endl; f_.resize(size_); y_.resize(size_); yp_.resize(size_); @@ -136,78 +138,73 @@ int BusPQ::allocate() ypB_.resize(size_); return 0; -} + } - -template -int BusPQ::tagDifferentiable() -{ + template + int BusPQ::tagDifferentiable() + { tag_[0] = false; tag_[1] = false; return 0; -} - - -/*! - * @brief initialize method sets bus variables to stored initial values. - */ -template -int BusPQ::initialize() -{ + } + + /*! + * @brief initialize method sets bus variables to stored initial values. + */ + template + int BusPQ::initialize() + { // std::cout << "Initialize BusPQ..." << std::endl; - y_[0] = V0_; - y_[1] = theta0_; + y_[0] = V0_; + y_[1] = theta0_; yp_[0] = 0.0; yp_[1] = 0.0; return 0; -} - -/*! - * @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. - * - */ -template -int BusPQ::evaluateResidual() -{ + } + + /*! + * @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. + * + */ + template + int BusPQ::evaluateResidual() + { // std::cout << "Evaluating residual of a PQ bus ...\n"; f_[0] = 0.0; f_[1] = 0.0; return 0; -} - - -/*! - * @brief initialize method sets bus variables to stored initial values. - */ -template -int BusPQ::initializeAdjoint() -{ + } + + /*! + * @brief initialize method sets bus variables to stored initial values. + */ + template + int BusPQ::initializeAdjoint() + { // std::cout << "Initialize BusPQ..." << std::endl; - yB_[0] = 0.0; - yB_[1] = 0.0; + yB_[0] = 0.0; + yB_[1] = 0.0; ypB_[0] = 0.0; ypB_[1] = 0.0; return 0; -} + } -template -int BusPQ::evaluateAdjointResidual() -{ + template + int BusPQ::evaluateAdjointResidual() + { fB_[0] = 0.0; fB_[1] = 0.0; return 0; -} - -// Available template instantiations -template class BusPQ; -template class BusPQ; + } + // Available template instantiations + template class BusPQ; + template class BusPQ; } // namespace GridKit - diff --git a/src/Model/PowerFlow/Bus/BusPQ.hpp b/src/Model/PowerFlow/Bus/BusPQ.hpp index f4081993..4e03b344 100644 --- a/src/Model/PowerFlow/Bus/BusPQ.hpp +++ b/src/Model/PowerFlow/Bus/BusPQ.hpp @@ -65,135 +65,133 @@ namespace GridKit { - /*! - * @brief Implementation of a PQ bus. - * - * Voltage _V_ and phase _theta_ are variables in PQ bus model. - * Active and reactive power, _P_ and _Q_, are residual components. - * - * - */ - template - class BusPQ : public BaseBus - { - using BaseBus::size_; - using BaseBus::y_; - using BaseBus::yp_; - using BaseBus::yB_; - using BaseBus::ypB_; - using BaseBus::f_; - using BaseBus::fB_; - using BaseBus::tag_; - - public: - using real_type = typename ModelEvaluatorImpl::real_type; - using BusData = GridKit::PowerSystemData::BusData; - - BusPQ(); - BusPQ(ScalarT V, ScalarT theta); - BusPQ(BusData& data); - virtual ~BusPQ(); - - virtual int allocate(); - virtual int tagDifferentiable(); - virtual int initialize(); - virtual int evaluateResidual(); - virtual int initializeAdjoint(); - virtual int evaluateAdjointResidual(); - - virtual ScalarT& V() - { - return y_[0]; - } - - virtual const ScalarT& V() const - { - return y_[0]; - } - - virtual ScalarT& theta() - { - return y_[1]; - } - - virtual const ScalarT& theta() const - { - return y_[1]; - } - - virtual ScalarT& P() - { - return f_[0]; - } - - virtual const ScalarT& P() const - { - return f_[0]; - } - - virtual ScalarT& Q() - { - return f_[1]; - } - - virtual const ScalarT& Q() const - { - return f_[1]; - } - - virtual ScalarT& lambdaP() - { - return yB_[0]; - } - - virtual const ScalarT& lambdaP() const - { - return yB_[0]; - } - - virtual ScalarT& lambdaQ() - { - return yB_[1]; - } - - virtual const ScalarT& lambdaQ() const - { - return yB_[1]; - } - - virtual ScalarT& PB() - { - return fB_[0]; - } - - virtual const ScalarT& PB() const - { - return fB_[0]; - } - - virtual ScalarT& QB() - { - return fB_[1]; - } - - virtual const ScalarT& QB() const - { - return fB_[1]; - } - - virtual int BusType() const - { - return BaseBus::BusType::PQ; - } - - private: - // Default initial values for voltage and phase on PQ bus - ScalarT V0_; - ScalarT theta0_; - - }; + /*! + * @brief Implementation of a PQ bus. + * + * Voltage _V_ and phase _theta_ are variables in PQ bus model. + * Active and reactive power, _P_ and _Q_, are residual components. + * + * + */ + template + class BusPQ : public BaseBus + { + using BaseBus::size_; + using BaseBus::y_; + using BaseBus::yp_; + using BaseBus::yB_; + using BaseBus::ypB_; + using BaseBus::f_; + using BaseBus::fB_; + using BaseBus::tag_; + + public: + using real_type = typename ModelEvaluatorImpl::real_type; + using BusData = GridKit::PowerSystemData::BusData; + + BusPQ(); + BusPQ(ScalarT V, ScalarT theta); + BusPQ(BusData& data); + virtual ~BusPQ(); + + virtual int allocate(); + virtual int tagDifferentiable(); + virtual int initialize(); + virtual int evaluateResidual(); + virtual int initializeAdjoint(); + virtual int evaluateAdjointResidual(); + + virtual ScalarT& V() + { + return y_[0]; + } -} // namespace GridKit + virtual const ScalarT& V() const + { + return y_[0]; + } + + virtual ScalarT& theta() + { + return y_[1]; + } + + virtual const ScalarT& theta() const + { + return y_[1]; + } + + virtual ScalarT& P() + { + return f_[0]; + } + virtual const ScalarT& P() const + { + return f_[0]; + } + + virtual ScalarT& Q() + { + return f_[1]; + } + + virtual const ScalarT& Q() const + { + return f_[1]; + } + + virtual ScalarT& lambdaP() + { + return yB_[0]; + } + + virtual const ScalarT& lambdaP() const + { + return yB_[0]; + } + + virtual ScalarT& lambdaQ() + { + return yB_[1]; + } + + virtual const ScalarT& lambdaQ() const + { + return yB_[1]; + } + + virtual ScalarT& PB() + { + return fB_[0]; + } + + virtual const ScalarT& PB() const + { + return fB_[0]; + } + + virtual ScalarT& QB() + { + return fB_[1]; + } + + virtual const ScalarT& QB() const + { + return fB_[1]; + } + + virtual int BusType() const + { + return BaseBus::BusType::PQ; + } + + private: + // Default initial values for voltage and phase on PQ bus + ScalarT V0_; + ScalarT theta0_; + }; + +} // namespace GridKit #endif // _BUS_PQ_HPP_ diff --git a/src/Model/PowerFlow/Bus/BusPV.cpp b/src/Model/PowerFlow/Bus/BusPV.cpp index 75ae6d05..f4d2d422 100644 --- a/src/Model/PowerFlow/Bus/BusPV.cpp +++ b/src/Model/PowerFlow/Bus/BusPV.cpp @@ -57,73 +57,75 @@ * */ -#include -#include #include "BusPV.hpp" -namespace GridKit { +#include +#include -/*! - * @brief Constructor for a PV bus - * - * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: - * - Number of equations = 1 (size_) - * - Number of variables = 1 (size_) - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ -template -BusPV::BusPV() - : BaseBus(0), V_(0.0), theta0_(0.0) +namespace GridKit { - //std::cout << "Create BusPV..." << std::endl; - //std::cout << "Number of equations is " << size_ << std::endl; - - size_ = 1; -} -/*! - * @brief Constructor for a PV bus - * - * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: - * - Number of equations = 1 (size_) - * - Number of variables = 1 (size_) - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ -template -BusPV::BusPV(ScalarT V, ScalarT theta0) - : BaseBus(0), V_(V), theta0_(theta0) -{ - //std::cout << "Create BusPV..." << std::endl; - //std::cout << "Number of equations is " << size_ << std::endl; + /*! + * @brief Constructor for a PV bus + * + * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: + * - Number of equations = 1 (size_) + * - Number of variables = 1 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ + template + BusPV::BusPV() + : BaseBus(0), V_(0.0), theta0_(0.0) + { + // std::cout << "Create BusPV..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; size_ = 1; -} - -template -BusPV::BusPV(BusData& data) - : BaseBus(data.bus_i), V_(data.Vm), theta0_(data.Va) -{ - //std::cout << "Create BusPV ..." << std::endl; - //std::cout << "Number of equations is " << size_ << std::endl; + } + + /*! + * @brief Constructor for a PV bus + * + * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: + * - Number of equations = 1 (size_) + * - Number of variables = 1 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ + template + BusPV::BusPV(ScalarT V, ScalarT theta0) + : BaseBus(0), V_(V), theta0_(theta0) + { + // std::cout << "Create BusPV..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; size_ = 1; -} + } -template -BusPV::~BusPV() -{ - //std::cout << "Destroy Gen2..." << std::endl; -} + template + BusPV::BusPV(BusData& data) + : BaseBus(data.bus_i), V_(data.Vm), theta0_(data.Va) + { + // std::cout << "Create BusPV ..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; -/*! - * @brief allocate method resizes local solution and residual vectors. - */ -template -int BusPV::allocate() -{ - //std::cout << "Allocate PV bus ..." << std::endl; + size_ = 1; + } + + template + BusPV::~BusPV() + { + // std::cout << "Destroy Gen2..." << std::endl; + } + + /*! + * @brief allocate method resizes local solution and residual vectors. + */ + template + int BusPV::allocate() + { + // std::cout << "Allocate PV bus ..." << std::endl; f_.resize(size_); y_.resize(size_); yp_.resize(size_); @@ -134,73 +136,68 @@ int BusPV::allocate() ypB_.resize(size_); return 0; -} - + } -template -int BusPV::tagDifferentiable() -{ + template + int BusPV::tagDifferentiable() + { tag_[0] = false; return 0; -} - - -/*! - * @brief initialize method sets bus variables to stored initial values. - */ -template -int BusPV::initialize() -{ + } + + /*! + * @brief initialize method sets bus variables to stored initial values. + */ + template + int BusPV::initialize() + { // std::cout << "Initialize BusPV..." << std::endl; theta() = theta0_; - yp_[0] = 0.0; + yp_[0] = 0.0; return 0; -} - -/*! - * @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. - * - */ -template -int BusPV::evaluateResidual() -{ + } + + /*! + * @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. + * + */ + template + int BusPV::evaluateResidual() + { // std::cout << "Evaluating residual of a PV bus ...\n"; P() = 0.0; // <-- Residual P Q() = 0.0; // <-- Output Qg, the reactive power generator needs to supply return 0; -} - - -/*! - * @brief initialize method sets bus variables to stored initial values. - */ -template -int BusPV::initializeAdjoint() -{ + } + + /*! + * @brief initialize method sets bus variables to stored initial values. + */ + template + int BusPV::initializeAdjoint() + { // std::cout << "Initialize BusPV..." << std::endl; - yB_[0] = 0.0; + yB_[0] = 0.0; ypB_[0] = 0.0; return 0; -} + } -template -int BusPV::evaluateAdjointResidual() -{ + template + int BusPV::evaluateAdjointResidual() + { fB_[0] = 0.0; return 0; -} - -// Available template instantiations -template class BusPV; -template class BusPV; + } + // Available template instantiations + template class BusPV; + template class BusPV; } // namespace GridKit - diff --git a/src/Model/PowerFlow/Bus/BusPV.hpp b/src/Model/PowerFlow/Bus/BusPV.hpp index 08f407a2..1029bd67 100644 --- a/src/Model/PowerFlow/Bus/BusPV.hpp +++ b/src/Model/PowerFlow/Bus/BusPV.hpp @@ -61,153 +61,152 @@ #define _BUS_PV_HPP_ #include + #include "BaseBus.hpp" #include namespace GridKit { - /*! - * @brief Implementation of a PV bus. - * - * Voltage _V_ and phase _theta_ are variables in PV bus model. - * Active and reactive power, _P_ and _Q_, are residual components. - * - * - */ - template - class BusPV : public BaseBus - { - using BaseBus::size_; - using BaseBus::y_; - using BaseBus::yp_; - using BaseBus::yB_; - using BaseBus::ypB_; - using BaseBus::f_; - using BaseBus::fB_; - using BaseBus::tag_; - - public: - using real_type = typename ModelEvaluatorImpl::real_type; - using BusData = GridKit::PowerSystemData::BusData; - - BusPV(); - BusPV(ScalarT V, ScalarT theta0); - BusPV(BusData& data); - virtual ~BusPV(); - - virtual int allocate(); - virtual int tagDifferentiable(); - virtual int initialize(); - virtual int evaluateResidual(); - virtual int initializeAdjoint(); - virtual int evaluateAdjointResidual(); - - virtual ScalarT& V() - { - return V_; - } - - virtual const ScalarT& V() const - { - return V_; - } - - virtual ScalarT& theta() - { - return y_[0]; - } - - virtual const ScalarT& theta() const - { - return y_[0]; - } - - virtual ScalarT& P() - { - return f_[0]; - } - - virtual const ScalarT& P() const - { - return f_[0]; - } - - - virtual ScalarT& Q() - { - return Q_; - } - - virtual const ScalarT& Q() const - { - return Q_; - } - - virtual ScalarT& lambdaP() - { - assert(false); - return thetaB_; - } - - virtual const ScalarT& lambdaP() const - { - assert(false); - return thetaB_; - } - - virtual ScalarT& lambdaQ() - { - assert(false); - return VB_; - } - - virtual const ScalarT& lambdaQ() const - { - assert(false); - return VB_; - } - - virtual ScalarT& PB() - { - assert(false); - return PB_; - } - - virtual const ScalarT& PB() const - { - assert(false); - return PB_; - } - - virtual ScalarT& QB() - { - assert(false); - return QB_; - } - - virtual const ScalarT& QB() const - { - assert(false); - return QB_; - } - - virtual int BusType() const - { - return BaseBus::BusType::PV; - } - - private: - ScalarT V_; ///< Bus voltage magnitude - ScalarT theta0_; ///< Default initial value for phase - ScalarT Q_; ///< Reactive power that generator needs to provide - - ScalarT VB_; - ScalarT thetaB_; - ScalarT PB_; - ScalarT QB_; - }; + /*! + * @brief Implementation of a PV bus. + * + * Voltage _V_ and phase _theta_ are variables in PV bus model. + * Active and reactive power, _P_ and _Q_, are residual components. + * + * + */ + template + class BusPV : public BaseBus + { + using BaseBus::size_; + using BaseBus::y_; + using BaseBus::yp_; + using BaseBus::yB_; + using BaseBus::ypB_; + using BaseBus::f_; + using BaseBus::fB_; + using BaseBus::tag_; + + public: + using real_type = typename ModelEvaluatorImpl::real_type; + using BusData = GridKit::PowerSystemData::BusData; + + BusPV(); + BusPV(ScalarT V, ScalarT theta0); + BusPV(BusData& data); + virtual ~BusPV(); + + virtual int allocate(); + virtual int tagDifferentiable(); + virtual int initialize(); + virtual int evaluateResidual(); + virtual int initializeAdjoint(); + virtual int evaluateAdjointResidual(); + + virtual ScalarT& V() + { + return V_; + } -} // namespace GridKit + virtual const ScalarT& V() const + { + return V_; + } + + virtual ScalarT& theta() + { + return y_[0]; + } + + virtual const ScalarT& theta() const + { + return y_[0]; + } + + virtual ScalarT& P() + { + return f_[0]; + } + virtual const ScalarT& P() const + { + return f_[0]; + } + + virtual ScalarT& Q() + { + return Q_; + } + + virtual const ScalarT& Q() const + { + return Q_; + } + + virtual ScalarT& lambdaP() + { + assert(false); + return thetaB_; + } + + virtual const ScalarT& lambdaP() const + { + assert(false); + return thetaB_; + } + + virtual ScalarT& lambdaQ() + { + assert(false); + return VB_; + } + + virtual const ScalarT& lambdaQ() const + { + assert(false); + return VB_; + } + + virtual ScalarT& PB() + { + assert(false); + return PB_; + } + + virtual const ScalarT& PB() const + { + assert(false); + return PB_; + } + + virtual ScalarT& QB() + { + assert(false); + return QB_; + } + + virtual const ScalarT& QB() const + { + assert(false); + return QB_; + } + + virtual int BusType() const + { + return BaseBus::BusType::PV; + } + + private: + ScalarT V_; ///< Bus voltage magnitude + ScalarT theta0_; ///< Default initial value for phase + ScalarT Q_; ///< Reactive power that generator needs to provide + + ScalarT VB_; + ScalarT thetaB_; + ScalarT PB_; + ScalarT QB_; + }; + +} // namespace GridKit #endif // _BUS_PV_HPP_ diff --git a/src/Model/PowerFlow/Bus/BusSlack.cpp b/src/Model/PowerFlow/Bus/BusSlack.cpp index 5abe099d..98e11d93 100644 --- a/src/Model/PowerFlow/Bus/BusSlack.cpp +++ b/src/Model/PowerFlow/Bus/BusSlack.cpp @@ -57,89 +57,88 @@ * */ -#include -#include #include "BusSlack.hpp" -namespace GridKit { +#include +#include -/*! - * @brief Constructor for a slack bus - * - * Arguments passed to ModelEvaluatorImpl: - * - Number of equations = 0 (size_) - * - Number of variables = 0 (size_) - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ -template -BusSlack::BusSlack() - : BaseBus(0), V_(0.0), theta_(0.0), P_(0.0), Q_(0.0), PB_(0.0), QB_(0.0) +namespace GridKit { - //std::cout << "Create BusSlack..." << std::endl; - //std::cout << "Number of equations is " << size_ << std::endl; + + /*! + * @brief Constructor for a slack bus + * + * Arguments passed to ModelEvaluatorImpl: + * - Number of equations = 0 (size_) + * - Number of variables = 0 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ + template + BusSlack::BusSlack() + : BaseBus(0), V_(0.0), theta_(0.0), P_(0.0), Q_(0.0), PB_(0.0), QB_(0.0) + { + // std::cout << "Create BusSlack..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; size_ = 0; -} + } -/*! - * @brief BusSlack constructor. - * - * Arguments passed to ModelEvaluatorImpl: - * - Number of equations = 0 (size_) - * - Number of variables = 0 (size_) - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ -template -BusSlack::BusSlack(ScalarT V, ScalarT theta) + /*! + * @brief BusSlack constructor. + * + * Arguments passed to ModelEvaluatorImpl: + * - Number of equations = 0 (size_) + * - Number of variables = 0 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ + 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) -{ - //std::cout << "Create BusSlack..." << std::endl; - //std::cout << "Number of equations is " << size_ << std::endl; - P() = 0.0; - Q() = 0.0; + { + // std::cout << "Create BusSlack..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; + P() = 0.0; + Q() = 0.0; size_ = 0; -} + } -template -BusSlack::BusSlack(BusData& data) + template + BusSlack::BusSlack(BusData& data) : BaseBus(data.bus_i), V_(data.Vm), theta_(data.Va) -{ - //std::cout << "Create BusSlack..." << std::endl; - //std::cout << "Number of equations is " << size_ << std::endl; - P() = 0.0; - Q() = 0.0; + { + // std::cout << "Create BusSlack..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; + P() = 0.0; + Q() = 0.0; size_ = 0; -} + } -template -BusSlack::~BusSlack() -{ -} + template + BusSlack::~BusSlack() + { + } -template -int BusSlack::evaluateResidual() -{ + template + int BusSlack::evaluateResidual() + { // std::cout << "Evaluating residual of a slack bus ...\n"; P() = 0.0; Q() = 0.0; return 0; -} + } -template -int BusSlack::evaluateAdjointResidual() -{ + template + int BusSlack::evaluateAdjointResidual() + { PB() = 0.0; QB() = 0.0; return 0; -} - - -// Available template instantiations -template class BusSlack; -template class BusSlack; + } + // Available template instantiations + template class BusSlack; + template class BusSlack; } // namespace GridKit - diff --git a/src/Model/PowerFlow/Bus/BusSlack.hpp b/src/Model/PowerFlow/Bus/BusSlack.hpp index 4a88594e..7bfd011d 100644 --- a/src/Model/PowerFlow/Bus/BusSlack.hpp +++ b/src/Model/PowerFlow/Bus/BusSlack.hpp @@ -65,140 +65,139 @@ namespace GridKit { - /*! - * @brief Implementation of a slack bus. - * - * Slack bus sets voltage _V_ and phase _theta_ as constants. - * Active and reactive power, _P_ and _Q_, are component model outputs, - * but are computed outside the BusSlack class. - * - * - */ - template - class BusSlack : public BaseBus - { - using BaseBus::size_; - using BaseBus::y_; - using BaseBus::yp_; - using BaseBus::f_; - using BaseBus::g_; - using BaseBus::abs_tol_; - using BaseBus::rel_tol_; - - public: - using real_type = typename ModelEvaluatorImpl::real_type; - using BusData = GridKit::PowerSystemData::BusData; - - BusSlack(); - BusSlack(ScalarT V, ScalarT theta); - BusSlack(BusData& data); - virtual ~BusSlack(); - virtual int evaluateResidual(); - virtual int evaluateAdjointResidual(); - - /// @todo Should slack bus allow changing voltage? - virtual ScalarT& V() - { - return V_; - } - - virtual const ScalarT& V() const - { - return V_; - } - - /// @todo Should slack bus allow changing phase? - virtual ScalarT& theta() - { - return theta_; - } - - virtual const ScalarT& theta() const - { - return theta_; - } - - virtual ScalarT& P() - { - return P_; - } - - virtual const ScalarT& P() const - { - return P_; - } - - virtual ScalarT& Q() - { - return Q_; - } - - virtual const ScalarT& Q() const - { - return Q_; - } - - /// @todo Should slack bus allow changing voltage? - virtual ScalarT& lambdaP() - { - return thetaB_; - } - - virtual const ScalarT& lambdaP() const - { - return thetaB_; - } - - /// @todo Should slack bus allow changing phase? - virtual ScalarT& lambdaQ() - { - return VB_; - } - - virtual const ScalarT& lambdaQ() const - { - return VB_; - } - - virtual ScalarT& PB() - { - return PB_; - } - - virtual const ScalarT& PB() const - { - return PB_; - } - - virtual ScalarT& QB() - { - return QB_; - } - - virtual const ScalarT& QB() const - { - return QB_; - } - - virtual int BusType() const - { - return BaseBus::BusType::Slack; - } - - private: - ScalarT V_; - ScalarT theta_; - ScalarT P_; - ScalarT Q_; - - ScalarT VB_; - ScalarT thetaB_; - ScalarT PB_; - ScalarT QB_; - - }; // class BusSlack + /*! + * @brief Implementation of a slack bus. + * + * Slack bus sets voltage _V_ and phase _theta_ as constants. + * Active and reactive power, _P_ and _Q_, are component model outputs, + * but are computed outside the BusSlack class. + * + * + */ + template + class BusSlack : public BaseBus + { + using BaseBus::size_; + using BaseBus::y_; + using BaseBus::yp_; + using BaseBus::f_; + using BaseBus::g_; + using BaseBus::abs_tol_; + using BaseBus::rel_tol_; + + public: + using real_type = typename ModelEvaluatorImpl::real_type; + using BusData = GridKit::PowerSystemData::BusData; + + BusSlack(); + BusSlack(ScalarT V, ScalarT theta); + BusSlack(BusData& data); + virtual ~BusSlack(); + virtual int evaluateResidual(); + virtual int evaluateAdjointResidual(); + + /// @todo Should slack bus allow changing voltage? + virtual ScalarT& V() + { + return V_; + } -} // namespace GridKit + virtual const ScalarT& V() const + { + return V_; + } + + /// @todo Should slack bus allow changing phase? + virtual ScalarT& theta() + { + return theta_; + } + + virtual const ScalarT& theta() const + { + return theta_; + } + + virtual ScalarT& P() + { + return P_; + } + + virtual const ScalarT& P() const + { + return P_; + } + + virtual ScalarT& Q() + { + return Q_; + } + + virtual const ScalarT& Q() const + { + return Q_; + } + + /// @todo Should slack bus allow changing voltage? + virtual ScalarT& lambdaP() + { + return thetaB_; + } + + virtual const ScalarT& lambdaP() const + { + return thetaB_; + } + /// @todo Should slack bus allow changing phase? + virtual ScalarT& lambdaQ() + { + return VB_; + } + + virtual const ScalarT& lambdaQ() const + { + return VB_; + } + + virtual ScalarT& PB() + { + return PB_; + } + + virtual const ScalarT& PB() const + { + return PB_; + } + + virtual ScalarT& QB() + { + return QB_; + } + + virtual const ScalarT& QB() const + { + return QB_; + } + + virtual int BusType() const + { + return BaseBus::BusType::Slack; + } + + private: + ScalarT V_; + ScalarT theta_; + ScalarT P_; + ScalarT Q_; + + ScalarT VB_; + ScalarT thetaB_; + ScalarT PB_; + ScalarT QB_; + + }; // class BusSlack + +} // namespace GridKit #endif // _BUS_SLACK_HPP_ diff --git a/src/Model/PowerFlow/Generator/GeneratorBase.hpp b/src/Model/PowerFlow/Generator/GeneratorBase.hpp index 29609a6f..18e60638 100644 --- a/src/Model/PowerFlow/Generator/GeneratorBase.hpp +++ b/src/Model/PowerFlow/Generator/GeneratorBase.hpp @@ -59,67 +59,108 @@ #pragma once -#include #include +#include + namespace GridKit { - template class BaseBus; + template + class BaseBus; } - namespace GridKit { - /** - * @brief Generator base class template - * - * @tparam ScalarT - Scalar type - * @tparam IdxT - Matrix and vector index type - */ - template - class GeneratorBase : public ModelEvaluatorImpl + /** + * @brief Generator base class template + * + * @tparam ScalarT - Scalar type + * @tparam IdxT - Matrix and vector index type + */ + template + class GeneratorBase : public ModelEvaluatorImpl + { + protected: + using ModelEvaluatorImpl::size_; + using ModelEvaluatorImpl::nnz_; + using ModelEvaluatorImpl::time_; + using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::yp_; + using ModelEvaluatorImpl::tag_; + using ModelEvaluatorImpl::f_; + using ModelEvaluatorImpl::g_; + using ModelEvaluatorImpl::yB_; + using ModelEvaluatorImpl::ypB_; + using ModelEvaluatorImpl::fB_; + using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::param_; + + using bus_type = BaseBus; + using real_type = typename ModelEvaluatorImpl::real_type; + + public: + GeneratorBase() { - protected: - using ModelEvaluatorImpl::size_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::alpha_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::yp_; - using ModelEvaluatorImpl::tag_; - using ModelEvaluatorImpl::f_; - using ModelEvaluatorImpl::g_; - using ModelEvaluatorImpl::yB_; - using ModelEvaluatorImpl::ypB_; - using ModelEvaluatorImpl::fB_; - using ModelEvaluatorImpl::gB_; - using ModelEvaluatorImpl::param_; - - using bus_type = BaseBus; - using real_type = typename ModelEvaluatorImpl::real_type; - - public: - GeneratorBase(){} - virtual ~GeneratorBase(){} - - virtual int allocate() { return 0;} - virtual int initialize() { return 0;} - virtual int tagDifferentiable() { return 0;} - virtual int evaluateResidual() { return 0;} - virtual int evaluateJacobian() { return 0;} - virtual int evaluateIntegrand() { return 0;} - - virtual int initializeAdjoint() { return 0;} - virtual int evaluateAdjointResidual() { return 0;} - //virtual int evaluateAdjointJacobian(); - virtual int evaluateAdjointIntegrand() { return 0;} - - void updateTime(real_type, real_type) {} - - virtual ScalarT& P() = 0; - virtual const ScalarT& P() const = 0; - virtual ScalarT& Q() = 0; - virtual const ScalarT& Q() const = 0; - }; -} + } + + virtual ~GeneratorBase() + { + } + + virtual int allocate() + { + return 0; + } + + virtual int initialize() + { + return 0; + } + + virtual int tagDifferentiable() + { + return 0; + } + + virtual int evaluateResidual() + { + return 0; + } + + virtual int evaluateJacobian() + { + return 0; + } + + virtual int evaluateIntegrand() + { + return 0; + } + + virtual int initializeAdjoint() + { + return 0; + } + + virtual int evaluateAdjointResidual() + { + return 0; + } + + // virtual int evaluateAdjointJacobian(); + virtual int evaluateAdjointIntegrand() + { + return 0; + } + + void updateTime(real_type, real_type) + { + } + virtual ScalarT& P() = 0; + virtual const ScalarT& P() const = 0; + virtual ScalarT& Q() = 0; + virtual const ScalarT& Q() const = 0; + }; +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator/GeneratorFactory.hpp b/src/Model/PowerFlow/Generator/GeneratorFactory.hpp index 571224b6..7c6e5ba2 100644 --- a/src/Model/PowerFlow/Generator/GeneratorFactory.hpp +++ b/src/Model/PowerFlow/Generator/GeneratorFactory.hpp @@ -59,44 +59,44 @@ #pragma once -#include #include -#include #include #include +#include +#include +namespace GridKit +{ -namespace GridKit { - - template - class GeneratorFactory - { - public: - using real_type = typename ModelEvaluatorImpl::real_type; - using GenData = GridKit::PowerSystemData::GenData; + template + class GeneratorFactory + { + public: + using real_type = typename ModelEvaluatorImpl::real_type; + using GenData = GridKit::PowerSystemData::GenData; - GeneratorFactory() = delete; + GeneratorFactory() = delete; - static GeneratorBase* create(BaseBus* bus, GenData& data) - { - GeneratorBase* gen = nullptr; - switch(bus->BusType()) - { - case 1: - gen = new GeneratorPQ(bus, data); - break; - case 2: - gen = new GeneratorPV(bus, data); - break; - case 3: - gen = new GeneratorSlack(bus, data); - break; - default: - // Throw exception - std::cout << "Generator type " << bus->BusType() << " unrecognized.\n"; - } - return gen; - } - }; + static GeneratorBase* create(BaseBus* bus, GenData& data) + { + GeneratorBase* gen = nullptr; + switch (bus->BusType()) + { + case 1: + gen = new GeneratorPQ(bus, data); + break; + case 2: + gen = new GeneratorPV(bus, data); + break; + case 3: + gen = new GeneratorSlack(bus, data); + break; + default: + // Throw exception + std::cout << "Generator type " << bus->BusType() << " unrecognized.\n"; + } + return gen; + } + }; } // namespace GridKit \ No newline at end of file diff --git a/src/Model/PowerFlow/Generator/GeneratorPQ.cpp b/src/Model/PowerFlow/Generator/GeneratorPQ.cpp index db59fc24..0991cf74 100644 --- a/src/Model/PowerFlow/Generator/GeneratorPQ.cpp +++ b/src/Model/PowerFlow/Generator/GeneratorPQ.cpp @@ -57,112 +57,111 @@ * */ +#include "GeneratorPQ.hpp" -#include #include +#include #include -#include "GeneratorPQ.hpp" -#include - -namespace GridKit { - -/*! - * @brief Constructor for a constant load model - * - * Calls default ModelEvaluatorImpl constructor. - */ -template -GeneratorPQ::GeneratorPQ(bus_type* bus, GenData& data) - : P_(data.Pg), - Q_(data.Qg), - bus_(bus) -{ - //std::cout << "Create a load model with " << size_ << " variables ...\n"; - size_ = 0; -} +#include -template -GeneratorPQ::~GeneratorPQ() +namespace GridKit { -} -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int GeneratorPQ::allocate() -{ + /*! + * @brief Constructor for a constant load model + * + * Calls default ModelEvaluatorImpl constructor. + */ + + template + GeneratorPQ::GeneratorPQ(bus_type* bus, GenData& data) + : P_(data.Pg), + Q_(data.Qg), + bus_(bus) + { + // std::cout << "Create a load model with " << size_ << " variables ...\n"; + size_ = 0; + } + + template + GeneratorPQ::~GeneratorPQ() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int GeneratorPQ::allocate() + { return 0; -} - -/** - * Initialization of the grid model - */ -template -int GeneratorPQ::initialize() -{ + } + + /** + * Initialization of the grid model + */ + template + int GeneratorPQ::initialize() + { return 0; -} - -/* - * \brief Identify differential variables - */ -template -int GeneratorPQ::tagDifferentiable() -{ + } + + /* + * \brief Identify differential variables + */ + template + int GeneratorPQ::tagDifferentiable() + { return 0; -} - -/** - * @brief Contributes to the bus residual. - * - * Must be connected to a PQ bus. - */ -template -int GeneratorPQ::evaluateResidual() -{ + } + + /** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ + template + int GeneratorPQ::evaluateResidual() + { // std::cout << "Evaluating load residual ...\n"; bus_->P() += P_; bus_->Q() += Q_; return 0; -} + } -template -int GeneratorPQ::evaluateJacobian() -{ + template + int GeneratorPQ::evaluateJacobian() + { return 0; -} + } -template -int GeneratorPQ::evaluateIntegrand() -{ + template + int GeneratorPQ::evaluateIntegrand() + { return 0; -} + } -template -int GeneratorPQ::initializeAdjoint() -{ + template + int GeneratorPQ::initializeAdjoint() + { return 0; -} + } -template -int GeneratorPQ::evaluateAdjointResidual() -{ + template + int GeneratorPQ::evaluateAdjointResidual() + { return 0; -} + } -template -int GeneratorPQ::evaluateAdjointIntegrand() -{ + template + int GeneratorPQ::evaluateAdjointIntegrand() + { return 0; -} - - -// Available template instantiations -template class GeneratorPQ; -template class GeneratorPQ; - + } -} //namespace GridKit + // Available template instantiations + template class GeneratorPQ; + template class GeneratorPQ; +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator/GeneratorPQ.hpp b/src/Model/PowerFlow/Generator/GeneratorPQ.hpp index 2b3b8c65..c497a3c5 100644 --- a/src/Model/PowerFlow/Generator/GeneratorPQ.hpp +++ b/src/Model/PowerFlow/Generator/GeneratorPQ.hpp @@ -60,84 +60,84 @@ #pragma once #include + +#include "GeneratorBase.hpp" #include #include -#include "GeneratorBase.hpp" namespace GridKit { - template class BaseBus; + template + class BaseBus; } - namespace GridKit { - /*! - * @brief Implementation of a PV generator. - * - */ - template - class GeneratorPQ : public GeneratorBase - { - using GeneratorBase::size_; - using GeneratorBase::nnz_; - using GeneratorBase::time_; - using GeneratorBase::alpha_; - using GeneratorBase::y_; - using GeneratorBase::yp_; - using GeneratorBase::tag_; - using GeneratorBase::f_; - using GeneratorBase::g_; - using GeneratorBase::yB_; - using GeneratorBase::ypB_; - using GeneratorBase::fB_; - using GeneratorBase::gB_; - using GeneratorBase::param_; + /*! + * @brief Implementation of a PV generator. + * + */ + template + class GeneratorPQ : public GeneratorBase + { + using GeneratorBase::size_; + using GeneratorBase::nnz_; + using GeneratorBase::time_; + using GeneratorBase::alpha_; + using GeneratorBase::y_; + using GeneratorBase::yp_; + using GeneratorBase::tag_; + using GeneratorBase::f_; + using GeneratorBase::g_; + using GeneratorBase::yB_; + using GeneratorBase::ypB_; + using GeneratorBase::fB_; + using GeneratorBase::gB_; + using GeneratorBase::param_; - using bus_type = BaseBus; - using real_type = typename ModelEvaluatorImpl::real_type; - using GenData = GridKit::PowerSystemData::GenData; + using bus_type = BaseBus; + using real_type = typename ModelEvaluatorImpl::real_type; + using GenData = GridKit::PowerSystemData::GenData; - public: - GeneratorPQ(bus_type* bus, GenData& data); - virtual ~GeneratorPQ(); + public: + GeneratorPQ(bus_type* bus, GenData& data); + virtual ~GeneratorPQ(); - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - virtual ScalarT& P() - { - return P_; - } + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); - virtual const ScalarT& P() const - { - return P_; - } + virtual ScalarT& P() + { + return P_; + } - virtual ScalarT& Q() - { - return Q_; - } + virtual const ScalarT& P() const + { + return P_; + } - virtual const ScalarT& Q() const - { - return Q_; - } + virtual ScalarT& Q() + { + return Q_; + } - private: - ScalarT P_; - ScalarT Q_; - bus_type* bus_; - }; -} + virtual const ScalarT& Q() const + { + return Q_; + } + private: + ScalarT P_; + ScalarT Q_; + bus_type* bus_; + }; +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator/GeneratorPV.cpp b/src/Model/PowerFlow/Generator/GeneratorPV.cpp index c1a15693..dfc8c897 100644 --- a/src/Model/PowerFlow/Generator/GeneratorPV.cpp +++ b/src/Model/PowerFlow/Generator/GeneratorPV.cpp @@ -57,112 +57,111 @@ * */ +#include "GeneratorPV.hpp" -#include #include +#include #include -#include "GeneratorPV.hpp" -#include - -namespace GridKit { - -/*! - * @brief Constructor for a constant load model - * - * Calls default ModelEvaluatorImpl constructor. - */ -template -GeneratorPV::GeneratorPV(bus_type* bus, GenData& data) - : P_(data.Pg), - // Q_(data.Qg), - bus_(bus) -{ - //std::cout << "Create a load model with " << size_ << " variables ...\n"; - size_ = 0; -} +#include -template -GeneratorPV::~GeneratorPV() +namespace GridKit { -} -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int GeneratorPV::allocate() -{ + /*! + * @brief Constructor for a constant load model + * + * Calls default ModelEvaluatorImpl constructor. + */ + + template + GeneratorPV::GeneratorPV(bus_type* bus, GenData& data) + : P_(data.Pg), + // Q_(data.Qg), + bus_(bus) + { + // std::cout << "Create a load model with " << size_ << " variables ...\n"; + size_ = 0; + } + + template + GeneratorPV::~GeneratorPV() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int GeneratorPV::allocate() + { return 0; -} - -/** - * Initialization of the grid model - */ -template -int GeneratorPV::initialize() -{ + } + + /** + * Initialization of the grid model + */ + template + int GeneratorPV::initialize() + { return 0; -} - -/* - * \brief Identify differential variables - */ -template -int GeneratorPV::tagDifferentiable() -{ + } + + /* + * \brief Identify differential variables + */ + template + int GeneratorPV::tagDifferentiable() + { return 0; -} - -/** - * @brief Contributes to the bus residual. - * - * Must be connected to a PQ bus. - */ -template -int GeneratorPV::evaluateResidual() -{ + } + + /** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ + template + int GeneratorPV::evaluateResidual() + { // std::cout << "Evaluating load residual ...\n"; bus_->P() += P_; // bus_->Q() += Q_; return 0; -} + } -template -int GeneratorPV::evaluateJacobian() -{ + template + int GeneratorPV::evaluateJacobian() + { return 0; -} + } -template -int GeneratorPV::evaluateIntegrand() -{ + template + int GeneratorPV::evaluateIntegrand() + { return 0; -} + } -template -int GeneratorPV::initializeAdjoint() -{ + template + int GeneratorPV::initializeAdjoint() + { return 0; -} + } -template -int GeneratorPV::evaluateAdjointResidual() -{ + template + int GeneratorPV::evaluateAdjointResidual() + { return 0; -} + } -template -int GeneratorPV::evaluateAdjointIntegrand() -{ + template + int GeneratorPV::evaluateAdjointIntegrand() + { return 0; -} - - -// Available template instantiations -template class GeneratorPV; -template class GeneratorPV; - + } -} //namespace GridKit + // Available template instantiations + template class GeneratorPV; + template class GeneratorPV; +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator/GeneratorPV.hpp b/src/Model/PowerFlow/Generator/GeneratorPV.hpp index 68671a08..e7a48597 100644 --- a/src/Model/PowerFlow/Generator/GeneratorPV.hpp +++ b/src/Model/PowerFlow/Generator/GeneratorPV.hpp @@ -60,87 +60,87 @@ #pragma once #include + +#include "GeneratorBase.hpp" #include #include -#include "GeneratorBase.hpp" namespace GridKit { - template class BaseBus; + template + class BaseBus; } - namespace GridKit { - /*! - * @brief Implementation of a PV generator. - * - */ - template - class GeneratorPV : public GeneratorBase - { - using GeneratorBase::size_; - using GeneratorBase::nnz_; - using GeneratorBase::time_; - using GeneratorBase::alpha_; - using GeneratorBase::y_; - using GeneratorBase::yp_; - using GeneratorBase::tag_; - using GeneratorBase::f_; - using GeneratorBase::g_; - using GeneratorBase::yB_; - using GeneratorBase::ypB_; - using GeneratorBase::fB_; - using GeneratorBase::gB_; - using GeneratorBase::param_; + /*! + * @brief Implementation of a PV generator. + * + */ + template + class GeneratorPV : public GeneratorBase + { + using GeneratorBase::size_; + using GeneratorBase::nnz_; + using GeneratorBase::time_; + using GeneratorBase::alpha_; + using GeneratorBase::y_; + using GeneratorBase::yp_; + using GeneratorBase::tag_; + using GeneratorBase::f_; + using GeneratorBase::g_; + using GeneratorBase::yB_; + using GeneratorBase::ypB_; + using GeneratorBase::fB_; + using GeneratorBase::gB_; + using GeneratorBase::param_; - using bus_type = BaseBus; - using real_type = typename ModelEvaluatorImpl::real_type; - using GenData = GridKit::PowerSystemData::GenData; + using bus_type = BaseBus; + using real_type = typename ModelEvaluatorImpl::real_type; + using GenData = GridKit::PowerSystemData::GenData; - public: - GeneratorPV(bus_type* bus, GenData& data); - virtual ~GeneratorPV(); + public: + GeneratorPV(bus_type* bus, GenData& data); + virtual ~GeneratorPV(); - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - virtual ScalarT& P() - { - return P_; - } + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); - virtual const ScalarT& P() const - { - return P_; - } + virtual ScalarT& P() + { + return P_; + } - /// @brief Reactive power excess on PV bus - /// @return reference to negative PV generator reactive power - virtual ScalarT& Q() - { - return (bus_->Q()); - } + virtual const ScalarT& P() const + { + return P_; + } - /// @brief Reactive power excess on PV bus - /// @return const reference to negative PV generator reactive power - virtual const ScalarT& Q() const - { - return (bus_->Q()); - } + /// @brief Reactive power excess on PV bus + /// @return reference to negative PV generator reactive power + virtual ScalarT& Q() + { + return (bus_->Q()); + } - private: - ScalarT P_; - bus_type* bus_; - }; -} + /// @brief Reactive power excess on PV bus + /// @return const reference to negative PV generator reactive power + virtual const ScalarT& Q() const + { + return (bus_->Q()); + } + private: + ScalarT P_; + bus_type* bus_; + }; +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator/GeneratorSlack.cpp b/src/Model/PowerFlow/Generator/GeneratorSlack.cpp index 623cd32b..d0a6a1c6 100644 --- a/src/Model/PowerFlow/Generator/GeneratorSlack.cpp +++ b/src/Model/PowerFlow/Generator/GeneratorSlack.cpp @@ -57,112 +57,109 @@ * */ +#include "GeneratorSlack.hpp" -#include #include +#include #include -#include "GeneratorSlack.hpp" -#include - -namespace GridKit { - -/*! - * @brief Constructor for a constant load model - * - * Calls default ModelEvaluatorImpl constructor. - */ -template -GeneratorSlack::GeneratorSlack(bus_type* bus, GenData& data) - : bus_(bus) -{ - //std::cout << "Create a load model with " << size_ << " variables ...\n"; - size_ = 0; -} +#include -template -GeneratorSlack::~GeneratorSlack() +namespace GridKit { -} -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int GeneratorSlack::allocate() -{ + /*! + * @brief Constructor for a constant load model + * + * Calls default ModelEvaluatorImpl constructor. + */ + + template + GeneratorSlack::GeneratorSlack(bus_type* bus, GenData& data) + : bus_(bus) + { + // std::cout << "Create a load model with " << size_ << " variables ...\n"; + size_ = 0; + } + + template + GeneratorSlack::~GeneratorSlack() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int GeneratorSlack::allocate() + { return 0; -} - -/** - * Initialization of the grid model - */ -template -int GeneratorSlack::initialize() -{ + } + + /** + * Initialization of the grid model + */ + template + int GeneratorSlack::initialize() + { return 0; -} - -/* - * \brief Identify differential variables - */ -template -int GeneratorSlack::tagDifferentiable() -{ + } + + /* + * \brief Identify differential variables + */ + template + int GeneratorSlack::tagDifferentiable() + { return 0; -} - -/** - * @brief Contributes to the bus residual. - * - * Must be connected to a PQ bus. - */ -template -int GeneratorSlack::evaluateResidual() -{ + } + + /** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ + template + int GeneratorSlack::evaluateResidual() + { // std::cout << "Evaluating load residual ...\n"; // bus_->P() += P_; // bus_->Q() += Q_; return 0; -} + } -template -int GeneratorSlack::evaluateJacobian() -{ + template + int GeneratorSlack::evaluateJacobian() + { return 0; -} + } -template -int GeneratorSlack::evaluateIntegrand() -{ + template + int GeneratorSlack::evaluateIntegrand() + { return 0; -} + } -template -int GeneratorSlack::initializeAdjoint() -{ + template + int GeneratorSlack::initializeAdjoint() + { return 0; -} + } -template -int GeneratorSlack::evaluateAdjointResidual() -{ + template + int GeneratorSlack::evaluateAdjointResidual() + { return 0; -} + } -template -int GeneratorSlack::evaluateAdjointIntegrand() -{ + template + int GeneratorSlack::evaluateAdjointIntegrand() + { return 0; -} - - - - -// Available template instantiations -template class GeneratorSlack; -template class GeneratorSlack; - + } -} //namespace GridKit + // Available template instantiations + template class GeneratorSlack; + template class GeneratorSlack; +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator/GeneratorSlack.hpp b/src/Model/PowerFlow/Generator/GeneratorSlack.hpp index 2b7fdea6..1ffd56bb 100644 --- a/src/Model/PowerFlow/Generator/GeneratorSlack.hpp +++ b/src/Model/PowerFlow/Generator/GeneratorSlack.hpp @@ -60,85 +60,84 @@ #pragma once // #include +#include + #include "GeneratorBase.hpp" #include -#include namespace GridKit { - template class BaseBus; + template + class BaseBus; } - namespace GridKit { - /*! - * @brief Implementation of a power grid. - * - */ - template - class GeneratorSlack : public GeneratorBase - { - using GeneratorBase::size_; - using GeneratorBase::nnz_; - using GeneratorBase::time_; - using GeneratorBase::alpha_; - using GeneratorBase::y_; - using GeneratorBase::yp_; - using GeneratorBase::tag_; - using GeneratorBase::f_; - using GeneratorBase::g_; - using GeneratorBase::yB_; - using GeneratorBase::ypB_; - using GeneratorBase::fB_; - using GeneratorBase::gB_; - using GeneratorBase::param_; - - using bus_type = BaseBus; - using real_type = typename ModelEvaluatorImpl::real_type; - using GenData = GridKit::PowerSystemData::GenData; - // typedef typename ModelEvaluatorImpl::real_type real_type; - // typedef BaseBus bus_type; + /*! + * @brief Implementation of a power grid. + * + */ + template + class GeneratorSlack : public GeneratorBase + { + using GeneratorBase::size_; + using GeneratorBase::nnz_; + using GeneratorBase::time_; + using GeneratorBase::alpha_; + using GeneratorBase::y_; + using GeneratorBase::yp_; + using GeneratorBase::tag_; + using GeneratorBase::f_; + using GeneratorBase::g_; + using GeneratorBase::yB_; + using GeneratorBase::ypB_; + using GeneratorBase::fB_; + using GeneratorBase::gB_; + using GeneratorBase::param_; - public: - GeneratorSlack(bus_type* bus, GenData& data); - virtual ~GeneratorSlack(); + using bus_type = BaseBus; + using real_type = typename ModelEvaluatorImpl::real_type; + using GenData = GridKit::PowerSystemData::GenData; + // typedef typename ModelEvaluatorImpl::real_type real_type; + // typedef BaseBus bus_type; - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + public: + GeneratorSlack(bus_type* bus, GenData& data); + virtual ~GeneratorSlack(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); - virtual ScalarT& P() - { - return bus_->P(); - } + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); - virtual const ScalarT& P() const - { - return bus_->P(); - } + virtual ScalarT& P() + { + return bus_->P(); + } - virtual ScalarT& Q() - { - return bus_->Q(); - } + virtual const ScalarT& P() const + { + return bus_->P(); + } - virtual const ScalarT& Q() const - { - return bus_->Q(); - } + virtual ScalarT& Q() + { + return bus_->Q(); + } - - private: - bus_type* bus_; - }; -} + virtual const ScalarT& Q() const + { + return bus_->Q(); + } + private: + bus_type* bus_; + }; +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator2/Generator2.cpp b/src/Model/PowerFlow/Generator2/Generator2.cpp index e4ac50a7..d482f486 100644 --- a/src/Model/PowerFlow/Generator2/Generator2.cpp +++ b/src/Model/PowerFlow/Generator2/Generator2.cpp @@ -57,177 +57,176 @@ * */ -#include -#include -#include #include "Generator2.hpp" -namespace GridKit { +#include +#include -/*! - * @brief Constructor for a simple generator model - * - * Arguments passed to ModelEvaluatorImpl: - * - Number of equations = 2 - * - Number of quadratures = 1 - * - Number of optimization parameters = 1 - */ -template -Generator2::Generator2(bus_type* bus) - : ModelEvaluatorImpl(2, 1, 1), - H_(5.0), - D_(0.005), - Pm_(0.7), - Xdp_(0.5), - Eqp_(0.93), - omega_s_(1.0), - omega_b_(2.0*60.0*M_PI), - omega_up_(omega_s_ + 0.0002), - omega_lo_(omega_s_ - 0.0002), - theta_s_(1.0), - c_(10000.0), - beta_(2), - bus_(bus) -{ -} +#include -template -Generator2::~Generator2() +namespace GridKit { -} -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int Generator2::allocate() -{ + /*! + * @brief Constructor for a simple generator model + * + * Arguments passed to ModelEvaluatorImpl: + * - Number of equations = 2 + * - Number of quadratures = 1 + * - Number of optimization parameters = 1 + */ + template + Generator2::Generator2(bus_type* bus) + : ModelEvaluatorImpl(2, 1, 1), + H_(5.0), + D_(0.005), + Pm_(0.7), + Xdp_(0.5), + Eqp_(0.93), + omega_s_(1.0), + omega_b_(2.0 * 60.0 * M_PI), + omega_up_(omega_s_ + 0.0002), + omega_lo_(omega_s_ - 0.0002), + theta_s_(1.0), + c_(10000.0), + beta_(2), + bus_(bus) + { + } + + template + Generator2::~Generator2() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int Generator2::allocate() + { tag_.resize(size_); return 0; -} + } -template -int Generator2::tagDifferentiable() -{ + template + int Generator2::tagDifferentiable() + { tag_[0] = true; tag_[1] = true; return 0; -} + } -template -int Generator2::initialize() -{ + template + int Generator2::initialize() + { // Set optimization parameter value and bounds - param_[0] = Pm_; + param_[0] = Pm_; param_up_[0] = 1.5; param_lo_[0] = 0.5; - y_[0] = asin((Pm_*Xdp_)/(Eqp_*V())) + theta(); // <~ asin(Pm/Pmax) - y_[1] = omega_s_; + y_[0] = asin((Pm_ * Xdp_) / (Eqp_ * V())) + theta(); // <~ asin(Pm/Pmax) + y_[1] = omega_s_; yp_[0] = 0.0; yp_[1] = 0.0; return 0; -} + } -template -int Generator2::evaluateResidual() -{ - f_[0] = -yp_[0] + omega_b_*(y_[1]-omega_s_); - f_[1] = -yp_[1] + omega_s_/(2.0*H_)*( param_[0] - Eqp_/Xdp_*V()*sin(y_[0] - theta()) - D_*(y_[1]-omega_s_) ); + template + int Generator2::evaluateResidual() + { + f_[0] = -yp_[0] + omega_b_ * (y_[1] - omega_s_); + f_[1] = -yp_[1] + omega_s_ / (2.0 * H_) * (param_[0] - Eqp_ / Xdp_ * V() * sin(y_[0] - theta()) - D_ * (y_[1] - omega_s_)); return 0; -} + } -template -int Generator2::evaluateJacobian() -{ + template + int Generator2::evaluateJacobian() + { std::cout << "Evaluate Jacobian for Gen2..." << std::endl; std::cout << "Jacobian evaluation not implemented!" << std::endl; return 0; -} + } -template -int Generator2::evaluateIntegrand() -{ + template + int Generator2::evaluateIntegrand() + { g_[0] = frequencyPenalty(y_[1]); return 0; -} + } -template -int Generator2::initializeAdjoint() -{ - yB_[0] = 0.0; - yB_[1] = 0.0; + template + int Generator2::initializeAdjoint() + { + yB_[0] = 0.0; + yB_[1] = 0.0; ypB_[0] = 0.0; ypB_[1] = frequencyPenaltyDer(y_[1]); return 0; -} + } -template -int Generator2::evaluateAdjointResidual() -{ - fB_[0] = -ypB_[0] + omega_s_/(2.0*H_)*Eqp_/Xdp_*V()*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]); + template + int Generator2::evaluateAdjointResidual() + { + fB_[0] = -ypB_[0] + omega_s_ / (2.0 * H_) * Eqp_ / Xdp_ * V() * 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]); return 0; -} - -// template -// int Generator2::evaluateAdjointJacobian() -// { -// std::cout << "Evaluate adjoint Jacobian for Gen2..." << std::endl; -// std::cout << "Adjoint Jacobian evaluation not implemented!" << std::endl; -// return 0; -// } - -template -int Generator2::evaluateAdjointIntegrand() -{ + } + + // template + // int Generator2::evaluateAdjointJacobian() + // { + // std::cout << "Evaluate adjoint Jacobian for Gen2..." << std::endl; + // std::cout << "Adjoint Jacobian evaluation not implemented!" << std::endl; + // return 0; + // } + + template + int Generator2::evaluateAdjointIntegrand() + { // std::cout << "Evaluate adjoint Integrand for Gen2..." << std::endl; - gB_[0] = -omega_s_/(2.0*H_) * yB_[1]; + gB_[0] = -omega_s_ / (2.0 * H_) * yB_[1]; return 0; -} - - -// -// Private functions -// - -/** - * Frequency penalty is used as the objective function for the generator model. - */ -template -ScalarT Generator2::frequencyPenalty(ScalarT omega) -{ + } + + // + // Private functions + // + + /** + * Frequency penalty is used as the objective function for the generator model. + */ + template + ScalarT Generator2::frequencyPenalty(ScalarT omega) + { return c_ * 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. - */ -template -ScalarT Generator2::frequencyPenaltyDer(ScalarT omega) -{ + } + + /** + * 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) + { if (omega > omega_up_) { - return beta_ * c_ * pow(omega - omega_up_, beta_ - 1.0); + return beta_ * c_ * pow(omega - omega_up_, beta_ - 1.0); } else if (omega < omega_lo_) { - return beta_ * c_ * pow(omega - omega_lo_, beta_ - 1.0); + return beta_ * c_ * pow(omega - omega_lo_, beta_ - 1.0); } else { - return 0.0; + return 0.0; } -} - - - -// Available template instantiations -template class Generator2; -template class Generator2; + } + // Available template instantiations + template class Generator2; + template class Generator2; } // namespace GridKit \ No newline at end of file diff --git a/src/Model/PowerFlow/Generator2/Generator2.hpp b/src/Model/PowerFlow/Generator2/Generator2.hpp index 51aaf28f..00be740b 100644 --- a/src/Model/PowerFlow/Generator2/Generator2.hpp +++ b/src/Model/PowerFlow/Generator2/Generator2.hpp @@ -61,99 +61,100 @@ namespace GridKit { - template class BaseBus; + template + class BaseBus; } namespace GridKit { - /*! - * @brief Implementation of a second order generator model. - * - */ - template - class Generator2 : public ModelEvaluatorImpl + /*! + * @brief Implementation of a second order generator model. + * + */ + template + class Generator2 : public ModelEvaluatorImpl + { + using ModelEvaluatorImpl::size_; + using ModelEvaluatorImpl::nnz_; + using ModelEvaluatorImpl::time_; + using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::yp_; + using ModelEvaluatorImpl::tag_; + using ModelEvaluatorImpl::f_; + using ModelEvaluatorImpl::g_; + using ModelEvaluatorImpl::yB_; + using ModelEvaluatorImpl::ypB_; + using ModelEvaluatorImpl::fB_; + using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::param_; + using ModelEvaluatorImpl::param_up_; + using ModelEvaluatorImpl::param_lo_; + + typedef typename ModelEvaluatorImpl::real_type real_type; + typedef BaseBus bus_type; + + public: + Generator2(bus_type* bus); + virtual ~Generator2(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + void updateTime(real_type t, real_type a) + { + time_ = t; + alpha_ = a; + } + + const ScalarT& V() const + { + return bus_->V(); + } + + ScalarT& V() + { + return bus_->V(); + } + + const ScalarT& theta() const + { + return bus_->theta(); + } + + ScalarT& theta() { - using ModelEvaluatorImpl::size_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::alpha_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::yp_; - using ModelEvaluatorImpl::tag_; - using ModelEvaluatorImpl::f_; - using ModelEvaluatorImpl::g_; - using ModelEvaluatorImpl::yB_; - using ModelEvaluatorImpl::ypB_; - using ModelEvaluatorImpl::fB_; - using ModelEvaluatorImpl::gB_; - using ModelEvaluatorImpl::param_; - using ModelEvaluatorImpl::param_up_; - using ModelEvaluatorImpl::param_lo_; - - typedef typename ModelEvaluatorImpl::real_type real_type; - typedef BaseBus bus_type; - - public: - Generator2(bus_type* bus); - virtual ~Generator2(); - - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); - - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - void updateTime(real_type t, real_type a) - { - time_ = t; - alpha_ = a; - } - - const ScalarT& V() const - { - return bus_->V(); - } - - ScalarT& V() - { - return bus_->V(); - } - - const ScalarT& theta() const - { - return bus_->theta(); - } - - ScalarT& theta() - { - return bus_->theta(); - } - - private: - inline ScalarT frequencyPenalty(ScalarT omega); - inline ScalarT frequencyPenaltyDer(ScalarT omega); - - private: - real_type H_; - real_type D_; - real_type Pm_; - real_type Xdp_; - real_type Eqp_; - real_type omega_s_; - real_type omega_b_; - real_type omega_up_; - real_type omega_lo_; - real_type theta_s_; - real_type c_; - real_type beta_; - - bus_type* bus_; - }; + return bus_->theta(); + } + + private: + inline ScalarT frequencyPenalty(ScalarT omega); + inline ScalarT frequencyPenaltyDer(ScalarT omega); + + private: + real_type H_; + real_type D_; + real_type Pm_; + real_type Xdp_; + real_type Eqp_; + real_type omega_s_; + real_type omega_b_; + real_type omega_up_; + real_type omega_lo_; + real_type theta_s_; + real_type c_; + real_type beta_; + + bus_type* bus_; + }; } // namespace GridKit \ No newline at end of file diff --git a/src/Model/PowerFlow/Generator4/Generator4.cpp b/src/Model/PowerFlow/Generator4/Generator4.cpp index 70fa61ec..f88cc84e 100644 --- a/src/Model/PowerFlow/Generator4/Generator4.cpp +++ b/src/Model/PowerFlow/Generator4/Generator4.cpp @@ -57,111 +57,113 @@ * */ - -#include -#include -#include #include "Generator4.hpp" -namespace GridKit { +#include +#include -/*! - * @brief Constructor for a simple generator model - * - * Arguments passed to ModelEvaluatorImpl: - * - Number of equations = 4 differential + 2 algebraic = 6 - * - Number of quadratures = 1 - * - Number of optimization parameters = 2 - */ -template -Generator4::Generator4(bus_type* bus, ScalarT P0, ScalarT Q0) - : ModelEvaluatorImpl(6, 1, 2), - H_(5.0), - D_(0.04), - Xq_(0.85), - Xd_(1.05), - Xqp_(0.35), - Xdp_(0.35), - Rs_(0.01), - Tq0p_(1.0), // [s] - Td0p_(8.0), // [s] - Ef_(1.45), - Pm_(1.0), - omega_s_(1.0), - omega_b_(2.0*60.0*M_PI), - omega_up_(omega_s_ + 0.0001), - omega_lo_(omega_s_ - 0.0001), - c_(10000.0), - beta_(2), - P0_(P0), - Q0_(Q0), - bus_(bus) -{ -} +#include -template -Generator4::~Generator4() +namespace GridKit { -} -/*! - * @brief This function will be used to allocate sparse Jacobian matrices. - * - */ -template -int Generator4::allocate() -{ - //std::cout << "Allocate Generator4..." << std::endl; + /*! + * @brief Constructor for a simple generator model + * + * Arguments passed to ModelEvaluatorImpl: + * - Number of equations = 4 differential + 2 algebraic = 6 + * - Number of quadratures = 1 + * - Number of optimization parameters = 2 + */ + template + Generator4::Generator4(bus_type* bus, ScalarT P0, ScalarT Q0) + : ModelEvaluatorImpl(6, 1, 2), + H_(5.0), + D_(0.04), + Xq_(0.85), + Xd_(1.05), + Xqp_(0.35), + Xdp_(0.35), + Rs_(0.01), + Tq0p_(1.0), // [s] + Td0p_(8.0), // [s] + Ef_(1.45), + Pm_(1.0), + omega_s_(1.0), + omega_b_(2.0 * 60.0 * M_PI), + omega_up_(omega_s_ + 0.0001), + omega_lo_(omega_s_ - 0.0001), + c_(10000.0), + beta_(2), + P0_(P0), + Q0_(Q0), + bus_(bus) + { + } + + template + Generator4::~Generator4() + { + } + + /*! + * @brief This function will be used to allocate sparse Jacobian matrices. + * + */ + template + int Generator4::allocate() + { + // std::cout << "Allocate Generator4..." << std::endl; tag_.resize(size_); return 0; -} - -/** - * @brief Initialization of the generator model - * - * Initialization equations are derived from example 9.2 in Power System - * 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), \\ - * &~& 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}, \\ - * &~& E_{q0}' = V_0 \cos(\delta_0 - \theta_0) + R_s I_{q0} + X_d' I_{d0} - * \f} - * - * The input from exciter and governor is set to the steady state value: - * \f{eqnarray*}{ - * &~& E_{f0} = E_{q0}' + (X_d - X_d') I_{d0}, \\ - * &~& P_{m0} = E_{d0}' I_{d0} + E_{q0}' I_{q0} + ( X_q' - X_d') I_{d0} I_{q0} - * \f} - * - */ -template -int Generator4::initialize() -{ + } + + /** + * @brief Initialization of the generator model + * + * Initialization equations are derived from example 9.2 in Power System + * 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), \\ + * &~& 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}, \\ + * &~& E_{q0}' = V_0 \cos(\delta_0 - \theta_0) + R_s I_{q0} + X_d' I_{d0} + * \f} + * + * The input from exciter and governor is set to the steady state value: + * \f{eqnarray*}{ + * &~& E_{f0} = E_{q0}' + (X_d - X_d') I_{d0}, \\ + * &~& P_{m0} = E_{d0}' I_{d0} + E_{q0}' I_{q0} + ( X_q' - X_d') I_{d0} I_{q0} + * \f} + * + */ + template + int Generator4::initialize() + { // std::cout << "Initialize Generator4..." << std::endl; // 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_); + const ScalarT phi = theta() - delta - atan(Q0_ / P0_); // Compute initial gueses for generator currents and potentials in d-q frame - const ScalarT Id = std::sqrt(P0_*P0_ + Q0_*Q0_)/V() * sin(phi); - const ScalarT Iq = std::sqrt(P0_*P0_ + Q0_*Q0_)/V() * cos(phi); - const ScalarT Ed = V()*sin(theta() - delta) + Rs_*Id + Xqp_*Iq; - const ScalarT Eq = V()*cos(theta() - delta) + Rs_*Iq - Xdp_*Id; - - y_[0] = delta; - y_[1] = omega_s_; - y_[2] = Ed; - y_[3] = Eq; - y_[4] = Id; - y_[5] = Iq; + const ScalarT Id = std::sqrt(P0_ * P0_ + Q0_ * Q0_) / V() * sin(phi); + const ScalarT Iq = std::sqrt(P0_ * P0_ + Q0_ * Q0_) / V() * cos(phi); + const ScalarT Ed = V() * sin(theta() - delta) + Rs_ * Id + Xqp_ * Iq; + const ScalarT Eq = V() * cos(theta() - delta) + Rs_ * Iq - Xdp_ * Id; + + y_[0] = delta; + y_[1] = omega_s_; + y_[2] = Ed; + y_[3] = Eq; + y_[4] = Id; + y_[5] = Iq; yp_[0] = 0.0; yp_[1] = 0.0; yp_[2] = 0.0; @@ -170,231 +172,225 @@ int Generator4::initialize() 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 - param_[0] = Pm_; + param_[0] = Pm_; param_up_[0] = 1.5; param_lo_[0] = 0.0; - param_[1] = Ef_; + param_[1] = Ef_; param_up_[1] = 1.7; param_lo_[1] = 0.0; return 0; -} - -/** - * \brief Identify differential variables. - */ -template -int Generator4::tagDifferentiable() -{ + } + + /** + * \brief Identify differential variables. + */ + template + int Generator4::tagDifferentiable() + { tag_[0] = true; tag_[1] = true; tag_[2] = true; tag_[3] = true; - for (IdxT i=4; i < size_; ++i) + for (IdxT i = 4; i < size_; ++i) { - tag_[i] = false; + tag_[i] = false; } return 0; -} - -/** - * @brief Computes residual vector for the generator model. - * - * Residual equations are given per model in Power System Modeling and - * 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_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} - * where \f$ \Omega_b \f$ is the synchronous frequency in [rad/s], and - * overdot denotes time derivative. - * - * 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), \\ - * 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_4 = I_d \f$, \f$ y_5 = I_q \f$. - * - */ -template -int Generator4::evaluateResidual() -{ + } + + /** + * @brief Computes residual vector for the generator model. + * + * Residual equations are given per model in Power System Modeling and + * 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_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} + * where \f$ \Omega_b \f$ is the synchronous frequency in [rad/s], and + * overdot denotes time derivative. + * + * 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), \\ + * 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_4 = I_d \f$, \f$ y_5 = I_q \f$. + * + */ + template + int Generator4::evaluateResidual() + { // std::cout << "Evaluate residual for Generator4..." << std::endl; - 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_[2] = Tq0p_*dotEdp() + Edp() - (Xq_ - Xqp_)*Iq(); - f_[3] = Td0p_*dotEqp() + Eqp() + (Xd_ - Xdp_)*Id() - Ef(); - f_[4] = Rs_*Id() - Xqp_*Iq() + V()*sin(delta() - theta()) - Edp(); - f_[5] = Xdp_*Id() + Rs_*Iq() + V()*cos(delta() - theta()) - Eqp(); + 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_[2] = Tq0p_ * dotEdp() + Edp() - (Xq_ - Xqp_) * Iq(); + f_[3] = Td0p_ * dotEqp() + Eqp() + (Xd_ - Xdp_) * Id() - Ef(); + f_[4] = Rs_ * Id() - Xqp_ * Iq() + V() * sin(delta() - theta()) - Edp(); + f_[5] = Xdp_ * Id() + Rs_ * Iq() + V() * cos(delta() - theta()) - Eqp(); // Compute active and reactive load provided by the infinite bus. P() += Pg(); Q() += Qg(); return 0; -} + } -template -int Generator4::evaluateJacobian() -{ + template + int Generator4::evaluateJacobian() + { std::cerr << "Evaluate Jacobian for Generator4..." << std::endl; std::cerr << "Jacobian evaluation not implemented!" << std::endl; return 0; -} + } -template -int Generator4::evaluateIntegrand() -{ + template + int Generator4::evaluateIntegrand() + { // std::cout << "Evaluate Integrand for Generator4..." << std::endl; g_[0] = frequencyPenalty(y_[1]); return 0; -} + } -template -int Generator4::initializeAdjoint() -{ - //std::cout << "Initialize adjoint for Generator4..." << std::endl; - for (IdxT i=0; i + int Generator4::initializeAdjoint() + { + // std::cout << "Initialize adjoint for Generator4..." << std::endl; + for (IdxT i = 0; i < size_; ++i) { - yB_[i] = 0.0; - ypB_[i] = 0.0; + yB_[i] = 0.0; + ypB_[i] = 0.0; } ypB_[1] = frequencyPenaltyDer(y_[1]); return 0; -} - - -/** - * @brief Computes adjoint residual vector for the generator model. - * - * 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} - * - */ -template -int Generator4::evaluateAdjointResidual() -{ + } + + /** + * @brief Computes adjoint residual vector for the generator model. + * + * 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} + * + */ + template + int Generator4::evaluateAdjointResidual() + { // std::cout << "Evaluate adjoint residual for Generator4..." << std::endl; ScalarT sinPhi = sin(delta() - theta()); ScalarT cosPhi = cos(delta() - theta()); // 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]; - 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_[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]; + 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_; return 0; -} - -// template -// int Generator4::evaluateAdjointJacobian() -// { -// std::cout << "Evaluate adjoint Jacobian for Generator4..." << std::endl; -// std::cout << "Adjoint Jacobian evaluation not implemented!" << std::endl; -// return 0; -// } - -template -int Generator4::evaluateAdjointIntegrand() -{ + } + + // template + // int Generator4::evaluateAdjointJacobian() + // { + // std::cout << "Evaluate adjoint Jacobian for Generator4..." << std::endl; + // std::cout << "Adjoint Jacobian evaluation not implemented!" << std::endl; + // return 0; + // } + + template + int Generator4::evaluateAdjointIntegrand() + { // std::cout << "Evaluate adjoint Integrand for Generator4..." << std::endl; gB_[0] = yB_[1]; gB_[1] = yB_[3]; return 0; -} - - -// -// Private functions -// - -/** - * 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] - * - */ -template -ScalarT Generator4::Pg() -{ - return y_[5]*V()*cos(theta() - y_[0]) + y_[4]*V()*sin(theta() - y_[0]); -} - -/** - * Generator reactive power Qg. - * - * \f[ Q_g = E_q' I_d - E_d' I_q - X_d' I_d^2 - X_q' I_q^2 \f] - */ -template -ScalarT Generator4::Qg() -{ - return y_[5]*V()*sin(theta() - y_[0]) - y_[4]*V()*cos(theta() - y_[0]); -} - -/** - * Frequency penalty is used as the objective function for the generator model. - */ -template -ScalarT Generator4::frequencyPenalty(ScalarT omega) -{ + } + + // + // Private functions + // + + /** + * 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] + * + */ + template + ScalarT Generator4::Pg() + { + return y_[5] * V() * cos(theta() - y_[0]) + y_[4] * V() * sin(theta() - y_[0]); + } + + /** + * Generator reactive power Qg. + * + * \f[ Q_g = E_q' I_d - E_d' I_q - X_d' I_d^2 - X_q' I_q^2 \f] + */ + template + ScalarT Generator4::Qg() + { + return y_[5] * V() * sin(theta() - y_[0]) - y_[4] * V() * cos(theta() - y_[0]); + } + + /** + * Frequency penalty is used as the objective function for the generator model. + */ + template + ScalarT Generator4::frequencyPenalty(ScalarT omega) + { return c_ * 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. - */ -template -ScalarT Generator4::frequencyPenaltyDer(ScalarT omega) -{ + } + + /** + * 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) + { if (omega > omega_up_) { - return beta_ * c_ * pow(omega - omega_up_, beta_ - 1.0); + return beta_ * c_ * pow(omega - omega_up_, beta_ - 1.0); } else if (omega < omega_lo_) { - return beta_ * c_ * pow(omega - omega_lo_, beta_ - 1.0); + return beta_ * c_ * pow(omega - omega_lo_, beta_ - 1.0); } else { - return 0.0; + return 0.0; } -} - - - -// Available template instantiations -template class Generator4; -template class Generator4; + } + // Available template instantiations + template class Generator4; + template class Generator4; } // namespace GridKit - diff --git a/src/Model/PowerFlow/Generator4/Generator4.hpp b/src/Model/PowerFlow/Generator4/Generator4.hpp index 1ceee9f8..923625ba 100644 --- a/src/Model/PowerFlow/Generator4/Generator4.hpp +++ b/src/Model/PowerFlow/Generator4/Generator4.hpp @@ -64,199 +64,198 @@ namespace GridKit { - template class BaseBus; + template + class BaseBus; } namespace GridKit { - /*! - * @brief Implementation of a fourth order generator model. - * - */ - template - class Generator4 : public ModelEvaluatorImpl + /*! + * @brief Implementation of a fourth order generator model. + * + */ + template + class Generator4 : public ModelEvaluatorImpl + { + using ModelEvaluatorImpl::size_; + using ModelEvaluatorImpl::nnz_; + using ModelEvaluatorImpl::time_; + using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::yp_; + using ModelEvaluatorImpl::tag_; + using ModelEvaluatorImpl::f_; + using ModelEvaluatorImpl::g_; + using ModelEvaluatorImpl::yB_; + using ModelEvaluatorImpl::ypB_; + using ModelEvaluatorImpl::fB_; + using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::param_; + using ModelEvaluatorImpl::param_up_; + using ModelEvaluatorImpl::param_lo_; + + typedef typename ModelEvaluatorImpl::real_type real_type; + typedef BaseBus bus_type; + + public: + Generator4(BaseBus* bus, ScalarT P0 = 1.0, ScalarT Q0 = 0.0); + virtual ~Generator4(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + void updateTime(real_type t, real_type a) { - using ModelEvaluatorImpl::size_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::alpha_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::yp_; - using ModelEvaluatorImpl::tag_; - using ModelEvaluatorImpl::f_; - using ModelEvaluatorImpl::g_; - using ModelEvaluatorImpl::yB_; - using ModelEvaluatorImpl::ypB_; - using ModelEvaluatorImpl::fB_; - using ModelEvaluatorImpl::gB_; - using ModelEvaluatorImpl::param_; - using ModelEvaluatorImpl::param_up_; - using ModelEvaluatorImpl::param_lo_; - - typedef typename ModelEvaluatorImpl::real_type real_type; - typedef BaseBus bus_type; - - public: - Generator4(BaseBus* bus, ScalarT P0 = 1.0, ScalarT Q0 = 0.0); - virtual ~Generator4(); - - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); - - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - void updateTime(real_type t, real_type a) - { - time_ = t; - alpha_ = a; - } - - // Inline accesor functions - ScalarT& V() - { - return bus_->V(); - } - - const ScalarT& V() const - { - return bus_->V(); - } - - ScalarT& theta() - { - return bus_->theta(); - } - - const ScalarT& theta() const - { - return bus_->theta(); - } - - ScalarT& P() - { - return bus_->P(); - } - - const ScalarT& P() const - { - return bus_->P(); - } - - ScalarT& Q() - { - return bus_->Q(); - } - - const ScalarT& Q() const - { - return bus_->Q(); - } - - - private: - const ScalarT& Pm() const - { - return param_[0]; - } - - const ScalarT& Ef() const - { - return param_[1]; - } - - ScalarT Pg(); - ScalarT Qg(); - ScalarT frequencyPenalty(ScalarT omega); - ScalarT frequencyPenaltyDer(ScalarT omega); - - private: - // - // Private inlined accessor methods - // - - const ScalarT dotDelta() const - { - return yp_[0]; - } - - const ScalarT dotOmega() const - { - return yp_[1]; - } - - const ScalarT dotEdp() const - { - return yp_[2]; - } - - const ScalarT dotEqp() const - { - return yp_[3]; - } - - const ScalarT delta() const - { - return y_[0]; - } - - const ScalarT omega() const - { - return y_[1]; - } - - const ScalarT Edp() const - { - return y_[2]; - } - - const ScalarT Eqp() const - { - return y_[3]; - } - - const ScalarT Id() const - { - return y_[4]; - } - - const ScalarT Iq() const - { - return y_[5]; - } - - private: - real_type H_; ///< Inertia constant [s] - real_type D_; ///< Damping constant [pu] - real_type Xq_; ///< q-axis synchronous reactance [pu] - real_type Xd_; ///< d-axis synchronous reactance [pu] - real_type Xqp_; ///< q-axis transient reactance [pu] - real_type Xdp_; ///< d-axis transient reactance [pu] - real_type Rs_; ///< stator armature resistance [pu] - real_type Tq0p_; ///< q-axis open circuit transient time constant [s] - real_type Td0p_; ///< d-axis open circuit transient time constant [s] - real_type Ef_; - real_type Pm_; - real_type omega_s_; - real_type omega_b_; - real_type omega_up_; - real_type omega_lo_; - real_type c_; - real_type beta_; - - ScalarT P0_; - ScalarT Q0_; - - bus_type* bus_; - }; + time_ = t; + alpha_ = a; + } -} // namespace GridKit + // Inline accesor functions + ScalarT& V() + { + return bus_->V(); + } + + const ScalarT& V() const + { + return bus_->V(); + } + + ScalarT& theta() + { + return bus_->theta(); + } + + const ScalarT& theta() const + { + return bus_->theta(); + } + + ScalarT& P() + { + return bus_->P(); + } + + const ScalarT& P() const + { + return bus_->P(); + } + + ScalarT& Q() + { + return bus_->Q(); + } + + const ScalarT& Q() const + { + return bus_->Q(); + } + + private: + const ScalarT& Pm() const + { + return param_[0]; + } + + const ScalarT& Ef() const + { + return param_[1]; + } + + ScalarT Pg(); + ScalarT Qg(); + ScalarT frequencyPenalty(ScalarT omega); + ScalarT frequencyPenaltyDer(ScalarT omega); + + private: + // + // Private inlined accessor methods + // + const ScalarT dotDelta() const + { + return yp_[0]; + } + + const ScalarT dotOmega() const + { + return yp_[1]; + } + + const ScalarT dotEdp() const + { + return yp_[2]; + } + + const ScalarT dotEqp() const + { + return yp_[3]; + } + + const ScalarT delta() const + { + return y_[0]; + } + + const ScalarT omega() const + { + return y_[1]; + } + + const ScalarT Edp() const + { + return y_[2]; + } + + const ScalarT Eqp() const + { + return y_[3]; + } + + const ScalarT Id() const + { + return y_[4]; + } + + const ScalarT Iq() const + { + return y_[5]; + } + + private: + real_type H_; ///< Inertia constant [s] + real_type D_; ///< Damping constant [pu] + real_type Xq_; ///< q-axis synchronous reactance [pu] + real_type Xd_; ///< d-axis synchronous reactance [pu] + real_type Xqp_; ///< q-axis transient reactance [pu] + real_type Xdp_; ///< d-axis transient reactance [pu] + real_type Rs_; ///< stator armature resistance [pu] + real_type Tq0p_; ///< q-axis open circuit transient time constant [s] + real_type Td0p_; ///< d-axis open circuit transient time constant [s] + real_type Ef_; + real_type Pm_; + real_type omega_s_; + real_type omega_b_; + real_type omega_up_; + real_type omega_lo_; + real_type c_; + real_type beta_; + + ScalarT P0_; + ScalarT Q0_; + + bus_type* bus_; + }; + +} // namespace GridKit #endif // _GENERATOR_4_H_ diff --git a/src/Model/PowerFlow/Generator4Governor/Generator4Governor.cpp b/src/Model/PowerFlow/Generator4Governor/Generator4Governor.cpp index 0f64a683..7f078363 100644 --- a/src/Model/PowerFlow/Generator4Governor/Generator4Governor.cpp +++ b/src/Model/PowerFlow/Generator4Governor/Generator4Governor.cpp @@ -57,123 +57,123 @@ * */ - -#include -#include #include "Generator4Governor.hpp" -#include "Model/PowerFlow/Bus/BaseBus.hpp" - -namespace GridKit { - -/*! - * @brief Constructor for a model of generator with governor - * - * Arguments passed to ModelEvaluatorImpl: - * - Number of equations = 6 differential + 3 algebraic = 9 - * - Number of quadratures = 1 - * - Number of optimization parameters = 2 - * - */ -template -Generator4Governor::Generator4Governor(bus_type* bus, ScalarT P0, ScalarT Q0) - : ModelEvaluatorImpl(9, 1, 2), - H_(5.0), - D_(0.04), - Xq_(0.85), - Xd_(1.05), - Xqp_(0.35), - Xdp_(0.35), - Rs_(0.01), - Tq0p_(1.0), // [s] - Td0p_(8.0), // [s] - Ef0_(1.45), - Pm0_(1.0), - deltaPm_(0.5), // 0.5 - deltaPn_(1.0), // 1.0 - omega_s_(1.0), - omega_b_(2.0*60.0*M_PI), // [rad/s] - omega_up_(omega_s_ + 0.0001), - omega_lo_(omega_s_ - 0.0001), - c_(10000.0), - beta_(2), - T1_(0.1), - T2_(0.15), - T3_(0.05), - K_(16.67), - offsetGen_(0), - offsetGov_(6), - P0_(P0), - Q0_(Q0), - bus_(bus) -{ -} +#include +#include +#include "Model/PowerFlow/Bus/BaseBus.hpp" -template -Generator4Governor::~Generator4Governor() +namespace GridKit { - //std::cout << "Destroy Gen2..." << std::endl; -} -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int Generator4Governor::allocate() -{ - //std::cout << "Allocate Gen2..." << std::endl; + /*! + * @brief Constructor for a model of generator with governor + * + * Arguments passed to ModelEvaluatorImpl: + * - Number of equations = 6 differential + 3 algebraic = 9 + * - Number of quadratures = 1 + * - Number of optimization parameters = 2 + * + */ + template + Generator4Governor::Generator4Governor(bus_type* bus, ScalarT P0, ScalarT Q0) + : ModelEvaluatorImpl(9, 1, 2), + H_(5.0), + D_(0.04), + Xq_(0.85), + Xd_(1.05), + Xqp_(0.35), + Xdp_(0.35), + Rs_(0.01), + Tq0p_(1.0), // [s] + Td0p_(8.0), // [s] + Ef0_(1.45), + Pm0_(1.0), + deltaPm_(0.5), // 0.5 + deltaPn_(1.0), // 1.0 + omega_s_(1.0), + omega_b_(2.0 * 60.0 * M_PI), // [rad/s] + omega_up_(omega_s_ + 0.0001), + omega_lo_(omega_s_ - 0.0001), + c_(10000.0), + beta_(2), + T1_(0.1), + T2_(0.15), + T3_(0.05), + K_(16.67), + offsetGen_(0), + offsetGov_(6), + P0_(P0), + Q0_(Q0), + bus_(bus) + { + } + + template + Generator4Governor::~Generator4Governor() + { + // std::cout << "Destroy Gen2..." << std::endl; + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int Generator4Governor::allocate() + { + // std::cout << "Allocate Gen2..." << std::endl; tag_.resize(size_); return 0; -} - -/** - * @brief Initialization of the generator model - * - * Initialization equations are derived from example 9.2 in Power System - * 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), \\ - * 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}, \\ - * E_{q0}' &=& V_0 \cos(\delta_0 - \theta_0) + R_s I_{q0} + X_d' I_{d0} - * \f} - * - * The input from exciter and governor is set to the steady state value: - * \f{eqnarray*}{ - * E_{f0} &=& E_{q0}' + (X_d - X_d') I_{d0}, \\ - * P_{m0} &=& E_{d0}' I_{d0} + E_{q0}' I_{q0} + ( X_q' - X_d') I_{d0} I_{q0} - * \f} - * - */ -template -int Generator4Governor::initialize() -{ + } + + /** + * @brief Initialization of the generator model + * + * Initialization equations are derived from example 9.2 in Power System + * 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), \\ + * 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}, \\ + * E_{q0}' &=& V_0 \cos(\delta_0 - \theta_0) + R_s I_{q0} + X_d' I_{d0} + * \f} + * + * The input from exciter and governor is set to the steady state value: + * \f{eqnarray*}{ + * E_{f0} &=& E_{q0}' + (X_d - X_d') I_{d0}, \\ + * P_{m0} &=& E_{d0}' I_{d0} + E_{q0}' I_{q0} + ( X_q' - X_d') I_{d0} I_{q0} + * \f} + * + */ + template + int Generator4Governor::initialize() + { // std::cout << "Initialize Generator4Governor..." << std::endl; // Compute 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 generator current phase - const ScalarT phi = delta - theta() + atan(Q0_/P0_); + const ScalarT phi = delta - theta() + atan(Q0_ / P0_); // Compute generator currents and potentials in d-q frame - const ScalarT Id = std::sqrt(P0_*P0_ + Q0_*Q0_)/V() * sin(phi); - const ScalarT Iq = std::sqrt(P0_*P0_ + Q0_*Q0_)/V() * cos(phi); - const ScalarT Edp = V()*sin(delta - theta()) + Rs_*Id - Xqp_*Iq; - const ScalarT Eqp = V()*cos(delta - theta()) + Rs_*Iq + Xdp_*Id; + const ScalarT Id = std::sqrt(P0_ * P0_ + Q0_ * Q0_) / V() * sin(phi); + const ScalarT Iq = std::sqrt(P0_ * P0_ + Q0_ * Q0_) / V() * cos(phi); + const ScalarT Edp = V() * sin(delta - theta()) + Rs_ * Id - Xqp_ * Iq; + const ScalarT Eqp = V() * cos(delta - theta()) + Rs_ * Iq + Xdp_ * Id; // Initialize generator - y_[offsetGen_ + 0] = delta; - y_[offsetGen_ + 1] = omega_s_ + 0.2; // <~ this is hack to perturb omega - y_[offsetGen_ + 2] = Edp; - y_[offsetGen_ + 3] = Eqp; - y_[offsetGen_ + 4] = Id; - y_[offsetGen_ + 5] = Iq; + y_[offsetGen_ + 0] = delta; + y_[offsetGen_ + 1] = omega_s_ + 0.2; // <~ this is hack to perturb omega + y_[offsetGen_ + 2] = Edp; + y_[offsetGen_ + 3] = Eqp; + y_[offsetGen_ + 4] = Id; + y_[offsetGen_ + 5] = Iq; yp_[offsetGen_ + 0] = 0.0; yp_[offsetGen_ + 1] = 0.0; yp_[offsetGen_ + 2] = 0.0; @@ -181,35 +181,35 @@ int Generator4Governor::initialize() yp_[offsetGen_ + 4] = 0.0; yp_[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_[offsetGov_ + 0] = Pm0_; - y_[offsetGov_ + 1] = 0.0; - y_[offsetGov_ + 2] = 0.0; + y_[offsetGov_ + 0] = Pm0_; + y_[offsetGov_ + 1] = 0.0; + y_[offsetGov_ + 2] = 0.0; yp_[offsetGov_ + 0] = 0.0; yp_[offsetGov_ + 1] = 0.0; yp_[offsetGov_ + 2] = 0.0; - param_[1] = K_; + param_[1] = K_; param_up_[1] = 20.0; param_lo_[1] = 0.0; - param_[0] = T2_; + param_[0] = T2_; param_up_[0] = 5.5; param_lo_[0] = 0.1; return 0; -} - -/** - * \brief Identify differential variables. - */ -template -int Generator4Governor::tagDifferentiable() -{ - //std::cout << "size of tag vector is " << tag_.size() << "\n"; + } + + /** + * \brief Identify differential variables. + */ + template + int Generator4Governor::tagDifferentiable() + { + // std::cout << "size of tag vector is " << tag_.size() << "\n"; tag_[offsetGen_ + 0] = true; tag_[offsetGen_ + 1] = true; tag_[offsetGen_ + 2] = true; @@ -222,54 +222,54 @@ int Generator4Governor::tagDifferentiable() tag_[offsetGov_ + 2] = false; return 0; -} - -/** - * @brief Computes residual vector for the generator model. - * - * 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_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} - * 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$ - * - * 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), \\ - * 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_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. - * - */ - -template -int Generator4Governor::evaluateResidual() -{ + } + + /** + * @brief Computes residual vector for the generator model. + * + * 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_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} + * 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$ + * + * 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), \\ + * 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_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. + * + */ + + template + int Generator4Governor::evaluateResidual() + { // Generator equations - f_[offsetGen_ + 0] = dotDelta() - omega_b_*(omega() - omega_s_); - f_[offsetGen_ + 1] = (2.0*H_)/omega_s_*dotOmega() - Lm(y_[offsetGov_ + 0]) + Eqp()*Iq() + Edp()*Id() + (- Xdp_ + Xqp_)*Id()*Iq() + D_*(omega() - omega_s_); - f_[offsetGen_ + 2] = Tq0p_*dotEdp() + Edp() - (Xq_ - Xqp_)*Iq(); - f_[offsetGen_ + 3] = Td0p_*dotEqp() + Eqp() + (Xd_ - Xdp_)*Id() - Ef0_; - f_[offsetGen_ + 4] = Rs_*Id() - Xqp_*Iq() + V()*sin(delta() - theta()) - Edp(); - f_[offsetGen_ + 5] = Xdp_*Id() + Rs_*Iq() + V()*cos(delta() - theta()) - Eqp(); + f_[offsetGen_ + 0] = dotDelta() - omega_b_ * (omega() - omega_s_); + f_[offsetGen_ + 1] = (2.0 * H_) / omega_s_ * dotOmega() - Lm(y_[offsetGov_ + 0]) + Eqp() * Iq() + Edp() * Id() + (-Xdp_ + Xqp_) * Id() * Iq() + D_ * (omega() - omega_s_); + f_[offsetGen_ + 2] = Tq0p_ * dotEdp() + Edp() - (Xq_ - Xqp_) * Iq(); + f_[offsetGen_ + 3] = Td0p_ * dotEqp() + Eqp() + (Xd_ - Xdp_) * Id() - Ef0_; + f_[offsetGen_ + 4] = Rs_ * Id() - Xqp_ * Iq() + V() * sin(delta() - theta()) - Edp(); + f_[offsetGen_ + 5] = Xdp_ * Id() + Rs_ * Iq() + V() * cos(delta() - theta()) - Eqp(); // Bus equations P() += Pg(); @@ -277,228 +277,217 @@ int Generator4Governor::evaluateResidual() // Governor equations f_[offsetGov_ + 0] = yp_[offsetGov_ + 0] - Ln(y_[offsetGov_ + 2]); - f_[offsetGov_ + 1] = T1()*yp_[offsetGov_ + 1] + y_[offsetGov_ + 1] - (1.0 - T2()/T1())*(omega() - omega_s_); - f_[offsetGov_ + 2] = T3()*y_[offsetGov_ + 2] - Pm0_ + Lm(y_[offsetGov_ + 0]) + K()*y_[offsetGov_ + 1] + K()*T2()/T1()*(omega() - omega_s_); + f_[offsetGov_ + 1] = T1() * yp_[offsetGov_ + 1] + y_[offsetGov_ + 1] - (1.0 - T2() / T1()) * (omega() - omega_s_); + f_[offsetGov_ + 2] = T3() * y_[offsetGov_ + 2] - Pm0_ + Lm(y_[offsetGov_ + 0]) + K() * y_[offsetGov_ + 1] + K() * T2() / T1() * (omega() - omega_s_); return 0; -} - -/* - * @brief Jacobian for the order 4 generator model (not implemented yet). - * - * - */ -template -int Generator4Governor::evaluateJacobian() -{ + } + + /* + * @brief Jacobian for the order 4 generator model (not implemented yet). + * + * + */ + template + int Generator4Governor::evaluateJacobian() + { std::cout << "Evaluate Jacobian for Gen2..." << std::endl; std::cout << "Jacobian evaluation not implemented!" << std::endl; return 0; -} + } -template -int Generator4Governor::evaluateIntegrand() -{ + template + int Generator4Governor::evaluateIntegrand() + { // std::cout << "Evaluate Integrand for Gen2..." << std::endl; g_[0] = frequencyPenalty(omega()); return 0; -} + } -template -int Generator4Governor::initializeAdjoint() -{ - //std::cout << "Initialize adjoint for Generator4Governor..." << std::endl; - for (IdxT i=0; i + int Generator4Governor::initializeAdjoint() + { + // std::cout << "Initialize adjoint for Generator4Governor..." << std::endl; + for (IdxT i = 0; i < size_; ++i) { - yB_[i] = 0.0; - ypB_[i] = 0.0; + yB_[i] = 0.0; + ypB_[i] = 0.0; } ypB_[offsetGen_ + 1] = frequencyPenaltyDer(omega()); return 0; -} - -/** - * @brief Computes adjoint residual vector for the generator model. - * - * 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_{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 - * \f} - * - * 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), \\ - * \f} - * respectively. - * - * - */ -template -int Generator4Governor::evaluateAdjointResidual() -{ + } + + /** + * @brief Computes adjoint residual vector for the generator model. + * + * 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_{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 + * \f} + * + * 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), \\ + * \f} + * respectively. + * + * + */ + template + int Generator4Governor::evaluateAdjointResidual() + { // std::cout << "Evaluate adjoint residual for Gen2..." << std::endl; ScalarT sinPhi = sin(delta() - theta()); ScalarT cosPhi = cos(delta() - theta()); // Generator adjoint - fB_[offsetGen_ + 0] = ypB_[offsetGen_ + 0] - yB_[offsetGen_ + 4]*V()*cosPhi + yB_[offsetGen_ + 5]*V()*sinPhi; - fB_[offsetGen_ + 1] = 2.0*H_/omega_s_*ypB_[offsetGen_ + 1] + yB_[offsetGen_ + 0]*omega_b_ - yB_[offsetGen_ + 1]*D_ + frequencyPenaltyDer(omega()) - + yB_[offsetGov_ + 1]*(1.0 - T2()/T1()) - yB_[offsetGov_ + 2]*K()*T2()/T1(); - fB_[offsetGen_ + 2] = Tq0p_*ypB_[offsetGen_ + 2] - yB_[offsetGen_ + 1]*Id() - yB_[offsetGen_ + 2] + yB_[offsetGen_ + 4] - + lambdaP()*Id() - lambdaQ()*Iq(); - fB_[offsetGen_ + 3] = Td0p_*ypB_[offsetGen_ + 3] - yB_[offsetGen_ + 1]*Iq() - yB_[offsetGen_ + 3] + yB_[offsetGen_ + 5] - + lambdaP()*Iq() + lambdaQ()*Id(); - fB_[offsetGen_ + 4] = -yB_[offsetGen_ + 1]*(Edp() + (Xqp_ - Xdp_)*Iq()) - yB_[offsetGen_ + 3]*(Xd_ - Xdp_) - yB_[offsetGen_ + 4]*Rs_ - yB_[offsetGen_ + 5]*Xdp_ - + lambdaP()*(Edp() + (Xqp_ - Xdp_)*Iq() - 2.0*Rs_*Id()) + lambdaQ()*(Eqp() - 2.0*Xdp_*Id()); - fB_[offsetGen_ + 5] = -yB_[offsetGen_ + 1]*(Eqp() + (Xqp_ - Xdp_)*Id()) + yB_[offsetGen_ + 2]*(Xq_ - Xqp_) + yB_[offsetGen_ + 4]*Xqp_ - yB_[offsetGen_ + 5]*Rs_ - + lambdaP()*(Eqp() + (Xqp_ -Xdp_)*Id() - 2.0*Rs_*Iq()) - lambdaQ()*(Edp() + 2.0*Xqp_*Iq()); + fB_[offsetGen_ + 0] = ypB_[offsetGen_ + 0] - yB_[offsetGen_ + 4] * V() * cosPhi + yB_[offsetGen_ + 5] * V() * sinPhi; + fB_[offsetGen_ + 1] = 2.0 * H_ / omega_s_ * ypB_[offsetGen_ + 1] + yB_[offsetGen_ + 0] * omega_b_ - yB_[offsetGen_ + 1] * D_ + frequencyPenaltyDer(omega()) + + yB_[offsetGov_ + 1] * (1.0 - T2() / T1()) - yB_[offsetGov_ + 2] * K() * T2() / T1(); + fB_[offsetGen_ + 2] = Tq0p_ * ypB_[offsetGen_ + 2] - yB_[offsetGen_ + 1] * Id() - yB_[offsetGen_ + 2] + yB_[offsetGen_ + 4] + + lambdaP() * Id() - lambdaQ() * Iq(); + fB_[offsetGen_ + 3] = Td0p_ * ypB_[offsetGen_ + 3] - yB_[offsetGen_ + 1] * Iq() - yB_[offsetGen_ + 3] + yB_[offsetGen_ + 5] + + lambdaP() * Iq() + lambdaQ() * Id(); + fB_[offsetGen_ + 4] = -yB_[offsetGen_ + 1] * (Edp() + (Xqp_ - Xdp_) * Iq()) - yB_[offsetGen_ + 3] * (Xd_ - Xdp_) - yB_[offsetGen_ + 4] * Rs_ - yB_[offsetGen_ + 5] * Xdp_ + + lambdaP() * (Edp() + (Xqp_ - Xdp_) * Iq() - 2.0 * Rs_ * Id()) + lambdaQ() * (Eqp() - 2.0 * Xdp_ * Id()); + fB_[offsetGen_ + 5] = -yB_[offsetGen_ + 1] * (Eqp() + (Xqp_ - Xdp_) * Id()) + yB_[offsetGen_ + 2] * (Xq_ - Xqp_) + yB_[offsetGen_ + 4] * Xqp_ - yB_[offsetGen_ + 5] * Rs_ + + lambdaP() * (Eqp() + (Xqp_ - Xdp_) * Id() - 2.0 * Rs_ * Iq()) - lambdaQ() * (Edp() + 2.0 * Xqp_ * Iq()); // Bus adjoint - PB() += (-yB_[offsetGen_ + 4]*sinPhi - yB_[offsetGen_ + 5]*cosPhi); - QB() += ( yB_[offsetGen_ + 4]*V()*cosPhi - yB_[offsetGen_ + 5]*V()*sinPhi); + PB() += (-yB_[offsetGen_ + 4] * sinPhi - yB_[offsetGen_ + 5] * cosPhi); + QB() += (yB_[offsetGen_ + 4] * V() * cosPhi - yB_[offsetGen_ + 5] * V() * sinPhi); // Governor adjoint - fB_[offsetGov_ + 0] = ypB_[offsetGov_ + 0] - yB_[offsetGov_ + 2]*dLm(y_[offsetGov_ + 0]) + yB_[offsetGen_ + 1]*dLm(y_[offsetGov_ + 0]); - fB_[offsetGov_ + 1] = ypB_[offsetGov_ + 1]*T1() - yB_[offsetGov_ + 1] - yB_[offsetGov_ + 2]*K(); - fB_[offsetGov_ + 2] = yB_[offsetGov_ + 0]*dLn(y_[offsetGov_ + 2]) - yB_[offsetGov_ + 2]*T3(); + fB_[offsetGov_ + 0] = ypB_[offsetGov_ + 0] - yB_[offsetGov_ + 2] * dLm(y_[offsetGov_ + 0]) + yB_[offsetGen_ + 1] * dLm(y_[offsetGov_ + 0]); + fB_[offsetGov_ + 1] = ypB_[offsetGov_ + 1] * T1() - yB_[offsetGov_ + 1] - yB_[offsetGov_ + 2] * K(); + fB_[offsetGov_ + 2] = yB_[offsetGov_ + 0] * dLn(y_[offsetGov_ + 2]) - yB_[offsetGov_ + 2] * T3(); return 0; -} - -// template -// int Generator4Governor::evaluateAdjointJacobian() -// { -// std::cout << "Evaluate adjoint Jacobian for Gen2..." << std::endl; -// std::cout << "Adjoint Jacobian evaluation not implemented!" << std::endl; -// return 0; -// } - -template -int Generator4Governor::evaluateAdjointIntegrand() -{ + } + + // template + // int Generator4Governor::evaluateAdjointJacobian() + // { + // std::cout << "Evaluate adjoint Jacobian for Gen2..." << std::endl; + // std::cout << "Adjoint Jacobian evaluation not implemented!" << std::endl; + // return 0; + // } + + template + int Generator4Governor::evaluateAdjointIntegrand() + { // std::cout << "Evaluate adjoint Integrand for Gen2..." << std::endl; // K adjoint - gB_[1] = -yB_[offsetGov_ + 2]*(y_[offsetGov_ + 1] + T2()/T1()*(omega() - omega_s_)); + gB_[1] = -yB_[offsetGov_ + 2] * (y_[offsetGov_ + 1] + T2() / T1() * (omega() - omega_s_)); // T2 adjoint - gB_[0] = -yB_[offsetGov_ + 1]*(omega() - omega_s_)/T1() - yB_[offsetGov_ + 2]*K()/T1()*(omega() - omega_s_); + gB_[0] = -yB_[offsetGov_ + 1] * (omega() - omega_s_) / T1() - yB_[offsetGov_ + 2] * K() / T1() * (omega() - omega_s_); return 0; -} - - - - - -// -// Private functions -// - -/** - * 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] - * - */ -template -ScalarT Generator4Governor::Pg() -{ - return Iq()*Eqp() + Id()*Edp() + (Xqp_ - Xdp_)*Id()*Iq() - Rs_*(Id()*Id() + Iq()*Iq()); -} - -/** - * Generator reactive power Qg. - * - * \f[ Q_g = E_q' I_d - E_d' I_q - X_d' I_d^2 - X_q' I_q^2 \f] - */ -template -ScalarT Generator4Governor::Qg() -{ - return -Iq()*Edp() + Id()*Eqp() - Xdp_*Id()*Id() - Xqp_*Iq()*Iq(); -} - -/** - * Frequency penalty is used as the objective function for the generator model. - * - * @todo Use smooth penalty function! - * - */ -template -ScalarT Generator4Governor::frequencyPenalty(ScalarT omega) -{ + } + + // + // Private functions + // + + /** + * 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] + * + */ + template + ScalarT Generator4Governor::Pg() + { + return Iq() * Eqp() + Id() * Edp() + (Xqp_ - Xdp_) * Id() * Iq() - Rs_ * (Id() * Id() + Iq() * Iq()); + } + + /** + * Generator reactive power Qg. + * + * \f[ Q_g = E_q' I_d - E_d' I_q - X_d' I_d^2 - X_q' I_q^2 \f] + */ + template + ScalarT Generator4Governor::Qg() + { + return -Iq() * Edp() + Id() * Eqp() - Xdp_ * Id() * Id() - Xqp_ * Iq() * Iq(); + } + + /** + * Frequency penalty is used as the objective function for the generator model. + * + * @todo Use smooth penalty function! + * + */ + template + ScalarT Generator4Governor::frequencyPenalty(ScalarT omega) + { return c_ * 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. - * - * @todo Use smooth penalty function! - * - */ -template -ScalarT Generator4Governor::frequencyPenaltyDer(ScalarT omega) -{ + } + + /** + * Derivative of frequency penalty cannot be written in terms of min/max functions. + * Need to expand conditional statements instead. + * + * @todo Use smooth penalty function! + * + */ + template + ScalarT Generator4Governor::frequencyPenaltyDer(ScalarT omega) + { if (omega > omega_up_) { - return beta_ * c_ * pow(omega - omega_up_, beta_ - 1.0); + return beta_ * c_ * pow(omega - omega_up_, beta_ - 1.0); } else if (omega < omega_lo_) { - return beta_ * c_ * pow(omega - omega_lo_, beta_ - 1.0); + return beta_ * c_ * pow(omega - omega_lo_, beta_ - 1.0); } else { - return 0.0; + return 0.0; } -} - - -template -ScalarT Generator4Governor::Lm(ScalarT Pm) -{ - return Pm0_ + deltaPm_*std::tanh(Pm); -} - -template -ScalarT Generator4Governor::dLm(ScalarT Pm) -{ - return deltaPm_/(std::cosh(Pm) * std::cosh(Pm)); -} - - -template -ScalarT Generator4Governor::Ln(ScalarT Pn) -{ - return deltaPn_*std::tanh(Pn); -} - -template -ScalarT Generator4Governor::dLn(ScalarT Pn) -{ - return deltaPn_/(std::cosh(Pn) * std::cosh(Pn)); -} - - - - - -// Available template instantiations -template class Generator4Governor; -template class Generator4Governor; - + } + + template + ScalarT Generator4Governor::Lm(ScalarT Pm) + { + return Pm0_ + deltaPm_ * std::tanh(Pm); + } + + template + ScalarT Generator4Governor::dLm(ScalarT Pm) + { + return deltaPm_ / (std::cosh(Pm) * std::cosh(Pm)); + } + + template + ScalarT Generator4Governor::Ln(ScalarT Pn) + { + return deltaPn_ * std::tanh(Pn); + } + + template + ScalarT Generator4Governor::dLn(ScalarT Pn) + { + return deltaPn_ / (std::cosh(Pn) * std::cosh(Pn)); + } + + // Available template instantiations + template class Generator4Governor; + template class Generator4Governor; } // namespace GridKit diff --git a/src/Model/PowerFlow/Generator4Governor/Generator4Governor.hpp b/src/Model/PowerFlow/Generator4Governor/Generator4Governor.hpp index 68ac1198..81e96787 100644 --- a/src/Model/PowerFlow/Generator4Governor/Generator4Governor.hpp +++ b/src/Model/PowerFlow/Generator4Governor/Generator4Governor.hpp @@ -64,262 +64,259 @@ namespace GridKit { - template class BaseBus; + template + class BaseBus; } namespace GridKit { - /*! - * @brief Implementation of a fourth order generator model with - * a simple governor. - * - */ - template - class Generator4Governor : public ModelEvaluatorImpl + /*! + * @brief Implementation of a fourth order generator model with + * a simple governor. + * + */ + template + class Generator4Governor : public ModelEvaluatorImpl + { + using ModelEvaluatorImpl::size_; + using ModelEvaluatorImpl::nnz_; + using ModelEvaluatorImpl::time_; + using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::yp_; + using ModelEvaluatorImpl::tag_; + using ModelEvaluatorImpl::f_; + using ModelEvaluatorImpl::g_; + using ModelEvaluatorImpl::yB_; + using ModelEvaluatorImpl::ypB_; + using ModelEvaluatorImpl::fB_; + using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::param_; + using ModelEvaluatorImpl::param_up_; + using ModelEvaluatorImpl::param_lo_; + + public: + typedef typename ModelEvaluatorImpl::real_type real_type; + typedef BaseBus bus_type; + + Generator4Governor(bus_type* bus, ScalarT P0, ScalarT Q0); + virtual ~Generator4Governor(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + void updateTime(real_type t, real_type a) { - using ModelEvaluatorImpl::size_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::alpha_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::yp_; - using ModelEvaluatorImpl::tag_; - using ModelEvaluatorImpl::f_; - using ModelEvaluatorImpl::g_; - using ModelEvaluatorImpl::yB_; - using ModelEvaluatorImpl::ypB_; - using ModelEvaluatorImpl::fB_; - using ModelEvaluatorImpl::gB_; - using ModelEvaluatorImpl::param_; - using ModelEvaluatorImpl::param_up_; - using ModelEvaluatorImpl::param_lo_; - - public: - typedef typename ModelEvaluatorImpl::real_type real_type; - typedef BaseBus bus_type; - - Generator4Governor(bus_type* bus, ScalarT P0, ScalarT Q0); - virtual ~Generator4Governor(); - - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); - - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - void updateTime(real_type t, real_type a) - { - time_ = t; - alpha_ = a; - } - - private: - // - // Private model methods - // - - ScalarT Pg(); - ScalarT Qg(); - - inline ScalarT frequencyPenalty(ScalarT omega); - inline ScalarT frequencyPenaltyDer(ScalarT omega); - - inline ScalarT Lm(ScalarT Pm); - inline ScalarT dLm(ScalarT Pm); - - inline ScalarT Ln(ScalarT Pn); - inline ScalarT dLn(ScalarT Pn); - - - public: - // - // Public inline accesor functions - // - - ScalarT& V() - { - return bus_->V(); - } - - const ScalarT& V() const - { - return bus_->V(); - } - - ScalarT& theta() - { - return bus_->theta(); - } - - const ScalarT& theta() const - { - return bus_->theta(); - } - - ScalarT& P() - { - return bus_->P(); - } - - const ScalarT& P() const - { - return bus_->P(); - } - - ScalarT& Q() - { - return bus_->Q(); - } - - const ScalarT& Q() const - { - return bus_->Q(); - } - - const ScalarT& lambdaP() const - { - return bus_->lambdaP(); - } - - const ScalarT& lambdaQ() const - { - return bus_->lambdaQ(); - } - - ScalarT& PB() - { - return bus_->PB(); - } - - ScalarT& QB() - { - return bus_->QB(); - } - - - private: - // - // Private inlined accessor methods - // - - const ScalarT dotDelta() const - { - return yp_[offsetGen_ + 0]; - } - - const ScalarT dotOmega() const - { - return yp_[offsetGen_ + 1]; - } - - const ScalarT dotEdp() const - { - return yp_[offsetGen_ + 2]; - } - - const ScalarT dotEqp() const - { - return yp_[offsetGen_ + 3]; - } - - const ScalarT delta() const - { - return y_[offsetGen_ + 0]; - } - - const ScalarT omega() const - { - return y_[offsetGen_ + 1]; - } - - const ScalarT Edp() const - { - return y_[offsetGen_ + 2]; - } - - const ScalarT Eqp() const - { - return y_[offsetGen_ + 3]; - } - - const ScalarT Id() const - { - return y_[offsetGen_ + 4]; - } - - const ScalarT Iq() const - { - return y_[offsetGen_ + 5]; - } - - const ScalarT K() const - { - return param_[1]; - } - - const ScalarT T1() const - { - return T1_; - } - - const ScalarT T2() const - { - return param_[0]; - } - - const ScalarT T3() const - { - return T3_; - } - - - private: - // Generator parameters - real_type H_; - real_type D_; - real_type Xq_; - real_type Xd_; - real_type Xqp_; - real_type Xdp_; - real_type Rs_; - real_type Tq0p_; - real_type Td0p_; - real_type Ef0_; - real_type Pm0_; - real_type deltaPm_; - real_type deltaPn_; - real_type omega_s_; - real_type omega_b_; - real_type omega_up_; - real_type omega_lo_; - real_type c_; - real_type beta_; - - // Governor parameters - real_type T1_; - real_type T2_; - real_type T3_; - real_type K_; - - // Index offsets - const IdxT offsetGen_; - const IdxT offsetGov_; - - // Initial power flow values - ScalarT P0_; - ScalarT Q0_; - - // Bus to which the generator is connected - bus_type* bus_; - }; + time_ = t; + alpha_ = a; + } -} // namespace GridKit + private: + // + // Private model methods + // + + ScalarT Pg(); + ScalarT Qg(); + + inline ScalarT frequencyPenalty(ScalarT omega); + inline ScalarT frequencyPenaltyDer(ScalarT omega); + + inline ScalarT Lm(ScalarT Pm); + inline ScalarT dLm(ScalarT Pm); + + inline ScalarT Ln(ScalarT Pn); + inline ScalarT dLn(ScalarT Pn); + + public: + // + // Public inline accesor functions + // + + ScalarT& V() + { + return bus_->V(); + } + + const ScalarT& V() const + { + return bus_->V(); + } + + ScalarT& theta() + { + return bus_->theta(); + } + + const ScalarT& theta() const + { + return bus_->theta(); + } + + ScalarT& P() + { + return bus_->P(); + } + + const ScalarT& P() const + { + return bus_->P(); + } + + ScalarT& Q() + { + return bus_->Q(); + } + + const ScalarT& Q() const + { + return bus_->Q(); + } + + const ScalarT& lambdaP() const + { + return bus_->lambdaP(); + } + + const ScalarT& lambdaQ() const + { + return bus_->lambdaQ(); + } + + ScalarT& PB() + { + return bus_->PB(); + } + + ScalarT& QB() + { + return bus_->QB(); + } + private: + // + // Private inlined accessor methods + // + + const ScalarT dotDelta() const + { + return yp_[offsetGen_ + 0]; + } + + const ScalarT dotOmega() const + { + return yp_[offsetGen_ + 1]; + } + + const ScalarT dotEdp() const + { + return yp_[offsetGen_ + 2]; + } + + const ScalarT dotEqp() const + { + return yp_[offsetGen_ + 3]; + } + + const ScalarT delta() const + { + return y_[offsetGen_ + 0]; + } + + const ScalarT omega() const + { + return y_[offsetGen_ + 1]; + } + + const ScalarT Edp() const + { + return y_[offsetGen_ + 2]; + } + + const ScalarT Eqp() const + { + return y_[offsetGen_ + 3]; + } + + const ScalarT Id() const + { + return y_[offsetGen_ + 4]; + } + + const ScalarT Iq() const + { + return y_[offsetGen_ + 5]; + } + + const ScalarT K() const + { + return param_[1]; + } + + const ScalarT T1() const + { + return T1_; + } + + const ScalarT T2() const + { + return param_[0]; + } + + const ScalarT T3() const + { + return T3_; + } + + private: + // Generator parameters + real_type H_; + real_type D_; + real_type Xq_; + real_type Xd_; + real_type Xqp_; + real_type Xdp_; + real_type Rs_; + real_type Tq0p_; + real_type Td0p_; + real_type Ef0_; + real_type Pm0_; + real_type deltaPm_; + real_type deltaPn_; + real_type omega_s_; + real_type omega_b_; + real_type omega_up_; + real_type omega_lo_; + real_type c_; + real_type beta_; + + // Governor parameters + real_type T1_; + real_type T2_; + real_type T3_; + real_type K_; + + // Index offsets + const IdxT offsetGen_; + const IdxT offsetGov_; + + // Initial power flow values + ScalarT P0_; + ScalarT Q0_; + + // Bus to which the generator is connected + bus_type* bus_; + }; + +} // namespace GridKit #endif // _GENERATOR_4_GOVERNOR_B_HPP_ diff --git a/src/Model/PowerFlow/Generator4Param/Generator4Param.cpp b/src/Model/PowerFlow/Generator4Param/Generator4Param.cpp index e8272d0b..661d2a27 100644 --- a/src/Model/PowerFlow/Generator4Param/Generator4Param.cpp +++ b/src/Model/PowerFlow/Generator4Param/Generator4Param.cpp @@ -57,107 +57,109 @@ * */ - -#include -#include -#include #include "Generator4Param.hpp" -namespace GridKit { +#include +#include -/*! - * @brief Constructor for a simple generator model - * - * Arguments passed to ModelEvaluatorImpl: - * - Number of equations = 4 differential + 2 algebraic = 6 - * - Number of quadratures = 1 - * - Number of optimization parameters = 1 - */ -template -Generator4Param::Generator4Param(bus_type* bus, ScalarT P0, ScalarT Q0) - : ModelEvaluatorImpl(6, 1, 1), - H_(5.0), - D_(0.04), - Xq_(0.85), - Xd_(1.05), - Xqp_(0.35), - Xdp_(0.35), - Rs_(0.01), - Tq0p_(1.0), // [s] - Td0p_(8.0), // [s] - Ef_(1.45), - Pm_(1.0), - omega_s_(1.0), - omega_b_(2.0*60.0*M_PI), - P0_(P0), - Q0_(Q0), - bus_(bus) -{ -} +#include -template -Generator4Param::~Generator4Param() +namespace GridKit { -} -/*! - * @brief This function will be used to allocate sparse Jacobian matrices. - * - */ -template -int Generator4Param::allocate() -{ - //std::cout << "Allocate Generator4Param..." << std::endl; + /*! + * @brief Constructor for a simple generator model + * + * Arguments passed to ModelEvaluatorImpl: + * - Number of equations = 4 differential + 2 algebraic = 6 + * - Number of quadratures = 1 + * - Number of optimization parameters = 1 + */ + template + Generator4Param::Generator4Param(bus_type* bus, ScalarT P0, ScalarT Q0) + : ModelEvaluatorImpl(6, 1, 1), + H_(5.0), + D_(0.04), + Xq_(0.85), + Xd_(1.05), + Xqp_(0.35), + Xdp_(0.35), + Rs_(0.01), + Tq0p_(1.0), // [s] + Td0p_(8.0), // [s] + Ef_(1.45), + Pm_(1.0), + omega_s_(1.0), + omega_b_(2.0 * 60.0 * M_PI), + P0_(P0), + Q0_(Q0), + bus_(bus) + { + } + + template + Generator4Param::~Generator4Param() + { + } + + /*! + * @brief This function will be used to allocate sparse Jacobian matrices. + * + */ + template + int Generator4Param::allocate() + { + // std::cout << "Allocate Generator4Param..." << std::endl; tag_.resize(size_); return 0; -} - -/** - * @brief Initialization of the generator model - * - * Initialization equations are derived from example 9.2 in Power System - * 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), \\ - * &~& 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}, \\ - * &~& E_{q0}' = V_0 \cos(\delta_0 - \theta_0) + R_s I_{q0} + X_d' I_{d0} - * \f} - * - * The input from exciter and governor is set to the steady state value: - * \f{eqnarray*}{ - * &~& E_{f0} = E_{q0}' + (X_d - X_d') I_{d0}, \\ - * &~& P_{m0} = E_{d0}' I_{d0} + E_{q0}' I_{q0} + ( X_q' - X_d') I_{d0} I_{q0} - * \f} - * - */ -template -int Generator4Param::initialize() -{ + } + + /** + * @brief Initialization of the generator model + * + * Initialization equations are derived from example 9.2 in Power System + * 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), \\ + * &~& 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}, \\ + * &~& E_{q0}' = V_0 \cos(\delta_0 - \theta_0) + R_s I_{q0} + X_d' I_{d0} + * \f} + * + * The input from exciter and governor is set to the steady state value: + * \f{eqnarray*}{ + * &~& E_{f0} = E_{q0}' + (X_d - X_d') I_{d0}, \\ + * &~& P_{m0} = E_{d0}' I_{d0} + E_{q0}' I_{q0} + ( X_q' - X_d') I_{d0} I_{q0} + * \f} + * + */ + template + int Generator4Param::initialize() + { // std::cout << "Initialize Generator4Param..." << std::endl; // 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_); + const ScalarT phi = theta() - delta - atan(Q0_ / P0_); // Compute initial gueses for generator currents and potentials in d-q frame - const ScalarT Id = std::sqrt(P0_*P0_ + Q0_*Q0_)/V() * sin(phi); - const ScalarT Iq = std::sqrt(P0_*P0_ + Q0_*Q0_)/V() * cos(phi); - const ScalarT Ed = V()*sin(theta() - delta) + Rs_*Id + Xqp_*Iq; - const ScalarT Eq = V()*cos(theta() - delta) + Rs_*Iq - Xdp_*Id; - - y_[0] = delta; - y_[1] = omega_s_; - y_[2] = Ed; - y_[3] = Eq; - y_[4] = Id; - y_[5] = Iq; + const ScalarT Id = std::sqrt(P0_ * P0_ + Q0_ * Q0_) / V() * sin(phi); + const ScalarT Iq = std::sqrt(P0_ * P0_ + Q0_ * Q0_) / V() * cos(phi); + const ScalarT Ed = V() * sin(theta() - delta) + Rs_ * Id + Xqp_ * Iq; + const ScalarT Eq = V() * cos(theta() - delta) + Rs_ * Iq - Xdp_ * Id; + + y_[0] = delta; + y_[1] = omega_s_; + y_[2] = Ed; + y_[3] = Eq; + y_[4] = Id; + y_[5] = Iq; yp_[0] = 0.0; yp_[1] = 0.0; yp_[2] = 0.0; @@ -166,13 +168,13 @@ int Generator4Param::initialize() 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 - param_[0] = H_; + param_[0] = H_; param_up_[0] = 10.0; - param_lo_[0] = 2.0; + param_lo_[0] = 2.0; // param_[0] = Pm_; // param_up_[0] = 1.5; @@ -183,293 +185,289 @@ int Generator4Param::initialize() // param_lo_[1] = 0.0; return 0; -} - -/** - * \brief Identify differential variables. - */ -template -int Generator4Param::tagDifferentiable() -{ + } + + /** + * \brief Identify differential variables. + */ + template + int Generator4Param::tagDifferentiable() + { tag_[0] = true; tag_[1] = true; tag_[2] = true; tag_[3] = true; - for (IdxT i=4; i < size_; ++i) + for (IdxT i = 4; i < size_; ++i) { - tag_[i] = false; + tag_[i] = false; } return 0; -} - -/** - * @brief Computes residual vector for the generator model. - * - * Residual equations are given per model in Power System Modeling and - * 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_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} - * where \f$ \Omega_b \f$ is the synchronous frequency in [rad/s], and - * overdot denotes time derivative. - * - * 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), \\ - * 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_4 = I_d \f$, \f$ y_5 = I_q \f$. - * - */ -template -int Generator4Param::evaluateResidual() -{ + } + + /** + * @brief Computes residual vector for the generator model. + * + * Residual equations are given per model in Power System Modeling and + * 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_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} + * where \f$ \Omega_b \f$ is the synchronous frequency in [rad/s], and + * overdot denotes time derivative. + * + * 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), \\ + * 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_4 = I_d \f$, \f$ y_5 = I_q \f$. + * + */ + template + int Generator4Param::evaluateResidual() + { // std::cout << "Evaluate residual for Generator4Param..." << std::endl; - 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_[2] = Tq0p_*dotEdp() + Edp() - (Xq_ - Xqp_)*Iq(); - f_[3] = Td0p_*dotEqp() + Eqp() + (Xd_ - Xdp_)*Id() - Ef(); - f_[4] = Rs_*Id() - Xqp_*Iq() + V()*sin(delta() - theta()) - Edp(); - f_[5] = Xdp_*Id() + Rs_*Iq() + V()*cos(delta() - theta()) - Eqp(); + 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_[2] = Tq0p_ * dotEdp() + Edp() - (Xq_ - Xqp_) * Iq(); + f_[3] = Td0p_ * dotEqp() + Eqp() + (Xd_ - Xdp_) * Id() - Ef(); + f_[4] = Rs_ * Id() - Xqp_ * Iq() + V() * sin(delta() - theta()) - Edp(); + f_[5] = Xdp_ * Id() + Rs_ * Iq() + V() * cos(delta() - theta()) - Eqp(); // Compute active and reactive load provided by the infinite bus. P() += Pg(); Q() += Qg(); - //std::cout << "Residual: t = " << time_ << std::endl; + // std::cout << "Residual: t = " << time_ << std::endl; return 0; -} + } -template -int Generator4Param::evaluateJacobian() -{ + template + int Generator4Param::evaluateJacobian() + { std::cerr << "Evaluate Jacobian for Generator4Param..." << std::endl; std::cerr << "Jacobian evaluation not implemented!" << std::endl; return 0; -} + } -template -int Generator4Param::evaluateIntegrand() -{ + template + int Generator4Param::evaluateIntegrand() + { // std::cout << "Evaluate Integrand for Generator4Param..." << std::endl; g_[0] = trajectoryPenalty(time_); return 0; -} + } -template -int Generator4Param::initializeAdjoint() -{ - //std::cout << "Initialize adjoint for Generator4Param..." << std::endl; - for (IdxT i=0; i + int Generator4Param::initializeAdjoint() + { + // std::cout << "Initialize adjoint for Generator4Param..." << std::endl; + for (IdxT i = 0; i < size_; ++i) { - yB_[i] = 0.0; - ypB_[i] = 0.0; + yB_[i] = 0.0; + ypB_[i] = 0.0; } - //ypB_[1] = frequencyPenaltyDer(y_[1]); - ypB_[2] = -trajectoryPenaltyDerEdp(time_)/Tq0p_; - ypB_[3] = -trajectoryPenaltyDerEqp(time_)/Td0p_; + // ypB_[1] = frequencyPenaltyDer(y_[1]); + ypB_[2] = -trajectoryPenaltyDerEdp(time_) / Tq0p_; + ypB_[3] = -trajectoryPenaltyDerEqp(time_) / Td0p_; return 0; -} - - -/** - * @brief Computes adjoint residual vector for the generator model. - * - * 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} - * - */ -template -int Generator4Param::evaluateAdjointResidual() -{ + } + + /** + * @brief Computes adjoint residual vector for the generator model. + * + * 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} + * + */ + template + int Generator4Param::evaluateAdjointResidual() + { // std::cout << "Evaluate adjoint residual for Generator4Param..." << std::endl; ScalarT sinPhi = sin(delta() - theta()); ScalarT cosPhi = cos(delta() - theta()); // 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_[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_; return 0; -} - -// template -// int Generator4Param::evaluateAdjointJacobian() -// { -// std::cout << "Evaluate adjoint Jacobian for Generator4Param..." << std::endl; -// std::cout << "Adjoint Jacobian evaluation not implemented!" << std::endl; -// return 0; -// } - -template -int Generator4Param::evaluateAdjointIntegrand() -{ + } + + // template + // int Generator4Param::evaluateAdjointJacobian() + // { + // std::cout << "Evaluate adjoint Jacobian for Generator4Param..." << std::endl; + // std::cout << "Adjoint Jacobian evaluation not implemented!" << std::endl; + // return 0; + // } + + template + int Generator4Param::evaluateAdjointIntegrand() + { // std::cout << "Evaluate adjoint Integrand for Generator4Param..." << std::endl; - gB_[0] = -2.0*yB_[1]*dotOmega()/omega_s_; + gB_[0] = -2.0 * yB_[1] * dotOmega() / omega_s_; return 0; -} - - -// -// Private functions -// - -/** - * 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] - * - */ -template -ScalarT Generator4Param::Pg() -{ - return y_[5]*V()*cos(theta() - y_[0]) + y_[4]*V()*sin(theta() - y_[0]); -} - -/** - * Generator reactive power Qg. - * - * \f[ Q_g = E_q' I_d - E_d' I_q - X_d' I_d^2 - X_q' I_q^2 \f] - */ -template -ScalarT Generator4Param::Qg() -{ - return y_[5]*V()*sin(theta() - y_[0]) - y_[4]*V()*cos(theta() - y_[0]); -} - -/** - * @brief Difference between computed system state and look-up table value. - * - * @todo Look-up table should probably live outside the generator model. - */ -template -ScalarT Generator4Param::trajectoryPenalty(ScalarT t) const -{ - size_t N = table_.size(); + } + + // + // Private functions + // + + /** + * 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] + * + */ + template + ScalarT Generator4Param::Pg() + { + return y_[5] * V() * cos(theta() - y_[0]) + y_[4] * V() * sin(theta() - y_[0]); + } + + /** + * Generator reactive power Qg. + * + * \f[ Q_g = E_q' I_d - E_d' I_q - X_d' I_d^2 - X_q' I_q^2 \f] + */ + template + ScalarT Generator4Param::Qg() + { + return y_[5] * V() * sin(theta() - y_[0]) - y_[4] * V() * cos(theta() - y_[0]); + } + + /** + * @brief Difference between computed system state and look-up table value. + * + * @todo Look-up table should probably live outside the generator model. + */ + template + ScalarT Generator4Param::trajectoryPenalty(ScalarT t) const + { + size_t N = table_.size(); double ti = table_[0][0]; - double tf = table_[N-1][0]; - double dt = (tf - ti)/(N-1); - int n = std::trunc(t/tf*(N-1.0)); + double tf = table_[N - 1][0]; + double dt = (tf - ti) / (N - 1); + int n = std::trunc(t / tf * (N - 1.0)); double Edp_est = 0.0; double Eqp_est = 0.0; - if(t >= ti && t < tf) + if (t >= ti && t < tf) { - // Interpolate from look-up table - Edp_est = (table_[n+1][3] - table_[n][3])/(table_[n+1][0] - table_[n][0]) * (t - table_[n][0]) + table_[n][3]; - Eqp_est = (table_[n+1][4] - table_[n][4])/(table_[n+1][0] - table_[n][0]) * (t - table_[n][0]) + table_[n][4]; + // Interpolate from look-up table + Edp_est = (table_[n + 1][3] - table_[n][3]) / (table_[n + 1][0] - table_[n][0]) * (t - table_[n][0]) + table_[n][3]; + Eqp_est = (table_[n + 1][4] - table_[n][4]) / (table_[n + 1][0] - table_[n][0]) * (t - table_[n][0]) + table_[n][4]; } else { - if(tf <= t && t < tf + dt) - { - // Extrapolate from look-up table - Edp_est = (table_[n][3] - table_[n-1][3])/(table_[n][0] - table_[n-1][0]) * (t - table_[n-1][0]) + table_[n-1][3]; - Eqp_est = (table_[n][4] - table_[n-1][4])/(table_[n][0] - table_[n-1][0]) * (t - table_[n-1][0]) + table_[n-1][4]; - } - else - { - // Too far away to extrapolate - std::cerr << "Trajectory penalty: Out of time bounds at time " << t << "\n"; - return -1.0; - } + if (tf <= t && t < tf + dt) + { + // Extrapolate from look-up table + Edp_est = (table_[n][3] - table_[n - 1][3]) / (table_[n][0] - table_[n - 1][0]) * (t - table_[n - 1][0]) + table_[n - 1][3]; + Eqp_est = (table_[n][4] - table_[n - 1][4]) / (table_[n][0] - table_[n - 1][0]) * (t - table_[n - 1][0]) + table_[n - 1][4]; + } + else + { + // Too far away to extrapolate + std::cerr << "Trajectory penalty: Out of time bounds at time " << t << "\n"; + return -1.0; + } } double d = (Edp() - Edp_est); double q = (Eqp() - Eqp_est); - return (d*d + q*q); -} - -template -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)/(N-1); - int n = std::trunc(t/tf*(N-1.0)); + return (d * d + q * q); + } + + template + 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) / (N - 1); + int n = std::trunc(t / tf * (N - 1.0)); double Edp_est = 0.0; - if(t >= ti && t < tf) + if (t >= ti && t < tf) { - Edp_est = (table_[n+1][3] - table_[n][3])/(table_[n+1][0] - table_[n][0]) * (t - table_[n][0]) + table_[n][3]; + Edp_est = (table_[n + 1][3] - table_[n][3]) / (table_[n + 1][0] - table_[n][0]) * (t - table_[n][0]) + table_[n][3]; } else { - if(tf <= t && t < tf + dt) - { - Edp_est = (table_[n][3] - table_[n-1][3])/(table_[n][0] - table_[n-1][0]) * (t - table_[n-1][0]) + table_[n-1][3]; - } - else - { - std::cerr << "Trajectory penalty: Out of time bounds at time " << t << "\n"; - return -1.0; - } + if (tf <= t && t < tf + dt) + { + Edp_est = (table_[n][3] - table_[n - 1][3]) / (table_[n][0] - table_[n - 1][0]) * (t - table_[n - 1][0]) + table_[n - 1][3]; + } + else + { + std::cerr << "Trajectory penalty: Out of time bounds at time " << t << "\n"; + return -1.0; + } } double d = (Edp() - Edp_est); - return 2.0*d; -} - -template -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)/(N-1); - int n = std::trunc(t/tf*(N-1.0)); + return 2.0 * d; + } + + template + 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) / (N - 1); + int n = std::trunc(t / tf * (N - 1.0)); double Eqp_est = 0.0; - if(t >= ti && t < tf) + if (t >= ti && t < tf) { - Eqp_est = (table_[n+1][4] - table_[n][4])/(table_[n+1][0] - table_[n][0]) * (t - table_[n][0]) + table_[n][4]; + Eqp_est = (table_[n + 1][4] - table_[n][4]) / (table_[n + 1][0] - table_[n][0]) * (t - table_[n][0]) + table_[n][4]; } else { - if(tf <= t && t < tf + dt) - { - Eqp_est = (table_[n][4] - table_[n-1][4])/(table_[n][0] - table_[n-1][0]) * (t - table_[n-1][0]) + table_[n-1][4]; - } - else - { - std::cerr << "Trajectory penalty: Out of time bounds at time " << t << "\n"; - return -1.0; - } + if (tf <= t && t < tf + dt) + { + Eqp_est = (table_[n][4] - table_[n - 1][4]) / (table_[n][0] - table_[n - 1][0]) * (t - table_[n - 1][0]) + table_[n - 1][4]; + } + else + { + std::cerr << "Trajectory penalty: Out of time bounds at time " << t << "\n"; + return -1.0; + } } double q = (Eqp() - Eqp_est); - return 2.0*q; -} - -template class Generator4Param; -template class Generator4Param; + return 2.0 * q; + } + template class Generator4Param; + template class Generator4Param; } // namespace GridKit - diff --git a/src/Model/PowerFlow/Generator4Param/Generator4Param.hpp b/src/Model/PowerFlow/Generator4Param/Generator4Param.hpp index 430a601f..de4a1e50 100644 --- a/src/Model/PowerFlow/Generator4Param/Generator4Param.hpp +++ b/src/Model/PowerFlow/Generator4Param/Generator4Param.hpp @@ -64,216 +64,216 @@ namespace GridKit { - template class BaseBus; + template + class BaseBus; } namespace GridKit { - /*! - * @brief Implementation of a fourth order generator model. - * - */ - template - class Generator4Param : public ModelEvaluatorImpl + /*! + * @brief Implementation of a fourth order generator model. + * + */ + template + class Generator4Param : public ModelEvaluatorImpl + { + using ModelEvaluatorImpl::size_; + using ModelEvaluatorImpl::nnz_; + using ModelEvaluatorImpl::time_; + using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::yp_; + using ModelEvaluatorImpl::tag_; + using ModelEvaluatorImpl::f_; + using ModelEvaluatorImpl::g_; + using ModelEvaluatorImpl::yB_; + using ModelEvaluatorImpl::ypB_; + using ModelEvaluatorImpl::fB_; + using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::param_; + using ModelEvaluatorImpl::param_up_; + using ModelEvaluatorImpl::param_lo_; + + typedef typename ModelEvaluatorImpl::real_type real_type; + typedef BaseBus bus_type; + + public: + Generator4Param(BaseBus* bus, ScalarT P0 = 1.0, ScalarT Q0 = 0.0); + virtual ~Generator4Param(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + void updateTime(real_type t, real_type a) { - using ModelEvaluatorImpl::size_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::alpha_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::yp_; - using ModelEvaluatorImpl::tag_; - using ModelEvaluatorImpl::f_; - using ModelEvaluatorImpl::g_; - using ModelEvaluatorImpl::yB_; - using ModelEvaluatorImpl::ypB_; - using ModelEvaluatorImpl::fB_; - using ModelEvaluatorImpl::gB_; - using ModelEvaluatorImpl::param_; - using ModelEvaluatorImpl::param_up_; - using ModelEvaluatorImpl::param_lo_; - - typedef typename ModelEvaluatorImpl::real_type real_type; - typedef BaseBus bus_type; - - public: - Generator4Param(BaseBus* bus, ScalarT P0 = 1.0, ScalarT Q0 = 0.0); - virtual ~Generator4Param(); - - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); - - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - void updateTime(real_type t, real_type a) - { - time_ = t; - alpha_ = a; - } - - // Inline accesor functions - ScalarT& V() - { - return bus_->V(); - } - - const ScalarT& V() const - { - return bus_->V(); - } - - ScalarT& theta() - { - return bus_->theta(); - } - - const ScalarT& theta() const - { - return bus_->theta(); - } - - ScalarT& P() - { - return bus_->P(); - } - - const ScalarT& P() const - { - return bus_->P(); - } - - ScalarT& Q() - { - return bus_->Q(); - } - - const ScalarT& Q() const - { - return bus_->Q(); - } - - ScalarT trajectoryPenalty(ScalarT t) const; - ScalarT trajectoryPenaltyDerEqp(ScalarT t) const; - ScalarT trajectoryPenaltyDerEdp(ScalarT t) const; - - std::vector>& getLookupTable() - { - return table_; - } - - std::vector> const& getLookupTable() const - { - return table_; - } - - private: - const ScalarT& H() const - { - return param_[0]; - } - - const ScalarT& Pm() const - { - return Pm_; - // return param_[0]; - } - - const ScalarT& Ef() const - { - return Ef_; - // return param_[1]; - } - - ScalarT Pg(); - ScalarT Qg(); - - private: - // - // Private inlined accessor methods - // - - const ScalarT dotDelta() const - { - return yp_[0]; - } - - const ScalarT dotOmega() const - { - return yp_[1]; - } - - const ScalarT dotEdp() const - { - return yp_[2]; - } - - const ScalarT dotEqp() const - { - return yp_[3]; - } - - const ScalarT delta() const - { - return y_[0]; - } - - const ScalarT omega() const - { - return y_[1]; - } - - const ScalarT Edp() const - { - return y_[2]; - } - - const ScalarT Eqp() const - { - return y_[3]; - } - - const ScalarT Id() const - { - return y_[4]; - } - - const ScalarT Iq() const - { - return y_[5]; - } - - private: - real_type H_; ///< Inertia constant [s] - real_type D_; ///< Damping constant [pu] - real_type Xq_; ///< q-axis synchronous reactance [pu] - real_type Xd_; ///< d-axis synchronous reactance [pu] - real_type Xqp_; ///< q-axis transient reactance [pu] - real_type Xdp_; ///< d-axis transient reactance [pu] - real_type Rs_; ///< stator armature resistance [pu] - real_type Tq0p_; ///< q-axis open circuit transient time constant [s] - real_type Td0p_; ///< d-axis open circuit transient time constant [s] - real_type Ef_; - real_type Pm_; - real_type omega_s_; - real_type omega_b_; - - ScalarT P0_; - ScalarT Q0_; - - bus_type* bus_; - - /// Look-up table data. @todo This should be part of a separate model. - std::vector> table_; - }; + time_ = t; + alpha_ = a; + } -} // namespace GridKit + // Inline accesor functions + ScalarT& V() + { + return bus_->V(); + } + + const ScalarT& V() const + { + return bus_->V(); + } + + ScalarT& theta() + { + return bus_->theta(); + } + + const ScalarT& theta() const + { + return bus_->theta(); + } + + ScalarT& P() + { + return bus_->P(); + } + + const ScalarT& P() const + { + return bus_->P(); + } + + ScalarT& Q() + { + return bus_->Q(); + } + + const ScalarT& Q() const + { + return bus_->Q(); + } + + ScalarT trajectoryPenalty(ScalarT t) const; + ScalarT trajectoryPenaltyDerEqp(ScalarT t) const; + ScalarT trajectoryPenaltyDerEdp(ScalarT t) const; + + std::vector>& getLookupTable() + { + return table_; + } + + std::vector> const& getLookupTable() const + { + return table_; + } + + private: + const ScalarT& H() const + { + return param_[0]; + } + + const ScalarT& Pm() const + { + return Pm_; + // return param_[0]; + } + const ScalarT& Ef() const + { + return Ef_; + // return param_[1]; + } + + ScalarT Pg(); + ScalarT Qg(); + + private: + // + // Private inlined accessor methods + // + + const ScalarT dotDelta() const + { + return yp_[0]; + } + + const ScalarT dotOmega() const + { + return yp_[1]; + } + + const ScalarT dotEdp() const + { + return yp_[2]; + } + + const ScalarT dotEqp() const + { + return yp_[3]; + } + + const ScalarT delta() const + { + return y_[0]; + } + + const ScalarT omega() const + { + return y_[1]; + } + + const ScalarT Edp() const + { + return y_[2]; + } + + const ScalarT Eqp() const + { + return y_[3]; + } + + const ScalarT Id() const + { + return y_[4]; + } + + const ScalarT Iq() const + { + return y_[5]; + } + + private: + real_type H_; ///< Inertia constant [s] + real_type D_; ///< Damping constant [pu] + real_type Xq_; ///< q-axis synchronous reactance [pu] + real_type Xd_; ///< d-axis synchronous reactance [pu] + real_type Xqp_; ///< q-axis transient reactance [pu] + real_type Xdp_; ///< d-axis transient reactance [pu] + real_type Rs_; ///< stator armature resistance [pu] + real_type Tq0p_; ///< q-axis open circuit transient time constant [s] + real_type Td0p_; ///< d-axis open circuit transient time constant [s] + real_type Ef_; + real_type Pm_; + real_type omega_s_; + real_type omega_b_; + + ScalarT P0_; + ScalarT Q0_; + + bus_type* bus_; + + /// Look-up table data. @todo This should be part of a separate model. + std::vector> table_; + }; + +} // namespace GridKit #endif // _GENERATOR_4_H_ diff --git a/src/Model/PowerFlow/Load/Load.cpp b/src/Model/PowerFlow/Load/Load.cpp index b5113051..909870dd 100644 --- a/src/Model/PowerFlow/Load/Load.cpp +++ b/src/Model/PowerFlow/Load/Load.cpp @@ -57,126 +57,123 @@ * */ +#include "Load.hpp" -#include #include +#include #include -#include "Load.hpp" -#include -namespace GridKit { - -/*! - * @brief Constructor for a constant load model - * - * Calls default ModelEvaluatorImpl constructor. - */ +#include -template -Load::Load(bus_type* bus, ScalarT P, ScalarT Q) - : P_(P), - Q_(Q), - busID_(0), - bus_(bus) +namespace GridKit { - //std::cout << "Create a load model with " << size_ << " variables ...\n"; + + /*! + * @brief Constructor for a constant load model + * + * Calls default ModelEvaluatorImpl constructor. + */ + + template + Load::Load(bus_type* bus, ScalarT P, ScalarT Q) + : P_(P), + Q_(Q), + busID_(0), + bus_(bus) + { + // std::cout << "Create a load model with " << size_ << " variables ...\n"; size_ = 0; -} - -template -Load::Load(bus_type* bus, LoadData& data) - : P_(data.Pd), - Q_(data.Qd), - busID_(data.bus_i), - bus_(bus) -{ - //std::cout << "Create a load model with " << size_ << " variables ...\n"; + } + + template + Load::Load(bus_type* bus, LoadData& data) + : P_(data.Pd), + Q_(data.Qd), + busID_(data.bus_i), + bus_(bus) + { + // std::cout << "Create a load model with " << size_ << " variables ...\n"; size_ = 0; -} - -template -Load::~Load() -{ -} - -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int Load::allocate() -{ + } + + template + Load::~Load() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int Load::allocate() + { return 0; -} - -/** - * Initialization of the grid model - */ -template -int Load::initialize() -{ + } + + /** + * Initialization of the grid model + */ + template + int Load::initialize() + { return 0; -} - -/* - * \brief Identify differential variables - */ -template -int Load::tagDifferentiable() -{ + } + + /* + * \brief Identify differential variables + */ + template + int Load::tagDifferentiable() + { return 0; -} - -/** - * @brief Contributes to the bus residual. - * - * Must be connected to a PQ bus. - */ -template -int Load::evaluateResidual() -{ + } + + /** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ + template + int Load::evaluateResidual() + { // std::cout << "Evaluating load residual ...\n"; bus_->P() -= P_; bus_->Q() -= Q_; return 0; -} + } -template -int Load::evaluateJacobian() -{ + template + int Load::evaluateJacobian() + { return 0; -} + } -template -int Load::evaluateIntegrand() -{ + template + int Load::evaluateIntegrand() + { return 0; -} + } -template -int Load::initializeAdjoint() -{ + template + int Load::initializeAdjoint() + { return 0; -} + } -template -int Load::evaluateAdjointResidual() -{ + template + int Load::evaluateAdjointResidual() + { return 0; -} + } -template -int Load::evaluateAdjointIntegrand() -{ + template + int Load::evaluateAdjointIntegrand() + { return 0; -} - - - - -// Available template instantiations -template class Load; -template class Load; - + } -} //namespace GridKit + // Available template instantiations + template class Load; + template class Load; +} // namespace GridKit diff --git a/src/Model/PowerFlow/Load/Load.hpp b/src/Model/PowerFlow/Load/Load.hpp index 55989c11..b991819e 100644 --- a/src/Model/PowerFlow/Load/Load.hpp +++ b/src/Model/PowerFlow/Load/Load.hpp @@ -65,69 +65,69 @@ namespace GridKit { - template class BaseBus; + template + class BaseBus; } - namespace GridKit { - /*! - * @brief Declaration of a passive load class. - * - */ - template - class Load : public ModelEvaluatorImpl - { - using ModelEvaluatorImpl::size_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::alpha_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::yp_; - using ModelEvaluatorImpl::tag_; - using ModelEvaluatorImpl::f_; - using ModelEvaluatorImpl::g_; - using ModelEvaluatorImpl::yB_; - using ModelEvaluatorImpl::ypB_; - using ModelEvaluatorImpl::fB_; - using ModelEvaluatorImpl::gB_; - using ModelEvaluatorImpl::param_; + /*! + * @brief Declaration of a passive load class. + * + */ + template + class Load : public ModelEvaluatorImpl + { + using ModelEvaluatorImpl::size_; + using ModelEvaluatorImpl::nnz_; + using ModelEvaluatorImpl::time_; + using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::yp_; + using ModelEvaluatorImpl::tag_; + using ModelEvaluatorImpl::f_; + using ModelEvaluatorImpl::g_; + using ModelEvaluatorImpl::yB_; + using ModelEvaluatorImpl::ypB_; + using ModelEvaluatorImpl::fB_; + using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::param_; - // typedef typename ModelEvaluatorImpl::real_type real_type; - // typedef BaseBus bus_type; - using bus_type = BaseBus; - using real_type = typename ModelEvaluatorImpl::real_type; - using LoadData = GridKit::PowerSystemData::LoadData; + // typedef typename ModelEvaluatorImpl::real_type real_type; + // typedef BaseBus bus_type; + using bus_type = BaseBus; + using real_type = typename ModelEvaluatorImpl::real_type; + using LoadData = GridKit::PowerSystemData::LoadData; - public: - Load(bus_type* bus, ScalarT P, ScalarT Q); - Load(bus_type* bus, LoadData& data); - virtual ~Load(); + public: + Load(bus_type* bus, ScalarT P, ScalarT Q); + Load(bus_type* bus, LoadData& data); + virtual ~Load(); - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int initializeAdjoint(); + int evaluateAdjointResidual(); + // int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); - void updateTime(real_type t, real_type a) - { - time_ = t; - alpha_ = a; - } - - private: - ScalarT P_; - ScalarT Q_; - const IdxT busID_; - bus_type* bus_; - }; -} + void updateTime(real_type t, real_type a) + { + time_ = t; + alpha_ = a; + } + + private: + ScalarT P_; + ScalarT Q_; + const IdxT busID_; + bus_type* bus_; + }; +} // namespace GridKit #endif // _LOAD_HPP_ diff --git a/src/Model/PowerFlow/MiniGrid/MiniGrid.cpp b/src/Model/PowerFlow/MiniGrid/MiniGrid.cpp index 462abbce..9cc3f340 100644 --- a/src/Model/PowerFlow/MiniGrid/MiniGrid.cpp +++ b/src/Model/PowerFlow/MiniGrid/MiniGrid.cpp @@ -57,92 +57,91 @@ * */ +#include "MiniGrid.hpp" -#include #include +#include #include -#include "MiniGrid.hpp" -#include - -namespace GridKit { -/*! - * @brief Constructor for a constant load model - * - * Calls default ModelEvaluatorImpl constructor. - */ +#include -template -MiniGrid::MiniGrid() - : ModelEvaluatorImpl(3, 0, 0), - Pl2_( 2.5), - Ql2_( -0.8), - Pg3_( 2.0), - V1_ ( 1.0), - th1_( 0.0), - V3_ ( 1.1), - B12_( 10.0), - B13_( 15.0), - B22_(-22.0), - B23_( 12.0) +namespace GridKit { - //std::cout << "Create a load model with " << size_ << " variables ...\n"; + + /*! + * @brief Constructor for a constant load model + * + * Calls default ModelEvaluatorImpl constructor. + */ + + template + MiniGrid::MiniGrid() + : ModelEvaluatorImpl(3, 0, 0), + Pl2_(2.5), + Ql2_(-0.8), + Pg3_(2.0), + V1_(1.0), + th1_(0.0), + V3_(1.1), + B12_(10.0), + B13_(15.0), + B22_(-22.0), + B23_(12.0) + { + // std::cout << "Create a load model with " << size_ << " variables ...\n"; rel_tol_ = 1e-5; abs_tol_ = 1e-5; -} - -template -MiniGrid::~MiniGrid() -{ -} - -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int MiniGrid::allocate() -{ + } + + template + MiniGrid::~MiniGrid() + { + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int MiniGrid::allocate() + { return 0; -} - -/** - * Initialization of the grid model - */ -template -int MiniGrid::initialize() -{ + } + + /** + * Initialization of the grid model + */ + template + int MiniGrid::initialize() + { th2() = 0.0; // th2 V2() = 1.0; // V2 th3() = 0.0; // th3 return 0; -} - - -/** - * @brief Contributes to the bus residual. - * - * Must be connected to a PQ bus. - */ -template -int MiniGrid::evaluateResidual() -{ - f_[0] = -Pl2_ - V2()*(V1_*B12_*sin(th2()-th1_) + V3_*B23_*sin(th2() - th3())); - f_[1] = -Ql2_ + V2()*(V1_*B12_*cos(th2()-th1_) + B22_*V2() + V3_*B23_*cos(th2() - th3())); - f_[2] = Pg3_ - V3_ *(V1_*B13_*sin(th3()-th1_) + V2()*B23_*sin(th3() - th2())); + } + + /** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ + template + int MiniGrid::evaluateResidual() + { + f_[0] = -Pl2_ - V2() * (V1_ * B12_ * sin(th2() - th1_) + V3_ * B23_ * sin(th2() - th3())); + f_[1] = -Ql2_ + V2() * (V1_ * B12_ * cos(th2() - th1_) + B22_ * V2() + V3_ * B23_ * cos(th2() - th3())); + f_[2] = Pg3_ - V3_ * (V1_ * B13_ * sin(th3() - th1_) + V2() * B23_ * sin(th3() - th2())); return 0; -} + } -template -int MiniGrid::evaluateJacobian() -{ + template + int MiniGrid::evaluateJacobian() + { return 0; -} - -// Available template instantiations -template class MiniGrid; -template class MiniGrid; - + } -} //namespace GridKit + // Available template instantiations + template class MiniGrid; + template class MiniGrid; +} // namespace GridKit diff --git a/src/Model/PowerFlow/MiniGrid/MiniGrid.hpp b/src/Model/PowerFlow/MiniGrid/MiniGrid.hpp index 1a46d008..b6c36d47 100644 --- a/src/Model/PowerFlow/MiniGrid/MiniGrid.hpp +++ b/src/Model/PowerFlow/MiniGrid/MiniGrid.hpp @@ -58,87 +58,110 @@ */ #pragma once -#include #include +#include + namespace GridKit { - /*! - * @brief Implementation of a power grid. - * - */ - template - class MiniGrid : public ModelEvaluatorImpl + /*! + * @brief Implementation of a power grid. + * + */ + template + class MiniGrid : public ModelEvaluatorImpl + { + using ModelEvaluatorImpl::size_; + using ModelEvaluatorImpl::nnz_; + using ModelEvaluatorImpl::time_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::f_; + using ModelEvaluatorImpl::rel_tol_; + using ModelEvaluatorImpl::abs_tol_; + + typedef typename ModelEvaluatorImpl::real_type real_type; + + public: + MiniGrid(); + virtual ~MiniGrid(); + + int allocate(); + int initialize(); + + int tagDifferentiable() + { + return -1; + } + + int evaluateResidual(); + int evaluateJacobian(); + + int evaluateIntegrand() + { + return -1; + } + + int initializeAdjoint() + { + return -1; + } + + int evaluateAdjointResidual() + { + return -1; + } + + // int evaluateAdjointJacobian() {return -1;} + int evaluateAdjointIntegrand() { - using ModelEvaluatorImpl::size_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::f_; - using ModelEvaluatorImpl::rel_tol_; - using ModelEvaluatorImpl::abs_tol_; - - typedef typename ModelEvaluatorImpl::real_type real_type; - - public: - MiniGrid(); - virtual ~MiniGrid(); - - int allocate(); - int initialize(); - int tagDifferentiable() {return -1;} - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand() {return -1;} - - int initializeAdjoint() {return -1;} - int evaluateAdjointResidual() {return -1;} - //int evaluateAdjointJacobian() {return -1;} - int evaluateAdjointIntegrand() {return -1;} - - void updateTime(real_type t, real_type a) {} - - // const accessors are public - ScalarT const& th2() const - { - return y_[0]; - } - - ScalarT const& V2() const - { - return y_[1]; - } - - ScalarT const& th3() const - { - return y_[2]; - } - - ScalarT& th2() - { - return y_[0]; - } - - ScalarT& V2() - { - return y_[1]; - } - - ScalarT& th3() - { - return y_[2]; - } - - private: - ScalarT Pl2_; - ScalarT Ql2_; - ScalarT Pg3_; - ScalarT V1_ ; - ScalarT th1_; - ScalarT V3_ ; - ScalarT B12_; - ScalarT B13_; - ScalarT B22_; - ScalarT B23_; - }; -} + return -1; + } + + void updateTime(real_type t, real_type a) + { + } + + // const accessors are public + ScalarT const& th2() const + { + return y_[0]; + } + + ScalarT const& V2() const + { + return y_[1]; + } + + ScalarT const& th3() const + { + return y_[2]; + } + + ScalarT& th2() + { + return y_[0]; + } + + ScalarT& V2() + { + return y_[1]; + } + + ScalarT& th3() + { + return y_[2]; + } + + private: + ScalarT Pl2_; + ScalarT Ql2_; + ScalarT Pg3_; + ScalarT V1_; + ScalarT th1_; + ScalarT V3_; + ScalarT B12_; + ScalarT B13_; + ScalarT B22_; + ScalarT B23_; + }; +} // namespace GridKit diff --git a/src/Model/PowerFlow/ModelEvaluatorImpl.hpp b/src/Model/PowerFlow/ModelEvaluatorImpl.hpp index d08e247d..3bd74117 100644 --- a/src/Model/PowerFlow/ModelEvaluatorImpl.hpp +++ b/src/Model/PowerFlow/ModelEvaluatorImpl.hpp @@ -61,262 +61,260 @@ #define _MODEL_EVALUATOR_IMPL_HPP_ #include + #include namespace GridKit { - /*! - * @brief Model implementation base class. - * - */ - template - class ModelEvaluatorImpl : public Model::Evaluator - { - public: - typedef typename Model::Evaluator::real_type real_type; - - ModelEvaluatorImpl() - : size_(0), - size_quad_(0), - size_opt_(0) - {} - - ModelEvaluatorImpl(IdxT size, IdxT size_quad, IdxT size_opt) - : size_(size), - size_quad_(size_quad), - size_opt_(size_opt), - y_(size_), - yp_(size_), - f_(size_), - g_(size_quad_), - yB_(size_), - ypB_(size_), - fB_(size_), - gB_(size_opt_), - jac_(COO_Matrix()), - param_(size_opt_), - param_up_(size_opt_), - param_lo_(size_opt_) - { - } - - virtual IdxT size() - { - return size_; - } - - virtual IdxT nnz() - { - return nnz_; - } - - virtual bool hasJacobian() - { - return false; - } - - virtual IdxT sizeQuadrature() - { - return size_quad_; - } - - virtual IdxT sizeParams() - { - return size_opt_; - } - - // virtual void updateTime(real_type t, real_type a) - // { - // time_ = t; - // alpha_ = a; - // std::cout << "updateTime: t = " << time_ << "\n"; - // } - - virtual void setTolerances(real_type& rel_tol, real_type& abs_tol) const - { - rel_tol = rel_tol_; - abs_tol = abs_tol_; - } - - virtual void setMaxSteps(IdxT& msa) const - { - msa = max_steps_; - } - - std::vector& y() - { - return y_; - } - - const std::vector& y() const - { - return y_; - } - - std::vector& yp() - { - return yp_; - } - - const std::vector& yp() const - { - return yp_; - } - - std::vector& tag() - { - return tag_; - } - - const std::vector& tag() const - { - return tag_; - } - - std::vector& yB() - { - return yB_; - } - - const std::vector& yB() const - { - return yB_; - } - - std::vector& ypB() - { - return ypB_; - } - - const std::vector& ypB() const - { - return ypB_; - } - - std::vector& param() - { - return param_; - } - - const std::vector& param() const - { - return param_; - } - - std::vector& param_up() - { - return param_up_; - } - - const std::vector& param_up() const - { - return param_up_; - } - - std::vector& param_lo() - { - return param_lo_; - } - - const std::vector& param_lo() const - { - return param_lo_; - } - - std::vector& getResidual() - { - return f_; - } - - const std::vector& getResidual() const - { - return f_; - } - - COO_Matrix& getJacobian() - { - return jac_; - } - - const COO_Matrix& getJacobian() const - { - return jac_; - } - - std::vector& getIntegrand() - { - return g_; - } - - const std::vector& getIntegrand() const - { - return g_; - } - - std::vector& getAdjointResidual() - { - return fB_; - } - - const std::vector& getAdjointResidual() const - { - return fB_; - } - - std::vector& getAdjointIntegrand() - { - return gB_; - } - - const std::vector& getAdjointIntegrand() const - { - return gB_; - } - - //@todo Fix ID naming - IdxT getIDcomponent() - { - return idc_; - } - - - - protected: - IdxT size_; - IdxT nnz_; - IdxT size_quad_; - IdxT size_opt_; - - std::vector y_; - std::vector yp_; - std::vector tag_; - std::vector f_; - std::vector g_; - - std::vector yB_; - std::vector ypB_; - std::vector fB_; - std::vector gB_; + /*! + * @brief Model implementation base class. + * + */ + template + class ModelEvaluatorImpl : public Model::Evaluator + { + public: + typedef typename Model::Evaluator::real_type real_type; + + ModelEvaluatorImpl() + : size_(0), + size_quad_(0), + size_opt_(0) + { + } + + ModelEvaluatorImpl(IdxT size, IdxT size_quad, IdxT size_opt) + : size_(size), + size_quad_(size_quad), + size_opt_(size_opt), + y_(size_), + yp_(size_), + f_(size_), + g_(size_quad_), + yB_(size_), + ypB_(size_), + fB_(size_), + gB_(size_opt_), + jac_(COO_Matrix()), + param_(size_opt_), + param_up_(size_opt_), + param_lo_(size_opt_) + { + } + + virtual IdxT size() + { + return size_; + } + + virtual IdxT nnz() + { + return nnz_; + } + + virtual bool hasJacobian() + { + return false; + } + + virtual IdxT sizeQuadrature() + { + return size_quad_; + } + + virtual IdxT sizeParams() + { + return size_opt_; + } + + // virtual void updateTime(real_type t, real_type a) + // { + // time_ = t; + // alpha_ = a; + // std::cout << "updateTime: t = " << time_ << "\n"; + // } + + virtual void setTolerances(real_type& rel_tol, real_type& abs_tol) const + { + rel_tol = rel_tol_; + abs_tol = abs_tol_; + } + + virtual void setMaxSteps(IdxT& msa) const + { + msa = max_steps_; + } + + std::vector& y() + { + return y_; + } + + const std::vector& y() const + { + return y_; + } + + std::vector& yp() + { + return yp_; + } + + const std::vector& yp() const + { + return yp_; + } + + std::vector& tag() + { + return tag_; + } + + const std::vector& tag() const + { + return tag_; + } + + std::vector& yB() + { + return yB_; + } + + const std::vector& yB() const + { + return yB_; + } + + std::vector& ypB() + { + return ypB_; + } + + const std::vector& ypB() const + { + return ypB_; + } + + std::vector& param() + { + return param_; + } + + const std::vector& param() const + { + return param_; + } + + std::vector& param_up() + { + return param_up_; + } + + const std::vector& param_up() const + { + return param_up_; + } + + std::vector& param_lo() + { + return param_lo_; + } + + const std::vector& param_lo() const + { + return param_lo_; + } + + std::vector& getResidual() + { + return f_; + } + + const std::vector& getResidual() const + { + return f_; + } + + COO_Matrix& getJacobian() + { + return jac_; + } + + const COO_Matrix& getJacobian() const + { + return jac_; + } + + std::vector& getIntegrand() + { + return g_; + } + + const std::vector& getIntegrand() const + { + return g_; + } + + std::vector& getAdjointResidual() + { + return fB_; + } + + const std::vector& getAdjointResidual() const + { + return fB_; + } + + std::vector& getAdjointIntegrand() + { + return gB_; + } + + const std::vector& getAdjointIntegrand() const + { + return gB_; + } + + //@todo Fix ID naming + IdxT getIDcomponent() + { + return idc_; + } + + protected: + IdxT size_; + IdxT nnz_; + IdxT size_quad_; + IdxT size_opt_; + + std::vector y_; + std::vector yp_; + std::vector tag_; + std::vector f_; + std::vector g_; + + std::vector yB_; + std::vector ypB_; + std::vector fB_; + std::vector gB_; - COO_Matrix jac_; - - std::vector param_; - std::vector param_up_; - std::vector param_lo_; - - real_type time_; - real_type alpha_; + COO_Matrix jac_; - real_type rel_tol_; - real_type abs_tol_; + std::vector param_; + std::vector param_up_; + std::vector param_lo_; - IdxT max_steps_; + real_type time_; + real_type alpha_; - IdxT idc_; + real_type rel_tol_; + real_type abs_tol_; - }; + IdxT max_steps_; + IdxT idc_; + }; } // namespace GridKit diff --git a/src/Model/PowerFlow/SystemModel.hpp b/src/Model/PowerFlow/SystemModel.hpp index 90588a21..b3e06dc7 100644 --- a/src/Model/PowerFlow/SystemModel.hpp +++ b/src/Model/PowerFlow/SystemModel.hpp @@ -60,32 +60,32 @@ #ifndef _SYSTEM_MODEL_HPP_ #define _SYSTEM_MODEL_HPP_ +#include #include #include -#include -#include #include +#include namespace GridKit { -/** - * @brief Prototype for a system model class - * - * This class maps component data to system data and implements - * Model::Evaluator for the system model. This is still work in - * progress and code is not optimized. - * - * @todo Address thread safety for the system model methods. - * - */ -template -class SystemModel : public ModelEvaluatorImpl -{ + /** + * @brief Prototype for a system model class + * + * This class maps component data to system data and implements + * Model::Evaluator for the system model. This is still work in + * progress and code is not optimized. + * + * @todo Address thread safety for the system model methods. + * + */ + template + class SystemModel : public ModelEvaluatorImpl + { using bus_type = Model::Evaluator; using component_type = Model::Evaluator; - using real_type = typename ModelEvaluatorImpl::real_type; + using real_type = typename ModelEvaluatorImpl::real_type; using ModelEvaluatorImpl::size_; using ModelEvaluatorImpl::size_quad_; @@ -108,16 +108,17 @@ class SystemModel : public ModelEvaluatorImpl using ModelEvaluatorImpl::param_up_; using ModelEvaluatorImpl::param_lo_; -public: + public: /** * @brief Constructor for the system model */ - SystemModel() : ModelEvaluatorImpl(0, 0, 0) + SystemModel() + : ModelEvaluatorImpl(0, 0, 0) { - // Set system model tolerances - rel_tol_ = 1e-7; - abs_tol_ = 1e-9; - this->max_steps_=2000; + // Set system model tolerances + rel_tol_ = 1e-7; + abs_tol_ = 1e-9; + this->max_steps_ = 2000; } /** @@ -141,58 +142,58 @@ class SystemModel : public ModelEvaluatorImpl */ int allocate() { - size_ = 0; - size_quad_ = 0; - size_opt_ = 0; - - // Allocate all buses - for(const auto& bus: buses_) - { - bus->allocate(); - size_ += bus->size(); - size_quad_ += bus->sizeQuadrature(); - size_opt_ += bus->sizeParams(); - } - - // Allocate all components - for(const auto& component : components_) - { - component->allocate(); - size_ += component->size(); - size_quad_ += component->sizeQuadrature(); - size_opt_ += component->sizeParams(); - } - - // Allocate global vectors - y_.resize(size_); - yp_.resize(size_); - yB_.resize(size_); - ypB_.resize(size_); - f_.resize(size_); - fB_.resize(size_); - tag_.resize(size_); - - g_.resize(size_quad_); - gB_.resize(size_quad_*size_opt_); - - param_.resize(size_opt_); - param_lo_.resize(size_opt_); - param_up_.resize(size_opt_); - - assert(size_quad_ == 1 or size_quad_ == 0); - - return 0; + size_ = 0; + size_quad_ = 0; + size_opt_ = 0; + + // Allocate all buses + for (const auto& bus : buses_) + { + bus->allocate(); + size_ += bus->size(); + size_quad_ += bus->sizeQuadrature(); + size_opt_ += bus->sizeParams(); + } + + // Allocate all components + for (const auto& component : components_) + { + component->allocate(); + size_ += component->size(); + size_quad_ += component->sizeQuadrature(); + size_opt_ += component->sizeParams(); + } + + // Allocate global vectors + y_.resize(size_); + yp_.resize(size_); + yB_.resize(size_); + ypB_.resize(size_); + f_.resize(size_); + fB_.resize(size_); + tag_.resize(size_); + + g_.resize(size_quad_); + gB_.resize(size_quad_ * size_opt_); + + param_.resize(size_opt_); + param_lo_.resize(size_opt_); + param_up_.resize(size_opt_); + + assert(size_quad_ == 1 or size_quad_ == 0); + + return 0; } /** * @brief Assume that jacobian is not avalible - * - * @return true - * @return false + * + * @return true + * @return false */ - bool hasJacobian() + bool hasJacobian() { - return false; + return false; } /** @@ -212,58 +213,58 @@ class SystemModel : public ModelEvaluatorImpl */ int initialize() { - // Set initial values for global solution vectors - IdxT varOffset = 0; - IdxT optOffset = 0; - - for(const auto& bus: buses_) + // Set initial values for global solution vectors + IdxT varOffset = 0; + IdxT optOffset = 0; + + for (const auto& bus : buses_) + { + bus->initialize(); + } + + for (const auto& bus : buses_) + { + for (IdxT j = 0; j < bus->size(); ++j) { - bus->initialize(); + y_[varOffset + j] = bus->y()[j]; + yp_[varOffset + j] = bus->yp()[j]; } + varOffset += bus->size(); - for(const auto& bus: buses_) + for (IdxT j = 0; j < bus->sizeParams(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - y_[varOffset + j] = bus->y()[j]; - yp_[varOffset + j] = bus->yp()[j]; - } - varOffset += bus->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - param_[optOffset + j] = bus->param()[j]; - param_lo_[optOffset + j] = bus->param_lo()[j]; - param_up_[optOffset + j] = bus->param_up()[j]; - } - optOffset += bus->sizeParams(); + param_[optOffset + j] = bus->param()[j]; + param_lo_[optOffset + j] = bus->param_lo()[j]; + param_up_[optOffset + j] = bus->param_up()[j]; } - - // Initialize components - for(const auto& component : components_) + optOffset += bus->sizeParams(); + } + + // Initialize components + for (const auto& component : components_) + { + component->initialize(); + } + + for (const auto& component : components_) + { + for (IdxT j = 0; j < component->size(); ++j) { - component->initialize(); + y_[varOffset + j] = component->y()[j]; + yp_[varOffset + j] = component->yp()[j]; } + varOffset += component->size(); - for(const auto& component : components_) + for (IdxT j = 0; j < component->sizeParams(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - y_[varOffset + j] = component->y()[j]; - yp_[varOffset + j] = component->yp()[j]; - } - varOffset += component->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - param_[optOffset + j] = component->param()[j]; - param_lo_[optOffset + j] = component->param_lo()[j]; - param_up_[optOffset + j] = component->param_up()[j]; - } - optOffset += component->sizeParams(); + param_[optOffset + j] = component->param()[j]; + param_lo_[optOffset + j] = component->param_lo()[j]; + param_up_[optOffset + j] = component->param_up()[j]; } + optOffset += component->sizeParams(); + } - return 0; + return 0; } /** @@ -275,29 +276,29 @@ class SystemModel : public ModelEvaluatorImpl */ int tagDifferentiable() { - // Set initial values for global solution vectors - IdxT offset = 0; - for(const auto& bus: buses_) + // Set initial values for global solution vectors + IdxT offset = 0; + for (const auto& bus : buses_) + { + bus->tagDifferentiable(); + for (IdxT j = 0; j < bus->size(); ++j) { - bus->tagDifferentiable(); - for(IdxT j=0; jsize(); ++j) - { - tag_[offset + j] = bus->tag()[j]; - } - offset += bus->size(); + tag_[offset + j] = bus->tag()[j]; } + offset += bus->size(); + } - for(const auto& component: components_) + for (const auto& component : components_) + { + component->tagDifferentiable(); + for (IdxT j = 0; j < component->size(); ++j) { - component->tagDifferentiable(); - for(IdxT j=0; jsize(); ++j) - { - tag_[offset + j] = component->tag()[j]; - } - offset += component->size(); + tag_[offset + j] = component->tag()[j]; } + offset += component->size(); + } - return 0; + return 0; } /** @@ -320,66 +321,66 @@ class SystemModel : public ModelEvaluatorImpl */ int evaluateResidual() { - // Update variables - IdxT varOffset = 0; - IdxT optOffset = 0; - for(const auto& bus: buses_) + // Update variables + IdxT varOffset = 0; + IdxT optOffset = 0; + for (const auto& bus : buses_) + { + for (IdxT j = 0; j < bus->size(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - bus->y()[j] = y_[varOffset + j]; - bus->yp()[j] = yp_[varOffset + j]; - } - varOffset += bus->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - bus->param()[j] = param_[optOffset + j]; - } - optOffset += bus->sizeParams(); - - bus->evaluateResidual(); + bus->y()[j] = y_[varOffset + j]; + bus->yp()[j] = yp_[varOffset + j]; } + varOffset += bus->size(); - for(const auto& component : components_) + for (IdxT j = 0; j < bus->sizeParams(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - component->y()[j] = y_[varOffset + j]; - component->yp()[j] = yp_[varOffset + j]; - } - varOffset += component->size(); + bus->param()[j] = param_[optOffset + j]; + } + optOffset += bus->sizeParams(); - for(IdxT j=0; jsizeParams(); ++j) - { - component->param()[j] = param_[optOffset + j]; - } - optOffset += component->sizeParams(); + bus->evaluateResidual(); + } - component->evaluateResidual(); + for (const auto& component : components_) + { + for (IdxT j = 0; j < component->size(); ++j) + { + component->y()[j] = y_[varOffset + j]; + component->yp()[j] = yp_[varOffset + j]; } + varOffset += component->size(); - // Update residual vector - IdxT resOffset = 0; - for(const auto& bus: buses_) + for (IdxT j = 0; j < component->sizeParams(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - f_[resOffset + j] = bus->getResidual()[j]; - } - resOffset += bus->size(); + component->param()[j] = param_[optOffset + j]; } + optOffset += component->sizeParams(); + + component->evaluateResidual(); + } - for(const auto& component : components_) + // Update residual vector + IdxT resOffset = 0; + for (const auto& bus : buses_) + { + for (IdxT j = 0; j < bus->size(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - f_[resOffset + j] = component->getResidual()[j]; - } - resOffset += component->size(); + f_[resOffset + j] = bus->getResidual()[j]; } + resOffset += bus->size(); + } - return 0; + for (const auto& component : components_) + { + for (IdxT j = 0; j < component->size(); ++j) + { + f_[resOffset + j] = component->getResidual()[j]; + } + resOffset += component->size(); + } + + return 0; } /** @@ -390,73 +391,76 @@ class SystemModel : public ModelEvaluatorImpl * only. * */ - int evaluateJacobian(){return 0;} + int evaluateJacobian() + { + return 0; + } /** * @brief Evaluate integrands for the system quadratures. */ int evaluateIntegrand() { - // Update variables - IdxT varOffset = 0; - IdxT optOffset = 0; - for(const auto& bus: buses_) + // Update variables + IdxT varOffset = 0; + IdxT optOffset = 0; + for (const auto& bus : buses_) + { + for (IdxT j = 0; j < bus->size(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - bus->y()[j] = y_[varOffset + j]; - bus->yp()[j] = yp_[varOffset + j]; - } - varOffset += bus->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - bus->param()[j] = param_[optOffset + j]; - } - optOffset += bus->sizeParams(); - - bus->evaluateIntegrand(); + bus->y()[j] = y_[varOffset + j]; + bus->yp()[j] = yp_[varOffset + j]; } + varOffset += bus->size(); - for(const auto& component : components_) + for (IdxT j = 0; j < bus->sizeParams(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - component->y()[j] = y_[varOffset + j]; - component->yp()[j] = yp_[varOffset + j]; - } - varOffset += component->size(); + bus->param()[j] = param_[optOffset + j]; + } + optOffset += bus->sizeParams(); - for(IdxT j=0; jsizeParams(); ++j) - { - component->param()[j] = param_[optOffset + j]; - } - optOffset += component->sizeParams(); + bus->evaluateIntegrand(); + } - component->evaluateIntegrand(); + for (const auto& component : components_) + { + for (IdxT j = 0; j < component->size(); ++j) + { + component->y()[j] = y_[varOffset + j]; + component->yp()[j] = yp_[varOffset + j]; } + varOffset += component->size(); - // Update integrand vector - IdxT intOffset = 0; - for(const auto& bus: buses_) + for (IdxT j = 0; j < component->sizeParams(); ++j) { - for(IdxT j=0; jsizeQuadrature(); ++j) - { - g_[intOffset + j] = bus->getIntegrand()[j]; - } - intOffset += bus->sizeQuadrature(); + component->param()[j] = param_[optOffset + j]; } + optOffset += component->sizeParams(); - for(const auto& component : components_) + component->evaluateIntegrand(); + } + + // Update integrand vector + IdxT intOffset = 0; + for (const auto& bus : buses_) + { + for (IdxT j = 0; j < bus->sizeQuadrature(); ++j) { - for(IdxT j=0; jsizeQuadrature(); ++j) - { - g_[intOffset + j] = component->getIntegrand()[j]; - } - intOffset += component->sizeQuadrature(); + g_[intOffset + j] = bus->getIntegrand()[j]; } + intOffset += bus->sizeQuadrature(); + } - return 0; + for (const auto& component : components_) + { + for (IdxT j = 0; j < component->sizeQuadrature(); ++j) + { + g_[intOffset + j] = component->getIntegrand()[j]; + } + intOffset += component->sizeQuadrature(); + } + + return 0; } /** @@ -467,73 +471,73 @@ class SystemModel : public ModelEvaluatorImpl */ int initializeAdjoint() { - IdxT offset = 0; - IdxT optOffset = 0; + IdxT offset = 0; + IdxT optOffset = 0; - // Update bus variables and optimization parameters - for(const auto& bus: buses_) + // Update bus variables and optimization parameters + for (const auto& bus : buses_) + { + for (IdxT j = 0; j < bus->size(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - bus->y()[j] = y_[offset + j]; - bus->yp()[j] = yp_[offset + j]; - } - offset += bus->size(); + bus->y()[j] = y_[offset + j]; + bus->yp()[j] = yp_[offset + j]; + } + offset += bus->size(); - for(IdxT j=0; jsizeParams(); ++j) - { - bus->param()[j] = param_[optOffset + j]; - } - optOffset += bus->sizeParams(); + for (IdxT j = 0; j < bus->sizeParams(); ++j) + { + bus->param()[j] = param_[optOffset + j]; } + optOffset += bus->sizeParams(); + } - // Update component variables and optimization parameters - for(const auto& component: components_) + // Update component variables and optimization parameters + for (const auto& component : components_) + { + for (IdxT j = 0; j < component->size(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - component->y()[j] = y_[offset + j]; - component->yp()[j] = yp_[offset + j]; - } - offset += component->size(); + component->y()[j] = y_[offset + j]; + component->yp()[j] = yp_[offset + j]; + } + offset += component->size(); - for(IdxT j=0; jsizeParams(); ++j) - { - component->param()[j] = param_[optOffset + j]; - } - optOffset += component->sizeParams(); + for (IdxT j = 0; j < component->sizeParams(); ++j) + { + component->param()[j] = param_[optOffset + j]; } + optOffset += component->sizeParams(); + } - // Reset counter - offset = 0; + // Reset counter + offset = 0; - // Initialize bus adjoints - for(const auto& bus: buses_) - { - bus->initializeAdjoint(); + // Initialize bus adjoints + for (const auto& bus : buses_) + { + bus->initializeAdjoint(); - for(IdxT j=0; jsize(); ++j) - { - yB_[offset + j] = bus->yB()[j]; - ypB_[offset + j] = bus->ypB()[j]; - } - offset += bus->size(); + for (IdxT j = 0; j < bus->size(); ++j) + { + yB_[offset + j] = bus->yB()[j]; + ypB_[offset + j] = bus->ypB()[j]; } + offset += bus->size(); + } - // Initialize component adjoints - for(const auto& component: components_) - { - component->initializeAdjoint(); + // Initialize component adjoints + for (const auto& component : components_) + { + component->initializeAdjoint(); - for(IdxT j=0; jsize(); ++j) - { - yB_[offset + j] = component->yB()[j]; - ypB_[offset + j] = component->ypB()[j]; - } - offset += component->size(); + for (IdxT j = 0; j < component->size(); ++j) + { + yB_[offset + j] = component->yB()[j]; + ypB_[offset + j] = component->ypB()[j]; } + offset += component->size(); + } - return 0; + return 0; } /** @@ -545,82 +549,80 @@ class SystemModel : public ModelEvaluatorImpl */ int evaluateAdjointResidual() { - IdxT varOffset = 0; - IdxT optOffset = 0; + IdxT varOffset = 0; + IdxT optOffset = 0; - // Update variables in component models - for(const auto& bus: buses_) + // Update variables in component models + for (const auto& bus : buses_) + { + for (IdxT j = 0; j < bus->size(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - bus->y()[j] = y_[varOffset + j]; - bus->yp()[j] = yp_[varOffset + j]; - bus->yB()[j] = yB_[varOffset + j]; - bus->ypB()[j] = ypB_[varOffset + j]; - } - varOffset += bus->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - bus->param()[j] = param_[optOffset + j]; - } - optOffset += bus->sizeParams(); - + bus->y()[j] = y_[varOffset + j]; + bus->yp()[j] = yp_[varOffset + j]; + bus->yB()[j] = yB_[varOffset + j]; + bus->ypB()[j] = ypB_[varOffset + j]; } + varOffset += bus->size(); - for(const auto& component : components_) + for (IdxT j = 0; j < bus->sizeParams(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - component->y()[j] = y_[varOffset + j]; - component->yp()[j] = yp_[varOffset + j]; - component->yB()[j] = yB_[varOffset + j]; - component->ypB()[j] = ypB_[varOffset + j]; - } - varOffset += component->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - component->param()[j] = param_[optOffset + j]; - } - optOffset += component->sizeParams(); - + bus->param()[j] = param_[optOffset + j]; } + optOffset += bus->sizeParams(); + } - for(const auto& bus: buses_) + for (const auto& component : components_) + { + for (IdxT j = 0; j < component->size(); ++j) { - bus->evaluateAdjointResidual(); + component->y()[j] = y_[varOffset + j]; + component->yp()[j] = yp_[varOffset + j]; + component->yB()[j] = yB_[varOffset + j]; + component->ypB()[j] = ypB_[varOffset + j]; } + varOffset += component->size(); - for(const auto& component : components_) + for (IdxT j = 0; j < component->sizeParams(); ++j) { - component->evaluateAdjointResidual(); + component->param()[j] = param_[optOffset + j]; } - - // Update residual vector - IdxT resOffset = 0; - for(const auto& bus: buses_) + optOffset += component->sizeParams(); + } + + for (const auto& bus : buses_) + { + bus->evaluateAdjointResidual(); + } + + for (const auto& component : components_) + { + component->evaluateAdjointResidual(); + } + + // Update residual vector + IdxT resOffset = 0; + for (const auto& bus : buses_) + { + for (IdxT j = 0; j < bus->size(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - fB_[resOffset + j] = bus->getAdjointResidual()[j]; - } - resOffset += bus->size(); + fB_[resOffset + j] = bus->getAdjointResidual()[j]; } + resOffset += bus->size(); + } - for(const auto& component : components_) + for (const auto& component : components_) + { + for (IdxT j = 0; j < component->size(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - fB_[resOffset + j] = component->getAdjointResidual()[j]; - } - resOffset += component->size(); + fB_[resOffset + j] = component->getAdjointResidual()[j]; } + resOffset += component->size(); + } - return 0; + return 0; } - //int evaluateAdjointJacobian(){return 0;} + // int evaluateAdjointJacobian(){return 0;} /** * @brief Evaluate adjoint integrand for the system model. @@ -631,84 +633,84 @@ class SystemModel : public ModelEvaluatorImpl */ int evaluateAdjointIntegrand() { - // First, update variables - IdxT varOffset = 0; - IdxT optOffset = 0; - for(const auto& bus: buses_) - { - for(IdxT j=0; jsize(); ++j) - { - bus->y()[j] = y_[varOffset + j]; - bus->yp()[j] = yp_[varOffset + j]; - bus->yB()[j] = yB_[varOffset + j]; - bus->ypB()[j] = ypB_[varOffset + j]; - } - varOffset += bus->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - bus->param()[j] = param_[optOffset + j]; - } - optOffset += bus->sizeParams(); - } - - for(const auto& component : components_) - { - for(IdxT j=0; jsize(); ++j) - { - component->y()[j] = y_[varOffset + j]; - component->yp()[j] = yp_[varOffset + j]; - component->yB()[j] = yB_[varOffset + j]; - component->ypB()[j] = ypB_[varOffset + j]; - } - varOffset += component->size(); - - for(IdxT j=0; jsizeParams(); ++j) - { - component->param()[j] = param_[optOffset + j]; - } - optOffset += component->sizeParams(); - } - - // Evaluate integrand and update global vector - for(const auto& component : components_) - { - if(component->sizeQuadrature() == 1) - { - component->evaluateAdjointIntegrand(); - for(IdxT j=0; jgetAdjointIntegrand()[j]; - } - break; - } - } - return 0; + // First, update variables + IdxT varOffset = 0; + IdxT optOffset = 0; + for (const auto& bus : buses_) + { + for (IdxT j = 0; j < bus->size(); ++j) + { + bus->y()[j] = y_[varOffset + j]; + bus->yp()[j] = yp_[varOffset + j]; + bus->yB()[j] = yB_[varOffset + j]; + bus->ypB()[j] = ypB_[varOffset + j]; + } + varOffset += bus->size(); + + for (IdxT j = 0; j < bus->sizeParams(); ++j) + { + bus->param()[j] = param_[optOffset + j]; + } + optOffset += bus->sizeParams(); + } + + for (const auto& component : components_) + { + for (IdxT j = 0; j < component->size(); ++j) + { + component->y()[j] = y_[varOffset + j]; + component->yp()[j] = yp_[varOffset + j]; + component->yB()[j] = yB_[varOffset + j]; + component->ypB()[j] = ypB_[varOffset + j]; + } + varOffset += component->size(); + + for (IdxT j = 0; j < component->sizeParams(); ++j) + { + component->param()[j] = param_[optOffset + j]; + } + optOffset += component->sizeParams(); + } + + // Evaluate integrand and update global vector + for (const auto& component : components_) + { + if (component->sizeQuadrature() == 1) + { + component->evaluateAdjointIntegrand(); + for (IdxT j = 0; j < size_opt_; ++j) + { + gB_[j] = component->getAdjointIntegrand()[j]; + } + break; + } + } + return 0; } void updateTime(real_type t, real_type a) { - for(const auto& component : components_) - { - component->updateTime(t, a); - } + for (const auto& component : components_) + { + component->updateTime(t, a); + } } void addBus(bus_type* bus) { - buses_.push_back(bus); + buses_.push_back(bus); } void addComponent(component_type* component) { - components_.push_back(component); + components_.push_back(component); } -private: - std::vector buses_; + private: + std::vector buses_; std::vector components_; -}; // class SystemModel + }; // class SystemModel } // namespace GridKit diff --git a/src/Model/PowerFlow/SystemModelPowerFlow.hpp b/src/Model/PowerFlow/SystemModelPowerFlow.hpp index f380c4cf..738888a0 100644 --- a/src/Model/PowerFlow/SystemModelPowerFlow.hpp +++ b/src/Model/PowerFlow/SystemModelPowerFlow.hpp @@ -60,38 +60,38 @@ /** * @file SystemSteadyStaeModel.hpp * @author Slaven Peles - * + * * Contains definition of power flow analysis class. - * + * */ #pragma once +#include #include #include -#include -#include #include +#include namespace GridKit { -/** - * @brief Prototype for a system model class - * - * This class maps component data to system data and implements - * ModelEvaluator for the system model. This is still work in - * progress and code is not optimized. - * - * @todo Address thread safety for the system model methods. - * - * @todo Tolerance management needs to be reconsidered. - * - */ -template -class SystemSteadyStateModel : public ModelEvaluatorImpl -{ - typedef BaseBus bus_type; + /** + * @brief Prototype for a system model class + * + * This class maps component data to system data and implements + * ModelEvaluator for the system model. This is still work in + * progress and code is not optimized. + * + * @todo Address thread safety for the system model methods. + * + * @todo Tolerance management needs to be reconsidered. + * + */ + template + class SystemSteadyStateModel : public ModelEvaluatorImpl + { + typedef BaseBus bus_type; typedef ModelEvaluatorImpl component_type; using real_type = typename ModelEvaluatorImpl::real_type; @@ -116,57 +116,59 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl // using ModelEvaluatorImpl::param_up_; // using ModelEvaluatorImpl::param_lo_; -public: + public: /** * @brief Constructor for the system model */ - SystemSteadyStateModel() : ModelEvaluatorImpl(0, 0, 0) + SystemSteadyStateModel() + : ModelEvaluatorImpl(0, 0, 0) { - // Set system model tolerances - rel_tol_ = 1e-5; - abs_tol_ = 1e-5; + // Set system model tolerances + rel_tol_ = 1e-5; + abs_tol_ = 1e-5; } /** * @brief Construct a new System Steady State Model object. Allows for simple allocation. - * + * * @param mp model data */ - SystemSteadyStateModel(GridKit::PowerSystemData::SystemModelData mp) : ModelEvaluatorImpl(0,0,0) + SystemSteadyStateModel(GridKit::PowerSystemData::SystemModelData mp) + : ModelEvaluatorImpl(0, 0, 0) { - rel_tol_ = 1e-5; - abs_tol_ = 1e-5; - - //add buses - for(auto busdata : mp.bus) - { - auto* bus = BusFactory::create(busdata); - this->addBus(bus); - } - - //add generators - for (auto gendata : mp.gen) - { - 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); - this->addComponent(branch); - } - - //add loads - for (auto loaddata : mp.load) - { - auto* loadm = new Load(this->getBus(loaddata.bus_i),loaddata); - this->addComponent(loadm); - } - - //There is no Generator Cost Object - //TODO: Implment for GenCost + rel_tol_ = 1e-5; + abs_tol_ = 1e-5; + + // add buses + for (auto busdata : mp.bus) + { + auto* bus = BusFactory::create(busdata); + this->addBus(bus); + } + + // add generators + for (auto gendata : mp.gen) + { + 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); + this->addComponent(branch); + } + + // add loads + for (auto loaddata : mp.load) + { + auto* loadm = new Load(this->getBus(loaddata.bus_i), loaddata); + this->addComponent(loadm); + } + + // There is no Generator Cost Object + // TODO: Implment for GenCost } /** @@ -174,8 +176,10 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl */ virtual ~SystemSteadyStateModel() { - for (auto comp : this->components_) delete comp; - for (auto bus : this->buses_) delete bus; + for (auto comp : this->components_) + delete comp; + for (auto bus : this->buses_) + delete bus; } /** @@ -192,27 +196,27 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl */ int allocate() { - size_ = 0; - - // Allocate all buses - for(const auto& bus: buses_) - { - bus->allocate(); - size_ += bus->size(); - } - - // Allocate all components - for(const auto& component : components_) - { - component->allocate(); - size_ += component->size(); - } - - // Allocate global vectors - y_.resize(size_); - f_.resize(size_); - - return 0; + size_ = 0; + + // Allocate all buses + for (const auto& bus : buses_) + { + bus->allocate(); + size_ += bus->size(); + } + + // Allocate all components + for (const auto& component : components_) + { + component->allocate(); + size_ += component->size(); + } + + // Allocate global vectors + y_.resize(size_); + f_.resize(size_); + + return 0; } /** @@ -232,38 +236,38 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl */ int initialize() { - // Set initial values for global solution vectors - IdxT varOffset = 0; + // Set initial values for global solution vectors + IdxT varOffset = 0; - for(const auto& bus: buses_) - { - bus->initialize(); - } - - for(const auto& bus: buses_) - { - for(IdxT j=0; jsize(); ++j) - { - y_[varOffset + j] = bus->y()[j]; - } - varOffset += bus->size(); - } + for (const auto& bus : buses_) + { + bus->initialize(); + } - // Initialize components - for(const auto& component : components_) + for (const auto& bus : buses_) + { + for (IdxT j = 0; j < bus->size(); ++j) { - component->initialize(); + y_[varOffset + j] = bus->y()[j]; } - - for(const auto& component : components_) + varOffset += bus->size(); + } + + // Initialize components + for (const auto& component : components_) + { + component->initialize(); + } + + for (const auto& component : components_) + { + for (IdxT j = 0; j < component->size(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - y_[varOffset + j] = component->y()[j]; - } - varOffset += component->size(); + y_[varOffset + j] = component->y()[j]; } - return 0; + varOffset += component->size(); + } + return 0; } /** @@ -275,7 +279,7 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl */ int tagDifferentiable() { - return 0; + return 0; } /** @@ -298,49 +302,49 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl */ int evaluateResidual() { - // Update variables - IdxT varOffset = 0; - for(const auto& bus: buses_) + // Update variables + IdxT varOffset = 0; + for (const auto& bus : buses_) + { + for (IdxT j = 0; j < bus->size(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - bus->y()[j] = y_[varOffset + j]; - } - varOffset += bus->size(); - bus->evaluateResidual(); + bus->y()[j] = y_[varOffset + j]; } + varOffset += bus->size(); + bus->evaluateResidual(); + } - for(const auto& component : components_) + for (const auto& component : components_) + { + for (IdxT j = 0; j < component->size(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - component->y()[j] = y_[varOffset + j]; - } - varOffset += component->size(); - component->evaluateResidual(); + component->y()[j] = y_[varOffset + j]; } - - // Update system residual vector - IdxT resOffset = 0; - for(const auto& bus : buses_) + varOffset += component->size(); + component->evaluateResidual(); + } + + // Update system residual vector + IdxT resOffset = 0; + for (const auto& bus : buses_) + { + for (IdxT j = 0; j < bus->size(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - f_[resOffset + j] = bus->getResidual()[j]; - } - resOffset += bus->size(); + f_[resOffset + j] = bus->getResidual()[j]; } + resOffset += bus->size(); + } - for(const auto& component : components_) + for (const auto& component : components_) + { + for (IdxT j = 0; j < component->size(); ++j) { - for(IdxT j=0; jsize(); ++j) - { - f_[resOffset + j] = component->getResidual()[j]; - } - resOffset += component->size(); + f_[resOffset + j] = component->getResidual()[j]; } + resOffset += component->size(); + } - return 0; + return 0; } /** @@ -351,7 +355,10 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl * only. * */ - int evaluateJacobian(){return 0;} + int evaluateJacobian() + { + return 0; + } /** * @brief Evaluate integrands for the system quadratures. @@ -359,7 +366,7 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl int evaluateIntegrand() { - return 0; + return 0; } /** @@ -370,7 +377,7 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl */ int initializeAdjoint() { - return 0; + return 0; } /** @@ -382,10 +389,10 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl */ int evaluateAdjointResidual() { - return 0; + return 0; } - //int evaluateAdjointJacobian(){return 0;} + // int evaluateAdjointJacobian(){return 0;} /** * @brief Evaluate adjoint integrand for the system model. @@ -396,7 +403,7 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl */ int evaluateAdjointIntegrand() { - return 0; + return 0; } void updateTime(real_type t, real_type a) @@ -405,25 +412,25 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl void addBus(bus_type* bus) { - buses_.push_back(bus); + buses_.push_back(bus); } void addComponent(component_type* component) { - components_.push_back(component); + components_.push_back(component); } bus_type* getBus(IdxT busid) { - // Need to implement mapping of bus IDs to buses in the system model - assert( (buses_[busid - 1])->BusID() == busid ); - return buses_[busid - 1]; + // Need to implement mapping of bus IDs to buses in the system model + assert((buses_[busid - 1])->BusID() == busid); + return buses_[busid - 1]; } -private: - std::vector buses_; + private: + std::vector buses_; std::vector components_; -}; // class SystemSteadyStateModel + }; // class SystemSteadyStateModel } // namespace GridKit \ No newline at end of file diff --git a/src/PowerSystemData.hpp b/src/PowerSystemData.hpp index 67294db4..a7b7dfb1 100644 --- a/src/PowerSystemData.hpp +++ b/src/PowerSystemData.hpp @@ -1,8 +1,8 @@ #pragma once -#include -#include #include +#include #include +#include /** * @@ -17,226 +17,226 @@ namespace GridKit { -namespace PowerSystemData -{ - - template - struct BusData + namespace PowerSystemData { - IdxT bus_i; ///< Bus ID - IdxT type; ///< Bus type: 1 = PQ, 2 = PV, 3 = ref, 4 = isolated - RealT Gs; ///< Shunt conductance (MW demanded at V = 1.0 p.u.) - RealT Bs; ///< Shunt susceptance (MVAr injected at V = 1.0 p.u.) - IdxT area; ///< Area number (>0) - RealT Vm; ///< Voltage magnitude (p.u.) - RealT Va; ///< Voltage phase (deg) - RealT baseKV; ///< Base voltage [kV] - IdxT zone; ///< Loss zone number (>0) - RealT Vmax; ///< Maximum voltage magnitude (p.u.) - RealT Vmin; ///< Minimum voltage magnitude (p.u.) - - inline std::string str() const - { - std::stringstream ss; - std::cerr << 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(); - } - }; - - template - struct LoadData - { - IdxT bus_i; ///< Bus ID - RealT Pd; ///< Active power demand [MW] - RealT Qd; ///< Reactive power demand [MVAr] - inline std::string str() const + template + struct BusData { - std::stringstream ss; - std::cerr << std::setw(10) << bus_i - << std::setw(10) << Pd - << std::setw(10) << Qd; - ss << "\n"; - return ss.str(); - } - }; - - template - struct GenData - { - IdxT bus; ///< Bus ID - RealT Pg; ///< Active power output [MW] - RealT Qg; ///< Reactive power output [MVAr] - RealT Qmax; ///< Maximum reactive power output [MVAr] - RealT Qmin; ///< Minimum reactive power output [MVAr] - RealT Vg; ///< - RealT mBase; ///< Total MVA base of machine - IdxT status; ///< Service status (>0 in service, <=0 out of service) - RealT Pmax; ///< Maximum active power output [MVAr] - RealT Pmin; ///< Minimum active power output [MVAr] - RealT Pc1; ///< - RealT Pc2; ///< - RealT Qc1min; ///< - RealT Qc1max; ///< - RealT Qc2min; ///< - RealT Qc2max; ///< - RealT ramp_agc; ///< - RealT ramp_10; ///< - RealT ramp_30; ///< - RealT ramp_q; ///< - RealT apf; ///< - - inline std::string str() const + IdxT bus_i; ///< Bus ID + IdxT type; ///< Bus type: 1 = PQ, 2 = PV, 3 = ref, 4 = isolated + RealT Gs; ///< Shunt conductance (MW demanded at V = 1.0 p.u.) + RealT Bs; ///< Shunt susceptance (MVAr injected at V = 1.0 p.u.) + IdxT area; ///< Area number (>0) + RealT Vm; ///< Voltage magnitude (p.u.) + RealT Va; ///< Voltage phase (deg) + RealT baseKV; ///< Base voltage [kV] + IdxT zone; ///< Loss zone number (>0) + RealT Vmax; ///< Maximum voltage magnitude (p.u.) + RealT Vmin; ///< Minimum voltage magnitude (p.u.) + + inline std::string str() const + { + std::stringstream ss; + std::cerr << 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(); + } + }; + + template + struct LoadData { - 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 << "\n"; - return ss.str(); - } - }; - - template - struct BranchData - { - IdxT fbus; ///< "From" bus ID - IdxT tbus; ///< "To" bus ID - RealT r; ///< Resistance (p.u.) - RealT x; ///< Reactance (p.u.) - RealT b; ///< Total line charging susceptance (p.u.) - RealT rateA; ///< MVA rating A (long term rating), 0=unlimited - RealT rateB; ///< MVA rating B (short term rating), 0=unlimited - RealT rateC; ///< MVA rating C (emergency rating), 0=unlimited - RealT ratio; ///< Transformer off nominal turns ratio - RealT angle; ///< Transformer phase shift angle [deg], positive ⇒ delay - IdxT status; ///< Initial service status: 1=in-service, 0=out-of-service - RealT angmin; ///< Minimum anngle difference af - at [deg] - RealT angmax; ///< Maximum anngle difference af - at [deg] - - inline std::string str() const + IdxT bus_i; ///< Bus ID + RealT Pd; ///< Active power demand [MW] + RealT Qd; ///< Reactive power demand [MVAr] + + inline std::string str() const + { + std::stringstream ss; + std::cerr << std::setw(10) << bus_i + << std::setw(10) << Pd + << std::setw(10) << Qd; + ss << "\n"; + return ss.str(); + } + }; + + template + struct GenData { - 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 << "\n"; - return ss.str(); - } - }; - - template - struct GenCostData - { - IdxT kind; - IdxT startup; - IdxT shutdown; - IdxT n; - std::vector rest; - - inline std::string str() const + IdxT bus; ///< Bus ID + RealT Pg; ///< Active power output [MW] + RealT Qg; ///< Reactive power output [MVAr] + RealT Qmax; ///< Maximum reactive power output [MVAr] + RealT Qmin; ///< Minimum reactive power output [MVAr] + RealT Vg; ///< + RealT mBase; ///< Total MVA base of machine + IdxT status; ///< Service status (>0 in service, <=0 out of service) + RealT Pmax; ///< Maximum active power output [MVAr] + RealT Pmin; ///< Minimum active power output [MVAr] + RealT Pc1; ///< + RealT Pc2; ///< + RealT Qc1min; ///< + RealT Qc1max; ///< + RealT Qc2min; ///< + RealT Qc2max; ///< + RealT ramp_agc; ///< + RealT ramp_10; ///< + RealT ramp_30; ///< + RealT ramp_q; ///< + RealT apf; ///< + + 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 << "\n"; + return ss.str(); + } + }; + + template + struct BranchData { - std::stringstream ss; - 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"; - return ss.str(); - } - }; - - template - struct SystemModelData - { - using BusDataT = BusData; - using GenDataT = GenData; - using BranchDataT = BranchData; - using GenCostDataT = GenCostData; - using LoadDataT = LoadData; - - std::string version; - IdxT baseMVA; - std::vector bus; - std::vector gen; - std::vector branch; - std::vector gencost; - std::vector load; - - // Not sure if these should be in this struct... Not all matpower files - // I found contained them. - // - // std::string name; - // std::vector bus_name; - - inline std::string str() const + IdxT fbus; ///< "From" bus ID + IdxT tbus; ///< "To" bus ID + RealT r; ///< Resistance (p.u.) + RealT x; ///< Reactance (p.u.) + RealT b; ///< Total line charging susceptance (p.u.) + RealT rateA; ///< MVA rating A (long term rating), 0=unlimited + RealT rateB; ///< MVA rating B (short term rating), 0=unlimited + RealT rateC; ///< MVA rating C (emergency rating), 0=unlimited + RealT ratio; ///< Transformer off nominal turns ratio + RealT angle; ///< Transformer phase shift angle [deg], positive ⇒ delay + IdxT status; ///< Initial service status: 1=in-service, 0=out-of-service + RealT angmin; ///< Minimum anngle difference af - at [deg] + RealT angmax; ///< Maximum anngle difference af - at [deg] + + 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 << "\n"; + return ss.str(); + } + }; + + template + struct GenCostData { - std::stringstream ss; - ss << "Version: " << version << "\n" - << "Base MVA: " << baseMVA << "\n"; - - ss << "Bus:\n"; - for (const auto& v : bus) - ss << bus.str() << "\n"; - - ss << "Gen:\n"; - for (const auto& v : gen) - ss << gen.str(); - - ss << "Branch:\n"; - for (const auto& v : branch) - ss << branch.str(); - - ss << "GenCost:\n"; - for (const auto& v : gencost) - ss << gencost.str(); - - ss << "\n"; - - return ss.str(); - } - }; // struct SystemModelData - -} // namespace PowerSystemData -} // namespace GridKit + IdxT kind; + IdxT startup; + IdxT shutdown; + IdxT n; + std::vector rest; + + 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; + for (const auto& val : rest) + ss << std::setw(10) << val; + ss << "\n"; + return ss.str(); + } + }; + + template + struct SystemModelData + { + using BusDataT = BusData; + using GenDataT = GenData; + using BranchDataT = BranchData; + using GenCostDataT = GenCostData; + using LoadDataT = LoadData; + + std::string version; + IdxT baseMVA; + std::vector bus; + std::vector gen; + std::vector branch; + std::vector gencost; + std::vector load; + + // Not sure if these should be in this struct... Not all matpower files + // I found contained them. + // + // std::string name; + // std::vector bus_name; + + inline std::string str() const + { + std::stringstream ss; + ss << "Version: " << version << "\n" + << "Base MVA: " << baseMVA << "\n"; + + ss << "Bus:\n"; + for (const auto& v : bus) + ss << bus.str() << "\n"; + + ss << "Gen:\n"; + for (const auto& v : gen) + ss << gen.str(); + + ss << "Branch:\n"; + for (const auto& v : branch) + ss << branch.str(); + + ss << "GenCost:\n"; + for (const auto& v : gencost) + ss << gencost.str(); + + ss << "\n"; + + return ss.str(); + } + }; // struct SystemModelData + + } // namespace PowerSystemData +} // namespace GridKit diff --git a/src/ScalarTraits.hpp b/src/ScalarTraits.hpp index 072e8371..ca5c0b38 100644 --- a/src/ScalarTraits.hpp +++ b/src/ScalarTraits.hpp @@ -62,19 +62,19 @@ namespace GridKit { - template - class ScalarTraits - { - }; + template + class ScalarTraits + { + }; - template<> - class ScalarTraits - { - public: - typedef double real_type; - typedef double norm_type; - typedef double scalar_type; - }; + template <> + class ScalarTraits + { + public: + typedef double real_type; + typedef double norm_type; + typedef double scalar_type; + }; } // namespace GridKit diff --git a/src/Solver/Dynamic/DynamicSolver.hpp b/src/Solver/Dynamic/DynamicSolver.hpp index ab7387f1..eabf0548 100644 --- a/src/Solver/Dynamic/DynamicSolver.hpp +++ b/src/Solver/Dynamic/DynamicSolver.hpp @@ -1,25 +1,25 @@ /* - * + * * Copyright (c) 2017, Lawrence Livermore National Security, LLC. * Produced at the Lawrence Livermore National Laboratory. * Written by Slaven Peles . * LLNL-CODE-718378. * All rights reserved. - * - * This file is part of GridKit™. For details, see github.com/LLNL/GridKit - * Please also read the LICENSE file. - * - * Redistribution and use in source and binary forms, with or without + * + * This file is part of GridKit™. For details, see github.com/LLNL/GridKit + * Please also read the LICENSE file. + * + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright notice, + * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the disclaimer below. * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the disclaimer (as noted below) in the + * this list of conditions and the disclaimer (as noted below) in the * documentation and/or other materials provided with the distribution. - * - Neither the name of the LLNS/LLNL nor the names of its contributors may - * be used to endorse or promote products derived from this software without + * - Neither the name of the LLNS/LLNL nor the names of its contributors may + * be used to endorse or promote products derived from this software without * specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF @@ -31,33 +31,32 @@ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. - * - * Lawrence Livermore National Laboratory is operated by Lawrence Livermore - * National Security, LLC, for the U.S. Department of Energy, National + * + * Lawrence Livermore National Laboratory is operated by Lawrence Livermore + * National Security, LLC, for the U.S. Department of Energy, National * Nuclear Security Administration under Contract DE-AC52-07NA27344. - * - * This document was prepared as an account of work sponsored by an agency - * of the United States government. Neither the United States government nor - * Lawrence Livermore National Security, LLC, nor any of their employees - * makes any warranty, expressed or implied, or assumes any legal liability - * or responsibility for the accuracy, completeness, or usefulness of any - * information, apparatus, product, or process disclosed, or represents that - * its use would not infringe privately owned rights. Reference herein to - * any specific commercial product, process, or service by trade name, - * trademark, manufacturer, or otherwise does not necessarily constitute or - * imply its endorsement, recommendation, or favoring by the United States - * government or Lawrence Livermore National Security, LLC. The views and - * opinions of authors expressed herein do not necessarily state or reflect - * those of the United States government or Lawrence Livermore National - * Security, LLC, and shall not be used for advertising or product - * endorsement purposes. - * + * + * This document was prepared as an account of work sponsored by an agency + * of the United States government. Neither the United States government nor + * Lawrence Livermore National Security, LLC, nor any of their employees + * makes any warranty, expressed or implied, or assumes any legal liability + * or responsibility for the accuracy, completeness, or usefulness of any + * information, apparatus, product, or process disclosed, or represents that + * its use would not infringe privately owned rights. Reference herein to + * any specific commercial product, process, or service by trade name, + * trademark, manufacturer, or otherwise does not necessarily constitute or + * imply its endorsement, recommendation, or favoring by the United States + * government or Lawrence Livermore National Security, LLC. The views and + * opinions of authors expressed herein do not necessarily state or reflect + * those of the United States government or Lawrence Livermore National + * Security, LLC, and shall not be used for advertising or product + * endorsement purposes. + * */ - #ifndef _DYNAMIC_SOLVER_HPP_ #define _DYNAMIC_SOLVER_HPP_ @@ -65,25 +64,28 @@ namespace AnalysisManager { - template - class DynamicSolver + template + class DynamicSolver + { + public: + DynamicSolver(GridKit::Model::Evaluator* model) + : model_(model) + { + } + + virtual ~DynamicSolver() + { + } + + GridKit::Model::Evaluator* getModel() { - public: - DynamicSolver(GridKit::Model::Evaluator* model) : model_(model) - { - } - virtual ~DynamicSolver(){} - - GridKit::Model::Evaluator* getModel() - { - return model_; - } - - protected: - GridKit::Model::Evaluator* model_; - }; + return model_; + } -} + protected: + GridKit::Model::Evaluator* model_; + }; +} // namespace AnalysisManager #endif // _DYNAMIC_SOLVER_HPP_ diff --git a/src/Solver/Dynamic/Ida.cpp b/src/Solver/Dynamic/Ida.cpp index f0e6478b..6294f2d1 100644 --- a/src/Solver/Dynamic/Ida.cpp +++ b/src/Solver/Dynamic/Ida.cpp @@ -57,757 +57,742 @@ * */ +#include "Ida.hpp" -#include #include +#include #include #include #include "Model/Evaluator.hpp" -#include "Ida.hpp" - namespace AnalysisManager { -namespace Sundials -{ + namespace Sundials + { template - Ida::Ida(GridKit::Model::Evaluator* model) : DynamicSolver(model) + Ida::Ida(GridKit::Model::Evaluator* model) + : DynamicSolver(model) { - int retval = 0; + int retval = 0; - // Create the SUNDIALS context that all SUNDIALS objects require - retval = SUNContext_Create(SUN_COMM_NULL, &context_); - checkOutput(retval, "SUNContext"); - solver_ = IDACreate(context_); - tag_ = NULL; + // Create the SUNDIALS context that all SUNDIALS objects require + retval = SUNContext_Create(SUN_COMM_NULL, &context_); + checkOutput(retval, "SUNContext"); + solver_ = IDACreate(context_); + tag_ = NULL; } /** * @brief Destroy the Ida< Scalar T, Idx T>:: Ida object - * + * * @note if sysmodel is freed before this will fail. May want something agnostic to this - * - * @tparam ScalarT - * @tparam IdxT + * + * @tparam ScalarT + * @tparam IdxT */ template Ida::~Ida() { - N_VDestroy(yy_); - N_VDestroy(yp_); - N_VDestroy(yy0_); - N_VDestroy(yp0_); - if (model_->hasJacobian()) - { - SUNLinSolFree_KLU(linearSolver_); - SUNMatDestroy_Sparse(JacobianMat_); - } - else - { - SUNLinSolFree_Dense(linearSolver_); - SUNMatDestroy_Dense(JacobianMat_); - } - ///@todo this free is needed but on geninfbus this seg faults - // IDAFree(&solver_); - SUNContext_Free(&context_); - + N_VDestroy(yy_); + N_VDestroy(yp_); + N_VDestroy(yy0_); + N_VDestroy(yp0_); + if (model_->hasJacobian()) + { + SUNLinSolFree_KLU(linearSolver_); + SUNMatDestroy_Sparse(JacobianMat_); + } + else + { + SUNLinSolFree_Dense(linearSolver_); + SUNMatDestroy_Dense(JacobianMat_); + } + ///@todo this free is needed but on geninfbus this seg faults + // IDAFree(&solver_); + SUNContext_Free(&context_); } template int Ida::configureSimulation() { - int retval = 0; + int retval = 0; - // Allocate solution vectors - yy_ = N_VNew_Serial(model_->size(), context_); - checkAllocation((void*) yy_, "N_VNew_Serial"); - yp_ = N_VClone(yy_); - checkAllocation((void*) yp_, "N_VClone"); + // Allocate solution vectors + yy_ = N_VNew_Serial(model_->size(), context_); + checkAllocation((void*) yy_, "N_VNew_Serial"); + yp_ = N_VClone(yy_); + checkAllocation((void*) yp_, "N_VClone"); - //get intial conditions - this->getDefaultInitialCondition(); + // get intial conditions + this->getDefaultInitialCondition(); - // Create vectors to store restart initial condition - yy0_ = N_VClone(yy_); - checkAllocation((void*) yy0_, "N_VClone"); - yp0_ = N_VClone(yy_); - checkAllocation((void*) yp0_, "N_VClone"); + // Create vectors to store restart initial condition + yy0_ = N_VClone(yy_); + checkAllocation((void*) yy0_, "N_VClone"); + yp0_ = N_VClone(yy_); + checkAllocation((void*) yp0_, "N_VClone"); - // Dummy initial time; will be overridden. - const sunrealtype t0 = SUN_RCONST(0.0); + // Dummy initial time; will be overridden. + const sunrealtype t0 = SUN_RCONST(0.0); - // Allocate and initialize IDA workspace - retval = IDAInit(solver_, this->Residual, t0, yy_, yp_); - checkOutput(retval, "IDAInit"); + // Allocate and initialize IDA workspace + retval = IDAInit(solver_, this->Residual, t0, yy_, yp_); + checkOutput(retval, "IDAInit"); - // Set pointer to model data - retval = IDASetUserData(solver_, model_); - checkOutput(retval, "IDASetUserData"); + // Set pointer to model data + retval = IDASetUserData(solver_, model_); + checkOutput(retval, "IDASetUserData"); - // Set tolerances - sunrealtype rel_tol; - sunrealtype abs_tol; + // Set tolerances + sunrealtype rel_tol; + sunrealtype abs_tol; - model_->setTolerances(rel_tol, abs_tol); ///< \todo Function name should be "getTolerances"! - retval = IDASStolerances(solver_, rel_tol, abs_tol); - checkOutput(retval, "IDASStolerances"); - - IdxT msa; - model_->setMaxSteps(msa); + model_->setTolerances(rel_tol, abs_tol); ///< \todo Function name should be "getTolerances"! + retval = IDASStolerances(solver_, rel_tol, abs_tol); + checkOutput(retval, "IDASStolerances"); - /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumSteps(solver_, msa); - checkOutput(retval, "IDASetMaxNumSteps"); + IdxT msa; + model_->setMaxSteps(msa); - // Tag differential variables - std::vector& tag = model_->tag(); - if (static_cast(tag.size()) == model_->size()) - { - tag_ = N_VClone(yy_); - checkAllocation((void*) tag_, "N_VClone"); - model_->tagDifferentiable(); - copyVec(tag, tag_); - - retval = IDASetId(solver_, tag_); - checkOutput(retval, "IDASetId"); - retval = IDASetSuppressAlg(solver_, SUNTRUE); - checkOutput(retval, "IDASetSuppressAlg"); - } + /// \todo Need to set max number of steps based on user input! + retval = IDASetMaxNumSteps(solver_, msa); + checkOutput(retval, "IDASetMaxNumSteps"); + + // Tag differential variables + std::vector& tag = model_->tag(); + if (static_cast(tag.size()) == model_->size()) + { + tag_ = N_VClone(yy_); + checkAllocation((void*) tag_, "N_VClone"); + model_->tagDifferentiable(); + copyVec(tag, tag_); - // Set up linear solver - this->configureLinearSolver(); + retval = IDASetId(solver_, tag_); + checkOutput(retval, "IDASetId"); + retval = IDASetSuppressAlg(solver_, SUNTRUE); + checkOutput(retval, "IDASetSuppressAlg"); + } - return retval; + // Set up linear solver + this->configureLinearSolver(); + + return retval; } template int Ida::configureLinearSolver() { - int retval = 0; - if (model_->hasJacobian()) - { - JacobianMat_ = SUNSparseMatrix(model_->size(), model_->size(), model_->size() * model_->size(), CSR_MAT, context_); - checkAllocation((void*) JacobianMat_, "SUNSparseMatrix"); + int retval = 0; + if (model_->hasJacobian()) + { + JacobianMat_ = SUNSparseMatrix(model_->size(), model_->size(), model_->size() * model_->size(), CSR_MAT, context_); + checkAllocation((void*) JacobianMat_, "SUNSparseMatrix"); - linearSolver_ = SUNLinSol_KLU(yy_, JacobianMat_, context_); - checkAllocation((void*) linearSolver_, "SUNLinSol_KLU"); + linearSolver_ = SUNLinSol_KLU(yy_, JacobianMat_, context_); + checkAllocation((void*) linearSolver_, "SUNLinSol_KLU"); - retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "IDASetLinearSolver"); - - retval = IDASetJacFn(solver_, this->Jac); - checkOutput(retval, "IDASetJacFn"); - } - else - { - JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); + retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "IDASetLinearSolver"); - linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); - checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); + retval = IDASetJacFn(solver_, this->Jac); + checkOutput(retval, "IDASetJacFn"); + } + else + { + JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); - retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "IDASetLinearSolver"); + linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); + checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); - } + retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "IDASetLinearSolver"); + } - return retval; + return retval; } template int Ida::getDefaultInitialCondition() { - model_->initialize(); + model_->initialize(); - copyVec(model_->y(), yy_); - copyVec(model_->yp(), yp_); + copyVec(model_->y(), yy_); + copyVec(model_->yp(), yp_); - return 0; + return 0; } template int Ida::setIntegrationTime(real_type t_init, real_type t_final, int nout) { - t_init_ = t_init; - t_final_ = t_final; - nout_ = nout; - return 0; + t_init_ = t_init; + t_final_ = t_final; + nout_ = nout; + return 0; } template int Ida::initializeSimulation(real_type t0, bool findConsistent) { - int retval = 0; + int retval = 0; - // Need to reinitialize IDA to set to get correct initial conditions - retval = IDAReInit(solver_, t0, yy_, yp_); - checkOutput(retval, "IDAReInit"); + // Need to reinitialize IDA to set to get correct initial conditions + retval = IDAReInit(solver_, t0, yy_, yp_); + checkOutput(retval, "IDAReInit"); - // Find a consistent set of initial conditions for DAE - if (findConsistent) - { - int initType = IDA_Y_INIT; + // Find a consistent set of initial conditions for DAE + if (findConsistent) + { + int initType = IDA_Y_INIT; - if (tag_) - initType = IDA_YA_YDP_INIT; + if (tag_) + initType = IDA_YA_YDP_INIT; - retval = IDACalcIC(solver_, initType, 0.1); - checkOutput(retval, "IDACalcIC"); - - copyVec(yy_, model_->y()); - copyVec(yp_, model_->yp()); - } + retval = IDACalcIC(solver_, initType, 0.1); + checkOutput(retval, "IDACalcIC"); - return retval; + copyVec(yy_, model_->y()); + copyVec(yp_, model_->yp()); + } + + return retval; } template int Ida::runSimulation(real_type tf, int nout) { - int retval = 0; - int iout = 0; - real_type tret; - real_type dt = tf / static_cast(nout); - real_type tout = dt; - - /* In loop, call IDASolve, print results, and test for error. - * Break out of loop when NOUT preset output times have been reached. */ - //printOutput(0.0); - while(nout > iout) + int retval = 0; + int iout = 0; + real_type tret; + real_type dt = tf / static_cast(nout); + real_type tout = dt; + + /* In loop, call IDASolve, print results, and test for error. + * Break out of loop when NOUT preset output times have been reached. */ + // printOutput(0.0); + while (nout > iout) + { + retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); + checkOutput(retval, "IDASolve"); + // printOutput(tout); + + if (retval == IDA_SUCCESS) { - retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); - checkOutput(retval, "IDASolve"); - //printOutput(tout); - - if (retval == IDA_SUCCESS) - { - ++iout; - tout += dt; - } + ++iout; + tout += dt; } + } - //Final copy out. No gaurentee last residual evaluation is final step. - model_->updateTime(tf, 0.0); - copyVec(yy_, model_->y()); - copyVec(yp_, model_->yp()); + // Final copy out. No gaurentee last residual evaluation is final step. + model_->updateTime(tf, 0.0); + copyVec(yy_, model_->y()); + copyVec(yp_, model_->yp()); - //std::cout << "\n"; - return retval; + // std::cout << "\n"; + return retval; } template int Ida::deleteSimulation() { - IDAFree(&solver_); - SUNLinSolFree(linearSolver_); - N_VDestroy(yy_); - N_VDestroy(yp_); - return 0; + IDAFree(&solver_); + SUNLinSolFree(linearSolver_); + N_VDestroy(yy_); + N_VDestroy(yp_); + return 0; } - template int Ida::configureQuadrature() { - int retval = 0; + int retval = 0; - // Create and initialize quadratures - q_ = N_VNew_Serial(model_->sizeQuadrature(), context_); - checkAllocation((void*) q_, "N_VNew_Serial"); + // Create and initialize quadratures + q_ = N_VNew_Serial(model_->sizeQuadrature(), context_); + checkAllocation((void*) q_, "N_VNew_Serial"); - // Set integrand function and allocate quadrature workspace - retval = IDAQuadInit(solver_, this->Integrand, q_); - checkOutput(retval, "IDAQuadInit"); + // Set integrand function and allocate quadrature workspace + retval = IDAQuadInit(solver_, this->Integrand, q_); + checkOutput(retval, "IDAQuadInit"); - // Set tolerances and error control for quadratures - real_type rel_tol, abs_tol; - model_->setTolerances(rel_tol, abs_tol); + // Set tolerances and error control for quadratures + real_type rel_tol, abs_tol; + model_->setTolerances(rel_tol, abs_tol); - // Set tolerances for quadrature stricter than for integration - retval = IDAQuadSStolerances(solver_, rel_tol*0.1, abs_tol*0.1); - checkOutput(retval, "IDAQuadSStolerances"); + // Set tolerances for quadrature stricter than for integration + retval = IDAQuadSStolerances(solver_, rel_tol * 0.1, abs_tol * 0.1); + checkOutput(retval, "IDAQuadSStolerances"); - // Include quadrature in eror checking - retval = IDASetQuadErrCon(solver_, SUNTRUE); - checkOutput(retval, "IDASetQuadErrCon"); + // Include quadrature in eror checking + retval = IDASetQuadErrCon(solver_, SUNTRUE); + checkOutput(retval, "IDASetQuadErrCon"); - return retval; + return retval; } - template int Ida::initializeQuadrature() { - int retval = 0; + int retval = 0; - // Set all quadratures to zero - N_VConst(SUN_RCONST(0.0), q_); + // Set all quadratures to zero + N_VConst(SUN_RCONST(0.0), q_); - // Initialize quadratures - retval = IDAQuadReInit(solver_, q_); - checkOutput(retval, "IDAQuadInit"); + // Initialize quadratures + retval = IDAQuadReInit(solver_, q_); + checkOutput(retval, "IDAQuadInit"); - return retval; + return retval; } - template int Ida::runSimulationQuadrature(real_type tf, int nout) { - int retval = 0; - real_type tret; + int retval = 0; + real_type tret; - //std::cout << "Forward integration for initial value problem ... \n"; + // std::cout << "Forward integration for initial value problem ... \n"; - real_type dt = tf / static_cast(nout); - real_type tout = dt; - //printOutput(0.0); - //printSpecial(0.0, yy_); - for(int i = 0; i < nout; ++i) + real_type dt = tf / static_cast(nout); + real_type tout = dt; + // printOutput(0.0); + // printSpecial(0.0, yy_); + for (int i = 0; i < nout; ++i) + { + retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); + checkOutput(retval, "IDASolve"); + // printSpecial(tout, yy_); + // printOutput(tout); + + if (retval == IDA_SUCCESS) { - retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); - checkOutput(retval, "IDASolve"); - //printSpecial(tout, yy_); - //printOutput(tout); - - if (retval == IDA_SUCCESS) - { - tout += dt; - } - - retval = IDAGetQuad(solver_, &tret, q_); - checkOutput(retval, "IDAGetQuad"); + tout += dt; } - - //Final copy out. No gaurentee last residual evaluation is final step. - model_->updateTime(tf, 0.0); - copyVec(yy_, model_->y()); - copyVec(yp_, model_->yp()); - return retval; - } + retval = IDAGetQuad(solver_, &tret, q_); + checkOutput(retval, "IDAGetQuad"); + } + // Final copy out. No gaurentee last residual evaluation is final step. + model_->updateTime(tf, 0.0); + copyVec(yy_, model_->y()); + copyVec(yp_, model_->yp()); + + return retval; + } template int Ida::deleteQuadrature() { - IDAQuadFree(solver_); - N_VDestroy(q_); + IDAQuadFree(solver_); + N_VDestroy(q_); - return 0; + return 0; } - template int Ida::configureAdjoint() { - // Allocate adjoint vector, derivatives and quadrature + // Allocate adjoint vector, derivatives and quadrature yyB_ = N_VNew_Serial(model_->size(), context_); - checkAllocation((void*) yyB_, "N_VNew_Serial"); + checkAllocation((void*) yyB_, "N_VNew_Serial"); - ypB_ = N_VClone(yyB_); - checkAllocation((void*) ypB_, "N_VClone"); + ypB_ = N_VClone(yyB_); + checkAllocation((void*) ypB_, "N_VClone"); - qB_ = N_VNew_Serial(model_->sizeParams(), context_); - checkAllocation((void*) qB_, "N_VNew_Serial"); + qB_ = N_VNew_Serial(model_->sizeParams(), context_); + checkAllocation((void*) qB_, "N_VNew_Serial"); - return 0; + return 0; } template int Ida::initializeAdjoint(IdxT steps) { - int retval = 0; + int retval = 0; - // Create adjoint workspace - retval = IDAAdjInit(solver_, steps, IDA_HERMITE); - checkOutput(retval, "IDAAdjInit"); + // Create adjoint workspace + retval = IDAAdjInit(solver_, steps, IDA_HERMITE); + checkOutput(retval, "IDAAdjInit"); - return retval; + return retval; } template int Ida::initializeBackwardSimulation(real_type tf) { - int retval = 0; - sunrealtype rel_tol; - sunrealtype abs_tol; - - model_->initializeAdjoint(); - - copyVec(model_->yB(), yyB_); - copyVec(model_->ypB(), ypB_); - N_VConst(0.0, qB_); + int retval = 0; + sunrealtype rel_tol; + sunrealtype abs_tol; - retval = IDACreateB(solver_, &backwardID_); - checkOutput(retval, "IDACreateB"); + model_->initializeAdjoint(); - // IDAInitB must be called after forward simulation run. - retval = IDAInitB(solver_, backwardID_, this->adjointResidual, tf, yyB_, ypB_); - checkOutput(retval, "IDAInitB"); + copyVec(model_->yB(), yyB_); + copyVec(model_->ypB(), ypB_); + N_VConst(0.0, qB_); - model_->setTolerances(rel_tol, abs_tol); - retval = IDASStolerancesB(solver_, backwardID_, rel_tol, abs_tol); - checkOutput(retval, "IDASStolerancesB"); + retval = IDACreateB(solver_, &backwardID_); + checkOutput(retval, "IDACreateB"); - retval = IDASetUserDataB(solver_, backwardID_, model_); - checkOutput(retval, "IDASetUserDataB"); + // IDAInitB must be called after forward simulation run. + retval = IDAInitB(solver_, backwardID_, this->adjointResidual, tf, yyB_, ypB_); + checkOutput(retval, "IDAInitB"); - /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumStepsB(solver_, backwardID_, 2000); - checkOutput(retval, "IDASetMaxNumSteps"); + model_->setTolerances(rel_tol, abs_tol); + retval = IDASStolerancesB(solver_, backwardID_, rel_tol, abs_tol); + checkOutput(retval, "IDASStolerancesB"); - // Set up linear solver - JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMatB_, "SUNDenseMatrix"); + retval = IDASetUserDataB(solver_, backwardID_, model_); + checkOutput(retval, "IDASetUserDataB"); - linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); - checkAllocation((void*) linearSolverB_, "SUNLinSol_Dense"); + /// \todo Need to set max number of steps based on user input! + retval = IDASetMaxNumStepsB(solver_, backwardID_, 2000); + checkOutput(retval, "IDASetMaxNumSteps"); - retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); - checkOutput(retval, "IDASetLinearSolverB"); + // Set up linear solver + JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void*) JacobianMatB_, "SUNDenseMatrix"); + linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); + checkAllocation((void*) linearSolverB_, "SUNLinSol_Dense"); - // Also reinitialize quadratures. - retval = IDAQuadInitB(solver_, backwardID_, this->adjointIntegrand, qB_); - checkOutput(retval, "IDAQuadInitB"); + retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); + checkOutput(retval, "IDASetLinearSolverB"); - //retval = IDAQuadSStolerancesB(solver_, backwardID_, rel_tol*1.1, abs_tol*1.1); - retval = IDAQuadSStolerancesB(solver_, backwardID_, rel_tol*0.1, abs_tol*0.1); - checkOutput(retval, "IDAQuadSStolerancesB"); + // Also reinitialize quadratures. + retval = IDAQuadInitB(solver_, backwardID_, this->adjointIntegrand, qB_); + checkOutput(retval, "IDAQuadInitB"); - // Include quadratures in error control - retval = IDASetQuadErrConB(solver_, backwardID_, SUNTRUE); - checkOutput(retval, "IDASetQuadErrConB"); + // retval = IDAQuadSStolerancesB(solver_, backwardID_, rel_tol*1.1, abs_tol*1.1); + retval = IDAQuadSStolerancesB(solver_, backwardID_, rel_tol * 0.1, abs_tol * 0.1); + checkOutput(retval, "IDAQuadSStolerancesB"); + // Include quadratures in error control + retval = IDASetQuadErrConB(solver_, backwardID_, SUNTRUE); + checkOutput(retval, "IDASetQuadErrConB"); - return retval; + return retval; } template int Ida::configureLinearSolverBackward() { - int retval = 0; + int retval = 0; - // Create Jacobian matrix - JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMatB_, "SUNDenseMatrix"); + // Create Jacobian matrix + JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void*) JacobianMatB_, "SUNDenseMatrix"); - // Create linear solver - linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); - checkAllocation((void*) linearSolverB_, "SUNLinSol_Dense"); + // Create linear solver + linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); + checkAllocation((void*) linearSolverB_, "SUNLinSol_Dense"); - // Attach linear solver to IDA - retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); - checkOutput(retval, "IDASetLinearSolverB"); + // Attach linear solver to IDA + retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); + checkOutput(retval, "IDASetLinearSolverB"); - return retval; + return retval; } template int Ida::runForwardSimulation(real_type tf, int nout) { - int retval = 0; - int ncheck; - real_type time; + int retval = 0; + int ncheck; + real_type time; - //std::cout << "Forward integration for adjoint analysis ... \n"; + // std::cout << "Forward integration for adjoint analysis ... \n"; - real_type dt = tf / static_cast(nout); - real_type tout = dt; - for(int i = 0; i < nout; ++i) + real_type dt = tf / static_cast(nout); + real_type tout = dt; + for (int i = 0; i < nout; ++i) + { + retval = IDASolveF(solver_, tout, &time, yy_, yp_, IDA_NORMAL, &ncheck); + checkOutput(retval, "IDASolveF"); + + if (retval == IDA_SUCCESS) { - retval = IDASolveF(solver_, tout, &time, yy_, yp_, IDA_NORMAL, &ncheck); - checkOutput(retval, "IDASolveF"); + tout += dt; + } - if (retval == IDA_SUCCESS) - { - tout += dt; - } + retval = IDAGetQuad(solver_, &time, q_); + checkOutput(retval, "IDASolve"); + } - retval = IDAGetQuad(solver_, &time, q_); - checkOutput(retval, "IDASolve"); - } - - //Final copy out. No gaurentee last residual evaluation is final step. - model_->updateTime(tf, 0.0); - copyVec(yy_, model_->y()); - copyVec(yp_, model_->yp()); + // Final copy out. No gaurentee last residual evaluation is final step. + model_->updateTime(tf, 0.0); + copyVec(yy_, model_->y()); + copyVec(yp_, model_->yp()); - return retval; + return retval; } template int Ida::runBackwardSimulation(real_type t_init) { - int retval = 0; - long int nstB; - real_type time; + int retval = 0; + long int nstB; + real_type time; - //std::cout << "Backward integration for adjoint analysis ... "; + // std::cout << "Backward integration for adjoint analysis ... "; - retval = IDASolveB(solver_, t_init, IDA_NORMAL); - checkOutput(retval, "IDASolveB"); + retval = IDASolveB(solver_, t_init, IDA_NORMAL); + checkOutput(retval, "IDASolveB"); - IDAGetNumSteps(IDAGetAdjIDABmem(solver_, backwardID_), &nstB); - //std::cout << "done ( nst = " << nstB << " )\n"; + IDAGetNumSteps(IDAGetAdjIDABmem(solver_, backwardID_), &nstB); + // std::cout << "done ( nst = " << nstB << " )\n"; - retval = IDAGetB(solver_, backwardID_, &time, yyB_, ypB_); - checkOutput(retval, "IDAGetB"); + retval = IDAGetB(solver_, backwardID_, &time, yyB_, ypB_); + checkOutput(retval, "IDAGetB"); - //Copy back into model - copyVec(yyB_, model_->yB()); - copyVec(ypB_, model_->ypB()); + // Copy back into model + copyVec(yyB_, model_->yB()); + copyVec(ypB_, model_->ypB()); - retval = IDAGetQuadB(solver_, backwardID_, &time, qB_); - checkOutput(retval, "IDAGetQuadB"); + retval = IDAGetQuadB(solver_, backwardID_, &time, qB_); + checkOutput(retval, "IDAGetQuadB"); - return retval; + return retval; } template int Ida::deleteAdjoint() { - IDAAdjFree(solver_); - return 0; + IDAAdjFree(solver_); + return 0; } template - int Ida::Residual(sunrealtype tres, N_Vector yy, N_Vector yp, N_Vector rr, void *user_data) + int Ida::Residual(sunrealtype tres, N_Vector yy, N_Vector yp, N_Vector rr, void* user_data) { - GridKit::Model::Evaluator* model = static_cast*>(user_data); + GridKit::Model::Evaluator* model = static_cast*>(user_data); - model->updateTime(tres, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); + model->updateTime(tres, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); - model->evaluateResidual(); - const std::vector& f = model->getResidual(); - copyVec(f, rr); + model->evaluateResidual(); + const std::vector& f = model->getResidual(); + copyVec(f, rr); - return 0; + return 0; } template - int Ida::Jac(sunrealtype t, sunrealtype cj, N_Vector yy, N_Vector yp, N_Vector resvec, SUNMatrix J, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) + int Ida::Jac(sunrealtype t, sunrealtype cj, N_Vector yy, N_Vector yp, N_Vector resvec, SUNMatrix J, void* user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) { - GridKit::Model::Evaluator* model = static_cast*>(user_data); + GridKit::Model::Evaluator* model = static_cast*>(user_data); + model->updateTime(t, cj); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); - model->updateTime(t, cj); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); + model->evaluateJacobian(); + COO_Matrix Jac = model->getJacobian(); - model->evaluateJacobian(); - COO_Matrix Jac = model->getJacobian(); - - //Get reference to the jacobian entries - std::tuple&, std::vector&, std::vector&> tpm = Jac.getEntries(); - const auto [r, c, val] = tpm; + // Get reference to the jacobian entries + std::tuple&, std::vector&, std::vector&> tpm = Jac.getEntries(); + const auto [r, c, val] = tpm; - //get the CSR row pointers from COO matrix - std::vector csrrowdata = Jac.getCSRRowData(); + // get the CSR row pointers from COO matrix + std::vector csrrowdata = Jac.getCSRRowData(); - SUNMatZero(J); + SUNMatZero(J); - //Set row pointers - sunindextype *rowptrs = SUNSparseMatrix_IndexPointers(J); - for (unsigned int i = 0; i < csrrowdata.size() ; i++) - { - rowptrs[i] = csrrowdata[i]; - } + // Set row pointers + sunindextype* rowptrs = SUNSparseMatrix_IndexPointers(J); + for (unsigned int i = 0; i < csrrowdata.size(); i++) + { + rowptrs[i] = csrrowdata[i]; + } - sunindextype *colvals = SUNSparseMatrix_IndexValues(J); - sunrealtype *data = SUNSparseMatrix_Data(J); - //Copy data from model jac to sundials - for (unsigned int i = 0; i < c.size(); i++ ) - { - colvals[i] = c[i]; - data[i] = val[i]; - } + sunindextype* colvals = SUNSparseMatrix_IndexValues(J); + sunrealtype* data = SUNSparseMatrix_Data(J); + // Copy data from model jac to sundials + for (unsigned int i = 0; i < c.size(); i++) + { + colvals[i] = c[i]; + data[i] = val[i]; + } - return 0; + return 0; } template - int Ida::Integrand(sunrealtype tt, N_Vector yy, N_Vector yp, N_Vector rhsQ, void *user_data) + int Ida::Integrand(sunrealtype tt, N_Vector yy, N_Vector yp, N_Vector rhsQ, void* user_data) { - GridKit::Model::Evaluator* model = static_cast*>(user_data); + GridKit::Model::Evaluator* model = static_cast*>(user_data); - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); - model->evaluateIntegrand(); - const std::vector& g = model->getIntegrand(); - copyVec(g, rhsQ); + model->evaluateIntegrand(); + const std::vector& g = model->getIntegrand(); + copyVec(g, rhsQ); - return 0; + return 0; } template - int Ida::adjointResidual(sunrealtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rrB, void *user_data) + int Ida::adjointResidual(sunrealtype 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); + GridKit::Model::Evaluator* model = static_cast*>(user_data); - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); - copyVec(yyB, model->yB()); - copyVec(ypB, model->ypB()); + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); + copyVec(yyB, model->yB()); + copyVec(ypB, model->ypB()); - model->evaluateAdjointResidual(); - const std::vector& fB = model->getAdjointResidual(); - copyVec(fB, rrB); + model->evaluateAdjointResidual(); + const std::vector& fB = model->getAdjointResidual(); + copyVec(fB, rrB); - return 0; + return 0; } - template - int Ida::adjointIntegrand(sunrealtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rhsQB, void *user_data) + int Ida::adjointIntegrand(sunrealtype 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); + GridKit::Model::Evaluator* model = static_cast*>(user_data); - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); - copyVec(yyB, model->yB()); - copyVec(ypB, model->ypB()); + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); + copyVec(yyB, model->yB()); + copyVec(ypB, model->ypB()); - model->evaluateAdjointIntegrand(); - const std::vector& gB = model->getAdjointIntegrand(); - copyVec(gB, rhsQB); + model->evaluateAdjointIntegrand(); + const std::vector& gB = model->getAdjointIntegrand(); + copyVec(gB, rhsQB); - return 0; + return 0; } - template - void Ida::copyVec(const N_Vector x, std::vector< ScalarT >& y) + void Ida::copyVec(const N_Vector x, std::vector& y) { - const ScalarT* xdata = NV_DATA_S(x); - for(unsigned int i = 0; i < y.size(); ++i) - { - y[i] = xdata[i]; - } + const ScalarT* xdata = NV_DATA_S(x); + for (unsigned int i = 0; i < y.size(); ++i) + { + y[i] = xdata[i]; + } } - template - void Ida::copyVec(const std::vector< ScalarT >& x, N_Vector y) + void Ida::copyVec(const std::vector& x, N_Vector y) { - ScalarT* ydata = NV_DATA_S(y); - for(unsigned int i = 0; i < x.size(); ++i) - { - ydata[i] = x[i]; - } + ScalarT* ydata = NV_DATA_S(y); + for (unsigned int i = 0; i < x.size(); ++i) + { + ydata[i] = x[i]; + } } template - void Ida::copyVec(const std::vector< bool >& x, N_Vector y) + void Ida::copyVec(const std::vector& x, N_Vector y) { - ScalarT* ydata = NV_DATA_S(y); - for(unsigned int i = 0; i < x.size(); ++i) - { - if (x[i]) - ydata[i] = 1.0; - else - ydata[i] = 0.0; - } + ScalarT* ydata = NV_DATA_S(y); + for (unsigned int i = 0; i < x.size(); ++i) + { + if (x[i]) + ydata[i] = 1.0; + else + ydata[i] = 0.0; + } } - template void Ida::printOutput(sunrealtype t) { - sunrealtype *yval = N_VGetArrayPointer_Serial(yy_); - sunrealtype *ypval = N_VGetArrayPointer_Serial(yp_); + sunrealtype* yval = N_VGetArrayPointer_Serial(yy_); + sunrealtype* ypval = N_VGetArrayPointer_Serial(yp_); - std::cout << std::setprecision(5) << std::setw(7) << t << " "; - for (IdxT i = 0; i < model_->size(); ++i) - { - std::cout << yval[i] << " "; - } - for (IdxT i = 0; i < model_->size(); ++i) - { - std::cout << ypval[i] << " "; - } - std::cout << "\n"; + std::cout << std::setprecision(5) << std::setw(7) << t << " "; + for (IdxT i = 0; i < model_->size(); ++i) + { + std::cout << yval[i] << " "; + } + for (IdxT i = 0; i < model_->size(); ++i) + { + std::cout << ypval[i] << " "; + } + std::cout << "\n"; } template void Ida::printSpecial(sunrealtype t, N_Vector y) { - sunrealtype *yval = N_VGetArrayPointer_Serial(y); - IdxT N = static_cast(N_VGetLength_Serial(y)); - std::cout << "{"; - std::cout << std::setprecision(5) << std::setw(7) << t; - for (IdxT i = 0; i < N; ++i) - { - std::cout << ", " << yval[i]; - } - std::cout << "},\n"; + sunrealtype* yval = N_VGetArrayPointer_Serial(y); + IdxT N = static_cast(N_VGetLength_Serial(y)); + std::cout << "{"; + std::cout << std::setprecision(5) << std::setw(7) << t; + for (IdxT i = 0; i < N; ++i) + { + std::cout << ", " << yval[i]; + } + std::cout << "},\n"; } template void Ida::printFinalStats() { - int retval = 0; - void* mem = solver_; - long int nst; - long int nre; - long int nje; - long int nni; - long int netf; - long int ncfn; - - retval = IDAGetNumSteps(mem, &nst); - checkOutput(retval, "IDAGetNumSteps"); - retval = IDAGetNumResEvals(mem, &nre); - checkOutput(retval, "IDAGetNumResEvals"); - retval = IDAGetNumJacEvals(mem, &nje); - checkOutput(retval, "IDAGetNumJacEvals"); - retval = IDAGetNumNonlinSolvIters(mem, &nni); - checkOutput(retval, "IDAGetNumNonlinSolvIters"); - retval = IDAGetNumErrTestFails(mem, &netf); - checkOutput(retval, "IDAGetNumErrTestFails"); - retval = IDAGetNumNonlinSolvConvFails(mem, &ncfn); - checkOutput(retval, "IDAGetNumNonlinSolvConvFails"); - - // std::cout << "\nFinal Run Statistics: \n\n"; - std::cout << "Number of steps = " << nst << "\n"; - std::cout << "Number of residual evaluations = " << nre << "\n"; - //std::cout << "Number of Jacobian evaluations = " << nje << "\n"; - std::cout << "Number of nonlinear iterations = " << nni << "\n"; - std::cout << "Number of error test failures = " << netf << "\n"; - std::cout << "Number of nonlinear conv. failures = " << ncfn << "\n"; + int retval = 0; + void* mem = solver_; + long int nst; + long int nre; + long int nje; + long int nni; + long int netf; + long int ncfn; + + retval = IDAGetNumSteps(mem, &nst); + checkOutput(retval, "IDAGetNumSteps"); + retval = IDAGetNumResEvals(mem, &nre); + checkOutput(retval, "IDAGetNumResEvals"); + retval = IDAGetNumJacEvals(mem, &nje); + checkOutput(retval, "IDAGetNumJacEvals"); + retval = IDAGetNumNonlinSolvIters(mem, &nni); + checkOutput(retval, "IDAGetNumNonlinSolvIters"); + retval = IDAGetNumErrTestFails(mem, &netf); + checkOutput(retval, "IDAGetNumErrTestFails"); + retval = IDAGetNumNonlinSolvConvFails(mem, &ncfn); + checkOutput(retval, "IDAGetNumNonlinSolvConvFails"); + + // std::cout << "\nFinal Run Statistics: \n\n"; + std::cout << "Number of steps = " << nst << "\n"; + std::cout << "Number of residual evaluations = " << nre << "\n"; + // std::cout << "Number of Jacobian evaluations = " << nje << "\n"; + std::cout << "Number of nonlinear iterations = " << nni << "\n"; + std::cout << "Number of error test failures = " << netf << "\n"; + std::cout << "Number of nonlinear conv. failures = " << ncfn << "\n"; } - template void Ida::checkAllocation(void* v, const char* functionName) { - if (v == NULL) - { - std::cerr << "\nERROR: Function " << functionName << " failed -- returned NULL pointer!\n\n"; - throw SundialsException(); - } + if (v == NULL) + { + std::cerr << "\nERROR: Function " << functionName << " failed -- returned NULL pointer!\n\n"; + throw SundialsException(); + } } template void Ida::checkOutput(int retval, const char* functionName) { - if (retval < 0) - { - std::cerr << "\nERROR: Function " << functionName << " failed with flag " << retval << "!\n\n"; - throw SundialsException(); - } + if (retval < 0) + { + std::cerr << "\nERROR: Function " << functionName << " failed with flag " << retval << "!\n\n"; + throw SundialsException(); + } } // Compiler will prevent building modules with data type incompatible with sunrealtype @@ -815,5 +800,5 @@ namespace Sundials template class Ida; template class Ida; -} // namespace Sundials + } // namespace Sundials } // namespace AnalysisManager diff --git a/src/Solver/Dynamic/Ida.hpp b/src/Solver/Dynamic/Ida.hpp index 272db453..9ed8b892 100644 --- a/src/Solver/Dynamic/Ida.hpp +++ b/src/Solver/Dynamic/Ida.hpp @@ -57,186 +57,188 @@ * */ - #ifndef _IDA_HPP_ #define _IDA_HPP_ -#include #include +#include + #include -#include /* access to sparse SUNMatrix */ -#include /* access to KLU linear solver */ -#include /* access to dense linear solver */ +#include /* access to dense linear solver */ +#include /* access to KLU linear solver */ +#include /* access to sparse SUNMatrix */ -#include "Model/Evaluator.hpp" #include "DynamicSolver.hpp" +#include "Model/Evaluator.hpp" namespace AnalysisManager { - namespace Sundials + namespace Sundials + { + template + class Ida : public DynamicSolver { - template - class Ida : public DynamicSolver - { - using DynamicSolver::model_; - - typedef typename GridKit::ScalarTraits::real_type real_type; - - public: - Ida(GridKit::Model::Evaluator* model); - ~Ida(); - - int configureSimulation(); - int configureLinearSolver(); - int getDefaultInitialCondition(); - int setIntegrationTime(real_type t_init, real_type t_final, int nout); - int initializeSimulation(real_type t0, bool findConsistent=false); - int runSimulation(real_type tf, int nout=1); - int deleteSimulation(); - - int configureQuadrature(); - int initializeQuadrature(); - int runSimulationQuadrature(real_type tf, int nout=1); - int deleteQuadrature(); - - int configureAdjoint(); - int configureLinearSolverBackward(); - int initializeAdjoint(IdxT steps = 100); - int initializeBackwardSimulation(real_type tf); - int runForwardSimulation(real_type tf, int nout=1); - int runBackwardSimulation(real_type t0); - int deleteAdjoint(); - - - int saveInitialCondition() - { - N_VScale(1.0, yy_, yy0_); - N_VScale(1.0, yp_, yp0_); - return 0; - } - - int getSavedInitialCondition() - { - N_VScale(1.0, yy0_, yy_); - N_VScale(1.0, yp0_, yp_); - return 0; - } - - real_type getInitialTime() - { - return t_init_; - } - - real_type getFinalTime() - { - return t_final_; - } - - int getNumberOutputTimes() - { - return nout_; - } - - const real_type* getIntegral() const - { - return NV_DATA_S(q_); - } - - real_type* getIntegral() - { - return NV_DATA_S(q_); - } - - const real_type* getAdjointIntegral() const - { - return NV_DATA_S(qB_); - } - - real_type* getAdjointIntegral() - { - return NV_DATA_S(qB_); - } - - void printOutput(sunrealtype t); - void printSpecial(sunrealtype t, N_Vector x); - void printFinalStats(); - - private: - static int Residual(sunrealtype t, - N_Vector yy, N_Vector yp, - N_Vector rr, void *user_data); - - static int Jac(sunrealtype t, sunrealtype 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(sunrealtype t, - N_Vector yy, N_Vector yp, - N_Vector rhsQ, void *user_data); - - static int adjointResidual(sunrealtype t, - N_Vector yy, N_Vector yp, - N_Vector yyB, N_Vector ypB, - N_Vector rrB, void *user_data); - - static int adjointIntegrand(sunrealtype t, - N_Vector yy, N_Vector yp, - N_Vector yyB, N_Vector ypB, - N_Vector rhsQB, void *user_data); - - private: - void* solver_; - SUNContext context_; - SUNMatrix JacobianMat_; - SUNMatrix JacobianMatB_; - SUNLinearSolver linearSolver_; - SUNLinearSolver linearSolverB_; - - real_type t_init_; - real_type t_final_; - int nout_; ///< Number of integration outputs - - N_Vector yy_; ///< Solution vector - N_Vector yp_; ///< Solution derivatives vector - N_Vector tag_; ///< Tags differential variables - N_Vector q_; ///< Integrand vector - - N_Vector yy0_; ///< Storage for initial values - N_Vector yp0_; ///< Storage for initial derivatives - - N_Vector yyB_; ///< Adjoint solution vector - N_Vector ypB_; ///< Adjoint solution derivatives vector - N_Vector qB_; ///< Backward integrand vector - - int backwardID_; - - private: - //static void copyMat(Model::Evaluator::Mat& J, SlsMat Jida); - static void copyVec(const N_Vector x, std::vector& y); - static void copyVec(const std::vector& x, N_Vector y); - static void copyVec(const std::vector& x, N_Vector y); - - //int check_flag(void *flagvalue, const char *funcname, int opt); - inline void checkAllocation(void* v, const char* functionName); - inline void checkOutput(int retval, const char* functionName); - - }; - - /// Simple exception to use within Ida class. - class SundialsException : public std::exception - { - virtual const char* what() const throw() - { - return "Method in Ida class failed!\n"; - } - }; - - - } // namespace Sundials + using DynamicSolver::model_; + + typedef typename GridKit::ScalarTraits::real_type real_type; + + public: + Ida(GridKit::Model::Evaluator* model); + ~Ida(); + + int configureSimulation(); + int configureLinearSolver(); + int getDefaultInitialCondition(); + int setIntegrationTime(real_type t_init, real_type t_final, int nout); + int initializeSimulation(real_type t0, bool findConsistent = false); + int runSimulation(real_type tf, int nout = 1); + int deleteSimulation(); + + int configureQuadrature(); + int initializeQuadrature(); + int runSimulationQuadrature(real_type tf, int nout = 1); + int deleteQuadrature(); + + int configureAdjoint(); + int configureLinearSolverBackward(); + int initializeAdjoint(IdxT steps = 100); + int initializeBackwardSimulation(real_type tf); + int runForwardSimulation(real_type tf, int nout = 1); + int runBackwardSimulation(real_type t0); + int deleteAdjoint(); + + int saveInitialCondition() + { + N_VScale(1.0, yy_, yy0_); + N_VScale(1.0, yp_, yp0_); + return 0; + } + + int getSavedInitialCondition() + { + N_VScale(1.0, yy0_, yy_); + N_VScale(1.0, yp0_, yp_); + return 0; + } + + real_type getInitialTime() + { + return t_init_; + } + + real_type getFinalTime() + { + return t_final_; + } + + int getNumberOutputTimes() + { + return nout_; + } + + const real_type* getIntegral() const + { + return NV_DATA_S(q_); + } + + real_type* getIntegral() + { + return NV_DATA_S(q_); + } + + const real_type* getAdjointIntegral() const + { + return NV_DATA_S(qB_); + } + + real_type* getAdjointIntegral() + { + return NV_DATA_S(qB_); + } + + void printOutput(sunrealtype t); + void printSpecial(sunrealtype t, N_Vector x); + void printFinalStats(); + + private: + static int Residual(sunrealtype t, + N_Vector yy, + N_Vector yp, + N_Vector rr, + void* user_data); + + static int Jac(sunrealtype t, sunrealtype 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(sunrealtype t, + N_Vector yy, + N_Vector yp, + N_Vector rhsQ, + void* user_data); + + static int adjointResidual(sunrealtype t, + N_Vector yy, + N_Vector yp, + N_Vector yyB, + N_Vector ypB, + N_Vector rrB, + void* user_data); + + static int adjointIntegrand(sunrealtype t, + N_Vector yy, + N_Vector yp, + N_Vector yyB, + N_Vector ypB, + N_Vector rhsQB, + void* user_data); + + private: + void* solver_; + SUNContext context_; + SUNMatrix JacobianMat_; + SUNMatrix JacobianMatB_; + SUNLinearSolver linearSolver_; + SUNLinearSolver linearSolverB_; + + real_type t_init_; + real_type t_final_; + int nout_; ///< Number of integration outputs + + N_Vector yy_; ///< Solution vector + N_Vector yp_; ///< Solution derivatives vector + N_Vector tag_; ///< Tags differential variables + N_Vector q_; ///< Integrand vector + + N_Vector yy0_; ///< Storage for initial values + N_Vector yp0_; ///< Storage for initial derivatives + + N_Vector yyB_; ///< Adjoint solution vector + N_Vector ypB_; ///< Adjoint solution derivatives vector + N_Vector qB_; ///< Backward integrand vector + + int backwardID_; + + private: + // static void copyMat(Model::Evaluator::Mat& J, SlsMat Jida); + static void copyVec(const N_Vector x, std::vector& y); + static void copyVec(const std::vector& x, N_Vector y); + static void copyVec(const std::vector& x, N_Vector y); + + // int check_flag(void *flagvalue, const char *funcname, int opt); + inline void checkAllocation(void* v, const char* functionName); + inline void checkOutput(int retval, const char* functionName); + }; + + /// Simple exception to use within Ida class. + class SundialsException : public std::exception + { + virtual const char* what() const throw() + { + return "Method in Ida class failed!\n"; + } + }; + } // namespace Sundials } // namespace AnalysisManager - #endif // _IDA_HPP_ diff --git a/src/Solver/Optimization/DynamicConstraint.cpp b/src/Solver/Optimization/DynamicConstraint.cpp index bdec5001..e9199a15 100644 --- a/src/Solver/Optimization/DynamicConstraint.cpp +++ b/src/Solver/Optimization/DynamicConstraint.cpp @@ -57,182 +57,169 @@ * */ - -#include -#include - #include "DynamicConstraint.hpp" -namespace AnalysisManager { -namespace IpoptInterface { - -template -DynamicConstraint::DynamicConstraint(Sundials::Ida* integrator) - : OptimizationSolver(integrator), - t_init_(integrator_->getInitialTime()), - t_final_(integrator_->getFinalTime()), - nout_(integrator_->getNumberOutputTimes()) -{ - model_ = integrator_->getModel(); -} - -template -DynamicConstraint::~DynamicConstraint() -{ -} - +#include +#include -template -bool DynamicConstraint::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, - Index& nnz_h_lag, IndexStyleEnum& index_style) +namespace AnalysisManager { - // This code handles one objective function - assert(model_->size_quad() == 1); + namespace IpoptInterface + { + + template + DynamicConstraint::DynamicConstraint(Sundials::Ida* integrator) + : OptimizationSolver(integrator), + t_init_(integrator_->getInitialTime()), + t_final_(integrator_->getFinalTime()), + nout_(integrator_->getNumberOutputTimes()) + { + model_ = integrator_->getModel(); + } - // Number of parameters is size of the system plus 1 fictitious parameter - // to store the objective value. - n = model_->sizeParams() + 1; + template + DynamicConstraint::~DynamicConstraint() + { + } - // There is one constraint - m = 1; + template + 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_->size_quad() == 1); - // Jacobian is a dense row matrix of length n+1. - nnz_jac_g = model_->sizeParams() + 1; + // Number of parameters is size of the system plus 1 fictitious parameter + // to store the objective value. + n = model_->sizeParams() + 1; - // Using numerical Hessian. - nnz_h_lag = 0; + // There is one constraint + m = 1; - // Use the C index style (0-based) for row/column entries - index_style = C_STYLE; + // Jacobian is a dense row matrix of length n+1. + nnz_jac_g = model_->sizeParams() + 1; - return true; -} + // Using numerical Hessian. + nnz_h_lag = 0; + // Use the C index style (0-based) for row/column entries + index_style = C_STYLE; -template -bool DynamicConstraint::get_bounds_info(Index n, Number* x_l, Number* x_u, - Index m, Number* g_l, Number* g_u) -{ - // Check if sizes are set correctly - assert(n == (Index) (model_->sizeParams() + 1)); - assert(m == 1); + return true; + } - // Get boundaries for the optimization parameters - for(IdxT i = 0; i < model_->sizeParams(); ++i) + template + bool DynamicConstraint::get_bounds_info(Index n, Number* x_l, Number* x_u, Index m, Number* g_l, Number* g_u) { + // Check if sizes are set correctly + assert(n == (Index) (model_->sizeParams() + 1)); + assert(m == 1); + + // Get boundaries for the optimization parameters + for (IdxT i = 0; i < model_->sizeParams(); ++i) + { x_l[i] = model_->param_lo()[i]; x_u[i] = model_->param_up()[i]; - } - - // No boundaries for fictitious parameter x[n] - x_l[model_->sizeParams()] = -1e20; - x_u[model_->sizeParams()] = +1e20; + } - // Set constraint g[0] to be equality constraint g[0] = 0 - g_l[0] = 0.0; - g_u[0] = 0.0; + // No boundaries for fictitious parameter x[n] + x_l[model_->sizeParams()] = -1e20; + x_u[model_->sizeParams()] = +1e20; - return true; -} + // Set constraint g[0] to be equality constraint g[0] = 0 + g_l[0] = 0.0; + g_u[0] = 0.0; + return true; + } -template -bool DynamicConstraint::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) -{ - // Only initial values for x provided. - assert(init_x == true); - assert(init_z == false); - assert(init_lambda == false); + template + bool DynamicConstraint::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) + { + // Only initial values for x provided. + assert(init_x == true); + assert(init_z == false); + assert(init_lambda == false); - // Initialize optimization parameters x - for(IdxT i = 0; i < model_->sizeParams(); ++i) + // Initialize optimization parameters x + for (IdxT i = 0; i < model_->sizeParams(); ++i) x[i] = model_->param()[i]; - // Initialize fictitious parameter x[n-1] to zero - x[model_->sizeParams()] = 0.0; - - return true; -} - + // Initialize fictitious parameter x[n-1] to zero + x[model_->sizeParams()] = 0.0; -template -bool DynamicConstraint::eval_f(Index n, const Number* x, bool new_x, Number& obj_value) -{ - // Set objective to fictitious optimization parameter x[n-1] - obj_value = x[model_->sizeParams()]; + return true; + } - return true; -} + template + bool DynamicConstraint::eval_f(Index n, const Number* x, bool new_x, Number& obj_value) + { + // Set objective to fictitious optimization parameter x[n-1] + obj_value = x[model_->sizeParams()]; + return true; + } -template -bool DynamicConstraint::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f) -{ - // Objective function equals to the fictitious parameter x[n-1]. - // Gradient, then assumes the simple form: - for(IdxT i = 0; i < model_->sizeParams(); ++i) + template + bool DynamicConstraint::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f) + { + // Objective function equals to the fictitious parameter x[n-1]. + // Gradient, then assumes the simple form: + for (IdxT i = 0; i < model_->sizeParams(); ++i) grad_f[i] = 0.0; - grad_f[model_->sizeParams()] = 1.0; - - return true; -} + grad_f[model_->sizeParams()] = 1.0; - -template -bool DynamicConstraint::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g) -{ - // Update optimization parameters - for(IdxT i = 0; i < model_->sizeParams(); ++i) - { - model_->param()[i] = x[i]; - //std::cout << "x[" << i << "] = " << x[i] << "\n"; + return true; } - // Evaluate objective function - integrator_->getSavedInitialCondition(); - integrator_->initializeSimulation(t_init_); - integrator_->initializeQuadrature(); - - int status = 0; - status = integrator_->runSimulationQuadrature(t_final_, nout_); - if (status) + template + bool DynamicConstraint::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g) { + // Update optimization parameters + for (IdxT i = 0; i < model_->sizeParams(); ++i) + { + model_->param()[i] = x[i]; + // std::cout << "x[" << i << "] = " << x[i] << "\n"; + } + + // Evaluate objective function + integrator_->getSavedInitialCondition(); + integrator_->initializeSimulation(t_init_); + integrator_->initializeQuadrature(); + + int status = 0; + status = integrator_->runSimulationQuadrature(t_final_, nout_); + if (status) + { std::cerr << "Integration failed when using Pm = " << x[0] << "\n"; return false; - } - - // For now assumes only one forward integrand and multiple optimization parameters. - g[0] = (integrator_->getIntegral())[0] - x[model_->sizeParams()]; - //std::cout << "constraint:" << g[0] << std::endl; - return true; -} + } + // For now assumes only one forward integrand and multiple optimization parameters. + g[0] = (integrator_->getIntegral())[0] - x[model_->sizeParams()]; + // std::cout << "constraint:" << g[0] << std::endl; + return true; + } -template -bool DynamicConstraint::eval_jac_g(Index n, const Number* x, bool new_x, - Index m, Index nele_jac, Index* iRow, Index *jCol, - Number* values) -{ - // Set Jacobian sparsity pattern ... - if(!values) + template + bool DynamicConstraint::eval_jac_g(Index n, const Number* x, bool new_x, Index m, Index nele_jac, Index* iRow, Index* jCol, Number* values) { - for(IdxT i = 0; i < model_->sizeParams(); ++i) + // Set Jacobian sparsity pattern ... + if (!values) + { + for (IdxT i = 0; i < model_->sizeParams(); ++i) { - iRow[i] = 0; - jCol[i] = i; + iRow[i] = 0; + jCol[i] = i; } iRow[model_->sizeParams()] = 0; jCol[model_->sizeParams()] = model_->sizeParams(); - } - // ... or compute Jacobian derivatives - else - { + } + // ... or compute Jacobian derivatives + else + { // Update optimization parameters - for(IdxT i = 0; i < model_->sizeParams(); ++i) - model_->param()[i] = x[i]; + for (IdxT i = 0; i < model_->sizeParams(); ++i) + model_->param()[i] = x[i]; // evaluate the gradient of the objective function grad_{x} f(x) // This is creating and deleting adjoint system for each iteration! @@ -244,11 +231,11 @@ bool DynamicConstraint::eval_jac_g(Index n, const Number* x, bool integrator_->initializeQuadrature(); int status = 0; - status = integrator_->runForwardSimulation(t_final_, nout_); + status = integrator_->runForwardSimulation(t_final_, nout_); if (status) { - std::cerr << "Forward integration for adjoint solution failed when using Pm = " << x[0] << "\n"; - return false; + std::cerr << "Forward integration for adjoint solution failed when using Pm = " << x[0] << "\n"; + return false; } integrator_->initializeBackwardSimulation(t_final_); @@ -256,49 +243,45 @@ bool DynamicConstraint::eval_jac_g(Index n, const Number* x, bool status = integrator_->runBackwardSimulation(t_init_); if (status) { - std::cerr << "Backward integration for adjoint solution failed when using Pm = " << x[0] << "\n"; - return false; + std::cerr << "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(IdxT i = 0; i < model_->sizeParams(); ++i) + for (IdxT i = 0; i < model_->sizeParams(); ++i) { - values[i] = -((integrator_->getAdjointIntegral())[i]); + values[i] = -((integrator_->getAdjointIntegral())[i]); } values[model_->sizeParams()] = -1.0; integrator_->deleteAdjoint(); + } + return true; } - return true; -} - - -template -bool DynamicConstraint::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) -{ - return true; -} - - -template -void DynamicConstraint::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) -{ - -} - + template + bool DynamicConstraint::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) + { + return true; + } + template + void DynamicConstraint::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) + { + } -template class DynamicConstraint; -template class DynamicConstraint; + template class DynamicConstraint; + template class DynamicConstraint; -} // namespace IpoptInterface + } // namespace IpoptInterface } // namespace AnalysisManager diff --git a/src/Solver/Optimization/DynamicConstraint.hpp b/src/Solver/Optimization/DynamicConstraint.hpp index 234ebcfb..e630793f 100644 --- a/src/Solver/Optimization/DynamicConstraint.hpp +++ b/src/Solver/Optimization/DynamicConstraint.hpp @@ -57,97 +57,93 @@ * */ - - #ifndef _IPOPT_DYNAMIC_CONSTRAINT_HPP_ #define _IPOPT_DYNAMIC_CONSTRAINT_HPP_ -#include #include "OptimizationSolver.hpp" +#include -namespace AnalysisManager { - - namespace IpoptInterface { - - /** - * Implementation of Ipopt's pure virtual TNLP class. - * - * TNLP defines Ipopt's interface to the model. This is in fact - * the model evaluator interface to Ipopt. In this case however, - * the model evaluator calls dynamic solver to compute the objective - * and the gradient. - * - * \note This clas is based on Cosmin's reformulation of the dynamic - * constrained optimization problem. For now it is hard-wired to - * 1-parameter optimization problems. - * - */ - template - class DynamicConstraint : public Ipopt::TNLP, public OptimizationSolver - { - using OptimizationSolver::integrator_; - using OptimizationSolver::model_; - - typedef typename GridKit::ScalarTraits::real_type real_type; - - typedef Ipopt::Index Index; - typedef Ipopt::Number Number; - typedef Ipopt::SolverReturn SolverReturn; - typedef Ipopt::IpoptCalculatedQuantities IpoptCalculatedQuantities; - typedef Ipopt::IpoptData IpoptData; - - public: - DynamicConstraint(Sundials::Ida* integrator); - 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); - - /// Returns problem bounds - 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); - - /// Evaluate objective - 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); - - /// Evaluate constraint residuals (not used here) - 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); - - /// 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); - - /// 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); - private: - real_type t_init_; - real_type t_final_; - int nout_; - }; - - } // namespace IpoptInterface +namespace AnalysisManager +{ + + namespace IpoptInterface + { + + /** + * Implementation of Ipopt's pure virtual TNLP class. + * + * TNLP defines Ipopt's interface to the model. This is in fact + * the model evaluator interface to Ipopt. In this case however, + * the model evaluator calls dynamic solver to compute the objective + * and the gradient. + * + * \note This clas is based on Cosmin's reformulation of the dynamic + * constrained optimization problem. For now it is hard-wired to + * 1-parameter optimization problems. + * + */ + template + class DynamicConstraint : public Ipopt::TNLP, public OptimizationSolver + { + using OptimizationSolver::integrator_; + using OptimizationSolver::model_; + + typedef typename GridKit::ScalarTraits::real_type real_type; + + typedef Ipopt::Index Index; + typedef Ipopt::Number Number; + typedef Ipopt::SolverReturn SolverReturn; + typedef Ipopt::IpoptCalculatedQuantities IpoptCalculatedQuantities; + typedef Ipopt::IpoptData IpoptData; + + public: + DynamicConstraint(Sundials::Ida* integrator); + 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); + + /// Returns problem bounds + 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); + + /// Evaluate objective + 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); + + /// Evaluate constraint residuals (not used here) + 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); + + /// 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); + + /// 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); + + private: + real_type t_init_; + real_type t_final_; + int nout_; + }; + + } // namespace IpoptInterface } // namespace AnalysisManager #endif // _IPOPT_DYNAMIC_CONSTRAINT_HPP_ diff --git a/src/Solver/Optimization/DynamicObjective.cpp b/src/Solver/Optimization/DynamicObjective.cpp index 6898354c..15bfb628 100644 --- a/src/Solver/Optimization/DynamicObjective.cpp +++ b/src/Solver/Optimization/DynamicObjective.cpp @@ -57,188 +57,171 @@ * */ - -#include -#include - #include "DynamicObjective.hpp" -namespace AnalysisManager { -namespace IpoptInterface { - -template -DynamicObjective::DynamicObjective(Sundials::Ida* integrator) - : OptimizationSolver(integrator), - t_init_(integrator_->getInitialTime()), - t_final_(integrator_->getFinalTime()), - nout_(integrator_->getNumberOutputTimes()) -{ - model_ = integrator_->getModel(); -} +#include +#include -template -DynamicObjective::~DynamicObjective() +namespace AnalysisManager { -} - + namespace IpoptInterface + { + + template + DynamicObjective::DynamicObjective(Sundials::Ida* integrator) + : OptimizationSolver(integrator), + t_init_(integrator_->getInitialTime()), + t_final_(integrator_->getFinalTime()), + nout_(integrator_->getNumberOutputTimes()) + { + model_ = integrator_->getModel(); + } -template -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_->size_quad() == 1); - - // Number of optimization variables. - n = model_->sizeParams(); + template + DynamicObjective::~DynamicObjective() + { + } - // There are no constraints - m = 0; + template + 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_->size_quad() == 1); - // No constraints, empty Jacobian. This is only temporary. - nnz_jac_g = 0; + // Number of optimization variables. + n = model_->sizeParams(); - // Using numerical Hessian. - nnz_h_lag = 0; + // There are no constraints + m = 0; - // Use the C index style (0-based) for row/column entries - index_style = C_STYLE; + // No constraints, empty Jacobian. This is only temporary. + nnz_jac_g = 0; - return true; -} + // Using numerical Hessian. + nnz_h_lag = 0; + // Use the C index style (0-based) for row/column entries + index_style = C_STYLE; -template -bool DynamicObjective::get_bounds_info(Index n, Number* x_l, Number* x_u, - Index m, Number* g_l, Number* g_u) -{ - // Check if sizes are set correctly - assert(n == (Index) model_->sizeParams()); - assert(m == 0); + return true; + } - // Get boundaries for the optimization parameters - for(IdxT i = 0; i < model_->sizeParams(); ++i) + template + bool DynamicObjective::get_bounds_info(Index n, Number* x_l, Number* x_u, Index m, Number* g_l, Number* g_u) { + // Check if sizes are set correctly + assert(n == (Index) model_->sizeParams()); + assert(m == 0); + + // Get boundaries for the optimization parameters + for (IdxT i = 0; i < model_->sizeParams(); ++i) + { x_l[i] = model_->param_lo()[i]; x_u[i] = model_->param_up()[i]; - } - - return true; -} + } + return true; + } -template -bool DynamicObjective::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) -{ - // Only initial values for x provided. - assert(init_x == true); - assert(init_z == false); - assert(init_lambda == false); + template + bool DynamicObjective::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) + { + // Only initial values for x provided. + assert(init_x == true); + assert(init_z == false); + assert(init_lambda == false); - // Initialize optimization parameters x - for(IdxT i = 0; i < model_->sizeParams(); ++i) + // Initialize optimization parameters x + for (IdxT i = 0; i < model_->sizeParams(); ++i) x[i] = model_->param()[i]; - return true; -} - + return true; + } -template -bool DynamicObjective::eval_f(Index n, const Number* x, bool new_x, Number& obj_value) -{ - // Update optimization parameters - for(IdxT i = 0; i < model_->sizeParams(); ++i) + template + bool DynamicObjective::eval_f(Index n, const Number* x, bool new_x, Number& obj_value) + { + // Update optimization parameters + for (IdxT i = 0; i < model_->sizeParams(); ++i) model_->param()[i] = x[i]; - // Evaluate objective function - integrator_->getSavedInitialCondition(); - integrator_->initializeSimulation(t_init_); - integrator_->initializeQuadrature(); - integrator_->runSimulationQuadrature(t_final_, nout_); - - // Assuming objective function is given as the integral (quadrature) 0 - obj_value = (integrator_->getIntegral())[0]; + // Evaluate objective function + integrator_->getSavedInitialCondition(); + integrator_->initializeSimulation(t_init_); + integrator_->initializeQuadrature(); + integrator_->runSimulationQuadrature(t_final_, nout_); - return true; -} + // Assuming objective function is given as the integral (quadrature) 0 + obj_value = (integrator_->getIntegral())[0]; + return true; + } -template -bool DynamicObjective::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f) -{ - assert(model_->sizeParams() == static_cast(n)); - // Update optimization parameters - for(IdxT i = 0; i < model_->sizeParams(); ++i) + template + bool DynamicObjective::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f) + { + assert(model_->sizeParams() == static_cast(n)); + // Update optimization parameters + for (IdxT i = 0; i < model_->sizeParams(); ++i) model_->param()[i] = x[i]; - // evaluate the gradient of the objective function grad_{x} f(x) - // This is creating and deleting adjoint system for each iteration! - // Currently there is no more efficient solution. - integrator_->initializeAdjoint(); + // evaluate the gradient of the objective function grad_{x} f(x) + // This is creating and deleting adjoint system for each iteration! + // Currently there is no more efficient solution. + integrator_->initializeAdjoint(); - integrator_->getSavedInitialCondition(); - integrator_->initializeSimulation(t_init_); - integrator_->initializeQuadrature(); - integrator_->runForwardSimulation(t_final_, nout_); + integrator_->getSavedInitialCondition(); + integrator_->initializeSimulation(t_init_); + integrator_->initializeQuadrature(); + integrator_->runForwardSimulation(t_final_, nout_); - integrator_->initializeBackwardSimulation(t_final_); - integrator_->runBackwardSimulation(t_init_); + integrator_->initializeBackwardSimulation(t_final_); + integrator_->runBackwardSimulation(t_init_); - // For now assumes only one forward integrand and multiple optimization parameters. - for(IdxT i = 0; i < model_->sizeParams(); ++i) + // 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]); - integrator_->deleteAdjoint(); - - return true; -} - - -template -bool DynamicObjective::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g) -{ - return true; -} - - -template -bool DynamicObjective::eval_jac_g(Index n, const Number* x, bool new_x, - Index m, Index nele_jac, Index* iRow, Index *jCol, - Number* values) -{ - return true; -} - + integrator_->deleteAdjoint(); -template -bool DynamicObjective::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) -{ - return true; -} - - -template -void DynamicObjective::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) -{ + return true; + } -} + template + bool DynamicObjective::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g) + { + return true; + } + template + bool DynamicObjective::eval_jac_g(Index n, const Number* x, bool new_x, Index m, Index nele_jac, Index* iRow, Index* jCol, Number* values) + { + return true; + } + template + bool DynamicObjective::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) + { + return true; + } + template + void DynamicObjective::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) + { + } -template class DynamicObjective; -template class DynamicObjective; + template class DynamicObjective; + template class DynamicObjective; -} // namespace IpoptInterface + } // namespace IpoptInterface } // namespace AnalysisManager diff --git a/src/Solver/Optimization/DynamicObjective.hpp b/src/Solver/Optimization/DynamicObjective.hpp index d2999730..09cde82f 100644 --- a/src/Solver/Optimization/DynamicObjective.hpp +++ b/src/Solver/Optimization/DynamicObjective.hpp @@ -57,93 +57,89 @@ * */ - - #ifndef _IPOPT_DYNAMIC_OBJECTIVE_HPP_ #define _IPOPT_DYNAMIC_OBJECTIVE_HPP_ -#include #include "OptimizationSolver.hpp" +#include -namespace AnalysisManager { - - namespace IpoptInterface { - - /** - * Implementation of Ipopt's pure virtual TNLP class. - * - * TNLP defines Ipopt's interface to the model. This is in fact - * the model evaluator interface to Ipopt. In this case however, - * the model evaluator calls dynamic solver to compute the objective - * and the gradient. - * - */ - template - class DynamicObjective : public Ipopt::TNLP, public OptimizationSolver - { - using OptimizationSolver::integrator_; - using OptimizationSolver::model_; - - typedef typename GridKit::ScalarTraits::real_type real_type; - - typedef Ipopt::Index Index; - typedef Ipopt::Number Number; - typedef Ipopt::SolverReturn SolverReturn; - typedef Ipopt::IpoptCalculatedQuantities IpoptCalculatedQuantities; - typedef Ipopt::IpoptData IpoptData; - - public: - DynamicObjective(Sundials::Ida* integrator); - 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); - - /// Returns problem bounds - 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); - - /// Evaluate objective - 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); - - /// Evaluate constraint residuals (not used here) - 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); - - /// 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); - - /// 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); - private: - real_type t_init_; - real_type t_final_; - int nout_; - }; - - } // namespace IpoptInterface +namespace AnalysisManager +{ + + namespace IpoptInterface + { + + /** + * Implementation of Ipopt's pure virtual TNLP class. + * + * TNLP defines Ipopt's interface to the model. This is in fact + * the model evaluator interface to Ipopt. In this case however, + * the model evaluator calls dynamic solver to compute the objective + * and the gradient. + * + */ + template + class DynamicObjective : public Ipopt::TNLP, public OptimizationSolver + { + using OptimizationSolver::integrator_; + using OptimizationSolver::model_; + + typedef typename GridKit::ScalarTraits::real_type real_type; + + typedef Ipopt::Index Index; + typedef Ipopt::Number Number; + typedef Ipopt::SolverReturn SolverReturn; + typedef Ipopt::IpoptCalculatedQuantities IpoptCalculatedQuantities; + typedef Ipopt::IpoptData IpoptData; + + public: + DynamicObjective(Sundials::Ida* integrator); + 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); + + /// Returns problem bounds + 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); + + /// Evaluate objective + 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); + + /// Evaluate constraint residuals (not used here) + 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); + + /// 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); + + /// 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); + + private: + real_type t_init_; + real_type t_final_; + int nout_; + }; + + } // namespace IpoptInterface } // namespace AnalysisManager #endif // _IPOPT_DYNAMIC_OBJECTIVE_HPP_ diff --git a/src/Solver/Optimization/OptimizationSolver.hpp b/src/Solver/Optimization/OptimizationSolver.hpp index d89657d4..b0cc2390 100644 --- a/src/Solver/Optimization/OptimizationSolver.hpp +++ b/src/Solver/Optimization/OptimizationSolver.hpp @@ -65,29 +65,31 @@ namespace AnalysisManager { - template - class DynamicSolver; + template + class DynamicSolver; - template - class OptimizationSolver + template + class OptimizationSolver + { + public: + OptimizationSolver() { - public: - OptimizationSolver() - { - } + } - OptimizationSolver(Sundials::Ida* integrator) : integrator_(integrator) - { - } - - virtual ~OptimizationSolver(){} + OptimizationSolver(Sundials::Ida* integrator) + : integrator_(integrator) + { + } - protected: - GridKit::Model::Evaluator* model_; - Sundials::Ida* integrator_; - }; + virtual ~OptimizationSolver() + { + } -} + protected: + GridKit::Model::Evaluator* model_; + Sundials::Ida* integrator_; + }; +} // namespace AnalysisManager #endif // _OPTIMIZATION_SOLVER_HPP_ diff --git a/src/Solver/SteadyState/Kinsol.cpp b/src/Solver/SteadyState/Kinsol.cpp index 0b14226f..f6556753 100644 --- a/src/Solver/SteadyState/Kinsol.cpp +++ b/src/Solver/SteadyState/Kinsol.cpp @@ -60,283 +60,280 @@ /** * @file Kinsol.cpp * @author Slaven Peles - * + * * Contains definition of interface to KINSOL nonlinear solver from * SUNDIALS library. - * + * */ -#include +#include "Kinsol.hpp" + #include +#include #include // access to KINSOL func., consts. -#include // access to serial N_Vector -#include // access to dense SUNMatrix +#include // access to serial N_Vector #include // access to dense SUNLinearSolver +#include // access to dense SUNMatrix #include "Model/Evaluator.hpp" -#include "Kinsol.hpp" - namespace AnalysisManager { -namespace Sundials -{ + namespace Sundials + { template - Kinsol::Kinsol(GridKit::Model::Evaluator* model) - : SteadyStateSolver(model) + Kinsol::Kinsol(GridKit::Model::Evaluator* model) + : SteadyStateSolver(model) { - int retval = 0; + int retval = 0; - // Create the SUNDIALS context that all SUNDIALS objects require - retval = SUNContext_Create(SUN_COMM_NULL, &context_); - checkOutput(retval, "SUNContext"); + // Create the SUNDIALS context that all SUNDIALS objects require + retval = SUNContext_Create(SUN_COMM_NULL, &context_); + checkOutput(retval, "SUNContext"); - solver_ = KINCreate(context_); - tag_ = NULL; + solver_ = KINCreate(context_); + tag_ = NULL; } template Kinsol::~Kinsol() { - SUNContext_Free(&context_); - KINFree(&solver_); + SUNContext_Free(&context_); + KINFree(&solver_); + + N_VDestroy_Serial(this->yy_); + N_VDestroy_Serial(this->yy0_); + N_VDestroy_Serial(this->scale_); - N_VDestroy_Serial(this->yy_); - N_VDestroy_Serial(this->yy0_); - N_VDestroy_Serial(this->scale_); + SUNMatDestroy(this->JacobianMat_); + SUNLinSolFree_Dense(this->linearSolver_); - SUNMatDestroy(this->JacobianMat_); - SUNLinSolFree_Dense(this->linearSolver_); - - solver_ = 0; + solver_ = 0; } template int Kinsol::configureSimulation() { - int retval = 0; + int retval = 0; - // Allocate solution vectors - yy_ = N_VNew_Serial(model_->size(), context_); - checkAllocation((void*) yy_, "N_VNew_Serial"); + // Allocate solution vectors + yy_ = N_VNew_Serial(model_->size(), context_); + checkAllocation((void*) yy_, "N_VNew_Serial"); - // Allocate scaling vector - scale_ = N_VClone(yy_); - checkAllocation((void*) scale_, "N_VClone"); + // Allocate scaling vector + scale_ = N_VClone(yy_); + checkAllocation((void*) scale_, "N_VClone"); - // Create vectors to store restart initial condition - yy0_ = N_VClone(yy_); - checkAllocation((void*) yy0_, "N_VClone"); + // Create vectors to store restart initial condition + yy0_ = N_VClone(yy_); + checkAllocation((void*) yy0_, "N_VClone"); - // Allocate and initialize KIN workspace - retval = KINInit(solver_, this->Residual, yy_); - checkOutput(retval, "KINInit"); + // Allocate and initialize KIN workspace + retval = KINInit(solver_, this->Residual, yy_); + checkOutput(retval, "KINInit"); - // Set pointer to model data - retval = KINSetUserData(solver_, model_); - checkOutput(retval, "KINSetUserData"); + // Set pointer to model data + retval = KINSetUserData(solver_, model_); + checkOutput(retval, "KINSetUserData"); - // Set tolerances - sunrealtype fnormtol; ///< Residual tolerance - sunrealtype scsteptol; ///< Scaled step tolerance + // Set tolerances + sunrealtype fnormtol; ///< Residual tolerance + sunrealtype scsteptol; ///< Scaled step tolerance - model_->setTolerances(fnormtol, scsteptol); ///< \todo Function name should be "getTolerances"! - retval = KINSetFuncNormTol(solver_, fnormtol); - checkOutput(retval, "KINSetFuncNormTol"); + model_->setTolerances(fnormtol, scsteptol); ///< \todo Function name should be "getTolerances"! + retval = KINSetFuncNormTol(solver_, fnormtol); + checkOutput(retval, "KINSetFuncNormTol"); - retval = KINSetScaledStepTol(solver_, scsteptol); - checkOutput(retval, "KINSetScaledStepTol"); + retval = KINSetScaledStepTol(solver_, scsteptol); + checkOutput(retval, "KINSetScaledStepTol"); - // Set up linear solver - JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); + // Set up linear solver + JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); - linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); - checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); + linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); + checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); - retval = KINSetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "KINSetLinearSolver"); + retval = KINSetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "KINSetLinearSolver"); - return retval; + return retval; } template int Kinsol::configureLinearSolver() { - int retval = 0; + int retval = 0; - // Set up linear solver - JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); + // Set up linear solver + JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); - linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); - checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); + linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); + checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); - retval = KINSetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "KINSetLinearSolver"); + retval = KINSetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "KINSetLinearSolver"); - return retval; + return retval; } template int Kinsol::getDefaultInitialCondition() { - model_->initialize(); + model_->initialize(); - copyVec(model_->y(), yy_); + copyVec(model_->y(), yy_); - return 0; + return 0; } template int Kinsol::runSimulation() { - int retval = 0; - N_VConst(1.0, scale_); - retval = KINSol(solver_, yy_, KIN_LINESEARCH, scale_, scale_); - checkOutput(retval, "KINSol"); - //printOutput(tout); - //std::cout << "\n"; - return retval; + int retval = 0; + N_VConst(1.0, scale_); + retval = KINSol(solver_, yy_, KIN_LINESEARCH, scale_, scale_); + checkOutput(retval, "KINSol"); + // printOutput(tout); + // std::cout << "\n"; + return retval; } template int Kinsol::deleteSimulation() { - SUNLinSolFree(linearSolver_); - KINFree(&solver_); - N_VDestroy(yy_); - N_VDestroy(scale_); - return 0; + SUNLinSolFree(linearSolver_); + KINFree(&solver_); + N_VDestroy(yy_); + N_VDestroy(scale_); + return 0; } 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) { - GridKit::Model::Evaluator* model = - static_cast*>(user_data); + GridKit::Model::Evaluator* model = + static_cast*>(user_data); - copyVec(yy, model->y()); + copyVec(yy, model->y()); - model->evaluateResidual(); - const std::vector& f = model->getResidual(); - copyVec(f, rr); + model->evaluateResidual(); + const std::vector& f = model->getResidual(); + copyVec(f, rr); - return 0; + return 0; } template - void Kinsol::copyVec(const N_Vector x, std::vector< ScalarT >& y) + void Kinsol::copyVec(const N_Vector x, std::vector& y) { - const ScalarT* xdata = NV_DATA_S(x); - for(unsigned int i = 0; i < y.size(); ++i) - { - y[i] = xdata[i]; - } + const ScalarT* xdata = NV_DATA_S(x); + for (unsigned int i = 0; i < y.size(); ++i) + { + y[i] = xdata[i]; + } } - template - void Kinsol::copyVec(const std::vector< ScalarT >& x, N_Vector y) + void Kinsol::copyVec(const std::vector& x, N_Vector y) { - ScalarT* ydata = NV_DATA_S(y); - for(unsigned int i = 0; i < x.size(); ++i) - { - ydata[i] = x[i]; - } + ScalarT* ydata = NV_DATA_S(y); + for (unsigned int i = 0; i < x.size(); ++i) + { + ydata[i] = x[i]; + } } template - void Kinsol::copyVec(const std::vector< bool >& x, N_Vector y) + void Kinsol::copyVec(const std::vector& x, N_Vector y) { - ScalarT* ydata = NV_DATA_S(y); - for(unsigned int i = 0; i < x.size(); ++i) - { - if (x[i]) - ydata[i] = 1.0; - else - ydata[i] = 0.0; - } + ScalarT* ydata = NV_DATA_S(y); + for (unsigned int i = 0; i < x.size(); ++i) + { + if (x[i]) + ydata[i] = 1.0; + else + ydata[i] = 0.0; + } } - template void Kinsol::printOutput() { - sunrealtype *yval = N_VGetArrayPointer_Serial(yy_); - - std::cout << std::setprecision(5) << std::setw(7); - for (IdxT i = 0; i < model_->size(); ++i) - { - std::cout << yval[i] << " "; - } - std::cout << "\n"; + sunrealtype* yval = N_VGetArrayPointer_Serial(yy_); + + std::cout << std::setprecision(5) << std::setw(7); + for (IdxT i = 0; i < model_->size(); ++i) + { + std::cout << yval[i] << " "; + } + std::cout << "\n"; } template void Kinsol::printSpecial(sunrealtype t, N_Vector y) { - sunrealtype *yval = N_VGetArrayPointer_Serial(y); - IdxT N = N_VGetLength_Serial(y); - std::cout << "{"; - std::cout << std::setprecision(5) << std::setw(7) << t; - for (IdxT i = 0; i < N; ++i) - { - std::cout << ", " << yval[i]; - } - std::cout << "},\n"; + sunrealtype* yval = N_VGetArrayPointer_Serial(y); + IdxT N = N_VGetLength_Serial(y); + std::cout << "{"; + std::cout << std::setprecision(5) << std::setw(7) << t; + for (IdxT i = 0; i < N; ++i) + { + std::cout << ", " << yval[i]; + } + std::cout << "},\n"; } template void Kinsol::printFinalStats() { - int retval = 0; - void* mem = solver_; - long int nni; - long int nfe; - long int nje; - long int nlfe; - - // retval = KINGetNumSteps(mem, &nst); - // checkOutput(retval, "KINGetNumSteps"); - retval = KINGetNumNonlinSolvIters(mem, &nni); - checkOutput(retval, "KINGetNumNonlinSolvIters"); - retval = KINGetNumFuncEvals(mem, &nfe); - checkOutput(retval, "KINGetNumFuncEvals"); - retval = KINGetNumJacEvals(mem, &nje); - checkOutput(retval, "KINGetNumJacEvals"); - retval = KINGetNumLinFuncEvals(mem, &nlfe); - checkOutput(retval, "KINGetNumLinFuncEvals"); - - // std::cout << "\nFinal Run Statistics: \n\n"; - std::cout << "Number of nonlinear iterations = " << nni << "\n"; - std::cout << "Number of function evaluations = " << nfe << "\n"; - std::cout << "Number of Jacobian evaluations = " << nje << "\n"; - std::cout << "Number of linear function evals. = " << nlfe << "\n"; + int retval = 0; + void* mem = solver_; + long int nni; + long int nfe; + long int nje; + long int nlfe; + + // retval = KINGetNumSteps(mem, &nst); + // checkOutput(retval, "KINGetNumSteps"); + retval = KINGetNumNonlinSolvIters(mem, &nni); + checkOutput(retval, "KINGetNumNonlinSolvIters"); + retval = KINGetNumFuncEvals(mem, &nfe); + checkOutput(retval, "KINGetNumFuncEvals"); + retval = KINGetNumJacEvals(mem, &nje); + checkOutput(retval, "KINGetNumJacEvals"); + retval = KINGetNumLinFuncEvals(mem, &nlfe); + checkOutput(retval, "KINGetNumLinFuncEvals"); + + // std::cout << "\nFinal Run Statistics: \n\n"; + std::cout << "Number of nonlinear iterations = " << nni << "\n"; + std::cout << "Number of function evaluations = " << nfe << "\n"; + std::cout << "Number of Jacobian evaluations = " << nje << "\n"; + std::cout << "Number of linear function evals. = " << nlfe << "\n"; } - template void Kinsol::checkAllocation(void* v, const char* functionName) { - if (v == NULL) - { - std::cerr << "\nERROR: Function " << functionName << " failed -- returned NULL pointer!\n\n"; - throw SundialsException(); - } + if (v == NULL) + { + std::cerr << "\nERROR: Function " << functionName << " failed -- returned NULL pointer!\n\n"; + throw SundialsException(); + } } template void Kinsol::checkOutput(int retval, const char* functionName) { - if (retval < 0) - { - std::cerr << "\nERROR: Function " << functionName << " failed with flag " << retval << "!\n\n"; - throw SundialsException(); - } + if (retval < 0) + { + std::cerr << "\nERROR: Function " << functionName << " failed with flag " << retval << "!\n\n"; + throw SundialsException(); + } } // Compiler will prevent building modules with data type incompatible with sunrealtype @@ -344,5 +341,5 @@ namespace Sundials template class Kinsol; template class Kinsol; -} // namespace Sundials + } // namespace Sundials } // namespace AnalysisManager diff --git a/src/Solver/SteadyState/Kinsol.hpp b/src/Solver/SteadyState/Kinsol.hpp index 0bd972df..e8b44102 100644 --- a/src/Solver/SteadyState/Kinsol.hpp +++ b/src/Solver/SteadyState/Kinsol.hpp @@ -57,168 +57,164 @@ * */ - /** * @file Kinsol.hpp * @author Slaven Peles - * + * * Contains declaration of interface to KINSOL nonlinear solver from * SUNDIALS library. - * + * */ #pragma once -#include #include +#include + #include -#include /* access to sparse SUNMatrix */ +#include /* access to sparse SUNMatrix */ // #include /* access to KLU linear solver */ -#include /* access to dense linear solver */ +#include /* access to dense linear solver */ #include "Model/Evaluator.hpp" #include "SteadyStateSolver.hpp" namespace AnalysisManager { - namespace Sundials + namespace Sundials + { + template + class Kinsol : public SteadyStateSolver + { + using SteadyStateSolver::model_; + + typedef typename GridKit::ScalarTraits::real_type real_type; + + public: + Kinsol(GridKit::Model::Evaluator* model); + ~Kinsol(); + + int configureSimulation(); + int configureLinearSolver(); + int getDefaultInitialCondition(); + // int setIntegrationTime(real_type t_init, real_type t_final, int nout); + // int initializeSimulation(); + int runSimulation(); + int deleteSimulation(); + + // int configureQuadrature(); + // int initializeQuadrature(); + // int runSimulationQuadrature(real_type tf, int nout=1); + // int deleteQuadrature(); + + // int configureAdjoint(); + // int configureLinearSolverBackward(); + // int initializeAdjoint(IdxT steps = 100); + // int initializeBackwardSimulation(real_type tf); + // int runForwardSimulation(real_type tf, int nout=1); + // int runBackwardSimulation(real_type t0); + // int deleteAdjoint(); + + int saveInitialCondition() + { + N_VScale(1.0, yy_, yy0_); + return 0; + } + + int getSavedInitialCondition() + { + N_VScale(1.0, yy0_, yy_); + return 0; + } + + // real_type getInitialTime() + // { + // return t_init_; + // } + + // real_type getFinalTime() + // { + // return t_final_; + // } + + // int getNumberOutputTimes() + // { + // return nout_; + // } + + // const real_type* getIntegral() const + // { + // return NV_DATA_S(q_); + // } + + // real_type* getIntegral() + // { + // return NV_DATA_S(q_); + // } + + // const real_type* getAdjointIntegral() const + // { + // return NV_DATA_S(qB_); + // } + + // real_type* getAdjointIntegral() + // { + // return NV_DATA_S(qB_); + // } + + void printOutput(); + void printSpecial(sunrealtype t, N_Vector x); + void printFinalStats(); + + private: + static int Residual(N_Vector yy, N_Vector rr, void* user_data); + + // static int Integrand(sunrealtype t, + // N_Vector yy, N_Vector yp, + // N_Vector rhsQ, void *user_data); + + // static int adjointResidual(sunrealtype t, + // N_Vector yy, N_Vector yp, + // N_Vector yyB, N_Vector ypB, + // N_Vector rrB, void *user_data); + + // static int adjointIntegrand(sunrealtype t, + // N_Vector yy, N_Vector yp, + // N_Vector yyB, N_Vector ypB, + // N_Vector rhsQB, void *user_data); + + private: + void* solver_; + SUNContext context_; + SUNMatrix JacobianMat_; + SUNLinearSolver linearSolver_; + + N_Vector yy_; ///< Solution vector + N_Vector scale_; ///< Scaling vector + N_Vector tag_; ///< Tags differential variables + N_Vector q_; ///< Integrand vector + + N_Vector yy0_; ///< Storage for initial values + + private: + // static void copyMat(Model::Evaluator::Mat& J, SlsMat Jida); + static void copyVec(const N_Vector x, std::vector& y); + static void copyVec(const std::vector& x, N_Vector y); + static void copyVec(const std::vector& x, N_Vector y); + + // int check_flag(void *flagvalue, const char *funcname, int opt); + inline void checkAllocation(void* v, const char* functionName); + inline void checkOutput(int retval, const char* functionName); + }; + + /// Simple exception to use within Kinsol class. + class SundialsException : public std::exception { - template - class Kinsol : public SteadyStateSolver - { - using SteadyStateSolver::model_; - - typedef typename GridKit::ScalarTraits::real_type real_type; - - public: - Kinsol(GridKit::Model::Evaluator* model); - ~Kinsol(); - - int configureSimulation(); - int configureLinearSolver(); - int getDefaultInitialCondition(); - // int setIntegrationTime(real_type t_init, real_type t_final, int nout); - // int initializeSimulation(); - int runSimulation(); - int deleteSimulation(); - - // int configureQuadrature(); - // int initializeQuadrature(); - // int runSimulationQuadrature(real_type tf, int nout=1); - // int deleteQuadrature(); - - // int configureAdjoint(); - // int configureLinearSolverBackward(); - // int initializeAdjoint(IdxT steps = 100); - // int initializeBackwardSimulation(real_type tf); - // int runForwardSimulation(real_type tf, int nout=1); - // int runBackwardSimulation(real_type t0); - // int deleteAdjoint(); - - - int saveInitialCondition() - { - N_VScale(1.0, yy_, yy0_); - return 0; - } - - int getSavedInitialCondition() - { - N_VScale(1.0, yy0_, yy_); - return 0; - } - - // real_type getInitialTime() - // { - // return t_init_; - // } - - // real_type getFinalTime() - // { - // return t_final_; - // } - - // int getNumberOutputTimes() - // { - // return nout_; - // } - - // const real_type* getIntegral() const - // { - // return NV_DATA_S(q_); - // } - - // real_type* getIntegral() - // { - // return NV_DATA_S(q_); - // } - - // const real_type* getAdjointIntegral() const - // { - // return NV_DATA_S(qB_); - // } - - // real_type* getAdjointIntegral() - // { - // return NV_DATA_S(qB_); - // } - - void printOutput(); - void printSpecial(sunrealtype t, N_Vector x); - void printFinalStats(); - - private: - static int Residual(N_Vector yy, N_Vector rr, void *user_data); - - // static int Integrand(sunrealtype t, - // N_Vector yy, N_Vector yp, - // N_Vector rhsQ, void *user_data); - - // static int adjointResidual(sunrealtype t, - // N_Vector yy, N_Vector yp, - // N_Vector yyB, N_Vector ypB, - // N_Vector rrB, void *user_data); - - // static int adjointIntegrand(sunrealtype t, - // N_Vector yy, N_Vector yp, - // N_Vector yyB, N_Vector ypB, - // N_Vector rhsQB, void *user_data); - - private: - void* solver_; - SUNContext context_; - SUNMatrix JacobianMat_; - SUNLinearSolver linearSolver_; - - N_Vector yy_; ///< Solution vector - N_Vector scale_; ///< Scaling vector - N_Vector tag_; ///< Tags differential variables - N_Vector q_; ///< Integrand vector - - N_Vector yy0_; ///< Storage for initial values - - private: - //static void copyMat(Model::Evaluator::Mat& J, SlsMat Jida); - static void copyVec(const N_Vector x, std::vector& y); - static void copyVec(const std::vector& x, N_Vector y); - static void copyVec(const std::vector& x, N_Vector y); - - //int check_flag(void *flagvalue, const char *funcname, int opt); - inline void checkAllocation(void* v, const char* functionName); - inline void checkOutput(int retval, const char* functionName); - - }; - - /// Simple exception to use within Kinsol class. - class SundialsException : public std::exception - { - virtual const char* what() const throw() - { - return "Method in Kinsol class failed!\n"; - } - }; - - - } // namespace Sundials + virtual const char* what() const throw() + { + return "Method in Kinsol class failed!\n"; + } + }; + } // namespace Sundials } // namespace AnalysisManager diff --git a/src/Solver/SteadyState/SteadyStateSolver.hpp b/src/Solver/SteadyState/SteadyStateSolver.hpp index a17024b4..555fa319 100644 --- a/src/Solver/SteadyState/SteadyStateSolver.hpp +++ b/src/Solver/SteadyState/SteadyStateSolver.hpp @@ -1,25 +1,25 @@ /* - * + * * Copyright (c) 2017, Lawrence Livermore National Security, LLC. * Produced at the Lawrence Livermore National Laboratory. * Written by Slaven Peles . * LLNL-CODE-718378. * All rights reserved. - * - * This file is part of GridKit™. For details, see github.com/LLNL/GridKit - * Please also read the LICENSE file. - * - * Redistribution and use in source and binary forms, with or without + * + * This file is part of GridKit™. For details, see github.com/LLNL/GridKit + * Please also read the LICENSE file. + * + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright notice, + * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the disclaimer below. * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the disclaimer (as noted below) in the + * this list of conditions and the disclaimer (as noted below) in the * documentation and/or other materials provided with the distribution. - * - Neither the name of the LLNS/LLNL nor the names of its contributors may - * be used to endorse or promote products derived from this software without + * - Neither the name of the LLNS/LLNL nor the names of its contributors may + * be used to endorse or promote products derived from this software without * specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF @@ -31,30 +31,30 @@ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. - * - * Lawrence Livermore National Laboratory is operated by Lawrence Livermore - * National Security, LLC, for the U.S. Department of Energy, National + * + * Lawrence Livermore National Laboratory is operated by Lawrence Livermore + * National Security, LLC, for the U.S. Department of Energy, National * Nuclear Security Administration under Contract DE-AC52-07NA27344. - * - * This document was prepared as an account of work sponsored by an agency - * of the United States government. Neither the United States government nor - * Lawrence Livermore National Security, LLC, nor any of their employees - * makes any warranty, expressed or implied, or assumes any legal liability - * or responsibility for the accuracy, completeness, or usefulness of any - * information, apparatus, product, or process disclosed, or represents that - * its use would not infringe privately owned rights. Reference herein to - * any specific commercial product, process, or service by trade name, - * trademark, manufacturer, or otherwise does not necessarily constitute or - * imply its endorsement, recommendation, or favoring by the United States - * government or Lawrence Livermore National Security, LLC. The views and - * opinions of authors expressed herein do not necessarily state or reflect - * those of the United States government or Lawrence Livermore National - * Security, LLC, and shall not be used for advertising or product - * endorsement purposes. - * + * + * This document was prepared as an account of work sponsored by an agency + * of the United States government. Neither the United States government nor + * Lawrence Livermore National Security, LLC, nor any of their employees + * makes any warranty, expressed or implied, or assumes any legal liability + * or responsibility for the accuracy, completeness, or usefulness of any + * information, apparatus, product, or process disclosed, or represents that + * its use would not infringe privately owned rights. Reference herein to + * any specific commercial product, process, or service by trade name, + * trademark, manufacturer, or otherwise does not necessarily constitute or + * imply its endorsement, recommendation, or favoring by the United States + * government or Lawrence Livermore National Security, LLC. The views and + * opinions of authors expressed herein do not necessarily state or reflect + * those of the United States government or Lawrence Livermore National + * Security, LLC, and shall not be used for advertising or product + * endorsement purposes. + * */ #pragma once @@ -62,22 +62,26 @@ namespace AnalysisManager { - template - class SteadyStateSolver + template + class SteadyStateSolver + { + public: + SteadyStateSolver(GridKit::Model::Evaluator* model) + : model_(model) { - public: - SteadyStateSolver(GridKit::Model::Evaluator* model) : model_(model) - { - } - virtual ~SteadyStateSolver(){} - - GridKit::Model::Evaluator* getModel() - { - return model_; - } - - protected: - GridKit::Model::Evaluator* model_; - }; + } -} + virtual ~SteadyStateSolver() + { + } + + GridKit::Model::Evaluator* getModel() + { + return model_; + } + + protected: + GridKit::Model::Evaluator* model_; + }; + +} // namespace AnalysisManager diff --git a/src/Utilities/FileIO.hpp b/src/Utilities/FileIO.hpp index 24b244b2..7ecc64df 100644 --- a/src/Utilities/FileIO.hpp +++ b/src/Utilities/FileIO.hpp @@ -80,327 +80,364 @@ namespace { -using namespace GridKit; -using namespace GridKit::PowerSystemData; - -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."}; - -std::ostream& logs() -{ + using namespace GridKit; + using namespace GridKit::PowerSystemData; + + 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."}; + + std::ostream& logs() + { #ifndef NDEBUG - std::cerr << "[FileIO.hpp]: "; - return std::cerr; + std::cerr << "[FileIO.hpp]: "; + return std::cerr; #else - static std::ofstream ofs; - ofs.setstate(std::ios_base::badbit); - return ofs; + static std::ofstream ofs; + ofs.setstate(std::ios_base::badbit); + return ofs; #endif -} - -void ltrim(std::string& s) -{ - const std::string nothing = ""; - s = std::regex_replace(s, std::regex("^\\s+"), nothing); -} - -void rtrim(std::string& s) -{ - const std::string nothing = ""; - s = std::regex_replace(s, std::regex("\\s+$"), nothing); -} + } -void trim_matlab_comments(std::string& s) -{ - const std::string nothing = ""; - s = std::regex_replace(s, std::regex("%.+"), nothing); -} - -// Retrive MATPOWER component from assignment line. -// -// For example, the string " mpc.bus = [ ... ] % Some comment" will -// return the value "bus". -std::string getMatPowerComponent(const std::string& line) -{ - logs() << "Getting matpower component from line\n"; - std::regex pat("mpc.([a-zA-Z]+)\\s*=.+"); - std::smatch matches; - std::string component; - if (std::regex_match(line, matches, pat)) + void ltrim(std::string& s) { - component = matches[1].str(); + const std::string nothing = ""; + s = std::regex_replace(s, std::regex("^\\s+"), nothing); } - else + + void rtrim(std::string& s) { - throw std::runtime_error(matlab_syntax_error + "\nGot line " + line); + const std::string nothing = ""; + s = std::regex_replace(s, std::regex("\\s+$"), nothing); } - ltrim(component); - rtrim(component); - return component; -} - -// Ensure that all of the given line has been consumed, and that the only -// remaining non-whitespace character left in the line is a semicolon. -void checkEndOfMatrixRow(std::istream& is) -{ - std::string rest; - is >> rest; - ltrim(rest); - rtrim(rest); - if (rest != ";") - throw std::runtime_error(matlab_syntax_error); -} - -template -void readMatPowerBusRow(const std::string& row, BusData& br, LoadData& lr) -{ - 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.) - - lr.bus_i = br.bus_i; - - // std::cout << br.str(); - // logs() << "Read BusData with the following values:\n" << br.str(); - // return br; -} - -template -void readMatPowerGenRow(GenData& gr, std::string& row) -{ - 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; - checkEndOfMatrixRow(is); -} - -template -void readMatPowerBranchRow(BranchData& br, std::string& row) -{ - 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; - checkEndOfMatrixRow(is); -} - -template -void readMatPowerGenCostRow(GenCostData& gcr, std::string& row) -{ - logs() << "Parsing MATPOWER gen cost row\n"; - // Ensure last character is semicolon. - rtrim(row); - if (row[row.size() - 1] != ';') - throw std::runtime_error(matlab_syntax_error + "\nGot line " + row); - std::stringstream is(row); - is >> gcr.kind >> gcr.startup >> gcr.shutdown >> gcr.n; + void trim_matlab_comments(std::string& s) + { + const std::string nothing = ""; + s = std::regex_replace(s, std::regex("%.+"), nothing); + } - for (RealT r; is >> r;) { - gcr.rest.push_back(r); + // Retrive MATPOWER component from assignment line. + // + // For example, the string " mpc.bus = [ ... ] % Some comment" will + // return the value "bus". + std::string getMatPowerComponent(const std::string& line) + { + logs() << "Getting matpower component from line\n"; + std::regex pat("mpc.([a-zA-Z]+)\\s*=.+"); + std::smatch matches; + std::string component; + if (std::regex_match(line, matches, pat)) + { + component = matches[1].str(); + } + else + { + throw std::runtime_error(matlab_syntax_error + "\nGot line " + line); + } + ltrim(component); + rtrim(component); + return component; } -} -template -void readMatPowerVersion(SystemModelData& mp, std::string& line) -{ - logs() << "Parsing matpower version\n"; - std::regex pat("mpc\\.version\\s*=\\s*'([0-9])';"); - std::smatch matches; - if (std::regex_match(line, matches, pat)) { - mp.version = matches[1].str(); - } else { - throw std::runtime_error(matlab_syntax_error + "\nGot line '" + line + "'"); + // Ensure that all of the given line has been consumed, and that the only + // remaining non-whitespace character left in the line is a semicolon. + void checkEndOfMatrixRow(std::istream& is) + { + std::string rest; + is >> rest; + ltrim(rest); + rtrim(rest); + if (rest != ";") + throw std::runtime_error(matlab_syntax_error); } -} -template -void readMatPowerBaseMVA(SystemModelData& mp, std::string& line) -{ - std::regex pat("mpc\\.baseMVA\\s*=\\s*([0-9]+);"); - std::smatch matches; - if (std::regex_match(line, matches, pat)) { - std::string s = matches[1]; - mp.baseMVA = std::atoi(s.c_str()); - } else { - throw std::runtime_error(matlab_syntax_error + "\nGot line '" + line + "'"); + template + void readMatPowerBusRow(const std::string& row, BusData& br, LoadData& lr) + { + 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.) + + lr.bus_i = br.bus_i; + + // std::cout << br.str(); + // logs() << "Read BusData with the following values:\n" << br.str(); + // return br; } -} -} // namespace + template + void readMatPowerGenRow(GenData& gr, std::string& row) + { + 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; + checkEndOfMatrixRow(is); + } -namespace GridKit -{ + template + void readMatPowerBranchRow(BranchData& br, std::string& row) + { + 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; + checkEndOfMatrixRow(is); + } -/** - * @brief Reads in an input stream of tabulated data - * - * @todo needs to return int for file error codes - * - * @tparam ScalarT - * @param[out] table object in memory where the data from the input stream is - * @param[in] filename input stream to space and newline separated data - * @param[out] ti initial time returned - * @param[out] tf final time returned - * - * @pre Input stream should read space separated data. Rows are separated - * by new line. Each row od data must have the same number of entries. The - * first column of the data represents time and other columns time dependent - * variables. - */ -template -void setLookupTable(std::vector>& table, - std::istream& idata, - ScalarT& ti, - ScalarT& tf) -{ - std::string line; - int oldwordcount = -1; - while (std::getline(idata, line)) { - std::istringstream iss(line); - double word; - int wordcount = 0; - std::vector row; - while (iss >> word) { - row.push_back(word); - ++wordcount; - } - table.push_back(std::move(row)); - if (oldwordcount != -1) { - if (oldwordcount != wordcount) { - std::cerr << "Corrupted input data!\n"; - return; - } - } else { - oldwordcount = wordcount; + template + void readMatPowerGenCostRow(GenCostData& gcr, std::string& row) + { + logs() << "Parsing MATPOWER gen cost row\n"; + // Ensure last character is semicolon. + rtrim(row); + if (row[row.size() - 1] != ';') + throw std::runtime_error(matlab_syntax_error + "\nGot line " + row); + + std::stringstream is(row); + is >> gcr.kind >> gcr.startup >> gcr.shutdown >> gcr.n; + + for (RealT r; is >> r;) + { + gcr.rest.push_back(r); } } - size_t N = table.size(); - if (N == 0) + template + void readMatPowerVersion(SystemModelData& mp, std::string& line) { - // do nothing + logs() << "Parsing matpower version\n"; + std::regex pat("mpc\\.version\\s*=\\s*'([0-9])';"); + std::smatch matches; + if (std::regex_match(line, matches, pat)) + { + mp.version = matches[1].str(); + } + else + { + throw std::runtime_error(matlab_syntax_error + "\nGot line '" + line + "'"); + } } - else if (N == 1) + + template + void readMatPowerBaseMVA(SystemModelData& mp, std::string& line) { - ti = table[0][0]; - tf = table[0][0]; + std::regex pat("mpc\\.baseMVA\\s*=\\s*([0-9]+);"); + std::smatch matches; + if (std::regex_match(line, matches, pat)) + { + std::string s = matches[1]; + mp.baseMVA = std::atoi(s.c_str()); + } + else + { + throw std::runtime_error(matlab_syntax_error + "\nGot line '" + line + "'"); + } } - else + +} // namespace + +namespace GridKit +{ + + /** + * @brief Reads in an input stream of tabulated data + * + * @todo needs to return int for file error codes + * + * @tparam ScalarT + * @param[out] table object in memory where the data from the input stream is + * @param[in] filename input stream to space and newline separated data + * @param[out] ti initial time returned + * @param[out] tf final time returned + * + * @pre Input stream should read space separated data. Rows are separated + * by new line. Each row od data must have the same number of entries. The + * first column of the data represents time and other columns time dependent + * variables. + */ + template + void setLookupTable(std::vector>& table, + std::istream& idata, + ScalarT& ti, + ScalarT& tf) { + std::string line; + int oldwordcount = -1; + while (std::getline(idata, line)) + { + std::istringstream iss(line); + double word; + int wordcount = 0; + std::vector row; + while (iss >> word) + { + row.push_back(word); + ++wordcount; + } + table.push_back(std::move(row)); + if (oldwordcount != -1) + { + if (oldwordcount != wordcount) + { + std::cerr << "Corrupted input data!\n"; + return; + } + } + else + { + oldwordcount = wordcount; + } + } + + size_t N = table.size(); + if (N == 0) + { + // do nothing + } + else if (N == 1) + { + ti = table[0][0]; + tf = table[0][0]; + } + else + { ti = table[0][0]; tf = table[N - 1][0]; + } } -} -template -void printLookupTable(std::vector> const& table) -{ - for (size_t i = 0; i < table.size(); ++i) { - for (size_t j = 0; j < table[i].size(); ++j) { - std::cout << table[i][j] << " "; + template + void printLookupTable(std::vector> const& table) + { + for (size_t i = 0; i < table.size(); ++i) + { + for (size_t j = 0; j < table[i].size(); ++j) + { + std::cout << table[i][j] << " "; + } + std::cout << "\n"; } - std::cout << "\n"; } -} -template -void readMatPowerFile(SystemModelData& mp, std::string& filename) -{ - std::ifstream ifs{filename}; - readMatPower(mp, ifs); -} - -template -void readMatPower(SystemModelData& mp, std::istream& is) -{ - using BusDataT = BusData; - using GenDataT = GenData; - using BranchDataT = BranchData; - using GenCostDataT = GenCostData; - using LoadDataT = LoadData; - - for (std::string line; std::getline(is, line);) { - // Trim whitespace and remove comments - ltrim(line); - rtrim(line); - logs() << line << "\n"; - trim_matlab_comments(line); - - // Skip empty lines and comment-only lines - if (line.size() == 0) continue; - - // Skip the matlab function declaration - if (line.find("function") != std::string::npos) continue; - - // Check for MATPOWER component definitions - if (line.find("mpc") != std::string::npos) { - const std::string component = getMatPowerComponent(line); - logs() << "Got component: '" << component << "'\n"; - // First, parse matrix components - if (component == "bus") { - while (std::getline(is, line)) { - if (line.find("];") != std::string::npos) break; - BusDataT br; - LoadDataT lr; - readMatPowerBusRow(line, br, lr); - mp.bus.push_back(std::move(br)); - mp.load.push_back(std::move(lr)); + template + void readMatPowerFile(SystemModelData& mp, std::string& filename) + { + std::ifstream ifs{filename}; + readMatPower(mp, ifs); + } + + template + void readMatPower(SystemModelData& mp, std::istream& is) + { + using BusDataT = BusData; + using GenDataT = GenData; + using BranchDataT = BranchData; + using GenCostDataT = GenCostData; + using LoadDataT = LoadData; + + for (std::string line; std::getline(is, line);) + { + // Trim whitespace and remove comments + ltrim(line); + rtrim(line); + logs() << line << "\n"; + trim_matlab_comments(line); + + // Skip empty lines and comment-only lines + if (line.size() == 0) + continue; + + // Skip the matlab function declaration + if (line.find("function") != std::string::npos) + continue; + + // Check for MATPOWER component definitions + if (line.find("mpc") != std::string::npos) + { + const std::string component = getMatPowerComponent(line); + logs() << "Got component: '" << component << "'\n"; + // First, parse matrix components + if (component == "bus") + { + while (std::getline(is, line)) + { + if (line.find("];") != std::string::npos) + break; + BusDataT br; + LoadDataT lr; + readMatPowerBusRow(line, br, lr); + mp.bus.push_back(std::move(br)); + mp.load.push_back(std::move(lr)); + } } - } else if (component == "gen") { - while (std::getline(is, line)) { - if (line.find("];") != std::string::npos) break; - GenDataT gr; - readMatPowerGenRow(gr, line); - mp.gen.push_back(gr); + else if (component == "gen") + { + while (std::getline(is, line)) + { + if (line.find("];") != std::string::npos) + break; + GenDataT gr; + readMatPowerGenRow(gr, line); + mp.gen.push_back(gr); + } } - } else if (component == "branch") { - while (std::getline(is, line)) { - if (line.find("];") != std::string::npos) break; - BranchDataT br; - readMatPowerBranchRow(br, line); - mp.branch.push_back(br); + else if (component == "branch") + { + while (std::getline(is, line)) + { + if (line.find("];") != std::string::npos) + break; + BranchDataT br; + readMatPowerBranchRow(br, line); + mp.branch.push_back(br); + } } - } else if (component == "gencost") { - while (std::getline(is, line)) { - if (line.find("];") != std::string::npos) break; - GenCostDataT gcr; - readMatPowerGenCostRow(gcr, line); - mp.gencost.push_back(gcr); + else if (component == "gencost") + { + while (std::getline(is, line)) + { + if (line.find("];") != std::string::npos) + break; + GenCostDataT gcr; + readMatPowerGenCostRow(gcr, line); + mp.gencost.push_back(gcr); + } } - } - // Next, parse scalar components - else if (component == "version") { - readMatPowerVersion(mp, line); - } else if (component == "baseMVA") { - readMatPowerBaseMVA(mp, line); + // Next, parse scalar components + else if (component == "version") + { + readMatPowerVersion(mp, line); + } + else if (component == "baseMVA") + { + readMatPowerBaseMVA(mp, line); + } } } } -} -} // namespace GridKit +} // namespace GridKit diff --git a/src/Utilities/TestHelpers.hpp b/src/Utilities/TestHelpers.hpp index fb84b470..d8e876c0 100644 --- a/src/Utilities/TestHelpers.hpp +++ b/src/Utilities/TestHelpers.hpp @@ -9,237 +9,247 @@ #define THROW_NULL_DEREF throw std::runtime_error("error") -#include #include #include - +#include namespace GridKit { -namespace Colors -{ + namespace Colors + { // must be const pointer and const dest for // const string declarations to pass -Wwrite-strings - static const char * const RED = "\033[1;31m"; - static const char * const GREEN = "\033[1;32m"; - static const char * const YELLOW = "\033[33;1m"; - static const char * const BLUE = "\033[34;1m"; - static const char * const ORANGE = "\u001b[38;5;208m"; - static const char * const CLEAR = "\033[0m"; -} - -namespace Testing -{ - enum TestOutcome {PASS=0, FAIL, SKIP, EXPECTED_FAIL, UNEXPECTED_PASS}; + static const char* const RED = "\033[1;31m"; + static const char* const GREEN = "\033[1;32m"; + static const char* const YELLOW = "\033[33;1m"; + static const char* const BLUE = "\033[34;1m"; + static const char* const ORANGE = "\u001b[38;5;208m"; + static const char* const CLEAR = "\033[0m"; + } // namespace Colors + + namespace Testing + { + enum TestOutcome + { + PASS = 0, + FAIL, + SKIP, + EXPECTED_FAIL, + UNEXPECTED_PASS + }; class TestStatus { public: - TestStatus() + TestStatus() : outcome_(TestOutcome::PASS) - { - } + { + } - TestStatus(bool success) + TestStatus(bool success) : outcome_(success ? TestOutcome::PASS : TestOutcome::FAIL) - { - } + { + } - TestStatus(const char* funcname) + TestStatus(const char* funcname) : outcome_(TestOutcome::PASS), funcname_(funcname) + { + } + + ~TestStatus() + { + } + + TestStatus& operator=(const bool isPass) + { + if (isPass) + outcome_ = TestOutcome::PASS; + else + outcome_ = TestOutcome::FAIL; + return *this; + } + + TestStatus& operator*=(const bool isPass) + { + if (!isPass) + outcome_ = TestOutcome::FAIL; + return *this; + } + + void skipTest() + { + outcome_ = TestOutcome::SKIP; + } + + void expectFailure() + { + expectFailure_ = true; + } + + TestOutcome report() + { + return report(funcname_); + } + + TestOutcome report(const char* funcname) + { + using namespace Colors; + + if (expectFailure_) { + if ((outcome_ == FAIL) || (outcome_ == EXPECTED_FAIL)) + outcome_ = EXPECTED_FAIL; + else if ((outcome_ == PASS) || (outcome_ == UNEXPECTED_PASS)) + outcome_ = UNEXPECTED_PASS; + else + outcome_ = SKIP; } - ~TestStatus() - { - } - - TestStatus& operator=(const bool isPass) - { - if(isPass) - outcome_ = TestOutcome::PASS; - else - outcome_ = TestOutcome::FAIL; - return *this; - } - - TestStatus& operator*=(const bool isPass) - { - if(!isPass) - outcome_ = TestOutcome::FAIL; - return *this; - } - - void skipTest() - { - outcome_ = TestOutcome::SKIP; - } - - void expectFailure() + switch (outcome_) { - expectFailure_ = true; - } - - TestOutcome report() - { - return report(funcname_); - } - - TestOutcome report(const char* funcname) - { - using namespace Colors; - - if (expectFailure_) - { - if ((outcome_ == FAIL) || (outcome_ == EXPECTED_FAIL)) - outcome_ = EXPECTED_FAIL; - else if ((outcome_ == PASS) || (outcome_ == UNEXPECTED_PASS)) - outcome_ = UNEXPECTED_PASS; - else - outcome_ = SKIP; - } - - switch(outcome_) - { - case PASS: - std::cout << "--- " << GREEN << "PASS" << CLEAR - << ": Test " << funcname << "\n"; - break; - case FAIL: - std::cout << "--- " << RED << "FAIL" << CLEAR - << ": Test " << funcname << "\n"; - break; - case SKIP: - std::cout << "--- " << YELLOW << "SKIP" << CLEAR - << ": Test " << funcname << CLEAR << "\n"; - break; - case EXPECTED_FAIL: - std::cout << "--- " << ORANGE << "FAIL" << CLEAR - << " (EXPECTED)" << ": Test " << funcname << "\n"; - break; - case UNEXPECTED_PASS: - std::cout << "--- " << BLUE << "PASS" << CLEAR - << " (UNEXPECTED)" << ": Test " << funcname << "\n"; - break; - default: - std::cout << "--- " << RED << "FAIL" << CLEAR - << "Unrecognized test result " << outcome_ - << " for test " << funcname << "\n"; - } - return outcome_; + case PASS: + std::cout << "--- " << GREEN << "PASS" << CLEAR + << ": Test " << funcname << "\n"; + break; + case FAIL: + std::cout << "--- " << RED << "FAIL" << CLEAR + << ": Test " << funcname << "\n"; + break; + case SKIP: + std::cout << "--- " << YELLOW << "SKIP" << CLEAR + << ": Test " << funcname << CLEAR << "\n"; + break; + case EXPECTED_FAIL: + std::cout << "--- " << ORANGE << "FAIL" << CLEAR + << " (EXPECTED)" + << ": Test " << funcname << "\n"; + break; + case UNEXPECTED_PASS: + std::cout << "--- " << BLUE << "PASS" << CLEAR + << " (UNEXPECTED)" + << ": Test " << funcname << "\n"; + break; + default: + std::cout << "--- " << RED << "FAIL" << CLEAR + << "Unrecognized test result " << outcome_ + << " for test " << funcname << "\n"; } + return outcome_; + } private: - TestOutcome outcome_; - const char* funcname_; - bool expectFailure_ = false; + TestOutcome outcome_; + const char* funcname_; + bool expectFailure_ = false; }; - - struct TestingResults { - int success = 0; - int failure = 0; - int skip = 0; - int expected_failure = 0; - int unexpected_success = 0; - - TestingResults(){} - ~TestingResults(){} - TestingResults(const TestingResults& r) - { - this->success = r.success; - this->failure = r.failure; - this->skip = r.skip; - this->expected_failure = r.expected_failure; - this->unexpected_success = r.unexpected_success; - } - - void init() + int success = 0; + int failure = 0; + int skip = 0; + int expected_failure = 0; + int unexpected_success = 0; + + TestingResults() + { + } + + ~TestingResults() + { + } + + TestingResults(const TestingResults& r) + { + this->success = r.success; + this->failure = r.failure; + this->skip = r.skip; + this->expected_failure = r.expected_failure; + this->unexpected_success = r.unexpected_success; + } + + void init() + { + this->success = 0; + this->failure = 0; + this->skip = 0; + this->expected_failure = 0; + this->unexpected_success = 0; + } + + TestingResults& operator+=(const TestingResults& rhs) + { + this->success += rhs.success; + this->failure += rhs.failure; + this->skip += rhs.skip; + this->expected_failure += rhs.expected_failure; + this->unexpected_success += rhs.unexpected_success; + + return *this; + } + + TestingResults& operator+=(const TestOutcome outcome) + { + switch (outcome) { - this->success = 0; - this->failure = 0; - this->skip = 0; - this->expected_failure = 0; - this->unexpected_success = 0; - } - - TestingResults& operator+=(const TestingResults& rhs) - { - this->success += rhs.success; - this->failure += rhs.failure; - this->skip += rhs.skip; - this->expected_failure += rhs.expected_failure; - this->unexpected_success += rhs.unexpected_success; - - return *this; - } - - TestingResults& operator+=(const TestOutcome outcome) - { - switch(outcome) - { - case PASS: - this->success++; - break; - case FAIL: - this->failure++; - break; - case SKIP: - this->skip++; - break; - case EXPECTED_FAIL: - this->expected_failure++; - break; - case UNEXPECTED_PASS: - this->unexpected_success++; - break; - default: - std::cout << "Warning: Unrecognized test outcome code " - << outcome << ". Assuming failure ...\n"; - this->failure++; - } - return *this; - } - - int summary() - { - std::cout << "\n\nTest Summary\n"; - std::cout << "----------------------------\n"; - std::cout << "\tSuccessful tests: " << success << "\n"; - std::cout << "\tFailed test: " << failure << "\n"; - std::cout << "\tSkipped tests: " << skip << "\n"; - std::cout << "\tExpected failures: " << expected_failure << "\n"; - std::cout << "\tUnexpected successes: " << unexpected_success << "\n"; - std::cout << "\n"; - - return failure; + case PASS: + this->success++; + break; + case FAIL: + this->failure++; + break; + case SKIP: + this->skip++; + break; + case EXPECTED_FAIL: + this->expected_failure++; + break; + case UNEXPECTED_PASS: + this->unexpected_success++; + break; + default: + std::cout << "Warning: Unrecognized test outcome code " + << outcome << ". Assuming failure ...\n"; + this->failure++; } + return *this; + } + + int summary() + { + std::cout << "\n\nTest Summary\n"; + std::cout << "----------------------------\n"; + std::cout << "\tSuccessful tests: " << success << "\n"; + std::cout << "\tFailed test: " << failure << "\n"; + std::cout << "\tSkipped tests: " << skip << "\n"; + std::cout << "\tExpected failures: " << expected_failure << "\n"; + std::cout << "\tUnexpected successes: " << unexpected_success << "\n"; + std::cout << "\n"; + + return failure; + } }; TestingResults operator+(const TestingResults& lhs, const TestingResults& rhs) { - return TestingResults(lhs) += rhs; + return TestingResults(lhs) += rhs; } TestingResults operator+(const TestingResults& lhs, const TestOutcome outcome) { - return TestingResults(lhs) += outcome; + return TestingResults(lhs) += outcome; } TestingResults operator+(const TestOutcome outcome, const TestingResults& rhs) { - return TestingResults(rhs) += outcome; + return TestingResults(rhs) += outcome; } - // /// @brief eps = 2.2e-15 for double type // static const real_type eps_ = 10*std::numeric_limits::epsilon(); - // class TestBase // { // public: @@ -253,8 +263,8 @@ namespace Testing // { // return (std::abs(a - b)/(1.0 + std::abs(b)) < eps); // } - + // }; -} // namespace Testing + } // namespace Testing } // namespace GridKit diff --git a/src/Utilities/Testing.hpp b/src/Utilities/Testing.hpp index 681bb95f..db3a3684 100644 --- a/src/Utilities/Testing.hpp +++ b/src/Utilities/Testing.hpp @@ -66,197 +66,219 @@ */ #pragma once -#include #include #include #include -namespace { +#include + +namespace +{ -static constexpr double tol_ = 1e-8; + static constexpr double tol_ = 1e-8; -inline std::ostream &errs() { - std::cerr << "[Utils/Testing.hpp]: "; - return std::cerr; -} + inline std::ostream& errs() + { + std::cerr << "[Utils/Testing.hpp]: "; + return std::cerr; + } } // namespace -namespace GridKit { -namespace Testing { +namespace GridKit +{ + namespace Testing + { - template + template 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); + T error = std::abs(value - ref) / (1.0 + std::abs(ref)); + return (error < tol); } -template -inline bool isEqual(PowerSystemData::GenCostData a, - PowerSystemData::GenCostData b, - RealT tol = tol_) -{ - (void) tol; // suppress warning - int fail = 0; - fail += a.kind != b.kind; - fail += a.startup != b.startup; - fail += a.shutdown != b.shutdown; - fail += a.n != b.n; - if (fail) { - errs() << "Got failure!\na=" << a.str() << "\nb=" << b.str(); - } - return fail == 0; -} + template + inline bool isEqual(PowerSystemData::GenCostData a, + PowerSystemData::GenCostData b, + RealT tol = tol_) + { + (void) tol; // suppress warning + int fail = 0; + fail += a.kind != b.kind; + fail += a.startup != b.startup; + fail += a.shutdown != b.shutdown; + fail += a.n != b.n; + if (fail) + { + errs() << "Got failure!\na=" << a.str() << "\nb=" << b.str(); + } + return fail == 0; + } -template -inline bool isEqual(PowerSystemData::GenData a, - PowerSystemData::GenData b, - RealT tol = tol_) -{ - int fail = 0; - fail += a.bus != b.bus; - fail += !isEqual(a.Pg, b.Pg, tol); - fail += !isEqual(a.Qg, b.Qg, tol); - fail += !isEqual(a.Qmax, b.Qmax, tol); - fail += !isEqual(a.Qmin, b.Qmin, tol); - fail += !isEqual(a.Vg, b.Vg, tol); - fail += a.mBase != b.mBase; - fail += a.status != b.status; - fail += a.Pmax != b.Pmax; - fail += a.Pmin != b.Pmin; - fail += a.Pc1 != b.Pc1; - fail += a.Pc2 != b.Pc2; - fail += a.Qc1min != b.Qc1min; - fail += a.Qc1max != b.Qc1max; - fail += a.Qc2min != b.Qc2min; - fail += a.Qc2max != b.Qc2max; - fail += a.ramp_agc != b.ramp_agc; - fail += a.ramp_10 != b.ramp_10; - fail += a.ramp_30 != b.ramp_30; - fail += a.ramp_q != b.ramp_q; - fail += a.apf != b.apf; - if (fail) { - errs() << "Got failure!\na=" << a.str() << "\nb=" << b.str(); - } - return fail == 0; -} + template + inline bool isEqual(PowerSystemData::GenData a, + PowerSystemData::GenData b, + RealT tol = tol_) + { + int fail = 0; -template -inline bool isEqual(PowerSystemData::BusData a, - PowerSystemData::BusData b, - RealT tol = tol_) -{ - int fail = 0; - fail += a.bus_i != b.bus_i; - fail += a.type != b.type; - fail += a.Gs != b.Gs; - fail += a.Bs != b.Bs; - fail += a.area != b.area; - fail += !isEqual(a.Vm, b.Vm, tol); - fail += !isEqual(a.Va, b.Va, tol); - fail += a.baseKV != b.baseKV; - fail += a.zone != b.zone; - fail += !isEqual(a.Vmax, b.Vmax, tol); - fail += !isEqual(a.Vmin, b.Vmin, tol); - if (fail) { - errs() << "bus_i: a=" << a.bus_i << ", b=" << b.bus_i << "\n" - << "type: a=" << a.type << ", b=" << b.type << "\n" - << "Gs: a=" << a.Gs << ", b=" << b.Gs << "\n" - << "Bs: a=" << a.Bs << ", b=" << b.Bs << "\n" - << "area: a=" << a.area << ", b=" << b.area << "\n" - << "Vm: a=" << a.Vm << ", b=" << b.Vm << "\n" - << "Va: a=" << a.Va << ", b=" << b.Va << "\n" - << "baseKV: a=" << a.baseKV << ", b=" << b.baseKV << "\n" - << "zone: a=" << a.zone << ", b=" << b.zone << "\n" - << "Vmax: a=" << a.Vmax << ", b=" << b.Vmax << "\n" - << "Vmin: a=" << a.Vmin << ", b=" << b.Vmin << "\n"; - } - return fail == 0; -} + fail += a.bus != b.bus; + fail += !isEqual(a.Pg, b.Pg, tol); + fail += !isEqual(a.Qg, b.Qg, tol); + fail += !isEqual(a.Qmax, b.Qmax, tol); + fail += !isEqual(a.Qmin, b.Qmin, tol); + fail += !isEqual(a.Vg, b.Vg, tol); + fail += a.mBase != b.mBase; + fail += a.status != b.status; + fail += a.Pmax != b.Pmax; + fail += a.Pmin != b.Pmin; + fail += a.Pc1 != b.Pc1; + fail += a.Pc2 != b.Pc2; + fail += a.Qc1min != b.Qc1min; + fail += a.Qc1max != b.Qc1max; + fail += a.Qc2min != b.Qc2min; + fail += a.Qc2max != b.Qc2max; + fail += a.ramp_agc != b.ramp_agc; + fail += a.ramp_10 != b.ramp_10; + fail += a.ramp_30 != b.ramp_30; + fail += a.ramp_q != b.ramp_q; + fail += a.apf != b.apf; -template -inline bool isEqual(PowerSystemData::LoadData a, - PowerSystemData::LoadData b, - RealT tol = tol_) -{ - int fail = 0; - fail += a.bus_i != b.bus_i; - fail += !isEqual(a.Pd, b.Pd, tol); - fail += !isEqual(a.Qd, b.Qd, tol); - if (fail) { - errs() << "bus_i: a=" << a.bus_i << ", b=" << b.bus_i << "\n" - << "Pd: a=" << a.Pd << ", b=" << b.Pd << "\n" - << "Qd: a=" << a.Qd << ", b=" << b.Qd << "\n"; - } - return fail == 0; -} + if (fail) + { + errs() << "Got failure!\na=" << a.str() << "\nb=" << b.str(); + } + return fail == 0; + } -template -inline bool isEqual(PowerSystemData::BranchData a, - PowerSystemData::BranchData b, - RealT tol = tol_) -{ - int fail = 0; - fail += a.fbus != b.fbus; - fail += a.tbus != b.tbus; - fail += !isEqual(a.r, b.r, tol); - fail += !isEqual(a.x, b.x, tol); - fail += !isEqual(a.b, b.b, tol); - fail += a.rateA != b.rateA; - fail += a.rateB != b.rateB; - fail += a.rateC != b.rateC; - fail += a.ratio != b.ratio; - fail += a.angle != b.angle; - fail += a.status != b.status; - fail += a.angmin != b.angmin; - fail += a.angmax != b.angmax; - if (fail) { - errs() << "Got failure!\na=" << a.str() << "\nb=" << b.str(); - } - return fail == 0; -} + template + inline bool isEqual(PowerSystemData::BusData a, + PowerSystemData::BusData b, + RealT tol = tol_) + { + int fail = 0; -template -inline bool isEqual(std::vector a, std::vector b, double tol = tol_) -{ - if (a.size() != b.size()) - throw std::runtime_error([&] { + fail += a.bus_i != b.bus_i; + fail += a.type != b.type; + fail += a.Gs != b.Gs; + fail += a.Bs != b.Bs; + fail += a.area != b.area; + fail += !isEqual(a.Vm, b.Vm, tol); + fail += !isEqual(a.Va, b.Va, tol); + fail += a.baseKV != b.baseKV; + fail += a.zone != b.zone; + fail += !isEqual(a.Vmax, b.Vmax, tol); + fail += !isEqual(a.Vmin, b.Vmin, tol); + + if (fail) + { + errs() << "bus_i: a=" << a.bus_i << ", b=" << b.bus_i << "\n" + << "type: a=" << a.type << ", b=" << b.type << "\n" + << "Gs: a=" << a.Gs << ", b=" << b.Gs << "\n" + << "Bs: a=" << a.Bs << ", b=" << b.Bs << "\n" + << "area: a=" << a.area << ", b=" << b.area << "\n" + << "Vm: a=" << a.Vm << ", b=" << b.Vm << "\n" + << "Va: a=" << a.Va << ", b=" << b.Va << "\n" + << "baseKV: a=" << a.baseKV << ", b=" << b.baseKV << "\n" + << "zone: a=" << a.zone << ", b=" << b.zone << "\n" + << "Vmax: a=" << a.Vmax << ", b=" << b.Vmax << "\n" + << "Vmin: a=" << a.Vmin << ", b=" << b.Vmin << "\n"; + } + return fail == 0; + } + + template + inline bool isEqual(PowerSystemData::LoadData a, + PowerSystemData::LoadData b, + RealT tol = tol_) + { + int fail = 0; + + fail += a.bus_i != b.bus_i; + fail += !isEqual(a.Pd, b.Pd, tol); + fail += !isEqual(a.Qd, b.Qd, tol); + + if (fail) + { + errs() << "bus_i: a=" << a.bus_i << ", b=" << b.bus_i << "\n" + << "Pd: a=" << a.Pd << ", b=" << b.Pd << "\n" + << "Qd: a=" << a.Qd << ", b=" << b.Qd << "\n"; + } + return fail == 0; + } + + template + inline bool isEqual(PowerSystemData::BranchData a, + PowerSystemData::BranchData b, + RealT tol = tol_) + { + int fail = 0; + + fail += a.fbus != b.fbus; + fail += a.tbus != b.tbus; + fail += !isEqual(a.r, b.r, tol); + fail += !isEqual(a.x, b.x, tol); + fail += !isEqual(a.b, b.b, tol); + fail += a.rateA != b.rateA; + fail += a.rateB != b.rateB; + fail += a.rateC != b.rateC; + fail += a.ratio != b.ratio; + fail += a.angle != b.angle; + fail += a.status != b.status; + fail += a.angmin != b.angmin; + fail += a.angmax != b.angmax; + + if (fail) + { + errs() << "Got failure!\na=" << a.str() << "\nb=" << b.str(); + } + return fail == 0; + } + + template + 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(); - }()); + return errs.str(); }()); + + int fail = 0; + for (std::size_t i = 0; i < a.size(); i++) + { + if (!isEqual(a[i], b[i], tol)) + { + fail++; + errs() << "[isEqual>]: Got failure with i=" << i << ".\n"; + } + } - int fail = 0; - for (std::size_t i = 0; i < a.size(); i++) { - if (!isEqual(a[i], b[i], tol)) { - fail++; - errs() << "[isEqual>]: Got failure with i=" << i << ".\n"; + return fail == 0; } - } - return fail == 0; -} + template + inline bool isEqual(PowerSystemData::SystemModelData a, + PowerSystemData::SystemModelData b) + { + int fail = 0; -template -inline bool isEqual(PowerSystemData::SystemModelData a, - PowerSystemData::SystemModelData b) -{ - int fail = 0; - fail += a.version != b.version; - fail += a.baseMVA != b.baseMVA; - fail += !isEqual(a.bus, b.bus); - fail += !isEqual(a.gen, b.gen); - fail += !isEqual(a.gencost, b.gencost); - fail += !isEqual(a.branch, b.branch); - fail += !isEqual(a.load, b.load); - return fail == 0; -} + fail += a.version != b.version; + fail += a.baseMVA != b.baseMVA; + fail += !isEqual(a.bus, b.bus); + fail += !isEqual(a.gen, b.gen); + fail += !isEqual(a.gencost, b.gencost); + fail += !isEqual(a.branch, b.branch); + fail += !isEqual(a.load, b.load); + + return fail == 0; + } -} // namespace Testing + } // namespace Testing } // namespace GridKit diff --git a/tests/UnitTests/PhasorDynamics/BranchTests.hpp b/tests/UnitTests/PhasorDynamics/BranchTests.hpp index 103f7af1..81e2c48e 100644 --- a/tests/UnitTests/PhasorDynamics/BranchTests.hpp +++ b/tests/UnitTests/PhasorDynamics/BranchTests.hpp @@ -1,149 +1,145 @@ -#include #include +#include +#include #include #include -#include -#include #include +#include namespace GridKit { -namespace Testing -{ + namespace Testing + { - template + template class BranchTests { private: - using real_type = typename PhasorDynamics::Component::real_type; + using real_type = typename PhasorDynamics::Component::real_type; public: - BranchTests() = default; - ~BranchTests() = default; - - TestOutcome constructor() - { - TestStatus success = true; - - auto* bus1 = new PhasorDynamics::Bus(1.0, 0.0); - auto* bus2 = new PhasorDynamics::Bus(1.0, 0.1); - - PhasorDynamics::Component* branch = - new PhasorDynamics::Branch(bus1, bus2); - - success *= (branch != nullptr); + BranchTests() = default; + ~BranchTests() = default; - if (branch) - { - delete branch; - } - delete bus1; - delete bus2; - - return success.report(__func__); - } - - TestOutcome residual() - { - TestStatus success = true; - - real_type R{2.0}; ///< Branch series resistance - real_type X{4.0}; ///< Branch series reactance - real_type G{0.2}; ///< Branch shunt conductance - real_type B{1.2}; ///< Branch shunt charging - - ScalarT Vr1{10.0}; ///< Bus-1 real voltage - ScalarT Vi1{20.0}; ///< Bus-1 imaginary voltage - 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 + TestOutcome constructor() + { + TestStatus success = true; + auto* bus1 = new PhasorDynamics::Bus(1.0, 0.0); + auto* bus2 = new PhasorDynamics::Bus(1.0, 0.1); - PhasorDynamics::BusInfinite bus1(Vr1, Vi1); - PhasorDynamics::BusInfinite bus2(Vr2, Vi2); + PhasorDynamics::Component* branch = + new PhasorDynamics::Branch(bus1, bus2); - PhasorDynamics::Branch branch(&bus1, &bus2, R, X, G, B); - branch.evaluateResidual(); + success *= (branch != nullptr); - success *= isEqual(bus1.Ir(), Ir1); - success *= isEqual(bus1.Ii(), Ii1); - success *= isEqual(bus2.Ir(), Ir2); - success *= isEqual(bus2.Ii(), Ii2); - - return success.report(__func__); - } - - TestOutcome accessors() + if (branch) { - TestStatus success = true; - - const real_type zero{0.0}; - - real_type R{2.0}; ///< Branch series resistance - real_type X{4.0}; ///< Branch series reactance - real_type G{0.2}; ///< Branch shunt conductance - real_type B{1.2}; ///< Branch shunt charging - - ScalarT Vr1{-1.0}; ///< Bus-1 real voltage - ScalarT Vi1{-1.0}; ///< Bus-1 imaginary voltage - ScalarT Vr2{1.0}; ///< Bus-2 real voltage - ScalarT Vi2{1.0}; ///< Bus-2 imaginary voltage - - const ScalarT res_R{1.0}; ///< Solution: real current entering bus-1 - const ScalarT res_X{0.5}; ///< Solution: imaginary current entering bus-1 - const ScalarT res_G{3.0}; ///< Solution: real current entering bus-2 - const ScalarT res_B{-4.0}; ///< Solution: imaginary current entering bus-2 - - - PhasorDynamics::BusInfinite bus1(Vr1, Vi1); - PhasorDynamics::BusInfinite bus2(Vr2, Vi2); - - PhasorDynamics::Branch branch(&bus1, - &bus2, - zero, - zero, - zero, - zero); - - // Test setting branch series resistance - branch.setR(R); - bus1.evaluateResidual(); // <- set Ir1 to zero - branch.evaluateResidual(); - success *= isEqual(bus1.Ir(), res_R); - branch.setR(zero); - - // Test setting branch series reactance - branch.setX(X); - bus1.evaluateResidual(); // <- set Ir1 to zero - branch.evaluateResidual(); - success *= isEqual(bus1.Ir(), res_X); - branch.setX(zero); - return success.report(__func__); - - // Test setting branch shunt conductance - branch.setG(G); - bus1.evaluateResidual(); // <- set Ir1 to zero - branch.evaluateResidual(); - success *= isEqual(bus1.Ir(), res_G); - branch.setG(zero); - - // Test setting branch shunt charging - branch.setB(B); - bus1.evaluateResidual(); // <- set Ir1 to zero - branch.evaluateResidual(); - success *= isEqual(bus1.Ir(), res_B); - branch.setB(zero); - - return success.report(__func__); + delete branch; } + delete bus1; + delete bus2; + + return success.report(__func__); + } + + TestOutcome residual() + { + TestStatus success = true; + + real_type R{2.0}; ///< Branch series resistance + real_type X{4.0}; ///< Branch series reactance + real_type G{0.2}; ///< Branch shunt conductance + real_type B{1.2}; ///< Branch shunt charging + + ScalarT Vr1{10.0}; ///< Bus-1 real voltage + ScalarT Vi1{20.0}; ///< Bus-1 imaginary voltage + 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 + + PhasorDynamics::BusInfinite bus1(Vr1, Vi1); + PhasorDynamics::BusInfinite bus2(Vr2, Vi2); + + PhasorDynamics::Branch branch(&bus1, &bus2, R, X, G, B); + branch.evaluateResidual(); + + success *= isEqual(bus1.Ir(), Ir1); + success *= isEqual(bus1.Ii(), Ii1); + success *= isEqual(bus2.Ir(), Ir2); + success *= isEqual(bus2.Ii(), Ii2); + + return success.report(__func__); + } + + TestOutcome accessors() + { + TestStatus success = true; + + const real_type zero{0.0}; + + real_type R{2.0}; ///< Branch series resistance + real_type X{4.0}; ///< Branch series reactance + real_type G{0.2}; ///< Branch shunt conductance + real_type B{1.2}; ///< Branch shunt charging + + ScalarT Vr1{-1.0}; ///< Bus-1 real voltage + ScalarT Vi1{-1.0}; ///< Bus-1 imaginary voltage + ScalarT Vr2{1.0}; ///< Bus-2 real voltage + ScalarT Vi2{1.0}; ///< Bus-2 imaginary voltage + + const ScalarT res_R{1.0}; ///< Solution: real current entering bus-1 + const ScalarT res_X{0.5}; ///< Solution: imaginary current entering bus-1 + const ScalarT res_G{3.0}; ///< Solution: real current entering bus-2 + const ScalarT res_B{-4.0}; ///< Solution: imaginary current entering bus-2 + + PhasorDynamics::BusInfinite bus1(Vr1, Vi1); + PhasorDynamics::BusInfinite bus2(Vr2, Vi2); + + PhasorDynamics::Branch branch(&bus1, + &bus2, + zero, + zero, + zero, + zero); + + // Test setting branch series resistance + branch.setR(R); + bus1.evaluateResidual(); // <- set Ir1 to zero + branch.evaluateResidual(); + success *= isEqual(bus1.Ir(), res_R); + branch.setR(zero); + + // Test setting branch series reactance + branch.setX(X); + bus1.evaluateResidual(); // <- set Ir1 to zero + branch.evaluateResidual(); + success *= isEqual(bus1.Ir(), res_X); + branch.setX(zero); + return success.report(__func__); + + // Test setting branch shunt conductance + branch.setG(G); + bus1.evaluateResidual(); // <- set Ir1 to zero + branch.evaluateResidual(); + success *= isEqual(bus1.Ir(), res_G); + branch.setG(zero); + + // Test setting branch shunt charging + branch.setB(B); + bus1.evaluateResidual(); // <- set Ir1 to zero + branch.evaluateResidual(); + success *= isEqual(bus1.Ir(), res_B); + branch.setB(zero); + + return success.report(__func__); + } }; // class BranchTest -} // namespace Testing + } // namespace Testing } // namespace GridKit - - diff --git a/tests/UnitTests/PhasorDynamics/BusTests.hpp b/tests/UnitTests/PhasorDynamics/BusTests.hpp index a0ec744d..0ba50587 100644 --- a/tests/UnitTests/PhasorDynamics/BusTests.hpp +++ b/tests/UnitTests/PhasorDynamics/BusTests.hpp @@ -1,103 +1,101 @@ -#include #include +#include #include #include -#include #include - +#include namespace GridKit { -namespace Testing -{ - template + namespace Testing + { + template class BusTests { public: - BusTests() = default; - ~BusTests() = default; - - /// Constructor, allocation, and initialization checks - TestOutcome constructor() - { - TestStatus success = true; - - ScalarT Vr{1.0}; - ScalarT Vi{2.0}; - - PhasorDynamics::BusBase* bus = nullptr; - - // Create an infinite bus - bus = new PhasorDynamics::BusInfinite(); - success *= isEqual(bus->Vr(), 0.0); - success *= isEqual(bus->Vi(), 0.0); - delete bus; - - bus = new PhasorDynamics::BusInfinite(Vr, Vi); - success *= isEqual(bus->Vr(), Vr); - success *= isEqual(bus->Vi(), Vi); - delete bus; - - // Create an default bus - bus = new PhasorDynamics::Bus(); - bus->allocate(); - bus->initialize(); - success *= isEqual(bus->Vr(), 0.0); - success *= isEqual(bus->Vi(), 0.0); - delete bus; - - bus = new PhasorDynamics::Bus(Vr, Vi); - bus->allocate(); - bus->initialize(); - success *= isEqual(bus->Vr(), Vr); - success *= isEqual(bus->Vi(), Vi); - delete bus; - - bus = nullptr; - - return success.report(__func__); - } - - /// Accessor method tests - TestOutcome residual() - { - TestStatus success = true; - - ScalarT Vr{1.0}; - ScalarT Vi{2.0}; - ScalarT Ir{1.0}; - ScalarT Ii{2.0}; - - PhasorDynamics::BusInfinite bus_inf; - bus_inf.Ir() = Ir; - success *= isEqual(bus_inf.Ir(), Ir); - bus_inf.Ii() = Ii; - success *= isEqual(bus_inf.Ii(), Ii); - - bus_inf.evaluateResidual(); - success *= isEqual(bus_inf.Ir(), 0.0); - success *= isEqual(bus_inf.Ii(), 0.0); - - PhasorDynamics::Bus bus(Vr,Vi); - bus.allocate(); - bus.initialize(); - success *= isEqual(bus.Vr(), Vr); - success *= isEqual(bus.Vi(), Vi); - - bus.Ir() = Ir; - success *= isEqual(bus.Ir(), Ir); - bus.Ii() = Ii; - success *= isEqual(bus.Ii(), Ii); - - bus.evaluateResidual(); - success *= isEqual(bus.Ir(), 0.0); - success *= isEqual(bus.Ii(), 0.0); - - return success.report(__func__); - } - + BusTests() = default; + ~BusTests() = default; + + /// Constructor, allocation, and initialization checks + TestOutcome constructor() + { + TestStatus success = true; + + ScalarT Vr{1.0}; + ScalarT Vi{2.0}; + + PhasorDynamics::BusBase* bus = nullptr; + + // Create an infinite bus + bus = new PhasorDynamics::BusInfinite(); + success *= isEqual(bus->Vr(), 0.0); + success *= isEqual(bus->Vi(), 0.0); + delete bus; + + bus = new PhasorDynamics::BusInfinite(Vr, Vi); + success *= isEqual(bus->Vr(), Vr); + success *= isEqual(bus->Vi(), Vi); + delete bus; + + // Create an default bus + bus = new PhasorDynamics::Bus(); + bus->allocate(); + bus->initialize(); + success *= isEqual(bus->Vr(), 0.0); + success *= isEqual(bus->Vi(), 0.0); + delete bus; + + bus = new PhasorDynamics::Bus(Vr, Vi); + bus->allocate(); + bus->initialize(); + success *= isEqual(bus->Vr(), Vr); + success *= isEqual(bus->Vi(), Vi); + delete bus; + + bus = nullptr; + + return success.report(__func__); + } + + /// Accessor method tests + TestOutcome residual() + { + TestStatus success = true; + + ScalarT Vr{1.0}; + ScalarT Vi{2.0}; + ScalarT Ir{1.0}; + ScalarT Ii{2.0}; + + PhasorDynamics::BusInfinite bus_inf; + bus_inf.Ir() = Ir; + success *= isEqual(bus_inf.Ir(), Ir); + bus_inf.Ii() = Ii; + success *= isEqual(bus_inf.Ii(), Ii); + + bus_inf.evaluateResidual(); + success *= isEqual(bus_inf.Ir(), 0.0); + success *= isEqual(bus_inf.Ii(), 0.0); + + PhasorDynamics::Bus bus(Vr, Vi); + bus.allocate(); + bus.initialize(); + success *= isEqual(bus.Vr(), Vr); + success *= isEqual(bus.Vi(), Vi); + + bus.Ir() = Ir; + success *= isEqual(bus.Ir(), Ir); + bus.Ii() = Ii; + success *= isEqual(bus.Ii(), Ii); + + bus.evaluateResidual(); + success *= isEqual(bus.Ir(), 0.0); + success *= isEqual(bus.Ii(), 0.0); + + return success.report(__func__); + } }; -} // namespace Testing + } // namespace Testing } // namespace GridKit diff --git a/tests/UnitTests/PhasorDynamics/LoadTests.hpp b/tests/UnitTests/PhasorDynamics/LoadTests.hpp index ecda1301..7a9688bc 100644 --- a/tests/UnitTests/PhasorDynamics/LoadTests.hpp +++ b/tests/UnitTests/PhasorDynamics/LoadTests.hpp @@ -1,73 +1,71 @@ #pragma once -#include #include +#include #include #include #include -#include #include +#include namespace GridKit { -namespace Testing -{ + namespace Testing + { template class LoadTests { public: - using real_type = typename PhasorDynamics::Component::real_type; + using real_type = typename PhasorDynamics::Component::real_type; - LoadTests() = default; - ~LoadTests() = default; + LoadTests() = default; + ~LoadTests() = default; - TestOutcome constructor() - { - TestStatus success = true; - - auto* bus = new PhasorDynamics::Bus(1.0, 0.0); + TestOutcome constructor() + { + TestStatus success = true; - PhasorDynamics::Component* load = - new PhasorDynamics::Load(bus); + auto* bus = new PhasorDynamics::Bus(1.0, 0.0); - success *= (load != nullptr); + PhasorDynamics::Component* load = + new PhasorDynamics::Load(bus); - if (load) - { - delete load; - } - delete bus; + success *= (load != nullptr); - return success.report(__func__); + if (load) + { + delete load; } + delete bus; - TestOutcome residual() - { - TestStatus success = true; - - real_type R{2.0}; ///< Load resistance - real_type X{4.0}; ///< Load reactance + return success.report(__func__); + } - ScalarT Vr{10.0}; ///< Bus real voltage - ScalarT Vi{20.0}; ///< Bus imaginary voltage + TestOutcome residual() + { + TestStatus success = true; - const ScalarT Ir{3.0}; ///< Solution real current - const ScalarT Ii{-4.0}; ///< Solution imaginary current + real_type R{2.0}; ///< Load resistance + real_type X{4.0}; ///< Load reactance - PhasorDynamics::BusInfinite bus(Vr, Vi); + ScalarT Vr{10.0}; ///< Bus real voltage + ScalarT Vi{20.0}; ///< Bus imaginary voltage - PhasorDynamics::Load load(&bus, R, X); - load.evaluateResidual(); + const ScalarT Ir{3.0}; ///< Solution real current + const ScalarT Ii{-4.0}; ///< Solution imaginary current - success *= isEqual(bus.Ir(), Ir); - success *= isEqual(bus.Ii(), Ii); + PhasorDynamics::BusInfinite bus(Vr, Vi); - return success.report(__func__); - } - }; + PhasorDynamics::Load load(&bus, R, X); + load.evaluateResidual(); -} // namespace Testing -} // namespace GridKit + success *= isEqual(bus.Ir(), Ir); + success *= isEqual(bus.Ii(), Ii); + return success.report(__func__); + } + }; + } // namespace Testing +} // namespace GridKit diff --git a/tests/UnitTests/PhasorDynamics/SynchronousMachineTests.hpp b/tests/UnitTests/PhasorDynamics/SynchronousMachineTests.hpp index b266b182..fb100335 100644 --- a/tests/UnitTests/PhasorDynamics/SynchronousMachineTests.hpp +++ b/tests/UnitTests/PhasorDynamics/SynchronousMachineTests.hpp @@ -1,67 +1,63 @@ -#include #include +#include #include #include #include -#include #include +#include namespace GridKit { -namespace Testing -{ + namespace Testing + { - template + template class SynchronousMachineTests { private: - using real_type = typename PhasorDynamics::Component::real_type; + using real_type = typename PhasorDynamics::Component::real_type; public: - SynchronousMachineTests() = default; - ~SynchronousMachineTests() = default; + SynchronousMachineTests() = default; + ~SynchronousMachineTests() = default; - TestOutcome constructor() - { - TestStatus success = true; - - auto* bus = new PhasorDynamics::Bus(1.0, 0.0); + TestOutcome constructor() + { + TestStatus success = true; - PhasorDynamics::Component* machine = - new PhasorDynamics::SynchronousMachine(bus); + auto* bus = new PhasorDynamics::Bus(1.0, 0.0); - success *= (machine != nullptr); + PhasorDynamics::Component* machine = + new PhasorDynamics::SynchronousMachine(bus); - if (machine) - { - delete machine; - } - delete bus; + success *= (machine != nullptr); - return success.report(__func__); - } - - TestOutcome residual() + if (machine) { - TestStatus success = true; - success.skipTest(); + delete machine; + } + delete bus; + return success.report(__func__); + } - return success.report(__func__); - } + TestOutcome residual() + { + TestStatus success = true; + success.skipTest(); - TestOutcome accessors() - { - TestStatus success = true; - success.skipTest(); + return success.report(__func__); + } + TestOutcome accessors() + { + TestStatus success = true; + success.skipTest(); - return success.report(__func__); - } + return success.report(__func__); + } }; // class SynchronousMachineTest -} // namespace Testing + } // namespace Testing } // namespace GridKit - - diff --git a/tests/UnitTests/PhasorDynamics/SystemTests.hpp b/tests/UnitTests/PhasorDynamics/SystemTests.hpp index 01deb34d..ea1cf7f2 100644 --- a/tests/UnitTests/PhasorDynamics/SystemTests.hpp +++ b/tests/UnitTests/PhasorDynamics/SystemTests.hpp @@ -1,99 +1,97 @@ #pragma once -#include #include +#include +#include #include #include -#include #include -#include #include - +#include namespace GridKit { -namespace Testing -{ - template + namespace Testing + { + template class SystemTests { private: - using real_type = typename PhasorDynamics::Component::real_type; + using real_type = typename PhasorDynamics::Component::real_type; public: - SystemTests() = default; - ~SystemTests() = default; + SystemTests() = default; + ~SystemTests() = default; - /// Constructor, allocation, and initialization checks - TestOutcome constructor() - { - TestStatus success = true; + /// Constructor, allocation, and initialization checks + TestOutcome constructor() + { + TestStatus success = true; - // ScalarT Vr{1.0}; - // ScalarT Vi{2.0}; - - PhasorDynamics::SystemModel* system = nullptr; + // ScalarT Vr{1.0}; + // ScalarT Vi{2.0}; - // Create an empty system - system = new PhasorDynamics::SystemModel(); + PhasorDynamics::SystemModel* system = nullptr; - success *= (system != nullptr); + // Create an empty system + system = new PhasorDynamics::SystemModel(); - if (system) - { - delete system; - } + success *= (system != nullptr); - return success.report(__func__); + if (system) + { + delete system; } - TestOutcome composer() - { - TestStatus success = true; + return success.report(__func__); + } - real_type R{2.0}; ///< Branch series resistance - real_type X{4.0}; ///< Branch series reactance - real_type G{0.2}; ///< Branch shunt conductance - real_type B{1.2}; ///< Branch shunt charging + TestOutcome composer() + { + TestStatus success = true; - ScalarT Vr1{10.0}; ///< Bus-1 real voltage - ScalarT Vi1{20.0}; ///< Bus-1 imaginary voltage - ScalarT Vr2{30.0}; ///< Bus-2 real voltage - ScalarT Vi2{40.0}; ///< Bus-2 imaginary voltage + real_type R{2.0}; ///< Branch series resistance + real_type X{4.0}; ///< Branch series reactance + real_type G{0.2}; ///< Branch shunt conductance + real_type B{1.2}; ///< Branch shunt charging - 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 + ScalarT Vr1{10.0}; ///< Bus-1 real voltage + ScalarT Vi1{20.0}; ///< Bus-1 imaginary voltage + ScalarT Vr2{30.0}; ///< Bus-2 real voltage + ScalarT Vi2{40.0}; ///< Bus-2 imaginary voltage - // Create an empty system model - PhasorDynamics::SystemModel system; + 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 - // Add a bus - PhasorDynamics::BusInfinite bus1(Vr1, Vi1); - system.addBus(&bus1); + // Create an empty system model + PhasorDynamics::SystemModel system; - // Add a bus - PhasorDynamics::BusInfinite bus2(Vr2, Vi2); - system.addBus(&bus1); + // Add a bus + PhasorDynamics::BusInfinite bus1(Vr1, Vi1); + system.addBus(&bus1); - PhasorDynamics::Branch branch(&bus1, &bus2, R, X, G, B); - system.addComponent(&branch); + // Add a bus + PhasorDynamics::BusInfinite bus2(Vr2, Vi2); + system.addBus(&bus1); - system.allocate(); - system.initialize(); - system.evaluateResidual(); + PhasorDynamics::Branch branch(&bus1, &bus2, R, X, G, B); + system.addComponent(&branch); - success *= isEqual(bus1.Ir(), Ir1); - success *= isEqual(bus1.Ii(), Ii1); - success *= isEqual(bus2.Ir(), Ir2); - success *= isEqual(bus2.Ii(), Ii2); + system.allocate(); + system.initialize(); + system.evaluateResidual(); - return success.report(__func__); - } + success *= isEqual(bus1.Ir(), Ir1); + success *= isEqual(bus1.Ii(), Ii1); + success *= isEqual(bus2.Ir(), Ir2); + success *= isEqual(bus2.Ii(), Ii2); + return success.report(__func__); + } }; -} // namespace Testing + } // namespace Testing } // namespace GridKit diff --git a/tests/UnitTests/PhasorDynamics/runBranchTests.cpp b/tests/UnitTests/PhasorDynamics/runBranchTests.cpp index ea809536..b1d99b4c 100644 --- a/tests/UnitTests/PhasorDynamics/runBranchTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runBranchTests.cpp @@ -2,15 +2,15 @@ int main() { - using namespace GridKit; - using namespace GridKit::Testing; + using namespace GridKit; + using namespace GridKit::Testing; - GridKit::Testing::TestingResults result; - GridKit::Testing::BranchTests test; + GridKit::Testing::TestingResults result; + GridKit::Testing::BranchTests test; - result += test.constructor(); - result += test.accessors(); - result += test.residual(); + result += test.constructor(); + result += test.accessors(); + result += test.residual(); - return result.summary(); + return result.summary(); } \ No newline at end of file diff --git a/tests/UnitTests/PhasorDynamics/runBusTests.cpp b/tests/UnitTests/PhasorDynamics/runBusTests.cpp index 0c172ae0..27983152 100644 --- a/tests/UnitTests/PhasorDynamics/runBusTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runBusTests.cpp @@ -2,14 +2,14 @@ int main() { - using namespace GridKit; - using namespace GridKit::Testing; + using namespace GridKit; + using namespace GridKit::Testing; - GridKit::Testing::TestingResults result; - GridKit::Testing::BusTests test; + GridKit::Testing::TestingResults result; + GridKit::Testing::BusTests test; - result += test.constructor(); - result += test.residual(); + result += test.constructor(); + result += test.residual(); - return result.summary(); + return result.summary(); } \ No newline at end of file diff --git a/tests/UnitTests/PhasorDynamics/runLoadTests.cpp b/tests/UnitTests/PhasorDynamics/runLoadTests.cpp index 47109985..79ee7b0b 100644 --- a/tests/UnitTests/PhasorDynamics/runLoadTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runLoadTests.cpp @@ -2,14 +2,14 @@ int main() { - using namespace GridKit; - using namespace GridKit::Testing; + using namespace GridKit; + using namespace GridKit::Testing; - GridKit::Testing::TestingResults result; - GridKit::Testing::LoadTests test; + GridKit::Testing::TestingResults result; + GridKit::Testing::LoadTests test; - result += test.constructor(); - result += test.residual(); + result += test.constructor(); + result += test.residual(); - return result.summary(); + return result.summary(); } \ No newline at end of file diff --git a/tests/UnitTests/PhasorDynamics/runSynchronousMachineTests.cpp b/tests/UnitTests/PhasorDynamics/runSynchronousMachineTests.cpp index e2da3b4f..081d11df 100644 --- a/tests/UnitTests/PhasorDynamics/runSynchronousMachineTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runSynchronousMachineTests.cpp @@ -2,15 +2,15 @@ int main() { - using namespace GridKit; - using namespace GridKit::Testing; + using namespace GridKit; + using namespace GridKit::Testing; - GridKit::Testing::TestingResults result; - GridKit::Testing::SynchronousMachineTests test; + GridKit::Testing::TestingResults result; + GridKit::Testing::SynchronousMachineTests test; - result += test.constructor(); - result += test.accessors(); - result += test.residual(); + result += test.constructor(); + result += test.accessors(); + result += test.residual(); - return result.summary(); + return result.summary(); } \ No newline at end of file diff --git a/tests/UnitTests/PhasorDynamics/runSystemTests.cpp b/tests/UnitTests/PhasorDynamics/runSystemTests.cpp index be0335de..db74963a 100644 --- a/tests/UnitTests/PhasorDynamics/runSystemTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runSystemTests.cpp @@ -2,14 +2,14 @@ int main() { - using namespace GridKit; - using namespace GridKit::Testing; + using namespace GridKit; + using namespace GridKit::Testing; - GridKit::Testing::TestingResults result; - GridKit::Testing::SystemTests test; + GridKit::Testing::TestingResults result; + GridKit::Testing::SystemTests test; - result += test.constructor(); - result += test.composer(); + result += test.constructor(); + result += test.composer(); - return result.summary(); + return result.summary(); } \ No newline at end of file diff --git a/tests/UnitTests/SparsityPattern/SparsityPatternTests.hpp b/tests/UnitTests/SparsityPattern/SparsityPatternTests.hpp index f05dba2e..c836f961 100644 --- a/tests/UnitTests/SparsityPattern/SparsityPatternTests.hpp +++ b/tests/UnitTests/SparsityPattern/SparsityPatternTests.hpp @@ -1,87 +1,88 @@ -#include #include +#include #include -#include #include - +#include namespace GridKit { -namespace Testing -{ - template + namespace Testing + { + template class SparsityPatternTests { public: - SparsityPatternTests() = default; - ~SparsityPatternTests() = default; + SparsityPatternTests() = default; + ~SparsityPatternTests() = default; + + /// Constructor, allocation, and initialization checks + TestOutcome variable() + { + TestStatus success = true; + + const size_t n = 3; + std::vector x(n), p(n), f(n); + + // decide x, y, and z are variables + for (size_t i = 0; i < n; ++i) + x[i].setVariableNumber(i); + + // ...and sigma, rho, and beta are constant parameters + for (size_t i = 0; i < n; ++i) + p[i].setFixed(true); - /// Constructor, allocation, and initialization checks - TestOutcome variable() + // initialize independent variables + x[0]() = 8.0; + x[1]() = 20.0; + x[2]() = 2.0 / 3.0; + + // set constant parameter values + p[0] = 10.0; + p[1] = 8.0 / 3.0; + p[2] = 28.0; + + // The residualFunction computes f + residualFunction(f, x, p); + + // Check dependenices of f[0] (depends on x[0] and x[1]) { - TestStatus success = true; - - const size_t n = 3; - std::vector x(n), p(n), f(n); - - // decide x, y, and z are variables - for (size_t i = 0; i < n; ++i) - x[i].setVariableNumber(i); - - // ...and sigma, rho, and beta are constant parameters - for (size_t i = 0; i < n; ++i) - p[i].setFixed(true); - - // initialize independent variables - x[0]() = 8.0; x[1]() = 20.0; x[2]() = 2.0/3.0; - - // set constant parameter values - p[0] = 10.0; p[1] = 8.0/3.0; p[2] = 28.0; - - // The residualFunction computes f - residualFunction(f, x, p); - - // Check dependenices of f[0] (depends on x[0] and x[1]) - { - const Sparse::Variable::DependencyMap& dependencies = - (f[0]).getDependencies(); - - success *= (dependencies.size() == 2); - success *= (dependencies.find(0) != dependencies.end()); - success *= (dependencies.find(1) != dependencies.end()); - success *= (dependencies.find(2) == dependencies.end()); - } - - // Check dependencies of f[2] (depends on x[0], x[1], x[2]) - { - const Sparse::Variable::DependencyMap& dependencies = - (f[2]).getDependencies(); - - success *= (dependencies.size() == 3); - success *= (dependencies.find(0) != dependencies.end()); - success *= (dependencies.find(1) != dependencies.end()); - success *= (dependencies.find(2) != dependencies.end()); - } - - return success.report(__func__); + const Sparse::Variable::DependencyMap& dependencies = + (f[0]).getDependencies(); + + success *= (dependencies.size() == 2); + success *= (dependencies.find(0) != dependencies.end()); + success *= (dependencies.find(1) != dependencies.end()); + success *= (dependencies.find(2) == dependencies.end()); } - private: - template - void residualFunction(std::vector& f, - const std::vector& x, - const std::vector& p) - { - const T u = x[0]*x[1]; - - f[0] = p[0]*(x[1] - x[0]); // sigma*(y - x) - f[1] = x[0]*(p[1] - x[2]) - x[1]; // x*(rho - z) - y - f[2] = u - p[2]*x[2]; // x*y - beta*z - } - + // Check dependencies of f[2] (depends on x[0], x[1], x[2]) + { + const Sparse::Variable::DependencyMap& dependencies = + (f[2]).getDependencies(); + + success *= (dependencies.size() == 3); + success *= (dependencies.find(0) != dependencies.end()); + success *= (dependencies.find(1) != dependencies.end()); + success *= (dependencies.find(2) != dependencies.end()); + } + + return success.report(__func__); + } + + private: + template + void residualFunction(std::vector& f, + const std::vector& x, + const std::vector& p) + { + const T u = x[0] * x[1]; + f[0] = p[0] * (x[1] - x[0]); // sigma*(y - x) + f[1] = x[0] * (p[1] - x[2]) - x[1]; // x*(rho - z) - y + f[2] = u - p[2] * x[2]; // x*y - beta*z + } }; -} // namespace Testing + } // namespace Testing } // namespace GridKit diff --git a/tests/UnitTests/SparsityPattern/runSparsityPatternTests.cpp b/tests/UnitTests/SparsityPattern/runSparsityPatternTests.cpp index 70273df2..0f2ddd93 100644 --- a/tests/UnitTests/SparsityPattern/runSparsityPatternTests.cpp +++ b/tests/UnitTests/SparsityPattern/runSparsityPatternTests.cpp @@ -2,13 +2,13 @@ int main() { - using namespace GridKit; - using namespace GridKit::Testing; + using namespace GridKit; + using namespace GridKit::Testing; - GridKit::Testing::TestingResults result; - GridKit::Testing::SparsityPatternTests test; + GridKit::Testing::TestingResults result; + GridKit::Testing::SparsityPatternTests test; - result += test.variable(); + result += test.variable(); - return result.summary(); + return result.summary(); } \ No newline at end of file From c00998f72fb78dfce012855c57b1799b0466c6fd Mon Sep 17 00:00:00 2001 From: pelesh Date: Tue, 4 Mar 2025 05:35:36 +0000 Subject: [PATCH 5/8] Apply pre-commmit fixes --- .clang-format | 2 +- .gitignore | 2 +- CONTRIBUTING.md | 1 - examples/AdjointSensitivity/CMakeLists.txt | 2 -- examples/Grid3Bus/3bus.mat | 2 +- examples/ParameterEstimation/lookup_table.hpp | 2 +- src/LinearAlgebra/DenseMatrix/CMakeLists.txt | 1 - src/LinearAlgebra/SparseMatrix/CMakeLists.txt | 1 - src/Model/CMakeLists.txt | 1 - .../PhasorDynamics/Branch/CMakeLists.txt | 1 - src/Model/PhasorDynamics/Bus/CMakeLists.txt | 1 - src/Model/PhasorDynamics/Exciter/README.md | 2 -- src/Model/PhasorDynamics/Load/CMakeLists.txt | 1 - src/Model/PhasorDynamics/Load/README.md | 1 - .../SynchronousMachine/CMakeLists.txt | 1 - .../SynchronousMachine/GENSALwS/README.md | 30 ------------------- src/Model/PowerElectronics/CMakeLists.txt | 2 +- .../PowerElectronics/Capacitor/CMakeLists.txt | 2 +- .../DistributedGenerator/CMakeLists.txt | 2 +- .../InductionMotor/CMakeLists.txt | 2 +- .../PowerElectronics/Inductor/CMakeLists.txt | 2 +- .../LinearTransformer/CMakeLists.txt | 2 +- .../MicrogridBusDQ/CMakeLists.txt | 2 +- .../MicrogridLine/CMakeLists.txt | 2 +- .../MicrogridLoad/CMakeLists.txt | 2 +- .../PowerElectronics/Resistor/CMakeLists.txt | 2 +- .../SynchronousMachine/CMakeLists.txt | 2 +- .../TransmissionLine/CMakeLists.txt | 2 +- .../VoltageSource/CMakeLists.txt | 2 +- src/Model/PowerFlow/Branch/CMakeLists.txt | 1 - src/Model/PowerFlow/Bus/BusFactory.hpp | 2 +- src/Model/PowerFlow/Bus/CMakeLists.txt | 1 - src/Model/PowerFlow/Generator/CMakeLists.txt | 1 - .../PowerFlow/Generator/GeneratorFactory.hpp | 2 +- src/Model/PowerFlow/Generator2/CMakeLists.txt | 1 - src/Model/PowerFlow/Generator2/Generator2.cpp | 2 +- src/Model/PowerFlow/Generator2/Generator2.hpp | 2 +- src/Model/PowerFlow/Generator4/CMakeLists.txt | 1 - .../Generator4Governor/CMakeLists.txt | 1 - .../PowerFlow/Generator4Param/CMakeLists.txt | 1 - src/Model/PowerFlow/Load/CMakeLists.txt | 1 - src/Model/PowerFlow/Load/README.md | 2 +- src/Model/PowerFlow/MiniGrid/CMakeLists.txt | 1 - src/Model/PowerFlow/ModelEvaluatorImpl.hpp | 2 +- src/Model/PowerFlow/SystemModel.hpp | 2 +- src/Model/PowerFlow/SystemModelPowerFlow.hpp | 2 +- src/Solver/Dynamic/CMakeLists.txt | 1 - src/Solver/Optimization/CMakeLists.txt | 1 - src/Solver/SteadyState/CMakeLists.txt | 1 - src/Utilities/CMakeLists.txt | 1 - .../PhasorDynamics/runBranchTests.cpp | 2 +- .../UnitTests/PhasorDynamics/runBusTests.cpp | 2 +- .../UnitTests/PhasorDynamics/runLoadTests.cpp | 2 +- .../runSynchronousMachineTests.cpp | 2 +- .../PhasorDynamics/runSystemTests.cpp | 2 +- .../runSparsityPatternTests.cpp | 2 +- 56 files changed, 31 insertions(+), 87 deletions(-) diff --git a/.clang-format b/.clang-format index c89dd8f7..2fcec4c5 100644 --- a/.clang-format +++ b/.clang-format @@ -69,4 +69,4 @@ IncludeCategories: - Regex: '.*' # Everything else Priority: 1 SortPriority: 0 - CaseSensitive: false \ No newline at end of file + CaseSensitive: false diff --git a/.gitignore b/.gitignore index 8a42cbb7..928aa52f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ .vscode/ *.DS_Store build/ -*.DS_Store \ No newline at end of file +*.DS_Store diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c9134cd6..c0f0ea77 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -321,4 +321,3 @@ class Matrix // No, class is outside GridKit namespace { // matrix code }; - diff --git a/examples/AdjointSensitivity/CMakeLists.txt b/examples/AdjointSensitivity/CMakeLists.txt index 18121888..af48723e 100644 --- a/examples/AdjointSensitivity/CMakeLists.txt +++ b/examples/AdjointSensitivity/CMakeLists.txt @@ -65,5 +65,3 @@ target_link_libraries(adjoint GRIDKIT::bus GRIDKIT::generator4 GRIDKIT::solvers_ install(TARGETS adjoint DESTINATION bin) add_test(NAME AdjointSens COMMAND $ ) - - diff --git a/examples/Grid3Bus/3bus.mat b/examples/Grid3Bus/3bus.mat index 4663eb33..cacc7955 100644 --- a/examples/Grid3Bus/3bus.mat +++ b/examples/Grid3Bus/3bus.mat @@ -44,4 +44,4 @@ mpc.gencost = [ 2 0 0 3 0 30 0; ]; -) \ No newline at end of file +) diff --git a/examples/ParameterEstimation/lookup_table.hpp b/examples/ParameterEstimation/lookup_table.hpp index ca694437..735f1db1 100644 --- a/examples/ParameterEstimation/lookup_table.hpp +++ b/examples/ParameterEstimation/lookup_table.hpp @@ -100,4 +100,4 @@ std::string lookup_table = 4.9 0.67312 0.99966 0.37728 1.0099 0.63087 0.7213 -0.12935 0.0043559 -0.016631 -0.00033208 -0.22427 -0.24786 4.95 0.66892 0.99991 0.37636 1.0099 0.62362 0.71433 -0.035255 0.0053896 -0.019197 0.000302 -0.060867 -0.025908 5 0.66968 1.0002 0.37545 1.0099 0.6249 0.71867 0.064531 0.0049577 -0.016122 0.00018828 0.10945 0.19374 -)"; \ No newline at end of file +)"; diff --git a/src/LinearAlgebra/DenseMatrix/CMakeLists.txt b/src/LinearAlgebra/DenseMatrix/CMakeLists.txt index 37eb294c..6b555da4 100644 --- a/src/LinearAlgebra/DenseMatrix/CMakeLists.txt +++ b/src/LinearAlgebra/DenseMatrix/CMakeLists.txt @@ -3,4 +3,3 @@ add_library(DenseMatrix INTERFACE) include_directories(DenseMatrix INTERFACE ${CMAKE_CURRENT_LIST_DIR}) add_library(GRIDKIT::DenseMatrix ALIAS DenseMatrix) - diff --git a/src/LinearAlgebra/SparseMatrix/CMakeLists.txt b/src/LinearAlgebra/SparseMatrix/CMakeLists.txt index ddb18548..e92b5d19 100644 --- a/src/LinearAlgebra/SparseMatrix/CMakeLists.txt +++ b/src/LinearAlgebra/SparseMatrix/CMakeLists.txt @@ -3,4 +3,3 @@ add_library(SparseMatrix INTERFACE) include_directories(SparseMatrix INTERFACE ${CMAKE_CURRENT_LIST_DIR}) add_library(GRIDKIT::SparseMatrix ALIAS SparseMatrix) - diff --git a/src/Model/CMakeLists.txt b/src/Model/CMakeLists.txt index 1d14a5ed..0631f71e 100644 --- a/src/Model/CMakeLists.txt +++ b/src/Model/CMakeLists.txt @@ -63,4 +63,3 @@ add_subdirectory(PhasorDynamics) add_subdirectory(PowerFlow) add_subdirectory(PowerElectronics) - diff --git a/src/Model/PhasorDynamics/Branch/CMakeLists.txt b/src/Model/PhasorDynamics/Branch/CMakeLists.txt index 71478c50..44523fbd 100644 --- a/src/Model/PhasorDynamics/Branch/CMakeLists.txt +++ b/src/Model/PhasorDynamics/Branch/CMakeLists.txt @@ -10,4 +10,3 @@ gridkit_add_library(phasor_dynamics_branch Branch.cpp OUTPUT_NAME gridkit_phasor_dynamics_branch) - diff --git a/src/Model/PhasorDynamics/Bus/CMakeLists.txt b/src/Model/PhasorDynamics/Bus/CMakeLists.txt index 636d4dd8..b11fe63a 100644 --- a/src/Model/PhasorDynamics/Bus/CMakeLists.txt +++ b/src/Model/PhasorDynamics/Bus/CMakeLists.txt @@ -10,4 +10,3 @@ gridkit_add_library(phasor_dynamics_bus BusInfinite.cpp OUTPUT_NAME gridkit_phasor_dynamics_bus) - diff --git a/src/Model/PhasorDynamics/Exciter/README.md b/src/Model/PhasorDynamics/Exciter/README.md index 9ba48ca1..79b743b3 100644 --- a/src/Model/PhasorDynamics/Exciter/README.md +++ b/src/Model/PhasorDynamics/Exciter/README.md @@ -107,5 +107,3 @@ V_{F}=0 ``` ```math x_{2_{0}}=-\dfrac{K_{F}}{T_{F1}}\dfrac{E_{FD}}{\omega} - - diff --git a/src/Model/PhasorDynamics/Load/CMakeLists.txt b/src/Model/PhasorDynamics/Load/CMakeLists.txt index bfcfa6d0..0f1659a7 100644 --- a/src/Model/PhasorDynamics/Load/CMakeLists.txt +++ b/src/Model/PhasorDynamics/Load/CMakeLists.txt @@ -10,4 +10,3 @@ gridkit_add_library(phasor_dynamics_load Load.cpp OUTPUT_NAME gridkit_phasor_dynamics_load) - diff --git a/src/Model/PhasorDynamics/Load/README.md b/src/Model/PhasorDynamics/Load/README.md index 90bb7f9f..24d2c13e 100644 --- a/src/Model/PhasorDynamics/Load/README.md +++ b/src/Model/PhasorDynamics/Load/README.md @@ -26,4 +26,3 @@ where ```math g = \frac{R}{R^2+X^2} ~~~\mathrm{and}~~~ b = \frac{-X}{R^2+X^2}. ``` - diff --git a/src/Model/PhasorDynamics/SynchronousMachine/CMakeLists.txt b/src/Model/PhasorDynamics/SynchronousMachine/CMakeLists.txt index 49216d88..f8239be4 100644 --- a/src/Model/PhasorDynamics/SynchronousMachine/CMakeLists.txt +++ b/src/Model/PhasorDynamics/SynchronousMachine/CMakeLists.txt @@ -10,4 +10,3 @@ gridkit_add_library(phasor_dynamics_synchronous_machine SynchronousMachine.cpp OUTPUT_NAME gridkit_phasor_dynamics_synchronous_machine) - diff --git a/src/Model/PhasorDynamics/SynchronousMachine/GENSALwS/README.md b/src/Model/PhasorDynamics/SynchronousMachine/GENSALwS/README.md index a234956b..4d4c8790 100644 --- a/src/Model/PhasorDynamics/SynchronousMachine/GENSALwS/README.md +++ b/src/Model/PhasorDynamics/SynchronousMachine/GENSALwS/README.md @@ -60,33 +60,3 @@ T''_{d0}\dfrac{d\psi'_{d}}{dt}=-\psi'_{d}-(X'_{d}-X_{l})I_{d}+E'_{q} ```math T''_{q0}\dfrac{d\psi''_{q}}{dt}=-\psi''_{q}-(X_{q}-X''_{q})I_{q} ``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Model/PowerElectronics/CMakeLists.txt b/src/Model/PowerElectronics/CMakeLists.txt index 2cfe97bc..d703d300 100644 --- a/src/Model/PowerElectronics/CMakeLists.txt +++ b/src/Model/PowerElectronics/CMakeLists.txt @@ -11,4 +11,4 @@ add_subdirectory(DistributedGenerator) add_subdirectory(TransmissionLine) add_subdirectory(MicrogridLoad) add_subdirectory(MicrogridLine) -add_subdirectory(MicrogridBusDQ) \ No newline at end of file +add_subdirectory(MicrogridBusDQ) diff --git a/src/Model/PowerElectronics/Capacitor/CMakeLists.txt b/src/Model/PowerElectronics/Capacitor/CMakeLists.txt index 2e05fad2..e91fcb5e 100644 --- a/src/Model/PowerElectronics/Capacitor/CMakeLists.txt +++ b/src/Model/PowerElectronics/Capacitor/CMakeLists.txt @@ -5,4 +5,4 @@ gridkit_add_library(power_elec_capacitor SOURCES Capacitor.cpp OUTPUT_NAME - gridkit_power_elec_capacitor) \ No newline at end of file + gridkit_power_elec_capacitor) diff --git a/src/Model/PowerElectronics/DistributedGenerator/CMakeLists.txt b/src/Model/PowerElectronics/DistributedGenerator/CMakeLists.txt index 3d4b805c..6d38d453 100644 --- a/src/Model/PowerElectronics/DistributedGenerator/CMakeLists.txt +++ b/src/Model/PowerElectronics/DistributedGenerator/CMakeLists.txt @@ -5,4 +5,4 @@ gridkit_add_library(power_elec_disgen SOURCES DistributedGenerator.cpp OUTPUT_NAME - gridkit_power_elec_disgen) \ No newline at end of file + gridkit_power_elec_disgen) diff --git a/src/Model/PowerElectronics/InductionMotor/CMakeLists.txt b/src/Model/PowerElectronics/InductionMotor/CMakeLists.txt index ce94553a..c9246583 100644 --- a/src/Model/PowerElectronics/InductionMotor/CMakeLists.txt +++ b/src/Model/PowerElectronics/InductionMotor/CMakeLists.txt @@ -5,4 +5,4 @@ gridkit_add_library(power_elec_inductionmotor SOURCES InductionMotor.cpp OUTPUT_NAME - gridkit_power_elec_inductionmotor) \ No newline at end of file + gridkit_power_elec_inductionmotor) diff --git a/src/Model/PowerElectronics/Inductor/CMakeLists.txt b/src/Model/PowerElectronics/Inductor/CMakeLists.txt index 3570a451..980fb86f 100644 --- a/src/Model/PowerElectronics/Inductor/CMakeLists.txt +++ b/src/Model/PowerElectronics/Inductor/CMakeLists.txt @@ -5,4 +5,4 @@ gridkit_add_library(power_elec_inductor SOURCES Inductor.cpp OUTPUT_NAME - gridkit_power_elec_inductor) \ No newline at end of file + gridkit_power_elec_inductor) diff --git a/src/Model/PowerElectronics/LinearTransformer/CMakeLists.txt b/src/Model/PowerElectronics/LinearTransformer/CMakeLists.txt index da1e7efb..d3e2c724 100644 --- a/src/Model/PowerElectronics/LinearTransformer/CMakeLists.txt +++ b/src/Model/PowerElectronics/LinearTransformer/CMakeLists.txt @@ -5,4 +5,4 @@ gridkit_add_library(power_elec_lineartrasnformer SOURCES LinearTransformer.cpp OUTPUT_NAME - gridkit_power_elec_lineartrasnformer) \ No newline at end of file + gridkit_power_elec_lineartrasnformer) diff --git a/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt b/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt index 21efbb7d..1ad57987 100644 --- a/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt +++ b/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt @@ -5,4 +5,4 @@ gridkit_add_library(power_elec_microbusdq SOURCES MicrogridBusDQ.cpp OUTPUT_NAME - gridkit_power_elec_microbusdq) \ No newline at end of file + gridkit_power_elec_microbusdq) diff --git a/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt b/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt index 3f422460..2f445785 100644 --- a/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt +++ b/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt @@ -5,4 +5,4 @@ gridkit_add_library(power_elec_microline SOURCES MicrogridLine.cpp OUTPUT_NAME - gridkit_power_elec_microline) \ No newline at end of file + gridkit_power_elec_microline) diff --git a/src/Model/PowerElectronics/MicrogridLoad/CMakeLists.txt b/src/Model/PowerElectronics/MicrogridLoad/CMakeLists.txt index 7f9eaf67..b17a875c 100644 --- a/src/Model/PowerElectronics/MicrogridLoad/CMakeLists.txt +++ b/src/Model/PowerElectronics/MicrogridLoad/CMakeLists.txt @@ -5,4 +5,4 @@ gridkit_add_library(power_elec_microload SOURCES MicrogridLoad.cpp OUTPUT_NAME - gridkit_power_elec_microload) \ No newline at end of file + gridkit_power_elec_microload) diff --git a/src/Model/PowerElectronics/Resistor/CMakeLists.txt b/src/Model/PowerElectronics/Resistor/CMakeLists.txt index 757597a6..3721b387 100644 --- a/src/Model/PowerElectronics/Resistor/CMakeLists.txt +++ b/src/Model/PowerElectronics/Resistor/CMakeLists.txt @@ -5,4 +5,4 @@ gridkit_add_library(power_elec_resistor SOURCES Resistor.cpp OUTPUT_NAME - gridkit_power_elec_resistor) \ No newline at end of file + gridkit_power_elec_resistor) diff --git a/src/Model/PowerElectronics/SynchronousMachine/CMakeLists.txt b/src/Model/PowerElectronics/SynchronousMachine/CMakeLists.txt index c42816d9..ff492047 100644 --- a/src/Model/PowerElectronics/SynchronousMachine/CMakeLists.txt +++ b/src/Model/PowerElectronics/SynchronousMachine/CMakeLists.txt @@ -5,4 +5,4 @@ gridkit_add_library(power_elec_synmachine SOURCES SynchronousMachine.cpp OUTPUT_NAME - gridkit_power_elec_synmachine) \ No newline at end of file + gridkit_power_elec_synmachine) diff --git a/src/Model/PowerElectronics/TransmissionLine/CMakeLists.txt b/src/Model/PowerElectronics/TransmissionLine/CMakeLists.txt index c80b3b6d..f8e76a1d 100644 --- a/src/Model/PowerElectronics/TransmissionLine/CMakeLists.txt +++ b/src/Model/PowerElectronics/TransmissionLine/CMakeLists.txt @@ -5,4 +5,4 @@ gridkit_add_library(power_elec_tranline SOURCES TransmissionLine.cpp OUTPUT_NAME - gridkit_power_elec_tranline) \ No newline at end of file + gridkit_power_elec_tranline) diff --git a/src/Model/PowerElectronics/VoltageSource/CMakeLists.txt b/src/Model/PowerElectronics/VoltageSource/CMakeLists.txt index 4fc50474..129da3bb 100644 --- a/src/Model/PowerElectronics/VoltageSource/CMakeLists.txt +++ b/src/Model/PowerElectronics/VoltageSource/CMakeLists.txt @@ -5,4 +5,4 @@ gridkit_add_library(power_elec_voltagesource SOURCES VoltageSource.cpp OUTPUT_NAME - gridkit_power_elec_voltagesource) \ No newline at end of file + gridkit_power_elec_voltagesource) diff --git a/src/Model/PowerFlow/Branch/CMakeLists.txt b/src/Model/PowerFlow/Branch/CMakeLists.txt index bd4ff42f..b3bb0604 100644 --- a/src/Model/PowerFlow/Branch/CMakeLists.txt +++ b/src/Model/PowerFlow/Branch/CMakeLists.txt @@ -65,4 +65,3 @@ gridkit_add_library(branch Branch.cpp OUTPUT_NAME gridkit_branch) - diff --git a/src/Model/PowerFlow/Bus/BusFactory.hpp b/src/Model/PowerFlow/Bus/BusFactory.hpp index f9b62f7d..9661f82c 100644 --- a/src/Model/PowerFlow/Bus/BusFactory.hpp +++ b/src/Model/PowerFlow/Bus/BusFactory.hpp @@ -98,4 +98,4 @@ namespace GridKit } }; -} // namespace GridKit \ No newline at end of file +} // namespace GridKit diff --git a/src/Model/PowerFlow/Bus/CMakeLists.txt b/src/Model/PowerFlow/Bus/CMakeLists.txt index c53ee677..53e4be33 100644 --- a/src/Model/PowerFlow/Bus/CMakeLists.txt +++ b/src/Model/PowerFlow/Bus/CMakeLists.txt @@ -67,4 +67,3 @@ gridkit_add_library(bus BusSlack.cpp OUTPUT_NAME gridkit_bus) - diff --git a/src/Model/PowerFlow/Generator/CMakeLists.txt b/src/Model/PowerFlow/Generator/CMakeLists.txt index a09c5aed..1f9a4423 100644 --- a/src/Model/PowerFlow/Generator/CMakeLists.txt +++ b/src/Model/PowerFlow/Generator/CMakeLists.txt @@ -67,4 +67,3 @@ gridkit_add_library(generator GeneratorPQ.cpp OUTPUT_NAME gridkit_generator) - diff --git a/src/Model/PowerFlow/Generator/GeneratorFactory.hpp b/src/Model/PowerFlow/Generator/GeneratorFactory.hpp index 7c6e5ba2..bfa1503a 100644 --- a/src/Model/PowerFlow/Generator/GeneratorFactory.hpp +++ b/src/Model/PowerFlow/Generator/GeneratorFactory.hpp @@ -99,4 +99,4 @@ namespace GridKit } }; -} // namespace GridKit \ No newline at end of file +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator2/CMakeLists.txt b/src/Model/PowerFlow/Generator2/CMakeLists.txt index a1fbc1d2..7767b22b 100644 --- a/src/Model/PowerFlow/Generator2/CMakeLists.txt +++ b/src/Model/PowerFlow/Generator2/CMakeLists.txt @@ -65,4 +65,3 @@ gridkit_add_library(generator2 Generator2.cpp OUTPUT_NAME gridkit_generator2) - diff --git a/src/Model/PowerFlow/Generator2/Generator2.cpp b/src/Model/PowerFlow/Generator2/Generator2.cpp index d482f486..c71cdff8 100644 --- a/src/Model/PowerFlow/Generator2/Generator2.cpp +++ b/src/Model/PowerFlow/Generator2/Generator2.cpp @@ -229,4 +229,4 @@ namespace GridKit template class Generator2; template class Generator2; -} // namespace GridKit \ No newline at end of file +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator2/Generator2.hpp b/src/Model/PowerFlow/Generator2/Generator2.hpp index 00be740b..c7caac5e 100644 --- a/src/Model/PowerFlow/Generator2/Generator2.hpp +++ b/src/Model/PowerFlow/Generator2/Generator2.hpp @@ -157,4 +157,4 @@ namespace GridKit bus_type* bus_; }; -} // namespace GridKit \ No newline at end of file +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator4/CMakeLists.txt b/src/Model/PowerFlow/Generator4/CMakeLists.txt index 527d4ab1..b0b02ebc 100644 --- a/src/Model/PowerFlow/Generator4/CMakeLists.txt +++ b/src/Model/PowerFlow/Generator4/CMakeLists.txt @@ -65,4 +65,3 @@ gridkit_add_library(generator4 Generator4.cpp OUTPUT_NAME gridkit_generator4) - diff --git a/src/Model/PowerFlow/Generator4Governor/CMakeLists.txt b/src/Model/PowerFlow/Generator4Governor/CMakeLists.txt index 24e2d9d2..096711b8 100644 --- a/src/Model/PowerFlow/Generator4Governor/CMakeLists.txt +++ b/src/Model/PowerFlow/Generator4Governor/CMakeLists.txt @@ -65,4 +65,3 @@ gridkit_add_library(generator4governor Generator4Governor.cpp OUTPUT_NAME gridkit_generator4governor) - diff --git a/src/Model/PowerFlow/Generator4Param/CMakeLists.txt b/src/Model/PowerFlow/Generator4Param/CMakeLists.txt index 457ebc40..2c87b718 100644 --- a/src/Model/PowerFlow/Generator4Param/CMakeLists.txt +++ b/src/Model/PowerFlow/Generator4Param/CMakeLists.txt @@ -65,4 +65,3 @@ gridkit_add_library(generator4param Generator4Param.cpp OUTPUT_NAME gridkit_generator4param) - diff --git a/src/Model/PowerFlow/Load/CMakeLists.txt b/src/Model/PowerFlow/Load/CMakeLists.txt index 46abf3a2..c57e81ef 100644 --- a/src/Model/PowerFlow/Load/CMakeLists.txt +++ b/src/Model/PowerFlow/Load/CMakeLists.txt @@ -65,4 +65,3 @@ gridkit_add_library(load Load.cpp OUTPUT_NAME gridkit_load) - diff --git a/src/Model/PowerFlow/Load/README.md b/src/Model/PowerFlow/Load/README.md index fa10a088..caa43996 100644 --- a/src/Model/PowerFlow/Load/README.md +++ b/src/Model/PowerFlow/Load/README.md @@ -29,4 +29,4 @@ Y_{SH}=G_{SH}+jB_{SH} ## Active -to be added \ No newline at end of file +to be added diff --git a/src/Model/PowerFlow/MiniGrid/CMakeLists.txt b/src/Model/PowerFlow/MiniGrid/CMakeLists.txt index c88608b5..8c6b2e68 100644 --- a/src/Model/PowerFlow/MiniGrid/CMakeLists.txt +++ b/src/Model/PowerFlow/MiniGrid/CMakeLists.txt @@ -65,4 +65,3 @@ gridkit_add_library(minigrid MiniGrid.cpp OUTPUT_NAME gridkit_minigrid) - diff --git a/src/Model/PowerFlow/ModelEvaluatorImpl.hpp b/src/Model/PowerFlow/ModelEvaluatorImpl.hpp index 3bd74117..48289ed0 100644 --- a/src/Model/PowerFlow/ModelEvaluatorImpl.hpp +++ b/src/Model/PowerFlow/ModelEvaluatorImpl.hpp @@ -318,4 +318,4 @@ namespace GridKit } // namespace GridKit -#endif // _MODEL_EVALUATOR_IMPL_HPP_ \ No newline at end of file +#endif // _MODEL_EVALUATOR_IMPL_HPP_ diff --git a/src/Model/PowerFlow/SystemModel.hpp b/src/Model/PowerFlow/SystemModel.hpp index b3e06dc7..bbeb4c7f 100644 --- a/src/Model/PowerFlow/SystemModel.hpp +++ b/src/Model/PowerFlow/SystemModel.hpp @@ -714,4 +714,4 @@ namespace GridKit } // namespace GridKit -#endif // _SYSTEM_MODEL_HPP_ \ No newline at end of file +#endif // _SYSTEM_MODEL_HPP_ diff --git a/src/Model/PowerFlow/SystemModelPowerFlow.hpp b/src/Model/PowerFlow/SystemModelPowerFlow.hpp index 738888a0..d113bd07 100644 --- a/src/Model/PowerFlow/SystemModelPowerFlow.hpp +++ b/src/Model/PowerFlow/SystemModelPowerFlow.hpp @@ -433,4 +433,4 @@ namespace GridKit }; // class SystemSteadyStateModel -} // namespace GridKit \ No newline at end of file +} // namespace GridKit diff --git a/src/Solver/Dynamic/CMakeLists.txt b/src/Solver/Dynamic/CMakeLists.txt index ab38756c..e202c1bd 100644 --- a/src/Solver/Dynamic/CMakeLists.txt +++ b/src/Solver/Dynamic/CMakeLists.txt @@ -69,4 +69,3 @@ gridkit_add_library(solvers_dyn PUBLIC SUNDIALS::sunlinsolklu OUTPUT_NAME gridkit_solvers_dyn) - diff --git a/src/Solver/Optimization/CMakeLists.txt b/src/Solver/Optimization/CMakeLists.txt index 756dfa57..d6693992 100644 --- a/src/Solver/Optimization/CMakeLists.txt +++ b/src/Solver/Optimization/CMakeLists.txt @@ -69,4 +69,3 @@ gridkit_add_library(solvers_opt PUBLIC GRIDKIT::solvers_dyn OUTPUT_NAME gridkit_solvers_opt) - diff --git a/src/Solver/SteadyState/CMakeLists.txt b/src/Solver/SteadyState/CMakeLists.txt index 3d71c5a1..e919cdfd 100644 --- a/src/Solver/SteadyState/CMakeLists.txt +++ b/src/Solver/SteadyState/CMakeLists.txt @@ -67,4 +67,3 @@ gridkit_add_library(solvers_steady PUBLIC SUNDIALS::kinsol OUTPUT_NAME gridkit_solvers_steady) - diff --git a/src/Utilities/CMakeLists.txt b/src/Utilities/CMakeLists.txt index aba0c614..3bd96fc9 100644 --- a/src/Utilities/CMakeLists.txt +++ b/src/Utilities/CMakeLists.txt @@ -2,4 +2,3 @@ add_library(Utilities INTERFACE) target_include_directories(Utilities INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) add_library(GRIDKIT::Utilities ALIAS Utilities) - diff --git a/tests/UnitTests/PhasorDynamics/runBranchTests.cpp b/tests/UnitTests/PhasorDynamics/runBranchTests.cpp index b1d99b4c..b70a39ff 100644 --- a/tests/UnitTests/PhasorDynamics/runBranchTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runBranchTests.cpp @@ -13,4 +13,4 @@ int main() result += test.residual(); return result.summary(); -} \ No newline at end of file +} diff --git a/tests/UnitTests/PhasorDynamics/runBusTests.cpp b/tests/UnitTests/PhasorDynamics/runBusTests.cpp index 27983152..c7063318 100644 --- a/tests/UnitTests/PhasorDynamics/runBusTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runBusTests.cpp @@ -12,4 +12,4 @@ int main() result += test.residual(); return result.summary(); -} \ No newline at end of file +} diff --git a/tests/UnitTests/PhasorDynamics/runLoadTests.cpp b/tests/UnitTests/PhasorDynamics/runLoadTests.cpp index 79ee7b0b..7ad3daf0 100644 --- a/tests/UnitTests/PhasorDynamics/runLoadTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runLoadTests.cpp @@ -12,4 +12,4 @@ int main() result += test.residual(); return result.summary(); -} \ No newline at end of file +} diff --git a/tests/UnitTests/PhasorDynamics/runSynchronousMachineTests.cpp b/tests/UnitTests/PhasorDynamics/runSynchronousMachineTests.cpp index 081d11df..f77e97db 100644 --- a/tests/UnitTests/PhasorDynamics/runSynchronousMachineTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runSynchronousMachineTests.cpp @@ -13,4 +13,4 @@ int main() result += test.residual(); return result.summary(); -} \ No newline at end of file +} diff --git a/tests/UnitTests/PhasorDynamics/runSystemTests.cpp b/tests/UnitTests/PhasorDynamics/runSystemTests.cpp index db74963a..25519f61 100644 --- a/tests/UnitTests/PhasorDynamics/runSystemTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runSystemTests.cpp @@ -12,4 +12,4 @@ int main() result += test.composer(); return result.summary(); -} \ No newline at end of file +} diff --git a/tests/UnitTests/SparsityPattern/runSparsityPatternTests.cpp b/tests/UnitTests/SparsityPattern/runSparsityPatternTests.cpp index 0f2ddd93..782148f2 100644 --- a/tests/UnitTests/SparsityPattern/runSparsityPatternTests.cpp +++ b/tests/UnitTests/SparsityPattern/runSparsityPatternTests.cpp @@ -11,4 +11,4 @@ int main() result += test.variable(); return result.summary(); -} \ No newline at end of file +} From 4ed11779d21d125f30df4cc4d8741199a59f91f1 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Mon, 3 Mar 2025 23:46:26 -0600 Subject: [PATCH 6/8] Fix bug in Branch and Load models. --- src/Model/PhasorDynamics/Branch/Branch.hpp | 2 +- src/Model/PhasorDynamics/Load/Load.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Model/PhasorDynamics/Branch/Branch.hpp b/src/Model/PhasorDynamics/Branch/Branch.hpp index 67ed8d31..9d6ac38d 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.hpp +++ b/src/Model/PhasorDynamics/Branch/Branch.hpp @@ -25,7 +25,7 @@ namespace GridKit namespace PhasorDynamics { template - class Bus; + class BusBase; } } // namespace GridKit diff --git a/src/Model/PhasorDynamics/Load/Load.hpp b/src/Model/PhasorDynamics/Load/Load.hpp index cc183028..d8535509 100644 --- a/src/Model/PhasorDynamics/Load/Load.hpp +++ b/src/Model/PhasorDynamics/Load/Load.hpp @@ -10,7 +10,7 @@ namespace GridKit namespace PhasorDynamics { template - class Bus; + class BusBase; } } // namespace GridKit From 616921cee3bca084d9f327ba4a89332c9cf36818 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Tue, 4 Mar 2025 10:36:15 -0600 Subject: [PATCH 7/8] Update contributing guidelines. --- CONTRIBUTING.md | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c0f0ea77..b1363ac5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,6 +30,25 @@ Each class should be implemented in a `*.cpp` and a `*.hpp` files with the same name. Files containing collection of standalone functions should have a descriptive name starting with lowercase character. +### Using `clang-format` + +Coding style rules are specified in `.clang-format` file in GridKit root +directory. Use +```shell +clang-format -i +``` +to make sure your code follows the style guidelines. + +### Line length + +Keep line length below 80 characters unless a longer line is needed for better +clarity of the code. If your line is longer than 90 characters, you are +probably doing something wrong. + +`clang-format` is configured so it does not enforce line length; that is +developer's responsibility. Break the long lineas at places where it will +improve readability of the code. Running `clang-format` after that will help +align the code properly in accordance with GridKit coding style. ### Local variables naming @@ -98,10 +117,10 @@ constants with long names, use underscores to separate words in the constant name. Use all caps (screaming snake case). ```c++ - constexpr double Pi = 3.1415; // No, the constant name should be all caps + constexpr double Pi = 3.1415; // No, use all caps for the constant name constexpr double SQRT_TWO = 1.4142 // Yes - constexpr double SQRTTWO_ = 1.4142 // No, there is a trailing underscore - constexpr double EXP = 2.7183 // Yes + constexpr double SQRTTWO = 1.4142 // No, the two words not separated by "_" + constexpr double EXP = 2.7183 // Yes ``` ### Pointers and references From 06f6f8e2a653ee4660dec1ef604e45164bd17ffa Mon Sep 17 00:00:00 2001 From: pelesh Date: Tue, 4 Mar 2025 23:25:26 -0500 Subject: [PATCH 8/8] [skip ci] Fix typo in CONTRIBUTING.md Co-authored-by: Nicholson Koukpaizan <72402802+nkoukpaizan@users.noreply.github.com> --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b1363ac5..3568ff24 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,7 +46,7 @@ clarity of the code. If your line is longer than 90 characters, you are probably doing something wrong. `clang-format` is configured so it does not enforce line length; that is -developer's responsibility. Break the long lineas at places where it will +developer's responsibility. Break the long lines at places where it will improve readability of the code. Running `clang-format` after that will help align the code properly in accordance with GridKit coding style.