From f965257cd304c97f1c0fcb7ec55b2a9be64f76f4 Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Mon, 13 Apr 2026 12:48:40 -0400 Subject: [PATCH 1/7] Separate internal and external residuals --- .../PowerElectronics/Capacitor/Capacitor.cpp | 12 ++++-- .../PowerElectronics/Capacitor/Capacitor.hpp | 3 +- .../PowerElectronics/CircuitComponent.hpp | 12 ++++++ .../DistributedGenerator.cpp | 41 +++++++++++-------- .../DistributedGenerator.hpp | 3 +- .../InductionMotor/InductionMotor.cpp | 17 +++++--- .../InductionMotor/InductionMotor.hpp | 3 +- .../PowerElectronics/Inductor/Inductor.cpp | 11 +++-- .../PowerElectronics/Inductor/Inductor.hpp | 3 +- .../LinearTransformer/LinearTransformer.cpp | 16 ++++++-- .../LinearTransformer/LinearTransformer.hpp | 3 +- .../MicrogridBusDQ/MicrogridBusDQ.cpp | 10 ++++- .../MicrogridBusDQ/MicrogridBusDQ.hpp | 3 +- .../MicrogridLine/MicrogridLine.cpp | 15 ++++--- .../MicrogridLine/MicrogridLine.hpp | 3 +- .../MicrogridLoad/MicrogridLoad.cpp | 15 ++++--- .../MicrogridLoad/MicrogridLoad.hpp | 3 +- .../PowerElectronics/Resistor/Resistor.cpp | 8 +++- .../PowerElectronics/Resistor/Resistor.hpp | 3 +- .../SynchronousMachine/SynchronousMachine.cpp | 28 ++++++++++--- .../SynchronousMachine/SynchronousMachine.hpp | 3 +- .../SystemModelPowerElectronics.hpp | 22 +++++++--- .../TransmissionLine/TransmissionLine.cpp | 34 ++++++++------- .../TransmissionLine/TransmissionLine.hpp | 3 +- .../VoltageSource/VoltageSource.cpp | 12 ++++-- .../VoltageSource/VoltageSource.hpp | 3 +- 26 files changed, 201 insertions(+), 88 deletions(-) diff --git a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp index 6b60c7f42..eb5f4fe68 100644 --- a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp +++ b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp @@ -57,15 +57,19 @@ namespace GridKit * */ template - int Capacitor::evaluateResidual() + int Capacitor::evaluateInternalResidual() + { + f_[2] = -C_ * yp_[2] + y_[0] - y_[1] - y_[2]; + return 0; + } + + template + int Capacitor::evaluateExternalResidual() { // input f_[0] = C_ * yp_[2]; // output f_[1] = -C_ * yp_[2]; - - // internal - f_[2] = -C_ * yp_[2] + y_[0] - y_[1] - y_[2]; return 0; } diff --git a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.hpp b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.hpp index c7e2390d1..fafdbf79a 100644 --- a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.hpp +++ b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.hpp @@ -47,7 +47,8 @@ namespace GridKit int initialize(); int tagDifferentiable(); - int evaluateResidual(); + int evaluateInternalResidual() final; + int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); diff --git a/GridKit/Model/PowerElectronics/CircuitComponent.hpp b/GridKit/Model/PowerElectronics/CircuitComponent.hpp index 90cd6e66e..89240c526 100644 --- a/GridKit/Model/PowerElectronics/CircuitComponent.hpp +++ b/GridKit/Model/PowerElectronics/CircuitComponent.hpp @@ -145,6 +145,18 @@ namespace GridKit return jacobian_coo_values_.get(); } + int evaluateResidual() final + { + if (int err_code = evaluateInternalResidual()) + return err_code; + + return evaluateExternalResidual(); + } + + virtual int evaluateInternalResidual() = 0; + + virtual int evaluateExternalResidual() = 0; + protected: /** * @brief Reset the Jacobian so it can be constructed. Helper method for \ref setJacValues(). diff --git a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp index 4eb99edc7..b766b8303 100644 --- a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp +++ b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp @@ -89,26 +89,9 @@ namespace GridKit * */ template - int DistributedGenerator::evaluateResidual() + int DistributedGenerator::evaluateInternalResidual() { - // ### Externals Componenets ### - ScalarT omega = wb_ - mp_ * y_[4]; - // ref common ref motor angle - /// @todo fix boolian conditional, unclear result - if (refframe_) - { - f_[0] = omega - y_[0]; - } - else - { - f_[0] = 0.0; - } - - // output - // current transformed to common frame - f_[1] = std::cos(y_[3]) * y_[14] - std::sin(y_[3]) * y_[15]; - f_[2] = std::sin(y_[3]) * y_[14] + std::cos(y_[3]) * y_[15]; // Take incoming voltages to current rotator reference frame ScalarT vbd_in = std::cos(y_[3]) * y_[1] + std::sin(y_[3]) * y_[2]; @@ -152,6 +135,28 @@ namespace GridKit return 0; } + template + int DistributedGenerator::evaluateExternalResidual() + { + ScalarT omega = wb_ - mp_ * y_[4]; + // ref common ref motor angle + /// @todo fix boolian conditional, unclear result + if (refframe_) + { + f_[0] = omega - y_[0]; + } + else + { + f_[0] = 0.0; + } + + // output + // current transformed to common frame + f_[1] = std::cos(y_[3]) * y_[14] - std::sin(y_[3]) * y_[15]; + f_[2] = std::sin(y_[3]) * y_[14] + std::cos(y_[3]) * y_[15]; + return 0; + } + /** * @brief Compute the jacobian of the DistributedGenerator for iteration. dF/dy - \alpha dF/dy' * diff --git a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp index a2e34db84..3b6aaba3f 100644 --- a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp +++ b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp @@ -74,7 +74,8 @@ namespace GridKit int initialize(); int allocate() final; int tagDifferentiable(); - int evaluateResidual(); + int evaluateInternalResidual() final; + int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); int initializeAdjoint(); diff --git a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp index 011a33fe4..20f0cc5d3 100644 --- a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp +++ b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp @@ -68,19 +68,24 @@ namespace GridKit * */ template - int InductionMotor::evaluateResidual() + int InductionMotor::evaluateInternalResidual() { + 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 / std::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.0) * y_[3] * ((Llr_ + Lms_) * y_[9] + Lms_ * y_[6]); + f_[9] = Rr_ * y_[9] + (Llr_ + Lms_) * yp_[9] + Lms_ * yp_[6] + (P_ / 2.0) * y_[3] * ((Llr_ + Lms_) * y_[8] + Lms_ * y_[5]); + return 0; + } + template + int InductionMotor::evaluateExternalResidual() + { f_[0] = y_[5] + y_[7]; f_[1] = (-1.0 / 2.0) * y_[5] - (std::sqrt(3.0) / 2.0) * y_[6] + y_[7]; f_[2] = (-1.0 / 2.0) * y_[5] + (std::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 / std::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.0) * y_[3] * ((Llr_ + Lms_) * y_[9] + Lms_ * y_[6]); - f_[9] = Rr_ * y_[9] + (Llr_ + Lms_) * yp_[9] + Lms_ * yp_[6] + (P_ / 2.0) * y_[3] * ((Llr_ + Lms_) * y_[8] + Lms_ * y_[5]); return 0; } diff --git a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp index dcd6ba865..e4f0c2f6a 100644 --- a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp +++ b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp @@ -47,7 +47,8 @@ namespace GridKit int initialize(); int tagDifferentiable(); - int evaluateResidual(); + int evaluateInternalResidual() final; + int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); diff --git a/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp b/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp index 293688834..e7fcdfb22 100644 --- a/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp +++ b/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp @@ -56,14 +56,19 @@ namespace GridKit * */ template - int Inductor::evaluateResidual() + int Inductor::evaluateInternalResidual() + { + f_[2] = -L_ * yp_[2] + y_[1] - y_[0]; + return 0; + } + + template + int Inductor::evaluateExternalResidual() { // input f_[0] = -y_[2]; // output f_[1] = y_[2]; - // internal - f_[2] = -L_ * yp_[2] + y_[1] - y_[0]; return 0; } diff --git a/GridKit/Model/PowerElectronics/Inductor/Inductor.hpp b/GridKit/Model/PowerElectronics/Inductor/Inductor.hpp index 88c0e2e03..8ccd72612 100644 --- a/GridKit/Model/PowerElectronics/Inductor/Inductor.hpp +++ b/GridKit/Model/PowerElectronics/Inductor/Inductor.hpp @@ -50,7 +50,8 @@ namespace GridKit int initialize(); int allocate() final; int tagDifferentiable(); - int evaluateResidual(); + int evaluateInternalResidual() final; + int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); diff --git a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp index 4d53b5d73..4aa74db35 100644 --- a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp +++ b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp @@ -67,18 +67,26 @@ namespace GridKit /** * @brief Computes the component resisdual - * + * @todo Check if there is a bug here */ template - int LinearTransformer::evaluateResidual() + int LinearTransformer::evaluateInternalResidual() { - f_[0] = y_[2]; - f_[1] = y_[3]; + // HMMMMM... This looks like a bug + // TODO f_[2] = y_[0] - R0_ * y_[2] - L0_ * yp_[2] - M_ * yp_[3]; f_[2] = y_[1] - R1_ * y_[3] - M_ * yp_[2] - L1_ * yp_[3]; return 0; } + template + int LinearTransformer::evaluateExternalResidual() + { + f_[0] = y_[2]; + f_[1] = y_[3]; + return 0; + } + template int LinearTransformer::evaluateJacobian() { diff --git a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp index 972ed4545..a83bb8879 100644 --- a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp +++ b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp @@ -47,7 +47,8 @@ namespace GridKit int initialize(); int tagDifferentiable(); - int evaluateResidual(); + int evaluateInternalResidual() final; + int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); diff --git a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp index e1a456241..f9174ba15 100644 --- a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -56,8 +56,14 @@ namespace GridKit return 0; } + template + int MicrogridBusDQ::evaluateInternalResidual() + { + return 0; + } + /** - * @brief Evaluate residual of microgrid line + * @brief Evaluate residual * This model has "Virtual resistors". The voltage of the bus divided by its virtual resistance. * The components are external to allow for outside components to add inductances to the terms. * @@ -65,7 +71,7 @@ namespace GridKit * */ template - int MicrogridBusDQ::evaluateResidual() + int MicrogridBusDQ::evaluateExternalResidual() { // bus voltage f_[0] = -y_[0] / RN_; diff --git a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp index 37f01dca0..2c7ff4d18 100644 --- a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp +++ b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp @@ -50,7 +50,8 @@ namespace GridKit int initialize(); int allocate() final; int tagDifferentiable(); - int evaluateResidual(); + int evaluateInternalResidual() final; + int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); diff --git a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp index 08cb5104a..23c2e90bb 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp @@ -70,7 +70,16 @@ namespace GridKit * */ template - int MicrogridLine::evaluateResidual() + int MicrogridLine::evaluateInternalResidual() + { + 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; + } + + template + int MicrogridLine::evaluateExternalResidual() { // ref motor f_[0] = 0.0; @@ -83,10 +92,6 @@ namespace GridKit 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; } diff --git a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp index ab3f80418..79fa5334c 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp +++ b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp @@ -50,7 +50,8 @@ namespace GridKit int initialize(); int allocate() final; int tagDifferentiable(); - int evaluateResidual(); + int evaluateInternalResidual() final; + int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); diff --git a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp index 4312d954c..7ba54d06a 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp @@ -65,7 +65,16 @@ namespace GridKit * @brief Eval Micro Load */ template - int MicrogridLoad::evaluateResidual() + int MicrogridLoad::evaluateInternalResidual() + { + 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; + } + + template + int MicrogridLoad::evaluateExternalResidual() { // ref motor f_[0] = 0.0; @@ -76,10 +85,6 @@ namespace GridKit 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; } diff --git a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp index 842db1762..63a5df20c 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp +++ b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp @@ -50,7 +50,8 @@ namespace GridKit int initialize(); int allocate() final; int tagDifferentiable(); - int evaluateResidual(); + int evaluateInternalResidual() final; + int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); diff --git a/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp b/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp index e17d7034c..9c2243010 100644 --- a/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp +++ b/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp @@ -57,7 +57,13 @@ namespace GridKit * */ template - int Resistor::evaluateResidual() + int Resistor::evaluateInternalResidual() + { + return 0; + } + + template + int Resistor::evaluateExternalResidual() { // input f_[0] = (y_[0] - y_[1]) / R_; diff --git a/GridKit/Model/PowerElectronics/Resistor/Resistor.hpp b/GridKit/Model/PowerElectronics/Resistor/Resistor.hpp index 16b248642..542e3d786 100644 --- a/GridKit/Model/PowerElectronics/Resistor/Resistor.hpp +++ b/GridKit/Model/PowerElectronics/Resistor/Resistor.hpp @@ -50,7 +50,8 @@ namespace GridKit int initialize(); int allocate() final; int tagDifferentiable(); - int evaluateResidual(); + int evaluateInternalResidual() final; + int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); diff --git a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp index c2ca90d0c..3f22e37bf 100644 --- a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp +++ b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp @@ -87,7 +87,7 @@ namespace GridKit * @todo not finished */ template - int SynchronousMachine::evaluateResidual() + int SynchronousMachine::evaluateInternalResidual() { ScalarT rkq1 = static_cast(std::get<0>(Rkq_)); [[maybe_unused]] ScalarT rkq2 = static_cast(std::get<1>(Rkq_)); @@ -101,11 +101,6 @@ namespace GridKit ScalarT cos23p = std::cos((P_ / 2.0) * y_[5] + (2.0 / 3.0) * M_PI); ScalarT sin23p = std::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]; @@ -114,6 +109,27 @@ namespace GridKit return 0; } + template + int SynchronousMachine::evaluateExternalResidual() + { + [[maybe_unused]] ScalarT rkq2 = static_cast(std::get<1>(Rkq_)); + [[maybe_unused]] ScalarT llkq2 = static_cast(std::get<1>(Llkq_)); + + ScalarT cos1 = std::cos((P_ / 2.0) * y_[5]); + ScalarT sin1 = std::sin((P_ / 2.0) * y_[5]); + ScalarT cos23m = std::cos((P_ / 2.0) * y_[5] - (2.0 / 3.0) * M_PI); + ScalarT sin23m = std::sin((P_ / 2.0) * y_[5] - (2.0 / 3.0) * M_PI); + ScalarT cos23p = std::cos((P_ / 2.0) * y_[5] + (2.0 / 3.0) * M_PI); + ScalarT sin23p = std::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]; + return 0; + } + template int SynchronousMachine::evaluateJacobian() { diff --git a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp index dd0f9ff18..c24eed38a 100644 --- a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp +++ b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp @@ -49,7 +49,8 @@ namespace GridKit int initialize(); int tagDifferentiable(); - int evaluateResidual(); + int evaluateInternalResidual() final; + int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); diff --git a/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp b/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp index 7a1ff4b72..a10607b34 100644 --- a/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp +++ b/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp @@ -363,7 +363,7 @@ namespace GridKit * * @return int 0 if successful, positive if there's a recoverable error, negative if unrecoverable */ - int evaluateResidual() final + int evaluateInternalResidual() final { for (IdxT i = 0; i < this->f_.size(); i++) { @@ -374,10 +374,17 @@ namespace GridKit // Update system residual vector + // Evaluate component internal residuals - this is embarassingly parallel + for (component_type* component : components_) + { + if (int err_code = component->evaluateInternalResidual()) + return err_code; + } + for (const auto& component : components_) { - // TODO:check return type - component->evaluateResidual(); + if (int err_code = component->evaluateExternalResidual()) + return err_code; IdxT size = component->size(); const std::vector& residual = component->getResidual(); @@ -391,9 +398,14 @@ namespace GridKit } } - // Uncomment to print the residual in matrix market format - // writeVectorToMatrixMarket(f_, "ScaleMicrogrid_Residual_N2_number" + std::to_string(jac_call_count_) + ".mtx", "Residual N2 number " + std::to_string(jac_call_count_)); + return 0; + } + /** + * @todo implement this for nested systems + */ + int evaluateExternalResidual() final + { return 0; } diff --git a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp index fa2256dac..f73c06042 100644 --- a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp +++ b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp @@ -82,21 +82,8 @@ namespace GridKit * To express this for Modified Nodal Analysis the Voltages of the admittance matrix are put into voltage drops */ template - int TransmissionLine::evaluateResidual() + int TransmissionLine::evaluateInternalResidual() { - // input - f_[0] = y_[8]; - f_[1] = y_[9]; - - f_[2] = y_[10]; - f_[3] = y_[11]; - // ouput - f_[4] = -y_[8]; - f_[5] = -y_[9]; - - f_[6] = -y_[10]; - f_[7] = -y_[11]; - // Voltage drop accross terminals ScalarT V1re = y_[0] - y_[4]; ScalarT V1im = y_[1] - y_[5]; @@ -115,6 +102,25 @@ namespace GridKit return 0; } + template + int TransmissionLine::evaluateExternalResidual() + { + // input + f_[0] = y_[8]; + f_[1] = y_[9]; + + f_[2] = y_[10]; + f_[3] = y_[11]; + // ouput + f_[4] = -y_[8]; + f_[5] = -y_[9]; + + f_[6] = -y_[10]; + f_[7] = -y_[11]; + + return 0; + } + /** * @brief Generate Jacobian for Transmission Line * diff --git a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp index c3222ef4e..e557b5d7c 100644 --- a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp +++ b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp @@ -51,7 +51,8 @@ namespace GridKit int initialize(); int tagDifferentiable(); - int evaluateResidual(); + int evaluateInternalResidual() final; + int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); diff --git a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp index b31cf3b3a..58b3173ad 100644 --- a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp +++ b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp @@ -56,14 +56,20 @@ namespace GridKit * @brief Evaluate resisdual of component */ template - int VoltageSource::evaluateResidual() + int VoltageSource::evaluateInternalResidual() + { + // internal + f_[2] = y_[1] - y_[0] - V_; + return 0; + } + + template + int VoltageSource::evaluateExternalResidual() { // input f_[0] = -y_[2]; // ouput f_[1] = y_[2]; - // internal - f_[2] = y_[1] - y_[0] - V_; return 0; } diff --git a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.hpp b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.hpp index b5b0f05fc..234513a73 100644 --- a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.hpp +++ b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.hpp @@ -50,7 +50,8 @@ namespace GridKit int initialize(); int allocate() final; int tagDifferentiable(); - int evaluateResidual(); + int evaluateInternalResidual() final; + int evaluateExternalResidual() final; int evaluateJacobian() final; int evaluateIntegrand(); From 69c3df91b616db8888da801864537810d74f73b7 Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Mon, 13 Apr 2026 14:09:16 -0400 Subject: [PATCH 2/7] [skip ci] Documentation --- .../PowerElectronics/CircuitComponent.hpp | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/GridKit/Model/PowerElectronics/CircuitComponent.hpp b/GridKit/Model/PowerElectronics/CircuitComponent.hpp index 89240c526..0b3e3ee4d 100644 --- a/GridKit/Model/PowerElectronics/CircuitComponent.hpp +++ b/GridKit/Model/PowerElectronics/CircuitComponent.hpp @@ -145,6 +145,14 @@ namespace GridKit return jacobian_coo_values_.get(); } + /** + * @brief Evaluating the residual of a CircuitComponent should be done by evaluating the + * internal residuals and external residuals. CircuitComponents should overload those + * functions for their residuals (and the system will call those function instead of this one), + * so there is no reason to overload this functionality. + * + * @return An error code, or 0 is successful. + */ int evaluateResidual() final { if (int err_code = evaluateInternalResidual()) @@ -153,8 +161,20 @@ namespace GridKit return evaluateExternalResidual(); } + /** + * @brief Evaluate all of the residuals of internal variables of the component, + * modifying \ref f_. + * + * @return An error code, or 0 if successful. + */ virtual int evaluateInternalResidual() = 0; + /** + * @brief Evaluate all of the residuals of external variables of the component, + * modifying \ref f_ + * + * @return An error code, or 0 if successful. + */ virtual int evaluateExternalResidual() = 0; protected: From 6bc244c7d98ee737e854eb33ca9c1de2cd323c1a Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Mon, 13 Apr 2026 14:10:18 -0400 Subject: [PATCH 3/7] [skip ci] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fd168618..8766c4b80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ - Added SEXS-PTI Exciter Model - Added 200 Bus Synthetic Illinois Case - Added node objects to `PowerElectronics` module & updated all examples to make use of them. +- Separated internal and external residuals of `PowerElectronics` models. ## v0.1 From f3ec7f81378af6fca71aadc5cb9c77e66d7fee3d Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Tue, 14 Apr 2026 10:46:47 -0400 Subject: [PATCH 4/7] Change connection_nodes_ to allocate in allocate() --- .../PowerElectronics/CircuitComponent.hpp | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/GridKit/Model/PowerElectronics/CircuitComponent.hpp b/GridKit/Model/PowerElectronics/CircuitComponent.hpp index 0b3e3ee4d..b787b48d8 100644 --- a/GridKit/Model/PowerElectronics/CircuitComponent.hpp +++ b/GridKit/Model/PowerElectronics/CircuitComponent.hpp @@ -24,14 +24,6 @@ namespace GridKit CircuitComponent() = default; - ~CircuitComponent() - { - if (connection_nodes_ != nullptr) - { - delete[] connection_nodes_; - } - }; - /** * @note Cannot be marked final, since it is overriden to recurse in the system model. */ @@ -70,12 +62,7 @@ namespace GridKit */ int setExternalConnectionNodes(IdxT local_index, IdxT global_index) { - if (connection_nodes_ == nullptr) - { - connection_nodes_ = new IdxT[static_cast(size_)]; - } - - connection_nodes_[local_index] = global_index; + connection_nodes_[static_cast(local_index)] = global_index; return 0; } @@ -108,6 +95,8 @@ namespace GridKit jacobian_coo_cols_ = std::make_unique(static_cast(nnz_)); jacobian_coo_values_ = std::make_unique(static_cast(nnz_)); + connection_nodes_ = std::make_unique(static_cast(size_)); + y_.resize(static_cast(size_)); yp_.resize(static_cast(size_)); f_.resize(static_cast(size_)); @@ -403,11 +392,11 @@ namespace GridKit } protected: - size_t n_extern_; - size_t n_intern_; - std::set extern_indices_; + 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 - IdxT* connection_nodes_ = nullptr; + std::unique_ptr connection_nodes_; protected: IdxT size_{0}; From 12ff49fc7e4dc0951a5a98934552c1017b1a6e38 Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Mon, 27 Apr 2026 15:44:43 -0400 Subject: [PATCH 5/7] Fix LinearTransformer --- .../PowerElectronics/LinearTransformer/LinearTransformer.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp index 4aa74db35..3a10fc7da 100644 --- a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp +++ b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp @@ -67,15 +67,12 @@ namespace GridKit /** * @brief Computes the component resisdual - * @todo Check if there is a bug here */ template int LinearTransformer::evaluateInternalResidual() { - // HMMMMM... This looks like a bug - // TODO 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]; + f_[3] = y_[1] - R1_ * y_[3] - M_ * yp_[2] - L1_ * yp_[3]; return 0; } From 52c72ebc86b74fc49a100921e843377a15de58de Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Thu, 30 Apr 2026 14:23:15 -0400 Subject: [PATCH 6/7] Remove extra todo --- .../DistributedGenerator/DistributedGenerator.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp index b766b8303..830033b59 100644 --- a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp +++ b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp @@ -140,7 +140,6 @@ namespace GridKit { ScalarT omega = wb_ - mp_ * y_[4]; // ref common ref motor angle - /// @todo fix boolian conditional, unclear result if (refframe_) { f_[0] = omega - y_[0]; From ed016c86cbbcb292453f4a233250cbb3c8a911ba Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Thu, 30 Apr 2026 16:51:34 -0400 Subject: [PATCH 7/7] Update comments --- .../Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp index 23c2e90bb..712c3af17 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp @@ -84,11 +84,11 @@ namespace GridKit // ref motor f_[0] = 0.0; - // input + // Port 1 f_[1] = -y_[5]; f_[2] = -y_[6]; - // output + // Port 2 f_[3] = y_[5]; f_[4] = y_[6];