From e65f390dc485d1d61a376343dc4f31690cd0df40 Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Thu, 13 Aug 2026 16:10:36 -0400 Subject: [PATCH 1/9] Implement tagDifferentiable in PowerElectronics --- .../PowerElectronics/Capacitor/Capacitor.cpp | 2 + .../PowerElectronics/CircuitComponent.hpp | 32 ++++++++-------- .../DistributedGenerator.cpp | 3 +- .../InductionMotor/InductionMotor.cpp | 2 + .../PowerElectronics/Inductor/Inductor.cpp | 2 + .../LinearTransformer/LinearTransformer.cpp | 2 + .../MicrogridBusDQ/MicrogridBusDQ.cpp | 2 + .../MicrogridLine/MicrogridLine.cpp | 2 + .../MicrogridLoad/MicrogridLoad.cpp | 2 + GridKit/Model/PowerElectronics/NodeBase.hpp | 2 +- .../SynchronousMachine/SynchronousMachine.cpp | 2 + .../SystemModelPowerElectronics.hpp | 37 ++++++++++++++++++- .../TransmissionLine/TransmissionLine.cpp | 2 + .../VoltageSource/VoltageSource.cpp | 2 + .../PowerElectronics/Microgrid/Microgrid.cpp | 23 ++++++++++++ 15 files changed, 97 insertions(+), 20 deletions(-) diff --git a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp index aab348679..31ec1b0e2 100644 --- a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp +++ b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp @@ -49,6 +49,8 @@ namespace GridKit template int Capacitor::tagDifferentiable() { + // All variables are differentials + tag_.resize(size_, true); return 0; } diff --git a/GridKit/Model/PowerElectronics/CircuitComponent.hpp b/GridKit/Model/PowerElectronics/CircuitComponent.hpp index c6fcad6dd..9a8767e55 100644 --- a/GridKit/Model/PowerElectronics/CircuitComponent.hpp +++ b/GridKit/Model/PowerElectronics/CircuitComponent.hpp @@ -128,14 +128,14 @@ namespace GridKit */ int allocate() override { - jacobian_coo_rows_ = std::make_unique(static_cast(nnz_)); - jacobian_coo_cols_ = std::make_unique(static_cast(nnz_)); - jacobian_coo_values_ = std::make_unique(static_cast(nnz_)); + jacobian_coo_rows_ = std::make_unique(nnz_); + jacobian_coo_cols_ = std::make_unique(nnz_); + jacobian_coo_values_ = std::make_unique(nnz_); - y_ext_ = std::make_unique(static_cast(size_)); - yp_ext_ = std::make_unique(static_cast(size_)); - f_ext_ = std::make_unique(static_cast(size_)); - connection_nodes_ = std::make_unique(static_cast(size_)); + y_ext_ = std::make_unique(size_); + yp_ext_ = std::make_unique(size_); + f_ext_ = std::make_unique(size_); + connection_nodes_ = std::make_unique(size_); if (!allocated_) { @@ -250,7 +250,7 @@ namespace GridKit { assert(rows.size() == cols.size()); assert(rows.size() == vals.size()); - assert(current_jac_size_ + rows.size() <= static_cast(nnz_)); + assert(current_jac_size_ + rows.size() <= nnz_); for (size_t i = 0; i < rows.size(); i++) { @@ -265,22 +265,22 @@ namespace GridKit public: IdxT size() final { - return size_; + return static_cast(size_); } IdxT size() const { - return size_; + return static_cast(size_); } IdxT nnz() final { - return nnz_; + return static_cast(nnz_); } IdxT nnz() const { - return nnz_; + return static_cast(nnz_); } IdxT sizeQuadrature() final @@ -491,11 +491,11 @@ namespace GridKit protected: /// The number of variables in this component. Should be equal to \ref n_extern_ plus \ref n_intern_. \see size() - IdxT size_{0}; + IdxT size_{0}; /// The number of nonzero elements in this component's Jacobian. \see nnz() - IdxT nnz_{0}; - IdxT size_quad_{0}; - IdxT size_opt_{0}; + size_t nnz_{0}; + IdxT size_quad_{0}; + IdxT size_opt_{0}; // COO Jacobian buffers std::unique_ptr jacobian_coo_rows_; diff --git a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp index dfa6f1a98..af707aea8 100644 --- a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp +++ b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp @@ -3,7 +3,6 @@ #include "DistributedGenerator.hpp" #include -#include #include namespace GridKit @@ -74,6 +73,8 @@ namespace GridKit template int DistributedGenerator::tagDifferentiable() { + // All variables are differentials + tag_.resize(size_, true); return 0; } diff --git a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp index 0224e6ebe..69f0dcc39 100644 --- a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp +++ b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp @@ -60,6 +60,8 @@ namespace GridKit template int InductionMotor::tagDifferentiable() { + // All variables are differentials + tag_.resize(size_, true); return 0; } diff --git a/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp b/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp index b192cebc5..ff521fd65 100644 --- a/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp +++ b/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp @@ -48,6 +48,8 @@ namespace GridKit template int Inductor::tagDifferentiable() { + // All variables are differentials + tag_.resize(size_, true); return 0; } diff --git a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp index fcfc4a02d..d8f453bf7 100644 --- a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp +++ b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp @@ -62,6 +62,8 @@ namespace GridKit template int LinearTransformer::tagDifferentiable() { + // All variables are differentials + tag_.resize(size_, true); return 0; } diff --git a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp index ffc02dfb3..0c3c6331c 100644 --- a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -77,6 +77,8 @@ namespace GridKit template int MicrogridBusDQ::evaluateInternalResidual() { + // No internal variables - tag doesn't matter. + tag_.resize(size_, false); return 0; } diff --git a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp index 65c3fb0a0..0b467b6d4 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp @@ -62,6 +62,8 @@ namespace GridKit template int MicrogridLine::tagDifferentiable() { + // All variables are differentials + tag_.resize(size_, true); return 0; } diff --git a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp index a14a038f1..a83ffcbb7 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp @@ -58,6 +58,8 @@ namespace GridKit template int MicrogridLoad::tagDifferentiable() { + // All variables are differentials + tag_.resize(size_, true); return 0; } diff --git a/GridKit/Model/PowerElectronics/NodeBase.hpp b/GridKit/Model/PowerElectronics/NodeBase.hpp index 3c7f7c80b..077854b97 100644 --- a/GridKit/Model/PowerElectronics/NodeBase.hpp +++ b/GridKit/Model/PowerElectronics/NodeBase.hpp @@ -145,7 +145,7 @@ namespace GridKit allocateVectors(static_cast(size)); } - tag_.resize(size); + tag_.resize(size, false); variable_indices_.resize(size); residual_indices_.resize(size); diff --git a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp index c3a647762..5972a4530 100644 --- a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp +++ b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp @@ -77,6 +77,8 @@ namespace GridKit template int SynchronousMachine::tagDifferentiable() { + // All variables are differentials + tag_.resize(size_, true); return 0; } diff --git a/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp b/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp index 57b705bbb..31695ad4b 100644 --- a/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp +++ b/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -12,6 +13,8 @@ #include #include +#include "GridKit/Utilities/Logger/Logger.hpp" + namespace GridKit { template @@ -148,8 +151,6 @@ namespace GridKit abs_tol_.setToZero(memory::HOST); } - tag_.resize(size_); - { // Start node internal indexing after all component internals for proper KLU ordering size_t node_internal_idx = component_internal_size; for (node_type* node : nodes_) @@ -294,6 +295,38 @@ namespace GridKit int tagDifferentiable() final { + for (size_t i = 0; i < components_.size(); i++) + { + component_type* component = components_[i]; + + if (int err = component->tagDifferentiable()) + { + return err; + } + + if (component->tag().size() != component->size()) + { + GridKit::Utilities::Logger::error() << std::format("Component {} has an ill-configured tag(). Expected tags for {} variables, got {} instead.\n", i, component->size(), component->tag().size()); + return 1; + } + } + + tag_.resize(size_, false); + + size_t idx = 0; + for (component_type* comp : components_) + { + const auto& external_indices = comp->getExternIndices(); + for (IdxT i = 0; i < comp->size(); i++) + { + if (!external_indices.contains(i)) + { + tag_[idx] = comp->tag()[i]; + idx++; + } + } + } + return 0; } diff --git a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp index 3adbbef58..38a4e6c1d 100644 --- a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp +++ b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp @@ -60,6 +60,8 @@ namespace GridKit template int TransmissionLine::tagDifferentiable() { + // All variables are algebraics + tag_.resize(size_, false); return 0; } diff --git a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp index 9a4accd0b..de1f8a8bd 100644 --- a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp +++ b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp @@ -49,6 +49,8 @@ namespace GridKit template int VoltageSource::tagDifferentiable() { + // All variables are algebraics + tag_.resize(size_, false); return 0; } diff --git a/examples/PowerElectronics/Microgrid/Microgrid.cpp b/examples/PowerElectronics/Microgrid/Microgrid.cpp index 74497fc41..ca94e575b 100644 --- a/examples/PowerElectronics/Microgrid/Microgrid.cpp +++ b/examples/PowerElectronics/Microgrid/Microgrid.cpp @@ -223,6 +223,29 @@ int main(int /* argc */, char const** /* argv */) sysmodel->getCsrJacobian()->print(); } + sysmodel->tagDifferentiable(); + + bool all_internal_diff = true; + bool all_external_alg = true; + + const size_t num_node_vars = 4 * 2 + 1; + + for (size_t i = 0; i < sysmodel->size() - num_node_vars; i++) + { + all_internal_diff = all_internal_diff && sysmodel->tag()[i]; + if (!sysmodel->tag()[i]) + { + std::cout << "Broken on " << i << '\n'; + } + } + + for (size_t i = sysmodel->size() - num_node_vars; i < sysmodel->size(); i++) + { + all_external_alg = all_external_alg && !sysmodel->tag()[i]; + } + + std::cout << "Verify all internal variables are differential: " << all_internal_diff << ", and all external variabels are algebraic: " << all_external_alg << '\n'; + // Create numerical integrator and configure it for the generator model auto* idas = new AnalysisManager::Sundials::Ida(sysmodel); From a1e9d87bea6030ddeb289936afb82829f91f056d Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Thu, 13 Aug 2026 17:37:19 -0400 Subject: [PATCH 2/9] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 744f6ec98..7e3336671 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -82,6 +82,7 @@ - Added `REECB` electrical-control model implementation for PhasorDynamics. - Added cases and validation for ACTIVSg10k, ACTIVSg200, ACTIVSg500, and WECC240. - Added IDA option to choose the consistent initial condition calculation type. +- Implemented `tagDifferentiable()` for `PowerElectronics` models. ## v0.1 From 11bcc4dd1e5e29cba31a080f1031f6b663e9610f Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Fri, 21 Aug 2026 13:26:29 -0400 Subject: [PATCH 3/9] Fix RLCircuit example Added tags to `Resistor`, which has no internal variables, but still need the appropriate tag size to be set. --- GridKit/Model/PowerElectronics/Resistor/Resistor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp b/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp index 5c6c4a1cb..bd8217163 100644 --- a/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp +++ b/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp @@ -49,6 +49,8 @@ namespace GridKit template int Resistor::tagDifferentiable() { + // No internal variables, so these valeus do not matter + tag_.resize(size_, true); return 0; } From ba6aa1e6fbad72ea558c2257d1582366a925889f Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Mon, 24 Aug 2026 12:32:48 -0400 Subject: [PATCH 4/9] Change tag_ to allocate in allocate() --- GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp | 2 +- GridKit/Model/PowerElectronics/CircuitComponent.hpp | 2 ++ .../DistributedGenerator/DistributedGenerator.cpp | 2 +- .../PowerElectronics/InductionMotor/InductionMotor.cpp | 2 +- GridKit/Model/PowerElectronics/Inductor/Inductor.cpp | 2 +- .../LinearTransformer/LinearTransformer.cpp | 2 +- .../PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp | 6 +----- .../Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp | 2 +- .../Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp | 2 +- GridKit/Model/PowerElectronics/Resistor/Resistor.cpp | 2 +- .../SynchronousMachine/SynchronousMachine.cpp | 2 +- .../Model/PowerElectronics/SystemModelPowerElectronics.hpp | 4 +++- .../PowerElectronics/TransmissionLine/TransmissionLine.cpp | 2 +- .../Model/PowerElectronics/VoltageSource/VoltageSource.cpp | 2 +- 14 files changed, 17 insertions(+), 17 deletions(-) diff --git a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp index 31ec1b0e2..6c0b5fdf6 100644 --- a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp +++ b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp @@ -50,7 +50,7 @@ namespace GridKit int Capacitor::tagDifferentiable() { // All variables are differentials - tag_.resize(size_, true); + std::fill(tag_.begin(), tag_.end(), true); return 0; } diff --git a/GridKit/Model/PowerElectronics/CircuitComponent.hpp b/GridKit/Model/PowerElectronics/CircuitComponent.hpp index 9a8767e55..816920e20 100644 --- a/GridKit/Model/PowerElectronics/CircuitComponent.hpp +++ b/GridKit/Model/PowerElectronics/CircuitComponent.hpp @@ -137,6 +137,8 @@ namespace GridKit f_ext_ = std::make_unique(size_); connection_nodes_ = std::make_unique(size_); + tag_.resize(size_); + if (!allocated_) { allocateVectors(size_); diff --git a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp index af707aea8..aa538933f 100644 --- a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp +++ b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp @@ -74,7 +74,7 @@ namespace GridKit int DistributedGenerator::tagDifferentiable() { // All variables are differentials - tag_.resize(size_, true); + std::fill(tag_.begin(), tag_.end(), true); return 0; } diff --git a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp index 69f0dcc39..74aabb549 100644 --- a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp +++ b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp @@ -61,7 +61,7 @@ namespace GridKit int InductionMotor::tagDifferentiable() { // All variables are differentials - tag_.resize(size_, true); + std::fill(tag_.begin(), tag_.end(), true); return 0; } diff --git a/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp b/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp index ff521fd65..0e6e7ea28 100644 --- a/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp +++ b/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp @@ -49,7 +49,7 @@ namespace GridKit int Inductor::tagDifferentiable() { // All variables are differentials - tag_.resize(size_, true); + std::fill(tag_.begin(), tag_.end(), true); return 0; } diff --git a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp index d8f453bf7..455ef202f 100644 --- a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp +++ b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp @@ -63,7 +63,7 @@ namespace GridKit int LinearTransformer::tagDifferentiable() { // All variables are differentials - tag_.resize(size_, true); + std::fill(tag_.begin(), tag_.end(), true); return 0; } diff --git a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp index 0c3c6331c..462c200f8 100644 --- a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -47,9 +47,7 @@ namespace GridKit return 0; } - /* - * \brief Identify differential variables - */ + /// There are no internal variables in this component, so \ref tag_ can be set arbitrarily. template int MicrogridBusDQ::tagDifferentiable() { @@ -77,8 +75,6 @@ namespace GridKit template int MicrogridBusDQ::evaluateInternalResidual() { - // No internal variables - tag doesn't matter. - tag_.resize(size_, false); return 0; } diff --git a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp index 0b467b6d4..efa5c2a36 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp @@ -63,7 +63,7 @@ namespace GridKit int MicrogridLine::tagDifferentiable() { // All variables are differentials - tag_.resize(size_, true); + std::fill(tag_.begin(), tag_.end(), true); return 0; } diff --git a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp index a83ffcbb7..36ac6c375 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp @@ -59,7 +59,7 @@ namespace GridKit int MicrogridLoad::tagDifferentiable() { // All variables are differentials - tag_.resize(size_, true); + std::fill(tag_.begin(), tag_.end(), true); return 0; } diff --git a/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp b/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp index bd8217163..76b26fbd0 100644 --- a/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp +++ b/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp @@ -50,7 +50,7 @@ namespace GridKit int Resistor::tagDifferentiable() { // No internal variables, so these valeus do not matter - tag_.resize(size_, true); + std::fill(tag_.begin(), tag_.end(), true); return 0; } diff --git a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp index 5972a4530..5ec5b3b91 100644 --- a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp +++ b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp @@ -78,7 +78,7 @@ namespace GridKit int SynchronousMachine::tagDifferentiable() { // All variables are differentials - tag_.resize(size_, true); + std::fill(tag_.begin(), tag_.end(), true); return 0; } diff --git a/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp b/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp index 31695ad4b..8d48ce747 100644 --- a/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp +++ b/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp @@ -151,6 +151,8 @@ namespace GridKit abs_tol_.setToZero(memory::HOST); } + tag_.resize(size_); + { // Start node internal indexing after all component internals for proper KLU ordering size_t node_internal_idx = component_internal_size; for (node_type* node : nodes_) @@ -311,7 +313,7 @@ namespace GridKit } } - tag_.resize(size_, false); + std::fill(tag_.begin(), tag_.end(), false); size_t idx = 0; for (component_type* comp : components_) diff --git a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp index 38a4e6c1d..f4700e275 100644 --- a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp +++ b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp @@ -61,7 +61,7 @@ namespace GridKit int TransmissionLine::tagDifferentiable() { // All variables are algebraics - tag_.resize(size_, false); + std::fill(tag_.begin(), tag_.end(), false); return 0; } diff --git a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp index de1f8a8bd..52f021a5a 100644 --- a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp +++ b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp @@ -50,7 +50,7 @@ namespace GridKit int VoltageSource::tagDifferentiable() { // All variables are algebraics - tag_.resize(size_, false); + std::fill(tag_.begin(), tag_.end(), false); return 0; } From 74ff0c259e6d5303340c1927fc15bbf8927606f1 Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Mon, 24 Aug 2026 12:36:38 -0400 Subject: [PATCH 5/9] Reverse change to types of nnz_ and size_ --- .../PowerElectronics/CircuitComponent.hpp | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/GridKit/Model/PowerElectronics/CircuitComponent.hpp b/GridKit/Model/PowerElectronics/CircuitComponent.hpp index 816920e20..62e67dc84 100644 --- a/GridKit/Model/PowerElectronics/CircuitComponent.hpp +++ b/GridKit/Model/PowerElectronics/CircuitComponent.hpp @@ -128,16 +128,16 @@ namespace GridKit */ int allocate() override { - jacobian_coo_rows_ = std::make_unique(nnz_); - jacobian_coo_cols_ = std::make_unique(nnz_); - jacobian_coo_values_ = std::make_unique(nnz_); + jacobian_coo_rows_ = std::make_unique(static_cast(nnz_)); + jacobian_coo_cols_ = std::make_unique(static_cast(nnz_)); + jacobian_coo_values_ = std::make_unique(static_cast(nnz_)); - y_ext_ = std::make_unique(size_); - yp_ext_ = std::make_unique(size_); - f_ext_ = std::make_unique(size_); - connection_nodes_ = std::make_unique(size_); + y_ext_ = std::make_unique(static_cast(size_)); + yp_ext_ = std::make_unique(static_cast(size_)); + f_ext_ = std::make_unique(static_cast(size_)); + connection_nodes_ = std::make_unique(static_cast(size_)); - tag_.resize(size_); + tag_.resize(static_cast(size_)); if (!allocated_) { @@ -252,7 +252,7 @@ namespace GridKit { assert(rows.size() == cols.size()); assert(rows.size() == vals.size()); - assert(current_jac_size_ + rows.size() <= nnz_); + assert(current_jac_size_ + rows.size() <= static_cast(nnz_)); for (size_t i = 0; i < rows.size(); i++) { @@ -267,22 +267,22 @@ namespace GridKit public: IdxT size() final { - return static_cast(size_); + return size_; } IdxT size() const { - return static_cast(size_); + return size_; } IdxT nnz() final { - return static_cast(nnz_); + return nnz_; } IdxT nnz() const { - return static_cast(nnz_); + return nnz_; } IdxT sizeQuadrature() final @@ -493,11 +493,11 @@ namespace GridKit protected: /// The number of variables in this component. Should be equal to \ref n_extern_ plus \ref n_intern_. \see size() - IdxT size_{0}; + IdxT size_{0}; /// The number of nonzero elements in this component's Jacobian. \see nnz() - size_t nnz_{0}; - IdxT size_quad_{0}; - IdxT size_opt_{0}; + IdxT nnz_{0}; + IdxT size_quad_{0}; + IdxT size_opt_{0}; // COO Jacobian buffers std::unique_ptr jacobian_coo_rows_; From 2bd5c509b4d1fa7d8db7e1210e8686d7f5835ed3 Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Mon, 24 Aug 2026 12:37:09 -0400 Subject: [PATCH 6/9] Update Resistor tagDifferentiable() Resistor, like MicrogridBusDQ, doesn't have an internal variables, so does not need to set any tags in tagDifferentiable() --- GridKit/Model/PowerElectronics/Resistor/Resistor.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp b/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp index 76b26fbd0..8fba09a55 100644 --- a/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp +++ b/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp @@ -43,14 +43,10 @@ namespace GridKit return 0; } - /* - * \brief Identify differential variables - */ + /// There are no internal variables in this component, so \ref tag_ can be set arbitrarily. template int Resistor::tagDifferentiable() { - // No internal variables, so these valeus do not matter - std::fill(tag_.begin(), tag_.end(), true); return 0; } From d39217b724767368ede5f2fa8d132d55560db4e0 Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Mon, 24 Aug 2026 12:47:48 -0400 Subject: [PATCH 7/9] Document system `tagDifferentiable()` Also removed check that isn't necessary anymore due to tag_ being alllocated in allocate() --- .../SystemModelPowerElectronics.hpp | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp b/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp index 8d48ce747..9cf1ee5cb 100644 --- a/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp +++ b/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp @@ -295,35 +295,50 @@ namespace GridKit return CircuitComponent::initialize(); } + /** + * @brief Tags all system variables as differentiable, based on what the + * components that own those variables tag them as. + * + * Starts by asking all components to tag their differentiables. This implementation + * assumes all node variables are algebraic, and will not ask nodes to tag their differentiables. + * Sets all variables to algebraic (`false`) to start, then loops over all component internal variables. + * Re-creates the same internal variable to system variables mapping as in \ref allocate() - all + * internal variables from the same component are stored contiguously in a block, and blocks are + * stored contiguously in the same order as \ref components_, with node variables at the end. + * Each internal variable's tag in the system is set to its tag in the component. + */ int tagDifferentiable() final { + // Ask all component to tag their differentiables for (size_t i = 0; i < components_.size(); i++) { component_type* component = components_[i]; + // Bubble up errors if necessary if (int err = component->tagDifferentiable()) { return err; } - - if (component->tag().size() != component->size()) - { - GridKit::Utilities::Logger::error() << std::format("Component {} has an ill-configured tag(). Expected tags for {} variables, got {} instead.\n", i, component->size(), component->tag().size()); - return 1; - } } + // Fill tags with a default value (false) for node variables. Assumed to be algebraic here. std::fill(tag_.begin(), tag_.end(), false); + // Copy tags for internal variables from their components - going in the order as described above size_t idx = 0; for (component_type* comp : components_) { const auto& external_indices = comp->getExternIndices(); + + // Loop over all component variables - including externals for (IdxT i = 0; i < comp->size(); i++) { + // Discard externals if (!external_indices.contains(i)) { tag_[idx] = comp->tag()[i]; + + // Ensures internal variables are contiguous, and in the same order as the component idx++; } } From f1fb08c0bae8739940b692a69604c5f9f22570a2 Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Mon, 24 Aug 2026 12:52:29 -0400 Subject: [PATCH 8/9] Add more descrtiptive test output --- examples/PowerElectronics/Microgrid/Microgrid.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/PowerElectronics/Microgrid/Microgrid.cpp b/examples/PowerElectronics/Microgrid/Microgrid.cpp index ca94e575b..dfd71a7e1 100644 --- a/examples/PowerElectronics/Microgrid/Microgrid.cpp +++ b/examples/PowerElectronics/Microgrid/Microgrid.cpp @@ -228,23 +228,27 @@ int main(int /* argc */, char const** /* argv */) bool all_internal_diff = true; bool all_external_alg = true; - const size_t num_node_vars = 4 * 2 + 1; + const size_t num_node_vars = bus1.size() + bus2.size() + bus3.size() + bus4.size() + dg_signal.size(); for (size_t i = 0; i < sysmodel->size() - num_node_vars; i++) { all_internal_diff = all_internal_diff && sysmodel->tag()[i]; if (!sysmodel->tag()[i]) { - std::cout << "Broken on " << i << '\n'; + std::cout << "Unexepected algebraic-tagged internal variable found in index " << i << '\n'; } } for (size_t i = sysmodel->size() - num_node_vars; i < sysmodel->size(); i++) { all_external_alg = all_external_alg && !sysmodel->tag()[i]; + if (sysmodel->tag()[i]) + { + std::cout << "Unexepected differential-tagged external variable found in index " << i << '\n'; + } } - std::cout << "Verify all internal variables are differential: " << all_internal_diff << ", and all external variabels are algebraic: " << all_external_alg << '\n'; + std::cout << "Verify all internal variables are differential: " << all_internal_diff << ", and all external variables are algebraic: " << all_external_alg << '\n'; // Create numerical integrator and configure it for the generator model auto* idas = new AnalysisManager::Sundials::Ida(sysmodel); From 1efb19b4072432c9a9561024a2ca390174bb7f15 Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Mon, 24 Aug 2026 12:56:32 -0400 Subject: [PATCH 9/9] [skip ci] Remove unused includes --- GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp b/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp index 9cf1ee5cb..51c8dcee1 100644 --- a/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp +++ b/GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp @@ -4,7 +4,6 @@ #include #include -#include #include #include @@ -13,8 +12,6 @@ #include #include -#include "GridKit/Utilities/Logger/Logger.hpp" - namespace GridKit { template