From dbffe7de91fb1bf65b304f75ded4df1af04db9d9 Mon Sep 17 00:00:00 2001 From: abdourahmanbarry Date: Wed, 26 Aug 2026 07:23:30 +0000 Subject: [PATCH 1/8] Add clone implementations for microgrid components --- .../PowerElectronics/Capacitor/Capacitor.cpp | 31 +++ .../PowerElectronics/Capacitor/Capacitor.hpp | 11 +- .../PowerElectronics/CircuitComponent.hpp | 178 +++++++++++++++++- .../DistributedGenerator.cpp | 12 ++ .../DistributedGenerator.hpp | 25 +-- .../InductionMotor/InductionMotor.cpp | 31 +++ .../InductionMotor/InductionMotor.hpp | 11 +- .../PowerElectronics/Inductor/Inductor.cpp | 12 ++ .../PowerElectronics/Inductor/Inductor.hpp | 9 +- .../LinearTransformer/LinearTransformer.cpp | 31 +++ .../LinearTransformer/LinearTransformer.hpp | 11 +- .../MicrogridBusDQ/MicrogridBusDQ.cpp | 12 ++ .../MicrogridBusDQ/MicrogridBusDQ.hpp | 9 +- .../MicrogridLine/MicrogridLine.cpp | 12 ++ .../MicrogridLine/MicrogridLine.hpp | 9 +- .../MicrogridLoad/MicrogridLoad.cpp | 12 ++ .../MicrogridLoad/MicrogridLoad.hpp | 9 +- GridKit/Model/PowerElectronics/NodeBase.hpp | 27 +++ .../PowerElectronics/Resistor/Resistor.cpp | 12 ++ .../PowerElectronics/Resistor/Resistor.hpp | 9 +- .../SynchronousMachine/SynchronousMachine.cpp | 31 +++ .../SynchronousMachine/SynchronousMachine.hpp | 11 +- .../TransmissionLine/TransmissionLine.cpp | 31 +++ .../TransmissionLine/TransmissionLine.hpp | 11 +- .../VoltageSource/VoltageSource.cpp | 12 ++ .../VoltageSource/VoltageSource.hpp | 9 +- 26 files changed, 525 insertions(+), 53 deletions(-) diff --git a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp index 6c0b5fdf6..4381abc55 100644 --- a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp +++ b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp @@ -54,6 +54,25 @@ namespace GridKit return 0; } + /** + * @brief Compute the absolute tolerance for each variable in the model + * + * @param rel_tol The relative tolerance which can be used to pick the + * absolute tolerance. + * @tparam ScalarT Scalar data type + * @tparam IdxT Index data type + * @return int 0 if successful, non-zero otherwise. + * + * This represents a "noise" level close to zero for which pure relative + * error cannot be used. + */ + template + int Capacitor::setAbsoluteTolerance(RealT rel_tol) + { + abs_tol_.setToConst(static_cast(rel_tol)); + return 0; + } + /** * @brief Evaluate the resisdual of the Capcitor * @@ -119,6 +138,18 @@ namespace GridKit return 0; } + template + bool Capacitor::isCloneable() const + { + return true; + } + + template + CircuitComponent* Capacitor::clone() const + { + return new Capacitor(*this); + } + // Available template instantiations template class Capacitor; template class Capacitor; diff --git a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.hpp b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.hpp index d7a131a9a..0b3353c47 100644 --- a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.hpp +++ b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.hpp @@ -29,6 +29,7 @@ namespace GridKit using CircuitComponent::y_int_; using CircuitComponent::yp_ext_; using CircuitComponent::yp_int_; + using CircuitComponent::abs_tol_; using CircuitComponent::tag_; using CircuitComponent::f_ext_; using CircuitComponent::f_int_; @@ -50,15 +51,19 @@ namespace GridKit int initialize(); int tagDifferentiable(); + int setAbsoluteTolerance(RealT); int evaluateInternalResidual() final; int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int evaluateAdjointIntegrand(); + bool isCloneable() const; + + CircuitComponent* clone() const; private: RealT C_; diff --git a/GridKit/Model/PowerElectronics/CircuitComponent.hpp b/GridKit/Model/PowerElectronics/CircuitComponent.hpp index a033b46e7..f3a0a8d09 100644 --- a/GridKit/Model/PowerElectronics/CircuitComponent.hpp +++ b/GridKit/Model/PowerElectronics/CircuitComponent.hpp @@ -27,6 +27,138 @@ namespace GridKit CircuitComponent() = default; + CircuitComponent(const CircuitComponent& other) + : n_extern_(other.n_extern_), + n_intern_(other.n_intern_), + extern_indices_(other.extern_indices_), + size_(other.size_), + nnz_(other.nnz_), + size_quad_(other.size_quad_), + size_opt_(other.size_opt_), + current_jac_size_(other.current_jac_size_), + + // These pointers refer to storage supplied by a parent system. + // The copied component must be connected to its own storage later. + y_int_(nullptr), + yp_int_(nullptr), + f_int_(nullptr), + + tag_(other.tag_), + time_(other.time_), + alpha_(other.alpha_), + max_steps_(other.max_steps_), + idc_(other.idc_), + allocated_(other.allocated_) + { + /* + * VectorT disables its normal copy constructor and copy-assignment + * operator. Use its provided copyFromExternal() operation to perform + * an independent copy of the vector data. + */ + auto copyVector = [](VectorT& destination, const VectorT& source) + { + const IdxT source_size = source.getSize(); + + if (source_size == 0) + { + return; + } + + destination.resize(source_size); + destination.copyFromExternal(source); + }; + + /* + * Deep-copy the local-to-global connection mapping. + */ + if (other.connection_nodes_) + { + connection_nodes_ = std::make_unique(static_cast(size_)); + + for (size_t i = 0; i < static_cast(size_); ++i) + { + connection_nodes_[i] = other.connection_nodes_[i]; + } + } + + /* + * Deep-copy the COO Jacobian row indices. + */ + if (other.jacobian_coo_rows_) + { + jacobian_coo_rows_ = std::make_unique(static_cast(nnz_)); + + for (size_t i = 0; i < static_cast(nnz_); ++i) + { + jacobian_coo_rows_[i] = other.jacobian_coo_rows_[i]; + } + } + + /* + * Deep-copy the COO Jacobian column indices. + */ + if (other.jacobian_coo_cols_) + { + jacobian_coo_cols_ = std::make_unique(static_cast(nnz_)); + + for (size_t i = 0; i < static_cast(nnz_); ++i) + { + jacobian_coo_cols_[i] = other.jacobian_coo_cols_[i]; + } + } + + /* + * Deep-copy the COO Jacobian values. + */ + if (other.jacobian_coo_values_) + { + jacobian_coo_values_ = std::make_unique(static_cast(nnz_)); + + for (size_t i = 0; i < static_cast(nnz_); ++i) + { + jacobian_coo_values_[i] = other.jacobian_coo_values_[i]; + } + } + + if (size_ > 0) + { + y_ext_ = std::make_unique(static_cast(size_)); + yp_ext_ = std::make_unique(static_cast(size_)); + f_ext_ = std::make_unique(static_cast(size_)); + + for (size_t i = 0; i < static_cast(size_); ++i) + { + y_ext_[i] = nullptr; + yp_ext_[i] = nullptr; + f_ext_[i] = nullptr; + } + } + + // State, state derivative, residual, and absolute tolerance. + copyVector(y_, other.y_); + copyVector(yp_, other.yp_); + copyVector(f_, other.f_); + copyVector(abs_tol_, other.abs_tol_); + copyVector(g_, other.g_); + copyVector(yB_, other.yB_); + copyVector(ypB_, other.ypB_); + copyVector(fB_, other.fB_); + copyVector(gB_, other.gB_); + copyVector(param_, other.param_); + copyVector(param_up_, other.param_up_); + copyVector(param_lo_, other.param_lo_); + } + + virtual CircuitComponent* clone() const + { + return nullptr; + } + + virtual bool isCloneable() const + { + return false; + } + /** * @note Cannot be marked final, since it is overriden to recurse in the system model. */ @@ -51,7 +183,7 @@ namespace GridKit return this->n_intern_; } - std::set getExternIndices() + std::set getExternIndices() { return this->extern_indices_; } @@ -69,7 +201,7 @@ namespace GridKit int setInternalConnectionNodes(size_t local_index, IdxT global_index) { assert(!extern_indices_.contains(static_cast(local_index))); - connection_nodes_[local_index] = global_index; + setConnectionNodes(local_index, global_index); return 0; } @@ -88,10 +220,27 @@ namespace GridKit int setExternalConnectionNodes(size_t local_index, ExternalConnection connection) { assert(extern_indices_.contains(local_index)); - y_ext_[local_index] = connection.y_; - yp_ext_[local_index] = connection.yp_; - f_ext_[local_index] = connection.f_; - connection_nodes_[local_index] = connection.idx_; + y_ext_[local_index] = connection.y_; + yp_ext_[local_index] = connection.yp_; + f_ext_[local_index] = connection.f_; + setConnectionNodes(local_index, connection.idx_); + return 0; + } + + /** + * @brief Update the connection index for a variable. + * + * Sets only the connection index without modifying the variable's + * internal/external classification or its associated data pointers. + * + * @param local_index Index of the local variable. + * @param connection_index New connection index for the variable. + * + * @return int 0 if successful. + */ + int setConnectionNodes(size_t local_index, IdxT connection_index) + { + connection_nodes_[local_index] = connection_index; return 0; } @@ -132,9 +281,10 @@ namespace GridKit jacobian_coo_cols_ = std::make_unique(static_cast(nnz_)); jacobian_coo_values_ = std::make_unique(static_cast(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_)); + 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(static_cast(size_)); @@ -441,6 +591,16 @@ namespace GridKit return idc_; } + /** + * @brief Check whether the component has already been allocated. + * + * @return true if allocate() has previously completed, false otherwise. + */ + bool isAllocated() const + { + return allocated_; + } + protected: /** * @brief Allocate state and residual storage owned by this component. diff --git a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp index aa538933f..1cc86e989 100644 --- a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp +++ b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp @@ -422,6 +422,18 @@ namespace GridKit return 0; } + template + bool DistributedGenerator::isCloneable() const + { + return true; + } + + template + CircuitComponent* DistributedGenerator::clone() const + { + return new DistributedGenerator(*this); + } + // Available template instantiations template class DistributedGenerator; template class DistributedGenerator; diff --git a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp index ab7e340f1..8a5219848 100644 --- a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp +++ b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp @@ -75,18 +75,21 @@ namespace GridKit NodeT* node_bus); virtual ~DistributedGenerator(); - int initialize(); - int allocate() final; - int tagDifferentiable(); - int setAbsoluteTolerance(RealT); - int evaluateInternalResidual() final; - int evaluateExternalResidual() final; - int evaluateJacobian(); - int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initialize(); + int allocate() final; + int tagDifferentiable(); + int setAbsoluteTolerance(RealT); + int evaluateInternalResidual() final; + int evaluateExternalResidual() final; + int evaluateJacobian(); + int evaluateIntegrand(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int evaluateAdjointIntegrand(); + bool isCloneable() const; + + CircuitComponent* clone() const; private: RealT wb_; diff --git a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp index 74aabb549..d15913e72 100644 --- a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp +++ b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp @@ -65,6 +65,25 @@ namespace GridKit return 0; } + /** + * @brief Compute the absolute tolerance for each variable in the model + * + * @param rel_tol The relative tolerance which can be used to pick the + * absolute tolerance. + * @tparam ScalarT Scalar data type + * @tparam IdxT Index data type + * @return int 0 if successful, non-zero otherwise. + * + * This represents a "noise" level close to zero for which pure relative + * error cannot be used. + */ + template + int InductionMotor::setAbsoluteTolerance(RealT rel_tol) + { + abs_tol_.setToConst(static_cast(rel_tol)); + return 0; + } + /** * @brief Contributes to the resisdual * @@ -131,6 +150,18 @@ namespace GridKit return 0; } + template + bool InductionMotor::isCloneable() const + { + return true; + } + + template + CircuitComponent* InductionMotor::clone() const + { + return new InductionMotor(*this); + } + // Available template instantiations template class InductionMotor; template class InductionMotor; diff --git a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp index 122cd4d30..6f1724670 100644 --- a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp +++ b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp @@ -29,6 +29,7 @@ namespace GridKit using CircuitComponent::y_int_; using CircuitComponent::yp_ext_; using CircuitComponent::yp_int_; + using CircuitComponent::abs_tol_; using CircuitComponent::tag_; using CircuitComponent::f_ext_; using CircuitComponent::f_int_; @@ -50,15 +51,19 @@ namespace GridKit int initialize(); int tagDifferentiable(); + int setAbsoluteTolerance(RealT); int evaluateInternalResidual() final; int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int evaluateAdjointIntegrand(); + bool isCloneable() const; + + CircuitComponent* clone() const; private: RealT Lls_; diff --git a/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp b/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp index 0e6e7ea28..6e9969366 100644 --- a/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp +++ b/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp @@ -149,6 +149,18 @@ namespace GridKit return 0; } + template + bool Inductor::isCloneable() const + { + return true; + } + + template + CircuitComponent* Inductor::clone() const + { + return new Inductor(*this); + } + // Available template instantiations template class Inductor; template class Inductor; diff --git a/GridKit/Model/PowerElectronics/Inductor/Inductor.hpp b/GridKit/Model/PowerElectronics/Inductor/Inductor.hpp index b82ce1070..30d25db79 100644 --- a/GridKit/Model/PowerElectronics/Inductor/Inductor.hpp +++ b/GridKit/Model/PowerElectronics/Inductor/Inductor.hpp @@ -60,10 +60,13 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int evaluateAdjointIntegrand(); + bool isCloneable() const; + + CircuitComponent* clone() const; private: RealT L_; diff --git a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp index 455ef202f..864250abc 100644 --- a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp +++ b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp @@ -67,6 +67,25 @@ namespace GridKit return 0; } + /** + * @brief Compute the absolute tolerance for each variable in the model + * + * @param rel_tol The relative tolerance which can be used to pick the + * absolute tolerance. + * @tparam ScalarT Scalar data type + * @tparam IdxT Index data type + * @return int 0 if successful, non-zero otherwise. + * + * This represents a "noise" level close to zero for which pure relative + * error cannot be used. + */ + template + int LinearTransformer::setAbsoluteTolerance(RealT rel_tol) + { + abs_tol_.setToConst(static_cast(rel_tol)); + return 0; + } + /** * @brief Computes the component resisdual */ @@ -116,6 +135,18 @@ namespace GridKit return 0; } + template + bool LinearTransformer::isCloneable() const + { + return true; + } + + template + CircuitComponent* LinearTransformer::clone() const + { + return new LinearTransformer(*this); + } + // Available template instantiations template class LinearTransformer; template class LinearTransformer; diff --git a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp index 62dc84305..6b75dcc1d 100644 --- a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp +++ b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp @@ -29,6 +29,7 @@ namespace GridKit using CircuitComponent::y_int_; using CircuitComponent::yp_ext_; using CircuitComponent::yp_int_; + using CircuitComponent::abs_tol_; using CircuitComponent::tag_; using CircuitComponent::f_ext_; using CircuitComponent::f_int_; @@ -50,15 +51,19 @@ namespace GridKit int initialize(); int tagDifferentiable(); + int setAbsoluteTolerance(RealT); int evaluateInternalResidual() final; int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int evaluateAdjointIntegrand(); + bool isCloneable() const; + + CircuitComponent* clone() const; private: RealT L0_; diff --git a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp index 462c200f8..1fee11c4b 100644 --- a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -152,6 +152,18 @@ namespace GridKit return 0; } + template + bool MicrogridBusDQ::isCloneable() const + { + return true; + } + + template + CircuitComponent* MicrogridBusDQ::clone() const + { + return new MicrogridBusDQ(*this); + } + // Available template instantiations template class MicrogridBusDQ; template class MicrogridBusDQ; diff --git a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp index 111ca7be8..2314700a3 100644 --- a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp +++ b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp @@ -60,10 +60,13 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int evaluateAdjointIntegrand(); + bool isCloneable() const; + + CircuitComponent* clone() const; private: RealT RN_; diff --git a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp index efa5c2a36..7e5f993c4 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp @@ -184,6 +184,18 @@ namespace GridKit return 0; } + template + bool MicrogridLine::isCloneable() const + { + return true; + } + + template + CircuitComponent* MicrogridLine::clone() const + { + return new MicrogridLine(*this); + } + // Available template instantiations template class MicrogridLine; template class MicrogridLine; diff --git a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp index 1354a9d9b..041562cbb 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp +++ b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp @@ -60,10 +60,13 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int evaluateAdjointIntegrand(); + bool isCloneable() const; + + CircuitComponent* clone() const; private: RealT R_; diff --git a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp index 36ac6c375..9e6098d0f 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp @@ -175,6 +175,18 @@ namespace GridKit return 0; } + template + bool MicrogridLoad::isCloneable() const + { + return true; + } + + template + CircuitComponent* MicrogridLoad::clone() const + { + return new MicrogridLoad(*this); + } + // Available template instantiations template class MicrogridLoad; template class MicrogridLoad; diff --git a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp index 931983d50..6189e941c 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp +++ b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp @@ -60,10 +60,13 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int evaluateAdjointIntegrand(); + bool isCloneable() const; + + CircuitComponent* clone() const; private: RealT R_; diff --git a/GridKit/Model/PowerElectronics/NodeBase.hpp b/GridKit/Model/PowerElectronics/NodeBase.hpp index 077854b97..b39539781 100644 --- a/GridKit/Model/PowerElectronics/NodeBase.hpp +++ b/GridKit/Model/PowerElectronics/NodeBase.hpp @@ -136,6 +136,23 @@ namespace GridKit }; } + /** + * @brief Update the connection index for a variable. + * + * Changes only the connection index without modifying the variable's + * internal/external classification or its associated data pointers. + * + * @param local_index Index of the local variable. + * @param connection_index New connection index for the variable. + * + * @return int 0 if successful. + */ + int setConnectionNodes(size_t local_index, IdxT connection_index) + { + connection_nodes_[local_index] = connection_index; + return 0; + } + int allocate() override { size_t size = static_cast(n_intern_ + n_extern_); @@ -392,6 +409,16 @@ namespace GridKit return gB_; } + /** + * @brief Check whether the Node has already been allocated. + * + * @return true if allocate() has previously completed, false otherwise. + */ + bool isAllocated() const + { + return allocated_; + } + private: void allocateVectors(IdxT n) { diff --git a/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp b/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp index 8fba09a55..55caa4837 100644 --- a/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp +++ b/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp @@ -139,6 +139,18 @@ namespace GridKit return 0; } + template + bool Resistor::isCloneable() const + { + return true; + } + + template + CircuitComponent* Resistor::clone() const + { + return new Resistor(*this); + } + // Available template instantiations template class Resistor; template class Resistor; diff --git a/GridKit/Model/PowerElectronics/Resistor/Resistor.hpp b/GridKit/Model/PowerElectronics/Resistor/Resistor.hpp index 540ab4d20..19c90a190 100644 --- a/GridKit/Model/PowerElectronics/Resistor/Resistor.hpp +++ b/GridKit/Model/PowerElectronics/Resistor/Resistor.hpp @@ -60,10 +60,13 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int evaluateAdjointIntegrand(); + bool isCloneable() const; + + CircuitComponent* clone() const; private: RealT R_; diff --git a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp index 5ec5b3b91..408bf241c 100644 --- a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp +++ b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp @@ -82,6 +82,25 @@ namespace GridKit return 0; } + /** + * @brief Compute the absolute tolerance for each variable in the model + * + * @param rel_tol The relative tolerance which can be used to pick the + * absolute tolerance. + * @tparam ScalarT Scalar data type + * @tparam IdxT Index data type + * @return int 0 if successful, non-zero otherwise. + * + * This represents a "noise" level close to zero for which pure relative + * error cannot be used. + */ + template + int SynchronousMachine::setAbsoluteTolerance(RealT rel_tol) + { + abs_tol_.setToConst(static_cast(rel_tol)); + return 0; + } + /** * @brief Compute the resisdual of the component. * @@ -165,6 +184,18 @@ namespace GridKit return 0; } + template + bool SynchronousMachine::isCloneable() const + { + return true; + } + + template + CircuitComponent* SynchronousMachine::clone() const + { + return new SynchronousMachine(*this); + } + // Available template instantiations template class SynchronousMachine; template class SynchronousMachine; diff --git a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp index 80b68eed2..7cf040583 100644 --- a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp +++ b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp @@ -31,6 +31,7 @@ namespace GridKit using CircuitComponent::y_int_; using CircuitComponent::yp_ext_; using CircuitComponent::yp_int_; + using CircuitComponent::abs_tol_; using CircuitComponent::tag_; using CircuitComponent::f_ext_; using CircuitComponent::f_int_; @@ -52,15 +53,19 @@ namespace GridKit int initialize(); int tagDifferentiable(); + int setAbsoluteTolerance(RealT); int evaluateInternalResidual() final; int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int evaluateAdjointIntegrand(); + bool isCloneable() const; + + CircuitComponent* clone() const; private: RealT Lls_; diff --git a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp index f4700e275..cfefa499f 100644 --- a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp +++ b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp @@ -65,6 +65,25 @@ namespace GridKit return 0; } + /** + * @brief Compute the absolute tolerance for each variable in the model + * + * @param rel_tol The relative tolerance which can be used to pick the + * absolute tolerance. + * @tparam ScalarT Scalar data type + * @tparam IdxT Index data type + * @return int 0 if successful, non-zero otherwise. + * + * This represents a "noise" level close to zero for which pure relative + * error cannot be used. + */ + template + int TransmissionLine::setAbsoluteTolerance(RealT rel_tol) + { + abs_tol_.setToConst(static_cast(rel_tol)); + return 0; + } + /** * @brief Evaluate residual of transmission line * @@ -186,6 +205,18 @@ namespace GridKit return 0; } + template + bool TransmissionLine::isCloneable() const + { + return true; + } + + template + CircuitComponent* TransmissionLine::clone() const + { + return new TransmissionLine(*this); + } + // Available template instantiations template class TransmissionLine; template class TransmissionLine; diff --git a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp index 091984c89..c9743e9dd 100644 --- a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp +++ b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp @@ -33,6 +33,7 @@ namespace GridKit using CircuitComponent::y_int_; using CircuitComponent::yp_ext_; using CircuitComponent::yp_int_; + using CircuitComponent::abs_tol_; using CircuitComponent::tag_; using CircuitComponent::f_ext_; using CircuitComponent::f_int_; @@ -54,15 +55,19 @@ namespace GridKit int initialize(); int tagDifferentiable(); + int setAbsoluteTolerance(RealT); int evaluateInternalResidual() final; int evaluateExternalResidual() final; int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int evaluateAdjointIntegrand(); + bool isCloneable() const; + + CircuitComponent* clone() const; private: RealT R_; diff --git a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp index 52f021a5a..3ac673129 100644 --- a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp +++ b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp @@ -142,6 +142,18 @@ namespace GridKit return 0; } + template + bool VoltageSource::isCloneable() const + { + return true; + } + + template + CircuitComponent* VoltageSource::clone() const + { + return new VoltageSource(*this); + } + // Available template instantiations template class VoltageSource; template class VoltageSource; diff --git a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.hpp b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.hpp index 814fa5ec5..ab9125f40 100644 --- a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.hpp +++ b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.hpp @@ -60,10 +60,13 @@ namespace GridKit int evaluateJacobian() final; int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); + int evaluateAdjointIntegrand(); + bool isCloneable() const; + + CircuitComponent* clone() const; private: RealT V_; From 6efbe170efed5e26f3820e9d08ccd0ffe19c33e1 Mon Sep 17 00:00:00 2001 From: abdourahmanbarry Date: Wed, 26 Aug 2026 07:24:45 +0000 Subject: [PATCH 2/8] Add tests for component cloning --- .../UnitTests/PowerElectronics/CMakeLists.txt | 11 + .../PowerElectronics/ComponentCloneTests.hpp | 263 ++++++++++++++++++ .../runComponentCloneTests.cpp | 15 + 3 files changed, 289 insertions(+) create mode 100644 tests/UnitTests/PowerElectronics/ComponentCloneTests.hpp create mode 100644 tests/UnitTests/PowerElectronics/runComponentCloneTests.cpp diff --git a/tests/UnitTests/PowerElectronics/CMakeLists.txt b/tests/UnitTests/PowerElectronics/CMakeLists.txt index 74d50eb1e..55a0ff790 100644 --- a/tests/UnitTests/PowerElectronics/CMakeLists.txt +++ b/tests/UnitTests/PowerElectronics/CMakeLists.txt @@ -3,6 +3,17 @@ target_link_libraries( test_power_electronics_node PRIVATE GridKit::power_electronics_circuit_node GridKit::testing) +add_executable(test_power_electronics_component_clone runComponentCloneTests.cpp) +target_link_libraries( + test_power_electronics_component_clone + PRIVATE GridKit::power_elec_disgen + GridKit::power_elec_microline + GridKit::power_elec_microload + GridKit::power_elec_microbusdq + GridKit::testing) + add_test(NAME PowerElectronicsNodeTest COMMAND $) +add_test(NAME PowerElectronicsComponentCloneTest COMMAND $) install(TARGETS test_power_electronics_node RUNTIME DESTINATION bin) +install(TARGETS test_power_electronics_component_clone RUNTIME DESTINATION bin) diff --git a/tests/UnitTests/PowerElectronics/ComponentCloneTests.hpp b/tests/UnitTests/PowerElectronics/ComponentCloneTests.hpp new file mode 100644 index 000000000..5124442d8 --- /dev/null +++ b/tests/UnitTests/PowerElectronics/ComponentCloneTests.hpp @@ -0,0 +1,263 @@ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace GridKit +{ + template + bool verifyComponentClone(ComponentT& component) + { + using RealT = typename CircuitComponent::RealT; + + bool success = true; + + auto* clone = dynamic_cast(component.clone()); + + if (clone == nullptr) + { + return false; + } + + /************************************************************************** + * Verify the Clone Initially Matches the Original + **************************************************************************/ + + success &= clone != &component; + success &= clone->size() == component.size(); + success &= clone->nnz() == component.nnz(); + success &= clone->getInternalSize() == component.getInternalSize(); + success &= clone->getExternSize() == component.getExternSize(); + success &= clone->getExternIndices() == component.getExternIndices(); + success &= clone->getIDcomponent() == component.getIDcomponent(); + + /************************************************************************** + * Verify Connection Independence + **************************************************************************/ + + for (IdxT i = 0; i < component.size(); ++i) + { + const IdxT connection = component.getNodeConnection(i); + + success &= clone->getNodeConnection(i) == connection; + + clone->setConnectionNodes(i, connection + 1); + + success &= component.getNodeConnection(i) == connection; + success &= clone->getNodeConnection(i) == connection + 1; + + clone->setConnectionNodes(i, connection); + } + + /************************************************************************** + * Verify State Independence + **************************************************************************/ + + auto checkVectorIndependence = [&success](auto& original, auto& copy) + { + success &= original.getSize() == copy.getSize(); + + if (original.getSize() == 0) + { + return; + } + + auto* original_data = original.getData(); + auto* copy_data = copy.getData(); + + success &= original_data != copy_data; + + const auto original_value = original_data[0]; + + copy_data[0] = original_value + 1.0; + + success &= original_data[0] == original_value; + success &= copy_data[0] == original_value + 1.0; + + copy_data[0] = original_value; + }; + + checkVectorIndependence(component.y(), clone->y()); + checkVectorIndependence(component.yp(), clone->yp()); + checkVectorIndependence(component.getResidual(), clone->getResidual()); + checkVectorIndependence(component.absoluteTolerance(), clone->absoluteTolerance()); + checkVectorIndependence(component.param(), clone->param()); + + /************************************************************************** + * Verify Jacobian Independence + **************************************************************************/ + + if (component.nnz() > 0) + { + auto* original_rows = component.jacobianCooRows(); + auto* original_cols = component.jacobianCooCols(); + auto* original_values = component.jacobianCooValues(); + + auto* clone_rows = clone->jacobianCooRows(); + auto* clone_cols = clone->jacobianCooCols(); + auto* clone_values = clone->jacobianCooValues(); + + success &= clone_rows != original_rows; + success &= clone_cols != original_cols; + success &= clone_values != original_values; + + for (IdxT i = 0; i < component.nnz(); ++i) + { + success &= clone_rows[i] == original_rows[i]; + success &= clone_cols[i] == original_cols[i]; + success &= clone_values[i] == original_values[i]; + } + + const IdxT original_row = original_rows[0]; + const IdxT original_col = original_cols[0]; + const RealT original_value = original_values[0]; + + clone_rows[0] = original_row + 1; + clone_cols[0] = original_col + 1; + clone_values[0] = original_value + 1.0; + + success &= original_rows[0] == original_row; + success &= original_cols[0] == original_col; + success &= original_values[0] == original_value; + + clone_rows[0] = original_row; + clone_cols[0] = original_col; + clone_values[0] = original_value; + } + + delete clone; + + return success; + } + + namespace Testing + { + template + class CircuitComponentCloneTests + { + using SignalNode = PowerElectronics::SignalNode; + using Bus = PowerElectronics::MicrogridBus; + using BusDQ = MicrogridBusDQ; + using Generator = DistributedGenerator; + using GeneratorParameters = DistributedGeneratorParameters; + using Line = MicrogridLine; + using Load = MicrogridLoad; + + public: + CircuitComponentCloneTests() + { + /************************************************************************** + * Construct Network Nodes + **************************************************************************/ + + signal_.allocate(); + + bus1_.allocate(); + bus2_.allocate(); + + /************************************************************************** + * Distributed Generator Parameters + **************************************************************************/ + + generator_parameters_.wb_ = 2.0 * M_PI * 50.0; + generator_parameters_.wc_ = 31.41; + generator_parameters_.mp_ = 9.4e-5; + generator_parameters_.Vn_ = 380.0; + generator_parameters_.nq_ = 1.3e-3; + generator_parameters_.F_ = 0.75; + generator_parameters_.Kiv_ = 420.0; + generator_parameters_.Kpv_ = 0.1; + generator_parameters_.Kic_ = 2.0e4; + generator_parameters_.Kpc_ = 15.0; + generator_parameters_.Cf_ = 5.0e-5; + generator_parameters_.rLf_ = 0.1; + generator_parameters_.Lf_ = 1.35e-3; + generator_parameters_.rLc_ = 0.03; + generator_parameters_.Lc_ = 0.35e-3; + + /************************************************************************** + * Construct Components + **************************************************************************/ + + generator_ = new Generator(1, generator_parameters_, true, &signal_, &bus1_); + + line_ = new Line(2, 0.23, 0.1 / (2.0 * M_PI * 50.0), &signal_, &bus1_, &bus2_); + + load_ = new Load(3, 3.0, 2.0 / (2.0 * M_PI * 50.0), &signal_, &bus1_); + + bus_dq_ = new BusDQ(4, 1.0e4, &bus1_); + + /************************************************************************** + * Allocate Components + **************************************************************************/ + + generator_->allocate(); + line_->allocate(); + load_->allocate(); + bus_dq_->allocate(); + } + + ~CircuitComponentCloneTests() + { + delete generator_; + delete line_; + delete load_; + delete bus_dq_; + } + + TestOutcome distributedGeneratorClone() + { + TestStatus success = true; + + success *= verifyComponentClone(*generator_); + + return success.report(__func__); + } + + TestOutcome microgridLineClone() + { + TestStatus success = true; + + success *= verifyComponentClone(*line_); + + return success.report(__func__); + } + + TestOutcome microgridLoadClone() + { + TestStatus success = true; + + success *= verifyComponentClone(*load_); + + return success.report(__func__); + } + + TestOutcome microgridBusDQClone() + { + TestStatus success = true; + + success *= verifyComponentClone(*bus_dq_); + + return success.report(__func__); + } + + private: + SignalNode signal_; + + Bus bus1_; + Bus bus2_; + + GeneratorParameters generator_parameters_; + + Generator* generator_{nullptr}; + Line* line_{nullptr}; + Load* load_{nullptr}; + BusDQ* bus_dq_{nullptr}; + }; + } // namespace Testing +} // namespace GridKit diff --git a/tests/UnitTests/PowerElectronics/runComponentCloneTests.cpp b/tests/UnitTests/PowerElectronics/runComponentCloneTests.cpp new file mode 100644 index 000000000..dfb5fa97f --- /dev/null +++ b/tests/UnitTests/PowerElectronics/runComponentCloneTests.cpp @@ -0,0 +1,15 @@ +#include "ComponentCloneTests.hpp" + +int main() +{ + GridKit::Testing::CircuitComponentCloneTests tests; + + GridKit::Testing::TestingResults result; + + result += tests.distributedGeneratorClone(); + result += tests.microgridLineClone(); + result += tests.microgridLoadClone(); + result += tests.microgridBusDQClone(); + + return result.summary(); +} From 0265482f5bb86eaa9b314555b0dab05dac2a5120 Mon Sep 17 00:00:00 2001 From: abdourahmanbarry Date: Thu, 3 Sep 2026 03:28:28 +0000 Subject: [PATCH 3/8] Add more comments --- .../PowerElectronics/CircuitComponent.hpp | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/GridKit/Model/PowerElectronics/CircuitComponent.hpp b/GridKit/Model/PowerElectronics/CircuitComponent.hpp index f3a0a8d09..cb06b8fe1 100644 --- a/GridKit/Model/PowerElectronics/CircuitComponent.hpp +++ b/GridKit/Model/PowerElectronics/CircuitComponent.hpp @@ -50,11 +50,7 @@ namespace GridKit idc_(other.idc_), allocated_(other.allocated_) { - /* - * VectorT disables its normal copy constructor and copy-assignment - * operator. Use its provided copyFromExternal() operation to perform - * an independent copy of the vector data. - */ + auto copyVector = [](VectorT& destination, const VectorT& source) { const IdxT source_size = source.getSize(); @@ -149,11 +145,30 @@ namespace GridKit copyVector(param_lo_, other.param_lo_); } + /** + * @brief Create an independent copy of this component. + * + * The clone preserves the component's model configuration, parameters, + * topology, and structural data, but does not preserve bindings to + * system-owned state or residual storage. + * + * @note By default, the cloned component's state, state-derivative, and + * residual pointers are not set. The user is responsible for setting these + * pointers to the appropriate storage before evaluating the residual. + */ virtual CircuitComponent* clone() const { return nullptr; } + /** + * @brief Indicates whether this component supports cloning. + * + * Derived components that implement clone() should override this method + * and return true. + * + * @return true if the component can be cloned, false otherwise. + */ virtual bool isCloneable() const { return false; From f2da54c99bebd786d5b65e952368f1b0062b96f5 Mon Sep 17 00:00:00 2001 From: abdourahmanbarry Date: Thu, 3 Sep 2026 17:44:32 +0000 Subject: [PATCH 4/8] Apply pre-commit fixes --- tests/UnitTests/PowerElectronics/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/UnitTests/PowerElectronics/CMakeLists.txt b/tests/UnitTests/PowerElectronics/CMakeLists.txt index 55a0ff790..94cd4fd91 100644 --- a/tests/UnitTests/PowerElectronics/CMakeLists.txt +++ b/tests/UnitTests/PowerElectronics/CMakeLists.txt @@ -13,7 +13,8 @@ target_link_libraries( GridKit::testing) add_test(NAME PowerElectronicsNodeTest COMMAND $) -add_test(NAME PowerElectronicsComponentCloneTest COMMAND $) +add_test(NAME PowerElectronicsComponentCloneTest + COMMAND $) install(TARGETS test_power_electronics_node RUNTIME DESTINATION bin) install(TARGETS test_power_electronics_component_clone RUNTIME DESTINATION bin) From 80a574f0a8234f8ee0ed76a41226f661599d7794 Mon Sep 17 00:00:00 2001 From: abdourahmanbarry Date: Fri, 4 Sep 2026 19:45:59 +0000 Subject: [PATCH 5/8] Update ComponentCloneTest --- .../PowerElectronics/ComponentCloneTests.hpp | 258 +++++++++--------- 1 file changed, 129 insertions(+), 129 deletions(-) diff --git a/tests/UnitTests/PowerElectronics/ComponentCloneTests.hpp b/tests/UnitTests/PowerElectronics/ComponentCloneTests.hpp index 5124442d8..77ea9a623 100644 --- a/tests/UnitTests/PowerElectronics/ComponentCloneTests.hpp +++ b/tests/UnitTests/PowerElectronics/ComponentCloneTests.hpp @@ -10,131 +10,6 @@ namespace GridKit { - template - bool verifyComponentClone(ComponentT& component) - { - using RealT = typename CircuitComponent::RealT; - - bool success = true; - - auto* clone = dynamic_cast(component.clone()); - - if (clone == nullptr) - { - return false; - } - - /************************************************************************** - * Verify the Clone Initially Matches the Original - **************************************************************************/ - - success &= clone != &component; - success &= clone->size() == component.size(); - success &= clone->nnz() == component.nnz(); - success &= clone->getInternalSize() == component.getInternalSize(); - success &= clone->getExternSize() == component.getExternSize(); - success &= clone->getExternIndices() == component.getExternIndices(); - success &= clone->getIDcomponent() == component.getIDcomponent(); - - /************************************************************************** - * Verify Connection Independence - **************************************************************************/ - - for (IdxT i = 0; i < component.size(); ++i) - { - const IdxT connection = component.getNodeConnection(i); - - success &= clone->getNodeConnection(i) == connection; - - clone->setConnectionNodes(i, connection + 1); - - success &= component.getNodeConnection(i) == connection; - success &= clone->getNodeConnection(i) == connection + 1; - - clone->setConnectionNodes(i, connection); - } - - /************************************************************************** - * Verify State Independence - **************************************************************************/ - - auto checkVectorIndependence = [&success](auto& original, auto& copy) - { - success &= original.getSize() == copy.getSize(); - - if (original.getSize() == 0) - { - return; - } - - auto* original_data = original.getData(); - auto* copy_data = copy.getData(); - - success &= original_data != copy_data; - - const auto original_value = original_data[0]; - - copy_data[0] = original_value + 1.0; - - success &= original_data[0] == original_value; - success &= copy_data[0] == original_value + 1.0; - - copy_data[0] = original_value; - }; - - checkVectorIndependence(component.y(), clone->y()); - checkVectorIndependence(component.yp(), clone->yp()); - checkVectorIndependence(component.getResidual(), clone->getResidual()); - checkVectorIndependence(component.absoluteTolerance(), clone->absoluteTolerance()); - checkVectorIndependence(component.param(), clone->param()); - - /************************************************************************** - * Verify Jacobian Independence - **************************************************************************/ - - if (component.nnz() > 0) - { - auto* original_rows = component.jacobianCooRows(); - auto* original_cols = component.jacobianCooCols(); - auto* original_values = component.jacobianCooValues(); - - auto* clone_rows = clone->jacobianCooRows(); - auto* clone_cols = clone->jacobianCooCols(); - auto* clone_values = clone->jacobianCooValues(); - - success &= clone_rows != original_rows; - success &= clone_cols != original_cols; - success &= clone_values != original_values; - - for (IdxT i = 0; i < component.nnz(); ++i) - { - success &= clone_rows[i] == original_rows[i]; - success &= clone_cols[i] == original_cols[i]; - success &= clone_values[i] == original_values[i]; - } - - const IdxT original_row = original_rows[0]; - const IdxT original_col = original_cols[0]; - const RealT original_value = original_values[0]; - - clone_rows[0] = original_row + 1; - clone_cols[0] = original_col + 1; - clone_values[0] = original_value + 1.0; - - success &= original_rows[0] == original_row; - success &= original_cols[0] == original_col; - success &= original_values[0] == original_value; - - clone_rows[0] = original_row; - clone_cols[0] = original_col; - clone_values[0] = original_value; - } - - delete clone; - - return success; - } - namespace Testing { template @@ -214,7 +89,7 @@ namespace GridKit { TestStatus success = true; - success *= verifyComponentClone(*generator_); + success *= verifyComponentClone(*generator_); return success.report(__func__); } @@ -223,7 +98,7 @@ namespace GridKit { TestStatus success = true; - success *= verifyComponentClone(*line_); + success *= verifyComponentClone(*line_); return success.report(__func__); } @@ -232,7 +107,7 @@ namespace GridKit { TestStatus success = true; - success *= verifyComponentClone(*load_); + success *= verifyComponentClone(*load_); return success.report(__func__); } @@ -241,12 +116,137 @@ namespace GridKit { TestStatus success = true; - success *= verifyComponentClone(*bus_dq_); + success *= verifyComponentClone(*bus_dq_); return success.report(__func__); } private: + template + bool verifyComponentClone(ComponentT& component) + { + using RealT = typename CircuitComponent::RealT; + + bool success = true; + + auto* clone = dynamic_cast(component.clone()); + + if (clone == nullptr) + { + return false; + } + + /************************************************************************** + * Verify the Clone Initially Matches the Original + **************************************************************************/ + + success &= clone != &component; + success &= clone->size() == component.size(); + success &= clone->nnz() == component.nnz(); + success &= clone->getInternalSize() == component.getInternalSize(); + success &= clone->getExternSize() == component.getExternSize(); + success &= clone->getExternIndices() == component.getExternIndices(); + success &= clone->getIDcomponent() == component.getIDcomponent(); + + /************************************************************************** + * Verify Connection Independence + **************************************************************************/ + + for (IdxT i = 0; i < component.size(); ++i) + { + const IdxT connection = component.getNodeConnection(i); + + success &= clone->getNodeConnection(i) == connection; + + clone->setConnectionNodes(i, connection + 1); + + success &= component.getNodeConnection(i) == connection; + success &= clone->getNodeConnection(i) == connection + 1; + + clone->setConnectionNodes(i, connection); + } + + /************************************************************************** + * Verify State Independence + **************************************************************************/ + + auto checkVectorIndependence = [&success](auto& original, auto& copy) + { + success &= original.getSize() == copy.getSize(); + + if (original.getSize() == 0) + { + return; + } + + auto* original_data = original.getData(); + auto* copy_data = copy.getData(); + + success &= original_data != copy_data; + + const auto original_value = original_data[0]; + + copy_data[0] = original_value + 1.0; + + success &= original_data[0] == original_value; + success &= copy_data[0] == original_value + 1.0; + + copy_data[0] = original_value; + }; + + checkVectorIndependence(component.y(), clone->y()); + checkVectorIndependence(component.yp(), clone->yp()); + checkVectorIndependence(component.getResidual(), clone->getResidual()); + checkVectorIndependence(component.absoluteTolerance(), clone->absoluteTolerance()); + checkVectorIndependence(component.param(), clone->param()); + + /************************************************************************** + * Verify Jacobian Independence + **************************************************************************/ + + if (component.nnz() > 0) + { + auto* original_rows = component.jacobianCooRows(); + auto* original_cols = component.jacobianCooCols(); + auto* original_values = component.jacobianCooValues(); + + auto* clone_rows = clone->jacobianCooRows(); + auto* clone_cols = clone->jacobianCooCols(); + auto* clone_values = clone->jacobianCooValues(); + + success &= clone_rows != original_rows; + success &= clone_cols != original_cols; + success &= clone_values != original_values; + + for (IdxT i = 0; i < component.nnz(); ++i) + { + success &= clone_rows[i] == original_rows[i]; + success &= clone_cols[i] == original_cols[i]; + success &= clone_values[i] == original_values[i]; + } + + const IdxT original_row = original_rows[0]; + const IdxT original_col = original_cols[0]; + const RealT original_value = original_values[0]; + + clone_rows[0] = original_row + 1; + clone_cols[0] = original_col + 1; + clone_values[0] = original_value + 1.0; + + success &= original_rows[0] == original_row; + success &= original_cols[0] == original_col; + success &= original_values[0] == original_value; + + clone_rows[0] = original_row; + clone_cols[0] = original_col; + clone_values[0] = original_value; + } + + delete clone; + + return success; + } + SignalNode signal_; Bus bus1_; From a9de6dd5e5265d69196ca5f1c6c7cf1e42dc73a2 Mon Sep 17 00:00:00 2001 From: abdourahmanbarry Date: Fri, 4 Sep 2026 19:46:52 +0000 Subject: [PATCH 6/8] Document copy constructor in CircuitComponnet.hpp --- .../PowerElectronics/CircuitComponent.hpp | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/GridKit/Model/PowerElectronics/CircuitComponent.hpp b/GridKit/Model/PowerElectronics/CircuitComponent.hpp index cb06b8fe1..7ddf3bd5a 100644 --- a/GridKit/Model/PowerElectronics/CircuitComponent.hpp +++ b/GridKit/Model/PowerElectronics/CircuitComponent.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -27,6 +28,31 @@ namespace GridKit CircuitComponent() = default; + /** + * @brief Constructs an independent copy of a circuit component. + * + * Copies the component metadata, local vector data, connection-node mapping, + * and COO Jacobian storage. Dynamically allocated component-owned data is + * deep-copied so that the new component does not share ownership of this + * storage with @p other. + * + * Pointers to state, state-derivative, and residual storage supplied by a + * parent system are intentionally not copied. The internal pointers + * (`y_int_`, `yp_int_`, and `f_int_`) are initialized to `nullptr`, and the + * external variable pointers (`y_ext_`, `yp_ext_`, and `f_ext_`) are allocated + * but initialized to `nullptr`. The copied component must therefore be + * connected to the appropriate parent-system storage before it is evaluated. + * + * Local vectors, including the state, state derivative, residual, tolerances, + * quadrature data, adjoint data, and parameter vectors, retain the values of + * the original component. + * + * @param other Component to copy. + * + * @note Copying a component reproduces its component-owned data and structural + * information, but does not preserve its connections to parent-system + * state or residual storage. + */ CircuitComponent(const CircuitComponent& other) : n_extern_(other.n_extern_), n_intern_(other.n_intern_), @@ -158,7 +184,7 @@ namespace GridKit */ virtual CircuitComponent* clone() const { - return nullptr; + throw std::runtime_error("clone() is not supported for this component."); } /** From c5138c1624171923a3ff90f9f54c5a6ee9ab2197 Mon Sep 17 00:00:00 2001 From: abdourahmanbarry Date: Fri, 4 Sep 2026 20:43:04 +0000 Subject: [PATCH 7/8] Update comments --- .../PowerElectronics/CircuitComponent.hpp | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/GridKit/Model/PowerElectronics/CircuitComponent.hpp b/GridKit/Model/PowerElectronics/CircuitComponent.hpp index 7ddf3bd5a..f402d743f 100644 --- a/GridKit/Model/PowerElectronics/CircuitComponent.hpp +++ b/GridKit/Model/PowerElectronics/CircuitComponent.hpp @@ -29,7 +29,7 @@ namespace GridKit CircuitComponent() = default; /** - * @brief Constructs an independent copy of a circuit component. + * @brief Constructs a copy of a circuit component. * * Copies the component metadata, local vector data, connection-node mapping, * and COO Jacobian storage. Dynamically allocated component-owned data is @@ -37,11 +37,11 @@ namespace GridKit * storage with @p other. * * Pointers to state, state-derivative, and residual storage supplied by a - * parent system are intentionally not copied. The internal pointers - * (`y_int_`, `yp_int_`, and `f_int_`) are initialized to `nullptr`, and the - * external variable pointers (`y_ext_`, `yp_ext_`, and `f_ext_`) are allocated - * but initialized to `nullptr`. The copied component must therefore be - * connected to the appropriate parent-system storage before it is evaluated. + * parent system are copied as-is. Consequently, the copied component initially + * references the same parent-system storage as @p other. The pointer arrays + * used for external variables are independently allocated, but their entries + * point to the same external state, state-derivative, and residual storage as + * the original component. * * Local vectors, including the state, state derivative, residual, tolerances, * quadrature data, adjoint data, and parameter vectors, retain the values of @@ -49,9 +49,9 @@ namespace GridKit * * @param other Component to copy. * - * @note Copying a component reproduces its component-owned data and structural - * information, but does not preserve its connections to parent-system - * state or residual storage. + * @note If the copied component is subsequently attached to a different parent + * system, its state, state-derivative, and residual pointers must be + * reassigned to the storage provided by that system before evaluation. */ CircuitComponent(const CircuitComponent& other) : n_extern_(other.n_extern_), @@ -62,13 +62,9 @@ namespace GridKit size_quad_(other.size_quad_), size_opt_(other.size_opt_), current_jac_size_(other.current_jac_size_), - - // These pointers refer to storage supplied by a parent system. - // The copied component must be connected to its own storage later. - y_int_(nullptr), - yp_int_(nullptr), - f_int_(nullptr), - + y_int_(other.y_int_), + yp_int_(other.yp_int_), + f_int_(other.f_int_), tag_(other.tag_), time_(other.time_), alpha_(other.alpha_), @@ -150,9 +146,9 @@ namespace GridKit for (size_t i = 0; i < static_cast(size_); ++i) { - y_ext_[i] = nullptr; - yp_ext_[i] = nullptr; - f_ext_[i] = nullptr; + y_ext_[i] = other.y_ext_[i]; + yp_ext_[i] = other.yp_ext_[i]; + f_ext_[i] = other.f_ext_[i]; } } From 9aae154b9b338de67669600869eddd34bed9360c Mon Sep 17 00:00:00 2001 From: abdourahmanbarry Date: Tue, 8 Sep 2026 15:45:23 +0000 Subject: [PATCH 8/8] Remove isCloneable method from PowerElectronics components --- .../PowerElectronics/Capacitor/Capacitor.cpp | 6 ----- .../PowerElectronics/Capacitor/Capacitor.hpp | 7 +++--- .../PowerElectronics/CircuitComponent.hpp | 3 ++- .../DistributedGenerator.cpp | 6 ----- .../DistributedGenerator.hpp | 23 +++++++++---------- .../InductionMotor/InductionMotor.cpp | 6 ----- .../InductionMotor/InductionMotor.hpp | 7 +++--- .../PowerElectronics/Inductor/Inductor.cpp | 6 ----- .../PowerElectronics/Inductor/Inductor.hpp | 7 +++--- .../LinearTransformer/LinearTransformer.cpp | 6 ----- .../LinearTransformer/LinearTransformer.hpp | 7 +++--- .../MicrogridBusDQ/MicrogridBusDQ.cpp | 6 ----- .../MicrogridBusDQ/MicrogridBusDQ.hpp | 7 +++--- .../MicrogridLine/MicrogridLine.cpp | 6 ----- .../MicrogridLine/MicrogridLine.hpp | 7 +++--- .../MicrogridLoad/MicrogridLoad.cpp | 6 ----- .../MicrogridLoad/MicrogridLoad.hpp | 7 +++--- .../PowerElectronics/Resistor/Resistor.cpp | 6 ----- .../PowerElectronics/Resistor/Resistor.hpp | 7 +++--- .../SynchronousMachine/SynchronousMachine.cpp | 6 ----- .../SynchronousMachine/SynchronousMachine.hpp | 7 +++--- .../TransmissionLine/TransmissionLine.cpp | 6 ----- .../TransmissionLine/TransmissionLine.hpp | 7 +++--- .../VoltageSource/VoltageSource.cpp | 6 ----- .../VoltageSource/VoltageSource.hpp | 7 +++--- 25 files changed, 46 insertions(+), 129 deletions(-) diff --git a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp index 4381abc55..7d53e309f 100644 --- a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp +++ b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp @@ -138,12 +138,6 @@ namespace GridKit return 0; } - template - bool Capacitor::isCloneable() const - { - return true; - } - template CircuitComponent* Capacitor::clone() const { diff --git a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.hpp b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.hpp index 0b3353c47..201597fa0 100644 --- a/GridKit/Model/PowerElectronics/Capacitor/Capacitor.hpp +++ b/GridKit/Model/PowerElectronics/Capacitor/Capacitor.hpp @@ -57,11 +57,10 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - bool isCloneable() const; + int evaluateAdjointIntegrand(); CircuitComponent* clone() const; diff --git a/GridKit/Model/PowerElectronics/CircuitComponent.hpp b/GridKit/Model/PowerElectronics/CircuitComponent.hpp index f402d743f..c3e33792a 100644 --- a/GridKit/Model/PowerElectronics/CircuitComponent.hpp +++ b/GridKit/Model/PowerElectronics/CircuitComponent.hpp @@ -28,6 +28,7 @@ namespace GridKit CircuitComponent() = default; + protected: /** * @brief Constructs a copy of a circuit component. * @@ -167,6 +168,7 @@ namespace GridKit copyVector(param_lo_, other.param_lo_); } + public: /** * @brief Create an independent copy of this component. * @@ -688,7 +690,6 @@ namespace GridKit */ std::unique_ptr connection_nodes_; - protected: /// The number of variables in this component. Should be equal to \ref n_extern_ plus \ref n_intern_. \see size() IdxT size_{0}; /// The number of nonzero elements in this component's Jacobian. \see nnz() diff --git a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp index 1cc86e989..db4a280a5 100644 --- a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp +++ b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.cpp @@ -422,12 +422,6 @@ namespace GridKit return 0; } - template - bool DistributedGenerator::isCloneable() const - { - return true; - } - template CircuitComponent* DistributedGenerator::clone() const { diff --git a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp index 8a5219848..11d6f9e97 100644 --- a/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp +++ b/GridKit/Model/PowerElectronics/DistributedGenerator/DistributedGenerator.hpp @@ -75,19 +75,18 @@ namespace GridKit NodeT* node_bus); virtual ~DistributedGenerator(); - int initialize(); - int allocate() final; - int tagDifferentiable(); - int setAbsoluteTolerance(RealT); - int evaluateInternalResidual() final; - int evaluateExternalResidual() final; - int evaluateJacobian(); - int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initialize(); + int allocate() final; + int tagDifferentiable(); + int setAbsoluteTolerance(RealT); + int evaluateInternalResidual() final; + int evaluateExternalResidual() final; + int evaluateJacobian(); + int evaluateIntegrand(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - bool isCloneable() const; + int evaluateAdjointIntegrand(); CircuitComponent* clone() const; diff --git a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp index d15913e72..0c7c87761 100644 --- a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp +++ b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp @@ -150,12 +150,6 @@ namespace GridKit return 0; } - template - bool InductionMotor::isCloneable() const - { - return true; - } - template CircuitComponent* InductionMotor::clone() const { diff --git a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp index 6f1724670..13ed162ec 100644 --- a/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp +++ b/GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.hpp @@ -57,11 +57,10 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - bool isCloneable() const; + int evaluateAdjointIntegrand(); CircuitComponent* clone() const; diff --git a/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp b/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp index 6e9969366..42c15c6a5 100644 --- a/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp +++ b/GridKit/Model/PowerElectronics/Inductor/Inductor.cpp @@ -149,12 +149,6 @@ namespace GridKit return 0; } - template - bool Inductor::isCloneable() const - { - return true; - } - template CircuitComponent* Inductor::clone() const { diff --git a/GridKit/Model/PowerElectronics/Inductor/Inductor.hpp b/GridKit/Model/PowerElectronics/Inductor/Inductor.hpp index 30d25db79..7440037c9 100644 --- a/GridKit/Model/PowerElectronics/Inductor/Inductor.hpp +++ b/GridKit/Model/PowerElectronics/Inductor/Inductor.hpp @@ -60,11 +60,10 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - bool isCloneable() const; + int evaluateAdjointIntegrand(); CircuitComponent* clone() const; diff --git a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp index 864250abc..b3b909ebb 100644 --- a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp +++ b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.cpp @@ -135,12 +135,6 @@ namespace GridKit return 0; } - template - bool LinearTransformer::isCloneable() const - { - return true; - } - template CircuitComponent* LinearTransformer::clone() const { diff --git a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp index 6b75dcc1d..0785dcb32 100644 --- a/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp +++ b/GridKit/Model/PowerElectronics/LinearTransformer/LinearTransformer.hpp @@ -57,11 +57,10 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - bool isCloneable() const; + int evaluateAdjointIntegrand(); CircuitComponent* clone() const; diff --git a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp index 1fee11c4b..a918eaf9d 100644 --- a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -152,12 +152,6 @@ namespace GridKit return 0; } - template - bool MicrogridBusDQ::isCloneable() const - { - return true; - } - template CircuitComponent* MicrogridBusDQ::clone() const { diff --git a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp index 2314700a3..806dd2751 100644 --- a/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp +++ b/GridKit/Model/PowerElectronics/MicrogridBusDQ/MicrogridBusDQ.hpp @@ -60,11 +60,10 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - bool isCloneable() const; + int evaluateAdjointIntegrand(); CircuitComponent* clone() const; diff --git a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp index 7e5f993c4..7dc2f6b80 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.cpp @@ -184,12 +184,6 @@ namespace GridKit return 0; } - template - bool MicrogridLine::isCloneable() const - { - return true; - } - template CircuitComponent* MicrogridLine::clone() const { diff --git a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp index 041562cbb..0749e5ceb 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp +++ b/GridKit/Model/PowerElectronics/MicrogridLine/MicrogridLine.hpp @@ -60,11 +60,10 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - bool isCloneable() const; + int evaluateAdjointIntegrand(); CircuitComponent* clone() const; diff --git a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp index 9e6098d0f..34de349d1 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp +++ b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.cpp @@ -175,12 +175,6 @@ namespace GridKit return 0; } - template - bool MicrogridLoad::isCloneable() const - { - return true; - } - template CircuitComponent* MicrogridLoad::clone() const { diff --git a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp index 6189e941c..12935d671 100644 --- a/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp +++ b/GridKit/Model/PowerElectronics/MicrogridLoad/MicrogridLoad.hpp @@ -60,11 +60,10 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - bool isCloneable() const; + int evaluateAdjointIntegrand(); CircuitComponent* clone() const; diff --git a/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp b/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp index 55caa4837..75b3ec18b 100644 --- a/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp +++ b/GridKit/Model/PowerElectronics/Resistor/Resistor.cpp @@ -139,12 +139,6 @@ namespace GridKit return 0; } - template - bool Resistor::isCloneable() const - { - return true; - } - template CircuitComponent* Resistor::clone() const { diff --git a/GridKit/Model/PowerElectronics/Resistor/Resistor.hpp b/GridKit/Model/PowerElectronics/Resistor/Resistor.hpp index 19c90a190..354074bc9 100644 --- a/GridKit/Model/PowerElectronics/Resistor/Resistor.hpp +++ b/GridKit/Model/PowerElectronics/Resistor/Resistor.hpp @@ -60,11 +60,10 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - bool isCloneable() const; + int evaluateAdjointIntegrand(); CircuitComponent* clone() const; diff --git a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp index 408bf241c..0616977e2 100644 --- a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp +++ b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.cpp @@ -184,12 +184,6 @@ namespace GridKit return 0; } - template - bool SynchronousMachine::isCloneable() const - { - return true; - } - template CircuitComponent* SynchronousMachine::clone() const { diff --git a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp index 7cf040583..55356f191 100644 --- a/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp +++ b/GridKit/Model/PowerElectronics/SynchronousMachine/SynchronousMachine.hpp @@ -59,11 +59,10 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - bool isCloneable() const; + int evaluateAdjointIntegrand(); CircuitComponent* clone() const; diff --git a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp index cfefa499f..f3be694d4 100644 --- a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp +++ b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.cpp @@ -205,12 +205,6 @@ namespace GridKit return 0; } - template - bool TransmissionLine::isCloneable() const - { - return true; - } - template CircuitComponent* TransmissionLine::clone() const { diff --git a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp index c9743e9dd..7a0bfb230 100644 --- a/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp +++ b/GridKit/Model/PowerElectronics/TransmissionLine/TransmissionLine.hpp @@ -61,11 +61,10 @@ namespace GridKit int evaluateJacobian(); int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - bool isCloneable() const; + int evaluateAdjointIntegrand(); CircuitComponent* clone() const; diff --git a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp index 3ac673129..900d2fc64 100644 --- a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp +++ b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.cpp @@ -142,12 +142,6 @@ namespace GridKit return 0; } - template - bool VoltageSource::isCloneable() const - { - return true; - } - template CircuitComponent* VoltageSource::clone() const { diff --git a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.hpp b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.hpp index ab9125f40..0cc94f66c 100644 --- a/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.hpp +++ b/GridKit/Model/PowerElectronics/VoltageSource/VoltageSource.hpp @@ -60,11 +60,10 @@ namespace GridKit int evaluateJacobian() final; int evaluateIntegrand(); - int initializeAdjoint(); - int evaluateAdjointResidual(); + int initializeAdjoint(); + int evaluateAdjointResidual(); // int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - bool isCloneable() const; + int evaluateAdjointIntegrand(); CircuitComponent* clone() const;