From 1fe2b6752693b3949e5b023f3af24d8a47394217 Mon Sep 17 00:00:00 2001 From: pelesh Date: Fri, 11 Jul 2025 20:47:10 -0400 Subject: [PATCH 1/6] Add signal nodes to Genrou. --- .../Tiny/TwoBus/Basic/CMakeLists.txt | 2 +- .../Tiny/TwoBus/Tgov1/CMakeLists.txt | 9 + .../Tiny/TwoBus/Tgov1/TwoBusTgov1Signal.cpp | 285 ++++++++++++++++ src/Model/PhasorDynamics/BusBase.hpp | 9 +- src/Model/PhasorDynamics/CMakeLists.txt | 2 + src/Model/PhasorDynamics/ComponentLibrary.hpp | 1 + .../Governor/Tgov1/CMakeLists.txt | 1 + .../PhasorDynamics/Governor/Tgov1/Tgov1.cpp | 68 +++- .../PhasorDynamics/Governor/Tgov1/Tgov1.hpp | 10 +- .../PhasorDynamics/SignalNode/CMakeLists.txt | 21 ++ .../PhasorDynamics/SignalNode/SignalNode.cpp | 15 + .../PhasorDynamics/SignalNode/SignalNode.hpp | 315 ++++++++++++++++++ .../SignalNode/SignalNodeData.hpp | 35 ++ .../SignalNodeDependencyTracking.cpp | 15 + .../SignalNode/SignalNodeImpl.hpp | 73 ++++ .../GENROUwS/CMakeLists.txt | 4 + .../SynchronousMachine/GENROUwS/Genrou.hpp | 13 +- .../GENROUwS/GenrouImpl.hpp | 131 +++++++- src/Model/PhasorDynamics/SystemModel.hpp | 30 +- src/Model/PhasorDynamics/SystemModelData.hpp | 5 +- tests/UnitTests/PhasorDynamics/CMakeLists.txt | 15 +- .../PhasorDynamics/GovernorTgov1Tests.hpp | 71 ++++ .../PhasorDynamics/runGovernorTgov1Tests.cpp | 1 + 23 files changed, 1098 insertions(+), 33 deletions(-) create mode 100644 examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1Signal.cpp create mode 100644 src/Model/PhasorDynamics/SignalNode/CMakeLists.txt create mode 100644 src/Model/PhasorDynamics/SignalNode/SignalNode.cpp create mode 100644 src/Model/PhasorDynamics/SignalNode/SignalNode.hpp create mode 100644 src/Model/PhasorDynamics/SignalNode/SignalNodeData.hpp create mode 100644 src/Model/PhasorDynamics/SignalNode/SignalNodeDependencyTracking.cpp create mode 100644 src/Model/PhasorDynamics/SignalNode/SignalNodeImpl.hpp diff --git a/examples/PhasorDynamics/Tiny/TwoBus/Basic/CMakeLists.txt b/examples/PhasorDynamics/Tiny/TwoBus/Basic/CMakeLists.txt index de388d37a..f215968d2 100644 --- a/examples/PhasorDynamics/Tiny/TwoBus/Basic/CMakeLists.txt +++ b/examples/PhasorDynamics/Tiny/TwoBus/Basic/CMakeLists.txt @@ -4,4 +4,4 @@ target_link_libraries(TwoBusBasic GRIDKIT::solvers_dyn) install(TARGETS TwoBusBasic RUNTIME DESTINATION bin) -add_test(NAME GenrouTest1 COMMAND $) +add_test(NAME TwoBusBasicTest COMMAND $) diff --git a/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/CMakeLists.txt b/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/CMakeLists.txt index e8fb96285..74a873976 100644 --- a/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/CMakeLists.txt +++ b/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/CMakeLists.txt @@ -5,3 +5,12 @@ target_link_libraries(TwoBusTgov1 install(TARGETS TwoBusTgov1 RUNTIME DESTINATION bin) add_test(NAME GenrouTest1_tgov1 COMMAND $) + +add_executable(TwoBusTgov1Signal TwoBusTgov1Signal.cpp) +target_link_libraries(TwoBusTgov1Signal + GRIDKIT::phasor_dynamics_components + GRIDKIT::phasor_dynamics_signal + GRIDKIT::solvers_dyn) +install(TARGETS TwoBusTgov1Signal RUNTIME DESTINATION bin) + +add_test(NAME TwoBusTgov1SignalTest COMMAND $) diff --git a/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1Signal.cpp b/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1Signal.cpp new file mode 100644 index 000000000..baeeef72a --- /dev/null +++ b/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1Signal.cpp @@ -0,0 +1,285 @@ +/** + * @file TwoBusTgov1Signal.cpp + * @author Adam Birchfield (abirchfield@tamu.edu) + * @author Slaven Peles (peless@ornl.gov) + * @brief Example running a 2-bus system + * + * Simulates a 2-bus system with Genrou 6th order generator model and + * compares results with data generated for the same system by Poweworld. + * + */ +#include +#include + +#include "TwoBusTgov1.hpp" +#include +#include +#include +#include +#include + +int main() +{ + using namespace GridKit::PhasorDynamics; + using namespace AnalysisManager::Sundials; + + using scalar_type = double; + using real_type = double; + using index_type = size_t; + + using BusType = BusData::BusType; + + std::cout << "Example: TwoBusTgov1 \n"; + + // + // Create model data + // + + SystemModelData data; + + // Set bus data + data.bus.resize(2); + + data.bus[0].bus_id = 0; + data.bus[0].bus_type = BusType::DEFAULT; + data.bus[0].Vr0 = 0.9949877346411762; + data.bus[0].Vi0 = 0.09999703952427966; + + data.bus[1].bus_id = 1; + data.bus[1].bus_type = BusType::SLACK; + data.bus[1].Vr0 = 1.0; + data.bus[1].Vi0 = 0.0; + + // Set signal nodes data + data.signal.resize(2); + + data.signal[0].name = "omega"; + data.signal[0].signal_id = 0; + + data.signal[1].name = "Pm"; + data.signal[1].signal_id = 1; + + // Set branch data + data.branch.resize(1); + + data.branch[0].ports[BranchPorts::bus1] = data.bus[0].bus_id; + data.branch[0].ports[BranchPorts::bus2] = data.bus[1].bus_id; + data.branch[0].parameters[BranchParameters::R] = 0.0; + data.branch[0].parameters[BranchParameters::X] = 0.1; + data.branch[0].parameters[BranchParameters::G] = 0.0; + data.branch[0].parameters[BranchParameters::B] = 0.0; + + // Add faults + data.bus_fault.resize(1); + + data.bus_fault[0].parameters[BusFaultParameters::R] = 0.0; + data.bus_fault[0].parameters[BusFaultParameters::X] = 1e-3; + data.bus_fault[0].parameters[BusFaultParameters::state0] = false; + + // Set generator data + data.genrou.resize(1); + + data.genrou[0].parameters[GenrouParameters::p0] = 1.; + data.genrou[0].parameters[GenrouParameters::q0] = 0.05013; + data.genrou[0].parameters[GenrouParameters::H] = 3.; + data.genrou[0].parameters[GenrouParameters::D] = 0.; + data.genrou[0].parameters[GenrouParameters::Ra] = 0.; + data.genrou[0].parameters[GenrouParameters::Tdop] = 7.; + data.genrou[0].parameters[GenrouParameters::Tdopp] = .04; + data.genrou[0].parameters[GenrouParameters::Tqopp] = .05; + data.genrou[0].parameters[GenrouParameters::Tqop] = .75; + data.genrou[0].parameters[GenrouParameters::Xd] = 2.1; + data.genrou[0].parameters[GenrouParameters::Xdp] = 0.2; + data.genrou[0].parameters[GenrouParameters::Xdpp] = 0.18; + data.genrou[0].parameters[GenrouParameters::Xq] = 0.5; + data.genrou[0].parameters[GenrouParameters::Xqp] = 0.5; + data.genrou[0].parameters[GenrouParameters::Xqpp] = 0.18; + data.genrou[0].parameters[GenrouParameters::Xl] = 0.15; + data.genrou[0].parameters[GenrouParameters::S10] = 0.; + data.genrou[0].parameters[GenrouParameters::S12] = 0.; + + // Set governor data (Default PW values) + data.gov.resize(1); + + data.gov[0].R = 0.05; + data.gov[0].Pvmin = 0; + data.gov[0].Pvmax = 1.0; + data.gov[0].T1 = 0.5; + data.gov[0].T2 = 2.5; + data.gov[0].T3 = 7.5; + data.gov[0].Dt = 0; + + // Manually add components + // This is a workaround since signal connections are not implemented in parser + + // Create buses + auto* bus0 = BusFactory::create(data.bus[0]); + auto* bus1 = BusFactory::create(data.bus[1]); + + // Create signal nodes + auto* omega = new SignalNode(data.signal[0]); + auto* pmech = new SignalNode(data.signal[1]); + + // Create branch + Branch branch(bus0, bus1, data.branch[0]); + + // Add bus fault to bus0 + BusFault fault(bus0, data.bus_fault[0]); + + // Create generator + Genrou gen(bus0, + omega, + pmech, + data.genrou[0]); + + // Create governor + Governor::Tgov1 gov(pmech, omega); + + // + // Instantiate system model and add components to it + // + + SystemModel sys; + sys.addBus(bus0); + sys.addBus(bus1); + sys.addSignal(omega); + sys.addSignal(pmech); + sys.addComponent(&branch); + sys.addComponent(&gen); + sys.addComponent(&gov); + sys.addFault(&fault); + + sys.allocate(); + + // Get access to the fault + // auto* fault = sys.getBusFault(0); + + // Set time step to 1/4 of a 60Hz cycle + real_type dt = 1.0 / 4.0 / 60.0; + + // A data structure to keep track of the data we want to + // compare to the reference solution. Rather than keeping + // the entire solution vector at every time step around, + // we instead narrow down exactly what we want to keep. + // + // Since this struct is "simple" enough (no constructors or + // assignment operators, and "simple" members), it is a POD + // (plain ol' data), which have some benefits in C++. + struct OutputData + { + // Output variables are time, real and imaginary voltage and + // frequency deviation + real_type ti, Vr, Vi, dw; + }; + + // A list of output for each time step. + std::vector output; + + // A callback which will be called by the integrator after + // each time step. It will be told the time of the current + // state, and it is allowed to access the up-to-date state + // of the components, which are captured by a closure + // due to the [&] notation (every variable that is referenced + // by the callback that is external to the callback itself - + // here output, bus1, and gen - will be considered a + // reference to that variable inside the callback). We select + // the subset of the output we're interested in recording and + // push it into output, which is updated outside the callback. + auto output_cb = [&](real_type t) + { + std::vector& y_val = sys.y(); + + output.push_back(OutputData{t, y_val[0], y_val[1], y_val[3]}); + }; + + // Set up simulation + Ida ida(&sys); + ida.configureSimulation(); + + // Run simulation - making sure to pass the callback to record output + real_type start = static_cast(clock()); + + // Run for 1s + ida.initializeSimulation(0.0, false); + int nout = static_cast(std::round((1.0 - 0.0) / dt)); + ida.runSimulation(1.0, nout, output_cb); + + // Introduce fault and run for the next 0.1s + fault.setStatus(true); + ida.initializeSimulation(1.0, false); + nout = static_cast(std::round((1.1 - 1.0) / dt)); + ida.runSimulation(1.1, nout, output_cb); + + // Clear the fault and run until t = 10s. + fault.setStatus(false); + ida.initializeSimulation(1.1, false); + nout = static_cast(std::round((10.0 - 1.1) / dt)); + ida.runSimulation(10.0, nout, output_cb); + real_type stop = static_cast(clock()); + + real_type error_V = 0.0; // error in |V| + real_type error_w = 0.0; // error in rotor speed + + // Read through the simulation data stored in the buffer. + // Since we captured by reference, output should be available + // for us to read here, outside the callback. + for (size_t i = 0; i < output.size(); i++) + { + OutputData data = output[i]; + std::vector& ref_sol = reference_solution[i + 1]; + + // Review Note: I believe the denominator should not have +1 + real_type err = + std::abs(std::sqrt(data.Vr * data.Vr + data.Vi * data.Vi) - ref_sol[2]) + / (1.0 + std::abs(ref_sol[2])); + if (err > error_V) + error_V = err; + + // Review Note: I believe the denominator should not have +1 + err = std::abs(1.0 + data.dw - ref_sol[1]) / (1.0 + ref_sol[1]); + if (err > error_w) + error_w = err; + + // // Optional output + // std::cout << "GridKit: t = " << data.ti + // << ", |V| = " << std::sqrt(data.Vr * data.Vr + data.Vi * data.Vi) + // << ", w = " << (1.0 + data.dw) << "\n"; + // std::cout << "Ref : t = " << ref_sol[0] + // << ", |V| = " << ref_sol[2] + // << ", w = " << ref_sol[1] + // << "\n"; + // std::cout << "Error in |V| = " + // << err + // << "\n"; + // std::cout << "\n"; + } + + // Errors allowed for agreement with Powerworld results + real_type error_V_allowed = 2e-4; + real_type error_w_allowed = 1e-4; + + // Tolerances based on Powerworld reference accuracy + int status = 0; + std::cout << "Max error in |V| = " << error_V << "\n"; + if (error_V > error_V_allowed) + { + std::cout << "Test failed with error too large!\n"; + status = 1; + } + std::cout << "Max error in w = " << error_w << "\n"; + if (error_w > error_w_allowed) + { + std::cout << "Test failed with error too large!\n"; + status = 1; + } + + std::cout << "\n\nComplete in " << (stop - start) / CLOCKS_PER_SEC << " seconds\n"; + + // Delete connectors created on heap + delete bus0; + delete bus1; + delete omega; + delete pmech; + + return status; +} diff --git a/src/Model/PhasorDynamics/BusBase.hpp b/src/Model/PhasorDynamics/BusBase.hpp index 0f2ca0945..ae9d81450 100644 --- a/src/Model/PhasorDynamics/BusBase.hpp +++ b/src/Model/PhasorDynamics/BusBase.hpp @@ -121,6 +121,11 @@ namespace GridKit return J_; } + virtual const IdxT busID() const + { + return bus_id_; + } + protected: const IdxT bus_id_{static_cast(-1)}; @@ -303,10 +308,6 @@ namespace GridKit return gB_; } - virtual const IdxT busID() const - { - return bus_id_; - } }; } // namespace PhasorDynamics diff --git a/src/Model/PhasorDynamics/CMakeLists.txt b/src/Model/PhasorDynamics/CMakeLists.txt index a54397d4a..7ad3e7ec9 100644 --- a/src/Model/PhasorDynamics/CMakeLists.txt +++ b/src/Model/PhasorDynamics/CMakeLists.txt @@ -12,4 +12,6 @@ add_subdirectory(Governor) add_subdirectory(Load) add_subdirectory(SynchronousMachine) +add_subdirectory(SignalNode) + add_library(GRIDKIT::phasor_dynamics_components ALIAS gridkit_phasor_dynamics_components) diff --git a/src/Model/PhasorDynamics/ComponentLibrary.hpp b/src/Model/PhasorDynamics/ComponentLibrary.hpp index 9aba244f7..417bdae4c 100644 --- a/src/Model/PhasorDynamics/ComponentLibrary.hpp +++ b/src/Model/PhasorDynamics/ComponentLibrary.hpp @@ -5,5 +5,6 @@ #include #include #include +#include #include #include diff --git a/src/Model/PhasorDynamics/Governor/Tgov1/CMakeLists.txt b/src/Model/PhasorDynamics/Governor/Tgov1/CMakeLists.txt index 36d5cf26e..164b89b07 100644 --- a/src/Model/PhasorDynamics/Governor/Tgov1/CMakeLists.txt +++ b/src/Model/PhasorDynamics/Governor/Tgov1/CMakeLists.txt @@ -9,6 +9,7 @@ gridkit_add_library(phasor_dynamics_governortgov1 Tgov1.cpp LINK_LIBRARIES GRIDKIT::phasor_dynamics_genrou + GRIDKIT::phasor_dynamics_signal OUTPUT_NAME gridkit_phasor_dynamics_governortgov1) diff --git a/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.cpp b/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.cpp index af140c130..41d7216a6 100644 --- a/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.cpp +++ b/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #define _USE_MATH_DEFINES @@ -45,6 +46,26 @@ namespace GridKit size_ = 3; } + /** + * + */ + template + Tgov1::Tgov1(signal_type* pmech, signal_type* omega, const model_data_type& data) + : pmech_(pmech), + omega_(omega), + R_(data.R), + Pvmin_(data.Pvmin), + Pvmax_(data.Pvmax), + T1_(data.T1), + T2_(data.T2), + T3_(data.T3), + Dt_(data.Dt) + { + + // 3 Internal Variables + size_ = 3; + } + template Tgov1::Tgov1(machine_type* machine) : machine_(machine), @@ -61,6 +82,23 @@ namespace GridKit size_ = 3; } + template + Tgov1::Tgov1(signal_type* pmech, signal_type* omega) + : pmech_(pmech), + omega_(omega), + R_(0.05), + Pvmin_(0), + Pvmax_(1), + T1_(0.5), + T2_(2.5), + T3_(7.5), + Dt_(0) + { + + // 3 Internal Variables + size_ = 3; + } + /*! * @brief Allocate memory for model * @@ -68,11 +106,19 @@ namespace GridKit template int Tgov1::allocate() { + // Allocate local component data auto size = static_cast(size_); // avoid compiler warnings f_.resize(size); y_.resize(size); yp_.resize(size); tag_.resize(size); + + // Set output signal after allocation + // The signal is accessible to the generator + if (pmech_) + { + pmech_->set(&y_[2]); + } return 0; } @@ -83,9 +129,17 @@ namespace GridKit template int Tgov1::initialize() { + ScalarT p0{0}; // Initial mechanical = initial electric torque - ScalarT p0 = machine_->getTorque(); + if (machine_) + { + p0 = machine_->getTorque(); + } + else if (pmech_) + { + p0 = y_[2]; //<- generator needs to be initialized first + } // Input Variables (Parameter for now) pref_ = R_ * p0; @@ -166,10 +220,16 @@ namespace GridKit template int Tgov1::evaluateResidual() { - // Input Variables - ScalarT omega = machine_->getSpeed(); - + ScalarT omega{0}; + if (machine_) + { + omega = machine_->getSpeed(); + } + else if (omega_) + { + omega = omega_->read(); + } // Read Internal Variables ScalarT ptx = y_[0]; // y0 - Ptx ScalarT pv = y_[1]; // y1 - Pv diff --git a/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp b/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp index 2383775ba..40c3cc6f1 100644 --- a/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp +++ b/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp @@ -25,6 +25,9 @@ namespace GridKit template class Genrou; + template + class SignalNode; + } // namespace PhasorDynamics } // namespace GridKit @@ -50,9 +53,12 @@ namespace GridKit using machine_type = Genrou; using real_type = typename Component::real_type; using model_data_type = Tgov1Data; + using signal_type = SignalNode; public: Tgov1(machine_type* machine, const model_data_type& data); + Tgov1(signal_type* pmech, signal_type* omega, const model_data_type& data); + Tgov1(signal_type* pmech, signal_type* omega); Tgov1(machine_type* machine); ~Tgov1() = default; @@ -73,7 +79,9 @@ namespace GridKit private: // Associated Machine Model - machine_type* machine_; + machine_type* machine_{nullptr}; + signal_type* pmech_{nullptr}; + signal_type* omega_{nullptr}; // Input parameters real_type R_; diff --git a/src/Model/PhasorDynamics/SignalNode/CMakeLists.txt b/src/Model/PhasorDynamics/SignalNode/CMakeLists.txt new file mode 100644 index 000000000..4bb43f79a --- /dev/null +++ b/src/Model/PhasorDynamics/SignalNode/CMakeLists.txt @@ -0,0 +1,21 @@ + +# [[ +# Author(s): +# - Cameron Rutherford +# - Slaven Peles +# ]] + +gridkit_add_library(phasor_dynamics_signal + SOURCES + SignalNode.cpp + OUTPUT_NAME + gridkit_phasor_dynamics_signal) + +# Link to interface target for all components +target_link_libraries(gridkit_phasor_dynamics_components INTERFACE GRIDKIT::phasor_dynamics_signal) + +gridkit_add_library(phasor_dynamics_signal_dependency_tracking + SOURCES + SignalNodeDependencyTracking.cpp + OUTPUT_NAME + gridkit_phasor_dynamics_signal_dependency_tracking) diff --git a/src/Model/PhasorDynamics/SignalNode/SignalNode.cpp b/src/Model/PhasorDynamics/SignalNode/SignalNode.cpp new file mode 100644 index 000000000..d510b6f20 --- /dev/null +++ b/src/Model/PhasorDynamics/SignalNode/SignalNode.cpp @@ -0,0 +1,15 @@ +/** + * @file SignalNode model implementation. + */ +#include "SignalNodeImpl.hpp" + + +namespace GridKit +{ + namespace PhasorDynamics + { + template class SignalNode; + template class SignalNode; + + } // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/SignalNode/SignalNode.hpp b/src/Model/PhasorDynamics/SignalNode/SignalNode.hpp new file mode 100644 index 000000000..e687f2274 --- /dev/null +++ b/src/Model/PhasorDynamics/SignalNode/SignalNode.hpp @@ -0,0 +1,315 @@ +#pragma once + +#include + +#include +#include + +namespace GridKit +{ + namespace PhasorDynamics + { + template + struct SignalNodeData; + } // namespace PhasorDynamics +} // namespace GridKit + +namespace GridKit +{ + namespace PhasorDynamics + { + /*! + * @brief SignalNode model implementation base class. + * + */ + template + class SignalNode : public Model::Evaluator + { + public: + using real_type = typename Model::Evaluator::real_type; + + SignalNode(); + SignalNode(const SignalNodeData& data); + + virtual ~SignalNode() = default; + + virtual int allocate() override; + virtual int initialize() override; + virtual int tagDifferentiable() override; + virtual int evaluateResidual() override; + virtual int evaluateJacobian() override; + + void set(ScalarT* signal_in); + ScalarT read() const; + void init(ScalarT signal_in); + + const IdxT signalId() const + { + return signal_id_; + } + + virtual IdxT size() override + { + return size_; + } + + virtual IdxT nnz() override + { + return nnz_; + } + + virtual bool hasJacobian() override + { + return false; + } + + virtual void updateTime(real_type /* t */, real_type /* a */) override + { + // No time to update in bus models + } + + virtual void setTolerances(real_type& rtol, real_type& atol) const override + { + rtol = rtol_; + atol = atol_; + } + + virtual void setMaxSteps(IdxT& msa) const override + { + 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_; + } + + GridKit::LinearAlgebra::COO_Matrix& getJacobian() override + { + return J_; + } + + const GridKit::LinearAlgebra::COO_Matrix& getJacobian() const override + { + return J_; + } + + private: + ScalarT* signal_{nullptr}; + IdxT signal_id_{0}; + + protected: + const IdxT bus_id_{static_cast(-1)}; + + IdxT size_{0}; + IdxT nnz_{0}; + + std::vector y_; + std::vector yp_; + std::vector tag_; + std::vector f_; + + GridKit::LinearAlgebra::COO_Matrix J_; + + real_type time_; + real_type alpha_; + + real_type rtol_; + real_type atol_; + + IdxT max_steps_; + + // + // Adjoint sensitivity members + // + + std::vector g_{}; + std::vector yB_{}; + std::vector ypB_{}; + std::vector fB_{}; + std::vector gB_{}; + + std::vector param_{}; + std::vector param_up_{}; + std::vector param_lo_{}; + + // + // Public adjoint sensitivity methods (not yet implemented in components) + // + + public: + virtual IdxT sizeQuadrature() override + { + throw "ERROR: Method not implemented!\n"; + return 0; + } + + virtual IdxT sizeParams() override + { + throw "ERROR: Method not implemented!\n"; + return 0; + } + + std::vector& yB() override + { + throw "ERROR: Method not implemented!\n"; + return yB_; + } + + const std::vector& yB() const override + { + throw "ERROR: Method not implemented!\n"; + return yB_; + } + + std::vector& ypB() override + { + throw "ERROR: Method not implemented!\n"; + return ypB_; + } + + const std::vector& ypB() const override + { + throw "ERROR: Method not implemented!\n"; + return ypB_; + } + + std::vector& param() override + { + throw "ERROR: Method not implemented!\n"; + return param_; + } + + const std::vector& param() const override + { + throw "ERROR: Method not implemented!\n"; + return param_; + } + + std::vector& param_up() override + { + throw "ERROR: Method not implemented!\n"; + return param_up_; + } + + const std::vector& param_up() const override + { + throw "ERROR: Method not implemented!\n"; + return param_up_; + } + + std::vector& param_lo() override + { + throw "ERROR: Method not implemented!\n"; + return param_lo_; + } + + const std::vector& param_lo() const override + { + throw "ERROR: Method not implemented!\n"; + return param_lo_; + } + + int evaluateIntegrand() override + { + throw "ERROR: Method not implemented!\n"; + return 1; + } + + int initializeAdjoint() override + { + throw "ERROR: Method not implemented!\n"; + return 1; + } + + int evaluateAdjointResidual() override + { + throw "ERROR: Method not implemented!\n"; + return 1; + } + + int evaluateAdjointIntegrand() override + { + throw "ERROR: Method not implemented!\n"; + return 1; + } + + std::vector& getResidual() override + { + return f_; + } + + const std::vector& getResidual() const override + { + return f_; + } + + std::vector& getIntegrand() override + { + throw "ERROR: Method not implemented!\n"; + return g_; + } + + const std::vector& getIntegrand() const override + { + throw "ERROR: Method not implemented!\n"; + return g_; + } + + std::vector& getAdjointResidual() override + { + throw "ERROR: Method not implemented!\n"; + return fB_; + } + + const std::vector& getAdjointResidual() const override + { + throw "ERROR: Method not implemented!\n"; + return fB_; + } + + std::vector& getAdjointIntegrand() override + { + throw "ERROR: Method not implemented!\n"; + return gB_; + } + + const std::vector& getAdjointIntegrand() const override + { + throw "ERROR: Method not implemented!\n"; + return gB_; + } + + virtual const IdxT busID() const + { + return bus_id_; + } + }; + + } // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/SignalNode/SignalNodeData.hpp b/src/Model/PhasorDynamics/SignalNode/SignalNodeData.hpp new file mode 100644 index 000000000..3a5854666 --- /dev/null +++ b/src/Model/PhasorDynamics/SignalNode/SignalNodeData.hpp @@ -0,0 +1,35 @@ +/** + * @file SignalNodeData.hpp + * @author Slaven Peles (peless@ornl.gov) + * @brief Modeling data for buses (nodes) + * + */ +#pragma once + +#include +#include +#include +#include + +namespace GridKit +{ + namespace PhasorDynamics + { + /** + * @brief Contains modeling data for a Bus + * + * @tparam RealT Real parameter data type + * @tparam IdxT Integer parameter data type + * + * Integer parameters are of the same type as matrix and vector indices. + * + * @todo Decide on naming scheme for model parameters. + */ + template + struct SignalNodeData + { + std::string name; ///< A name given to this bus + IdxT signal_id{0}; ///< The unique ID of the signal node + }; + } // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/SignalNode/SignalNodeDependencyTracking.cpp b/src/Model/PhasorDynamics/SignalNode/SignalNodeDependencyTracking.cpp new file mode 100644 index 000000000..a85f6d46b --- /dev/null +++ b/src/Model/PhasorDynamics/SignalNode/SignalNodeDependencyTracking.cpp @@ -0,0 +1,15 @@ +/** + * @file SignalNode model implementation. + */ +#include "SignalNodeImpl.hpp" + + +namespace GridKit +{ + namespace PhasorDynamics + { + template class SignalNode; + template class SignalNode; + + } // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/SignalNode/SignalNodeImpl.hpp b/src/Model/PhasorDynamics/SignalNode/SignalNodeImpl.hpp new file mode 100644 index 000000000..750036ec1 --- /dev/null +++ b/src/Model/PhasorDynamics/SignalNode/SignalNodeImpl.hpp @@ -0,0 +1,73 @@ +/** + * @file SignalNode model implementation. + */ +#include "SignalNode.hpp" + +#include + +namespace GridKit +{ + namespace PhasorDynamics + { + template + SignalNode::SignalNode() + : size_(0) + { + } + + template + SignalNode::SignalNode(const SignalNodeData& data) + : size_(0), + signal_id_(data.signal_id) + { + } + + template + int SignalNode::allocate() + { + return 0; + } + + template + int SignalNode::initialize() + { + return 0; + } + + template + int SignalNode::tagDifferentiable() + { + return 0; + } + + template + int SignalNode::evaluateResidual() + { + return 0; + } + + template + int SignalNode::evaluateJacobian() + { + return 0; + } + + template + void SignalNode::set(ScalarT* signal) + { + signal_ = signal; + } + + template + ScalarT SignalNode::read() const + { + return *signal_; + } + + template + void SignalNode::init(ScalarT signal) + { + *signal_ = signal; + } + } // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/CMakeLists.txt b/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/CMakeLists.txt index 215d7562e..9170a327b 100644 --- a/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/CMakeLists.txt +++ b/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/CMakeLists.txt @@ -1,12 +1,16 @@ gridkit_add_library(phasor_dynamics_genrou SOURCES Genrou.cpp + LINK_LIBRARIES + PUBLIC GRIDKIT::phasor_dynamics_signal OUTPUT_NAME gridkit_phasor_dynamics_genrou) gridkit_add_library(phasor_dynamics_genrou_dependency_tracking SOURCES GenrouDependencyTracking.cpp + LINK_LIBRARIES + PUBLIC GRIDKIT::phasor_dynamics_signal_dependency_tracking OUTPUT_NAME gridkit_phasor_dynamics_genrou_dependency_tracking) diff --git a/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp b/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp index ed77d0864..9c9eb387f 100644 --- a/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp +++ b/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp @@ -18,6 +18,9 @@ namespace GridKit template class BusBase; + template + class SignalNode; + template class GovernorBase; // <- TODO: Temporary, to be removed. @@ -47,9 +50,11 @@ namespace GridKit using gov_type = GovernorBase; using bus_type = BusBase; using model_data_type = GenrouData; + using signal_type = SignalNode; public: Genrou(bus_type* bus, IdxT unit_id); + Genrou(bus_type* bus, signal_type* omega, signal_type* pmech, const model_data_type& data); Genrou(bus_type* bus, const model_data_type& data); Genrou(bus_type* bus, IdxT unit_id, @@ -118,9 +123,11 @@ namespace GridKit private: /* Identification */ - bus_type* bus_; - IdxT busID_{0}; - IdxT unit_id_; //< @todo this should be removed + bus_type* bus_; + signal_type* pmech_{nullptr}; + signal_type* omega_{nullptr}; + IdxT bus_id_{0}; + IdxT unit_id_; //< @todo this should be removed // Governor Pointer gov_type* gov_; diff --git a/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/GenrouImpl.hpp b/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/GenrouImpl.hpp index ad6a9ea7d..582732290 100644 --- a/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/GenrouImpl.hpp +++ b/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/GenrouImpl.hpp @@ -7,6 +7,7 @@ #include "Genrou.hpp" #include #include // <- TODO: Temporary, to be removed. +#include #include namespace GridKit @@ -25,7 +26,7 @@ namespace GridKit template Genrou::Genrou(bus_type* bus, IdxT unit_id) : bus_(bus), - busID_(0), + bus_id_(0), unit_id_(unit_id), gov_(nullptr), // <- TODO: Temporary, to be removed. p0_(0.), @@ -76,7 +77,7 @@ namespace GridKit real_type S10, real_type S12) : bus_(bus), - busID_(0), + bus_id_(0), unit_id_(unit_id), gov_(nullptr), // <- TODO: Temporary, to be removed. p0_(p0), @@ -203,7 +204,117 @@ namespace GridKit if (data.ports.contains(model_data_type::Ports::bus)) { - busID_ = data.ports.at(model_data_type::Ports::bus); + bus_id_ = data.ports.at(model_data_type::Ports::bus); + } + + size_ = 20; + setDerivedParams(); + } + + /** + * @brief Constructor for a GENROU generator model with saturation + */ + template + Genrou::Genrou(bus_type* bus, signal_type* omega, signal_type* pmech, const model_data_type& data) + : bus_(bus), + pmech_(pmech), + omega_(omega), + unit_id_(1), + gov_(nullptr) // <- TODO: Temporary, to be removed. + { + if (data.parameters.contains(model_data_type::Parameters::p0)) + { + p0_ = std::get(data.parameters.at(model_data_type::Parameters::p0)); + } + + if (data.parameters.contains(model_data_type::Parameters::q0)) + { + q0_ = std::get(data.parameters.at(model_data_type::Parameters::q0)); + } + + if (data.parameters.contains(model_data_type::Parameters::H)) + { + H_ = std::get(data.parameters.at(model_data_type::Parameters::H)); + } + + if (data.parameters.contains(model_data_type::Parameters::D)) + { + D_ = std::get(data.parameters.at(model_data_type::Parameters::D)); + } + + if (data.parameters.contains(model_data_type::Parameters::Ra)) + { + Ra_ = std::get(data.parameters.at(model_data_type::Parameters::Ra)); + } + + if (data.parameters.contains(model_data_type::Parameters::Tdop)) + { + Tdop_ = std::get(data.parameters.at(model_data_type::Parameters::Tdop)); + } + + if (data.parameters.contains(model_data_type::Parameters::Tdopp)) + { + Tdopp_ = std::get(data.parameters.at(model_data_type::Parameters::Tdopp)); + } + + if (data.parameters.contains(model_data_type::Parameters::Tqopp)) + { + Tqopp_ = std::get(data.parameters.at(model_data_type::Parameters::Tqopp)); + } + + if (data.parameters.contains(model_data_type::Parameters::Tqop)) + { + Tqop_ = std::get(data.parameters.at(model_data_type::Parameters::Tqop)); + } + + if (data.parameters.contains(model_data_type::Parameters::Xd)) + { + Xd_ = std::get(data.parameters.at(model_data_type::Parameters::Xd)); + } + + if (data.parameters.contains(model_data_type::Parameters::Xdp)) + { + Xdp_ = std::get(data.parameters.at(model_data_type::Parameters::Xdp)); + } + + if (data.parameters.contains(model_data_type::Parameters::Xdpp)) + { + Xdpp_ = std::get(data.parameters.at(model_data_type::Parameters::Xdpp)); + } + + if (data.parameters.contains(model_data_type::Parameters::Xq)) + { + Xq_ = std::get(data.parameters.at(model_data_type::Parameters::Xq)); + } + + if (data.parameters.contains(model_data_type::Parameters::Xqp)) + { + Xqp_ = std::get(data.parameters.at(model_data_type::Parameters::Xqp)); + } + + if (data.parameters.contains(model_data_type::Parameters::Xqpp)) + { + Xqpp_ = std::get(data.parameters.at(model_data_type::Parameters::Xqpp)); + } + + if (data.parameters.contains(model_data_type::Parameters::Xl)) + { + Xl_ = std::get(data.parameters.at(model_data_type::Parameters::Xl)); + } + + if (data.parameters.contains(model_data_type::Parameters::S10)) + { + S10_ = std::get(data.parameters.at(model_data_type::Parameters::S10)); + } + + if (data.parameters.contains(model_data_type::Parameters::S12)) + { + S12_ = std::get(data.parameters.at(model_data_type::Parameters::S12)); + } + + if (data.ports.contains(model_data_type::Ports::bus)) + { + bus_id_ = data.ports.at(model_data_type::Ports::bus); } size_ = 20; @@ -232,6 +343,12 @@ namespace GridKit y_.resize(static_cast(size_)); yp_.resize(static_cast(size_)); tag_.resize(static_cast(size_)); + + if (omega_) + { + omega_->set(&y_[1]); + } + return 0; } @@ -298,6 +415,10 @@ namespace GridKit // Set Setpoint mechanical power, which may or may not be used pmech_set_ = Te; + if (pmech_) + { + pmech_->init(Te); + } for (IdxT i = 0; i < size_; ++i) yp_[static_cast(i)] = 0.0; @@ -354,6 +475,10 @@ namespace GridKit { pmech = gov_->Pmech(); } + else if (pmech_) + { + pmech = pmech_->read(); + } else { pmech = pmech_set_; diff --git a/src/Model/PhasorDynamics/SystemModel.hpp b/src/Model/PhasorDynamics/SystemModel.hpp index dbb256a2c..3d8ec7502 100644 --- a/src/Model/PhasorDynamics/SystemModel.hpp +++ b/src/Model/PhasorDynamics/SystemModel.hpp @@ -4,18 +4,14 @@ #include #include +#include #include #include #include #include -// Temporary -#include -#include -#include -#include -#include -#include +// Include all components +#include namespace GridKit { @@ -36,6 +32,7 @@ namespace GridKit class SystemModel : public PhasorDynamics::Component { using bus_type = PhasorDynamics::BusBase; + using signal_type = PhasorDynamics::SignalNode; using component_type = PhasorDynamics::Component; using real_type = typename Model::Evaluator::real_type; @@ -89,6 +86,12 @@ namespace GridKit addBus(bus); } + for (const auto& signaldata : data.signal) + { + SignalNode* signal = new SignalNode(); + addSignal(signal); + } + // Add branches for (const auto& branchdata : data.branch) { @@ -410,6 +413,11 @@ namespace GridKit buses_.push_back(bus); } + void addSignal(signal_type* signal) + { + signals_.push_back(signal); + } + void addComponent(component_type* component) { components_.push_back(component); @@ -428,6 +436,13 @@ namespace GridKit return buses_[busid]; } + signal_type* getSignal(IdxT signalid) + { + // Need to implement mapping of signal IDs to signals in the system model + assert((signals_[signalid])->signalId() == signalid); + return signals_[signalid]; + } + /** * @brief Return pointer to a bus fault model * @@ -444,6 +459,7 @@ namespace GridKit private: std::vector buses_; + std::vector signals_; std::vector components_; std::vector faults_; diff --git a/src/Model/PhasorDynamics/SystemModelData.hpp b/src/Model/PhasorDynamics/SystemModelData.hpp index 4cddedabb..2d8aaa319 100644 --- a/src/Model/PhasorDynamics/SystemModelData.hpp +++ b/src/Model/PhasorDynamics/SystemModelData.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,7 @@ namespace GridKit using GenrouDataT = GenrouData; using GenClassicalDataT = GenClassicalData; using LoadDataT = LoadData; + using SignalDataT = SignalNodeData; /// The version of the grid dynamics case format this system model was /// parsed from @@ -68,9 +70,10 @@ namespace GridKit std::vector branch; ///< Branches within the model std::vector bus_fault; ///< Bus faults within the model std::vector genrou; ///< GENROU instances within the model - std::vector genclassical; ///< GENROU instances within the model + std::vector genclassical; ///< Classical generator instances within the model std::vector load; ///< Loads within the model std::vector gov; ///< Governors within the model + std::vector signal; ///< Signal nodes }; } // namespace PhasorDynamics } // namespace GridKit diff --git a/tests/UnitTests/PhasorDynamics/CMakeLists.txt b/tests/UnitTests/PhasorDynamics/CMakeLists.txt index e1f2b161d..b5542d7b2 100644 --- a/tests/UnitTests/PhasorDynamics/CMakeLists.txt +++ b/tests/UnitTests/PhasorDynamics/CMakeLists.txt @@ -22,8 +22,9 @@ target_link_libraries(test_phasor_genrou GRIDKIT::phasor_dynamics_genrou add_executable(test_phasor_governortgov1 runGovernorTgov1Tests.cpp) target_link_libraries(test_phasor_governortgov1 GRIDKIT::phasor_dynamics_genrou - GRIDKIT::phasor_dynamics_governortgov1 - GRIDKIT::phasor_dynamics_bus) + GRIDKIT::phasor_dynamics_governortgov1 + GRIDKIT::phasor_dynamics_signal + GRIDKIT::phasor_dynamics_bus) add_executable(test_phasor_gen_classical runGenClassicalTests.cpp) target_link_libraries(test_phasor_gen_classical GRIDKIT::phasor_dynamics_gen_classical @@ -33,16 +34,12 @@ target_link_libraries(test_phasor_gen_classical GRIDKIT::phasor_dynamics_gen_cla add_executable(test_phasor_system runSystemTests.cpp) -target_link_libraries(test_phasor_system GRIDKIT::phasor_dynamics_load +target_link_libraries(test_phasor_system GRIDKIT::phasor_dynamics_components GRIDKIT::phasor_dynamics_load_dependency_tracking - GRIDKIT::phasor_dynamics_branch - GRIDKIT::phasor_dynamics_genrou GRIDKIT::phasor_dynamics_genrou_dependency_tracking - GRIDKIT::phasor_dynamics_gen_classical GRIDKIT::phasor_dynamics_gen_classical_dependency_tracking - GRIDKIT::phasor_dynamics_bus_fault - GRIDKIT::phasor_dynamics_bus_fault_dependency_tracking - GRIDKIT::phasor_dynamics_bus) + GRIDKIT::phasor_dynamics_signal_dependency_tracking + GRIDKIT::phasor_dynamics_bus_fault_dependency_tracking) add_test(NAME PhasorDynamicsBusTest COMMAND $) add_test(NAME PhasorDynamicsBranchTest COMMAND $) diff --git a/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp b/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp index 479141082..cc795dfe2 100644 --- a/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp +++ b/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp @@ -2,9 +2,12 @@ #include #include +#include #include #include +#include #include +#include #include #include @@ -111,6 +114,74 @@ namespace GridKit return success.report(__func__); } + TestOutcome residualWithSignalNode() + { + TestStatus success = true; + + using BusType = PhasorDynamics::BusData::BusType; + using GenrouParameters = PhasorDynamics::GenrouData::Parameters; + using GenrouPorts = PhasorDynamics::GenrouData::Ports; + + PhasorDynamics::BusData busdata; + busdata.bus_id = 0; + busdata.bus_type = BusType::DEFAULT; + busdata.Vr0 = 1.0; + busdata.Vi0 = 0.0; + + PhasorDynamics::GenrouData gendata; + gendata.ports[GenrouPorts::bus] = 0; + + gendata.parameters[GenrouParameters::p0] = 1.; + gendata.parameters[GenrouParameters::q0] = 0.05013; + gendata.parameters[GenrouParameters::H] = 3.; + gendata.parameters[GenrouParameters::D] = 0.; + gendata.parameters[GenrouParameters::Ra] = 0.; + gendata.parameters[GenrouParameters::Tdop] = 7.; + gendata.parameters[GenrouParameters::Tdopp] = .04; + gendata.parameters[GenrouParameters::Tqopp] = .05; + gendata.parameters[GenrouParameters::Tqop] = .75; + gendata.parameters[GenrouParameters::Xd] = 2.1; + gendata.parameters[GenrouParameters::Xdp] = 0.2; + gendata.parameters[GenrouParameters::Xdpp] = 0.18; + gendata.parameters[GenrouParameters::Xq] = 0.5; + gendata.parameters[GenrouParameters::Xqp] = 0.5; + gendata.parameters[GenrouParameters::Xqpp] = 0.18; + gendata.parameters[GenrouParameters::Xl] = 0.15; + gendata.parameters[GenrouParameters::S10] = 0.; + gendata.parameters[GenrouParameters::S12] = 0.; + + PhasorDynamics::Bus bus(busdata); + PhasorDynamics::SignalNode pmech; + PhasorDynamics::SignalNode omega; + PhasorDynamics::Genrou gen(&bus, &omega, &pmech, gendata); + // Create governor to be tested + PhasorDynamics::Governor::Tgov1 gov(&pmech, &omega); + + bus.allocate(); + gov.allocate(); + gen.allocate(); + + bus.initialize(); + gen.initialize(); + gov.initialize(); + + bus.evaluateResidual(); + gen.evaluateResidual(); + gov.evaluateResidual(); + + // Require results to be within machine precision + auto tol = 10 * std::numeric_limits::epsilon(); + + const std::vector& f = gov.getResidual(); + for (const auto& f_val : f) + { + if (!isEqual(f_val, 0.0, tol)) + success = false; + } + + return success.report(__func__); + } + TestOutcome accessors() { TestStatus success = true; diff --git a/tests/UnitTests/PhasorDynamics/runGovernorTgov1Tests.cpp b/tests/UnitTests/PhasorDynamics/runGovernorTgov1Tests.cpp index ced215e1d..d8d026d34 100644 --- a/tests/UnitTests/PhasorDynamics/runGovernorTgov1Tests.cpp +++ b/tests/UnitTests/PhasorDynamics/runGovernorTgov1Tests.cpp @@ -9,6 +9,7 @@ int main() result += test.constructor(); result += test.accessors(); result += test.residual(); + result += test.residualWithSignalNode(); return result.summary(); } From 9ee66f15e7fd4af09c68e87736780750ac919405 Mon Sep 17 00:00:00 2001 From: pelesh Date: Fri, 18 Jul 2025 02:33:13 +0000 Subject: [PATCH 2/6] Apply pre-commmit fixes --- src/Model/PhasorDynamics/BusBase.hpp | 1 - src/Model/PhasorDynamics/SignalNode/SignalNode.cpp | 1 - .../PhasorDynamics/SignalNode/SignalNodeDependencyTracking.cpp | 1 - src/Model/PhasorDynamics/SignalNode/SignalNodeImpl.hpp | 1 - 4 files changed, 4 deletions(-) diff --git a/src/Model/PhasorDynamics/BusBase.hpp b/src/Model/PhasorDynamics/BusBase.hpp index ae9d81450..64372f0e0 100644 --- a/src/Model/PhasorDynamics/BusBase.hpp +++ b/src/Model/PhasorDynamics/BusBase.hpp @@ -307,7 +307,6 @@ namespace GridKit throw "ERROR: Method not implemented!\n"; return gB_; } - }; } // namespace PhasorDynamics diff --git a/src/Model/PhasorDynamics/SignalNode/SignalNode.cpp b/src/Model/PhasorDynamics/SignalNode/SignalNode.cpp index d510b6f20..d0310c67d 100644 --- a/src/Model/PhasorDynamics/SignalNode/SignalNode.cpp +++ b/src/Model/PhasorDynamics/SignalNode/SignalNode.cpp @@ -3,7 +3,6 @@ */ #include "SignalNodeImpl.hpp" - namespace GridKit { namespace PhasorDynamics diff --git a/src/Model/PhasorDynamics/SignalNode/SignalNodeDependencyTracking.cpp b/src/Model/PhasorDynamics/SignalNode/SignalNodeDependencyTracking.cpp index a85f6d46b..ea9d83ce8 100644 --- a/src/Model/PhasorDynamics/SignalNode/SignalNodeDependencyTracking.cpp +++ b/src/Model/PhasorDynamics/SignalNode/SignalNodeDependencyTracking.cpp @@ -3,7 +3,6 @@ */ #include "SignalNodeImpl.hpp" - namespace GridKit { namespace PhasorDynamics diff --git a/src/Model/PhasorDynamics/SignalNode/SignalNodeImpl.hpp b/src/Model/PhasorDynamics/SignalNode/SignalNodeImpl.hpp index 750036ec1..b9c92032d 100644 --- a/src/Model/PhasorDynamics/SignalNode/SignalNodeImpl.hpp +++ b/src/Model/PhasorDynamics/SignalNode/SignalNodeImpl.hpp @@ -2,7 +2,6 @@ * @file SignalNode model implementation. */ #include "SignalNode.hpp" - #include namespace GridKit From aa54a127f54b76a9dcf5ba486ab25357b0883f06 Mon Sep 17 00:00:00 2001 From: pelesh Date: Thu, 17 Jul 2025 23:09:55 -0400 Subject: [PATCH 3/6] Fix compiler warnings. --- src/Model/PhasorDynamics/SignalNode/SignalNode.hpp | 2 +- src/Model/PhasorDynamics/SignalNode/SignalNodeImpl.hpp | 6 +++--- src/Model/PhasorDynamics/SystemModel.hpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Model/PhasorDynamics/SignalNode/SignalNode.hpp b/src/Model/PhasorDynamics/SignalNode/SignalNode.hpp index e687f2274..9968dbf44 100644 --- a/src/Model/PhasorDynamics/SignalNode/SignalNode.hpp +++ b/src/Model/PhasorDynamics/SignalNode/SignalNode.hpp @@ -29,7 +29,7 @@ namespace GridKit using real_type = typename Model::Evaluator::real_type; SignalNode(); - SignalNode(const SignalNodeData& data); + SignalNode(const SignalNodeData& data); virtual ~SignalNode() = default; diff --git a/src/Model/PhasorDynamics/SignalNode/SignalNodeImpl.hpp b/src/Model/PhasorDynamics/SignalNode/SignalNodeImpl.hpp index b9c92032d..c815855b9 100644 --- a/src/Model/PhasorDynamics/SignalNode/SignalNodeImpl.hpp +++ b/src/Model/PhasorDynamics/SignalNode/SignalNodeImpl.hpp @@ -15,9 +15,9 @@ namespace GridKit } template - SignalNode::SignalNode(const SignalNodeData& data) - : size_(0), - signal_id_(data.signal_id) + SignalNode::SignalNode(const SignalNodeData& data) + : signal_id_(data.signal_id), + size_(0) { } diff --git a/src/Model/PhasorDynamics/SystemModel.hpp b/src/Model/PhasorDynamics/SystemModel.hpp index 3d8ec7502..27d500297 100644 --- a/src/Model/PhasorDynamics/SystemModel.hpp +++ b/src/Model/PhasorDynamics/SystemModel.hpp @@ -88,7 +88,7 @@ namespace GridKit for (const auto& signaldata : data.signal) { - SignalNode* signal = new SignalNode(); + SignalNode* signal = new SignalNode(signaldata); addSignal(signal); } From b2f49fe98290c390010308b2b1664f89efb3d799 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Fri, 18 Jul 2025 11:03:35 -0400 Subject: [PATCH 4/6] Remove direct governor/generator links --- .../Tiny/TwoBus/Tgov1/CMakeLists.txt | 9 +- .../Tiny/TwoBus/Tgov1/TwoBusTgov1.cpp | 86 ++++-- .../Tiny/TwoBus/Tgov1/TwoBusTgov1Signal.cpp | 285 ------------------ .../PhasorDynamics/Governor/Tgov1/Tgov1.cpp | 18 +- .../PhasorDynamics/Governor/Tgov1/Tgov1.hpp | 2 - .../SynchronousMachine/GENROUwS/Genrou.hpp | 6 - .../GENROUwS/GenrouImpl.hpp | 20 +- 7 files changed, 64 insertions(+), 362 deletions(-) delete mode 100644 examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1Signal.cpp diff --git a/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/CMakeLists.txt b/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/CMakeLists.txt index 74a873976..d8ee5fdbc 100644 --- a/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/CMakeLists.txt +++ b/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/CMakeLists.txt @@ -1,16 +1,9 @@ add_executable(TwoBusTgov1 TwoBusTgov1.cpp) target_link_libraries(TwoBusTgov1 GRIDKIT::phasor_dynamics_components + GRIDKIT::phasor_dynamics_signal GRIDKIT::solvers_dyn) install(TARGETS TwoBusTgov1 RUNTIME DESTINATION bin) add_test(NAME GenrouTest1_tgov1 COMMAND $) -add_executable(TwoBusTgov1Signal TwoBusTgov1Signal.cpp) -target_link_libraries(TwoBusTgov1Signal - GRIDKIT::phasor_dynamics_components - GRIDKIT::phasor_dynamics_signal - GRIDKIT::solvers_dyn) -install(TARGETS TwoBusTgov1Signal RUNTIME DESTINATION bin) - -add_test(NAME TwoBusTgov1SignalTest COMMAND $) diff --git a/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1.cpp b/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1.cpp index 8f84d93a2..baeeef72a 100644 --- a/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1.cpp +++ b/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1.cpp @@ -1,5 +1,5 @@ /** - * @file TwoBusTgov1.cpp + * @file TwoBusTgov1Signal.cpp * @author Adam Birchfield (abirchfield@tamu.edu) * @author Slaven Peles (peless@ornl.gov) * @brief Example running a 2-bus system @@ -8,11 +8,10 @@ * compares results with data generated for the same system by Poweworld. * */ -#include "TwoBusTgov1.hpp" - #include #include +#include "TwoBusTgov1.hpp" #include #include #include @@ -51,6 +50,15 @@ int main() data.bus[1].Vr0 = 1.0; data.bus[1].Vi0 = 0.0; + // Set signal nodes data + data.signal.resize(2); + + data.signal[0].name = "omega"; + data.signal[0].signal_id = 0; + + data.signal[1].name = "Pm"; + data.signal[1].signal_id = 1; + // Set branch data data.branch.resize(1); @@ -68,12 +76,6 @@ int main() data.bus_fault[0].parameters[BusFaultParameters::X] = 1e-3; data.bus_fault[0].parameters[BusFaultParameters::state0] = false; - // - // Instantiate system model - // - - SystemModel sys(data); - // Set generator data data.genrou.resize(1); @@ -96,9 +98,9 @@ int main() data.genrou[0].parameters[GenrouParameters::S10] = 0.; data.genrou[0].parameters[GenrouParameters::S12] = 0.; + // Set governor data (Default PW values) data.gov.resize(1); - // Set Gov data (Default PW values) data.gov[0].R = 0.05; data.gov[0].Pvmin = 0; data.gov[0].Pvmax = 1.0; @@ -107,32 +109,50 @@ int main() data.gov[0].T3 = 7.5; data.gov[0].Dt = 0; - // Manual add gen & gov components - // This is a hack since SignalBus not implemented + // Manually add components + // This is a workaround since signal connections are not implemented in parser + + // Create buses + auto* bus0 = BusFactory::create(data.bus[0]); + auto* bus1 = BusFactory::create(data.bus[1]); + + // Create signal nodes + auto* omega = new SignalNode(data.signal[0]); + auto* pmech = new SignalNode(data.signal[1]); + + // Create branch + Branch branch(bus0, bus1, data.branch[0]); - // Create Pointers first - Genrou* gen; - Governor::Tgov1* gov; + // Add bus fault to bus0 + BusFault fault(bus0, data.bus_fault[0]); - // Instatiate Genrou & add to system model - gen = new Genrou( - sys.getBus(0), - data.genrou[0]); + // Create generator + Genrou gen(bus0, + omega, + pmech, + data.genrou[0]); - // Instatiate GovernorTgov1 & add to system model - gov = new Governor::Tgov1( - gen, - data.gov[0]); - gen->setgovenor(gov); + // Create governor + Governor::Tgov1 gov(pmech, omega); - // Add Generator and Governor to System - sys.addComponent(gen); - sys.addComponent(gov); + // + // Instantiate system model and add components to it + // + + SystemModel sys; + sys.addBus(bus0); + sys.addBus(bus1); + sys.addSignal(omega); + sys.addSignal(pmech); + sys.addComponent(&branch); + sys.addComponent(&gen); + sys.addComponent(&gov); + sys.addFault(&fault); sys.allocate(); // Get access to the fault - auto* fault = sys.getBusFault(0); + // auto* fault = sys.getBusFault(0); // Set time step to 1/4 of a 60Hz cycle real_type dt = 1.0 / 4.0 / 60.0; @@ -185,13 +205,13 @@ int main() ida.runSimulation(1.0, nout, output_cb); // Introduce fault and run for the next 0.1s - fault->setStatus(true); + fault.setStatus(true); ida.initializeSimulation(1.0, false); nout = static_cast(std::round((1.1 - 1.0) / dt)); ida.runSimulation(1.1, nout, output_cb); // Clear the fault and run until t = 10s. - fault->setStatus(false); + fault.setStatus(false); ida.initializeSimulation(1.1, false); nout = static_cast(std::round((10.0 - 1.1) / dt)); ida.runSimulation(10.0, nout, output_cb); @@ -255,5 +275,11 @@ int main() std::cout << "\n\nComplete in " << (stop - start) / CLOCKS_PER_SEC << " seconds\n"; + // Delete connectors created on heap + delete bus0; + delete bus1; + delete omega; + delete pmech; + return status; } diff --git a/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1Signal.cpp b/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1Signal.cpp deleted file mode 100644 index baeeef72a..000000000 --- a/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1Signal.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/** - * @file TwoBusTgov1Signal.cpp - * @author Adam Birchfield (abirchfield@tamu.edu) - * @author Slaven Peles (peless@ornl.gov) - * @brief Example running a 2-bus system - * - * Simulates a 2-bus system with Genrou 6th order generator model and - * compares results with data generated for the same system by Poweworld. - * - */ -#include -#include - -#include "TwoBusTgov1.hpp" -#include -#include -#include -#include -#include - -int main() -{ - using namespace GridKit::PhasorDynamics; - using namespace AnalysisManager::Sundials; - - using scalar_type = double; - using real_type = double; - using index_type = size_t; - - using BusType = BusData::BusType; - - std::cout << "Example: TwoBusTgov1 \n"; - - // - // Create model data - // - - SystemModelData data; - - // Set bus data - data.bus.resize(2); - - data.bus[0].bus_id = 0; - data.bus[0].bus_type = BusType::DEFAULT; - data.bus[0].Vr0 = 0.9949877346411762; - data.bus[0].Vi0 = 0.09999703952427966; - - data.bus[1].bus_id = 1; - data.bus[1].bus_type = BusType::SLACK; - data.bus[1].Vr0 = 1.0; - data.bus[1].Vi0 = 0.0; - - // Set signal nodes data - data.signal.resize(2); - - data.signal[0].name = "omega"; - data.signal[0].signal_id = 0; - - data.signal[1].name = "Pm"; - data.signal[1].signal_id = 1; - - // Set branch data - data.branch.resize(1); - - data.branch[0].ports[BranchPorts::bus1] = data.bus[0].bus_id; - data.branch[0].ports[BranchPorts::bus2] = data.bus[1].bus_id; - data.branch[0].parameters[BranchParameters::R] = 0.0; - data.branch[0].parameters[BranchParameters::X] = 0.1; - data.branch[0].parameters[BranchParameters::G] = 0.0; - data.branch[0].parameters[BranchParameters::B] = 0.0; - - // Add faults - data.bus_fault.resize(1); - - data.bus_fault[0].parameters[BusFaultParameters::R] = 0.0; - data.bus_fault[0].parameters[BusFaultParameters::X] = 1e-3; - data.bus_fault[0].parameters[BusFaultParameters::state0] = false; - - // Set generator data - data.genrou.resize(1); - - data.genrou[0].parameters[GenrouParameters::p0] = 1.; - data.genrou[0].parameters[GenrouParameters::q0] = 0.05013; - data.genrou[0].parameters[GenrouParameters::H] = 3.; - data.genrou[0].parameters[GenrouParameters::D] = 0.; - data.genrou[0].parameters[GenrouParameters::Ra] = 0.; - data.genrou[0].parameters[GenrouParameters::Tdop] = 7.; - data.genrou[0].parameters[GenrouParameters::Tdopp] = .04; - data.genrou[0].parameters[GenrouParameters::Tqopp] = .05; - data.genrou[0].parameters[GenrouParameters::Tqop] = .75; - data.genrou[0].parameters[GenrouParameters::Xd] = 2.1; - data.genrou[0].parameters[GenrouParameters::Xdp] = 0.2; - data.genrou[0].parameters[GenrouParameters::Xdpp] = 0.18; - data.genrou[0].parameters[GenrouParameters::Xq] = 0.5; - data.genrou[0].parameters[GenrouParameters::Xqp] = 0.5; - data.genrou[0].parameters[GenrouParameters::Xqpp] = 0.18; - data.genrou[0].parameters[GenrouParameters::Xl] = 0.15; - data.genrou[0].parameters[GenrouParameters::S10] = 0.; - data.genrou[0].parameters[GenrouParameters::S12] = 0.; - - // Set governor data (Default PW values) - data.gov.resize(1); - - data.gov[0].R = 0.05; - data.gov[0].Pvmin = 0; - data.gov[0].Pvmax = 1.0; - data.gov[0].T1 = 0.5; - data.gov[0].T2 = 2.5; - data.gov[0].T3 = 7.5; - data.gov[0].Dt = 0; - - // Manually add components - // This is a workaround since signal connections are not implemented in parser - - // Create buses - auto* bus0 = BusFactory::create(data.bus[0]); - auto* bus1 = BusFactory::create(data.bus[1]); - - // Create signal nodes - auto* omega = new SignalNode(data.signal[0]); - auto* pmech = new SignalNode(data.signal[1]); - - // Create branch - Branch branch(bus0, bus1, data.branch[0]); - - // Add bus fault to bus0 - BusFault fault(bus0, data.bus_fault[0]); - - // Create generator - Genrou gen(bus0, - omega, - pmech, - data.genrou[0]); - - // Create governor - Governor::Tgov1 gov(pmech, omega); - - // - // Instantiate system model and add components to it - // - - SystemModel sys; - sys.addBus(bus0); - sys.addBus(bus1); - sys.addSignal(omega); - sys.addSignal(pmech); - sys.addComponent(&branch); - sys.addComponent(&gen); - sys.addComponent(&gov); - sys.addFault(&fault); - - sys.allocate(); - - // Get access to the fault - // auto* fault = sys.getBusFault(0); - - // Set time step to 1/4 of a 60Hz cycle - real_type dt = 1.0 / 4.0 / 60.0; - - // A data structure to keep track of the data we want to - // compare to the reference solution. Rather than keeping - // the entire solution vector at every time step around, - // we instead narrow down exactly what we want to keep. - // - // Since this struct is "simple" enough (no constructors or - // assignment operators, and "simple" members), it is a POD - // (plain ol' data), which have some benefits in C++. - struct OutputData - { - // Output variables are time, real and imaginary voltage and - // frequency deviation - real_type ti, Vr, Vi, dw; - }; - - // A list of output for each time step. - std::vector output; - - // A callback which will be called by the integrator after - // each time step. It will be told the time of the current - // state, and it is allowed to access the up-to-date state - // of the components, which are captured by a closure - // due to the [&] notation (every variable that is referenced - // by the callback that is external to the callback itself - - // here output, bus1, and gen - will be considered a - // reference to that variable inside the callback). We select - // the subset of the output we're interested in recording and - // push it into output, which is updated outside the callback. - auto output_cb = [&](real_type t) - { - std::vector& y_val = sys.y(); - - output.push_back(OutputData{t, y_val[0], y_val[1], y_val[3]}); - }; - - // Set up simulation - Ida ida(&sys); - ida.configureSimulation(); - - // Run simulation - making sure to pass the callback to record output - real_type start = static_cast(clock()); - - // Run for 1s - ida.initializeSimulation(0.0, false); - int nout = static_cast(std::round((1.0 - 0.0) / dt)); - ida.runSimulation(1.0, nout, output_cb); - - // Introduce fault and run for the next 0.1s - fault.setStatus(true); - ida.initializeSimulation(1.0, false); - nout = static_cast(std::round((1.1 - 1.0) / dt)); - ida.runSimulation(1.1, nout, output_cb); - - // Clear the fault and run until t = 10s. - fault.setStatus(false); - ida.initializeSimulation(1.1, false); - nout = static_cast(std::round((10.0 - 1.1) / dt)); - ida.runSimulation(10.0, nout, output_cb); - real_type stop = static_cast(clock()); - - real_type error_V = 0.0; // error in |V| - real_type error_w = 0.0; // error in rotor speed - - // Read through the simulation data stored in the buffer. - // Since we captured by reference, output should be available - // for us to read here, outside the callback. - for (size_t i = 0; i < output.size(); i++) - { - OutputData data = output[i]; - std::vector& ref_sol = reference_solution[i + 1]; - - // Review Note: I believe the denominator should not have +1 - real_type err = - std::abs(std::sqrt(data.Vr * data.Vr + data.Vi * data.Vi) - ref_sol[2]) - / (1.0 + std::abs(ref_sol[2])); - if (err > error_V) - error_V = err; - - // Review Note: I believe the denominator should not have +1 - err = std::abs(1.0 + data.dw - ref_sol[1]) / (1.0 + ref_sol[1]); - if (err > error_w) - error_w = err; - - // // Optional output - // std::cout << "GridKit: t = " << data.ti - // << ", |V| = " << std::sqrt(data.Vr * data.Vr + data.Vi * data.Vi) - // << ", w = " << (1.0 + data.dw) << "\n"; - // std::cout << "Ref : t = " << ref_sol[0] - // << ", |V| = " << ref_sol[2] - // << ", w = " << ref_sol[1] - // << "\n"; - // std::cout << "Error in |V| = " - // << err - // << "\n"; - // std::cout << "\n"; - } - - // Errors allowed for agreement with Powerworld results - real_type error_V_allowed = 2e-4; - real_type error_w_allowed = 1e-4; - - // Tolerances based on Powerworld reference accuracy - int status = 0; - std::cout << "Max error in |V| = " << error_V << "\n"; - if (error_V > error_V_allowed) - { - std::cout << "Test failed with error too large!\n"; - status = 1; - } - std::cout << "Max error in w = " << error_w << "\n"; - if (error_w > error_w_allowed) - { - std::cout << "Test failed with error too large!\n"; - status = 1; - } - - std::cout << "\n\nComplete in " << (stop - start) / CLOCKS_PER_SEC << " seconds\n"; - - // Delete connectors created on heap - delete bus0; - delete bus1; - delete omega; - delete pmech; - - return status; -} diff --git a/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.cpp b/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.cpp index 41d7216a6..d32ebcd55 100644 --- a/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.cpp +++ b/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.cpp @@ -32,8 +32,7 @@ namespace GridKit */ template Tgov1::Tgov1(machine_type* machine, const model_data_type& data) - : machine_(machine), - R_(data.R), + : R_(data.R), Pvmin_(data.Pvmin), Pvmax_(data.Pvmax), T1_(data.T1), @@ -68,8 +67,7 @@ namespace GridKit template Tgov1::Tgov1(machine_type* machine) - : machine_(machine), - R_(0.05), + : R_(0.05), Pvmin_(0), Pvmax_(1), T1_(0.5), @@ -132,11 +130,7 @@ namespace GridKit ScalarT p0{0}; // Initial mechanical = initial electric torque - if (machine_) - { - p0 = machine_->getTorque(); - } - else if (pmech_) + if (pmech_) { p0 = y_[2]; //<- generator needs to be initialized first } @@ -222,11 +216,7 @@ namespace GridKit { // Input Variables ScalarT omega{0}; - if (machine_) - { - omega = machine_->getSpeed(); - } - else if (omega_) + if (omega_) { omega = omega_->read(); } diff --git a/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp b/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp index 40c3cc6f1..99803728e 100644 --- a/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp +++ b/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp @@ -78,8 +78,6 @@ namespace GridKit ScalarT& Pmech() override; private: - // Associated Machine Model - machine_type* machine_{nullptr}; signal_type* pmech_{nullptr}; signal_type* omega_{nullptr}; diff --git a/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp b/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp index 9c9eb387f..8f6f527f2 100644 --- a/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp +++ b/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp @@ -95,9 +95,6 @@ namespace GridKit ScalarT getSpeed(); ScalarT getTorque(); - // Temporary set governor function until SignalBus implemented - void setgovenor(gov_type* gov); - private: void setDerivedParams(); @@ -129,9 +126,6 @@ namespace GridKit IdxT bus_id_{0}; IdxT unit_id_; //< @todo this should be removed - // Governor Pointer - gov_type* gov_; - /* Initial terminal conditions */ ScalarT p0_{0.0}; ScalarT q0_{0.0}; diff --git a/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/GenrouImpl.hpp b/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/GenrouImpl.hpp index 582732290..3c710418b 100644 --- a/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/GenrouImpl.hpp +++ b/src/Model/PhasorDynamics/SynchronousMachine/GENROUwS/GenrouImpl.hpp @@ -28,7 +28,6 @@ namespace GridKit : bus_(bus), bus_id_(0), unit_id_(unit_id), - gov_(nullptr), // <- TODO: Temporary, to be removed. p0_(0.), q0_(0.), H_(3.), @@ -79,7 +78,6 @@ namespace GridKit : bus_(bus), bus_id_(0), unit_id_(unit_id), - gov_(nullptr), // <- TODO: Temporary, to be removed. p0_(p0), q0_(q0), H_(H), @@ -109,8 +107,7 @@ namespace GridKit template Genrou::Genrou(bus_type* bus, const model_data_type& data) : bus_(bus), - unit_id_(1), - gov_(nullptr) // <- TODO: Temporary, to be removed. + unit_id_(1) { if (data.parameters.contains(model_data_type::Parameters::p0)) { @@ -219,8 +216,7 @@ namespace GridKit : bus_(bus), pmech_(pmech), omega_(omega), - unit_id_(1), - gov_(nullptr) // <- TODO: Temporary, to be removed. + unit_id_(1) { if (data.parameters.contains(model_data_type::Parameters::p0)) { @@ -471,11 +467,7 @@ namespace GridKit ScalarT vr = Vr(); ScalarT vi = Vi(); ScalarT pmech; - if (gov_) - { - pmech = gov_->Pmech(); - } - else if (pmech_) + if (pmech_) { pmech = pmech_->read(); } @@ -561,12 +553,6 @@ namespace GridKit return y_[12]; } - template - void Genrou::setgovenor(gov_type* gov) - { - gov_ = gov; - } - template void Genrou::setDerivedParams() { From aa3423f55dcc297ce91ca588f5f1325185245449 Mon Sep 17 00:00:00 2001 From: pelesh Date: Fri, 18 Jul 2025 15:04:05 +0000 Subject: [PATCH 5/6] Apply pre-commmit fixes --- examples/PhasorDynamics/Tiny/TwoBus/Tgov1/CMakeLists.txt | 1 - examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1.cpp | 3 ++- src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/CMakeLists.txt b/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/CMakeLists.txt index d8ee5fdbc..2a49ab28f 100644 --- a/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/CMakeLists.txt +++ b/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/CMakeLists.txt @@ -6,4 +6,3 @@ target_link_libraries(TwoBusTgov1 install(TARGETS TwoBusTgov1 RUNTIME DESTINATION bin) add_test(NAME GenrouTest1_tgov1 COMMAND $) - diff --git a/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1.cpp b/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1.cpp index baeeef72a..8f8223d2e 100644 --- a/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1.cpp +++ b/examples/PhasorDynamics/Tiny/TwoBus/Tgov1/TwoBusTgov1.cpp @@ -8,10 +8,11 @@ * compares results with data generated for the same system by Poweworld. * */ +#include "TwoBusTgov1.hpp" + #include #include -#include "TwoBusTgov1.hpp" #include #include #include diff --git a/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp b/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp index 99803728e..e0cc46752 100644 --- a/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp +++ b/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp @@ -78,8 +78,8 @@ namespace GridKit ScalarT& Pmech() override; private: - signal_type* pmech_{nullptr}; - signal_type* omega_{nullptr}; + signal_type* pmech_{nullptr}; + signal_type* omega_{nullptr}; // Input parameters real_type R_; From 74ad64947d119210222a077f44a4ae29a9a46771 Mon Sep 17 00:00:00 2001 From: pelesh Date: Fri, 18 Jul 2025 14:28:50 -0400 Subject: [PATCH 6/6] Remove compiler warnings and unused code. --- .../PhasorDynamics/Governor/Tgov1/Tgov1.cpp | 39 ----------- .../PhasorDynamics/Governor/Tgov1/Tgov1.hpp | 3 - .../PhasorDynamics/GovernorTgov1Tests.hpp | 66 ++----------------- .../PhasorDynamics/runGovernorTgov1Tests.cpp | 1 - 4 files changed, 4 insertions(+), 105 deletions(-) diff --git a/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.cpp b/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.cpp index d32ebcd55..1be41020d 100644 --- a/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.cpp +++ b/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.cpp @@ -23,28 +23,6 @@ namespace GridKit { namespace Governor { - - /*! - * @brief Constructor for Governor - * - * @param machine Generator Object - * @param data TGOV1 Data Object - */ - template - Tgov1::Tgov1(machine_type* machine, const model_data_type& data) - : R_(data.R), - Pvmin_(data.Pvmin), - Pvmax_(data.Pvmax), - T1_(data.T1), - T2_(data.T2), - T3_(data.T3), - Dt_(data.Dt) - { - - // 3 Internal Variables - size_ = 3; - } - /** * */ @@ -60,22 +38,6 @@ namespace GridKit T3_(data.T3), Dt_(data.Dt) { - - // 3 Internal Variables - size_ = 3; - } - - template - Tgov1::Tgov1(machine_type* machine) - : R_(0.05), - Pvmin_(0), - Pvmax_(1), - T1_(0.5), - T2_(2.5), - T3_(7.5), - Dt_(0) - { - // 3 Internal Variables size_ = 3; } @@ -92,7 +54,6 @@ namespace GridKit T3_(7.5), Dt_(0) { - // 3 Internal Variables size_ = 3; } diff --git a/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp b/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp index e0cc46752..63c9c3c0e 100644 --- a/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp +++ b/src/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp @@ -50,16 +50,13 @@ namespace GridKit using Component::y_; using Component::yp_; - using machine_type = Genrou; using real_type = typename Component::real_type; using model_data_type = Tgov1Data; using signal_type = SignalNode; public: - Tgov1(machine_type* machine, const model_data_type& data); Tgov1(signal_type* pmech, signal_type* omega, const model_data_type& data); Tgov1(signal_type* pmech, signal_type* omega); - Tgov1(machine_type* machine); ~Tgov1() = default; int allocate() override; diff --git a/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp b/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp index cc795dfe2..20740512c 100644 --- a/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp +++ b/tests/UnitTests/PhasorDynamics/GovernorTgov1Tests.hpp @@ -30,13 +30,12 @@ namespace GridKit { TestStatus success = true; - auto* bus = new PhasorDynamics::Bus(1.0, 0.0); - - PhasorDynamics::Genrou* machine = - new PhasorDynamics::Genrou(bus, 1); + PhasorDynamics::Bus bus(1.0, 0.0); + PhasorDynamics::SignalNode pmech; + PhasorDynamics::SignalNode omega; PhasorDynamics::Governor::Tgov1* gov = - new PhasorDynamics::Governor::Tgov1(machine); + new PhasorDynamics::Governor::Tgov1(&pmech, &omega); success *= (gov != nullptr); @@ -44,11 +43,6 @@ namespace GridKit { delete gov; } - if (machine) - { - delete machine; - } - delete bus; return success.report(__func__); } @@ -66,58 +60,6 @@ namespace GridKit { TestStatus success = true; - PhasorDynamics::Bus bus(1.0, 0.0); - PhasorDynamics::Genrou gen(&bus, - 1, - 1, - 0.05013, - 3, - 0, - 0, - 7, - 0.04, - 0.05, - 0.75, - 2.1, - 0.2, - 0.18, - 0.5, - 0.5, - 0.18, - 0.15, - 0, - 0); - PhasorDynamics::Governor::Tgov1 gov(&gen); - - bus.allocate(); - bus.initialize(); - bus.evaluateResidual(); - - gen.allocate(); - gen.initialize(); - gen.evaluateResidual(); - - gov.allocate(); - gov.initialize(); - gov.evaluateResidual(); - - // Require results to be within machine precision - auto tol = 10 * std::numeric_limits::epsilon(); - - const std::vector& f = gov.getResidual(); - for (const auto& f_val : f) - { - if (!isEqual(f_val, 0.0, tol)) - success = false; - } - - return success.report(__func__); - } - - TestOutcome residualWithSignalNode() - { - TestStatus success = true; - using BusType = PhasorDynamics::BusData::BusType; using GenrouParameters = PhasorDynamics::GenrouData::Parameters; using GenrouPorts = PhasorDynamics::GenrouData::Ports; diff --git a/tests/UnitTests/PhasorDynamics/runGovernorTgov1Tests.cpp b/tests/UnitTests/PhasorDynamics/runGovernorTgov1Tests.cpp index d8d026d34..ced215e1d 100644 --- a/tests/UnitTests/PhasorDynamics/runGovernorTgov1Tests.cpp +++ b/tests/UnitTests/PhasorDynamics/runGovernorTgov1Tests.cpp @@ -9,7 +9,6 @@ int main() result += test.constructor(); result += test.accessors(); result += test.residual(); - result += test.residualWithSignalNode(); return result.summary(); }