diff --git a/.github/workflows/pre_commit.yaml b/.github/workflows/pre_commit.yaml new file mode 100644 index 000000000..653943dd0 --- /dev/null +++ b/.github/workflows/pre_commit.yaml @@ -0,0 +1,23 @@ +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/.gitignore b/.gitignore index 8a42cbb73..928aa52fa 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/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..eda93831a --- /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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fbba2cb6..e964a9d39 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,6 +150,7 @@ add_subdirectory(src) # Create examples and tests enable_testing() add_subdirectory(examples) +add_subdirectory(tests) export(EXPORT gridkit-targets FILE ${CMAKE_CURRENT_BINARY_DIR}/GridKitTargets.cmake) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a62f660c6..b06d1a8bd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -331,4 +331,4 @@ To help enforce the above code style guidelines, we use autoformatting provided VS Code users can use `clang-format` to automatically format their code by installing the [C/C++ Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) and using the `Format Document` command in the command palette with the file to be formatted open. As well, you can enabled the `editor.formatOnSave` option to auto-format any file when you save it. -Other users can use the [`git clang-format`](https://clang.llvm.org/docs/ClangFormat.html#git-integration) subcommand installed along with `clang-format` to auto-format all staged files. \ No newline at end of file +Other users can use the [`git clang-format`](https://clang.llvm.org/docs/ClangFormat.html#git-integration) subcommand installed along with `clang-format` to auto-format all staged files. diff --git a/cmake/FindEnzyme.cmake b/cmake/FindEnzyme.cmake index 21cec75f1..14420797e 100644 --- a/cmake/FindEnzyme.cmake +++ b/cmake/FindEnzyme.cmake @@ -64,78 +64,44 @@ User may set: Author(s): - Asher Mancinelli +- Nicholson Koukpaizan ]] -if(NOT ${CMAKE_C_COMPILER_ID} STREQUAL "Clang" OR NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") - message(FATAL_ERROR "Enzyme may only be enabled if building with Clang") -endif() +find_package(Enzyme REQUIRED CONFIG + PATHS + ${ENZYME_DIR} + ${ENZYME_DIR}/lib/cmake/Enzyme) +message(STATUS "Enzyme configuration found: ${Enzyme_CONFIG}") find_library(ENZYME_LLVM_PLUGIN_LIBRARY NAMES - LLVMEnzyme-19.so - LLVMEnzyme-18.so - LLVMEnzyme-17.so - LLVMEnzyme-16.so - LLVMEnzyme-15.so - LLVMEnzyme-14.so - LLVMEnzyme-13.so - LLVMEnzyme-12.so - LLVMEnzyme-11.so - LLVMEnzyme-10.so - LLVMEnzyme-9.so + LLVMEnzyme-${Enzyme_LLVM_VERSION_MAJOR}.so + LLVMEnzyme-${Enzyme_LLVM_VERSION_MAJOR}.dylib + LLVMEnzyme-${Enzyme_LLVM_VERSION_MAJOR}.dll PATHS - ${ENZYME_DIR} $ENV{ENZYME_DIR} - ENV LD_LIBRARY_PATH ENV DYLD_LIBRARY_PATH + ${ENZYME_DIR} + ENV LD_LIBRARY_PATH + ENV DYLD_LIBRARY_PATH PATH_SUFFIXES - lib64 lib) + lib64 lib + REQUIRED) +message(STATUS "Enzyme LLVM plugin library: ${ENZYME_LLVM_PLUGIN_LIBRARY}") -find_library(ENZYME_CLANG_PLUGIN_LIBRARY - NAMES - ClangEnzyme-19.so - ClangEnzyme-18.so - ClangEnzyme-17.so - ClangEnzyme-16.so - ClangEnzyme-15.so - ClangEnzyme-14.so - ClangEnzyme-13.so - ClangEnzyme-12.so - ClangEnzyme-11.so - ClangEnzyme-10.so - ClangEnzyme-9.so - PATHS - ${ENZYME_DIR} $ENV{ENZYME_DIR} - ENV LD_LIBRARY_PATH ENV DYLD_LIBRARY_PATH - PATH_SUFFIXES - lib64 lib) - -find_program(GRIDKIT_LLVM_LINK llvm-link) -find_program(GRIDKIT_OPT opt) - -if("${GRIDKIT_LLVM_LINK}" STREQUAL "GRIDKIT_LLVM_LINK-NOTFOUND") - message(FATAL_ERROR "Could not find llvm-link! Will not be able to build Enzyme targets.") -endif() - -if("${GRIDKIT_OPT}" STREQUAL "GRIDKIT_OPT-NOTFOUND") - message(FATAL_ERROR "Could not find opt! Will not be able to build Enzyme targets.") -endif() - -message(STATUS "${ENZYME_CLANG_PLUGIN_LIBRARY};${ENZYME_LLVM_PLUGIN_LIBRARY}") -if((NOT ${ENZYME_LLVM_PLUGIN_LIBRARY}) OR (NOT ${ENZYME_CLANG_PLUGIN_LIBRARY})) - set(ENZYME_CLANG_PLUGIN_LIBRARY CACHE FILEPATH "Path to Enzyme Clang plugin library") - set(ENZYME_LLVM_PLUGIN_LIBRARY CACHE FILEPATH "Path to Enzyme LLVM plugin library") - message(STATUS "Found Enzyme clang plugin: ${ENZYME_CLANG_PLUGIN_LIBRARY}") - message(STATUS "Found Enzyme LLVM plugin: ${ENZYME_LLVM_PLUGIN_LIBRARY}") - get_filename_component(ENZYME_LIBRARY_DIR ${ENZYME_CLANG_PLUGIN_LIBRARY} DIRECTORY CACHE "Enzyme library directory") -else() - message(FATAL_ERROR "Enzyme library not found!" - " Set ENZYME_DIR to Enzyme's installation prefix.") -endif() +find_program(GRIDKIT_LLVM_LINK llvm-link + PATHS ${Enzyme_LLVM_BINARY_DIR} + REQUIRED) +message(STATUS "llvm-link: ${GRIDKIT_LLVM_LINK}") + +find_program(GRIDKIT_OPT opt + PATHS ${Enzyme_LLVM_BINARY_DIR} + REQUIRED) +message(STATUS "opt: ${GRIDKIT_OPT}") macro(enzyme_add_executable) set(options) set(oneValueArgs NAME) - set(multiValueArgs SOURCES LINK_LIBRARIES) + set(multiValueArgs SOURCES LINK_LIBRARIES INCLUDE_DIRECTORIES) cmake_parse_arguments(enzyme_add_executable "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -145,14 +111,32 @@ macro(enzyme_add_executable) set(PHASE5 "${CMAKE_CURRENT_BINARY_DIR}/${enzyme_add_executable_NAME}") set(OBJS "") + set(includes "${enzyme_add_executable_INCLUDE_DIRECTORIES}") + + foreach(lib ${enzyme_add_executable_LINK_LIBRARIES}) + get_target_property(include ${lib} INCLUDE_DIRECTORIES) + set(includes "${includes}" ${include}) + + get_target_property(libsource ${lib} SOURCES) + string(FIND "${libsource}" "TARGET" found) + if(NOT(${found} EQUAL -1)) + list(APPEND LINKER_FLAGS "-Wl,${libsource}") + endif() + endforeach() + + foreach(dir ${includes}) + if(EXISTS ${dir}) + list(APPEND INCLUDE_COMPILER_LIST "-I${dir}") + endif() + endforeach() foreach(SRC ${enzyme_add_executable_SOURCES}) set(PHASE0 "${CMAKE_CURRENT_SOURCE_DIR}/${SRC}") set(PHASE1 "${CMAKE_CURRENT_BINARY_DIR}/${enzyme_add_executable_NAME}_${SRC}_compile.o") add_custom_command( - DEPENDS ${PHASE0} + DEPENDS ${PHASE0} OUTPUT ${PHASE1} - COMMAND ${CMAKE_CXX_COMPILER} -flto -c ${PHASE0} -O2 -fno-vectorize -ffast-math -fno-unroll-loops -o ${PHASE1} + COMMAND ${CMAKE_CXX_COMPILER} -flto -c ${PHASE0} ${INCLUDE_COMPILER_LIST} -O2 -fno-vectorize -ffast-math -fno-unroll-loops -o ${PHASE1} COMMENT "Compiling ${SRC} to object file for target ${enzyme_add_executable_NAME}" ) set(OBJS "${OBJS} ${PHASE1}") @@ -182,9 +166,9 @@ macro(enzyme_add_executable) ) add_custom_command( - DEPENDS ${PHASE4} + DEPENDS ${PHASE4} ${enzyme_add_executable_LINK_LIBRARIES} OUTPUT ${PHASE5} - COMMAND ${CMAKE_CXX_COMPILER} ${PHASE4} -o ${PHASE5} + COMMAND ${CMAKE_CXX_COMPILER} ${LINKER_FLAGS} ${PHASE4} -o ${PHASE5} ) add_custom_target( diff --git a/examples/AdjointSensitivity/AdjointSensitivity.cpp b/examples/AdjointSensitivity/AdjointSensitivity.cpp index 83e3890ef..0a7f4e253 100644 --- a/examples/AdjointSensitivity/AdjointSensitivity.cpp +++ b/examples/AdjointSensitivity/AdjointSensitivity.cpp @@ -57,13 +57,12 @@ * */ - -#include #include +#include #include #include -#include +#include #include #include @@ -79,7 +78,7 @@ */ int main() { - using namespace ModelLib; + using namespace GridKit; using namespace AnalysisManager::Sundials; using namespace AnalysisManager; using namespace GridKit::Testing; @@ -112,7 +111,6 @@ int main() idas->configureQuadrature(); idas->initializeQuadrature(); - idas->runSimulation(0.1, 2); idas->saveInitialCondition(); @@ -138,30 +136,29 @@ int main() std::cout << "\n\nCost of computing objective function:\n\n"; idas->printFinalStats(); - const double g1 = Q[0]; + const double g1 = Q[0]; const double eps = 2e-3; // Compute gradient of the objective function numerically - std::vector dGdp(model->size_opt()); + std::vector dGdp(model->sizeParams()); - for (unsigned i=0; isize_opt(); ++i) + for (unsigned i = 0; i < model->sizeParams(); ++i) { - model->param()[i] += eps; - 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]; - - // restore parameter to original value - model->param()[i] -= eps; - - // Evaluate dG/dp numerically - dGdp[i] = (g2 - g1)/eps; + model->param()[i] += eps; + 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]; + + // 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 @@ -185,15 +182,15 @@ int main() int retval = 0; std::cout << "\n\nComparison of numerical and adjoint results:\n\n"; double* neg_dGdp = idas->getAdjointIntegral(); - for (unsigned i=0; isize_opt(); ++i) + for (unsigned i = 0; i < model->sizeParams(); ++i) { - std::cout << "dG/dp" << i << " (numerical) = " << dGdp[i] << "\n"; + 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 (!isEqual(dGdp[i], -neg_dGdp[i], 10 * eps)) + --retval; } - if(retval < 0) + if (retval < 0) { std::cout << "The two results differ beyond solver tolerance!\n"; } diff --git a/examples/AdjointSensitivity/CMakeLists.txt b/examples/AdjointSensitivity/CMakeLists.txt index 18121888a..af48723e0 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/CMakeLists.txt b/examples/CMakeLists.txt index 5b75c689b..100de2338 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -56,7 +56,7 @@ # add_subdirectory(MatPowerTesting) -add_subdirectory(SparseTest) +add_subdirectory(LinearAlgebra) add_subdirectory(DistributedGeneratorTest) if(TARGET SUNDIALS::kinsol) diff --git a/examples/DistributedGeneratorTest/CMakeLists.txt b/examples/DistributedGeneratorTest/CMakeLists.txt index 41b124cb8..6ed544e93 100644 --- a/examples/DistributedGeneratorTest/CMakeLists.txt +++ b/examples/DistributedGeneratorTest/CMakeLists.txt @@ -3,9 +3,9 @@ add_executable(dgtest DGTest.cpp) -target_link_libraries(dgtest GRIDKIT::powerelec_disgen - GRIDKIT::powerelec_mircoline - GRIDKIT::powerelec_microload +target_link_libraries(dgtest GRIDKIT::power_elec_disgen + GRIDKIT::power_elec_microline + GRIDKIT::power_elec_microload GRIDKIT::solvers_dyn) add_test(NAME DistributedGeneratorTest COMMAND $) diff --git a/examples/DistributedGeneratorTest/DGTest.cpp b/examples/DistributedGeneratorTest/DGTest.cpp index 22903c609..7b016a2d0 100644 --- a/examples/DistributedGeneratorTest/DGTest.cpp +++ b/examples/DistributedGeneratorTest/DGTest.cpp @@ -1,85 +1,85 @@ -#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[]) { - - ModelLib::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; - ModelLib::DistributedGenerator *dg = new ModelLib::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 df24ad597..5d53ba512 100644 --- a/examples/DynamicConstrainedOpt/DynamicConstrainedOpt.cpp +++ b/examples/DynamicConstrainedOpt/DynamicConstrainedOpt.cpp @@ -57,24 +57,22 @@ * */ - -#include #include +#include +#include +#include #include #include -#include +#include #include - -#include -#include -#include #include +#include #include int main() { - using namespace ModelLib; + using namespace GridKit; using namespace AnalysisManager::Sundials; using namespace AnalysisManager; using namespace GridKit::Testing; @@ -114,7 +112,7 @@ int main() { gen->V() = 0.0; idas->runSimulation(t_clear, 2); - gen->V() = 1.0; + gen->V() = 1.0; gen->theta() = -0.01; idas->saveInitialCondition(); } @@ -131,13 +129,14 @@ int main() // Initialize the IpoptApplication and process the options Ipopt::ApplicationReturnStatus status; status = ipoptApp->Initialize(); - if (status != Ipopt::Solve_Succeeded) { + if (status != Ipopt::Solve_Succeeded) + { std::cout << "\n\n*** Initialization failed! ***\n\n"; return (int) status; } // Set solver tolerance - const double tol = 1e-4; + const double tol = 1e-4; // Configure Ipopt application ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); @@ -155,18 +154,19 @@ int main() status = ipoptApp->OptimizeTNLP(ipoptDynamicObjectiveInterface); std::cout << "\n\nProblem formulated as dynamic objective optimization ...\n"; - if (status == Ipopt::Solve_Succeeded) { + if (status == Ipopt::Solve_Succeeded) + { // Print result - std::cout << "\nSucess:\n The problem solved in " - << ipoptApp->Statistics()->IterationCount() << " iterations!\n" + 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"; + << " The final value of the objective function G(Pm) = " << ipoptApp->Statistics()->FinalObjective() + << "\n\n"; } // Store dynamic objective optimization results - double* results = new double[model->size_opt()]; - for(unsigned i=0; i size_opt(); ++i) + double* results = new double[model->sizeParams()]; + for (unsigned i = 0; i < model->sizeParams(); ++i) { results[i] = model->param()[i]; } @@ -177,34 +177,35 @@ int main() // 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) { + if (status == Ipopt::Solve_Succeeded) + { // Print result - std::cout << "\nSucess:\n The problem solved in " - << ipoptApp->Statistics()->IterationCount() << " iterations!\n" + 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"; + << " 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 size_opt(); ++i) + for (unsigned i = 0; i < model->sizeParams(); ++i) { - if(!isEqual(results[i], model->param()[i], 10*tol)) - --retval; + if (!isEqual(results[i], model->param()[i], 10 * tol)) + --retval; } - if(retval < 0) + if (retval < 0) { std::cout << "The two results differ beyond solver tolerance!\n"; } - delete [] results; + delete[] results; delete idas; delete model; return retval; diff --git a/examples/Enzyme/CMakeLists.txt b/examples/Enzyme/CMakeLists.txt index 794ec850c..f7ed45025 100644 --- a/examples/Enzyme/CMakeLists.txt +++ b/examples/Enzyme/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(Standalone) add_subdirectory(Library) +add_subdirectory(PowerElectronics) diff --git a/examples/Enzyme/Library/CMakeLists.txt b/examples/Enzyme/Library/CMakeLists.txt index 78566c983..6dec74892 100644 --- a/examples/Enzyme/Library/CMakeLists.txt +++ b/examples/Enzyme/Library/CMakeLists.txt @@ -1,4 +1,2 @@ -enzyme_add_executable(NAME EnzymeLibCheck SOURCES main.cpp library.cpp) -#install(TARGETS ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibCheck DESTINATION bin) - -add_test(NAME "EnzymeLibCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibCheck) +add_subdirectory(Scalar) +add_subdirectory(Vector) diff --git a/examples/Enzyme/Library/Scalar/CMakeLists.txt b/examples/Enzyme/Library/Scalar/CMakeLists.txt new file mode 100644 index 000000000..6dff430a6 --- /dev/null +++ b/examples/Enzyme/Library/Scalar/CMakeLists.txt @@ -0,0 +1,6 @@ +enzyme_add_executable( + NAME EnzymeLibScalarCheck + SOURCES EnzymeScalar.cpp ScalarModel.cpp +) + +add_test(NAME "EnzymeLibScalarCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibScalarCheck) diff --git a/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp b/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp new file mode 100644 index 000000000..140fe2f11 --- /dev/null +++ b/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp @@ -0,0 +1,33 @@ +#include +#include + +#include "ScalarModel.hpp" + +/** + * @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 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 new file mode 100644 index 000000000..354c630d3 --- /dev/null +++ b/examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp @@ -0,0 +1,16 @@ +#pragma once + +int enzyme_dup; +int enzyme_dupnoneed; +int enzyme_out; +int enzyme_const; + +template +return_type __enzyme_fwddiff(return_type*, int, T*...); + +template +return_type wrapper(T* obj) +{ + obj->evalFunction(); + return obj->getFunctionValue(); +} diff --git a/examples/Enzyme/Library/Scalar/ScalarModel.cpp b/examples/Enzyme/Library/Scalar/ScalarModel.cpp new file mode 100644 index 000000000..f2daec816 --- /dev/null +++ b/examples/Enzyme/Library/Scalar/ScalarModel.cpp @@ -0,0 +1,51 @@ +#include "ScalarModel.hpp" + +#include + +#include "EnzymeWrapper.hpp" + +ScalarModel::ScalarModel() +{ +} + +inline double ScalarModel::square(double x) +{ + return x * x; +} + +void ScalarModel::setVariable(double x) +{ + x_ = x; +} + +void ScalarModel::evalFunction() +{ + f_ = square(x_); +} + +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); +} + +double ScalarModel::getVariable() const +{ + return x_; +} + +double ScalarModel::getFunctionValue() const +{ + return f_; +} + +double ScalarModel::getDerivativeValue() const +{ + return df_dx_; +} + +ScalarModel::~ScalarModel() +{ +} diff --git a/examples/Enzyme/Library/Scalar/ScalarModel.hpp b/examples/Enzyme/Library/Scalar/ScalarModel.hpp new file mode 100644 index 000000000..61b47faaf --- /dev/null +++ b/examples/Enzyme/Library/Scalar/ScalarModel.hpp @@ -0,0 +1,22 @@ +#pragma once + +/** + * @brief Class providing methods to evaluate a function and its derivative. + * This is used to test automatic differentiation. + */ +class ScalarModel +{ +private: + 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(); +}; diff --git a/examples/Enzyme/Library/Vector/CMakeLists.txt b/examples/Enzyme/Library/Vector/CMakeLists.txt new file mode 100644 index 000000000..eda952de8 --- /dev/null +++ b/examples/Enzyme/Library/Vector/CMakeLists.txt @@ -0,0 +1,7 @@ +enzyme_add_executable( + NAME EnzymeLibVectorCheck + SOURCES EnzymeVector.cpp VectorModel.cpp + LINK_LIBRARIES GRIDKIT::DenseMatrix +) + +add_test(NAME "EnzymeLibVectorCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibVectorCheck) diff --git a/examples/Enzyme/Library/Vector/EnzymeVector.cpp b/examples/Enzyme/Library/Vector/EnzymeVector.cpp new file mode 100644 index 000000000..d709acec5 --- /dev/null +++ b/examples/Enzyme/Library/Vector/EnzymeVector.cpp @@ -0,0 +1,89 @@ +#include +#include + +#include "VectorModel.hpp" + +/** + * @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) +{ + return 2.0 * x; +} + +// Reference Jacobian +DenseMatrix dsquare_ref(std::vector x, std::vector y) +{ + DenseMatrix jac(x.size(), y.size()); + for (int idy = 0; idy < y.size(); ++idy) + { + for (int idx = 0; idx < x.size(); ++idx) + { + if (idx == idy) + jac.setValue(idx, idy, dsquare_ref_scalar(x[idx])); + } + } + return jac; +} + +int main() +{ + // 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(); + } + + // 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); + + // Check + int fail = 0; + bool verbose = true; + for (int idy = 0; idy < res.size(); ++idy) + { + 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) + { + 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"; + + // Cleanup + delete vector_model; + + return fail; +} diff --git a/examples/Enzyme/Library/Vector/EnzymeWrapper.hpp b/examples/Enzyme/Library/Vector/EnzymeWrapper.hpp new file mode 100644 index 000000000..96fd52b10 --- /dev/null +++ b/examples/Enzyme/Library/Vector/EnzymeWrapper.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +int enzyme_dup; +int enzyme_dupnoneed; +int enzyme_out; +int enzyme_const; + +template +std::vector __enzyme_fwddiff(std::vector*, int, T*, T*); + +template +std::vector wrapper(T* obj) +{ + obj->evalResidual(); + return obj->getResidual(); +} diff --git a/examples/Enzyme/Library/Vector/VectorModel.cpp b/examples/Enzyme/Library/Vector/VectorModel.cpp new file mode 100644 index 000000000..39a36f9ca --- /dev/null +++ b/examples/Enzyme/Library/Vector/VectorModel.cpp @@ -0,0 +1,81 @@ +#include "VectorModel.hpp" + +#include + +#include "EnzymeWrapper.hpp" + +VectorModel::VectorModel(int n) : x_(n), f_(n), df_dx_(n, n) +{ +} + +inline double VectorModel::square_scalar(double x) +{ + return x * x; +} + +void VectorModel::square(std::vector& x, std::vector& y) +{ + for (int idx = 0; idx < x.size(); ++idx) + { + y[idx] = this->square_scalar(x[idx]); + } +} + +void VectorModel::setVariable(std::vector x) +{ + for (int idx = 0; idx < x.size(); ++idx) + { + x_[idx] = x[idx]; + } +} + +void VectorModel::evalResidual() +{ + square(x_, f_); +} + +void VectorModel::evalJacobian() +{ + 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) + { + df_dx_.setValue(idx, idy, d_res[idx]); + } + } +} + +std::vector& VectorModel::getVariable() +{ + return x_; +} + +std::vector& VectorModel::getResidual() +{ + return f_; +} + +DenseMatrix& VectorModel::getJacobian() +{ + return df_dx_; +} + +VectorModel::~VectorModel() +{ +} diff --git a/examples/Enzyme/Library/Vector/VectorModel.hpp b/examples/Enzyme/Library/Vector/VectorModel.hpp new file mode 100644 index 000000000..faea8a2c7 --- /dev/null +++ b/examples/Enzyme/Library/Vector/VectorModel.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include + +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 +{ +private: + 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(); +}; diff --git a/examples/Enzyme/Library/library.cpp b/examples/Enzyme/Library/library.cpp deleted file mode 100644 index 6ff34da7a..000000000 --- a/examples/Enzyme/Library/library.cpp +++ /dev/null @@ -1,3 +0,0 @@ -double square(double x) { - return x * x; -} diff --git a/examples/Enzyme/Library/library.hpp b/examples/Enzyme/Library/library.hpp deleted file mode 100644 index b498a295b..000000000 --- a/examples/Enzyme/Library/library.hpp +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -double square(double x); diff --git a/examples/Enzyme/Library/main.cpp b/examples/Enzyme/Library/main.cpp deleted file mode 100644 index e0aef4ecd..000000000 --- a/examples/Enzyme/Library/main.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include -#include "library.hpp" - -double __enzyme_autodiff(double (*)(double), ...); - -int main() { - int fail = 0; - double sq = square(5.0); - double dsq = __enzyme_autodiff(square, 5.0); - - std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; - if (std::abs(dsq - 10.0) > std::numeric_limits::epsilon()) - { - fail++; - std::cout << "Result incorrect\n"; - } - std::cout << "Status: " << fail << "\n"; - return fail; -} diff --git a/examples/Enzyme/PowerElectronics/CMakeLists.txt b/examples/Enzyme/PowerElectronics/CMakeLists.txt new file mode 100644 index 000000000..a8e74e881 --- /dev/null +++ b/examples/Enzyme/PowerElectronics/CMakeLists.txt @@ -0,0 +1,7 @@ +enzyme_add_executable( + NAME EnzymePowerElectronicsCheck + SOURCES main.cpp + LINK_LIBRARIES GRIDKIT::DenseMatrix GRIDKIT::power_elec_disgen +) + +add_test(NAME "EnzymePowerElectronicsCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymePowerElectronicsCheck) diff --git a/examples/Enzyme/PowerElectronics/main.cpp b/examples/Enzyme/PowerElectronics/main.cpp new file mode 100644 index 000000000..aeb9aa5ea --- /dev/null +++ b/examples/Enzyme/PowerElectronics/main.cpp @@ -0,0 +1,195 @@ +#include +#include + +#include +#include +#include + +/** + * @brief Standalone example that computes the Jacobian associated with the + * residual function of DistributedGenerator. We compare the Jacobian obtained + * by automatic differentiation via Enzyme to the analytical Jacobian + * implemented witin GridKit. + * + * TODO: Move automatic differentiation inside GridKit and convert this into a unit test. + */ + +using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; +using SparseMatrix = COO_Matrix; +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*); + +// Copy from DistributedGenerator::evaluateResidual +// Need to find a way to differentiate the member function directly +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_; +} + +// Function that computes the Jacobian via automatic differentiation +template +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) + { + // 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]); + } + } +} + +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) + { + 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) + { + 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; +} diff --git a/examples/Enzyme/Standalone/CMakeLists.txt b/examples/Enzyme/Standalone/CMakeLists.txt index 919d755e0..fe41dc744 100644 --- a/examples/Enzyme/Standalone/CMakeLists.txt +++ b/examples/Enzyme/Standalone/CMakeLists.txt @@ -1,6 +1,13 @@ enzyme_add_executable( - NAME EnzymeStandaloneCheck - SOURCES main.cpp - ) + NAME EnzymeStandaloneScalarCheck + SOURCES EnzymeScalar.cpp +) -add_test(NAME "EnzymeStandaloneCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneCheck) +enzyme_add_executable( + NAME EnzymeStandaloneVectorCheck + SOURCES EnzymeVector.cpp + LINK_LIBRARIES GRIDKIT::DenseMatrix +) + +add_test(NAME "EnzymeStandaloneScalarCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneScalarCheck) +add_test(NAME "EnzymeStandaloneVectorCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneVectorCheck) diff --git a/examples/Enzyme/Standalone/EnzymeScalar.cpp b/examples/Enzyme/Standalone/EnzymeScalar.cpp new file mode 100644 index 000000000..83edd0533 --- /dev/null +++ b/examples/Enzyme/Standalone/EnzymeScalar.cpp @@ -0,0 +1,37 @@ +#include +#include + +/** + * @brief Standalone example that computes the derivative of a scalar function + * by automatic differentiation via Enzyme. + * + * TODO: Convert this into a unit test. + */ + +double square(double x) +{ + return x * x; +} + +double __enzyme_autodiff(double (*)(double), ...); + +double dsquare(double 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; +} diff --git a/examples/Enzyme/Standalone/EnzymeVector.cpp b/examples/Enzyme/Standalone/EnzymeVector.cpp new file mode 100644 index 000000000..a16735d85 --- /dev/null +++ b/examples/Enzyme/Standalone/EnzymeVector.cpp @@ -0,0 +1,129 @@ +#include +#include +#include + +#include + +/** + * @brief Standalone example that computes the Jacobian of a vector-valued function + * by automatic differentiation via Enzyme. + * + * TODO: Convert this into a unit test. + */ + +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) +{ + return x * x; +} + +inline double dsquare_ref_scalar(double x) +{ + return 2.0 * x; +} + +// Vector-valued function to differentiate +void square(std::vector x, std::vector& y) +{ + 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) +{ + for (int idy = 0; idy < y.size(); ++idy) + { + for (int idx = 0; idx < x.size(); ++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) +{ + 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) + { + 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)); + 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) + { + 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; +} diff --git a/examples/Enzyme/Standalone/main.cpp b/examples/Enzyme/Standalone/main.cpp deleted file mode 100644 index c9b81ef05..000000000 --- a/examples/Enzyme/Standalone/main.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include - -double square(double x) { - return x * x; -} - -double __enzyme_autodiff(double(*)(double), ...); -double dsquare(double x) { - return __enzyme_autodiff(square, x); -} - -double sq = square(5.0); -double dsq = dsquare(5.0); - -int main() -{ - int fail = 0; - std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; - if (std::abs(dsq - 10.0) > std::numeric_limits::epsilon()) - { - fail++; - std::cout << "Result incorrect\n"; - } - std::cout << "Status: " << fail << "\n"; - return fail; -} diff --git a/examples/GenConstLoad/GenConstLoad.cpp b/examples/GenConstLoad/GenConstLoad.cpp index 836b40cb8..d7a75a279 100644 --- a/examples/GenConstLoad/GenConstLoad.cpp +++ b/examples/GenConstLoad/GenConstLoad.cpp @@ -57,25 +57,23 @@ * */ - -#include #include +#include +#include +#include #include -#include #include +#include +#include #include -#include - -#include -#include -#include #include +#include #include int main() { - using namespace ModelLib; + using namespace GridKit; using namespace AnalysisManager::Sundials; using namespace AnalysisManager; using namespace GridKit::Testing; @@ -118,7 +116,7 @@ int main() idas->setIntegrationTime(t_init, t_final, 250); // Guess optimization parameter values - double T2 = 0.15; + double T2 = 0.15; double K = 16.0; // Create an instance of the IpoptApplication @@ -127,13 +125,14 @@ int main() // Initialize the IpoptApplication and process the options Ipopt::ApplicationReturnStatus status; status = ipoptApp->Initialize(); - if (status != Ipopt::Solve_Succeeded) { + if (status != Ipopt::Solve_Succeeded) + { std::cout << "\n\n*** Initialization failed! ***\n\n"; return (int) status; } // Set solver tolerance - const double tol = 1e-4; + const double tol = 1e-4; // Configure Ipopt application ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); @@ -151,29 +150,23 @@ int main() // Solve the problem status = ipoptApp->OptimizeTNLP(ipoptDynamicObjectiveInterface); - if (status == Ipopt::Solve_Succeeded) { + 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"; + 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; + int retval = isEqual(ipoptApp->Statistics()->FinalObjective(), 1239.0, 10 * tol) ? 0 : 1; - if(retval != 0) + if (retval != 0) { std::cout << "The two results differ beyond solver tolerance!\n"; } - delete idas; delete gen; delete load; diff --git a/examples/GenInfiniteBus/GenInfiniteBus.cpp b/examples/GenInfiniteBus/GenInfiniteBus.cpp index a215e26b6..636e65c2a 100644 --- a/examples/GenInfiniteBus/GenInfiniteBus.cpp +++ b/examples/GenInfiniteBus/GenInfiniteBus.cpp @@ -57,25 +57,22 @@ * */ - -#include #include +#include +#include +#include #include #include -#include +#include #include - -#include -#include -#include #include +#include #include - int main() { - using namespace ModelLib; + using namespace GridKit; using namespace AnalysisManager::Sundials; using namespace AnalysisManager; using namespace GridKit::Testing; @@ -93,7 +90,6 @@ int main() // allocate model components model->allocate(); - // Create numerical integrator and configure it for the generator model Ida* idas = new Ida(model); @@ -136,13 +132,14 @@ int main() // Initialize the IpoptApplication and process the options Ipopt::ApplicationReturnStatus status; status = ipoptApp->Initialize(); - if (status != Ipopt::Solve_Succeeded) { + if (status != Ipopt::Solve_Succeeded) + { std::cout << "\n\n*** Initialization failed! ***\n\n"; return (int) status; } // Set solver tolerance - const double tol = 1e-4; + const double tol = 1e-4; // Configure Ipopt application ipoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); @@ -161,10 +158,11 @@ int main() status = ipoptApp->OptimizeTNLP(ipoptDynamicObjectiveInterface); std::cout << "\n\nProblem formulated as dynamic objective optimiztion ...\n"; - if (status == Ipopt::Solve_Succeeded) { + if (status == Ipopt::Solve_Succeeded) + { // Print result - std::cout << "\nSucess:\n The problem solved in " - << ipoptApp->Statistics()->IterationCount() << " iterations!\n" + 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) = " @@ -176,8 +174,8 @@ int main() new IpoptInterface::DynamicConstraint(idas); // Store dynamic objective optimization results - double* results = new double[model->size_opt()]; - for(unsigned i=0; i size_opt(); ++i) + double* results = new double[model->sizeParams()]; + for (unsigned i = 0; i < model->sizeParams(); ++i) { results[i] = model->param()[i]; } @@ -190,10 +188,11 @@ int main() status = ipoptApp->OptimizeTNLP(ipoptDynamicConstraintInterface); std::cout << "\n\nProblem formulated as dynamic constraint optimiztion ...\n"; - if (status == Ipopt::Solve_Succeeded) { + if (status == Ipopt::Solve_Succeeded) + { // Print result - std::cout << "\nSucess:\n The problem solved in " - << ipoptApp->Statistics()->IterationCount() << " iterations!\n" + 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) = " @@ -202,18 +201,18 @@ int main() // Compare results of the two optimization methods int retval = 0; - for(unsigned i=0; i size_opt(); ++i) + for (unsigned i = 0; i < model->sizeParams(); ++i) { - if(!isEqual(results[i], model->param()[i], 100*tol)) - --retval; + if (!isEqual(results[i], model->param()[i], 100 * tol)) + --retval; } - if(retval < 0) + if (retval < 0) { std::cout << "The two results differ beyond solver tolerance!\n"; } - delete [] results; + delete[] results; delete idas; delete model; return 0; diff --git a/examples/Grid3Bus/3bus.mat b/examples/Grid3Bus/3bus.mat index 4663eb33c..cacc79555 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/Grid3Bus/Grid3BusSys.cpp b/examples/Grid3Bus/Grid3BusSys.cpp index 551869872..74065ed06 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,24 +132,23 @@ mpc.gencost = [ )"; - -using namespace ModelLib; +using namespace GridKit; using namespace AnalysisManager::Sundials; using namespace AnalysisManager; 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"; + std::cout << "\nSolving power flow for a 3-bus monolithic model ...\n\n"; // Create a 3-bus model MiniGrid* model = new MiniGrid(); @@ -170,48 +168,49 @@ int monolithicCase() // Compute solution kinsol->runSimulation(); // Print solution - double th2 = model->th2() * 180.0/M_PI; + double th2 = model->th2() * 180.0 / M_PI; double V2 = model->V2(); - double th3 = model->th3() * 180.0/M_PI; + 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 << " 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); + 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) + 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; + 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 + // 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); @@ -226,47 +225,47 @@ int parserCase() // setup simulation kinsol->configureSimulation(); - // initialize simulation with default initial guess + // 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; - + 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 << " 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); + 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) + 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; - + + 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"; @@ -277,65 +276,93 @@ int hardwiredCase() // 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; + 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 + + // 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; + 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; + 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; + 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; + 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); + 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); + 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); + 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; + 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; + 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); @@ -350,51 +377,50 @@ int hardwiredCase() // setup simulation kinsol->configureSimulation(); - // initialize simulation with default initial guess + // initialize simulation with default initial guess kinsol->getDefaultInitialCondition(); // Compute solution kinsol->runSimulation(); // Print solution - double th2 = bus2->theta() * 180.0/M_PI; + double th2 = bus2->theta() * 180.0 / M_PI; double V2 = bus2->V(); - double th3 = bus3->theta() * 180.0/M_PI; - + 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 << " 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); + 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) + 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; + delete kinsol; + kinsol = nullptr; + delete sysmodel; + sysmodel = nullptr; return retval2; } - int main() { - //return the results of each case + // return the results of each case int resolve = 0; - std::cout << std::string(32,'-') << std::endl; + std::cout << std::string(32, '-') << std::endl; resolve |= monolithicCase(); - std::cout << std::string(32,'-') << std::endl; + std::cout << std::string(32, '-') << std::endl; resolve |= parserCase(); - std::cout << std::string(32,'-') << std::endl; + std::cout << std::string(32, '-') << std::endl; resolve |= hardwiredCase(); if (resolve) @@ -405,7 +431,6 @@ int main() { std::cout << "Success!\n"; } - - + return resolve; } diff --git a/examples/Grid3Bus/README.md b/examples/Grid3Bus/README.md index b628ad426..31bd6f9bc 100644 --- a/examples/Grid3Bus/README.md +++ b/examples/Grid3Bus/README.md @@ -22,13 +22,13 @@ Problem variables are voltage magnitudes and phases; they are stored in bus obje **Bus 1**: Slack bus, does not store variables no residuals. Voltage and phase are set to $`V_1 \equiv 1`$p.u. and $`\theta_1 \equiv 0`$, respectively. -**Bus 2**: PQ bus, stores variables $`V_2, \theta_2`$ and residuals $`P_2, Q_2`$. Load $`P_{L2} = 2.5`$p.u., $`Q_{L2} = -j0.8`$p.u. is attached to it. From the equations for [branch](../../src/Model/PowerFlow/Branch/README.md) and [load](../../src/Model/PowerFlow/Load/README.md) components, we assemble Bus 2 residuals as: +**Bus 2**: PQ bus, stores variables $`V_2, \theta_2`$ and residuals $`P_2, Q_2`$. Load $`P_{L1} = 2.5`$p.u., $`Q_{L1} = -j0.8`$p.u. is attached to it. From the equations for [branch](../../src/Model/PowerFlow/Branch/README.md) and [load](../../src/Model/PowerFlow/Load/README.md) components, we assemble Bus 2 residuals as: ```math \begin{array}{rcll} -P_2 & = &-P_{L2} &~~~\mathrm{(load ~2)} \\ +P_2 & = &-P_{L1} &~~~\mathrm{(load ~2)} \\ &&+ b_{12}|V_1||V_2|\sin(\theta_2-\theta_1) &~~~\mathrm{(branch ~12)} \\ &&+ b_{23}|V_2||V_3|\sin(\theta_2-\theta_3) &~~~\mathrm{(branch ~23)} \\ -Q_2 & = & -Q_{L2} &~~~\mathrm{(load ~2)} \\ +Q_2 & = & -Q_{L1} &~~~\mathrm{(load ~2)} \\ &&+ b_{12}|V_2|^2 - b_{12}|V_1||V_2|\cos(\theta_2-\theta_1) &~~~\mathrm{(branch ~12)} \\ &&+ b_{23}|V_2|^2 - b_{23}|V_2||V_3|\cos(\theta_2-\theta_3) &~~~\mathrm{(branch ~23)} \end{array} diff --git a/examples/LinearAlgebra/CMakeLists.txt b/examples/LinearAlgebra/CMakeLists.txt new file mode 100644 index 000000000..553b0587e --- /dev/null +++ b/examples/LinearAlgebra/CMakeLists.txt @@ -0,0 +1,3 @@ + +add_subdirectory(SparseTest) +add_subdirectory(DenseTest) diff --git a/examples/LinearAlgebra/DenseTest/CMakeLists.txt b/examples/LinearAlgebra/DenseTest/CMakeLists.txt new file mode 100644 index 000000000..5d3bf7b5c --- /dev/null +++ b/examples/LinearAlgebra/DenseTest/CMakeLists.txt @@ -0,0 +1,6 @@ + +add_executable(densemattest DenseTest.cpp) +target_link_libraries(densemattest GRIDKIT::DenseMatrix) + +add_test(NAME DenseMatrixTest COMMAND $) +install(TARGETS densemattest RUNTIME DESTINATION bin) diff --git a/examples/LinearAlgebra/DenseTest/DenseTest.cpp b/examples/LinearAlgebra/DenseTest/DenseTest.cpp new file mode 100644 index 000000000..e774150b0 --- /dev/null +++ b/examples/LinearAlgebra/DenseTest/DenseTest.cpp @@ -0,0 +1,25 @@ + +#include + +int main() +{ + int fail = 0; + + 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) + { + for (size_t i = 0; i < m; ++i) + { + A.setValue(i, j, val); + val += 1.0; + } + } + A.printMatrix("Dense matrix test output"); + (A.getValuesCOO())->printMatrix(); + + return fail; +} diff --git a/examples/SparseTest/CMakeLists.txt b/examples/LinearAlgebra/SparseTest/CMakeLists.txt similarity index 100% rename from examples/SparseTest/CMakeLists.txt rename to examples/LinearAlgebra/SparseTest/CMakeLists.txt diff --git a/examples/SparseTest/SparseTest.cpp b/examples/LinearAlgebra/SparseTest/SparseTest.cpp similarity index 66% rename from examples/SparseTest/SparseTest.cpp rename to examples/LinearAlgebra/SparseTest/SparseTest.cpp index c7c07195d..f0196ffff 100644 --- a/examples/SparseTest/SparseTest.cpp +++ b/examples/LinearAlgebra/SparseTest/SparseTest.cpp @@ -1,24 +1,24 @@ -#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[]) { 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 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); + COO_Matrix A = COO_Matrix(x, y, val, m, n); std::vector valn(4); std::vector xn(4); @@ -31,13 +31,13 @@ int main(int argc, char const *argv[]) std::cout << valn[i] << "\n"; } - std::cout << "A:\n"; + std::cout << "A:\n"; A.printMatrix(); - 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::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 << "B:\n"; B.printMatrix(); @@ -50,22 +50,22 @@ int main(int argc, char const *argv[]) std::vector r; std::vector c; std::vector v; - std::tie(r,c,v) = A.getDataToCSR(); + std::tie(r, c, v) = A.setDataToCSR(); for (size_t i = 0; i < r.size() - 1; i++) { std::cout << r[i] << std::endl; - size_t rdiff = r[i+1] - r[i]; + 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 << 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}; + // 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()); @@ -77,18 +77,18 @@ int main(int argc, char const *argv[]) { if (r[i] != rtest[i]) { - failval--; + failval--; } } 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) + if (c[i] != ctest[i] || -1e-14 > vdiff || vdiff > 1e-14) { failval--; } } - + if (failval == 0) { std::cout << "Success!" << std::endl; diff --git a/examples/MatPowerTesting/test_parse_branch_row.cpp b/examples/MatPowerTesting/test_parse_branch_row.cpp index 8d87d9e82..b6ff14a56 100644 --- a/examples/MatPowerTesting/test_parse_branch_row.cpp +++ b/examples/MatPowerTesting/test_parse_branch_row.cpp @@ -1,15 +1,17 @@ +#include + #include #include #include -#include using namespace GridKit; using namespace GridKit::Testing; using namespace GridKit::PowerSystemData; -namespace { +namespace +{ -using IdxT = int; +using IdxT = int; using RealT = double; static const std::string matpower_data{ @@ -31,27 +33,28 @@ mpc.branch = [ } // namespace -int main(int argc, char **argv) { - int fail = 0; - std::vector> branch_answer{ - {1, 2, 0.00281, 0.0281, 0.00712, 400, 400, 400, 0, 0, 1, -360, 360}, - {1, 4, 0.00304, 0.0304, 0.00658, 0, 0, 0, 0, 0, 1, -360, 360}, - {1, 5, 0.00064, 0.0064, 0.03126, 0, 0, 0, 0, 0, 1, -360, 360}, - {2, 3, 0.00108, 0.0108, 0.01852, 0, 0, 0, 0, 0, 1, -360, 360}, - {3, 4, 0.00297, 0.0297, 0.00674, 0, 0, 0, 0, 0, 1, -360, 360}, - {4, 5, 0.00297, 0.0297, 0.00674, 240, 240, 240, 0, 0, 1, -360, 360}, - }; - SystemModelData mp; - - { - std::istringstream iss(matpower_data); - GridKit::readMatPower(mp, iss); - if (!isEqual(mp.branch, branch_answer)) - fail++; - std::cout << "After reading the branch component, fail == " << fail << "\n"; - } - - std::cout << "Tests " << (fail ? "FAILED" : "PASSED") << "\n"; - - return fail; +int main(int argc, char** argv) +{ + int fail = 0; + std::vector> branch_answer{ + {1, 2, 0.00281, 0.0281, 0.00712, 400, 400, 400, 0, 0, 1, -360, 360}, + {1, 4, 0.00304, 0.0304, 0.00658, 0, 0, 0, 0, 0, 1, -360, 360}, + {1, 5, 0.00064, 0.0064, 0.03126, 0, 0, 0, 0, 0, 1, -360, 360}, + {2, 3, 0.00108, 0.0108, 0.01852, 0, 0, 0, 0, 0, 1, -360, 360}, + {3, 4, 0.00297, 0.0297, 0.00674, 0, 0, 0, 0, 0, 1, -360, 360}, + {4, 5, 0.00297, 0.0297, 0.00674, 240, 240, 240, 0, 0, 1, -360, 360}, + }; + SystemModelData mp; + + { + std::istringstream iss(matpower_data); + GridKit::readMatPower(mp, iss); + if (!isEqual(mp.branch, branch_answer)) + fail++; + std::cout << "After reading the branch component, fail == " << fail << "\n"; + } + + std::cout << "Tests " << (fail ? "FAILED" : "PASSED") << "\n"; + + return fail; } diff --git a/examples/MatPowerTesting/test_parse_bus_row.cpp b/examples/MatPowerTesting/test_parse_bus_row.cpp index 38695c5fa..a8daf4090 100644 --- a/examples/MatPowerTesting/test_parse_bus_row.cpp +++ b/examples/MatPowerTesting/test_parse_bus_row.cpp @@ -1,15 +1,17 @@ +#include + #include #include #include -#include using namespace GridKit; using namespace GridKit::Testing; using namespace GridKit::PowerSystemData; -namespace { +namespace +{ -using IdxT = int; +using IdxT = int; using RealT = double; static const std::string matpower_data{ @@ -24,43 +26,46 @@ mpc.bus = [ ]; )"}; -} // namespace +} // namespace -int main(int argc, char** argv) { - int fail = 0; - std::vector> bus_answer{ - {1, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {2, 1, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {3, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {4, 3, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {5, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.9}, - }; +int main(int argc, char** argv) +{ + int fail = 0; + std::vector> bus_answer{ + {1, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {2, 1, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {3, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {4, 3, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {5, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.9}, + }; - std::vector> load_answer{ - {1, 0, 0}, - {2, 300, 98.61}, - {3, 300, 98.61}, - {4, 400, 131.47}, - {5, 0, 0}, - }; + std::vector> load_answer{ + {1, 0, 0}, + {2, 300, 98.61}, + {3, 300, 98.61}, + {4, 400, 131.47}, + {5, 0, 0}, + }; - { - SystemModelData mp; - std::istringstream iss(matpower_data); - GridKit::readMatPower(mp, iss); - if (!isEqual(mp.bus, bus_answer)) fail++; - std::cout << "After reading the bus component, fail == " << fail << "\n"; - } + { + SystemModelData mp; + std::istringstream iss(matpower_data); + GridKit::readMatPower(mp, iss); + if (!isEqual(mp.bus, bus_answer)) + fail++; + std::cout << "After reading the bus component, fail == " << fail << "\n"; + } - { - SystemModelData mp; - std::istringstream iss(matpower_data); - GridKit::readMatPower(mp, iss); - if (!isEqual(mp.load, load_answer)) fail++; - std::cout << "After reading the bus component, fail == " << fail << "\n"; - } + { + SystemModelData mp; + std::istringstream iss(matpower_data); + GridKit::readMatPower(mp, iss); + 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; + return fail; } diff --git a/examples/MatPowerTesting/test_parse_gen_row.cpp b/examples/MatPowerTesting/test_parse_gen_row.cpp index b524ae899..328405a4c 100644 --- a/examples/MatPowerTesting/test_parse_gen_row.cpp +++ b/examples/MatPowerTesting/test_parse_gen_row.cpp @@ -1,15 +1,17 @@ +#include + #include #include #include -#include using namespace GridKit; using namespace GridKit::Testing; using namespace GridKit::PowerSystemData; -namespace { +namespace +{ -using IdxT = int; +using IdxT = int; using RealT = double; static const std::string matpower_data{ @@ -28,28 +30,26 @@ mpc.gen = [ } // namespace -int main(int argc, char **argv) { - int fail = 0; - std::vector> gen_answer{ - {1, 40, 0, 30, -30, 1, 100, 1, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 170, 0, 127.5, -127.5, 1, 100, 1, 170, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 323.49, 0, 390, -390, 1, 100, 1, 520, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 0, 0, 150, -150, 1, 100, 1, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {5, 466.51, 0, 450, -450, 1, 100, 1, 600, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; - SystemModelData mp; - - { - std::istringstream iss(matpower_data); - GridKit::readMatPower(mp, iss); - if (!isEqual(mp.gen, gen_answer)) - fail++; - std::cout << "After reading the gen component, fail == " << fail << "\n"; - } - - std::cout << "Tests " << (fail ? "FAILED" : "PASSED") << "\n"; - - return fail; +int main(int argc, char** argv) +{ + int fail = 0; + std::vector> gen_answer{ + {1, 40, 0, 30, -30, 1, 100, 1, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 170, 0, 127.5, -127.5, 1, 100, 1, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 323.49, 0, 390, -390, 1, 100, 1, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 0, 150, -150, 1, 100, 1, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {5, 466.51, 0, 450, -450, 1, 100, 1, 600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + SystemModelData mp; + + { + std::istringstream iss(matpower_data); + GridKit::readMatPower(mp, iss); + if (!isEqual(mp.gen, gen_answer)) + fail++; + std::cout << "After reading the gen component, fail == " << fail << "\n"; + } + + std::cout << "Tests " << (fail ? "FAILED" : "PASSED") << "\n"; + + return fail; } diff --git a/examples/MatPowerTesting/test_parse_gencost_row.cpp b/examples/MatPowerTesting/test_parse_gencost_row.cpp index efc409d89..dd4a60780 100644 --- a/examples/MatPowerTesting/test_parse_gencost_row.cpp +++ b/examples/MatPowerTesting/test_parse_gencost_row.cpp @@ -1,15 +1,17 @@ +#include + #include #include #include -#include using namespace GridKit; using namespace GridKit::Testing; using namespace GridKit::PowerSystemData; -namespace { +namespace +{ -using IdxT = int; +using IdxT = int; using RealT = double; static const std::string matpower_data{ @@ -31,25 +33,27 @@ mpc.gencost = [ } // namespace -int main(int argc, char **argv) { - int fail = 0; - std::vector> gencost_answer{ - {2, 0, 0, 3, {0, 14, 0}}, {2, 0, 0, 3, {0, 15, 0}}, - {2, 0, 0, 3, {0, 30, 0}}, {2, 0, 0, 3, {0, 40, 0}}, - {2, 0, 0, 3, {0, 10, 0}}, - }; - SystemModelData mp; - - { - std::istringstream iss(matpower_data); - GridKit::readMatPower(mp, iss); - if (!isEqual(mp.gencost, gencost_answer)) - fail++; - std::cout << "After reading the gencost component, fail == " << fail - << "\n"; - } - - std::cout << "Tests " << (fail ? "FAILED" : "PASSED") << "\n"; - - return fail; +int main(int argc, char** argv) +{ + int fail = 0; + std::vector> gencost_answer{ + {2, 0, 0, 3, {0, 14, 0}}, + {2, 0, 0, 3, {0, 15, 0}}, + {2, 0, 0, 3, {0, 30, 0}}, + {2, 0, 0, 3, {0, 40, 0}}, + {2, 0, 0, 3, {0, 10, 0}}, + }; + SystemModelData mp; + + { + std::istringstream iss(matpower_data); + GridKit::readMatPower(mp, iss); + if (!isEqual(mp.gencost, gencost_answer)) + fail++; + std::cout << "After reading the gencost component, fail == " << fail << "\n"; + } + + std::cout << "Tests " << (fail ? "FAILED" : "PASSED") << "\n"; + + return fail; } diff --git a/examples/MatPowerTesting/test_parse_matpower.cpp b/examples/MatPowerTesting/test_parse_matpower.cpp index fa926cad2..23fc630c7 100644 --- a/examples/MatPowerTesting/test_parse_matpower.cpp +++ b/examples/MatPowerTesting/test_parse_matpower.cpp @@ -1,15 +1,17 @@ +#include + #include #include #include -#include using namespace GridKit; using namespace GridKit::Testing; using namespace GridKit::PowerSystemData; -namespace { +namespace +{ -using IdxT = int; +using IdxT = int; using RealT = double; static const std::string matpower_data{ @@ -81,77 +83,74 @@ mpc.gencost = [ } // namespace -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 SystemModelDataT = SystemModelData; - using LoadDataT = LoadData; - - // Create the struct of expected values - std::vector branch_answer{ - {1, 2, 0.00281, 0.0281, 0.00712, 400, 400, 400, 0, 0, 1, -360, 360}, - {1, 4, 0.00304, 0.0304, 0.00658, 0, 0, 0, 0, 0, 1, -360, 360}, - {1, 5, 0.00064, 0.0064, 0.03126, 0, 0, 0, 0, 0, 1, -360, 360}, - {2, 3, 0.00108, 0.0108, 0.01852, 0, 0, 0, 0, 0, 1, -360, 360}, - {3, 4, 0.00297, 0.0297, 0.00674, 0, 0, 0, 0, 0, 1, -360, 360}, - {4, 5, 0.00297, 0.0297, 0.00674, 240, 240, 240, 0, 0, 1, -360, 360}, - }; - std::vector bus_answer{ - {1, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {2, 1, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {3, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {4, 3, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, - {5, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.9}, - }; - std::vector gen_answer{ - {1, 40, 0, 30, -30, 1, 100, 1, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 170, 0, 127.5, -127.5, 1, 100, 1, 170, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 323.49, 0, 390, -390, 1, 100, 1, 520, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 0, 0, 150, -150, 1, 100, 1, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {5, 466.51, 0, 450, -450, 1, 100, 1, 600, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; - std::vector gencost_answer{ - {2, 0, 0, 3, {0, 14, 0}}, {2, 0, 0, 3, {0, 15, 0}}, - {2, 0, 0, 3, {0, 30, 0}}, {2, 0, 0, 3, {0, 40, 0}}, - {2, 0, 0, 3, {0, 10, 0}}, - }; - std::vector load_answer{ - {1, 0, 0}, - {2, 300, 98.61}, - {3, 300, 98.61}, - {4, 400, 131.47}, - {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.version = "2"; - mp_answer.baseMVA = 100; - - SystemModelDataT mp; - - { - std::istringstream iss(matpower_data); - GridKit::readMatPower(mp, iss); - if (!isEqual(mp, mp_answer)) - fail++; - std::cout << "\n\nAfter reading the gencost component, fail == " << fail - << "\n"; - } - - std::cout << "Tests " << (fail ? "FAILED" : "PASSED") << "\n"; - - return fail; +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 SystemModelDataT = SystemModelData; + using LoadDataT = LoadData; + + // Create the struct of expected values + std::vector branch_answer{ + {1, 2, 0.00281, 0.0281, 0.00712, 400, 400, 400, 0, 0, 1, -360, 360}, + {1, 4, 0.00304, 0.0304, 0.00658, 0, 0, 0, 0, 0, 1, -360, 360}, + {1, 5, 0.00064, 0.0064, 0.03126, 0, 0, 0, 0, 0, 1, -360, 360}, + {2, 3, 0.00108, 0.0108, 0.01852, 0, 0, 0, 0, 0, 1, -360, 360}, + {3, 4, 0.00297, 0.0297, 0.00674, 0, 0, 0, 0, 0, 1, -360, 360}, + {4, 5, 0.00297, 0.0297, 0.00674, 240, 240, 240, 0, 0, 1, -360, 360}, + }; + std::vector bus_answer{ + {1, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {2, 1, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {3, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {4, 3, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.0}, + {5, 2, 0, 0, 1, 1, 0, 230, 1, 1.1, 0.9}, + }; + std::vector gen_answer{{1, 40, 0, 30, -30, 1, 100, 1, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 170, 0, 127.5, -127.5, 1, 100, 1, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 323.49, 0, 390, -390, 1, 100, 1, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 0, 150, -150, 1, 100, 1, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {5, 466.51, 0, 450, -450, 1, 100, 1, 600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + std::vector gencost_answer{ + {2, 0, 0, 3, {0, 14, 0}}, + {2, 0, 0, 3, {0, 15, 0}}, + {2, 0, 0, 3, {0, 30, 0}}, + {2, 0, 0, 3, {0, 40, 0}}, + {2, 0, 0, 3, {0, 10, 0}}, + }; + std::vector load_answer{ + {1, 0, 0}, + {2, 300, 98.61}, + {3, 300, 98.61}, + {4, 400, 131.47}, + {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.version = "2"; + mp_answer.baseMVA = 100; + + SystemModelDataT mp; + + { + std::istringstream iss(matpower_data); + GridKit::readMatPower(mp, iss); + if (!isEqual(mp, mp_answer)) + fail++; + std::cout << "\n\nAfter reading the gencost component, fail == " << fail << "\n"; + } + + std::cout << "Tests " << (fail ? "FAILED" : "PASSED") << "\n"; + + return fail; } diff --git a/examples/Microgrid/CMakeLists.txt b/examples/Microgrid/CMakeLists.txt index 77c59d753..9d627fcac 100644 --- a/examples/Microgrid/CMakeLists.txt +++ b/examples/Microgrid/CMakeLists.txt @@ -3,11 +3,11 @@ add_executable(microgrid Microgrid.cpp) -target_link_libraries(microgrid GRIDKIT::powerelec_disgen - GRIDKIT::powerelec_mircoline - GRIDKIT::powerelec_microload +target_link_libraries(microgrid GRIDKIT::power_elec_disgen + GRIDKIT::power_elec_microline + GRIDKIT::power_elec_microload GRIDKIT::solvers_dyn - GRIDKIT::powerelec_mircobusdq) + GRIDKIT::power_elec_microbusdq) add_test(NAME Microgrid COMMAND $) install(TARGETS microgrid RUNTIME DESTINATION bin) diff --git a/examples/Microgrid/Microgrid.cpp b/examples/Microgrid/Microgrid.cpp index 3168b12bd..9e02e8a41 100644 --- a/examples/Microgrid/Microgrid.cpp +++ b/examples/Microgrid/Microgrid.cpp @@ -1,74 +1,72 @@ - -#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 abstol = 1.0e-8; - double reltol = 1.0e-8; + ///@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 usejac = true; + bool use_jac = true; - //Create model - ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac, max_step_amount); + // Create model + GridKit::PowerElectronicsModel* sysmodel = + new GridKit::PowerElectronicsModel(rel_tol, abs_tol, use_jac, max_step_amount); - //Modeled after the problem in the paper + // Modeled after the problem in the paper double RN = 1.0e4; - //DG Params - ModelLib::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; + // 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.Cf_ = 5.0e-5; parms1.rLf_ = 0.1; - parms1.Lf_ = 1.35e-3; + parms1.Lf_ = 1.35e-3; parms1.rLc_ = 0.03; - parms1.Lc_ = 0.35e-3; - - ModelLib::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; + 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.Cf_ = 50.0e-6; parms2.rLf_ = 0.1; - parms2.Lf_ = 1.35e-3; + parms2.Lf_ = 1.35e-3; parms2.rLc_ = 0.03; - parms2.Lc_ = 0.35e-3; + parms2.Lc_ = 0.35e-3; - //Line params + // Line params double rline1 = 0.23; double Lline1 = 0.1 / (2.0 * M_PI * 50.0); @@ -78,216 +76,216 @@ int main(int argc, char const *argv[]) double rline3 = 0.23; double Lline3 = 0.1 / (2.0 * M_PI * 50.0); - //load parms + // 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; + // 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_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 - ModelLib::DistributedGenerator *dg1 = new ModelLib::DistributedGenerator(0, parms1, true); - //ref motor - dg1->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg1->setExternalConnectionNodes(1,dqbus1); - dg1->setExternalConnectionNodes(2,dqbus1 + 1); + // 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 + dg1->setExternalConnectionNodes(3, -1); + // internal connections for (size_t i = 0; i < 12; i++) { - - dg1->setExternalConnectionNodes(4 + i,indexv + i); + + dg1->setExternalConnectionNodes(4 + i, indexv + i); } indexv += 12; sysmodel->addComponent(dg1); - //dg 2 - ModelLib::DistributedGenerator *dg2 = new ModelLib::DistributedGenerator(1, parms1, false); - //ref motor - dg2->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg2->setExternalConnectionNodes(1,dqbus2); - dg2->setExternalConnectionNodes(2,dqbus2 + 1); - //internal connections + // 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); + + dg2->setExternalConnectionNodes(3 + i, indexv + i); } indexv += 13; sysmodel->addComponent(dg2); - - - //dg 3 - ModelLib::DistributedGenerator *dg3 = new ModelLib::DistributedGenerator(2, parms2, false); - //ref motor - dg3->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg3->setExternalConnectionNodes(1,dqbus3); - dg3->setExternalConnectionNodes(2,dqbus3 + 1); - //internal connections + + // 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); + + 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); - //dg 4 - ModelLib::DistributedGenerator *dg4 = new ModelLib::DistributedGenerator(3, parms2, false); - //ref motor - dg4->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg4->setExternalConnectionNodes(1,dqbus4); - dg4->setExternalConnectionNodes(2,dqbus4 + 1); - - //internal connections + // internal connections for (size_t i = 0; i < 13; i++) { - - dg4->setExternalConnectionNodes(3 + i,indexv + i); + + dg4->setExternalConnectionNodes(3 + i, indexv + i); } indexv += 13; sysmodel->addComponent(dg4); // Lines - //line 1 - ModelLib::MicrogridLine *l1 = new ModelLib::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 + // 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); + + l1->setExternalConnectionNodes(5 + i, indexv + i); } indexv += 2; sysmodel->addComponent(l1); - - //line 2 - ModelLib::MicrogridLine *l2 = new ModelLib::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 + // 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); + + l2->setExternalConnectionNodes(5 + i, indexv + i); } indexv += 2; sysmodel->addComponent(l2); - - //line 3 - ModelLib::MicrogridLine *l3 = new ModelLib::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 + + // 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); + + l3->setExternalConnectionNodes(5 + i, indexv + i); } indexv += 2; sysmodel->addComponent(l3); // loads - //load 1 - ModelLib::MicrogridLoad *load1 = new ModelLib::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 + // 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); + + load1->setExternalConnectionNodes(3 + i, indexv + i); } indexv += 2; sysmodel->addComponent(load1); - //load 2 - ModelLib::MicrogridLoad *load2 = new ModelLib::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 + // 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); + + load2->setExternalConnectionNodes(3 + i, indexv + i); } indexv += 2; sysmodel->addComponent(load2); - //Virtual PQ Buses - ModelLib::MicrogridBusDQ *bus1 = new ModelLib::MicrogridBusDQ(9, RN); + // Virtual PQ Buses + GridKit::MicrogridBusDQ* bus1 = new GridKit::MicrogridBusDQ(9, RN); - bus1->setExternalConnectionNodes(0,dqbus1); - bus1->setExternalConnectionNodes(1,dqbus1 + 1); + bus1->setExternalConnectionNodes(0, dqbus1); + bus1->setExternalConnectionNodes(1, dqbus1 + 1); sysmodel->addComponent(bus1); - ModelLib::MicrogridBusDQ *bus2 = new ModelLib::MicrogridBusDQ(10, RN); + GridKit::MicrogridBusDQ* bus2 = new GridKit::MicrogridBusDQ(10, RN); - bus2->setExternalConnectionNodes(0,dqbus2); - bus2->setExternalConnectionNodes(1,dqbus2 + 1); + bus2->setExternalConnectionNodes(0, dqbus2); + bus2->setExternalConnectionNodes(1, dqbus2 + 1); sysmodel->addComponent(bus2); - ModelLib::MicrogridBusDQ *bus3 = new ModelLib::MicrogridBusDQ(11, RN); + GridKit::MicrogridBusDQ* bus3 = new GridKit::MicrogridBusDQ(11, RN); - bus3->setExternalConnectionNodes(0,dqbus3); - bus3->setExternalConnectionNodes(1,dqbus3 + 1); + bus3->setExternalConnectionNodes(0, dqbus3); + bus3->setExternalConnectionNodes(1, dqbus3 + 1); sysmodel->addComponent(bus3); - ModelLib::MicrogridBusDQ *bus4 = new ModelLib::MicrogridBusDQ(12, RN); + GridKit::MicrogridBusDQ* bus4 = new GridKit::MicrogridBusDQ(12, RN); - bus4->setExternalConnectionNodes(0,dqbus4); - bus4->setExternalConnectionNodes(1,dqbus4 + 1); + bus4->setExternalConnectionNodes(0, dqbus4); + bus4->setExternalConnectionNodes(1, dqbus4 + 1); sysmodel->addComponent(bus4); sysmodel->allocate(vec_size_total); @@ -295,37 +293,35 @@ int main(int argc, char const *argv[]) std::cout << sysmodel->y().size() << std::endl; std::cout << vec_size_internals << ", " << vec_size_externals << "\n"; - //Create Intial points for states + // Create Intial points for states for (size_t i = 0; i < vec_size_total; i++) { - sysmodel->y()[i] = 0.0; + 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_; + // 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_; + 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 + // since the intial P_com = 0 sysmodel->y()[vec_size_internals] = parms1.wb_; - - sysmodel->initialize(); sysmodel->evaluateResidual(); - std::vector& fres = sysmodel->getResidual(); + std::vector& fres = sysmodel->getResidual(); std::cout << "Verify Intial Resisdual is Zero: {\n"; for (size_t i = 0; i < fres.size(); i++) { @@ -336,10 +332,8 @@ int main(int argc, char const *argv[]) sysmodel->updateTime(0.0, 1.0e-8); sysmodel->evaluateJacobian(); std::cout << "Intial Jacobian with alpha:\n"; - // std::cout << sysmodel->getJacobian().frobnorm() << "\n"; - - //Create numerical integrator and configure it for the generator model + // Create numerical integrator and configure it for the generator model AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); double t_init = 0.0; @@ -352,7 +346,7 @@ int main(int argc, char const *argv[]) idas->runSimulation(t_final); - std::vector& yfinial = sysmodel->y(); + std::vector& yfinial = sysmodel->y(); std::cout << "Final Vector y\n"; for (size_t i = 0; i < yfinial.size(); i++) @@ -360,88 +354,35 @@ int main(int argc, char const *argv[]) 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 - }; + // 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])); + 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; } diff --git a/examples/ParameterEstimation/ParameterEstimation.cpp b/examples/ParameterEstimation/ParameterEstimation.cpp index 91406e37d..1995252b4 100644 --- a/examples/ParameterEstimation/ParameterEstimation.cpp +++ b/examples/ParameterEstimation/ParameterEstimation.cpp @@ -57,30 +57,25 @@ * */ - -#include #include +#include #include +#include "lookup_table.hpp" #include #include - -#include -#include #include #include -#include +#include #include - +#include +#include #include #include -#include "lookup_table.hpp" - - int main() { - using namespace ModelLib; + using namespace GridKit; using namespace AnalysisManager::Sundials; using namespace AnalysisManager; using namespace GridKit::Testing; @@ -143,7 +138,7 @@ int main() Ipopt::SmartPtr ipoptApp = IpoptApplicationFactory(); // Set solver tolerance - const double tol = 1e-5; + const double tol = 1e-5; // Initialize the IpoptApplication and process the options Ipopt::ApplicationReturnStatus status; @@ -170,16 +165,16 @@ int main() if (status == Ipopt::Solve_Succeeded) { // Print result - std::cout << "\nSucess:\n The problem solved in " - << ipoptApp->Statistics()->IterationCount() << " iterations!\n" + 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"; + << " The final value of the objective function G(H) = " << ipoptApp->Statistics()->FinalObjective() + << "\n\n"; } // Store dynamic objective optimization results - double* results = new double[model->size_opt()]; - for(unsigned i=0; i size_opt(); ++i) + double* results = new double[model->sizeParams()]; + for (unsigned i = 0; i < model->sizeParams(); ++i) { results[i] = model->param()[i]; } @@ -198,27 +193,27 @@ int main() if (status == Ipopt::Solve_Succeeded) { // Print result - std::cout << "\nSucess:\n The problem solved in " - << ipoptApp->Statistics()->IterationCount() << " iterations!\n" + 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"; + << " 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 size_opt(); ++i) + for (unsigned i = 0; i < model->sizeParams(); ++i) { - if(!isEqual(results[i], model->param()[i], 100*tol)) - --retval; + if (!isEqual(results[i], model->param()[i], 100 * tol)) + --retval; } - if(retval < 0) + if (retval < 0) { std::cout << "The two results differ beyond solver tolerance!\n"; } - delete [] results; + delete[] results; delete idas; delete model; return retval; diff --git a/examples/ParameterEstimation/lookup_table.hpp b/examples/ParameterEstimation/lookup_table.hpp index 069ce1497..735f1db18 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 @@ -100,4 +100,4 @@ R"( 0 0.092182 0.99596 -0.17574 0.98107 2.7864 0.58172 -1.5217 0.092914 0.4 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/examples/RLCircuit/CMakeLists.txt b/examples/RLCircuit/CMakeLists.txt index e7e052603..56599c521 100644 --- a/examples/RLCircuit/CMakeLists.txt +++ b/examples/RLCircuit/CMakeLists.txt @@ -3,10 +3,10 @@ add_executable(rlcircuit RLCircuit.cpp) -target_link_libraries(rlcircuit GRIDKIT::powerelec_capacitor - GRIDKIT::powerelec_inductor - GRIDKIT::powerelec_resistor - GRIDKIT::powerelec_voltagesource +target_link_libraries(rlcircuit GRIDKIT::power_elec_capacitor + GRIDKIT::power_elec_inductor + GRIDKIT::power_elec_resistor + GRIDKIT::power_elec_voltagesource GRIDKIT::solvers_dyn) add_test(NAME RLCircuit COMMAND $) diff --git a/examples/RLCircuit/RLCircuit.cpp b/examples/RLCircuit/RLCircuit.cpp index c00be85fb..8b76d95d6 100644 --- a/examples/RLCircuit/RLCircuit.cpp +++ b/examples/RLCircuit/RLCircuit.cpp @@ -1,95 +1,89 @@ -#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 abstol = 1.0e-8; - double reltol = 1.0e-8; - bool usejac = true; + double abs_tol = 1.0e-8; + double rel_tol = 1.0e-8; + bool use_jac = true; - //TODO:setup as named parameters - //Create circuit model - ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac); + // 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 + // RL circuit parameters double rinit = 1.0; double linit = 1.0; double vinit = 1.0; - - //inductor - ModelLib::Inductor* induct = new ModelLib::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 + // 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 + // resistor idoff++; - ModelLib::Resistor* resis = new ModelLib::Resistor(idoff, rinit); - //Form index to node uid realations - //input - resis->setExternalConnectionNodes(0,0); - //output - resis->setExternalConnectionNodes(1,1); - //add + 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 + // voltage source idoff++; - ModelLib::VoltageSource* vsource = new ModelLib::VoltageSource(idoff, vinit); - //Form index to node uid realations - //input - vsource->setExternalConnectionNodes(0,-1); - //output - vsource->setExternalConnectionNodes(1,0); - //internal - vsource->setExternalConnectionNodes(2,3); - - + 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 + // 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->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()[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(); @@ -100,13 +94,11 @@ int main(int argc, char const *argv[]) } 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); @@ -120,7 +112,7 @@ int main(int argc, char const *argv[]) idas->runSimulation(t_final); - std::vector& yfinial = sysmodel->y(); + std::vector& yfinial = sysmodel->y(); std::cout << "Final Vector y\n"; for (size_t i = 0; i < yfinial.size(); i++) @@ -130,16 +122,16 @@ int main(int argc, char const *argv[]) std::vector yexact(4); - //analytical solution to the circuit + // 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"; + std::cout << abs((yfinial[i] - yexact[i]) / yexact[i]) << "\n"; } return 0; diff --git a/examples/ScaleMicrogrid/CMakeLists.txt b/examples/ScaleMicrogrid/CMakeLists.txt index d1822c587..1f0fe0cbb 100644 --- a/examples/ScaleMicrogrid/CMakeLists.txt +++ b/examples/ScaleMicrogrid/CMakeLists.txt @@ -3,11 +3,11 @@ add_executable(scalemicrogrid ScaleMicrogrid.cpp) -target_link_libraries(scalemicrogrid GRIDKIT::powerelec_disgen - GRIDKIT::powerelec_mircoline - GRIDKIT::powerelec_microload +target_link_libraries(scalemicrogrid GRIDKIT::power_elec_disgen + GRIDKIT::power_elec_microline + GRIDKIT::power_elec_microload GRIDKIT::solvers_dyn - GRIDKIT::powerelec_mircobusdq) + GRIDKIT::power_elec_microbusdq) add_test(NAME ScaleMicrogrid COMMAND $) install(TARGETS scalemicrogrid RUNTIME DESTINATION bin) diff --git a/examples/ScaleMicrogrid/ScaleMicrogrid.cpp b/examples/ScaleMicrogrid/ScaleMicrogrid.cpp index 86fc27dd9..60fa430d2 100644 --- a/examples/ScaleMicrogrid/ScaleMicrogrid.cpp +++ b/examples/ScaleMicrogrid/ScaleMicrogrid.cpp @@ -1,43 +1,40 @@ -#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; + 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); @@ -55,7 +52,7 @@ int main(int argc, char const *argv[]) /** * @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,103 +61,99 @@ int main(int argc, char const *argv[]) */ int test(index_type Nsize, real_type error_tol, bool debug_output) { - using namespace ModelLib; + using namespace GridKit; - bool usejac = true; + bool use_jac = true; real_type t_init = 0.0; real_type t_final = 1.0; - real_type reltol = SCALE_MICROGRID_REL_TOL; - real_type abstol = SCALE_MICROGRID_ABS_TOL; + real_type rel_tol = SCALE_MICROGRID_REL_TOL; + real_type abs_tol = SCALE_MICROGRID_ABS_TOL; // Create circuit model - auto* sysmodel = new PowerElectronicsModel(reltol, - abstol, - usejac, - SCALE_MICROGRID_MAX_STEPS); + 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"; + 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. - ModelLib::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; + 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.Cf_ = 5.0e-5; DG_parms1.rLf_ = 0.1; - DG_parms1.Lf_ = 1.35e-3; + DG_parms1.Lf_ = 1.35e-3; DG_parms1.rLc_ = 0.03; - DG_parms1.Lc_ = 0.35e-3; - - ModelLib::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_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.Cf_ = 50.0e-6; DG_parms2.rLf_ = 0.1; - DG_parms2.Lf_ = 1.35e-3; + DG_parms2.Lf_ = 1.35e-3; DG_parms2.rLc_ = 0.03; - DG_parms2.Lc_ = 0.35e-3; + DG_parms2.Lc_ = 0.35e-3; - std::vector> DGParams_list(2*Nsize, DG_parms2); + 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); + // 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. + // 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; @@ -171,80 +164,74 @@ int test(index_type Nsize, real_type error_tol, bool debug_output) 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; + // 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); + index_type vec_size_externals = 1 + 2 * (2 * Nsize); - std::vector vdqbus_index(2*Nsize,0); + 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; + vdqbus_index[i] = vdqbus_index[i - 1] + 2; } - //Total size of the vector setup + // 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 + // Create the reference DG + auto* dg_ref = new DistributedGenerator(0, DGParams_list[0], true); + // ref motor dg_ref->setExternalConnectionNodes(0, vec_size_internals); - //outputs + // 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 + // 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; + // 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++) + // 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 + // 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); + dg->setExternalConnectionNodes(3 + j, indexv + j); } indexv += 13; sysmodel->addComponent(dg); } // Load all the Line compoenents - for (index_type i = 0; i < 2*Nsize - 1; i++) + 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 + auto* line_model = new MicrogridLine(model_id++, rline_list[i], Lline_list[i]); + // ref motor line_model->setExternalConnectionNodes(0, vec_size_internals); - //input connections + // 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 + // 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); @@ -256,15 +243,13 @@ int test(index_type Nsize, real_type error_tol, bool debug_output) // 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 + 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 + // 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); @@ -273,8 +258,8 @@ int test(index_type Nsize, real_type error_tol, bool debug_output) sysmodel->addComponent(load_model); } - //Add all the microgrid Virtual DQ Buses - for (index_type i = 0; i < 2*Nsize; i++) + // Add all the microgrid Virtual DQ Buses + for (index_type i = 0; i < 2 * Nsize; i++) { auto* virDQbus_model = new MicrogridBusDQ(model_id++, RN); @@ -282,8 +267,8 @@ int test(index_type Nsize, real_type error_tol, bool debug_output) virDQbus_model->setExternalConnectionNodes(1, vdqbus_index[i] + 1); sysmodel->addComponent(virDQbus_model); } - - //allocate all the intial conditions + + // allocate all the intial conditions sysmodel->allocate(vec_size_total); if (debug_output) @@ -292,22 +277,23 @@ int test(index_type Nsize, real_type error_tol, bool debug_output) std::cout << vec_size_internals << ", " << vec_size_externals << "\n"; } - //Create Intial points for states. Every state is to specified to the zero intially + // 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->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++) + 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_; + 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 + // 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(); @@ -329,8 +315,7 @@ int test(index_type Nsize, real_type error_tol, bool debug_output) if (debug_output) std::cout << "Intial Jacobian with alpha:\n"; - - //Create numerical integrator and configure it for the generator model + // Create numerical integrator and configure it for the generator model auto* idas = new AnalysisManager::Sundials::Ida(sysmodel); // setup simulation @@ -340,7 +325,7 @@ int test(index_type Nsize, real_type error_tol, bool debug_output) idas->runSimulation(t_final); - std::vector& yfinal = sysmodel->y(); + std::vector& yfinal = sysmodel->y(); if (debug_output) { @@ -353,30 +338,29 @@ int test(index_type Nsize, real_type error_tol, bool debug_output) bool test_pass = true; - real_type sumtop = 0.0; + 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 + // 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]); + 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; + 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; + delete sysmodel; - if(test_pass) + if (test_pass) { std::cout << "Test with Nsize = " << Nsize << " passes!\n"; return 0; diff --git a/examples/ScaleMicrogrid/SolutionKeys.hpp b/examples/ScaleMicrogrid/SolutionKeys.hpp index 1d0ca8e64..d57b1c5a1 100644 --- a/examples/ScaleMicrogrid/SolutionKeys.hpp +++ b/examples/ScaleMicrogrid/SolutionKeys.hpp @@ -3,540 +3,136 @@ * @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 - * abstol = 1e-12 and reltol = 1e-12 for the ODE derivation of the model. + * 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, - 0.0376305671131306, - -0.0209815421114537, - 0.0184828563235406, - -0.00015632917065729, - 63.2193617412383, - -29.4226556659582, - 363.420924977355, - -3.01001804456668e-06, - 63.2193618667302, - -35.0920143829141, - -0.00755583999797958, - 22975.8457840701, - 8742.0172166684, - 0.0371009878165673, - -0.0142112776774797, - 0.0187407972932474, - -9.8913852531819e-05, - 62.3296548917654, - -17.9650261562766, - 368.635407345931, - 3.79041261513032e-05, - 62.3296560841534, - -23.7157298601546, - -0.0827401584095097, - 17277.712521392, - 16493.7578328327, - 0.0311645357391787, - -0.0298601153771274, - 0.0225001003469904, - -0.000264388302121386, - 48.6166482764357, - -40.8862612232969, - 355.25957014696, - -0.000167008045114112, - 48.6166481095298, - -46.4283022775928, - -0.0844566209033113, - 17277.2493364959, - 9182.29479881977, - 0.0302503981389185, - -0.0161722538457184, - 0.023180586071601, - -0.000129590157483103, - 47.1906392248137, - -19.3574255862892, - 366.226354188735, - 0.000121054462396047, - 47.19063792117, - -25.0705499054599, - -18.8125403122072, - 21.1471334522508, - 43.2997340692497, - -3.03798323340816, - -44.8715356440453, - 28.9585224749495, - 81.99613295014, - -56.2385627562355, - 132.749774614687, - -82.280664729262, - 311.999576042192, - 357.692287974629, - -5.85078929333349, - 364.119335219897, - -8.84631033126304, - 347.214535767435, - -32.7241067379802, - 360.411028950125, - -34.9283280833745 -}; + 22975.4182636905, 12753.1173017451, 0.0376305671131306, -0.0209815421114537, 0.0184828563235406, + -0.00015632917065729, 63.2193617412383, -29.4226556659582, 363.420924977355, -3.01001804456668e-06, + 63.2193618667302, -35.0920143829141, -0.00755583999797958, 22975.8457840701, 8742.0172166684, + 0.0371009878165673, -0.0142112776774797, 0.0187407972932474, -9.8913852531819e-05, 62.3296548917654, + -17.9650261562766, 368.635407345931, 3.79041261513032e-05, 62.3296560841534, -23.7157298601546, + -0.0827401584095097, 17277.712521392, 16493.7578328327, 0.0311645357391787, -0.0298601153771274, + 0.0225001003469904, -0.000264388302121386, 48.6166482764357, -40.8862612232969, 355.25957014696, + -0.000167008045114112, 48.6166481095298, -46.4283022775928, -0.0844566209033113, 17277.2493364959, + 9182.29479881977, 0.0302503981389185, -0.0161722538457184, 0.023180586071601, -0.000129590157483103, + 47.1906392248137, -19.3574255862892, 366.226354188735, 0.000121054462396047, 47.19063792117, + -25.0705499054599, -18.8125403122072, 21.1471334522508, 43.2997340692497, -3.03798323340816, + -44.8715356440453, 28.9585224749495, 81.99613295014, -56.2385627562355, 132.749774614687, + -82.280664729262, 311.999576042192, 357.692287974629, -5.85078929333349, 364.119335219897, + -8.84631033126304, 347.214535767435, -32.7241067379802, 360.411028950125, -34.9283280833745}; const std::vector answer_key_N4 = { - 27828.3291148094, - 10602.3611530864, - 0.0452452394028709, - -0.0173410584955486, - 0.018686818367312, - -0.000129595027000909, - 76.0120809944985, - -23.2367034227098, - 366.216582730654, - -0.000167782960864797, - 76.0120710728117, - -28.9413214479885, - -0.0154989336357971, - 27832.0772154743, - 7838.80352597054, - 0.0448129806183038, - -0.0127296381144373, - 0.0188642014642206, - -9.04502393904097e-05, - 75.2859236720964, - -15.4316980534341, - 369.809174828127, - -5.17440472732025e-05, - 75.285919083362, - -21.1922719962368, - -0.142596248886844, - 20950.1519748442, - 16334.3924580166, - 0.0377787488551238, - -0.0295717781600636, - 0.0225780601074885, - -0.000265567743682681, - 58.9348270364006, - -40.4081583028089, - 355.498460539903, - -8.66167274613643e-05, - 58.9348242715342, - -45.9457664944992, - -0.164628885385433, - 20956.2846481359, - 12345.7855779785, - 0.0371673110634281, - -0.0220171188824754, - 0.0229486760225139, - -0.000191111142238558, - 57.9810673844105, - -28.5265491599081, - 361.481100853144, - 8.24481547667206e-05, - 57.9810719040216, - -34.1573355283559, - -0.245126576498858, - 20978.9206932923, - 17875.6825958711, - 0.0380785081131898, - -0.0325621468970297, - 0.0224354615928625, - -0.000295085318936756, - 59.4025243779293, - -45.1101946009202, - 353.186117339098, - 5.52721744209165e-05, - 59.4025238741703, - -50.6117204294148, - -0.253672269778405, - 20990.6142554844, - 11779.5685373245, - 0.0371243965775962, - -0.0209716906203726, - 0.0230016494389548, - -0.000180846578022512, - 57.9140614794815, - -26.8817831662193, - 362.331254349606, - 0.000209247259473183, - 57.9140782926947, - -32.5257339504705, - -0.288747285297145, - 21004.5418902462, - 16686.981801999, - 0.0379131316203435, - -0.0302602142538338, - 0.0225460339603269, - -0.000272422675391038, - 59.1444740212228, - -41.4902940591195, - 354.969993387113, - 8.14114753778542e-05, - 59.1444846638236, - -47.0195494892644, - -0.285876486857154, - 21005.895228757, - 8274.13913126834, - 0.0366267978764156, - -0.0145584209340773, - 0.0233276948336748, - -0.000117627382397687, - 57.1378568500881, - -16.7923279871216, - 367.58883605301, - 0.000263351556352378, - 57.1378679159653, - -22.518140603782, - -6.57009481597077, - 28.1053117219546, - 68.341829672125, - 5.75010361666728, - -7.27398138223966, - 42.3413009908014, - 44.2901915856089, - -0.850144510998897, - -26.9214526328474, - 37.7939474726438, - 20.9421230166698, - -8.2155394685309, - -48.4341275019927, - 37.706248875936, - 82.5460878639016, - -57.0458911301263, - 127.388509162578, - -90.4406093871607, - 116.522583626035, - -102.149734009655, - 112.650118587972, - -107.825883544914, - 311.543402422187, - 360.780248808368, - -7.42039816792328, - 365.078323407317, - -13.2331839185884, - 344.46378568747, - -54.5546252592288, - 350.335287885457, - -63.572021962256, - 334.342198258035, - -88.749585714325, - 344.281369936645, - -94.7726681838823, - 332.2248206198, - -103.942854393111, - 347.103721199815, - -107.812479611979 -}; + 27828.3291148094, 10602.3611530864, 0.0452452394028709, -0.0173410584955486, 0.018686818367312, + -0.000129595027000909, 76.0120809944985, -23.2367034227098, 366.216582730654, -0.000167782960864797, + 76.0120710728117, -28.9413214479885, -0.0154989336357971, 27832.0772154743, 7838.80352597054, + 0.0448129806183038, -0.0127296381144373, 0.0188642014642206, -9.04502393904097e-05, 75.2859236720964, + -15.4316980534341, 369.809174828127, -5.17440472732025e-05, 75.285919083362, -21.1922719962368, + -0.142596248886844, 20950.1519748442, 16334.3924580166, 0.0377787488551238, -0.0295717781600636, + 0.0225780601074885, -0.000265567743682681, 58.9348270364006, -40.4081583028089, 355.498460539903, + -8.66167274613643e-05, 58.9348242715342, -45.9457664944992, -0.164628885385433, 20956.2846481359, + 12345.7855779785, 0.0371673110634281, -0.0220171188824754, 0.0229486760225139, -0.000191111142238558, + 57.9810673844105, -28.5265491599081, 361.481100853144, 8.24481547667206e-05, 57.9810719040216, + -34.1573355283559, -0.245126576498858, 20978.9206932923, 17875.6825958711, 0.0380785081131898, + -0.0325621468970297, 0.0224354615928625, -0.000295085318936756, 59.4025243779293, -45.1101946009202, + 353.186117339098, 5.52721744209165e-05, 59.4025238741703, -50.6117204294148, -0.253672269778405, + 20990.6142554844, 11779.5685373245, 0.0371243965775962, -0.0209716906203726, 0.0230016494389548, + -0.000180846578022512, 57.9140614794815, -26.8817831662193, 362.331254349606, 0.000209247259473183, + 57.9140782926947, -32.5257339504705, -0.288747285297145, 21004.5418902462, 16686.981801999, + 0.0379131316203435, -0.0302602142538338, 0.0225460339603269, -0.000272422675391038, 59.1444740212228, + -41.4902940591195, 354.969993387113, 8.14114753778542e-05, 59.1444846638236, -47.0195494892644, + -0.285876486857154, 21005.895228757, 8274.13913126834, 0.0366267978764156, -0.0145584209340773, + 0.0233276948336748, -0.000117627382397687, 57.1378568500881, -16.7923279871216, 367.58883605301, + 0.000263351556352378, 57.1378679159653, -22.518140603782, -6.57009481597077, 28.1053117219546, + 68.341829672125, 5.75010361666728, -7.27398138223966, 42.3413009908014, 44.2901915856089, + -0.850144510998897, -26.9214526328474, 37.7939474726438, 20.9421230166698, -8.2155394685309, + -48.4341275019927, 37.706248875936, 82.5460878639016, -57.0458911301263, 127.388509162578, + -90.4406093871607, 116.522583626035, -102.149734009655, 112.650118587972, -107.825883544914, + 311.543402422187, 360.780248808368, -7.42039816792328, 365.078323407317, -13.2331839185884, + 344.46378568747, -54.5546252592288, 350.335287885457, -63.572021962256, 334.342198258035, + -88.749585714325, 344.281369936645, -94.7726681838823, 332.2248206198, -103.942854393111, + 347.103721199815, -107.812479611979}; const std::vector answer_key_N8 = { - 29266.6517718661, - 9842.93617289812, - 0.0475360674334622, - -0.0160323945316821, - 0.0187557247105805, - -0.000119821248231538, - 79.8612117213119, - -21.0144010498971, - 367.201497494684, - -0.00135963018489767, - 79.8611351716573, - -26.7318789917162, - -0.018074876389402, - 29296.9645459408, - 7415.51099954903, - 0.0471789367393934, - -0.0120180219897291, - 0.0189117902285582, - -8.57914733703415e-05, - 79.2614266664798, - -14.2194852461262, - 370.357116139458, - -0.00065261697325357, - 79.261388452934, - -19.9860446882469, - -0.161178046356866, - 22178.7337755581, - 15750.48869542, - 0.0399575496599213, - -0.028431003000158, - 0.0226540351215628, - -0.000255811047442045, - 62.3338080750298, - -38.6061338491152, - 356.372404460464, - -0.000888421043595241, - 62.3337589017493, - -44.1546192236143, - -0.191206982234175, - 22245.3587939821, - 12476.0312983393, - 0.0395296431152022, - -0.0222832972915751, - 0.0229591349358969, - -0.000195357283522886, - 61.6667253463805, - -28.9363062720176, - 361.284131747149, - 0.000606091049765824, - 61.6667589580497, - -34.5611135316627, - -0.300475535038271, - 22471.354929649, - 17410.9400696732, - 0.0407475331761201, - -0.0316496339533813, - 0.0225047347006168, - -0.000287941144857336, - 63.5662158978541, - -43.6654709736205, - 353.882194971394, - -0.00050508442766251, - 63.5661867600733, - -49.1745383652835, - -0.321406735230742, - 22562.1063953332, - 12532.040739496, - 0.0400730650460856, - -0.0224103188019356, - 0.0229590093469276, - -0.000197040279593967, - 62.5145400797163, - -29.1337602252211, - 361.200953962968, - 0.00123813270414561, - 62.5146115608051, - -34.7565572443792, - -0.398765881347133, - 22822.9625175864, - 17526.9123376124, - 0.0413769691613727, - -0.0318846988884131, - 0.0224996948233429, - -0.000290724959665147, - 64.5480523645119, - -44.0326735095454, - 353.709220392926, - -0.000255137918253834, - 64.548036917491, - -49.5382706457328, - -0.409294621792759, - 22917.4640781459, - 11700.1980576741, - 0.0405370737861658, - -0.0208717910251266, - 0.0230419643488667, - -0.000182321342412399, - 63.2383663569188, - -26.7111380754575, - 362.449323338104, - 0.00143605100750772, - 63.2384503029344, - -32.3525635247183, - -0.460038982115987, - 23175.0870418607, - 17429.0372806116, - 0.0419717095772374, - -0.0317010913432995, - 0.0225145433123769, - -0.000289381352876061, - 65.4757968347883, - -43.7415548084125, - 353.856643943042, - -0.000116590766441278, - 65.4757901489451, - -49.2486679790579, - -0.461848591689221, - 23264.6732405303, - 10919.0360806903, - 0.0409947737541995, - -0.0194331296392293, - 0.0231200668519233, - -0.000168575863901554, - 63.9522672718067, - -24.4455560147541, - 363.621937642842, - 0.00154556746783549, - 63.9523565934322, - -30.1044436917781, - -0.491529580804623, - 23488.6137650364, - 17313.8654584652, - 0.0424952351974662, - -0.0314883547842804, - 0.0225303364455447, - -0.000287714847080755, - 66.2924442955506, - -43.4048501801219, - 354.030311475628, - 0.000169934086992562, - 66.2924545883603, - -48.9139721676174, - -0.486548093474613, - 23557.6136117665, - 10241.0790360359, - 0.0413774884672506, - -0.0181860120867723, - 0.0231877453638413, - -0.000156639599075328, - 64.5492156984859, - -22.4816084883194, - 364.639179755733, - 0.00142420279185394, - 64.5492984953198, - -28.1556597465189, - -0.499726325044563, - 23722.4168131373, - 16958.7765974266, - 0.0428487548646152, - -0.0308090857078185, - 0.0225672437721518, - -0.000281355782039133, - 66.8440182379463, - -42.3350991467661, - 354.562942832682, - 0.000573219240561573, - 66.844044569212, - -47.8519918014414, - -0.490219448053285, - 23769.8747006891, - 9267.5206785042, - 0.0415639300026818, - -0.0164109903099032, - 0.0232814268213158, - -0.000139385907988285, - 64.8399200066663, - -19.6874999818575, - 366.100410278813, - 0.00128332197988872, - 64.8400012051758, - -25.3838027935624, - -0.491586583798841, - 23854.0240861864, - 15160.7060140903, - 0.0427385845553072, - -0.0273659210853948, - 0.0227360281885303, - -0.00024756822257102, - 66.6722121992594, - -36.9193366680176, - 357.260483774461, - 0.000734666517031364, - 66.6722602990682, - -42.4779079553274, - -0.482907936930927, - 23870.5548740189, - 6166.60742794455, - 0.0412253604361869, - -0.0108406830677542, - 0.0235710268609798, - -8.45378382385454e-05, - 64.3117067426907, - -10.9219886629635, - 370.751596332923, - 0.00130490570318174, - 64.3117765573399, - -16.6904284244068, - -2.9267653635869, - 30.5878043390112, - 75.9238910016987, - 9.17392754248112, - 4.3701560041079, - 48.7765765968327, - 58.3101300775815, - 3.13323809951331, - -6.37573932293514, - 46.1701408549949, - 41.9244199648313, - -6.5432868117422, - -17.3691293511209, - 41.8611610718482, - 27.7383173553277, - -12.9709065074016, - -27.5322418670623, - 38.9032728624808, - 16.2733736528389, - -16.5280348065045, - -36.4800564569504, - 37.0627808819117, - 7.38198504755967, - -17.9899033675727, - -44.0731708800056, - 36.9539474625741, - 1.14781892918688, - -15.9507601441003, - -49.1751072411967, - 44.6278268007059, - 82.7517114852138, - -57.3188928805757, - 125.959171148664, - -93.1822145893453, - 110.816672146529, - -108.811406393296, - 99.5107131550674, - -119.104827911048, - 92.0427992280762, - -125.056967118294, - 88.0811872722293, - -127.985464658329, - 87.1649116220972, - -128.957730829954, - 89.0189233593932, - -129.480383815729, - 311.408200092424, - 361.890500304156, - -7.90450151715305, - 365.594288034004, - -14.6504114199963, - 344.278948204657, - -61.517809887448, - 348.104769580715, - -73.1715704285651, - 329.472137794467, - -107.797643650827, - 335.509251816504, - -117.787067889008, - 317.044841017058, - -139.602945170765, - 325.182412285621, - -147.51178633583, - 307.989533967543, - -158.91998673915, - 318.171184823086, - -165.141414351062, - 302.951769665185, - -168.712626964975, - 315.009688292198, - -173.624287308414, - 302.070219389208, - -171.572667424371, - 315.86470341008, - -175.706947618597, - 306.288884765777, - -170.785573848562, - 322.018589824395, - -176.179397251772 -}; - - + 29266.6517718661, 9842.93617289812, 0.0475360674334622, -0.0160323945316821, 0.0187557247105805, + -0.000119821248231538, 79.8612117213119, -21.0144010498971, 367.201497494684, -0.00135963018489767, + 79.8611351716573, -26.7318789917162, -0.018074876389402, 29296.9645459408, 7415.51099954903, + 0.0471789367393934, -0.0120180219897291, 0.0189117902285582, -8.57914733703415e-05, 79.2614266664798, + -14.2194852461262, 370.357116139458, -0.00065261697325357, 79.261388452934, -19.9860446882469, + -0.161178046356866, 22178.7337755581, 15750.48869542, 0.0399575496599213, -0.028431003000158, + 0.0226540351215628, -0.000255811047442045, 62.3338080750298, -38.6061338491152, 356.372404460464, + -0.000888421043595241, 62.3337589017493, -44.1546192236143, -0.191206982234175, 22245.3587939821, + 12476.0312983393, 0.0395296431152022, -0.0222832972915751, 0.0229591349358969, -0.000195357283522886, + 61.6667253463805, -28.9363062720176, 361.284131747149, 0.000606091049765824, 61.6667589580497, + -34.5611135316627, -0.300475535038271, 22471.354929649, 17410.9400696732, 0.0407475331761201, + -0.0316496339533813, 0.0225047347006168, -0.000287941144857336, 63.5662158978541, -43.6654709736205, + 353.882194971394, -0.00050508442766251, 63.5661867600733, -49.1745383652835, -0.321406735230742, + 22562.1063953332, 12532.040739496, 0.0400730650460856, -0.0224103188019356, 0.0229590093469276, + -0.000197040279593967, 62.5145400797163, -29.1337602252211, 361.200953962968, 0.00123813270414561, + 62.5146115608051, -34.7565572443792, -0.398765881347133, 22822.9625175864, 17526.9123376124, + 0.0413769691613727, -0.0318846988884131, 0.0224996948233429, -0.000290724959665147, 64.5480523645119, + -44.0326735095454, 353.709220392926, -0.000255137918253834, 64.548036917491, -49.5382706457328, + -0.409294621792759, 22917.4640781459, 11700.1980576741, 0.0405370737861658, -0.0208717910251266, + 0.0230419643488667, -0.000182321342412399, 63.2383663569188, -26.7111380754575, 362.449323338104, + 0.00143605100750772, 63.2384503029344, -32.3525635247183, -0.460038982115987, 23175.0870418607, + 17429.0372806116, 0.0419717095772374, -0.0317010913432995, 0.0225145433123769, -0.000289381352876061, + 65.4757968347883, -43.7415548084125, 353.856643943042, -0.000116590766441278, 65.4757901489451, + -49.2486679790579, -0.461848591689221, 23264.6732405303, 10919.0360806903, 0.0409947737541995, + -0.0194331296392293, 0.0231200668519233, -0.000168575863901554, 63.9522672718067, -24.4455560147541, + 363.621937642842, 0.00154556746783549, 63.9523565934322, -30.1044436917781, -0.491529580804623, + 23488.6137650364, 17313.8654584652, 0.0424952351974662, -0.0314883547842804, 0.0225303364455447, + -0.000287714847080755, 66.2924442955506, -43.4048501801219, 354.030311475628, 0.000169934086992562, + 66.2924545883603, -48.9139721676174, -0.486548093474613, 23557.6136117665, 10241.0790360359, + 0.0413774884672506, -0.0181860120867723, 0.0231877453638413, -0.000156639599075328, 64.5492156984859, + -22.4816084883194, 364.639179755733, 0.00142420279185394, 64.5492984953198, -28.1556597465189, + -0.499726325044563, 23722.4168131373, 16958.7765974266, 0.0428487548646152, -0.0308090857078185, + 0.0225672437721518, -0.000281355782039133, 66.8440182379463, -42.3350991467661, 354.562942832682, + 0.000573219240561573, 66.844044569212, -47.8519918014414, -0.490219448053285, 23769.8747006891, + 9267.5206785042, 0.0415639300026818, -0.0164109903099032, 0.0232814268213158, -0.000139385907988285, + 64.8399200066663, -19.6874999818575, 366.100410278813, 0.00128332197988872, 64.8400012051758, + -25.3838027935624, -0.491586583798841, 23854.0240861864, 15160.7060140903, 0.0427385845553072, + -0.0273659210853948, 0.0227360281885303, -0.00024756822257102, 66.6722121992594, -36.9193366680176, + 357.260483774461, 0.000734666517031364, 66.6722602990682, -42.4779079553274, -0.482907936930927, + 23870.5548740189, 6166.60742794455, 0.0412253604361869, -0.0108406830677542, 0.0235710268609798, + -8.45378382385454e-05, 64.3117067426907, -10.9219886629635, 370.751596332923, 0.00130490570318174, + 64.3117765573399, -16.6904284244068, -2.9267653635869, 30.5878043390112, 75.9238910016987, + 9.17392754248112, 4.3701560041079, 48.7765765968327, 58.3101300775815, 3.13323809951331, + -6.37573932293514, 46.1701408549949, 41.9244199648313, -6.5432868117422, -17.3691293511209, + 41.8611610718482, 27.7383173553277, -12.9709065074016, -27.5322418670623, 38.9032728624808, + 16.2733736528389, -16.5280348065045, -36.4800564569504, 37.0627808819117, 7.38198504755967, + -17.9899033675727, -44.0731708800056, 36.9539474625741, 1.14781892918688, -15.9507601441003, + -49.1751072411967, 44.6278268007059, 82.7517114852138, -57.3188928805757, 125.959171148664, + -93.1822145893453, 110.816672146529, -108.811406393296, 99.5107131550674, -119.104827911048, + 92.0427992280762, -125.056967118294, 88.0811872722293, -127.985464658329, 87.1649116220972, + -128.957730829954, 89.0189233593932, -129.480383815729, 311.408200092424, 361.890500304156, + -7.90450151715305, 365.594288034004, -14.6504114199963, 344.278948204657, -61.517809887448, + 348.104769580715, -73.1715704285651, 329.472137794467, -107.797643650827, 335.509251816504, + -117.787067889008, 317.044841017058, -139.602945170765, 325.182412285621, -147.51178633583, + 307.989533967543, -158.91998673915, 318.171184823086, -165.141414351062, 302.951769665185, + -168.712626964975, 315.009688292198, -173.624287308414, 302.070219389208, -171.572667424371, + 315.86470341008, -175.706947618597, 306.288884765777, -170.785573848562, 322.018589824395, + -176.179397251772}; diff --git a/src/CircuitGraph.hpp b/src/CircuitGraph.hpp index 070d838f1..df55e90f6 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,66 +57,67 @@ 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(); } /** - * @brief Printing + * @brief Print the bipartite graph * * @todo need to add verbose printing for connections display * * @tparam IdxT - * @param verbose + * @param[in] verbose if true will print connections, + * otherwise just the number of nodes and edges */ 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/CMakeLists.txt b/src/LinearAlgebra/CMakeLists.txt index b51d669ec..d290617be 100644 --- a/src/LinearAlgebra/CMakeLists.txt +++ b/src/LinearAlgebra/CMakeLists.txt @@ -1,7 +1,3 @@ -add_library(SparseMatrix INTERFACE) -include_directories(SparseMatrix INTERFACE ${CMAKE_CURRENT_LIST_DIR}) - -add_library(GRIDKIT::SparseMatrix ALIAS SparseMatrix) - - +add_subdirectory(SparseMatrix) +add_subdirectory(DenseMatrix) diff --git a/src/LinearAlgebra/COO_Matrix.hpp b/src/LinearAlgebra/COO_Matrix.hpp deleted file mode 100644 index 9036085a5..000000000 --- a/src/LinearAlgebra/COO_Matrix.hpp +++ /dev/null @@ -1,766 +0,0 @@ - - -#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_ list. 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_indexes_; - std::vector column_indexes_; - Intdx rows_size_; - Intdx columns_size_; - bool sorted_; -public: - //Constructors - COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n); - COO_Matrix(Intdx m, Intdx n); - COO_Matrix(); - ~COO_Matrix(); - - - //Operations - - // --- Functions which call sort --- - std::tuple, std::vector> getRowCopy(Intdx r); - std::tuple&, std::vector&, std::vector&> getEntries(); - std::tuple, std::vector, std::vector> getEntrieCopies(); - std::tuple, std::vector, std::vector> getEntrieCopiesSubMatrix(std::vector submap); - - std::tuple, std::vector, std::vector> getDataToCSR(); - 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(); - - // --- Permutation Operations --- - //No sorting is actually done. Only done when nesscary - void permutation(std::vector row_perm, std::vector col_perm); - void permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n); - - void zeroMatrix(); - - void identityMatrix(Intdx n); - - //Resort values_ - void sortSparse(); - bool isSorted(); - Intdx nnz(); - - std::tuple getDimensions(); - - void printMatrix(); - - - static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &vals); - -private: - Intdx indexStartRow(const std::vector &rows, Intdx r); - Intdx sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci); - bool checkIncreaseSize(Intdx r, Intdx c); - -}; - -/** - * @brief Get copy of row values_ - * - * @tparam ScalarT - * @tparam Intdx - * @param r - * @return std::tuple, std::vector> - */ -template -inline std::tuple, std::vector> COO_Matrix::getRowCopy(Intdx r) -{ - if (!this->sorted_) - { - this->sortSparse(); - } - Intdx rowindex = this->indexStartRow(r); - - - if (rowindex == -1) - { - return {std::vector(),std::vector()}; - } - - Intdx rsize = rowindex; - do - { - rsize++; - } while (rsize < this->values_.size() && this->row_indexes_[rsize] == r); - - return {{this->column_indexes_.begin() + rowindex, this->column_indexes_.begin() + rsize},{this->values_.begin() + rowindex, this->values_.begin() + rsize}}; -} - -/** - * @brief Get all Entries pointers. Will sort before returnings - * - * @tparam ScalarT - * @tparam Intdx - * @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_indexes_, this->column_indexes_, this->values_}; -} - -/** - * @brief Get copies of the data. Sorted_ before returning - * - * @tparam ScalarT - * @tparam Intdx - * @return std::tuple, std::vector, std::vector> - */ -template -inline std::tuple, std::vector, std::vector> COO_Matrix::getEntrieCopies() -{ - if (!this->sorted_) - { - this->sortSparse(); - } - return {this->row_indexes_, this->column_indexes_, this->values_}; -} - -/** - * @brief Returns the data into CSR Format - * - * @tparam ScalarT - * @tparam Intdx - * @return std::tuple, std::vector, std::vector> - */ -template -inline std::tuple, std::vector, std::vector> COO_Matrix::getDataToCSR() -{ - if (!this->isSorted()) this->sortSparse(); - std::vector rowsizevec(this->rows_size_ + 1, 0); - Intdx counter = 0; - for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) - { - rowsizevec[i + 1] = rowsizevec[i]; - while (counter < static_cast(this->row_indexes_.size()) && i == this->row_indexes_[counter]) - { - rowsizevec[i+1]++; - counter++; - } - } - return {rowsizevec, this->column_indexes_, 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 Intdx - * @return std::vector - */ -template -inline std::vector COO_Matrix::getCSRRowData() -{ - if (!this->isSorted()) this->sortSparse(); - std::vector rowsizevec(this->rows_size_ + 1, 0); - Intdx counter = 0; - for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) - { - rowsizevec[i + 1] = rowsizevec[i]; - while (counter < static_cast(this->row_indexes_.size()) && i == this->row_indexes_[counter]) - { - rowsizevec[i+1]++; - counter++; - } - } - return rowsizevec; -} - -/** - * @brief Given set of vector data it will set the values_ into the matrix - * - * @tparam ScalarT - * @tparam Intdx - * @param r - * @param c - * @param v - */ -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 - Intdx aiter = 0; - //iterate for all current values_ in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes_.size()); i++) - { - //pushback values_ when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) - { - this->row_indexes_.push_back(r[aiter]); - this->column_indexes_.push_back(c[aiter]); - this->values_.push_back(v[aiter]); - this->checkIncreaseSize(r[aiter], c[aiter]); - aiter++; - } - if (aiter >= static_cast(r.size())) - { - break; - } - - - if (r[aiter] == this->row_indexes_[i] && c[aiter] == this->column_indexes_[i]) - { - this->values_[i] = v[aiter]; - aiter++; - } - } - //push back rest that was not found sorted - for (Intdx i = aiter; i < static_cast(r.size()); i++) - { - this->row_indexes_.push_back(r[i]); - this->column_indexes_.push_back(c[i]); - this->values_.push_back(v[i]); - - this->checkIncreaseSize(r[i], c[i]); - } - - this->sorted_ = false; - -} - -/** - * @brief BLAS axpy operation on another COO matrix. Will sort both matrices before acting - * - * @tparam ScalarT - * @tparam Intdx - * @param alpha - * @param a - */ -template -inline void COO_Matrix::axpy(ScalarT alpha, COO_Matrix& a) -{ - if (alpha == 0) - { - return; - } - - if (!this->sorted_) - { - this->sortSparse(); - } - if (!a.isSorted()) - { - a.sortSparse(); - } - Intdx m = 0; - Intdx 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 nesscary - this->rows_size_ = this->rows_size_ > m ? this->rows_size_ : m; - this->columns_size_ = this->columns_size_ > n ? this->columns_size_ : n; - - Intdx aiter = 0; - //iterate for all current values_ in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes_.size()); i++) - { - //pushback values_ when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) - { - this->row_indexes_.push_back(r[aiter]); - this->column_indexes_.push_back(c[aiter]); - this->values_.push_back(alpha * val[aiter]); - - this->checkIncreaseSize(r[aiter], c[aiter]); - aiter++; - } - if (aiter >= static_cast(r.size())) - { - break; - } - - - if (r[aiter] == this->row_indexes_[i] && c[aiter] == this->column_indexes_[i]) - { - this->values_[i] += alpha * val[aiter]; - aiter++; - } - } - //push back rest that was not found sorted_ - for (Intdx i = aiter; i < static_cast(r.size()); i++) - { - this->row_indexes_.push_back(r[i]); - this->column_indexes_.push_back(c[i]); - this->values_.push_back(alpha * val[i]); - - this->checkIncreaseSize(r[i], c[i]); - } - - this->sorted_ = false; -} - -/** - * @brief axpy on 3list. - * - * @tparam ScalarT - * @tparam Intdx - * @param alpha - * @param r - * @param c - * @param v - */ -template -inline void COO_Matrix::axpy(ScalarT alpha, std::vector r, std::vector c, std::vector v) -{ - if (alpha == 0) return; - - if (!this->sorted_) - { - this->sortSparse(); - } - - //sort input - this->sortSparseCOO(r, c, v); - - Intdx aiter = 0; - //iterate for all current values_ in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes_.size()); i++) - { - //pushback values_ when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) - { - this->row_indexes_.push_back(r[aiter]); - this->column_indexes_.push_back(c[aiter]); - this->values_.push_back(alpha * v[aiter]); - - this->checkIncreaseSize(r[aiter], c[aiter]); - aiter++; - } - if (aiter >= static_cast(r.size())) - { - break; - } - - - if (r[aiter] == this->row_indexes_[i] && c[aiter] == this->column_indexes_[i]) - { - this->values_[i] += alpha * v[aiter]; - aiter++; - } - } - //push back rest that was not found sorted_ - for (Intdx i = aiter; i < static_cast(r.size()); i++) - { - this->row_indexes_.push_back(r[i]); - this->column_indexes_.push_back(c[i]); - this->values_.push_back(alpha * v[i]); - - this->checkIncreaseSize(r[i], c[i]); - } - - this->sorted_ = false; -} - -/** - * @brief Scale all values_ - * - * @tparam ScalarT - * @tparam Intdx - * @param alpha - */ -template -inline void COO_Matrix::scal(ScalarT alpha) -{ - for (auto i = this->values_.begin(); i < this->values_.end(); i++) - { - *i *= alpha; - } -} - -/** - * @brief Frobenius Norm of the Matrix - * - * @tparam ScalarT - * @tparam Intdx - * @return ScalarT - */ -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; -} - -/** - * @brief Permutate the matrix to a different one. Only changes the coordinates - * - * @tparam ScalarT - * @tparam Intdx - * @param row_perm - * @param 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_indexes_[i] = row_perm[this->row_indexes_[i]]; - this->column_indexes_[i] = col_perm[this->column_indexes_[i]]; - } - this->sorted_ = false; - //cycle sorting maybe useful since permutations are already known -} - -/** - * @brief Permutates the matrix and can change its size efficently - * if size is shrinking and value is to be removed the negative one - * - * @tparam ScalarT - * @tparam Intdx - * @param row_perm size of m - * @param col_perm size of n - * @param m - * @param n - */ -template -inline void COO_Matrix::permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx 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++) - { - if (row_perm[this->row_indexes_[i]] == -1 || col_perm[this->column_indexes_[i]] == -1) - { - this->values_[i] = 0; - } - else - { - this->row_indexes_[i] = row_perm[this->row_indexes_[i]]; - this->column_indexes_[i] = col_perm[this->column_indexes_[i]]; - } - } - this->sorted_ = false; -} - -/** - * @brief Turn matrix into the zero matrix. Does not actual delete memory - * - * @tparam ScalarT - * @tparam Intdx - */ -template -inline void COO_Matrix::zeroMatrix() -{ - //resize doesn't effect capacity if smaller - this->column_indexes_.resize(0); - this->row_indexes_.resize(0); - this->values_.resize(0); - this->sorted_ = true; -} - -template -inline void COO_Matrix::identityMatrix(Intdx n) -{ - //Reset Matrix - this->zeroMatrix(); - for (Intdx i = 0; i < n; i++) - { - this->column_indexes_[i] = i; - this->row_indexes_[i] = i; - this->values_[i] = 1.0; - } - this->sorted_ = true; -} - -/** - * @brief Restructure the sparse matrix for faster accesses and modifications - * - * @tparam ScalarT - * @tparam Intdx - */ -template -inline void COO_Matrix::sortSparse() -{ - this->sortSparseCOO(this->row_indexes_, this->column_indexes_, this->values_); - this->sorted_ = true; -} - -template -inline bool COO_Matrix::isSorted() -{ - return this->sorted_; -} - -template -inline Intdx COO_Matrix::nnz() -{ - return static_cast(this->values_.size); -} - -template -inline std::tuple COO_Matrix::getDimensions() -{ - return std::tuple(this->rows_size_, this->columns_size_); -} - -/** - * @brief Print matrix that is sorted_ - * - * @tparam ScalarT - * @tparam Intdx - */ -template -inline void COO_Matrix::printMatrix() -{ - if (this->sorted_ == false) - { - this->sortSparse(); - } - - std::cout << "Sparse COO Matrix\n"; - std::cout << "(x , y, value)\n"; - for (size_t i = 0; i < this->values_.size(); i++) - { - std::cout << "(" << this->row_indexes_[i] - << ", " << this->column_indexes_[i] - << ", " << this->values_[i] << ")\n"; - } - std::cout << std::flush; -} - -/** - * @brief Find the lowest row cordinate from set of provided cordinates - * - * Assumes rows and columns are sorted_ - * @tparam ScalarT - * @tparam Intdx - * @param r - * @return Intdx - */ -template -inline Intdx COO_Matrix::indexStartRow(const std::vector &rows, Intdx r) -{ - //Specialized Binary Search for Lowest Row - Intdx i1 = 0; - Intdx i2 = rows->size()-1; - Intdx m_smallest = -1; - Intdx m = -1; - while (i1 <= i2) - { - 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; - } - } - return m_smallest; -} - -/** - * @brief Basic binary search - * - * @tparam ScalarT - * @tparam Intdx - * @param rows - * @param columns - * @param ri - * @param ci - * @return Intdx - */ -template -inline Intdx COO_Matrix::sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci) -{ - assert(rows.size() == columns.size()); - //basic binary search - Intdx i1 = 0; - Intdx i2 = rows.size()-1; - Intdx m = 0; - while (i1 <= i2) - { - 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; - } - } - - return m; -} - -template -inline bool COO_Matrix::checkIncreaseSize(Intdx r, Intdx 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; -} - -/** - * @brief Sort a disoreded set of values_. Assume nothing on order. - * - * @todo simple setup. Should add stable sorting since list are pre-sorted_ - * - * @tparam ScalarT - * @tparam Intdx - * @param rows - * @param columns - * @param values_ - */ -template -inline void COO_Matrix::sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &vals) -{ - - //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]]) - { - std::swap(rows[ordervec[i]], rows[ordervec[ordervec[i]]]); - std::swap(columns[ordervec[i]], columns[ordervec[ordervec[i]]]); - std::swap(vals[ordervec[i]], vals[ordervec[ordervec[i]]]); - - //swap orderings - std::swap(ordervec[i], ordervec[ordervec[i]]); - } - - } -} - -template -inline COO_Matrix::COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n) -{ - this->values_ = v; - this->row_indexes_ = r; - this->column_indexes_ = c; - this->rows_size_ = m; - this->columns_size_ = n; - this->sorted_ = false; -} - -template -inline COO_Matrix::COO_Matrix(Intdx m, Intdx n) -{ - this->rows_size_ = m; - this->columns_size_ = n; - this->values_ = std::vector(); - this->row_indexes_ = std::vector(); - this->column_indexes_ = std::vector(); - this->sorted_ = false; -} - -template -inline COO_Matrix::COO_Matrix() -{ - this->rows_size_ = 0; - this->columns_size_ = 0; - this->values_ = std::vector(); - this->row_indexes_ = std::vector(); - this->column_indexes_ = std::vector(); - this->sorted_ = false; -} - -template -COO_Matrix::~COO_Matrix() -{ - -} diff --git a/src/LinearAlgebra/DenseMatrix/CMakeLists.txt b/src/LinearAlgebra/DenseMatrix/CMakeLists.txt new file mode 100644 index 000000000..6b555da41 --- /dev/null +++ b/src/LinearAlgebra/DenseMatrix/CMakeLists.txt @@ -0,0 +1,5 @@ + +add_library(DenseMatrix INTERFACE) +include_directories(DenseMatrix INTERFACE ${CMAKE_CURRENT_LIST_DIR}) + +add_library(GRIDKIT::DenseMatrix ALIAS DenseMatrix) diff --git a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp new file mode 100644 index 000000000..3d9f71cd8 --- /dev/null +++ b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp @@ -0,0 +1,229 @@ +#pragma once + +#include +#include +#include +#include + +#include + +/** + * @brief Class to provide dense matrices. + * + * 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) + { + } + + /** + * @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 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 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_); + } + + /** + * @brief Dense matrix conversion to COO form + * + * @tparam ScalarT + * @tparam IdxT + */ + template + inline void DenseMatrix::toCOO() + { + 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) + { + 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); + } + } + } + values_COO_.setValues(rcord, ccord, vals); + 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) + { + for (IdxT j = 0; j < this->columns_size_; ++j) + { + 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; + +} // namespace LinearAlgebra +} // namespace GridKit diff --git a/src/LinearAlgebra/SparseMatrix/CMakeLists.txt b/src/LinearAlgebra/SparseMatrix/CMakeLists.txt new file mode 100644 index 000000000..e92b5d190 --- /dev/null +++ b/src/LinearAlgebra/SparseMatrix/CMakeLists.txt @@ -0,0 +1,5 @@ + +add_library(SparseMatrix INTERFACE) +include_directories(SparseMatrix INTERFACE ${CMAKE_CURRENT_LIST_DIR}) + +add_library(GRIDKIT::SparseMatrix ALIAS SparseMatrix) diff --git a/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp b/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp new file mode 100644 index 000000000..1858a750c --- /dev/null +++ b/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp @@ -0,0 +1,892 @@ +#ifndef COO_MATRIX_HPP +#define COO_MATRIX_HPP + +#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. + * + * 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(); + + // 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); + + 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(); + + // --- 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 identityMatrix(IdxT n); + + // Resort values_ + void sortSparse(); + bool isSorted(); + IdxT nnz(); + + std::tuple getDimensions(); + + void printMatrix(std::string name = ""); + + 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); +}; + +/** + * @brief Get copy of row index + * + * @tparam ScalarT + * @tparam IdxT + * @param[in] r row index + * @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}}; +} + +/** + * @brief Get all entry pointers. Will sort before returning + * + * @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_}; +} + +/** + * @brief Sorts the data if it's not already sorted + * + * @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_}; +} + +/** + * @brief Returns the data in CSR Format + * + * @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++) + { + 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++; + } + } + 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 + */ +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++) + { + 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++; + } + } + return row_size_vec; +} + +/** + * @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 + * @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++) + { + // 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++; + } + } + // 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 + * @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_) + { + 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->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++; + } + } + // 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 + * @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_) + { + 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->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++; + } + } + // 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 + * @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; + } +} + +/** + * @brief Calculates the Frobenius Norm of the matrix + * + * @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; +} + +/** + * @brief Permutate the matrix to a different one. Only changes the coordinates + * + * @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 +} + +/** + * @brief Permutes the matrix and can change its size efficently + * + * @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 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; + + 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 + { + this->row_indices_[i] = row_perm[this->row_indices_[i]]; + this->column_indices_[i] = col_perm[this->column_indices_[i]]; + } + } + this->sorted_ = false; +} + +/** + * @brief Turn matrix into the zero matrix. Does not actually delete memory + * + * @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; +} + +/** + * @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; +} + +/** + * @brief Restructure the sparse matrix for faster accesses and modifications + * + * @tparam ScalarT + * @tparam IdxT + */ +template +inline void COO_Matrix::sortSparse() +{ + 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_; +} + +/** + * @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()); +} + +template +inline std::tuple COO_Matrix::getDimensions() +{ + return std::tuple(this->rows_size_, this->columns_size_); +} + +/** + * @brief Print matrix in sorted order + * + * @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; +} + +/** + * @brief Find the lowest row cordinate from set of provided coordinates + * + * Assumes rows and columns are sorted + * @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) +{ + // 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]) + { + i2 = m - 1; + } + 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 + * @param[in] rows - row indices + * @param[in] columns - column indices + * @param[in] ri - row index + * @param[in] ci - column index + * @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) +{ + 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]) + { + i2 = m - 1; + } + 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 + * @param[in] r row index + * @param[in] c column index + * @return true if size was increased + */ + +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; +} + +/** + * @brief Sorts unordered COO matrix + * + * 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 + * @param values + */ +template +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++) + { + // 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]]); + } + } +} + +/** + * @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. +} + +/** + * @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. +} + +/** + * @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. +} + +template +COO_Matrix::~COO_Matrix() +{ +} + +#endif diff --git a/src/LinearAlgebra/SparsityPattern/Variable.hpp b/src/LinearAlgebra/SparsityPattern/Variable.hpp new file mode 100644 index 000000000..eb97740ce --- /dev/null +++ b/src/LinearAlgebra/SparsityPattern/Variable.hpp @@ -0,0 +1,320 @@ +/** + \file Variable.hpp +*/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace GridKit +{ +namespace Sparse +{ + + /** + @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); + + 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); + }; + + //------------------------------------ + // 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 std::istream& operator>>(std::istream& is, Variable& v); + +} // namespace Sparse +} // namespace GridKit + +#include "VariableImplementation.hpp" +#include "VariableOperators.hpp" diff --git a/src/LinearAlgebra/SparsityPattern/VariableImplementation.hpp b/src/LinearAlgebra/SparsityPattern/VariableImplementation.hpp new file mode 100644 index 000000000..b603af5dd --- /dev/null +++ b/src/LinearAlgebra/SparsityPattern/VariableImplementation.hpp @@ -0,0 +1,207 @@ +/** + \file VariableImplementation.hpp +*/ + +#pragma once + +namespace GridKit +{ +namespace Sparse +{ + /** + @brief Returns the list of derivatives. + */ + const Variable::DependencyMap& Variable::getDependencies() const + { + assert(dependencies_ != 0); + return *dependencies_; + } + + /** + @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) + { + setVariableNumber(offset); // define global variable number + setFixed(false); // not a constant + + 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; + } + + /** + @brief Multiplies each partial derivative of @a this by @a c. + */ + void Variable::scaleDependencies(double 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 << "]"; + } + } + + //------------------------------------ + // compound assignment operators + //------------------------------------ + + /** + @brief Compound addition-assignment operator. Right hand + side is a built-in double type. + */ + Variable& Variable::operator+=(const double& rhs) + { + value_ += rhs; + return *this; + } + + /** + @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 value of *this + value_ += rhs.value_; + + return *this; + } + + // -= + /** + @brief Compound subtraction-assignment operator. Right hand + side is a built-in double type. + */ + Variable& Variable::operator-=(const double& rhs) + { + value_ -= rhs; + return *this; + } + + /** + @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 value of *this + value_ -= rhs.value_; + + return *this; + } + + // *= + /** + @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 value + value_ *= rhs; + + return *this; + } + + /** + @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_); + + // 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_; + + return *this; + } + + // /= + /** + @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; + + // compute derivatives of @a *this + scaleDependencies(inverseRhs); + + value_ *= inverseRhs; + return *this; + } + + /** + @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; + + // 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; + + return *this; + } + +} // namespace Sparse +} // namespace GridKit diff --git a/src/LinearAlgebra/SparsityPattern/VariableOperators.hpp b/src/LinearAlgebra/SparsityPattern/VariableOperators.hpp new file mode 100644 index 000000000..3681d99e5 --- /dev/null +++ b/src/LinearAlgebra/SparsityPattern/VariableOperators.hpp @@ -0,0 +1,356 @@ +/** + \file VariableOperators.hpp + +*/ +#pragma once + +namespace GridKit +{ +namespace Sparse +{ + //------------------------------------ + // non-member operators and functions + //------------------------------------ + + // unary - + const Variable operator-(const Variable& v) + { + return -1.0 * v; + } + + // + + const Variable operator+(const Variable& lhs, const Variable& rhs) + { + return Variable(lhs) += rhs; + } + + const Variable operator+(const Variable& lhs, const double& rhs) + { + return Variable(lhs) += rhs; + } + + const Variable operator+(const double& lhs, const Variable& rhs) + { + return Variable(rhs) += lhs; + } + + // - + const Variable operator-(const Variable& lhs, const Variable& rhs) + { + return Variable(lhs) -= rhs; + } + + const Variable operator-(const Variable& lhs, const double& rhs) + { + return Variable(lhs) -= rhs; + } + + const Variable operator-(const double& lhs, const Variable& rhs) + { + return Variable(lhs) -= rhs; + } + + // * + const Variable operator*(const Variable& lhs, const Variable& rhs) + { + return Variable(lhs) *= rhs; + } + + const Variable operator*(const Variable& lhs, const double& rhs) + { + return Variable(lhs) *= rhs; + } + + const Variable operator*(const double& lhs, const Variable& rhs) + { + return Variable(lhs) *= rhs; + } + + // / + const Variable operator/(const Variable& lhs, const Variable& rhs) + { + return Variable(lhs) /= rhs; + } + + const Variable operator/(const Variable& lhs, const double& rhs) + { + return Variable(lhs) /= rhs; + } + + const Variable operator/(const double& lhs, const Variable& rhs) + { + return Variable(lhs) /= rhs; + } + + // == + bool operator==(const Variable& lhs, const Variable& rhs) + { + return lhs.getValue() == rhs.getValue(); + } + + bool operator==(const Variable& lhs, const double& rhs) + { + return lhs.getValue() == rhs; + } + + bool operator==(const double& lhs, const Variable& rhs) + { + return lhs == rhs.getValue(); + } + + // != + bool operator!=(const Variable& lhs, const Variable& rhs) + { + return !(lhs.getValue() == rhs.getValue()); + } + + bool operator!=(const Variable& lhs, const double& rhs) + { + return !(lhs.getValue() == rhs); + } + + bool operator!=(const double& lhs, const Variable& rhs) + { + return !(lhs == rhs.getValue()); + } + + // < + bool operator<(const Variable& lhs, const Variable& rhs) + { + return lhs.getValue() < rhs.getValue(); + } + + bool operator<(const Variable& lhs, const double& rhs) + { + return lhs.getValue() < rhs; + } + + bool operator<(const double& lhs, const Variable& rhs) + { + return lhs < rhs.getValue(); + } + + // > + bool operator>(const Variable& lhs, const Variable& rhs) + { + return lhs.getValue() > rhs.getValue(); + } + + bool operator>(const Variable& lhs, const double& rhs) + { + return lhs.getValue() > rhs; + } + + bool operator>(const double& lhs, const Variable& rhs) + { + return lhs > rhs.getValue(); + } + + // <= + bool operator<=(const Variable& lhs, const Variable& rhs) + { + return lhs < rhs || lhs == rhs; + } + + bool operator<=(const Variable& lhs, const double& rhs) + { + return lhs < rhs || lhs == rhs; + } + + bool operator<=(const double& lhs, const Variable& rhs) + { + return lhs < rhs || lhs == rhs; + } + + // >= + bool operator>=(const Variable& lhs, const Variable& rhs) + { + return lhs > rhs || lhs == rhs; + } + + bool operator>=(const Variable& lhs, const double& rhs) + { + return lhs > rhs || lhs == rhs; + } + + bool operator>=(const double& lhs, const Variable& 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; + } + + /** + @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; + } + + /** + @brief Stream extraction operator for variables. + */ + std::istream& operator>>(std::istream& is, Variable& v) + { + return is >> v(); + } + + //------------------------------------------- + // definitions of cmath functions derivatives + //------------------------------------------- + + /// Derivative of sine + inline double sin_derivative(double x) + { + return std::cos(x); + } + + /// Derivative of cosine + inline double cos_derivative(double x) + { + return -std::sin(x); + } + + /// Derivative of tangent + inline double tan_derivative(double 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); + } + + /// Derivative of arc cosine + inline double acos_derivative(double 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); + } + + /// Derivative of hyperbolic sine + inline double sinh_derivative(double x) + { + return std::cosh(x); + } + + /// Derivative of hyperbolic cosine + inline double cosh_derivative(double x) + { + return std::sinh(x); + } + + /// Derivative of hyperbolic tangent + inline double tanh_derivative(double 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); + } + + /// Derivative of hyperbolic arc cosine + inline double acosh_derivative(double x) + { + 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); + } + + /// Derivative of exponential function. + inline double exp_derivative(double x) + { + return std::exp(x); + } + + /// Derivative of natural logarithm function. + inline double log_derivative(double 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; + } + + /// Derivative of square root function. + inline double sqrt_derivative(double 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; + } + +} // namespace Sparse +} // namespace GridKit + +// 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) + +#undef IMPL_FUN_1 + +} // namespace std diff --git a/src/Model/CMakeLists.txt b/src/Model/CMakeLists.txt index 1d14a5ed1..0631f71e8 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/Evaluator.hpp b/src/Model/Evaluator.hpp new file mode 100644 index 000000000..4c1a2b5f6 --- /dev/null +++ b/src/Model/Evaluator.hpp @@ -0,0 +1,100 @@ +#pragma once + +#include + +#include +#include + +namespace GridKit +{ +namespace Model +{ + /*! + * @brief Abstract class describing a model. + * + */ + template + class Evaluator + { + public: + typedef typename GridKit::ScalarTraits::real_type real_type; + + Evaluator() + { + } + + virtual ~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 int initializeAdjoint() = 0; + virtual int evaluateAdjointResidual() = 0; + // virtual int evaluateAdjointJacobian() = 0; + virtual int evaluateAdjointIntegrand() = 0; + + virtual IdxT size() = 0; + virtual IdxT nnz() = 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 std::vector& y() = 0; + virtual const std::vector& y() const = 0; + + virtual std::vector& yp() = 0; + virtual const std::vector& yp() const = 0; + + virtual std::vector& tag() = 0; + virtual const std::vector& tag() const = 0; + + virtual std::vector& yB() = 0; + virtual const std::vector& yB() const = 0; + + virtual std::vector& ypB() = 0; + virtual const std::vector& ypB() const = 0; + + virtual std::vector& param() = 0; + virtual const std::vector& param() 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 std::vector& getResidual() = 0; + virtual const std::vector& getResidual() const = 0; + + virtual COO_Matrix& getJacobian() = 0; + virtual const COO_Matrix& getJacobian() const = 0; + + virtual std::vector& getIntegrand() = 0; + virtual const std::vector& getIntegrand() 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 GridKit diff --git a/src/Model/PhasorDynamics/Branch/Branch.cpp b/src/Model/PhasorDynamics/Branch/Branch.cpp index b8782a654..b06da28d9 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.cpp +++ b/src/Model/PhasorDynamics/Branch/Branch.cpp @@ -1,224 +1,200 @@ -/* - * - * Copyright (c) 2017, Lawrence Livermore National Security, LLC. - * Produced at the Lawrence Livermore National Laboratory. - * Written by Slaven Peles and Duan Nan . - * 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 - * modification, are permitted provided that the following conditions are met: - * - 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 - * 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 - * 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 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL - * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * 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 - * 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 - * Nuclear Security Administration under Contract DE-AC52-07NA27344. +/** + * @file Branch.hpp + * @author Slaven Peles (peless@ornl.gov) + * @brief Definition of a phasor dynamics branch model. * - * 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. + * The model uses Cartesian coordinates. * */ -#include -#include -#include -#include - #include "Branch.hpp" -namespace ModelLib { // change to GridKit -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 - */ - -template -Branch::Branch(bus_type* bus1, bus_type* bus2) - : R_(0.0), - X_(0.01), - G_(0.0), - B_(0.0), - bus1ID_(0), - bus2ID_(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), - bus1ID_(0), - bus2ID_(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), - bus1ID_(data.fbus), - bus2ID_(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; - return 0; -} - -/** - * Initialization of the branch model - * - */ -template -int Branch::initialize() -{ - return 0; -} - -/** - * \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() -{ - // 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(); - - return 0; -} - -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() -{ - // std::cout << "Evaluate Integrand for Branch..." << std::endl; - return 0; -} +#include +#include -template -int Branch::initializeAdjoint() -{ - //std::cout << "Initialize adjoint for Branch..." << std::endl; - return 0; -} +#include +#include -template -int Branch::evaluateAdjointResidual() +namespace GridKit { - // std::cout << "Evaluate adjoint residual for Branch..." << std::endl; - return 0; -} - -template -int Branch::evaluateAdjointIntegrand() +namespace PhasorDynamics { - // std::cout << "Evaluate adjoint Integrand for Branch..." << std::endl; - return 0; -} - -// Available template instantiations -template class Branch; -template class Branch; - -} //namespace PhasorDynamics -} //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) + : bus1_(bus1), bus2_(bus2), R_(0.0), X_(0.01), G_(0.0), B_(0.0), bus1ID_(0), bus2ID_(0) + { + size_ = 0; + } + + /** + * @brief Construct a new Branch + * + * @tparam ScalarT - scalar type + * @tparam IdxT - matrix/vector index type + * @param bus1 - pointer to bus-1 + * @param bus2 - pointer to bus-2 + * @param R - line series resistance + * @param X - line series reactance + * @param G - line shunt conductance + * @param B - line shunt charging + */ + template + Branch::Branch(bus_type* bus1, bus_type* bus2, real_type R, 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) + { + } + + 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) + { + size_ = 0; + } + + /** + * @brief Destroy the Branch + * + * @tparam ScalarT + * @tparam IdxT + */ + 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() + { + return 0; + } + + /** + * \brief Identify differential variables. + */ + template + int Branch::tagDifferentiable() + { + 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_); + + 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; + } + + /** + * @brief Jacobian evaluation not implemented yet + * + * @tparam ScalarT - scalar data type + * @tparam IdxT - matrix index data type + * @return int - error code, 0 = success + */ + template + int Branch::evaluateJacobian() + { + 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 + */ + template + int Branch::evaluateIntegrand() + { + // 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 + */ + template + int Branch::initializeAdjoint() + { + // 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 + */ + template + int Branch::evaluateAdjointResidual() + { + // 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 + */ + template + int Branch::evaluateAdjointIntegrand() + { + // std::cout << "Evaluate adjoint Integrand for Branch..." << std::endl; + return 0; + } + + // Available template instantiations + template class Branch; + template class Branch; + +} // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/Branch/Branch.hpp b/src/Model/PhasorDynamics/Branch/Branch.hpp index e8aa3df03..07f3716a3 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.hpp +++ b/src/Model/PhasorDynamics/Branch/Branch.hpp @@ -1,132 +1,86 @@ -/* +/** + * @file Branch.hpp + * @author Slaven Peles (peless@ornl.gov) + * @brief Declaration of a phasor dynamics branch model. * - * Copyright (c) 2017, Lawrence Livermore National Security, LLC. - * Produced at the Lawrence Livermore National Laboratory. - * Written by Slaven Peles and Duan Nan . - * 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 - * modification, are permitted provided that the following conditions are met: - * - 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 - * 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 - * 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 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL - * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * 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 - * 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 - * 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. + * The model uses Cartesian coordinates. * */ - #pragma once -#include +#include // Forward declarations. namespace GridKit { namespace PowerSystemData { - template struct BranchData; -} + template + struct BranchData; } +} // namespace GridKit -namespace ModelLib +namespace GridKit { namespace PhasorDynamics { - template class Bus; -} + template + class BusBase; } +} // namespace GridKit -namespace ModelLib +namespace GridKit { 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 - class Branch : public ModelEvaluatorImpl + template + class Branch : public Component { - 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 = Bus; - using real_type = typename ModelEvaluatorImpl::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; 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, real_type R, real_type X, real_type G, real_type B); Branch(bus_type* bus1, bus_type* bus2, BranchData& data); virtual ~Branch(); - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); + virtual int allocate() override; + virtual int initialize() override; + virtual int tagDifferentiable() override; + virtual int evaluateResidual() override; + virtual int evaluateJacobian() override; + virtual int evaluateIntegrand() override; - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + virtual int initializeAdjoint() override; + virtual int evaluateAdjointResidual() override; + // virtual int evaluateAdjointJacobian() override; + virtual int evaluateAdjointIntegrand() override; - void updateTime(real_type t, real_type a) + virtual void updateTime(real_type /* t */, real_type /* a */) override { } @@ -194,14 +148,14 @@ namespace PhasorDynamics } private: - real_type R_; - real_type X_; - real_type G_; - real_type B_; + 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_; }; } // namespace PhasorDynamics diff --git a/src/Model/PhasorDynamics/Branch/CMakeLists.txt b/src/Model/PhasorDynamics/Branch/CMakeLists.txt index ba05a10a9..44523fbd3 100644 --- a/src/Model/PhasorDynamics/Branch/CMakeLists.txt +++ b/src/Model/PhasorDynamics/Branch/CMakeLists.txt @@ -1,63 +1,8 @@ -# -# 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 -# modification, are permitted provided that the following conditions are met: -# - 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 -# 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 -# 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 -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL -# SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# 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 -# 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 -# 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. -# # [[ # Author(s): # - Cameron Rutherford +# - Slaven Peles # ]] gridkit_add_library(phasor_dynamics_branch @@ -65,4 +10,3 @@ gridkit_add_library(phasor_dynamics_branch Branch.cpp OUTPUT_NAME gridkit_phasor_dynamics_branch) - diff --git a/src/Model/PhasorDynamics/Bus/Bus.cpp b/src/Model/PhasorDynamics/Bus/Bus.cpp index e7e4e14c8..52e6afd4f 100644 --- a/src/Model/PhasorDynamics/Bus/Bus.cpp +++ b/src/Model/PhasorDynamics/Bus/Bus.cpp @@ -1,227 +1,213 @@ -/* - * - * 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 - * modification, are permitted provided that the following conditions are met: - * - 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 - * 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 - * 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 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL - * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * 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 - * 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 - * 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. - * - */ -#include -#include - -#include #include "Bus.hpp" -namespace ModelLib // change to 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) - : 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; -} - - -template -int Bus::tagDifferentiable() -{ - tag_[0] = false; - tag_[1] = false; - return 0; -} +#include +#include +#include -/*! - * @brief initialize method sets bus variables to stored initial values. - */ -template -int Bus::initialize() +namespace GridKit { - // 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() +namespace PhasorDynamics { - // 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 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; -} - -template -int Bus::evaluateAdjointResidual() -{ - fB_[0] = 0.0; - fB_[1] = 0.0; - - return 0; -} - -// Available template instantiations -template class Bus; -template class Bus; - -} // namespace PhasorDynamic -} // namespace ModelLib + /*! + * @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 f3a9e5cd7..1ca6c845f 100644 --- a/src/Model/PhasorDynamics/Bus/Bus.hpp +++ b/src/Model/PhasorDynamics/Bus/Bus.hpp @@ -1,66 +1,7 @@ -/* - * - * 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 - * modification, are permitted provided that the following conditions are met: - * - 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 - * 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 - * 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 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL - * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * 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 - * 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 - * 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. - * - */ #pragma once -#include - +#include // Forward declaration of BusData structure namespace GridKit @@ -70,9 +11,9 @@ namespace PowerSystemData template struct BusData; } -} +} // namespace GridKit -namespace ModelLib // change to GridKit +namespace GridKit { namespace PhasorDynamics { @@ -84,20 +25,20 @@ namespace PhasorDynamics * * */ - template - class Bus : public ModelEvaluatorImpl + template + class Bus : public BusBase { - using ModelEvaluatorImpl::size_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::yp_; - using ModelEvaluatorImpl::yB_; - using ModelEvaluatorImpl::ypB_; - using ModelEvaluatorImpl::f_; - using ModelEvaluatorImpl::fB_; - using ModelEvaluatorImpl::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 ModelEvaluatorImpl::real_type; + using real_type = typename BusBase::real_type; using BusData = GridKit::PowerSystemData::BusData; Bus(); @@ -105,104 +46,105 @@ namespace PhasorDynamics Bus(BusData& data); virtual ~Bus(); - virtual int allocate(); - virtual int tagDifferentiable(); - virtual int initialize(); - virtual int evaluateResidual(); - virtual int initializeAdjoint(); - virtual int evaluateAdjointResidual(); + 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() + virtual ScalarT& Vr() override { return y_[0]; } - virtual const ScalarT& Vr() const + virtual const ScalarT& Vr() const override { return y_[0]; } - virtual ScalarT& Vi() + virtual ScalarT& Vi() override { return y_[1]; } - virtual const ScalarT& Vi() const + virtual const ScalarT& Vi() const override { return y_[1]; } - virtual ScalarT& Ir() + virtual ScalarT& Ir() override { return f_[0]; } - virtual const ScalarT& Ir() const + virtual const ScalarT& Ir() const override { return f_[0]; } - virtual ScalarT& Ii() + virtual ScalarT& Ii() override { return f_[1]; } - virtual const ScalarT& Ii() const + virtual const ScalarT& Ii() const override { return f_[1]; } - virtual ScalarT& lambdaIr() - { - return yB_[0]; - } - - virtual const ScalarT& lambdaIr() const - { - return yB_[0]; - } + // virtual ScalarT& VrB() override + // { + // return yB_[0]; + // } - virtual ScalarT& lambdaIi() - { - return yB_[1]; - } + // virtual const ScalarT& VrB() const override + // { + // return yB_[0]; + // } - virtual const ScalarT& lambdaIi() const - { - return yB_[1]; - } + // virtual ScalarT& ViB() override + // { + // return yB_[1]; + // } - virtual ScalarT& IrB() - { - return fB_[0]; - } + // virtual const ScalarT& ViB() const override + // { + // return yB_[1]; + // } - virtual const ScalarT& IrB() const - { - return fB_[0]; - } + // virtual ScalarT& IrB() override + // { + // return fB_[0]; + // } - virtual ScalarT& IiB() - { - return fB_[1]; - } + // virtual const ScalarT& IrB() const override + // { + // return fB_[0]; + // } - virtual const ScalarT& IiB() const - { - return fB_[1]; - } + // virtual ScalarT& IiB() override + // { + // return fB_[1]; + // } - // virtual const int BusType() const + // virtual const ScalarT& IiB() const override // { - // return BaseBus::BusType::PQ; + // return fB_[1]; // } private: - // Default initial values for voltage and phase on PQ bus 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 new file mode 100644 index 000000000..2c977f2bb --- /dev/null +++ b/src/Model/PhasorDynamics/Bus/BusInfinite.cpp @@ -0,0 +1,197 @@ + +#include "BusInfinite.hpp" + +#include +#include + +#include + +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 PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/Bus/BusInfinite.hpp b/src/Model/PhasorDynamics/Bus/BusInfinite.hpp new file mode 100644 index 000000000..4b3a65080 --- /dev/null +++ b/src/Model/PhasorDynamics/Bus/BusInfinite.hpp @@ -0,0 +1,155 @@ + +#pragma once + +#include + +// Forward declaration of BusData structure +namespace GridKit +{ +namespace PowerSystemData +{ + template + struct BusData; +} +} // namespace GridKit + +namespace GridKit +{ +namespace PhasorDynamics +{ + /*! + * @brief Implementation of an "infinite" bus. + * + * + * + */ + 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_; + + 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_; + // } + + 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}; + }; + +} // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/Bus/CMakeLists.txt b/src/Model/PhasorDynamics/Bus/CMakeLists.txt index 356b7f517..b11fe63ac 100644 --- a/src/Model/PhasorDynamics/Bus/CMakeLists.txt +++ b/src/Model/PhasorDynamics/Bus/CMakeLists.txt @@ -1,68 +1,12 @@ -# -# 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 -# modification, are permitted provided that the following conditions are met: -# - 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 -# 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 -# 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 -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL -# SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# 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 -# 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 -# 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. -# - # [[ # Author(s): # - Cameron Rutherford +# - Slaven Peles #]] gridkit_add_library(phasor_dynamics_bus SOURCES Bus.cpp + BusInfinite.cpp OUTPUT_NAME gridkit_phasor_dynamics_bus) - diff --git a/src/Model/PhasorDynamics/BusBase.hpp b/src/Model/PhasorDynamics/BusBase.hpp new file mode 100644 index 000000000..7ac53fcb1 --- /dev/null +++ b/src/Model/PhasorDynamics/BusBase.hpp @@ -0,0 +1,281 @@ +#pragma once + +#include + +#include + +namespace GridKit +{ +namespace PhasorDynamics +{ + /*! + * @brief BusBase model implementation base class. + * + */ + template + 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_; + } + + protected: + const IdxT bus_id_{static_cast(-1)}; + + 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 yB_; + std::vector ypB_; + std::vector fB_; + std::vector gB_; + + COO_Matrix J_; + + std::vector param_; + std::vector param_up_; + std::vector param_lo_; + + real_type time_; + real_type alpha_; + + real_type rtol_; + real_type atol_; + + IdxT max_steps_; + }; + +} // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/CMakeLists.txt b/src/Model/PhasorDynamics/CMakeLists.txt index d88233100..77dc2d3e3 100644 --- a/src/Model/PhasorDynamics/CMakeLists.txt +++ b/src/Model/PhasorDynamics/CMakeLists.txt @@ -1,60 +1,3 @@ -# -# 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 -# modification, are permitted provided that the following conditions are met: -# - 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 -# 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 -# 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 -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL -# SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# 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 -# 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 -# 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. -# - # [[ # Author(s): # - Cameron Rutherford @@ -62,3 +5,5 @@ add_subdirectory(Branch) add_subdirectory(Bus) +add_subdirectory(Load) +add_subdirectory(SynchronousMachine) diff --git a/src/Model/PhasorDynamics/Component.hpp b/src/Model/PhasorDynamics/Component.hpp new file mode 100644 index 000000000..4cb677207 --- /dev/null +++ b/src/Model/PhasorDynamics/Component.hpp @@ -0,0 +1,259 @@ +#pragma once + +#include + +#include + +namespace GridKit +{ +namespace PhasorDynamics +{ + + /*! + * @brief Component model implementation base class. + * + */ + template + 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_; + } + + protected: + 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 yB_; + std::vector ypB_; + std::vector fB_; + std::vector gB_; + + COO_Matrix J_; + + 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 component_id_; + }; + +} // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/Exciter/README.md b/src/Model/PhasorDynamics/Exciter/README.md index 9ba48ca10..79b743b37 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 new file mode 100644 index 000000000..0f1659a71 --- /dev/null +++ b/src/Model/PhasorDynamics/Load/CMakeLists.txt @@ -0,0 +1,12 @@ + + +# [[ +# Author(s): +# - Cameron Rutherford +# ]] + +gridkit_add_library(phasor_dynamics_load + SOURCES + Load.cpp + OUTPUT_NAME + gridkit_phasor_dynamics_load) diff --git a/src/Model/PhasorDynamics/Load/Load.cpp b/src/Model/PhasorDynamics/Load/Load.cpp new file mode 100644 index 000000000..3b9e4b78a --- /dev/null +++ b/src/Model/PhasorDynamics/Load/Load.cpp @@ -0,0 +1,171 @@ + +#include "Load.hpp" + +#include +#include + +#include +#include + +namespace GridKit +{ +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 + */ + + template + Load::Load(bus_type* bus) : bus_(bus) + { + size_ = 0; + } + + template + Load::Load(bus_type* bus, real_type R, real_type X) : bus_(bus), R_(R), X_(X) + + { + } + + template + Load::Load(bus_type* bus, IdxT component_id) : bus_(bus) + + { + size_ = 0; + component_id_ = component_id; + } + + template + Load::~Load() + { + // std::cout << "Destroy Load..." << std::endl; + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int Load::allocate() + { + // std::cout << "Allocate Load..." << std::endl; + return 0; + } + + /** + * Initialization of the load model + * + */ + template + int Load::initialize() + { + return 0; + } + + /** + * \brief Identify differential variables. + */ + template + int Load::tagDifferentiable() + { + 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_); + + Ir() += -g * Vr() - b * Vi(); + Ii() += b * Vr() - g * Vi(); + + 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 + */ + template + int Load::evaluateJacobian() + { + 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 + */ + template + int Load::evaluateIntegrand() + { + // 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 + */ + template + int Load::initializeAdjoint() + { + // 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 + */ + template + int Load::evaluateAdjointResidual() + { + // 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 + */ + template + int Load::evaluateAdjointIntegrand() + { + // std::cout << "Evaluate adjoint Integrand for Load..." << std::endl; + return 0; + } + + // Available template instantiations + template class Load; + template class Load; + +} // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/Load/Load.hpp b/src/Model/PhasorDynamics/Load/Load.hpp new file mode 100644 index 000000000..8c635a0d1 --- /dev/null +++ b/src/Model/PhasorDynamics/Load/Load.hpp @@ -0,0 +1,109 @@ + + +#pragma once + +#include + +// Forward declarations. +namespace GridKit +{ +namespace PhasorDynamics +{ + template + class BusBase; +} +} // namespace GridKit + +namespace GridKit +{ +namespace PhasorDynamics +{ + /*! + * @brief Implementation of a constant load. + * + */ + 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; + + 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 + { + } + + public: + void setR(real_type R) + { + R_ = R; + } + + 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(); + } + + private: + bus_type* bus_{nullptr}; + real_type R_{0.1}; + real_type X_{0.01}; + }; + +} // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/Load/README.md b/src/Model/PhasorDynamics/Load/README.md new file mode 100644 index 000000000..24d2c13ee --- /dev/null +++ b/src/Model/PhasorDynamics/Load/README.md @@ -0,0 +1,28 @@ +# Load Model + +Load modeling is one of the more complex aspects of power system dynamics. +The simplest model, which is used for this challenge problem, is to model +the load as a complex shunt impedance with the impedance given by: +``` math +Z = R + jX +``` +where $`R`$ is the load resistance, $`X`$ is the load reactance. The current +drawn by the load is then obtained as +```math +I_{\mathrm{load}} = \frac{V_{\mathrm{bus}}}{Z}, +``` +where $`V_{bus}`$ is the voltage on the bus to which the load is connected. + +After some algebra, one obtains expressions for real and imaginary components +for the currents entering the bus: +```math +I_{r} = -g V_{r} - b V_{i} +``` + +```math +I_{i} = b V_{r} - g V_{i} +``` +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 new file mode 100644 index 000000000..f8239be47 --- /dev/null +++ b/src/Model/PhasorDynamics/SynchronousMachine/CMakeLists.txt @@ -0,0 +1,12 @@ + +# [[ +# Author(s): +# - Cameron Rutherford +# - Slaven Peles +# ]] + +gridkit_add_library(phasor_dynamics_synchronous_machine + SOURCES + 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 a234956b5..4d4c87900 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/PhasorDynamics/SynchronousMachine/SynchronousMachine.cpp b/src/Model/PhasorDynamics/SynchronousMachine/SynchronousMachine.cpp new file mode 100644 index 000000000..2b49cb93f --- /dev/null +++ b/src/Model/PhasorDynamics/SynchronousMachine/SynchronousMachine.cpp @@ -0,0 +1,170 @@ +/** + * @file SynchronousMachine.hpp + * @author Slaven Peles (peless@ornl.gov) + * @brief Definition of a phasor dynamics branch model. + * + * The model uses Cartesian coordinates. + * + */ + +#include "SynchronousMachine.hpp" + +#include +#include + +#include +#include + +namespace GridKit +{ +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 + */ + template + SynchronousMachine::SynchronousMachine(bus_type* bus) + : bus_(bus), R_(0.0), X_(0.01), G_(0.0), B_(0.0) + { + size_ = 0; + } + + /** + * @brief Destroy the SynchronousMachine + * + * @tparam ScalarT + * @tparam IdxT + */ + template + SynchronousMachine::~SynchronousMachine() + { + // std::cout << "Destroy SynchronousMachine..." << std::endl; + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int SynchronousMachine::allocate() + { + // std::cout << "Allocate SynchronousMachine..." << std::endl; + return 0; + } + + /** + * Initialization of the branch model + * + */ + template + int SynchronousMachine::initialize() + { + return 0; + } + + /** + * \brief Identify differential variables. + */ + template + int SynchronousMachine::tagDifferentiable() + { + 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_); + + 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 + */ + template + int SynchronousMachine::evaluateJacobian() + { + 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 + */ + template + int SynchronousMachine::evaluateIntegrand() + { + // 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 + */ + template + int SynchronousMachine::initializeAdjoint() + { + // 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 + */ + template + int SynchronousMachine::evaluateAdjointResidual() + { + // 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 + */ + template + int SynchronousMachine::evaluateAdjointIntegrand() + { + // std::cout << "Evaluate adjoint Integrand for SynchronousMachine..." << std::endl; + return 0; + } + + // Available template instantiations + template class SynchronousMachine; + template class SynchronousMachine; + +} // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/SynchronousMachine/SynchronousMachine.hpp b/src/Model/PhasorDynamics/SynchronousMachine/SynchronousMachine.hpp new file mode 100644 index 000000000..a4ab5eb8c --- /dev/null +++ b/src/Model/PhasorDynamics/SynchronousMachine/SynchronousMachine.hpp @@ -0,0 +1,127 @@ +/** + * @file SynchronousMachine.hpp + * @author Slaven Peles (peless@ornl.gov) + * @brief Declaration of a phasor dynamics branch model. + * + * The model uses Cartesian coordinates. + * + */ +#pragma once + +#include + +// Forward declarations. +namespace GridKit +{ +namespace PhasorDynamics +{ + template + class BusBase; +} +} // namespace GridKit + +namespace GridKit +{ +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 + 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; + + public: + 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 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; + } + + private: + 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_; + }; + +} // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/SystemModel.hpp b/src/Model/PhasorDynamics/SystemModel.hpp new file mode 100644 index 000000000..db8120e0a --- /dev/null +++ b/src/Model/PhasorDynamics/SystemModel.hpp @@ -0,0 +1,658 @@ +#pragma once + +#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; + } + + /** + * @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_) + { + bus->allocate(); + size_ += bus->size(); + size_quad_ += bus->sizeQuadrature(); + size_param_ += bus->sizeParams(); + } + + // Allocate all components + for (const auto& component : components_) + { + component->allocate(); + size_ += component->size(); + size_quad_ += component->sizeQuadrature(); + size_param_ += 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_param_); + + param_.resize(size_param_); + param_lo_.resize(size_param_); + param_up_.resize(size_param_); + + assert(size_quad_ == 1 or size_quad_ == 0); + + return 0; + } + + /** + * @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() + { + // 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) + { + 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_) + { + component->initialize(); + } + + for (const auto& component : components_) + { + 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() + { + // 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) + { + tag_[offset + j] = bus->tag()[j]; + } + offset += bus->size(); + } + + for (const auto& component : components_) + { + 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() + { + // 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]; + } + 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 (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 (IdxT j = 0; j < bus->size(); ++j) + { + f_[resOffset + j] = bus->getResidual()[j]; + } + resOffset += bus->size(); + } + + for (const auto& component : components_) + { + 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 integrands for the system quadratures. + */ + int evaluateIntegrand() + { + // 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]; + } + 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 (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 (IdxT j = 0; j < bus->sizeQuadrature(); ++j) + { + g_[intOffset + j] = bus->getIntegrand()[j]; + } + intOffset += bus->sizeQuadrature(); + } + + for (const auto& component : components_) + { + 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; + IdxT optOffset = 0; + + // Update bus variables and optimization parameters + for (const auto& bus : buses_) + { + 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 (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_) + { + 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_) + { + 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() + { + IdxT varOffset = 0; + IdxT optOffset = 0; + + // Update variables in component models + 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(); + } + + 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) + { + fB_[resOffset + j] = bus->getAdjointResidual()[j]; + } + resOffset += bus->size(); + } + + for (const auto& component : components_) + { + 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() + { + // 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_param_; ++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); + } + } + + void addBus(bus_type* bus) + { + buses_.push_back(bus); + } + + void addComponent(component_type* component) + { + components_.push_back(component); + } + + private: + std::vector buses_; + std::vector components_; + + }; // class SystemModel + +} // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PowerElectronics/CMakeLists.txt b/src/Model/PowerElectronics/CMakeLists.txt index 2cfe97bc2..d703d3006 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 62efc1795..e91fcb5ed 100644 --- a/src/Model/PowerElectronics/Capacitor/CMakeLists.txt +++ b/src/Model/PowerElectronics/Capacitor/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_capacitor +gridkit_add_library(power_elec_capacitor SOURCES Capacitor.cpp OUTPUT_NAME - gridkit_powerelec_capacitor) \ No newline at end of file + gridkit_power_elec_capacitor) diff --git a/src/Model/PowerElectronics/Capacitor/Capacitor.cpp b/src/Model/PowerElectronics/Capacitor/Capacitor.cpp index 779b8a627..0901f010e 100644 --- a/src/Model/PowerElectronics/Capacitor/Capacitor.cpp +++ b/src/Model/PowerElectronics/Capacitor/Capacitor.cpp @@ -1,12 +1,13 @@ +#include "Capacitor.hpp" -#include #include +#include #include -#include "Capacitor.hpp" -namespace ModelLib { +namespace GridKit +{ /*! * @brief Constructor for Capacitor @@ -17,14 +18,13 @@ namespace ModelLib { */ template -Capacitor::Capacitor(IdxT id, ScalarT C) - : C_(C) +Capacitor::Capacitor(IdxT id, ScalarT C) : C_(C) { - size_ = 3; - n_intern_ = 1; - n_extern_ = 2; - extern_indices_ = {0,1}; - idc_ = id; + size_ = 3; + n_intern_ = 1; + n_extern_ = 2; + extern_indices_ = {0, 1}; + idc_ = id; } template @@ -41,7 +41,7 @@ int Capacitor::allocate() y_.resize(size_); yp_.resize(size_); f_.resize(size_); - + return 0; } @@ -70,41 +70,41 @@ int Capacitor::tagDifferentiable() template int Capacitor::evaluateResidual() { - //input + // 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 + * + * @tparam ScalarT + * @tparam IdxT + * @return int */ template int Capacitor::evaluateJacobian() { - J_.zeroMatrix(); - //Create dF/dy - std::vector rcord{2,2,2}; - std::vector ccord{0,1,2}; + jac_.zeroMatrix(); + // Create dF/dy + std::vector rcord{2, 2, 2}; + std::vector ccord{0, 1, 2}; std::vector vals{1.0, -1.0, -1.0}; - J_.setValues(rcord, ccord, vals); + 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' - J_.axpy(alpha_, Jacder); + // 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; } @@ -133,13 +133,8 @@ int Capacitor::evaluateAdjointIntegrand() return 0; } - - - // Available template instantiations template class Capacitor; template class Capacitor; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerElectronics/Capacitor/Capacitor.hpp b/src/Model/PowerElectronics/Capacitor/Capacitor.hpp index 76cdc3504..d53dd0072 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 +#include - -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +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::J_; - 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 8186c7272..cc00f9ec0 100644 --- a/src/Model/PowerElectronics/CircuitComponent.hpp +++ b/src/Model/PowerElectronics/CircuitComponent.hpp @@ -1,86 +1,288 @@ -#ifndef _CIRCCOMP_HPP_ -#define _CIRCCOMP_HPP_ +#pragma once -#include -#include #include #include +#include +#include -namespace ModelLib +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 ModelEvaluatorImpl - { - - public: - - - 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 indexes - * - * @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); - } - - 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_; - - }; - - -} - -#endif + 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/CMakeLists.txt b/src/Model/PowerElectronics/DistributedGenerator/CMakeLists.txt index 22652f53b..6d38d4536 100644 --- a/src/Model/PowerElectronics/DistributedGenerator/CMakeLists.txt +++ b/src/Model/PowerElectronics/DistributedGenerator/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_disgen +gridkit_add_library(power_elec_disgen SOURCES DistributedGenerator.cpp OUTPUT_NAME - gridkit_powerelec_disgen) \ No newline at end of file + gridkit_power_elec_disgen) diff --git a/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp b/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp index 00d174ae4..b4727ac87 100644 --- a/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp +++ b/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp @@ -1,47 +1,50 @@ +#include "DistributedGenerator.hpp" -#include #include +#include #include -#include "DistributedGenerator.hpp" - -namespace ModelLib { +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 + * @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) +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; + size_ = 16; + n_intern_ = 13; + n_extern_ = 3; + extern_indices_ = {0, 1, 2}; + idc_ = id; } template @@ -58,7 +61,7 @@ int DistributedGenerator::allocate() y_.resize(size_); yp_.resize(size_); f_.resize(size_); - + return 0; } @@ -90,7 +93,7 @@ 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_) { @@ -100,18 +103,17 @@ int DistributedGenerator::evaluateResidual() { 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,32 +121,31 @@ 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; @@ -152,177 +153,224 @@ int DistributedGenerator::evaluateResidual() /** * @brief Compute the jacobian of the DistributedGenerator for iteration. dF/dy - \alpha dF/dy' - * + * * The matrix dF/dy should be - * -[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -[-1, 0, 0, 0, -mp, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -[ 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, 0, wc*x15, wc*x16, wc*x13, wc*x14] -[ 0, 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, -wc*x16, wc*x15, wc*x14, -wc*x13] -[ 0, 0, 0, 0, 0, -nq, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0] -[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0] -[ 0, 0, 0, 0, 0, -Kpv*nq, Kiv, 0, 0, 0, -1, 0, -Kpv, -Cf*wb, F, 0] -[ 0, 0, 0, 0, 0, 0, 0, Kiv, 0, 0, 0, -1, Cf*wb, -Kpv, 0, F] -[ 0, 0, 0, 0, -mp*x12, -(Kpc*Kpv*nq)/Lf, (Kiv*Kpc)/Lf, 0, Kic/Lf, 0, - Kpc/Lf - rLf/Lf, -mp*x5, -(Kpc*Kpv + 1)/Lf, -(Cf*Kpc*wb)/Lf, (F*Kpc)/Lf, 0] -[ 0, 0, 0, 0, mp*x11, 0, 0, (Kiv*Kpc)/Lf, 0, Kic/Lf, mp*x5, - Kpc/Lf - rLf/Lf, (Cf*Kpc*wb)/Lf, -(Kpc*Kpv + 1)/Lf, 0, (F*Kpc)/Lf] -[ 0, 0, 0, 0, -mp*x14, 0, 0, 0, 0, 0, 1/Cf, 0, 0, wb - mp*x5, -1/Cf, 0] -[ 0, 0, 0, 0, mp*x13, 0, 0, 0, 0, 0, 0, 1/Cf, mp*x5 - wb, 0, 0, -1/Cf] -[ 0, -cos(x4)/Lc, -sin(x4)/Lc, -(x3*cos(x4) - x2*sin(x4))/Lc, -mp*x16, 0, 0, 0, 0, 0, 0, 0, 1/Lc, 0, -rLc/Lc, wb - mp*x5] -[ 0, sin(x4)/Lc, -cos(x4)/Lc, (x2*cos(x4) + x3*sin(x4))/Lc, mp*x15, 0, 0, 0, 0, 0, 0, 0, 0, 1/Lc, mp*x5 - wb, -rLc/Lc] + * +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0] [ 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0] [ 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0] +[-1, 0, 0, 0, -mp, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0] [ 0, 0, +0, 0, -wc, 0, 0, 0, 0, 0, 0, 0, wc*x15, +wc*x16, wc*x13, wc*x14] [ 0, 0, 0, 0, 0, -wc, +0, 0, 0, 0, 0, 0, -wc*x16, wc*x15, wc*x14, +-wc*x13] [ 0, 0, 0, 0, 0, -nq, 0, 0, 0, 0, +0, 0, -1, 0, 0, 0] [ 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, -1, 0, +0] [ 0, 0, 0, 0, 0, -Kpv*nq, Kiv, 0, +0, 0, -1, 0, -Kpv, -Cf*wb, F, 0] [ 0, 0, +0, 0, 0, 0, 0, Kiv, 0, 0, 0, -1, Cf*wb, +-Kpv, 0, F] [ 0, 0, 0, 0, -mp*x12, -(Kpc*Kpv*nq)/Lf, +(Kiv*Kpc)/Lf, 0, Kic/Lf, 0, - Kpc/Lf - rLf/Lf, -mp*x5, -(Kpc*Kpv + 1)/Lf, -(Cf*Kpc*wb)/Lf, +(F*Kpc)/Lf, 0] [ 0, 0, 0, 0, mp*x11, 0, 0, +(Kiv*Kpc)/Lf, 0, Kic/Lf, mp*x5, - Kpc/Lf - rLf/Lf, (Cf*Kpc*wb)/Lf, -(Kpc*Kpv + 1)/Lf, 0, +(F*Kpc)/Lf] [ 0, 0, 0, 0, -mp*x14, 0, 0, 0, 0, +0, 1/Cf, 0, 0, wb - mp*x5, -1/Cf, 0] [ 0, 0, +0, 0, mp*x13, 0, 0, 0, 0, 0, 0, 1/Cf, mp*x5 +- wb, 0, 0, -1/Cf] [ 0, -cos(x4)/Lc, -sin(x4)/Lc, -(x3*cos(x4) - x2*sin(x4))/Lc, -mp*x16, +0, 0, 0, 0, 0, 0, 0, 1/Lc, 0, -rLc/Lc, +wb - mp*x5] [ 0, sin(x4)/Lc, -cos(x4)/Lc, (x2*cos(x4) + x3*sin(x4))/Lc, mp*x15, 0, 0, 0, 0, +0, 0, 0, 0, 1/Lc, mp*x5 - wb, -rLc/Lc] * 'Generated from MATLAB symbolic' - * - * @tparam ScalarT - * @tparam IdxT - * @return int + * + * @tparam ScalarT + * @tparam IdxT + * @return int */ template int DistributedGenerator::evaluateJacobian() { - J_.zeroMatrix(); - //Create dF/dy' - std::vector rcordder(13); + jac_.zeroMatrix(); + // Create dF/dy' + std::vector rcordder(13); std::vector valsder(13, -1.0); for (int i = 0; i < 13; i++) { 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])}; - J_.setValues(rtemp, ctemp, valtemp); + 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])}; - J_.setValues(rtemp, ctemp, valtemp); + 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_}; - J_.setValues(rtemp, ctemp, valtemp); - - //r = 0 + jac_.setValues(rtemp, ctemp, valtemp); + + // r = 0 if (refframe_) { ctemp = {0, 4}; rtemp.clear(); - for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(0); + for (size_t i = 0; i < ctemp.size(); i++) + rtemp.push_back(0); valtemp = {-1.0, -mp_}; - J_.setValues(rtemp, ctemp, valtemp); + 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]}; - J_.setValues(rtemp, ctemp, valtemp); + 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]}; - J_.setValues(rtemp, ctemp, valtemp); + 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}; - J_.setValues(rtemp, ctemp, valtemp); - - //r = 7 + jac_.setValues(rtemp, ctemp, valtemp); + + // 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}; - J_.setValues(rtemp, ctemp, valtemp); + 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_}; - J_.setValues(rtemp, ctemp, valtemp); + 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_}; - J_.setValues(rtemp, ctemp, valtemp); - - //r = 10 + 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 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_}; - J_.setValues(rtemp, ctemp, valtemp); - - //r = 11 + 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 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_}; - J_.setValues(rtemp, ctemp, valtemp); - - //r = 12 + 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 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_}; - J_.setValues(rtemp, ctemp, valtemp); + 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_}; - J_.setValues(rtemp, ctemp, valtemp); + 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]}; - J_.setValues(rtemp, ctemp, valtemp); - - - //r = 15 + 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 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_}; - J_.setValues(rtemp, ctemp, valtemp); + 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' - - J_.axpy(alpha_, Jacder); + jac_.axpy(alpha_, Jacder); return 0; } @@ -351,13 +399,8 @@ int DistributedGenerator::evaluateAdjointIntegrand() return 0; } - - - // Available template instantiations template class DistributedGenerator; template class DistributedGenerator; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp b/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp index bbb9475fa..c6382117a 100644 --- a/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp +++ b/src/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp @@ -3,101 +3,98 @@ #ifndef _CAP_HPP_ #define _CAP_HPP_ -#include -#include #include +#include - -namespace ModelLib +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 ModelLib +namespace GridKit +{ +/*! + * @brief Declaration of a DistributedGenerator class. + * + */ +template +class DistributedGenerator : public CircuitComponent { - /*! - * @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::J_; - using CircuitComponent::param_; - using CircuitComponent::idc_; - - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + 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/CMakeLists.txt b/src/Model/PowerElectronics/InductionMotor/CMakeLists.txt index 95ef42436..c9246583c 100644 --- a/src/Model/PowerElectronics/InductionMotor/CMakeLists.txt +++ b/src/Model/PowerElectronics/InductionMotor/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_inductionmotor +gridkit_add_library(power_elec_inductionmotor SOURCES InductionMotor.cpp OUTPUT_NAME - gridkit_powerelec_inductionmotor) \ No newline at end of file + gridkit_power_elec_inductionmotor) diff --git a/src/Model/PowerElectronics/InductionMotor/InductionMotor.cpp b/src/Model/PowerElectronics/InductionMotor/InductionMotor.cpp index fa0da7fbc..78de8699c 100644 --- a/src/Model/PowerElectronics/InductionMotor/InductionMotor.cpp +++ b/src/Model/PowerElectronics/InductionMotor/InductionMotor.cpp @@ -1,15 +1,13 @@ +#include "InductionMotor.hpp" -#include #include +#include #include -#include "InductionMotor.hpp" - - -namespace ModelLib { - +namespace GridKit +{ /*! * @brief Constructor for a constant InductionMotor model @@ -17,23 +15,24 @@ namespace ModelLib { * 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) +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; + size_ = 10; + n_intern_ = 5; + n_extern_ = 5; + extern_indices_ = {0, 1, 2, 3, 4}; + idc_ = id; } template @@ -78,33 +77,35 @@ int InductionMotor::tagDifferentiable() 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]); + 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 + * + * @tparam ScalarT + * @tparam IdxT + * @return int */ template int InductionMotor::evaluateJacobian() { - + return 0; } @@ -132,14 +133,8 @@ int InductionMotor::evaluateAdjointIntegrand() return 0; } - - - - // Available template instantiations template class InductionMotor; template class InductionMotor; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerElectronics/InductionMotor/InductionMotor.hpp b/src/Model/PowerElectronics/InductionMotor/InductionMotor.hpp index 0a502d556..9ecf08ce2 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 +#include - -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +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::J_; - 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/CMakeLists.txt b/src/Model/PowerElectronics/Inductor/CMakeLists.txt index 4c620030f..980fb86f4 100644 --- a/src/Model/PowerElectronics/Inductor/CMakeLists.txt +++ b/src/Model/PowerElectronics/Inductor/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_inductor +gridkit_add_library(power_elec_inductor SOURCES Inductor.cpp OUTPUT_NAME - gridkit_powerelec_inductor) \ No newline at end of file + gridkit_power_elec_inductor) diff --git a/src/Model/PowerElectronics/Inductor/Inductor.cpp b/src/Model/PowerElectronics/Inductor/Inductor.cpp index 2bb4dd1d9..d0a5f30e6 100644 --- a/src/Model/PowerElectronics/Inductor/Inductor.cpp +++ b/src/Model/PowerElectronics/Inductor/Inductor.cpp @@ -1,12 +1,13 @@ +#include "Inductor.hpp" -#include #include +#include #include -#include "Inductor.hpp" -namespace ModelLib { +namespace GridKit +{ /*! * @brief Constructor for a inductor @@ -15,14 +16,13 @@ namespace ModelLib { */ template -Inductor::Inductor(IdxT id, ScalarT L) - : L_(L) +Inductor::Inductor(IdxT id, ScalarT L) : L_(L) { - size_ = 3; - n_intern_ = 1; - n_extern_ = 2; - extern_indices_ = {0,1}; - idc_ = id; + size_ = 3; + n_intern_ = 1; + n_extern_ = 2; + extern_indices_ = {0, 1}; + idc_ = id; } template @@ -36,11 +36,11 @@ Inductor::~Inductor() template int Inductor::allocate() { - + y_.resize(size_); yp_.resize(size_); f_.resize(size_); - + return 0; } @@ -69,41 +69,41 @@ int Inductor::tagDifferentiable() template int Inductor::evaluateResidual() { - //input + // 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 + * + * @tparam ScalarT + * @tparam IdxT + * @return int */ template int Inductor::evaluateJacobian() { - J_.zeroMatrix(); + 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}; - J_.setValues(rcord, ccord, vals); + 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); - //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' - J_.axpy(alpha_, Jacder); + // Perform dF/dy + \alpha dF/dy' + jac_.axpy(alpha_, Jacder); return 0; } @@ -132,13 +132,8 @@ int Inductor::evaluateAdjointIntegrand() return 0; } - - - // Available template instantiations template class Inductor; template class Inductor; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerElectronics/Inductor/Inductor.hpp b/src/Model/PowerElectronics/Inductor/Inductor.hpp index fbab06496..a87ce64f3 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 +#include - -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +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::J_; - 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/CMakeLists.txt b/src/Model/PowerElectronics/LinearTransformer/CMakeLists.txt index eaf95c043..d3e2c7243 100644 --- a/src/Model/PowerElectronics/LinearTransformer/CMakeLists.txt +++ b/src/Model/PowerElectronics/LinearTransformer/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_lineartrasnformer +gridkit_add_library(power_elec_lineartrasnformer SOURCES LinearTransformer.cpp OUTPUT_NAME - gridkit_powerelec_lineartrasnformer) \ No newline at end of file + gridkit_power_elec_lineartrasnformer) diff --git a/src/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp b/src/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp index b53fbd278..f74f6837d 100644 --- a/src/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp +++ b/src/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp @@ -1,12 +1,13 @@ +#include "LinearTransformer.hpp" -#include #include +#include #include -#include "LinearTransformer.hpp" -namespace ModelLib { +namespace GridKit +{ /*! * @brief Constructor for a LinearTransformer model @@ -14,21 +15,27 @@ namespace ModelLib { * 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 L1, ScalarT L2, ScalarT R1, ScalarT R2, ScalarT M) - : L1_(L1), - L2_(L2), - R1_(R1), - R2_(R2), - M_(M) +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; + size_ = 4; + n_intern_ = 2; + n_extern_ = 2; + extern_indices_ = {0, 1}; + idc_ = id; } template @@ -68,15 +75,15 @@ int LinearTransformer::tagDifferentiable() /** * @brief Computes the component resisdual - * + * */ template int LinearTransformer::evaluateResidual() { f_[0] = y_[2]; f_[1] = y_[3]; - f_[2] = y_[0] - R1_ * y_[2] - L1_ * yp_[2] - M_ * yp_[3]; - f_[2] = y_[1] - R2_ * y_[3] - M_ * yp_[2] - L2_ * yp_[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; } @@ -110,14 +117,8 @@ int LinearTransformer::evaluateAdjointIntegrand() return 0; } - - - - // Available template instantiations template class LinearTransformer; template class LinearTransformer; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp b/src/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp index 7938ed76b..d5c792c7b 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 +#include - -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +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::J_; - 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 L1, ScalarT L2, ScalarT R1, ScalarT R2, 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 L1_; - ScalarT L2_; - ScalarT R1_; - ScalarT R2_; - 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/CMakeLists.txt b/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt index 1bfb8dc3d..1ad579876 100644 --- a/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt +++ b/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_mircobusdq +gridkit_add_library(power_elec_microbusdq SOURCES MicrogridBusDQ.cpp OUTPUT_NAME - gridkit_powerelec_mircobusdq) \ No newline at end of file + gridkit_power_elec_microbusdq) diff --git a/src/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp b/src/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp index f486e1720..7d55134d6 100644 --- a/src/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/src/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -1,16 +1,18 @@ -#include +#include "MicrogridBusDQ.hpp" + #include +#include #include -#include "MicrogridBusDQ.hpp" -namespace ModelLib { +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 @@ -18,15 +20,14 @@ namespace ModelLib { * Timothy C. Green, Section E */ template -MicrogridBusDQ::MicrogridBusDQ(IdxT id, ScalarT RN) - : RN_(RN) +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; + size_ = 2; + n_intern_ = 0; + n_extern_ = 2; + extern_indices_ = {0, 1}; + idc_ = id; } template @@ -43,7 +44,7 @@ int MicrogridBusDQ::allocate() y_.resize(size_); yp_.resize(size_); f_.resize(size_); - + return 0; } @@ -71,12 +72,12 @@ int MicrogridBusDQ::tagDifferentiable() * 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 + // bus voltage f_[0] = -y_[0] / RN_; f_[1] = -y_[1] / RN_; @@ -85,21 +86,21 @@ int MicrogridBusDQ::evaluateResidual() /** * @brief Generate Jacobian - * - * @tparam ScalarT - * @tparam IdxT - * @return int + * + * @tparam ScalarT + * @tparam IdxT + * @return int */ template int MicrogridBusDQ::evaluateJacobian() { - J_.zeroMatrix(); + jac_.zeroMatrix(); - //Create dF/dy - std::vector rtemp{0,1}; - std::vector ctemp{0,1}; - std::vector vals{-1.0 / RN_,-1.0 / RN_}; - J_.setValues(rtemp, ctemp, vals); + // 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; } @@ -128,11 +129,8 @@ int MicrogridBusDQ::evaluateAdjointIntegrand() return 0; } - // Available template instantiations template class MicrogridBusDQ; template class MicrogridBusDQ; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp b/src/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp index 027143e66..75534193b 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 +#include - -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +namespace GridKit +{ +/*! + * @brief Declaration of a MicrogridBusDQ class. + * + */ +template +class MicrogridBusDQ : public CircuitComponent { - /*! - * @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::J_; - using CircuitComponent::param_; - using CircuitComponent::idc_; - - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + 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/CMakeLists.txt b/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt index d59cebb9c..2f4457855 100644 --- a/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt +++ b/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_mircoline +gridkit_add_library(power_elec_microline SOURCES MicrogridLine.cpp OUTPUT_NAME - gridkit_powerelec_mircoline) \ No newline at end of file + gridkit_power_elec_microline) diff --git a/src/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp b/src/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp index 3198af2e5..43324b1a9 100644 --- a/src/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp +++ b/src/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp @@ -1,36 +1,36 @@ -#include +#include "MicrogridLine.hpp" + #include +#include #include -#include "MicrogridLine.hpp" -namespace ModelLib { +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) +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; + size_ = 7; + n_intern_ = 2; + n_extern_ = 5; + extern_indices_ = {0, 1, 2, 3, 4}; + idc_ = id; } template @@ -47,7 +47,7 @@ int MicrogridLine::allocate() y_.resize(size_); yp_.resize(size_); f_.resize(size_); - + return 0; } @@ -71,71 +71,66 @@ int MicrogridLine::tagDifferentiable() /** * @brief Evaluate residual of microgrid line - * + * */ template int MicrogridLine::evaluateResidual() { - //ref motor + // ref motor f_[0] = 0.0; - //input - f_[1] = -y_[5] ; - f_[2] = -y_[6] ; - - //output - f_[3] = y_[5] ; - f_[4] = y_[6] ; + // input + f_[1] = -y_[5]; + f_[2] = -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 + * + * @tparam ScalarT + * @tparam IdxT + * @return int */ template int MicrogridLine::evaluateJacobian() { - J_.zeroMatrix(); + 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}; - J_.setValues(rtemp, ctemp, vals); + // 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]}; - J_.setValues(rcord, ccord, vals); + 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_)}; - J_.setValues(rcord, ccor2, vals); - + 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); - - //Perform dF/dy + \alpha dF/dy' - J_.axpy(alpha_, Jacder); + // 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' + jac_.axpy(alpha_, Jacder); return 0; } @@ -164,12 +159,8 @@ int MicrogridLine::evaluateAdjointIntegrand() return 0; } - - // Available template instantiations template class MicrogridLine; template class MicrogridLine; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp b/src/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp index 17cc18ba9..e185b0a59 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 +#include -namespace ModelLib +namespace GridKit { - template - class BaseBus; +template +class BaseBus; } -namespace ModelLib +namespace GridKit +{ +/*! + * @brief Declaration of a MicrogridLine class. + * + */ +template +class MicrogridLine : public CircuitComponent { - /*! - * @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::J_; - using CircuitComponent::param_; - using CircuitComponent::idc_; - - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + 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/CMakeLists.txt b/src/Model/PowerElectronics/MicrogridLoad/CMakeLists.txt index 313d47688..b17a875cb 100644 --- a/src/Model/PowerElectronics/MicrogridLoad/CMakeLists.txt +++ b/src/Model/PowerElectronics/MicrogridLoad/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_microload +gridkit_add_library(power_elec_microload SOURCES MicrogridLoad.cpp OUTPUT_NAME - gridkit_powerelec_microload) \ No newline at end of file + gridkit_power_elec_microload) diff --git a/src/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp b/src/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp index ddfa9ab94..627f03345 100644 --- a/src/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp +++ b/src/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp @@ -1,35 +1,35 @@ -#include +#include "MicrogridLoad.hpp" + #include +#include #include -#include "MicrogridLoad.hpp" -namespace ModelLib { +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" + "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) +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; - + size_ = 5; + n_intern_ = 2; + n_extern_ = 3; + extern_indices_ = {0, 1, 2}; + idc_ = id; } template @@ -46,7 +46,7 @@ int MicrogridLoad::allocate() y_.resize(size_); yp_.resize(size_); f_.resize(size_); - + return 0; } @@ -74,63 +74,59 @@ int MicrogridLoad::tagDifferentiable() template int MicrogridLoad::evaluateResidual() { - //ref motor + // 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 + * + * @tparam ScalarT + * @tparam IdxT + * @return int */ template int MicrogridLoad::evaluateJacobian() { - J_.zeroMatrix(); + jac_.zeroMatrix(); - //Create dF/dy - std::vector rtemp{1,2}; - std::vector ctemp{3,4}; - std::vector vals{-1.0,-1.0}; - J_.setValues(rtemp, ctemp, vals); + // 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]}; - J_.setValues(rcord, ccord, vals); + 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_)}; - J_.setValues(rcord, ccor2, vals); + 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' - J_.axpy(alpha_, Jacder); + // Perform dF/dy + \alpha dF/dy' + jac_.axpy(alpha_, Jacder); return 0; } @@ -159,14 +155,8 @@ int MicrogridLoad::evaluateAdjointIntegrand() return 0; } - - - - // Available template instantiations template class MicrogridLoad; template class MicrogridLoad; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp b/src/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp index f64626bee..b77f0cb64 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 +#include - -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +namespace GridKit +{ +/*! + * @brief Declaration of a passive MicrogridLoad class. + * + */ +template +class MicrogridLoad : public CircuitComponent { - /*! - * @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::J_; - using CircuitComponent::param_; - using CircuitComponent::idc_; - - using CircuitComponent::extern_indices_; - using CircuitComponent::n_extern_; - using CircuitComponent::n_intern_; + 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/CMakeLists.txt b/src/Model/PowerElectronics/Resistor/CMakeLists.txt index 9386bda83..3721b387e 100644 --- a/src/Model/PowerElectronics/Resistor/CMakeLists.txt +++ b/src/Model/PowerElectronics/Resistor/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_resistor +gridkit_add_library(power_elec_resistor SOURCES Resistor.cpp OUTPUT_NAME - gridkit_powerelec_resistor) \ No newline at end of file + gridkit_power_elec_resistor) diff --git a/src/Model/PowerElectronics/Resistor/Resistor.cpp b/src/Model/PowerElectronics/Resistor/Resistor.cpp index caf0335f1..da75f1dda 100644 --- a/src/Model/PowerElectronics/Resistor/Resistor.cpp +++ b/src/Model/PowerElectronics/Resistor/Resistor.cpp @@ -1,12 +1,13 @@ +#include "Resistor.hpp" -#include #include +#include #include -#include "Resistor.hpp" -namespace ModelLib { +namespace GridKit +{ /*! * @brief Constructor for a resistor model @@ -15,14 +16,13 @@ namespace ModelLib { */ template -Resistor::Resistor(IdxT id, ScalarT R) - : R_(R) +Resistor::Resistor(IdxT id, ScalarT R) : R_(R) { - size_ = 2; - n_intern_ = 0; - n_extern_ = 2; - extern_indices_ = {0,1}; - idc_ = id; + size_ = 2; + n_intern_ = 0; + n_extern_ = 2; + extern_indices_ = {0, 1}; + idc_ = id; } template @@ -39,7 +39,7 @@ int Resistor::allocate() y_.resize(size_); yp_.resize(size_); f_.resize(size_); - + return 0; } @@ -68,23 +68,23 @@ int Resistor::tagDifferentiable() template int Resistor::evaluateResidual() { - //input - f_[0] = (y_[0] - y_[1])/R_ ; - //ouput - f_[1] = (y_[1] - y_[0])/R_ ; + // 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}; + + // 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_}; - J_.setValues(rcord, ccord, vals); + jac_.setValues(rcord, ccord, vals); return 0; } @@ -113,14 +113,8 @@ int Resistor::evaluateAdjointIntegrand() return 0; } - - - - // Available template instantiations template class Resistor; template class Resistor; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerElectronics/Resistor/Resistor.hpp b/src/Model/PowerElectronics/Resistor/Resistor.hpp index f3c925abd..cdfa8d7c5 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 +#include - -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +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::J_; - 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/CMakeLists.txt b/src/Model/PowerElectronics/SynchronousMachine/CMakeLists.txt index bfaeace4b..ff492047e 100644 --- a/src/Model/PowerElectronics/SynchronousMachine/CMakeLists.txt +++ b/src/Model/PowerElectronics/SynchronousMachine/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_synmachine +gridkit_add_library(power_elec_synmachine SOURCES SynchronousMachine.cpp OUTPUT_NAME - gridkit_powerelec_synmachine) \ No newline at end of file + gridkit_power_elec_synmachine) diff --git a/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp b/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp index e3f65bed5..aa511c4dc 100644 --- a/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp +++ b/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp @@ -1,45 +1,72 @@ +#include "SynchronousMachine.hpp" - - -#include #include +#include #include -#include "SynchronousMachine.hpp" - - -namespace ModelLib { - +namespace GridKit +{ /*! * @brief Constructor for a constant SynchronousMachine model * * Calls default ModelEvaluatorImpl constructor. - * @todo This models equations are not finish + * @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) +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; + size_ = 13; + n_intern_ = 6; + n_extern_ = 7; + extern_indices_ = {0, 1, 2, 3, 4}; + idc_ = id; } template @@ -85,28 +112,33 @@ int SynchronousMachine::tagDifferentiable() template int SynchronousMachine::evaluateResidual() { - ScalarT rkq1 = std::get<0>(Rkq_); - ScalarT rkq2 = std::get<1>(Rkq_); + 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; } @@ -140,14 +172,8 @@ int SynchronousMachine::evaluateAdjointIntegrand() return 0; } - - - - // Available template instantiations template class SynchronousMachine; template class SynchronousMachine; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp b/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp index f2b9b842f..7a91f5587 100644 --- a/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp +++ b/src/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp @@ -3,79 +3,91 @@ #ifndef _SYNMACH_HPP_ #define _SYNMACH_HPP_ -#include -#include -#include #include +#include +#include -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +namespace GridKit +{ +/*! + * @brief Declaration of a SynchronousMachine class. + * + */ +template +class SynchronousMachine : public CircuitComponent { - /*! - * @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::J_; - using CircuitComponent::param_; - using CircuitComponent::idc_; + 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 32b7ddd71..23fef7de2 100644 --- a/src/Model/PowerElectronics/SystemModelPowerElectronics.hpp +++ b/src/Model/PowerElectronics/SystemModelPowerElectronics.hpp @@ -2,331 +2,337 @@ #pragma once +#include #include #include -#include -#include -#include #include #include +#include -namespace ModelLib +namespace GridKit { - template - class PowerElectronicsModel : public ModelEvaluatorImpl +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 ModelEvaluatorImpl::size_; - // using ModelEvaluatorImpl::size_quad_; - // using ModelEvaluatorImpl::size_opt_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::alpha_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::yp_; - // using ModelEvaluatorImpl::yB_; - // using ModelEvaluatorImpl::ypB_; - // using ModelEvaluatorImpl::tag_; - using ModelEvaluatorImpl::f_; - // using ModelEvaluatorImpl::fB_; - // using ModelEvaluatorImpl::g_; - // using ModelEvaluatorImpl::gB_; - using ModelEvaluatorImpl::J_; - using ModelEvaluatorImpl::rtol_; - using ModelEvaluatorImpl::atol_; - // using ModelEvaluatorImpl::param_; - // using ModelEvaluatorImpl::param_up_; - // using ModelEvaluatorImpl::param_lo_; - - public: - /** - * @brief Default constructor for the system model - */ - PowerElectronicsModel() : ModelEvaluatorImpl(0, 0, 0) - { - // Set system model tolerances as default - rtol_ = 1e-4; - atol_ = 1e-4; - this->max_steps_ = 2000; - // By default not use jacobian - usejac_ = false; - } - - /** - * @brief Constructor for the system model - */ - PowerElectronicsModel(double rt = 1e-4, double at = 1e-4, bool ju = false, IdxT msa = 2000) : ModelEvaluatorImpl(0, 0, 0) - { - // Set system model tolerances from input - rtol_ = rt; - atol_ = at; - this->max_steps_ = msa; - // Can choose if to use jacobain - usejac_ = ju; - } - - /** - * @brief Destructor for the system model - */ - 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; - } + // 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 Will check if each component has jacobian avalible. If one doesn't then jacobain is false. - * - * - * @return true - * @return false - */ - bool hasJacobian() + for (const auto& component : components_) { - if (!this->usejac_) - return false; - - for (const auto &component : components_) + if (!component->hasJacobian()) { - if (!component->hasJacobian()) - { - return false; - } + return false; } - 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 s - * @return int - */ - int allocate(IdxT s) + 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_) { - - // 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; + component->allocate(); } - /** - * @brief Set intial y and y' of each component - * - * @return int - */ - int initialize() - { + // Allocate global vectors + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); - // Initialize components - for (const auto &component : components_) - { - component->initialize(); - } - this->distributeVectors(); + return 0; + } - 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(); } - - /** - * @brief Distribute y and y' to each component based of node connection graph - * - * @return int - */ - int distributeVectors() + 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 (const auto &component : components_) + for (IdxT j = 0; j < component->size(); ++j) { - 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 { - 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; - } + component->y()[j] = 0.0; + component->yp()[j] = 0.0; } } - return 0; } + return 0; + } - int tagDifferentiable() + 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++) { - return 0; + f_[i] = 0.0; } - /** - * @brief Evaluate Residuals at each component then collect them - * - * @return int - */ - int evaluateResidual() - { - for (IdxT i = 0; i < this->f_.size(); i++) - { - f_[i] = 0.0; - } + this->distributeVectors(); - this->distributeVectors(); + // Update system residual vector - // Update system residual vector - - for (const auto &component : components_) + for (const auto& component : components_) + { + // TODO:check return type + component->evaluateResidual(); + for (IdxT j = 0; j < component->size(); ++j) { - // 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_) { - //@todo should do a different grounding check - if (component->getNodeConnection(j) != neg1_) - { - f_[component->getNodeConnection(j)] += component->getResidual()[j]; - } + f_[component->getNodeConnection(j)] += component->getResidual()[j]; } } - - return 0; } - /** - * @brief Creates the Sparse COO Jacobian representing \alpha dF/dy' + dF/dy - * - * @return int - */ - int evaluateJacobian() - { - J_.zeroMatrix(); - distributeVectors(); + return 0; + } - // Evaluate component jacs - for (const auto &component : components_) - { - component->evaluateJacobian(); - - // get references to local jacobain - std::tuple&, std::vector&, std::vector&> tpm = component->getJacobian().getEntries(); - const auto& [r, c, v] = tpm; + /** + * @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(); - // 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++) + // 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_) { - 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]); - } + rgr.push_back(component->getNodeConnection(r[i])); + cgr.push_back(component->getNodeConnection(c[i])); + vgr.push_back(v[i]); } - - // AXPY to Global Jacobian - J_.axpy(1.0, rgr, cgr, vgr); } - return 0; + // AXPY to Global Jacobian + // elementwise jac_(rgr, cgr) += vgr + jac_.axpy(1.0, rgr, cgr, vgr); } - /** - * @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() - { - return 0; - } - - /** - * @brief Compute adjoint residual for the system model. - * - * - */ - int evaluateAdjointResidual() - { - return 0; - } + /** + * @brief Evaluate integrands for the system quadratures. + */ + int evaluateIntegrand() + { - /** - * @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; - } - - void addComponent(component_type *component) + /** + * @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_) { - components_.push_back(component); + component->updateTime(t, a); } + time_ = t; + alpha_ = a; + } - private: + 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 usejac_; + std::vector components_; + bool use_jac_; - }; // class PowerElectronicsModel +}; // class PowerElectronicsModel -} // namespace ModelLib +} // namespace GridKit diff --git a/src/Model/PowerElectronics/TransmissionLine/CMakeLists.txt b/src/Model/PowerElectronics/TransmissionLine/CMakeLists.txt index 6e2cea4f4..f8e76a1dc 100644 --- a/src/Model/PowerElectronics/TransmissionLine/CMakeLists.txt +++ b/src/Model/PowerElectronics/TransmissionLine/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_tranline +gridkit_add_library(power_elec_tranline SOURCES TransmissionLine.cpp OUTPUT_NAME - gridkit_powerelec_tranline) \ No newline at end of file + gridkit_power_elec_tranline) diff --git a/src/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp b/src/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp index 010f38e1f..ff10b042d 100644 --- a/src/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp +++ b/src/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp @@ -1,16 +1,18 @@ -#include +#include "TransmissionLine.hpp" + #include +#include #include -#include "TransmissionLine.hpp" -namespace ModelLib { +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 @@ -18,23 +20,20 @@ namespace ModelLib { */ template -TransmissionLine::TransmissionLine(IdxT id, ScalarT R,ScalarT X, ScalarT B) - : R_(R), - X_(X), - B_(B) +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_; + 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 @@ -51,7 +50,7 @@ int TransmissionLine::allocate() y_.resize(size_); yp_.resize(size_); f_.resize(size_); - + return 0; } @@ -78,92 +77,87 @@ int TransmissionLine::tagDifferentiable() * * The complex admittance matrix is: * [[ Y/2 + 1/Z, -1/Z]; - * [ -1/Z, Y/2 + 1/Z]] = + * [ -1/Z, Y/2 + 1/Z]] = * [[R/|Z|, -R/|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 + * + * 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] ; + // 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_[2] = y_[10]; + f_[3] = y_[11]; + // ouput + f_[4] = -y_[8]; + f_[5] = -y_[9]; - f_[6] = -y_[10] ; - f_[7] = -y_[11] ; + f_[6] = -y_[10]; + f_[7] = -y_[11]; - //Voltage drop accross terminals + // 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 + * + * @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}; - J_.setValues(rtemp, ctemp, vals); - - std::vector ccord{0,1,2,3,4,5,6,7}; + // 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 rcord(ccord.size(),8); - vals = {YReMat_, -YImMatDi_ ,-YReMat_, -YImMatOff_,-YReMat_, YImMatDi_ ,YReMat_, YImMatOff_}; - J_.setValues(rtemp, ctemp, vals); + 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_}; - J_.setValues(rtemp, ctemp, vals); + 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_}; - J_.setValues(rtemp, ctemp, vals); + 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_}; - J_.setValues(rtemp, ctemp, vals); + vals = {YImMatDi_, -YReMat_, YImMatOff_, YReMat_, -YImMatDi_, YReMat_, -YImMatOff_, -YReMat_}; + jac_.setValues(rtemp, ctemp, vals); return 0; } @@ -192,14 +186,8 @@ int TransmissionLine::evaluateAdjointIntegrand() return 0; } - - - - // Available template instantiations template class TransmissionLine; template class TransmissionLine; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp b/src/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp index 09355a8ab..caa258895 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 +#include - -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +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 { - /*! - * @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::J_; - using CircuitComponent::param_; - using CircuitComponent::idc_; + 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/CMakeLists.txt b/src/Model/PowerElectronics/VoltageSource/CMakeLists.txt index 7196f4d43..129da3bb5 100644 --- a/src/Model/PowerElectronics/VoltageSource/CMakeLists.txt +++ b/src/Model/PowerElectronics/VoltageSource/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_voltagesource +gridkit_add_library(power_elec_voltagesource SOURCES VoltageSource.cpp OUTPUT_NAME - gridkit_powerelec_voltagesource) \ No newline at end of file + gridkit_power_elec_voltagesource) diff --git a/src/Model/PowerElectronics/VoltageSource/VoltageSource.cpp b/src/Model/PowerElectronics/VoltageSource/VoltageSource.cpp index 2e4041519..d703da108 100644 --- a/src/Model/PowerElectronics/VoltageSource/VoltageSource.cpp +++ b/src/Model/PowerElectronics/VoltageSource/VoltageSource.cpp @@ -1,12 +1,13 @@ +#include "VoltageSource.hpp" -#include #include +#include #include -#include "VoltageSource.hpp" -namespace ModelLib { +namespace GridKit +{ /*! * @brief Constructor for a constant VoltageSource model @@ -15,14 +16,13 @@ namespace ModelLib { */ template -VoltageSource::VoltageSource(IdxT id, ScalarT V) - : V_(V) +VoltageSource::VoltageSource(IdxT id, ScalarT V) : V_(V) { - size_ = 3; - n_intern_ = 1; - n_extern_ = 2; - extern_indices_ = {0,1}; - idc_ = id; + size_ = 3; + n_intern_ = 1; + n_extern_ = 2; + extern_indices_ = {0, 1}; + idc_ = id; } template @@ -39,7 +39,7 @@ int VoltageSource::allocate() y_.resize(size_); yp_.resize(size_); f_.resize(size_); - + return 0; } @@ -67,11 +67,11 @@ int VoltageSource::tagDifferentiable() template int VoltageSource::evaluateResidual() { - //input + // input f_[0] = -y_[2]; - //ouput + // ouput f_[1] = y_[2]; - //internal + // internal f_[2] = y_[1] - y_[0] - V_; return 0; } @@ -79,11 +79,11 @@ int VoltageSource::evaluateResidual() template int VoltageSource::evaluateJacobian() { - //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}; - J_.setValues(rcord, ccord, vals); + jac_.setValues(rcord, ccord, vals); return 0; } @@ -112,11 +112,8 @@ int VoltageSource::evaluateAdjointIntegrand() return 0; } - // Available template instantiations template class VoltageSource; template class VoltageSource; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerElectronics/VoltageSource/VoltageSource.hpp b/src/Model/PowerElectronics/VoltageSource/VoltageSource.hpp index 46f2ddc6f..d6ba57a22 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 +#include - -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +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::J_; - 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 993e3dbd1..08f064213 100644 --- a/src/Model/PowerFlow/Branch/Branch.cpp +++ b/src/Model/PowerFlow/Branch/Branch.cpp @@ -57,14 +57,16 @@ * */ -#include +#include "Branch.hpp" + #include +#include + #include #include -#include "Branch.hpp" - -namespace ModelLib { +namespace GridKit +{ /*! * @brief Constructor for a pi-model branch @@ -78,50 +80,28 @@ namespace ModelLib { 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) + : 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) + : 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) + : 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; + // std::cout << "Destroy Branch..." << std::endl; } /*! @@ -130,7 +110,7 @@ Branch::~Branch() template int Branch::allocate() { - //std::cout << "Allocate Branch..." << std::endl; + // std::cout << "Allocate Branch..." << std::endl; return 0; } @@ -156,21 +136,21 @@ int Branch::tagDifferentiable() /** * \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; } @@ -193,7 +173,7 @@ int Branch::evaluateIntegrand() template int Branch::initializeAdjoint() { - //std::cout << "Initialize adjoint for Branch..." << std::endl; + // std::cout << "Initialize adjoint for Branch..." << std::endl; return 0; } @@ -215,4 +195,4 @@ int Branch::evaluateAdjointIntegrand() template class Branch; template class Branch; -} //namespace ModelLib +} // namespace GridKit diff --git a/src/Model/PowerFlow/Branch/Branch.hpp b/src/Model/PowerFlow/Branch/Branch.hpp index 4637784cd..e09a6a407 100644 --- a/src/Model/PowerFlow/Branch/Branch.hpp +++ b/src/Model/PowerFlow/Branch/Branch.hpp @@ -60,136 +60,144 @@ #ifndef _BRANCH_H_ #define _BRANCH_H_ -#include +#include -namespace ModelLib +// Forward declarations. +namespace GridKit { - template class BaseBus; +template +class BaseBus; + +namespace PowerSystemData +{ + template + struct BranchData; } +} // namespace GridKit -namespace ModelLib +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) { - 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_; - }; -} + } + +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_; +}; +} // namespace GridKit #endif // _BRANCH_H diff --git a/src/Model/PowerFlow/Branch/CMakeLists.txt b/src/Model/PowerFlow/Branch/CMakeLists.txt index bd4ff42f1..b3bb06049 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/BaseBus.hpp b/src/Model/PowerFlow/Bus/BaseBus.hpp index 0413201db..6bc88213e 100644 --- a/src/Model/PowerFlow/Bus/BaseBus.hpp +++ b/src/Model/PowerFlow/Bus/BaseBus.hpp @@ -60,98 +60,145 @@ #ifndef _BASE_BUS_HPP_ #define _BASE_BUS_HPP_ -#include +#include -namespace ModelLib +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 + { + 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() { - protected: - using ModelEvaluatorImpl::size_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::alpha_; - using ModelEvaluatorImpl::rtol_; - using ModelEvaluatorImpl::atol_; - 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 - -} // namespace ModelLib + 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 9b514c297..27e90bc8d 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 ModelLib { +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) + static BaseBus* create(BusData& data) + { + BaseBus* bus = nullptr; + switch (data.type) { - 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; + 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 ModelLib \ No newline at end of file +} // namespace GridKit diff --git a/src/Model/PowerFlow/Bus/BusPQ.cpp b/src/Model/PowerFlow/Bus/BusPQ.cpp index 18c6ec22c..2748c9b19 100644 --- a/src/Model/PowerFlow/Bus/BusPQ.cpp +++ b/src/Model/PowerFlow/Bus/BusPQ.cpp @@ -57,11 +57,13 @@ * */ -#include -#include #include "BusPQ.hpp" -namespace ModelLib { +#include +#include + +namespace GridKit +{ /*! * @brief Constructor for a PQ bus @@ -73,11 +75,10 @@ namespace ModelLib { * - Number of optimization parameters = 0 */ template -BusPQ::BusPQ() - : BaseBus(0), V0_(0.0), theta0_(0.0) +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; + // std::cout << "Create BusPQ..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; size_ = 2; } @@ -94,21 +95,19 @@ BusPQ::BusPQ() * - Number of optimization parameters = 0 */ template -BusPQ::BusPQ(ScalarT V, ScalarT theta) - : BaseBus(0), V0_(V), theta0_(theta) +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; + // 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) +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; + // std::cout << "Create BusPQ..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; size_ = 2; } @@ -116,7 +115,7 @@ BusPQ::BusPQ(BusData& data) template BusPQ::~BusPQ() { - //std::cout << "Destroy PQ bus ..." << std::endl; + // std::cout << "Destroy PQ bus ..." << std::endl; } /*! @@ -125,7 +124,7 @@ BusPQ::~BusPQ() template int BusPQ::allocate() { - //std::cout << "Allocate PQ bus ..." << std::endl; + // std::cout << "Allocate PQ bus ..." << std::endl; f_.resize(size_); y_.resize(size_); yp_.resize(size_); @@ -138,7 +137,6 @@ int BusPQ::allocate() return 0; } - template int BusPQ::tagDifferentiable() { @@ -147,7 +145,6 @@ int BusPQ::tagDifferentiable() return 0; } - /*! * @brief initialize method sets bus variables to stored initial values. */ @@ -155,8 +152,8 @@ 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; @@ -179,7 +176,6 @@ int BusPQ::evaluateResidual() return 0; } - /*! * @brief initialize method sets bus variables to stored initial values. */ @@ -187,8 +183,8 @@ 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; @@ -208,6 +204,4 @@ int BusPQ::evaluateAdjointResidual() template class BusPQ; template class BusPQ; - -} // namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerFlow/Bus/BusPQ.hpp b/src/Model/PowerFlow/Bus/BusPQ.hpp index 6d0c963d6..efd6ed0cf 100644 --- a/src/Model/PowerFlow/Bus/BusPQ.hpp +++ b/src/Model/PowerFlow/Bus/BusPQ.hpp @@ -63,137 +63,135 @@ #include "BaseBus.hpp" #include -namespace ModelLib +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_; - - }; - -} // namespace ModelLib +/*! + * @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_; +}; +} // namespace GridKit #endif // _BUS_PQ_HPP_ diff --git a/src/Model/PowerFlow/Bus/BusPV.cpp b/src/Model/PowerFlow/Bus/BusPV.cpp index d5a05dc98..e4dcc6ad6 100644 --- a/src/Model/PowerFlow/Bus/BusPV.cpp +++ b/src/Model/PowerFlow/Bus/BusPV.cpp @@ -57,11 +57,13 @@ * */ -#include -#include #include "BusPV.hpp" -namespace ModelLib { +#include +#include + +namespace GridKit +{ /*! * @brief Constructor for a PV bus @@ -73,11 +75,10 @@ namespace ModelLib { * - Number of optimization parameters = 0 */ template -BusPV::BusPV() - : BaseBus(0), V_(0.0), theta0_(0.0) +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; + // std::cout << "Create BusPV..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; size_ = 1; } @@ -92,21 +93,19 @@ BusPV::BusPV() * - Number of optimization parameters = 0 */ template -BusPV::BusPV(ScalarT V, ScalarT theta0) - : BaseBus(0), V_(V), theta0_(theta0) +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; + // 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) +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; + // std::cout << "Create BusPV ..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; size_ = 1; } @@ -114,7 +113,7 @@ BusPV::BusPV(BusData& data) template BusPV::~BusPV() { - //std::cout << "Destroy Gen2..." << std::endl; + // std::cout << "Destroy Gen2..." << std::endl; } /*! @@ -123,7 +122,7 @@ BusPV::~BusPV() template int BusPV::allocate() { - //std::cout << "Allocate PV bus ..." << std::endl; + // std::cout << "Allocate PV bus ..." << std::endl; f_.resize(size_); y_.resize(size_); yp_.resize(size_); @@ -136,7 +135,6 @@ int BusPV::allocate() return 0; } - template int BusPV::tagDifferentiable() { @@ -144,7 +142,6 @@ int BusPV::tagDifferentiable() return 0; } - /*! * @brief initialize method sets bus variables to stored initial values. */ @@ -153,7 +150,7 @@ int BusPV::initialize() { // std::cout << "Initialize BusPV..." << std::endl; theta() = theta0_; - yp_[0] = 0.0; + yp_[0] = 0.0; return 0; } @@ -175,7 +172,6 @@ int BusPV::evaluateResidual() return 0; } - /*! * @brief initialize method sets bus variables to stored initial values. */ @@ -183,7 +179,7 @@ template int BusPV::initializeAdjoint() { // std::cout << "Initialize BusPV..." << std::endl; - yB_[0] = 0.0; + yB_[0] = 0.0; ypB_[0] = 0.0; return 0; @@ -201,6 +197,4 @@ int BusPV::evaluateAdjointResidual() template class BusPV; template class BusPV; - -} // namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerFlow/Bus/BusPV.hpp b/src/Model/PowerFlow/Bus/BusPV.hpp index 14f8def55..0b5a16b1f 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 ModelLib +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 { - /*! - * @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_; - }; - -} // namespace ModelLib + 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_; +}; +} // namespace GridKit #endif // _BUS_PV_HPP_ diff --git a/src/Model/PowerFlow/Bus/BusSlack.cpp b/src/Model/PowerFlow/Bus/BusSlack.cpp index 54318de74..890f88dd3 100644 --- a/src/Model/PowerFlow/Bus/BusSlack.cpp +++ b/src/Model/PowerFlow/Bus/BusSlack.cpp @@ -57,11 +57,13 @@ * */ -#include -#include #include "BusSlack.hpp" -namespace ModelLib { +#include +#include + +namespace GridKit +{ /*! * @brief Constructor for a slack bus @@ -76,8 +78,8 @@ 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; + // std::cout << "Create BusSlack..." << std::endl; + // std::cout << "Number of equations is " << size_ << std::endl; size_ = 0; } @@ -95,21 +97,20 @@ 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) - : BaseBus(data.bus_i), V_(data.Vm), theta_(data.Va) +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; } @@ -135,11 +136,8 @@ int BusSlack::evaluateAdjointResidual() return 0; } - // Available template instantiations template class BusSlack; template class BusSlack; - -} // namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerFlow/Bus/BusSlack.hpp b/src/Model/PowerFlow/Bus/BusSlack.hpp index a4fce8f5a..c2d045ae8 100644 --- a/src/Model/PowerFlow/Bus/BusSlack.hpp +++ b/src/Model/PowerFlow/Bus/BusSlack.hpp @@ -63,142 +63,141 @@ #include "BaseBus.hpp" #include -namespace ModelLib +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::atol_; - using BaseBus::rtol_; - - 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 - -} // namespace ModelLib +/*! + * @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 +} // namespace GridKit #endif // _BUS_SLACK_HPP_ diff --git a/src/Model/PowerFlow/Bus/CMakeLists.txt b/src/Model/PowerFlow/Bus/CMakeLists.txt index c53ee6774..53e4be331 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 a09c5aed1..1f9a44236 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/GeneratorBase.hpp b/src/Model/PowerFlow/Generator/GeneratorBase.hpp index e1efa22bd..d9ddf6d22 100644 --- a/src/Model/PowerFlow/Generator/GeneratorBase.hpp +++ b/src/Model/PowerFlow/Generator/GeneratorBase.hpp @@ -59,67 +59,108 @@ #pragma once -#include #include -namespace ModelLib +#include + +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +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 bddffc9c3..51369f822 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 ModelLib { - - 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) + static GeneratorBase* create(BaseBus* bus, GenData& data) + { + GeneratorBase* gen = nullptr; + switch (bus->BusType()) { - 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; + 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 ModelLib \ No newline at end of file +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator/GeneratorPQ.cpp b/src/Model/PowerFlow/Generator/GeneratorPQ.cpp index a0d73ddfa..396baf2cb 100644 --- a/src/Model/PowerFlow/Generator/GeneratorPQ.cpp +++ b/src/Model/PowerFlow/Generator/GeneratorPQ.cpp @@ -57,14 +57,16 @@ * */ +#include "GeneratorPQ.hpp" -#include #include +#include #include -#include "GeneratorPQ.hpp" + #include -namespace ModelLib { +namespace GridKit +{ /*! * @brief Constructor for a constant load model @@ -73,12 +75,9 @@ namespace ModelLib { */ template -GeneratorPQ::GeneratorPQ(bus_type* bus, GenData& data) - : P_(data.Pg), - Q_(data.Qg), - bus_(bus) +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"; + // std::cout << "Create a load model with " << size_ << " variables ...\n"; size_ = 0; } @@ -158,11 +157,8 @@ int GeneratorPQ::evaluateAdjointIntegrand() return 0; } - // Available template instantiations template class GeneratorPQ; template class GeneratorPQ; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator/GeneratorPQ.hpp b/src/Model/PowerFlow/Generator/GeneratorPQ.hpp index ba72d022a..216b78d6a 100644 --- a/src/Model/PowerFlow/Generator/GeneratorPQ.hpp +++ b/src/Model/PowerFlow/Generator/GeneratorPQ.hpp @@ -60,84 +60,84 @@ #pragma once #include -#include -#include + #include "GeneratorBase.hpp" +#include +#include -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +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 036ea8c96..6024a28e9 100644 --- a/src/Model/PowerFlow/Generator/GeneratorPV.cpp +++ b/src/Model/PowerFlow/Generator/GeneratorPV.cpp @@ -57,14 +57,16 @@ * */ +#include "GeneratorPV.hpp" -#include #include +#include #include -#include "GeneratorPV.hpp" + #include -namespace ModelLib { +namespace GridKit +{ /*! * @brief Constructor for a constant load model @@ -74,11 +76,11 @@ namespace ModelLib { template GeneratorPV::GeneratorPV(bus_type* bus, GenData& data) - : P_(data.Pg), - // Q_(data.Qg), - bus_(bus) + : P_(data.Pg), + // Q_(data.Qg), + bus_(bus) { - //std::cout << "Create a load model with " << size_ << " variables ...\n"; + // std::cout << "Create a load model with " << size_ << " variables ...\n"; size_ = 0; } @@ -158,11 +160,8 @@ int GeneratorPV::evaluateAdjointIntegrand() return 0; } - // Available template instantiations template class GeneratorPV; template class GeneratorPV; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator/GeneratorPV.hpp b/src/Model/PowerFlow/Generator/GeneratorPV.hpp index c34df84ad..da9307336 100644 --- a/src/Model/PowerFlow/Generator/GeneratorPV.hpp +++ b/src/Model/PowerFlow/Generator/GeneratorPV.hpp @@ -60,87 +60,87 @@ #pragma once #include -#include -#include + #include "GeneratorBase.hpp" +#include +#include -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +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 7d451b457..513e780e3 100644 --- a/src/Model/PowerFlow/Generator/GeneratorSlack.cpp +++ b/src/Model/PowerFlow/Generator/GeneratorSlack.cpp @@ -57,14 +57,16 @@ * */ +#include "GeneratorSlack.hpp" -#include #include +#include #include -#include "GeneratorSlack.hpp" + #include -namespace ModelLib { +namespace GridKit +{ /*! * @brief Constructor for a constant load model @@ -73,10 +75,9 @@ namespace ModelLib { */ template -GeneratorSlack::GeneratorSlack(bus_type* bus, GenData& data) - : bus_(bus) +GeneratorSlack::GeneratorSlack(bus_type* bus, GenData& data) : bus_(bus) { - //std::cout << "Create a load model with " << size_ << " variables ...\n"; + // std::cout << "Create a load model with " << size_ << " variables ...\n"; size_ = 0; } @@ -156,13 +157,8 @@ int GeneratorSlack::evaluateAdjointIntegrand() return 0; } - - - // Available template instantiations template class GeneratorSlack; template class GeneratorSlack; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator/GeneratorSlack.hpp b/src/Model/PowerFlow/Generator/GeneratorSlack.hpp index e821f8a6b..277086684 100644 --- a/src/Model/PowerFlow/Generator/GeneratorSlack.hpp +++ b/src/Model/PowerFlow/Generator/GeneratorSlack.hpp @@ -59,86 +59,85 @@ #pragma once -// #include +// #include +#include + #include "GeneratorBase.hpp" #include -#include -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +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/CMakeLists.txt b/src/Model/PowerFlow/Generator2/CMakeLists.txt index a1fbc1d21..7767b22b7 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 74c620385..a2e0a73c7 100644 --- a/src/Model/PowerFlow/Generator2/Generator2.cpp +++ b/src/Model/PowerFlow/Generator2/Generator2.cpp @@ -57,12 +57,15 @@ * */ -#include +#include "Generator2.hpp" + #include +#include + #include -#include "Generator2.hpp" -namespace ModelLib { +namespace GridKit +{ /*! * @brief Constructor for a simple generator model @@ -74,20 +77,20 @@ namespace ModelLib { */ 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) + : 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) { } @@ -118,12 +121,12 @@ 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; @@ -133,8 +136,9 @@ int Generator2::initialize() 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_) ); + 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; } @@ -156,8 +160,8 @@ int Generator2::evaluateIntegrand() template int Generator2::initializeAdjoint() { - yB_[0] = 0.0; - yB_[1] = 0.0; + yB_[0] = 0.0; + yB_[1] = 0.0; ypB_[0] = 0.0; ypB_[1] = frequencyPenaltyDer(y_[1]); @@ -167,8 +171,8 @@ int Generator2::initializeAdjoint() 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]); + 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; } @@ -184,11 +188,10 @@ 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 // @@ -223,11 +226,8 @@ ScalarT Generator2::frequencyPenaltyDer(ScalarT omega) } } - - // Available template instantiations template class Generator2; template class Generator2; - -} // namespace ModelLib \ 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 3604ce335..551b02ff9 100644 --- a/src/Model/PowerFlow/Generator2/Generator2.hpp +++ b/src/Model/PowerFlow/Generator2/Generator2.hpp @@ -57,103 +57,104 @@ * */ -#include +#include -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } -namespace ModelLib +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 { - 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_; - }; - -} // namespace ModelLib \ No newline at end of file + 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_; +}; + +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator4/CMakeLists.txt b/src/Model/PowerFlow/Generator4/CMakeLists.txt index 527d4ab11..b0b02ebcc 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/Generator4/Generator4.cpp b/src/Model/PowerFlow/Generator4/Generator4.cpp index a8e014afb..a87943494 100644 --- a/src/Model/PowerFlow/Generator4/Generator4.cpp +++ b/src/Model/PowerFlow/Generator4/Generator4.cpp @@ -57,13 +57,15 @@ * */ +#include "Generator4.hpp" -#include #include +#include + #include -#include "Generator4.hpp" -namespace ModelLib { +namespace GridKit +{ /*! * @brief Constructor for a simple generator model @@ -75,27 +77,27 @@ namespace ModelLib { */ 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) + : 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) { } @@ -111,7 +113,7 @@ Generator4::~Generator4() template int Generator4::allocate() { - //std::cout << "Allocate Generator4..." << std::endl; + // std::cout << "Allocate Generator4..." << std::endl; tag_.resize(size_); return 0; @@ -145,23 +147,23 @@ 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,15 +172,15 @@ 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; @@ -196,7 +198,7 @@ int Generator4::tagDifferentiable() tag_[2] = true; tag_[3] = true; - for (IdxT i=4; i < size_; ++i) + for (IdxT i = 4; i < size_; ++i) { tag_[i] = false; } @@ -211,7 +213,8 @@ int Generator4::tagDifferentiable() * Scripting, Federico Milano, Chapter 15, p. 334: * \f{eqnarray*}{ * f_0: &~& \dot{\delta} -\omega_b (\omega - \omega_s), \\ - * f_1: &~& 2H/\omega_s \dot{\omega} - L_m(P_m) + E_q' I_q + E_d' I_d + (X_q' - X_d')I_d I_q + D (\omega - \omega_s), \\ + * f_1: &~& 2H/\omega_s \dot{\omega} - L_m(P_m) + E_q' I_q + E_d' I_d + (X_q' - X_d')I_d I_q + D (\omega - \omega_s), + * \\ * f_2: &~& T_{q0}' \dot{E}_d' + E_d' - (X_q - X_q')I_q, \\ * f_3: &~& T_{d0}' \dot{E}_q' + E_q' + (X_d - X_d')I_d - E_f, \\ * f_4: &~& R_s I_d - X_q' I_q + V \sin(\delta - \theta) - E_d', \\ @@ -236,12 +239,13 @@ 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(); @@ -269,10 +273,10 @@ int Generator4::evaluateIntegrand() template int Generator4::initializeAdjoint() { - //std::cout << "Initialize adjoint for Generator4..." << std::endl; - for (IdxT i=0; i::initializeAdjoint() 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_{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_{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} * */ @@ -303,12 +309,12 @@ int Generator4::evaluateAdjointResidual() 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; } @@ -331,7 +337,6 @@ int Generator4::evaluateAdjointIntegrand() return 0; } - // // Private functions // @@ -345,7 +350,7 @@ int Generator4::evaluateAdjointIntegrand() template ScalarT Generator4::Pg() { - return y_[5]*V()*cos(theta() - y_[0]) + y_[4]*V()*sin(theta() - y_[0]); + return y_[5] * V() * cos(theta() - y_[0]) + y_[4] * V() * sin(theta() - y_[0]); } /** @@ -356,7 +361,7 @@ ScalarT Generator4::Pg() template ScalarT Generator4::Qg() { - return y_[5]*V()*sin(theta() - y_[0]) - y_[4]*V()*cos(theta() - y_[0]); + return y_[5] * V() * sin(theta() - y_[0]) - y_[4] * V() * cos(theta() - y_[0]); } /** @@ -389,12 +394,8 @@ ScalarT Generator4::frequencyPenaltyDer(ScalarT omega) } } - - // Available template instantiations template class Generator4; template class Generator4; - -} // namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator4/Generator4.hpp b/src/Model/PowerFlow/Generator4/Generator4.hpp index ff4333ef8..cd10690ef 100644 --- a/src/Model/PowerFlow/Generator4/Generator4.hpp +++ b/src/Model/PowerFlow/Generator4/Generator4.hpp @@ -60,203 +60,202 @@ #ifndef _GENERATOR_4_H_ #define _GENERATOR_4_H_ -#include +#include -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } -namespace ModelLib +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) + { + 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 { - 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_; - }; - -} // namespace ModelLib + 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/CMakeLists.txt b/src/Model/PowerFlow/Generator4Governor/CMakeLists.txt index 24e2d9d21..096711b8f 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/Generator4Governor/Generator4Governor.cpp b/src/Model/PowerFlow/Generator4Governor/Generator4Governor.cpp index 6c5d02527..e8ee7e1e3 100644 --- a/src/Model/PowerFlow/Generator4Governor/Generator4Governor.cpp +++ b/src/Model/PowerFlow/Generator4Governor/Generator4Governor.cpp @@ -57,14 +57,15 @@ * */ +#include "Generator4Governor.hpp" -#include #include -#include "Generator4Governor.hpp" -#include "Model/PowerFlow/Bus/BaseBus.hpp" +#include -namespace ModelLib { +#include "Model/PowerFlow/Bus/BaseBus.hpp" +namespace GridKit +{ /*! * @brief Constructor for a model of generator with governor @@ -77,43 +78,42 @@ namespace ModelLib { */ 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) + : 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; + // std::cout << "Destroy Gen2..." << std::endl; } /*! @@ -122,7 +122,7 @@ Generator4Governor::~Generator4Governor() template int Generator4Governor::allocate() { - //std::cout << "Allocate Gen2..." << std::endl; + // std::cout << "Allocate Gen2..." << std::endl; tag_.resize(size_); return 0; @@ -156,24 +156,24 @@ 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,22 +181,22 @@ 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; @@ -209,7 +209,7 @@ int Generator4Governor::initialize() template int Generator4Governor::tagDifferentiable() { - //std::cout << "size of tag vector is " << tag_.size() << "\n"; + // std::cout << "size of tag vector is " << tag_.size() << "\n"; tag_[offsetGen_ + 0] = true; tag_[offsetGen_ + 1] = true; tag_[offsetGen_ + 2] = true; @@ -230,7 +230,8 @@ int Generator4Governor::tagDifferentiable() * Residual equations are given as: * \f{eqnarray*}{ * f_0: &~& \dot{\delta} -\omega_b (\omega - \omega_s), \\ - * f_1: &~& 2H/\omega_s \dot{\omega} - L_m(P_m) + E_q' I_q + E_d' I_d + (X_q' - X_d')I_d I_q + D (\omega - \omega_s), \\ + * f_1: &~& 2H/\omega_s \dot{\omega} - L_m(P_m) + E_q' I_q + E_d' I_d + (X_q' - X_d')I_d I_q + D (\omega - \omega_s), + * \\ * f_2: &~& T_{q0}' \dot{E}_d' + E_d' - (X_q - X_q')I_q, \\ * f_3: &~& T_{d0}' \dot{E}_q' + E_q' + (X_d - X_d')I_d - E_f, \\ * f_4: &~& R_s I_d - X_q' I_q + V \sin(\delta - \theta) - E_d', \\ @@ -264,12 +265,13 @@ 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,8 +279,9 @@ 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; } @@ -307,10 +310,10 @@ int Generator4Governor::evaluateIntegrand() template int Generator4Governor::initializeAdjoint() { - //std::cout << "Initialize adjoint for Generator4Governor..." << std::endl; - for (IdxT i=0; i::initializeAdjoint() * 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_{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' @@ -353,26 +357,33 @@ int Generator4Governor::evaluateAdjointResidual() 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; } @@ -391,18 +402,15 @@ 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 // @@ -416,7 +424,7 @@ int Generator4Governor::evaluateAdjointIntegrand() template ScalarT Generator4Governor::Pg() { - return Iq()*Eqp() + Id()*Edp() + (Xqp_ - Xdp_)*Id()*Iq() - Rs_*(Id()*Id() + Iq()*Iq()); + return Iq() * Eqp() + Id() * Edp() + (Xqp_ - Xdp_) * Id() * Iq() - Rs_ * (Id() * Id() + Iq() * Iq()); } /** @@ -427,7 +435,7 @@ ScalarT Generator4Governor::Pg() template ScalarT Generator4Governor::Qg() { - return -Iq()*Edp() + Id()*Eqp() - Xdp_*Id()*Id() - Xqp_*Iq()*Iq(); + return -Iq() * Edp() + Id() * Eqp() - Xdp_ * Id() * Id() - Xqp_ * Iq() * Iq(); } /** @@ -466,39 +474,32 @@ ScalarT Generator4Governor::frequencyPenaltyDer(ScalarT omega) } } - template ScalarT Generator4Governor::Lm(ScalarT Pm) { - return Pm0_ + deltaPm_*std::tanh(Pm); + return Pm0_ + deltaPm_ * std::tanh(Pm); } template ScalarT Generator4Governor::dLm(ScalarT Pm) { - return deltaPm_/(std::cosh(Pm) * std::cosh(Pm)); + return deltaPm_ / (std::cosh(Pm) * std::cosh(Pm)); } - template ScalarT Generator4Governor::Ln(ScalarT Pn) { - return deltaPn_*std::tanh(Pn); + return deltaPn_ * std::tanh(Pn); } template ScalarT Generator4Governor::dLn(ScalarT Pn) { - return deltaPn_/(std::cosh(Pn) * std::cosh(Pn)); + return deltaPn_ / (std::cosh(Pn) * std::cosh(Pn)); } - - - - // Available template instantiations template class Generator4Governor; template class Generator4Governor; - -} // namespace ModelLib +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator4Governor/Generator4Governor.hpp b/src/Model/PowerFlow/Generator4Governor/Generator4Governor.hpp index c8fd2c424..16c6f239b 100644 --- a/src/Model/PowerFlow/Generator4Governor/Generator4Governor.hpp +++ b/src/Model/PowerFlow/Generator4Governor/Generator4Governor.hpp @@ -60,266 +60,263 @@ #ifndef _GENERATOR_4_GOVERNOR_B_HPP_ #define _GENERATOR_4_GOVERNOR_B_HPP_ -#include +#include -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } -namespace ModelLib +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) + { + 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() { - 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_; - }; - -} // namespace ModelLib + 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/CMakeLists.txt b/src/Model/PowerFlow/Generator4Param/CMakeLists.txt index 457ebc407..2c87b7187 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/Generator4Param/Generator4Param.cpp b/src/Model/PowerFlow/Generator4Param/Generator4Param.cpp index d0bb84561..10f347fe2 100644 --- a/src/Model/PowerFlow/Generator4Param/Generator4Param.cpp +++ b/src/Model/PowerFlow/Generator4Param/Generator4Param.cpp @@ -57,13 +57,15 @@ * */ +#include "Generator4Param.hpp" -#include #include +#include + #include -#include "Generator4Param.hpp" -namespace ModelLib { +namespace GridKit +{ /*! * @brief Constructor for a simple generator model @@ -75,23 +77,23 @@ namespace ModelLib { */ 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) + : 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) { } @@ -107,7 +109,7 @@ Generator4Param::~Generator4Param() template int Generator4Param::allocate() { - //std::cout << "Allocate Generator4Param..." << std::endl; + // std::cout << "Allocate Generator4Param..." << std::endl; tag_.resize(size_); return 0; @@ -141,23 +143,23 @@ 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; @@ -196,7 +198,7 @@ int Generator4Param::tagDifferentiable() tag_[2] = true; tag_[3] = true; - for (IdxT i=4; i < size_; ++i) + for (IdxT i = 4; i < size_; ++i) { tag_[i] = false; } @@ -211,7 +213,8 @@ int Generator4Param::tagDifferentiable() * Scripting, Federico Milano, Chapter 15, p. 334: * \f{eqnarray*}{ * f_0: &~& \dot{\delta} -\omega_b (\omega - \omega_s), \\ - * f_1: &~& 2H/\omega_s \dot{\omega} - L_m(P_m) + E_q' I_q + E_d' I_d + (X_q' - X_d')I_d I_q + D (\omega - \omega_s), \\ + * f_1: &~& 2H/\omega_s \dot{\omega} - L_m(P_m) + E_q' I_q + E_d' I_d + (X_q' - X_d')I_d I_q + D (\omega - \omega_s), + * \\ * f_2: &~& T_{q0}' \dot{E}_d' + E_d' - (X_q - X_q')I_q, \\ * f_3: &~& T_{d0}' \dot{E}_q' + E_q' + (X_d - X_d')I_d - E_f, \\ * f_4: &~& R_s I_d - X_q' I_q + V \sin(\delta - \theta) - E_d', \\ @@ -236,18 +239,19 @@ 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; } @@ -271,31 +275,33 @@ int Generator4Param::evaluateIntegrand() template int Generator4Param::initializeAdjoint() { - //std::cout << "Initialize adjoint for Generator4Param..." << std::endl; - for (IdxT i=0; i::evaluateAdjointResidual() 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; } @@ -329,12 +335,11 @@ 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 // @@ -348,7 +353,7 @@ int Generator4Param::evaluateAdjointIntegrand() template ScalarT Generator4Param::Pg() { - return y_[5]*V()*cos(theta() - y_[0]) + y_[4]*V()*sin(theta() - y_[0]); + return y_[5] * V() * cos(theta() - y_[0]) + y_[4] * V() * sin(theta() - y_[0]); } /** @@ -359,39 +364,43 @@ ScalarT Generator4Param::Pg() template ScalarT Generator4Param::Qg() { - return y_[5]*V()*sin(theta() - y_[0]) - y_[4]*V()*cos(theta() - y_[0]); + 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(); + 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]; + 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) + 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]; + 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 { @@ -402,28 +411,30 @@ ScalarT Generator4Param::trajectoryPenalty(ScalarT t) const } double d = (Edp() - Edp_est); double q = (Eqp() - Eqp_est); - return (d*d + q*q); + 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)); + 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) + 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]; + 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 { @@ -433,28 +444,30 @@ ScalarT Generator4Param::trajectoryPenaltyDerEdp(ScalarT t) const } double d = (Edp() - Edp_est); - return 2.0*d; + 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)); + 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) + 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]; + 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 { @@ -464,12 +477,10 @@ ScalarT Generator4Param::trajectoryPenaltyDerEqp(ScalarT t) const } double q = (Eqp() - Eqp_est); - return 2.0*q; + return 2.0 * q; } template class Generator4Param; template class Generator4Param; - -} // namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerFlow/Generator4Param/Generator4Param.hpp b/src/Model/PowerFlow/Generator4Param/Generator4Param.hpp index ea8774b82..71e0bd188 100644 --- a/src/Model/PowerFlow/Generator4Param/Generator4Param.hpp +++ b/src/Model/PowerFlow/Generator4Param/Generator4Param.hpp @@ -60,220 +60,220 @@ #ifndef _GENERATOR_4_H_ #define _GENERATOR_4_H_ -#include +#include -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } -namespace ModelLib +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) + { + 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 { - 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_; - }; - -} // namespace ModelLib + 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/CMakeLists.txt b/src/Model/PowerFlow/Load/CMakeLists.txt index 46abf3a22..c57e81ef9 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/Load.cpp b/src/Model/PowerFlow/Load/Load.cpp index 398623657..68838fd86 100644 --- a/src/Model/PowerFlow/Load/Load.cpp +++ b/src/Model/PowerFlow/Load/Load.cpp @@ -57,14 +57,16 @@ * */ +#include "Load.hpp" -#include #include +#include #include -#include "Load.hpp" + #include -namespace ModelLib { +namespace GridKit +{ /*! * @brief Constructor for a constant load model @@ -73,24 +75,16 @@ namespace ModelLib { */ template -Load::Load(bus_type* bus, ScalarT P, ScalarT Q) - : P_(P), - Q_(Q), - busID_(0), - bus_(bus) +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"; + // 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) +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"; + // std::cout << "Create a load model with " << size_ << " variables ...\n"; size_ = 0; } @@ -170,13 +164,8 @@ int Load::evaluateAdjointIntegrand() return 0; } - - - // Available template instantiations template class Load; template class Load; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerFlow/Load/Load.hpp b/src/Model/PowerFlow/Load/Load.hpp index c6d3d55a2..e57f1a4c3 100644 --- a/src/Model/PowerFlow/Load/Load.hpp +++ b/src/Model/PowerFlow/Load/Load.hpp @@ -60,74 +60,74 @@ #ifndef _LOAD_HPP_ #define _LOAD_HPP_ -#include +#include #include -namespace ModelLib +namespace GridKit { - template class BaseBus; +template +class BaseBus; } - -namespace ModelLib +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/Load/README.md b/src/Model/PowerFlow/Load/README.md index fa10a0888..caa43996f 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 c88608b53..8c6b2e682 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/MiniGrid/MiniGrid.cpp b/src/Model/PowerFlow/MiniGrid/MiniGrid.cpp index c937f3d78..5511f3001 100644 --- a/src/Model/PowerFlow/MiniGrid/MiniGrid.cpp +++ b/src/Model/PowerFlow/MiniGrid/MiniGrid.cpp @@ -57,14 +57,16 @@ * */ +#include "MiniGrid.hpp" -#include #include +#include #include -#include "MiniGrid.hpp" + #include -namespace ModelLib { +namespace GridKit +{ /*! * @brief Constructor for a constant load model @@ -74,21 +76,21 @@ namespace ModelLib { 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) + : 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"; - rtol_ = 1e-5; - atol_ = 1e-5; + // std::cout << "Create a load model with " << size_ << " variables ...\n"; + rel_tol_ = 1e-5; + abs_tol_ = 1e-5; } template @@ -117,7 +119,6 @@ int MiniGrid::initialize() return 0; } - /** * @brief Contributes to the bus residual. * @@ -126,9 +127,9 @@ int MiniGrid::initialize() 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())); + 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; } @@ -143,6 +144,4 @@ int MiniGrid::evaluateJacobian() template class MiniGrid; template class MiniGrid; - -} //namespace ModelLib - +} // namespace GridKit diff --git a/src/Model/PowerFlow/MiniGrid/MiniGrid.hpp b/src/Model/PowerFlow/MiniGrid/MiniGrid.hpp index 1ec9e431a..2a98afa50 100644 --- a/src/Model/PowerFlow/MiniGrid/MiniGrid.hpp +++ b/src/Model/PowerFlow/MiniGrid/MiniGrid.hpp @@ -58,87 +58,110 @@ */ #pragma once -#include #include -namespace ModelLib +#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() + { + 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() { - using ModelEvaluatorImpl::size_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::f_; - using ModelEvaluatorImpl::rtol_; - using ModelEvaluatorImpl::atol_; - - 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 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 new file mode 100644 index 000000000..c2a479508 --- /dev/null +++ b/src/Model/PowerFlow/ModelEvaluatorImpl.hpp @@ -0,0 +1,318 @@ +/* + * + * 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 + * modification, are permitted provided that the following conditions are met: + * - 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 + * 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 + * 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 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL + * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * 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 + * 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 + * 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. + * + */ + +#ifndef _MODEL_EVALUATOR_IMPL_HPP_ +#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_; + + 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 + +#endif // _MODEL_EVALUATOR_IMPL_HPP_ diff --git a/src/SystemModel.hpp b/src/Model/PowerFlow/SystemModel.hpp similarity index 74% rename from src/SystemModel.hpp rename to src/Model/PowerFlow/SystemModel.hpp index 14b7e4e97..416c5743a 100644 --- a/src/SystemModel.hpp +++ b/src/Model/PowerFlow/SystemModel.hpp @@ -60,21 +60,21 @@ #ifndef _SYSTEM_MODEL_HPP_ #define _SYSTEM_MODEL_HPP_ +#include #include #include -#include +#include #include -#include -namespace ModelLib +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 + * 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. @@ -83,9 +83,9 @@ namespace ModelLib template class SystemModel : public ModelEvaluatorImpl { - typedef BaseBus bus_type; - typedef ModelEvaluatorImpl component_type; - using real_type = typename ModelEvaluatorImpl::real_type; + using bus_type = Model::Evaluator; + using component_type = Model::Evaluator; + using real_type = typename ModelEvaluatorImpl::real_type; using ModelEvaluatorImpl::size_; using ModelEvaluatorImpl::size_quad_; @@ -102,8 +102,8 @@ class SystemModel : public ModelEvaluatorImpl using ModelEvaluatorImpl::fB_; using ModelEvaluatorImpl::g_; using ModelEvaluatorImpl::gB_; - using ModelEvaluatorImpl::rtol_; - using ModelEvaluatorImpl::atol_; + using ModelEvaluatorImpl::rel_tol_; + using ModelEvaluatorImpl::abs_tol_; using ModelEvaluatorImpl::param_; using ModelEvaluatorImpl::param_up_; using ModelEvaluatorImpl::param_lo_; @@ -115,9 +115,9 @@ class SystemModel : public ModelEvaluatorImpl SystemModel() : ModelEvaluatorImpl(0, 0, 0) { // Set system model tolerances - rtol_ = 1e-7; - atol_ = 1e-9; - this->max_steps_=2000; + rel_tol_ = 1e-7; + abs_tol_ = 1e-9; + this->max_steps_ = 2000; } /** @@ -146,21 +146,21 @@ class SystemModel : public ModelEvaluatorImpl size_opt_ = 0; // Allocate all buses - for(const auto& bus: buses_) + for (const auto& bus : buses_) { bus->allocate(); size_ += bus->size(); - size_quad_ += bus->size_quad(); - size_opt_ += bus->size_opt(); + size_quad_ += bus->sizeQuadrature(); + size_opt_ += bus->sizeParams(); } // Allocate all components - for(const auto& component : components_) + for (const auto& component : components_) { component->allocate(); size_ += component->size(); - size_quad_ += component->size_quad(); - size_opt_ += component->size_opt(); + size_quad_ += component->sizeQuadrature(); + size_opt_ += component->sizeParams(); } // Allocate global vectors @@ -173,7 +173,7 @@ class SystemModel : public ModelEvaluatorImpl tag_.resize(size_); g_.resize(size_quad_); - gB_.resize(size_quad_*size_opt_); + gB_.resize(size_quad_ * size_opt_); param_.resize(size_opt_); param_lo_.resize(size_opt_); @@ -186,11 +186,11 @@ class SystemModel : public ModelEvaluatorImpl /** * @brief Assume that jacobian is not avalible - * - * @return true - * @return false + * + * @return true + * @return false */ - bool hasJacobian() + bool hasJacobian() { return false; } @@ -216,51 +216,51 @@ class SystemModel : public ModelEvaluatorImpl IdxT varOffset = 0; IdxT optOffset = 0; - for(const auto& bus: buses_) + for (const auto& bus : buses_) { bus->initialize(); } - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) + 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; jsize_opt(); ++j) + 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->size_opt(); + optOffset += bus->sizeParams(); } // Initialize components - for(const auto& component : components_) + for (const auto& component : components_) { component->initialize(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize(); ++j) + 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; jsize_opt(); ++j) + 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->size_opt(); + optOffset += component->sizeParams(); } return 0; @@ -277,22 +277,22 @@ class SystemModel : public ModelEvaluatorImpl { // 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) + for (IdxT j = 0; j < bus->size(); ++j) { - tag_[offset + j] = bus->tag()[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) + for (IdxT j = 0; j < component->size(); ++j) { - tag_[offset + j] = component->tag()[j]; + tag_[offset + j] = component->tag()[j]; } offset += component->size(); } @@ -323,58 +323,58 @@ class SystemModel : public ModelEvaluatorImpl // Update variables IdxT varOffset = 0; IdxT optOffset = 0; - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) + 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; jsize_opt(); ++j) + for (IdxT j = 0; j < bus->sizeParams(); ++j) { bus->param()[j] = param_[optOffset + j]; } - optOffset += bus->size_opt(); + optOffset += bus->sizeParams(); bus->evaluateResidual(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize(); ++j) + 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; jsize_opt(); ++j) + for (IdxT j = 0; j < component->sizeParams(); ++j) { component->param()[j] = param_[optOffset + j]; } - optOffset += component->size_opt(); + 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) + for (IdxT j = 0; j < bus->size(); ++j) { - f_[resOffset + j] = bus->getResidual()[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) + for (IdxT j = 0; j < component->size(); ++j) { - f_[resOffset + j] = component->getResidual()[j]; + f_[resOffset + j] = component->getResidual()[j]; } resOffset += component->size(); } @@ -390,7 +390,10 @@ class SystemModel : public ModelEvaluatorImpl * only. * */ - int evaluateJacobian(){return 0;} + int evaluateJacobian() + { + return 0; + } /** * @brief Evaluate integrands for the system quadratures. @@ -400,60 +403,60 @@ class SystemModel : public ModelEvaluatorImpl // Update variables IdxT varOffset = 0; IdxT optOffset = 0; - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) + 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; jsize_opt(); ++j) + for (IdxT j = 0; j < bus->sizeParams(); ++j) { bus->param()[j] = param_[optOffset + j]; } - optOffset += bus->size_opt(); + optOffset += bus->sizeParams(); bus->evaluateIntegrand(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize(); ++j) + 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; jsize_opt(); ++j) + for (IdxT j = 0; j < component->sizeParams(); ++j) { component->param()[j] = param_[optOffset + j]; } - optOffset += component->size_opt(); + 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; jsize_quad(); ++j) + for (IdxT j = 0; j < bus->sizeQuadrature(); ++j) { - g_[intOffset + j] = bus->getIntegrand()[j]; + g_[intOffset + j] = bus->getIntegrand()[j]; } - intOffset += bus->size_quad(); + intOffset += bus->sizeQuadrature(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize_quad(); ++j) + for (IdxT j = 0; j < component->sizeQuadrature(); ++j) { - g_[intOffset + j] = component->getIntegrand()[j]; + g_[intOffset + j] = component->getIntegrand()[j]; } - intOffset += component->size_quad(); + intOffset += component->sizeQuadrature(); } return 0; @@ -467,52 +470,52 @@ class SystemModel : public ModelEvaluatorImpl */ int initializeAdjoint() { - IdxT offset = 0; + 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) + 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; jsize_opt(); ++j) + for (IdxT j = 0; j < bus->sizeParams(); ++j) { - bus->param()[j] = param_[optOffset + j]; + bus->param()[j] = param_[optOffset + j]; } - optOffset += bus->size_opt(); + 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) + 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; jsize_opt(); ++j) + for (IdxT j = 0; j < component->sizeParams(); ++j) { - component->param()[j] = param_[optOffset + j]; + component->param()[j] = param_[optOffset + j]; } - optOffset += component->size_opt(); + 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) + for (IdxT j = 0; j < bus->size(); ++j) { yB_[offset + j] = bus->yB()[j]; ypB_[offset + j] = bus->ypB()[j]; @@ -521,11 +524,11 @@ class SystemModel : public ModelEvaluatorImpl } // Initialize component adjoints - for(const auto& component: components_) + for (const auto& component : components_) { component->initializeAdjoint(); - for(IdxT j=0; jsize(); ++j) + for (IdxT j = 0; j < component->size(); ++j) { yB_[offset + j] = component->yB()[j]; ypB_[offset + j] = component->ypB()[j]; @@ -549,9 +552,9 @@ class SystemModel : public ModelEvaluatorImpl IdxT optOffset = 0; // Update variables in component models - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) + for (IdxT j = 0; j < bus->size(); ++j) { bus->y()[j] = y_[varOffset + j]; bus->yp()[j] = yp_[varOffset + j]; @@ -560,17 +563,16 @@ class SystemModel : public ModelEvaluatorImpl } varOffset += bus->size(); - for(IdxT j=0; jsize_opt(); ++j) + for (IdxT j = 0; j < bus->sizeParams(); ++j) { bus->param()[j] = param_[optOffset + j]; } - optOffset += bus->size_opt(); - + optOffset += bus->sizeParams(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize(); ++j) + for (IdxT j = 0; j < component->size(); ++j) { component->y()[j] = y_[varOffset + j]; component->yp()[j] = yp_[varOffset + j]; @@ -579,40 +581,39 @@ class SystemModel : public ModelEvaluatorImpl } varOffset += component->size(); - for(IdxT j=0; jsize_opt(); ++j) + for (IdxT j = 0; j < component->sizeParams(); ++j) { component->param()[j] = param_[optOffset + j]; } - optOffset += component->size_opt(); - + optOffset += component->sizeParams(); } - for(const auto& bus: buses_) + for (const auto& bus : buses_) { bus->evaluateAdjointResidual(); } - for(const auto& component : components_) + for (const auto& component : components_) { component->evaluateAdjointResidual(); } // Update residual vector IdxT resOffset = 0; - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) + for (IdxT j = 0; j < bus->size(); ++j) { - fB_[resOffset + j] = bus->getAdjointResidual()[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) + for (IdxT j = 0; j < component->size(); ++j) { - fB_[resOffset + j] = component->getAdjointResidual()[j]; + fB_[resOffset + j] = component->getAdjointResidual()[j]; } resOffset += component->size(); } @@ -620,7 +621,7 @@ class SystemModel : public ModelEvaluatorImpl return 0; } - //int evaluateAdjointJacobian(){return 0;} + // int evaluateAdjointJacobian(){return 0;} /** * @brief Evaluate adjoint integrand for the system model. @@ -634,9 +635,9 @@ class SystemModel : public ModelEvaluatorImpl // 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) + for (IdxT j = 0; j < bus->size(); ++j) { bus->y()[j] = y_[varOffset + j]; bus->yp()[j] = yp_[varOffset + j]; @@ -645,16 +646,16 @@ class SystemModel : public ModelEvaluatorImpl } varOffset += bus->size(); - for(IdxT j=0; jsize_opt(); ++j) + for (IdxT j = 0; j < bus->sizeParams(); ++j) { bus->param()[j] = param_[optOffset + j]; } - optOffset += bus->size_opt(); + optOffset += bus->sizeParams(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize(); ++j) + for (IdxT j = 0; j < component->size(); ++j) { component->y()[j] = y_[varOffset + j]; component->yp()[j] = yp_[varOffset + j]; @@ -663,20 +664,20 @@ class SystemModel : public ModelEvaluatorImpl } varOffset += component->size(); - for(IdxT j=0; jsize_opt(); ++j) + for (IdxT j = 0; j < component->sizeParams(); ++j) { component->param()[j] = param_[optOffset + j]; } - optOffset += component->size_opt(); + optOffset += component->sizeParams(); } // Evaluate integrand and update global vector - for(const auto& component : components_) + for (const auto& component : components_) { - if(component->size_quad() == 1) + if (component->sizeQuadrature() == 1) { component->evaluateAdjointIntegrand(); - for(IdxT j=0; jgetAdjointIntegrand()[j]; } @@ -688,7 +689,7 @@ class SystemModel : public ModelEvaluatorImpl void updateTime(real_type t, real_type a) { - for(const auto& component : components_) + for (const auto& component : components_) { component->updateTime(t, a); } @@ -705,11 +706,11 @@ class SystemModel : public ModelEvaluatorImpl } private: - std::vector buses_; + std::vector buses_; std::vector components_; }; // class SystemModel -} // namespace ModelLib +} // 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 ca1af16f0..3d1ae125a 100644 --- a/src/Model/PowerFlow/SystemModelPowerFlow.hpp +++ b/src/Model/PowerFlow/SystemModelPowerFlow.hpp @@ -60,20 +60,20 @@ /** * @file SystemSteadyStaeModel.hpp * @author Slaven Peles - * + * * Contains definition of power flow analysis class. - * + * */ #pragma once +#include #include #include -#include +#include #include -#include -namespace ModelLib +namespace GridKit { /** @@ -84,14 +84,14 @@ namespace ModelLib * 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 BaseBus bus_type; typedef ModelEvaluatorImpl component_type; using real_type = typename ModelEvaluatorImpl::real_type; @@ -110,8 +110,8 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl // using ModelEvaluatorImpl::fB_; // using ModelEvaluatorImpl::g_; // using ModelEvaluatorImpl::gB_; - using ModelEvaluatorImpl::rtol_; - using ModelEvaluatorImpl::atol_; + using ModelEvaluatorImpl::rel_tol_; + using ModelEvaluatorImpl::abs_tol_; // using ModelEvaluatorImpl::param_; // using ModelEvaluatorImpl::param_up_; // using ModelEvaluatorImpl::param_lo_; @@ -123,50 +123,52 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl SystemSteadyStateModel() : ModelEvaluatorImpl(0, 0, 0) { // Set system model tolerances - rtol_ = 1e-5; - atol_ = 1e-5; + 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) { - rtol_ = 1e-5; - atol_ = 1e-5; + rel_tol_ = 1e-5; + abs_tol_ = 1e-5; - //add buses - for(auto busdata : mp.bus) + // add buses + for (auto busdata : mp.bus) { auto* bus = BusFactory::create(busdata); this->addBus(bus); } - //add generators + // add generators for (auto gendata : mp.gen) { - auto* gen = GeneratorFactory::create(this->getBus(gendata.bus),gendata); + auto* gen = GeneratorFactory::create(this->getBus(gendata.bus), gendata); this->addComponent(gen); } - //add branches + // add branches for (auto branchdata : mp.branch) { - auto* branch = new Branch(this->getBus(branchdata.fbus),this->getBus(branchdata.tbus),branchdata); + auto* branch = + new Branch(this->getBus(branchdata.fbus), this->getBus(branchdata.tbus), branchdata); this->addComponent(branch); } - //add loads + // add loads for (auto loaddata : mp.load) { - auto* loadm = new Load(this->getBus(loaddata.bus_i),loaddata); + auto* loadm = new Load(this->getBus(loaddata.bus_i), loaddata); this->addComponent(loadm); } - //There is no Generator Cost Object - //TODO: Implment for GenCost + // 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; } /** @@ -195,14 +199,14 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl size_ = 0; // Allocate all buses - for(const auto& bus: buses_) + for (const auto& bus : buses_) { bus->allocate(); size_ += bus->size(); } // Allocate all components - for(const auto& component : components_) + for (const auto& component : components_) { component->allocate(); size_ += component->size(); @@ -235,31 +239,31 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl // Set initial values for global solution vectors IdxT varOffset = 0; - for(const auto& bus: buses_) + for (const auto& bus : buses_) { bus->initialize(); } - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) + for (IdxT j = 0; j < bus->size(); ++j) { - y_[varOffset + j] = bus->y()[j]; + y_[varOffset + j] = bus->y()[j]; } varOffset += bus->size(); } // Initialize components - for(const auto& component : components_) + for (const auto& component : components_) { component->initialize(); } - for(const auto& component : components_) + for (const auto& component : components_) { - for(IdxT j=0; jsize(); ++j) + for (IdxT j = 0; j < component->size(); ++j) { - y_[varOffset + j] = component->y()[j]; + y_[varOffset + j] = component->y()[j]; } varOffset += component->size(); } @@ -300,21 +304,21 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl { // Update variables IdxT varOffset = 0; - for(const auto& bus: buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) + for (IdxT j = 0; j < bus->size(); ++j) { - bus->y()[j] = y_[varOffset + j]; + 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; jsize(); ++j) + for (IdxT j = 0; j < component->size(); ++j) { - component->y()[j] = y_[varOffset + j]; + component->y()[j] = y_[varOffset + j]; } varOffset += component->size(); component->evaluateResidual(); @@ -322,18 +326,18 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl // Update system residual vector IdxT resOffset = 0; - for(const auto& bus : buses_) + for (const auto& bus : buses_) { - for(IdxT j=0; jsize(); ++j) + 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) + for (IdxT j = 0; j < component->size(); ++j) { f_[resOffset + j] = component->getResidual()[j]; } @@ -351,7 +355,10 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl * only. * */ - int evaluateJacobian(){return 0;} + int evaluateJacobian() + { + return 0; + } /** * @brief Evaluate integrands for the system quadratures. @@ -385,7 +392,7 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl return 0; } - //int evaluateAdjointJacobian(){return 0;} + // int evaluateAdjointJacobian(){return 0;} /** * @brief Evaluate adjoint integrand for the system model. @@ -416,14 +423,14 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl bus_type* getBus(IdxT busid) { // Need to implement mapping of bus IDs to buses in the system model - assert( (buses_[busid - 1])->BusID() == busid ); + assert((buses_[busid - 1])->BusID() == busid); return buses_[busid - 1]; } private: - std::vector buses_; + std::vector buses_; std::vector components_; }; // class SystemSteadyStateModel -} // namespace ModelLib \ No newline at end of file +} // namespace GridKit diff --git a/src/ModelEvaluator.hpp b/src/ModelEvaluator.hpp deleted file mode 100644 index f502acf25..000000000 --- a/src/ModelEvaluator.hpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - * - * 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 - * modification, are permitted provided that the following conditions are met: - * - 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 - * 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 - * 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 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL - * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * 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 - * 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 - * 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. - * - */ - -#ifndef _MODEL_EVALUATOR_HPP_ -#define _MODEL_EVALUATOR_HPP_ - -#include -#include -#include - -namespace ModelLib -{ - - /*! - * @brief Abstract class describing a model. - * - */ - template - class ModelEvaluator - { - public: - typedef typename GridKit::ScalarTraits::real_type real_type; - - ModelEvaluator(){} - virtual ~ModelEvaluator(){} - - 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 int initializeAdjoint() = 0; - virtual int evaluateAdjointResidual() = 0; - // virtual int evaluateAdjointJacobian() = 0; - virtual int evaluateAdjointIntegrand() = 0; - - virtual IdxT size() = 0; - virtual IdxT nnz() = 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 size_quad() = 0; - virtual IdxT size_opt() = 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& y() = 0; - virtual const std::vector& y() const = 0; - - virtual std::vector& yp() = 0; - virtual const std::vector& yp() const = 0; - - virtual std::vector& tag() = 0; - virtual const std::vector& tag() const = 0; - - virtual std::vector& yB() = 0; - virtual const std::vector& yB() const = 0; - - virtual std::vector& ypB() = 0; - virtual const std::vector& ypB() const = 0; - - virtual std::vector& param() = 0; - virtual const std::vector& param() 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 std::vector& getResidual() = 0; - virtual const std::vector& getResidual() const = 0; - - - virtual COO_Matrix& getJacobian() = 0; - virtual const COO_Matrix& getJacobian() const = 0; - - virtual std::vector& getIntegrand() = 0; - virtual const std::vector& getIntegrand() 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 ModelLib - -#endif // _MODEL_EVALUATOR_HPP_ \ No newline at end of file diff --git a/src/ModelEvaluatorImpl.hpp b/src/ModelEvaluatorImpl.hpp deleted file mode 100644 index 0f8969f0b..000000000 --- a/src/ModelEvaluatorImpl.hpp +++ /dev/null @@ -1,323 +0,0 @@ -/* - * - * 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 - * modification, are permitted provided that the following conditions are met: - * - 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 - * 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 - * 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 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL - * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * 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 - * 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 - * 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. - * - */ - -#ifndef _MODEL_EVALUATOR_IMPL_HPP_ -#define _MODEL_EVALUATOR_IMPL_HPP_ - -#include -#include - -namespace ModelLib -{ - - /*! - * @brief Model implementation base class. - * - */ - template - class ModelEvaluatorImpl : public ModelEvaluator - { - public: - typedef typename ModelEvaluator::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_), - J_(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 size_quad() - { - return size_quad_; - } - - virtual IdxT size_opt() - { - 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& rtol, real_type& atol) const - { - rtol = rtol_; - atol = atol_; - } - - 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 J_; - } - - const COO_Matrix& getJacobian() const - { - return J_; - } - - 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 J_; - - std::vector param_; - std::vector param_up_; - std::vector param_lo_; - - real_type time_; - real_type alpha_; - - real_type rtol_; - real_type atol_; - - IdxT max_steps_; - - IdxT idc_; - - }; - - -} // namespace ModelLib - -#endif // _MODEL_EVALUATOR_IMPL_HPP_ \ No newline at end of file diff --git a/src/PowerSystemData.hpp b/src/PowerSystemData.hpp index 67294db4f..098a7f50c 100644 --- a/src/PowerSystemData.hpp +++ b/src/PowerSystemData.hpp @@ -1,8 +1,8 @@ #pragma once -#include -#include #include +#include #include +#include /** * @@ -20,223 +20,186 @@ namespace GridKit namespace PowerSystemData { - template - struct BusData - { - 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 + template + struct BusData { - 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 + 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; - 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 + 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) << 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; ///< 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) << 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 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 << 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 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 { - 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 + 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 072e83710..875028f81 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/CMakeLists.txt b/src/Solver/Dynamic/CMakeLists.txt index ab38756c5..e202c1bdf 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/Dynamic/DynamicSolver.hpp b/src/Solver/Dynamic/DynamicSolver.hpp index 7094d8a45..2e231d227 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,59 +31,60 @@ * 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_ -#include "ModelEvaluator.hpp" +#include "Model/Evaluator.hpp" namespace AnalysisManager { - template - class DynamicSolver +template +class DynamicSolver +{ +public: + DynamicSolver(GridKit::Model::Evaluator* model) : model_(model) + { + } + + virtual ~DynamicSolver() + { + } + + GridKit::Model::Evaluator* getModel() { - public: - DynamicSolver(ModelLib::ModelEvaluator* model) : model_(model) - { - } - virtual ~DynamicSolver(){} - - ModelLib::ModelEvaluator* getModel() - { - return model_; - } - - protected: - ModelLib::ModelEvaluator* 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 2c7df1d30..54d154de0 100644 --- a/src/Solver/Dynamic/Ida.cpp +++ b/src/Solver/Dynamic/Ida.cpp @@ -57,16 +57,15 @@ * */ +#include "Ida.hpp" -#include #include +#include #include #include -#include "ModelEvaluator.hpp" -#include "Ida.hpp" - +#include "Model/Evaluator.hpp" namespace AnalysisManager { @@ -75,7 +74,7 @@ namespace Sundials { template - Ida::Ida(ModelLib::ModelEvaluator* model) : DynamicSolver(model) + Ida::Ida(GridKit::Model::Evaluator* model) : DynamicSolver(model) { int retval = 0; @@ -83,16 +82,16 @@ namespace Sundials retval = SUNContext_Create(SUN_COMM_NULL, &context_); checkOutput(retval, "SUNContext"); solver_ = IDACreate(context_); - tag_ = NULL; + 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() @@ -114,7 +113,6 @@ namespace Sundials ///@todo this free is needed but on geninfbus this seg faults // IDAFree(&solver_); SUNContext_Free(&context_); - } template @@ -128,7 +126,7 @@ namespace Sundials yp_ = N_VClone(yy_); checkAllocation((void*) yp_, "N_VClone"); - //get intial conditions + // get intial conditions this->getDefaultInitialCondition(); // Create vectors to store restart initial condition @@ -149,13 +147,13 @@ namespace Sundials checkOutput(retval, "IDASetUserData"); // Set tolerances - sunrealtype rtol; - sunrealtype atol; + sunrealtype rel_tol; + sunrealtype abs_tol; - model_->setTolerances(rtol, atol); ///< \todo Function name should be "getTolerances"! - retval = IDASStolerances(solver_, rtol, atol); + 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); @@ -190,7 +188,8 @@ namespace Sundials int retval = 0; if (model_->hasJacobian()) { - JacobianMat_ = SUNSparseMatrix(model_->size(), model_->size(), model_->size() * model_->size(), CSR_MAT, context_); + JacobianMat_ = + SUNSparseMatrix(model_->size(), model_->size(), model_->size() * model_->size(), CSR_MAT, context_); checkAllocation((void*) JacobianMat_, "SUNSparseMatrix"); linearSolver_ = SUNLinSol_KLU(yy_, JacobianMat_, context_); @@ -212,7 +211,6 @@ namespace Sundials retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); checkOutput(retval, "IDASetLinearSolver"); - } return retval; @@ -257,7 +255,7 @@ namespace Sundials retval = IDACalcIC(solver_, initType, 0.1); checkOutput(retval, "IDACalcIC"); - + copyVec(yy_, model_->y()); copyVec(yp_, model_->yp()); } @@ -268,20 +266,20 @@ namespace Sundials template int Ida::runSimulation(real_type tf, int nout) { - int retval = 0; - int iout = 0; + int retval = 0; + int iout = 0; real_type tret; - real_type dt = tf / static_cast(nout); + 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) + // printOutput(0.0); + while (nout > iout) { retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); checkOutput(retval, "IDASolve"); - //printOutput(tout); + // printOutput(tout); if (retval == IDA_SUCCESS) { @@ -290,12 +288,12 @@ namespace Sundials } } - //Final copy out. No gaurentee last residual evaluation is final step. + // 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"; + // std::cout << "\n"; return retval; } @@ -309,14 +307,13 @@ namespace Sundials return 0; } - template int Ida::configureQuadrature() { int retval = 0; // Create and initialize quadratures - q_ = N_VNew_Serial(model_->size_quad(), context_); + q_ = N_VNew_Serial(model_->sizeQuadrature(), context_); checkAllocation((void*) q_, "N_VNew_Serial"); // Set integrand function and allocate quadrature workspace @@ -324,11 +321,11 @@ namespace Sundials checkOutput(retval, "IDAQuadInit"); // Set tolerances and error control for quadratures - real_type rtol, atol; - model_->setTolerances(rtol, atol); + real_type rel_tol, abs_tol; + model_->setTolerances(rel_tol, abs_tol); // Set tolerances for quadrature stricter than for integration - retval = IDAQuadSStolerances(solver_, rtol*0.1, atol*0.1); + retval = IDAQuadSStolerances(solver_, rel_tol * 0.1, abs_tol * 0.1); checkOutput(retval, "IDAQuadSStolerances"); // Include quadrature in eror checking @@ -338,7 +335,6 @@ namespace Sundials return retval; } - template int Ida::initializeQuadrature() { @@ -354,25 +350,24 @@ namespace Sundials return retval; } - template int Ida::runSimulationQuadrature(real_type tf, int nout) { - int retval = 0; + 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 dt = tf / static_cast(nout); real_type tout = dt; - //printOutput(0.0); - //printSpecial(0.0, yy_); - for(int i = 0; i < nout; ++i) + // 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); + // printSpecial(tout, yy_); + // printOutput(tout); if (retval == IDA_SUCCESS) { @@ -382,8 +377,8 @@ namespace Sundials retval = IDAGetQuad(solver_, &tret, q_); checkOutput(retval, "IDAGetQuad"); } - - //Final copy out. No gaurentee last residual evaluation is final step. + + // Final copy out. No gaurentee last residual evaluation is final step. model_->updateTime(tf, 0.0); copyVec(yy_, model_->y()); copyVec(yp_, model_->yp()); @@ -391,7 +386,6 @@ namespace Sundials return retval; } - template int Ida::deleteQuadrature() { @@ -401,18 +395,17 @@ namespace Sundials return 0; } - template int Ida::configureAdjoint() { // Allocate adjoint vector, derivatives and quadrature - yyB_ = N_VNew_Serial(model_->size(), context_); + yyB_ = N_VNew_Serial(model_->size(), context_); checkAllocation((void*) yyB_, "N_VNew_Serial"); ypB_ = N_VClone(yyB_); checkAllocation((void*) ypB_, "N_VClone"); - qB_ = N_VNew_Serial(model_->size_opt(), context_); + qB_ = N_VNew_Serial(model_->sizeParams(), context_); checkAllocation((void*) qB_, "N_VNew_Serial"); return 0; @@ -433,13 +426,13 @@ namespace Sundials template int Ida::initializeBackwardSimulation(real_type tf) { - int retval = 0; - sunrealtype rtol; - sunrealtype atol; + int retval = 0; + sunrealtype rel_tol; + sunrealtype abs_tol; model_->initializeAdjoint(); - copyVec(model_->yB(), yyB_); + copyVec(model_->yB(), yyB_); copyVec(model_->ypB(), ypB_); N_VConst(0.0, qB_); @@ -450,8 +443,8 @@ namespace Sundials retval = IDAInitB(solver_, backwardID_, this->adjointResidual, tf, yyB_, ypB_); checkOutput(retval, "IDAInitB"); - model_->setTolerances(rtol, atol); - retval = IDASStolerancesB(solver_, backwardID_, rtol, atol); + model_->setTolerances(rel_tol, abs_tol); + retval = IDASStolerancesB(solver_, backwardID_, rel_tol, abs_tol); checkOutput(retval, "IDASStolerancesB"); retval = IDASetUserDataB(solver_, backwardID_, model_); @@ -471,20 +464,18 @@ namespace Sundials retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); checkOutput(retval, "IDASetLinearSolverB"); - // Also reinitialize quadratures. retval = IDAQuadInitB(solver_, backwardID_, this->adjointIntegrand, qB_); checkOutput(retval, "IDAQuadInitB"); - //retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol*1.1, atol*1.1); - retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol*0.1, atol*0.1); + // 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; } @@ -511,15 +502,15 @@ namespace Sundials template int Ida::runForwardSimulation(real_type tf, int nout) { - int retval = 0; - int ncheck; + 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 dt = tf / static_cast(nout); real_type tout = dt; - for(int i = 0; i < nout; ++i) + for (int i = 0; i < nout; ++i) { retval = IDASolveF(solver_, tout, &time, yy_, yp_, IDA_NORMAL, &ncheck); checkOutput(retval, "IDASolveF"); @@ -532,8 +523,8 @@ namespace Sundials retval = IDAGetQuad(solver_, &time, q_); checkOutput(retval, "IDASolve"); } - - //Final copy out. No gaurentee last residual evaluation is final step. + + // Final copy out. No gaurentee last residual evaluation is final step. model_->updateTime(tf, 0.0); copyVec(yy_, model_->y()); copyVec(yp_, model_->yp()); @@ -544,22 +535,22 @@ namespace Sundials template int Ida::runBackwardSimulation(real_type t_init) { - int retval = 0; - long int nstB; + 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"); IDAGetNumSteps(IDAGetAdjIDABmem(solver_, backwardID_), &nstB); - //std::cout << "done ( nst = " << nstB << " )\n"; + // std::cout << "done ( nst = " << nstB << " )\n"; retval = IDAGetB(solver_, backwardID_, &time, yyB_, ypB_); checkOutput(retval, "IDAGetB"); - //Copy back into model + // Copy back into model copyVec(yyB_, model_->yB()); copyVec(ypB_, model_->ypB()); @@ -577,9 +568,10 @@ namespace Sundials } 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) { - ModelLib::ModelEvaluator* model = static_cast*>(user_data); + GridKit::Model::Evaluator* model = + static_cast*>(user_data); model->updateTime(tres, 0.0); copyVec(yy, model->y()); @@ -593,11 +585,20 @@ namespace Sundials } 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) { - ModelLib::ModelEvaluator* model = static_cast*>(user_data); - + GridKit::Model::Evaluator* model = + static_cast*>(user_data); model->updateTime(t, cj); copyVec(yy, model->y()); @@ -605,39 +606,40 @@ namespace Sundials model->evaluateJacobian(); COO_Matrix Jac = model->getJacobian(); - - //Get reference to the jacobian entries + + // Get reference to the jacobian entries std::tuple&, std::vector&, std::vector&> tpm = Jac.getEntries(); - const auto [r, c, val] = tpm; + const auto [r, c, val] = tpm; - //get the CSR row pointers from COO matrix + // get the CSR row pointers from COO matrix std::vector csrrowdata = Jac.getCSRRowData(); SUNMatZero(J); - //Set row pointers - sunindextype *rowptrs = SUNSparseMatrix_IndexPointers(J); - for (unsigned int i = 0; i < csrrowdata.size() ; 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++ ) + 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]; + data[i] = val[i]; } 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) { - ModelLib::ModelEvaluator* model = static_cast*>(user_data); + GridKit::Model::Evaluator* model = + static_cast*>(user_data); model->updateTime(tt, 0.0); copyVec(yy, model->y()); @@ -651,9 +653,11 @@ namespace Sundials } 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) { - ModelLib::ModelEvaluator* model = static_cast*>(user_data); + GridKit::Model::Evaluator* model = + static_cast*>(user_data); model->updateTime(tt, 0.0); copyVec(yy, model->y()); @@ -668,11 +672,12 @@ namespace Sundials 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) { - ModelLib::ModelEvaluator* model = static_cast*>(user_data); + GridKit::Model::Evaluator* model = + static_cast*>(user_data); model->updateTime(tt, 0.0); copyVec(yy, model->y()); @@ -687,33 +692,31 @@ namespace Sundials 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) + 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) + 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) + for (unsigned int i = 0; i < x.size(); ++i) { if (x[i]) ydata[i] = 1.0; @@ -722,12 +725,11 @@ namespace Sundials } } - 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) @@ -744,8 +746,8 @@ namespace Sundials template void Ida::printSpecial(sunrealtype t, N_Vector y) { - sunrealtype *yval = N_VGetArrayPointer_Serial(y); - IdxT N = static_cast(N_VGetLength_Serial(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) @@ -758,8 +760,8 @@ namespace Sundials template void Ida::printFinalStats() { - int retval = 0; - void* mem = solver_; + int retval = 0; + void* mem = solver_; long int nst; long int nre; long int nje; @@ -781,15 +783,14 @@ namespace Sundials 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"; + 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) { diff --git a/src/Solver/Dynamic/Ida.hpp b/src/Solver/Dynamic/Ida.hpp index f7524a733..6447de912 100644 --- a/src/Solver/Dynamic/Ida.hpp +++ b/src/Solver/Dynamic/Ida.hpp @@ -57,186 +57,179 @@ * */ - #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 "ModelEvaluator.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() { - using DynamicSolver::model_; - - typedef typename GridKit::ScalarTraits::real_type real_type; - - public: - Ida(ModelLib::ModelEvaluator* 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(ModelEvaluator::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 + N_VScale(1.0, yy_, yy0_); + N_VScale(1.0, yp_, yp0_); + return 0; + } + + int getSavedInitialCondition() { - virtual const char* what() const throw() - { - return "Method in Ida class failed!\n"; - } - }; + N_VScale(1.0, yy0_, yy_); + N_VScale(1.0, yp0_, yp_); + return 0; + } + real_type getInitialTime() + { + return t_init_; + } - } // namespace Sundials + real_type getFinalTime() + { + return t_final_; + } + int getNumberOutputTimes() + { + return nout_; + } -} // namespace AnalysisManager + 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/CMakeLists.txt b/src/Solver/Optimization/CMakeLists.txt index 756dfa572..d6693992a 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/Optimization/DynamicConstraint.cpp b/src/Solver/Optimization/DynamicConstraint.cpp index 05ba82bcf..78f6cc046 100644 --- a/src/Solver/Optimization/DynamicConstraint.cpp +++ b/src/Solver/Optimization/DynamicConstraint.cpp @@ -57,248 +57,252 @@ * */ - -#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(); -} +#include +#include -template -DynamicConstraint::~DynamicConstraint() +namespace AnalysisManager { -} - - -template -bool DynamicConstraint::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, - Index& nnz_h_lag, IndexStyleEnum& index_style) +namespace IpoptInterface { - // This code handles one objective function - assert(model_->size_quad() == 1); - - // Number of parameters is size of the system plus 1 fictitious parameter - // to store the objective value. - n = model_->size_opt() + 1; - - // There is one constraint - m = 1; - - // Jacobian is a dense row matrix of length n+1. - nnz_jac_g = model_->size_opt() + 1; - - // Using numerical Hessian. - nnz_h_lag = 0; - - // Use the C index style (0-based) for row/column entries - index_style = C_STYLE; - - return true; -} + template + DynamicConstraint::DynamicConstraint(Sundials::Ida* integrator) + : OptimizationSolver(integrator), + t_init_(integrator_->getInitialTime()), + t_final_(integrator_->getFinalTime()), + nout_(integrator_->getNumberOutputTimes()) + { + model_ = integrator_->getModel(); + } -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_->size_opt() + 1)); - assert(m == 1); - - // Get boundaries for the optimization parameters - for(IdxT i = 0; i < model_->size_opt(); ++i) + template + DynamicConstraint::~DynamicConstraint() { - x_l[i] = model_->param_lo()[i]; - x_u[i] = model_->param_up()[i]; } - // No boundaries for fictitious parameter x[n] - x_l[model_->size_opt()] = -1e20; - x_u[model_->size_opt()] = +1e20; + 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); - // Set constraint g[0] to be equality constraint g[0] = 0 - g_l[0] = 0.0; - g_u[0] = 0.0; + // Number of parameters is size of the system plus 1 fictitious parameter + // to store the objective value. + n = model_->sizeParams() + 1; - return true; -} + // There is one constraint + m = 1; + // Jacobian is a dense row matrix of length n+1. + nnz_jac_g = model_->sizeParams() + 1; -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); + // Using numerical Hessian. + nnz_h_lag = 0; - // Initialize optimization parameters x - for(IdxT i = 0; i < model_->size_opt(); ++i) - x[i] = model_->param()[i]; + // Use the C index style (0-based) for row/column entries + index_style = C_STYLE; - // Initialize fictitious parameter x[n-1] to zero - x[model_->size_opt()] = 0.0; + return true; + } - return true; -} + 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]; + } -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_->size_opt()]; + // 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::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_->size_opt(); ++i) - grad_f[i] = 0.0; - grad_f[model_->size_opt()] = 1.0; + 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); - return true; -} + // 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; -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_->size_opt(); ++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_f(Index n, const Number* x, bool new_x, Number& obj_value) { - 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_->size_opt()]; - //std::cout << "constraint:" << g[0] << std::endl; - return true; -} + // Set objective to fictitious optimization parameter x[n-1] + obj_value = x[model_->sizeParams()]; + 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_grad_f(Index n, const Number* x, bool new_x, Number* grad_f) { - for(IdxT i = 0; i < model_->size_opt(); ++i) - { - iRow[i] = 0; - jCol[i] = i; - } - iRow[model_->size_opt()] = 0; - jCol[model_->size_opt()] = model_->size_opt(); + // 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; } - // ... or compute Jacobian derivatives - else + + 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_->size_opt(); ++i) + for (IdxT i = 0; i < model_->sizeParams(); ++i) + { model_->param()[i] = x[i]; + // std::cout << "x[" << i << "] = " << x[i] << "\n"; + } - // 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 objective function integrator_->getSavedInitialCondition(); integrator_->initializeSimulation(t_init_); integrator_->initializeQuadrature(); int status = 0; - status = integrator_->runForwardSimulation(t_final_, nout_); + status = integrator_->runSimulationQuadrature(t_final_, nout_); if (status) { - std::cerr << "Forward integration for adjoint solution failed when using Pm = " << x[0] << "\n"; + std::cerr << "Integration failed when using Pm = " << x[0] << "\n"; return false; } - integrator_->initializeBackwardSimulation(t_final_); + // 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; + } - status = integrator_->runBackwardSimulation(t_init_); - if (status) + 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) { - std::cerr << "Backward integration for adjoint solution failed when using Pm = " << x[0] << "\n"; - return false; + for (IdxT i = 0; i < model_->sizeParams(); ++i) + { + iRow[i] = 0; + jCol[i] = i; + } + iRow[model_->sizeParams()] = 0; + jCol[model_->sizeParams()] = model_->sizeParams(); } - - // For now assumes only one forward integrand and multiple optimization parameters. - for(IdxT i = 0; i < model_->size_opt(); ++i) + // ... or compute Jacobian derivatives + else { - values[i] = -((integrator_->getAdjointIntegral())[i]); + // 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(); + + integrator_->getSavedInitialCondition(); + integrator_->initializeSimulation(t_init_); + integrator_->initializeQuadrature(); + + int status = 0; + status = integrator_->runForwardSimulation(t_final_, nout_); + if (status) + { + std::cerr << "Forward integration for adjoint solution failed when using Pm = " << x[0] << "\n"; + return false; + } + + integrator_->initializeBackwardSimulation(t_final_); + + status = integrator_->runBackwardSimulation(t_init_); + if (status) + { + 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) + { + values[i] = -((integrator_->getAdjointIntegral())[i]); + } + values[model_->sizeParams()] = -1.0; + + integrator_->deleteAdjoint(); } - values[model_->size_opt()] = -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 AnalysisManager diff --git a/src/Solver/Optimization/DynamicConstraint.hpp b/src/Solver/Optimization/DynamicConstraint.hpp index 234ebcfb7..dd5df8a40 100644 --- a/src/Solver/Optimization/DynamicConstraint.hpp +++ b/src/Solver/Optimization/DynamicConstraint.hpp @@ -57,97 +57,112 @@ * */ - - #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 adc743ba2..bb0a5b5a7 100644 --- a/src/Solver/Optimization/DynamicObjective.cpp +++ b/src/Solver/Optimization/DynamicObjective.cpp @@ -57,188 +57,192 @@ * */ - -#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(); -} - -template -DynamicObjective::~DynamicObjective() -{ -} - +#include +#include -template -bool DynamicObjective::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); - - // Number of optimization variables. - n = model_->size_opt(); - - // There are no constraints - m = 0; - - // No constraints, empty Jacobian. This is only temporary. - nnz_jac_g = 0; - - // Using numerical Hessian. - nnz_h_lag = 0; - - // Use the C index style (0-based) for row/column entries - index_style = C_STYLE; - - return true; -} - - -template -bool DynamicObjective::get_bounds_info(Index n, Number* x_l, Number* x_u, - Index m, Number* g_l, Number* g_u) +namespace IpoptInterface { - // Check if sizes are set correctly - assert(n == (Index) model_->size_opt()); - assert(m == 0); - // Get boundaries for the optimization parameters - for(IdxT i = 0; i < model_->size_opt(); ++i) + template + DynamicObjective::DynamicObjective(Sundials::Ida* integrator) + : OptimizationSolver(integrator), + t_init_(integrator_->getInitialTime()), + t_final_(integrator_->getFinalTime()), + nout_(integrator_->getNumberOutputTimes()) { - x_l[i] = model_->param_lo()[i]; - x_u[i] = model_->param_up()[i]; + model_ = integrator_->getModel(); } - 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); - - // Initialize optimization parameters x - for(IdxT i = 0; i < model_->size_opt(); ++i) - x[i] = model_->param()[i]; + template + DynamicObjective::~DynamicObjective() + { + } - return true; -} + 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 -bool DynamicObjective::eval_f(Index n, const Number* x, bool new_x, Number& obj_value) -{ - // Update optimization parameters - for(IdxT i = 0; i < model_->size_opt(); ++i) - model_->param()[i] = x[i]; + // There are no constraints + m = 0; - // Evaluate objective function - integrator_->getSavedInitialCondition(); - integrator_->initializeSimulation(t_init_); - integrator_->initializeQuadrature(); - integrator_->runSimulationQuadrature(t_final_, nout_); + // No constraints, empty Jacobian. This is only temporary. + nnz_jac_g = 0; - // Assuming objective function is given as the integral (quadrature) 0 - obj_value = (integrator_->getIntegral())[0]; + // Using numerical Hessian. + nnz_h_lag = 0; - return true; -} + // Use the C index style (0-based) for row/column entries + index_style = C_STYLE; + return true; + } -template -bool DynamicObjective::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f) -{ - assert(model_->size_opt() == static_cast(n)); - // Update optimization parameters - for(IdxT i = 0; i < model_->size_opt(); ++i) - model_->param()[i] = x[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; + } - // 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(); + 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); - integrator_->getSavedInitialCondition(); - integrator_->initializeSimulation(t_init_); - integrator_->initializeQuadrature(); - integrator_->runForwardSimulation(t_final_, nout_); + // Initialize optimization parameters x + for (IdxT i = 0; i < model_->sizeParams(); ++i) + x[i] = model_->param()[i]; - integrator_->initializeBackwardSimulation(t_final_); - integrator_->runBackwardSimulation(t_init_); + return true; + } - // For now assumes only one forward integrand and multiple optimization parameters. - for(IdxT i = 0; i < model_->size_opt(); ++i) - grad_f[i] = -((integrator_->getAdjointIntegral())[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]; - integrator_->deleteAdjoint(); + // 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_g(Index n, const Number* x, bool new_x, Index m, Number* g) -{ - 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) + 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(); -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_->getSavedInitialCondition(); + integrator_->initializeSimulation(t_init_); + integrator_->initializeQuadrature(); + integrator_->runForwardSimulation(t_final_, nout_); + integrator_->initializeBackwardSimulation(t_final_); + integrator_->runBackwardSimulation(t_init_); -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; -} + // 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(); -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 AnalysisManager diff --git a/src/Solver/Optimization/DynamicObjective.hpp b/src/Solver/Optimization/DynamicObjective.hpp index d2999730a..61500038b 100644 --- a/src/Solver/Optimization/DynamicObjective.hpp +++ b/src/Solver/Optimization/DynamicObjective.hpp @@ -57,93 +57,108 @@ * */ - - #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 4da398145..9a2c6e9f5 100644 --- a/src/Solver/Optimization/OptimizationSolver.hpp +++ b/src/Solver/Optimization/OptimizationSolver.hpp @@ -60,34 +60,35 @@ #ifndef _OPTIMIZATION_SOLVER_HPP_ #define _OPTIMIZATION_SOLVER_HPP_ -#include "ModelEvaluator.hpp" +#include "Model/Evaluator.hpp" #include 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: - ModelLib::ModelEvaluator* 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/CMakeLists.txt b/src/Solver/SteadyState/CMakeLists.txt index 3d71c5a19..e919cdfd0 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/Solver/SteadyState/Kinsol.cpp b/src/Solver/SteadyState/Kinsol.cpp index 5f6e27392..edc6a2aa3 100644 --- a/src/Solver/SteadyState/Kinsol.cpp +++ b/src/Solver/SteadyState/Kinsol.cpp @@ -60,23 +60,23 @@ /** * @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 "ModelEvaluator.hpp" -#include "Kinsol.hpp" - +#include "Model/Evaluator.hpp" namespace AnalysisManager { @@ -85,7 +85,7 @@ namespace Sundials { template - Kinsol::Kinsol(ModelLib::ModelEvaluator* model) + Kinsol::Kinsol(GridKit::Model::Evaluator* model) : SteadyStateSolver(model) { int retval = 0; @@ -95,7 +95,7 @@ namespace Sundials checkOutput(retval, "SUNContext"); solver_ = KINCreate(context_); - tag_ = NULL; + tag_ = NULL; } template @@ -110,7 +110,7 @@ namespace Sundials SUNMatDestroy(this->JacobianMat_); SUNLinSolFree_Dense(this->linearSolver_); - + solver_ = 0; } @@ -198,8 +198,8 @@ namespace Sundials N_VConst(1.0, scale_); retval = KINSol(solver_, yy_, KIN_LINESEARCH, scale_, scale_); checkOutput(retval, "KINSol"); - //printOutput(tout); - //std::cout << "\n"; + // printOutput(tout); + // std::cout << "\n"; return retval; } @@ -214,10 +214,10 @@ namespace Sundials } 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) { - ModelLib::ModelEvaluator* model = - static_cast*>(user_data); + GridKit::Model::Evaluator* model = + static_cast*>(user_data); copyVec(yy, model->y()); @@ -229,31 +229,30 @@ namespace Sundials } 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) + 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) + 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) + for (unsigned int i = 0; i < x.size(); ++i) { if (x[i]) ydata[i] = 1.0; @@ -262,11 +261,10 @@ namespace Sundials } } - template void Kinsol::printOutput() { - sunrealtype *yval = N_VGetArrayPointer_Serial(yy_); + sunrealtype* yval = N_VGetArrayPointer_Serial(yy_); std::cout << std::setprecision(5) << std::setw(7); for (IdxT i = 0; i < model_->size(); ++i) @@ -279,8 +277,8 @@ namespace Sundials template void Kinsol::printSpecial(sunrealtype t, N_Vector y) { - sunrealtype *yval = N_VGetArrayPointer_Serial(y); - IdxT N = N_VGetLength_Serial(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) @@ -293,8 +291,8 @@ namespace Sundials template void Kinsol::printFinalStats() { - int retval = 0; - void* mem = solver_; + int retval = 0; + void* mem = solver_; long int nni; long int nfe; long int nje; @@ -312,13 +310,12 @@ namespace Sundials 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"; + 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) { diff --git a/src/Solver/SteadyState/Kinsol.hpp b/src/Solver/SteadyState/Kinsol.hpp index acfab9a72..bbd6bbf6b 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 "ModelEvaluator.hpp" +#include "Model/Evaluator.hpp" #include "SteadyStateSolver.hpp" namespace AnalysisManager { - namespace Sundials +namespace Sundials +{ + template + class Kinsol : public SteadyStateSolver { - template - class Kinsol : public SteadyStateSolver - { - using SteadyStateSolver::model_; - - typedef typename GridKit::ScalarTraits::real_type real_type; - - public: - Kinsol(ModelLib::ModelEvaluator* 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(ModelEvaluator::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 + 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() { - virtual const char* what() const throw() - { - return "Method in Kinsol class failed!\n"; - } - }; - + N_VScale(1.0, yy_, yy0_); + return 0; + } - } // namespace Sundials + 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 } // namespace AnalysisManager diff --git a/src/Solver/SteadyState/SteadyStateSolver.hpp b/src/Solver/SteadyState/SteadyStateSolver.hpp index eb9380cfc..f4be7fc12 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,53 +31,56 @@ * 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 -#include "ModelEvaluator.hpp" +#include "Model/Evaluator.hpp" namespace AnalysisManager { - template - class SteadyStateSolver +template +class SteadyStateSolver +{ +public: + SteadyStateSolver(GridKit::Model::Evaluator* model) : model_(model) + { + } + + virtual ~SteadyStateSolver() { - public: - SteadyStateSolver(ModelLib::ModelEvaluator* model) : model_(model) - { - } - virtual ~SteadyStateSolver(){} - - ModelLib::ModelEvaluator* getModel() - { - return model_; - } - - protected: - ModelLib::ModelEvaluator* model_; - }; + } + + GridKit::Model::Evaluator* getModel() + { + return model_; + } + +protected: + GridKit::Model::Evaluator* model_; +}; -} +} // namespace AnalysisManager diff --git a/src/Utilities/CMakeLists.txt b/src/Utilities/CMakeLists.txt index aba0c614f..3bd96fc96 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/src/Utilities/FileIO.hpp b/src/Utilities/FileIO.hpp index 24b244b26..d8bec3bfb 100644 --- a/src/Utilities/FileIO.hpp +++ b/src/Utilities/FileIO.hpp @@ -83,42 +83,41 @@ 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."}; +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); + 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); + 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); + const std::string nothing = ""; + s = std::regex_replace(s, std::regex("%.+"), nothing); } // Retrive MATPOWER component from assignment line. @@ -127,280 +126,310 @@ void trim_matlab_comments(std::string& s) // 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; + 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; } // 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); + 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; + 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); + 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); + 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; - - for (RealT r; is >> r;) { - gcr.rest.push_back(r); - } + 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); + } } 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 + "'"); - } + 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 + "'"); + } } 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 + "'"); - } + 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 + "'"); + } } -} // namespace +} // namespace namespace GridKit { /** * @brief Reads in an input stream of tabulated data - * + * * @todo needs to return int for file error codes - * - * @tparam ScalarT + * + * @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) +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; + 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 } - table.push_back(std::move(row)); - if (oldwordcount != -1) { - if (oldwordcount != wordcount) { - std::cerr << "Corrupted input data!\n"; - return; - } - } else { - oldwordcount = wordcount; + else if (N == 1) + { + ti = table[0][0]; + tf = table[0][0]; + } + else + { + ti = table[0][0]; + tf = table[N - 1][0]; } - } - - 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] << " "; + 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); + std::ifstream ifs{filename}; + readMatPower(mp, ifs); } -template +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 == "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); + 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 == "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); + } + } + + // 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 new file mode 100644 index 000000000..40469a804 --- /dev/null +++ b/src/Utilities/TestHelpers.hpp @@ -0,0 +1,257 @@ + +/** + * @file UnitTest.hpp + * + * @author Slaven Peles , ORNL + * + */ +#pragma once + +#define THROW_NULL_DEREF throw std::runtime_error("error") + +#include +#include +#include + +namespace GridKit +{ + +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 Colors + +namespace Testing +{ + enum TestOutcome + { + PASS = 0, + FAIL, + SKIP, + EXPECTED_FAIL, + UNEXPECTED_PASS + }; + + class TestStatus + { + public: + TestStatus() : outcome_(TestOutcome::PASS) + { + } + + TestStatus(bool success) : outcome_(success ? TestOutcome::PASS : TestOutcome::FAIL) + { + } + + 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; + } + + 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_; + } + + private: + 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() + { + 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; + } + }; + + TestingResults operator+(const TestingResults& lhs, const TestingResults& rhs) + { + return TestingResults(lhs) += rhs; + } + + TestingResults operator+(const TestingResults& lhs, const TestOutcome outcome) + { + return TestingResults(lhs) += outcome; + } + + TestingResults operator+(const TestOutcome outcome, const TestingResults& rhs) + { + 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: + // TestBase() = default; + // ~TestBase() = default; + + // protected: + // /// Returns true if two real numbers are equal within tolerance + // [[nodiscard]] static + // bool isEqual(const real_type a, const real_type b) + // { + // return (std::abs(a - b)/(1.0 + std::abs(b)) < eps); + // } + + // }; + +} // namespace Testing +} // namespace GridKit diff --git a/src/Utilities/Testing.hpp b/src/Utilities/Testing.hpp index f061cdbd1..9433437a9 100644 --- a/src/Utilities/Testing.hpp +++ b/src/Utilities/Testing.hpp @@ -66,191 +66,203 @@ */ #pragma once -#include #include #include +#include + +#include -namespace { +namespace +{ 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 { - -template bool isEqual(const T value, const T ref, const T tol) +namespace GridKit { - 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_) +namespace Testing { - 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 + 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); + } -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; -} + 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::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::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::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; + 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(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(); - }()); + 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; + } - int fail = 0; - for (std::size_t i = 0; i < a.size(); i++) { - if (!isEqual(a[i], b[i])) { - fail++; - errs() << "[isEqual>]: Got failure with i=" << i << ".\n"; + 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; } - } - 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(); + }()); -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; -} + 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; + } + + 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; + } } // namespace Testing diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 000000000..d80cc13bc --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,3 @@ + + +add_subdirectory(UnitTests) diff --git a/tests/UnitTests/CMakeLists.txt b/tests/UnitTests/CMakeLists.txt new file mode 100644 index 000000000..034023832 --- /dev/null +++ b/tests/UnitTests/CMakeLists.txt @@ -0,0 +1,3 @@ +# +add_subdirectory(PhasorDynamics) +add_subdirectory(SparsityPattern) diff --git a/tests/UnitTests/PhasorDynamics/BranchTests.hpp b/tests/UnitTests/PhasorDynamics/BranchTests.hpp new file mode 100644 index 000000000..64e2453db --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/BranchTests.hpp @@ -0,0 +1,139 @@ +#include +#include + +#include +#include +#include +#include +#include + +namespace GridKit +{ +namespace Testing +{ + + template + class BranchTests + { + private: + 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); + + 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 + + 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 GridKit diff --git a/tests/UnitTests/PhasorDynamics/BusTests.hpp b/tests/UnitTests/PhasorDynamics/BusTests.hpp new file mode 100644 index 000000000..0807bf290 --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/BusTests.hpp @@ -0,0 +1,101 @@ +#include +#include + +#include +#include +#include +#include + +namespace GridKit +{ +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__); + } + }; + +} // namespace Testing +} // namespace GridKit diff --git a/tests/UnitTests/PhasorDynamics/CMakeLists.txt b/tests/UnitTests/PhasorDynamics/CMakeLists.txt new file mode 100644 index 000000000..7077c1295 --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/CMakeLists.txt @@ -0,0 +1,38 @@ +# [[ +# Author(s): +# - Slaven Peles +#]] + + +add_executable(test_phasor_bus runBusTests.cpp) +target_link_libraries(test_phasor_bus GRIDKIT::phasor_dynamics_bus) + +add_executable(test_phasor_branch runBranchTests.cpp) +target_link_libraries(test_phasor_branch GRIDKIT::phasor_dynamics_branch + GRIDKIT::phasor_dynamics_bus) + +add_executable(test_phasor_load runLoadTests.cpp) +target_link_libraries(test_phasor_load GRIDKIT::phasor_dynamics_load + GRIDKIT::phasor_dynamics_bus) + +add_executable(test_phasor_synchronous_machine runSynchronousMachineTests.cpp) +target_link_libraries(test_phasor_synchronous_machine GRIDKIT::phasor_dynamics_synchronous_machine + GRIDKIT::phasor_dynamics_bus) + + +add_executable(test_phasor_system runSystemTests.cpp) +target_link_libraries(test_phasor_system GRIDKIT::phasor_dynamics_load + GRIDKIT::phasor_dynamics_branch + GRIDKIT::phasor_dynamics_bus) + +add_test(NAME PhasorDynamicsBusTest COMMAND $) +add_test(NAME PhasorDynamicsBranchTest COMMAND $) +add_test(NAME PhasorDynamicsSynchronousMachineTest COMMAND $) +add_test(NAME PhasorDynamicsLoadTest COMMAND $) +add_test(NAME PhasorDynamicsSystemTest COMMAND $) + +install(TARGETS test_phasor_bus + test_phasor_branch + test_phasor_load + test_phasor_synchronous_machine + test_phasor_system RUNTIME DESTINATION bin) diff --git a/tests/UnitTests/PhasorDynamics/LoadTests.hpp b/tests/UnitTests/PhasorDynamics/LoadTests.hpp new file mode 100644 index 000000000..40d5e0cd2 --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/LoadTests.hpp @@ -0,0 +1,70 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include +#include + +namespace GridKit +{ +namespace Testing +{ + template + class LoadTests + { + public: + using real_type = typename PhasorDynamics::Component::real_type; + + LoadTests() = default; + ~LoadTests() = default; + + TestOutcome constructor() + { + TestStatus success = true; + + auto* bus = new PhasorDynamics::Bus(1.0, 0.0); + + PhasorDynamics::Component* load = new PhasorDynamics::Load(bus); + + success *= (load != nullptr); + + if (load) + { + delete load; + } + delete bus; + + return success.report(__func__); + } + + TestOutcome residual() + { + TestStatus success = true; + + real_type R{2.0}; ///< Load resistance + real_type X{4.0}; ///< Load reactance + + ScalarT Vr{10.0}; ///< Bus real voltage + ScalarT Vi{20.0}; ///< Bus imaginary voltage + + const ScalarT Ir{3.0}; ///< Solution real current + const ScalarT Ii{-4.0}; ///< Solution imaginary current + + PhasorDynamics::BusInfinite bus(Vr, Vi); + + PhasorDynamics::Load load(&bus, R, X); + load.evaluateResidual(); + + 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 new file mode 100644 index 000000000..7504ddf65 --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/SynchronousMachineTests.hpp @@ -0,0 +1,63 @@ +#include +#include + +#include +#include +#include +#include +#include + +namespace GridKit +{ +namespace Testing +{ + + template + class SynchronousMachineTests + { + private: + using real_type = typename PhasorDynamics::Component::real_type; + + public: + SynchronousMachineTests() = default; + ~SynchronousMachineTests() = default; + + TestOutcome constructor() + { + TestStatus success = true; + + auto* bus = new PhasorDynamics::Bus(1.0, 0.0); + + PhasorDynamics::Component* machine = + new PhasorDynamics::SynchronousMachine(bus); + + success *= (machine != nullptr); + + if (machine) + { + delete machine; + } + delete bus; + + return success.report(__func__); + } + + TestOutcome residual() + { + TestStatus success = true; + success.skipTest(); + + return success.report(__func__); + } + + TestOutcome accessors() + { + TestStatus success = true; + success.skipTest(); + + return success.report(__func__); + } + }; // class SynchronousMachineTest + +} // namespace Testing +} // namespace GridKit diff --git a/tests/UnitTests/PhasorDynamics/SystemTests.hpp b/tests/UnitTests/PhasorDynamics/SystemTests.hpp new file mode 100644 index 000000000..d05b8e82f --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/SystemTests.hpp @@ -0,0 +1,97 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace GridKit +{ +namespace Testing +{ + template + class SystemTests + { + private: + using real_type = typename PhasorDynamics::Component::real_type; + + public: + SystemTests() = default; + ~SystemTests() = default; + + /// Constructor, allocation, and initialization checks + TestOutcome constructor() + { + TestStatus success = true; + + // ScalarT Vr{1.0}; + // ScalarT Vi{2.0}; + + PhasorDynamics::SystemModel* system = nullptr; + + // Create an empty system + system = new PhasorDynamics::SystemModel(); + + success *= (system != nullptr); + + if (system) + { + delete system; + } + + return success.report(__func__); + } + + TestOutcome composer() + { + 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 + + // Create an empty system model + PhasorDynamics::SystemModel system; + + // Add a bus + PhasorDynamics::BusInfinite bus1(Vr1, Vi1); + system.addBus(&bus1); + + // Add a bus + PhasorDynamics::BusInfinite bus2(Vr2, Vi2); + system.addBus(&bus1); + + PhasorDynamics::Branch branch(&bus1, &bus2, R, X, G, B); + system.addComponent(&branch); + + system.allocate(); + system.initialize(); + system.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__); + } + }; + +} // namespace Testing +} // namespace GridKit diff --git a/tests/UnitTests/PhasorDynamics/runBranchTests.cpp b/tests/UnitTests/PhasorDynamics/runBranchTests.cpp new file mode 100644 index 000000000..b19c6f430 --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/runBranchTests.cpp @@ -0,0 +1,16 @@ +#include "BranchTests.hpp" + +int main() +{ + using namespace GridKit; + using namespace GridKit::Testing; + + GridKit::Testing::TestingResults result; + GridKit::Testing::BranchTests test; + + result += test.constructor(); + result += test.accessors(); + result += test.residual(); + + return result.summary(); +} diff --git a/tests/UnitTests/PhasorDynamics/runBusTests.cpp b/tests/UnitTests/PhasorDynamics/runBusTests.cpp new file mode 100644 index 000000000..2833239d6 --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/runBusTests.cpp @@ -0,0 +1,15 @@ +#include "BusTests.hpp" + +int main() +{ + using namespace GridKit; + using namespace GridKit::Testing; + + GridKit::Testing::TestingResults result; + GridKit::Testing::BusTests test; + + result += test.constructor(); + result += test.residual(); + + return result.summary(); +} diff --git a/tests/UnitTests/PhasorDynamics/runLoadTests.cpp b/tests/UnitTests/PhasorDynamics/runLoadTests.cpp new file mode 100644 index 000000000..756934c06 --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/runLoadTests.cpp @@ -0,0 +1,15 @@ +#include "LoadTests.hpp" + +int main() +{ + using namespace GridKit; + using namespace GridKit::Testing; + + GridKit::Testing::TestingResults result; + GridKit::Testing::LoadTests test; + + result += test.constructor(); + result += test.residual(); + + return result.summary(); +} diff --git a/tests/UnitTests/PhasorDynamics/runSynchronousMachineTests.cpp b/tests/UnitTests/PhasorDynamics/runSynchronousMachineTests.cpp new file mode 100644 index 000000000..0ff2f75f2 --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/runSynchronousMachineTests.cpp @@ -0,0 +1,16 @@ +#include "SynchronousMachineTests.hpp" + +int main() +{ + using namespace GridKit; + using namespace GridKit::Testing; + + GridKit::Testing::TestingResults result; + GridKit::Testing::SynchronousMachineTests test; + + result += test.constructor(); + result += test.accessors(); + result += test.residual(); + + return result.summary(); +} diff --git a/tests/UnitTests/PhasorDynamics/runSystemTests.cpp b/tests/UnitTests/PhasorDynamics/runSystemTests.cpp new file mode 100644 index 000000000..f86d1463c --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/runSystemTests.cpp @@ -0,0 +1,15 @@ +#include "SystemTests.hpp" + +int main() +{ + using namespace GridKit; + using namespace GridKit::Testing; + + GridKit::Testing::TestingResults result; + GridKit::Testing::SystemTests test; + + result += test.constructor(); + result += test.composer(); + + return result.summary(); +} diff --git a/tests/UnitTests/SparsityPattern/CMakeLists.txt b/tests/UnitTests/SparsityPattern/CMakeLists.txt new file mode 100644 index 000000000..c4c9cc854 --- /dev/null +++ b/tests/UnitTests/SparsityPattern/CMakeLists.txt @@ -0,0 +1,14 @@ +# [[ +# Author(s): +# - Slaven Peles +#]] + + +add_executable(test_sparsity_pattern runSparsityPatternTests.cpp) +target_link_libraries(test_sparsity_pattern GRIDKIT::phasor_dynamics_bus) + + +add_test(NAME SparsityPatternTest COMMAND $) + +install(TARGETS test_sparsity_pattern + RUNTIME DESTINATION bin) diff --git a/tests/UnitTests/SparsityPattern/SparsityPatternTests.hpp b/tests/UnitTests/SparsityPattern/SparsityPatternTests.hpp new file mode 100644 index 000000000..e01887d40 --- /dev/null +++ b/tests/UnitTests/SparsityPattern/SparsityPatternTests.hpp @@ -0,0 +1,84 @@ +#include +#include + +#include +#include +#include + +namespace GridKit +{ +namespace Testing +{ + template + class SparsityPatternTests + { + public: + 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); + + // 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__); + } + + 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 GridKit diff --git a/tests/UnitTests/SparsityPattern/runSparsityPatternTests.cpp b/tests/UnitTests/SparsityPattern/runSparsityPatternTests.cpp new file mode 100644 index 000000000..2311e2bda --- /dev/null +++ b/tests/UnitTests/SparsityPattern/runSparsityPatternTests.cpp @@ -0,0 +1,14 @@ +#include "SparsityPatternTests.hpp" + +int main() +{ + using namespace GridKit; + using namespace GridKit::Testing; + + GridKit::Testing::TestingResults result; + GridKit::Testing::SparsityPatternTests test; + + result += test.variable(); + + return result.summary(); +}