From a4f2d9572bcb23fe7916992f0c6cdacdfd3b4f2e Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Mon, 10 Feb 2025 13:01:42 -0500 Subject: [PATCH 01/13] Defined base classes for Buses and components. --- src/Model/PhasorDynamics/Branch/Branch.hpp | 36 +-- src/Model/PhasorDynamics/Bus/Bus.hpp | 36 +-- src/Model/PhasorDynamics/BusBase.hpp | 269 +++++++++++++++++++++ src/Model/PhasorDynamics/Component.hpp | 261 ++++++++++++++++++++ src/SystemModel.hpp | 4 +- 5 files changed, 571 insertions(+), 35 deletions(-) create mode 100644 src/Model/PhasorDynamics/BusBase.hpp create mode 100644 src/Model/PhasorDynamics/Component.hpp diff --git a/src/Model/PhasorDynamics/Branch/Branch.hpp b/src/Model/PhasorDynamics/Branch/Branch.hpp index d1d973e8b..6f3efaa25 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.hpp +++ b/src/Model/PhasorDynamics/Branch/Branch.hpp @@ -59,7 +59,7 @@ #pragma once -#include +#include // Forward declarations. namespace GridKit @@ -87,25 +87,25 @@ namespace PhasorDynamics * */ template - class Branch : public ModelEvaluatorImpl + class Branch : public Component { - using ModelEvaluatorImpl::size_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::alpha_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::yp_; - using ModelEvaluatorImpl::tag_; - using ModelEvaluatorImpl::f_; - using ModelEvaluatorImpl::g_; - using ModelEvaluatorImpl::yB_; - using ModelEvaluatorImpl::ypB_; - using ModelEvaluatorImpl::fB_; - using ModelEvaluatorImpl::gB_; - using ModelEvaluatorImpl::param_; + using Component::size_; + using Component::nnz_; + using Component::time_; + using Component::alpha_; + using Component::y_; + using Component::yp_; + using Component::tag_; + using Component::f_; + using Component::g_; + using Component::yB_; + using Component::ypB_; + using Component::fB_; + using Component::gB_; + using Component::param_; using bus_type = Bus; - using real_type = typename ModelEvaluatorImpl::real_type; + using real_type = typename Component::real_type; using BranchData = GridKit::PowerSystemData::BranchData; public: @@ -126,7 +126,7 @@ namespace PhasorDynamics //int evaluateAdjointJacobian(); int evaluateAdjointIntegrand(); - void updateTime(real_type t, real_type a) + void updateTime(real_type /* t */, real_type /* a */) { } diff --git a/src/Model/PhasorDynamics/Bus/Bus.hpp b/src/Model/PhasorDynamics/Bus/Bus.hpp index 575124e27..ec3a398f2 100644 --- a/src/Model/PhasorDynamics/Bus/Bus.hpp +++ b/src/Model/PhasorDynamics/Bus/Bus.hpp @@ -59,7 +59,7 @@ #pragma once -#include +#include // Forward declaration of BusData structure @@ -85,19 +85,19 @@ namespace PhasorDynamics * */ template - class Bus : public ModelEvaluatorImpl + class Bus : public BusBase { - using ModelEvaluatorImpl::size_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::yp_; - using ModelEvaluatorImpl::yB_; - using ModelEvaluatorImpl::ypB_; - using ModelEvaluatorImpl::f_; - using ModelEvaluatorImpl::fB_; - using ModelEvaluatorImpl::tag_; + using BusBase::size_; + using BusBase::y_; + using BusBase::yp_; + using BusBase::yB_; + using BusBase::ypB_; + using BusBase::f_; + using BusBase::fB_; + using BusBase::tag_; public: - using real_type = typename ModelEvaluatorImpl::real_type; + using real_type = typename BusBase::real_type; using BusData = GridKit::PowerSystemData::BusData; Bus(); @@ -152,22 +152,22 @@ namespace PhasorDynamics return f_[1]; } - virtual ScalarT& lambdaIr() + virtual ScalarT& VrB() { return yB_[0]; } - virtual const ScalarT& lambdaIr() const + virtual const ScalarT& VrB() const { return yB_[0]; } - virtual ScalarT& lambdaIi() + virtual ScalarT& ViB() { return yB_[1]; } - virtual const ScalarT& lambdaIi() const + virtual const ScalarT& ViB() const { return yB_[1]; } @@ -197,8 +197,14 @@ namespace PhasorDynamics // return BaseBus::BusType::PQ; // } + // virtual const IdxT BusID() const + // { + // return busID_; + // } + private: // Default initial values for voltage and phase on PQ bus + // const IdxT busID_{static_cast(-1)}; ScalarT Vr0_{0.0}; ScalarT Vi0_{0.0}; diff --git a/src/Model/PhasorDynamics/BusBase.hpp b/src/Model/PhasorDynamics/BusBase.hpp new file mode 100644 index 000000000..6f69bb01d --- /dev/null +++ b/src/Model/PhasorDynamics/BusBase.hpp @@ -0,0 +1,269 @@ +#pragma once + +#include +#include + +namespace GridKit +{ +namespace PhasorDynamics +{ + /*! + * @brief BusBase model implementation base class. + * + */ + template + class BusBase : public ModelEvaluator + { + public: + typedef typename ModelEvaluator::real_type real_type; + + BusBase() + : size_(0), + size_quad_(0), + size_param_(0) + {} + + BusBase(IdxT size, IdxT size_quad, IdxT size_opt) + : size_(size), + size_quad_(size_quad), + size_param_(size_opt), + y_(size_), + yp_(size_), + f_(size_), + g_(size_quad_), + yB_(size_), + ypB_(size_), + fB_(size_), + gB_(size_param_), + J_(COO_Matrix()), + param_(size_param_), + param_up_(size_param_), + param_lo_(size_param_) + { + } + + virtual IdxT size() + { + return size_; + } + + virtual IdxT nnz() + { + return nnz_; + } + + virtual bool hasJacobian() + { + return false; + } + + virtual IdxT size_quad() + { + return size_quad_; + } + + virtual IdxT size_opt() + { + return size_param_; + } + + // virtual void updateTime(real_type t, real_type a) + // { + // time_ = t; + // alpha_ = a; + // std::cout << "updateTime: t = " << time_ << "\n"; + // } + + virtual void setTolerances(real_type& rtol, real_type& atol) const + { + rtol = rtol_; + atol = atol_; + } + + virtual void setMaxSteps(IdxT& msa) const + { + msa = max_steps_; + } + + std::vector& y() + { + return y_; + } + + const std::vector& y() const + { + return y_; + } + + std::vector& yp() + { + return yp_; + } + + const std::vector& yp() const + { + return yp_; + } + + std::vector& tag() + { + return tag_; + } + + const std::vector& tag() const + { + return tag_; + } + + std::vector& yB() + { + return yB_; + } + + const std::vector& yB() const + { + return yB_; + } + + std::vector& ypB() + { + return ypB_; + } + + const std::vector& ypB() const + { + return ypB_; + } + + std::vector& param() + { + return param_; + } + + const std::vector& param() const + { + return param_; + } + + std::vector& param_up() + { + return param_up_; + } + + const std::vector& param_up() const + { + return param_up_; + } + + std::vector& param_lo() + { + return param_lo_; + } + + const std::vector& param_lo() const + { + return param_lo_; + } + + std::vector& getResidual() + { + return f_; + } + + const std::vector& getResidual() const + { + return f_; + } + + COO_Matrix& getJacobian() + { + return J_; + } + + const COO_Matrix& getJacobian() const + { + return J_; + } + + std::vector& getIntegrand() + { + return g_; + } + + const std::vector& getIntegrand() const + { + return g_; + } + + std::vector& getAdjointResidual() + { + return fB_; + } + + const std::vector& getAdjointResidual() const + { + return fB_; + } + + std::vector& getAdjointIntegrand() + { + return gB_; + } + + const std::vector& getAdjointIntegrand() const + { + return gB_; + } + + //@todo Fix ID naming + IdxT getIDBusBase() + { + return idc_; + } + + + + protected: + virtual const IdxT BusID() const + { + return busID_; + } + + const IdxT busID_{static_cast(-1)}; + + IdxT size_; + IdxT nnz_; + IdxT size_quad_; + IdxT size_param_; + + std::vector y_; + std::vector yp_; + std::vector tag_; + std::vector f_; + std::vector g_; + + std::vector yB_; + std::vector ypB_; + std::vector fB_; + std::vector gB_; + + COO_Matrix J_; + + std::vector param_; + std::vector param_up_; + std::vector param_lo_; + + real_type time_; + real_type alpha_; + + real_type rtol_; + real_type atol_; + + IdxT max_steps_; + + IdxT idc_; + + }; + +} // namespace BusBase +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/Component.hpp b/src/Model/PhasorDynamics/Component.hpp new file mode 100644 index 000000000..d01e26e57 --- /dev/null +++ b/src/Model/PhasorDynamics/Component.hpp @@ -0,0 +1,261 @@ +#pragma once + +#include +#include + +namespace GridKit +{ + + /*! + * @brief Component model implementation base class. + * + */ + template + class Component : public ModelEvaluator + { + public: + typedef typename ModelEvaluator::real_type real_type; + + Component() + : size_(0), + size_quad_(0), + size_param_(0) + {} + + Component(IdxT size, IdxT size_quad, IdxT size_opt) + : size_(size), + size_quad_(size_quad), + size_param_(size_opt), + y_(size_), + yp_(size_), + f_(size_), + g_(size_quad_), + yB_(size_), + ypB_(size_), + fB_(size_), + gB_(size_param_), + J_(COO_Matrix()), + param_(size_param_), + param_up_(size_param_), + param_lo_(size_param_) + { + } + + virtual IdxT size() + { + return size_; + } + + virtual IdxT nnz() + { + return nnz_; + } + + virtual bool hasJacobian() + { + return false; + } + + virtual IdxT size_quad() + { + return size_quad_; + } + + virtual IdxT size_opt() + { + return size_param_; + } + + // virtual void updateTime(real_type t, real_type a) + // { + // time_ = t; + // alpha_ = a; + // std::cout << "updateTime: t = " << time_ << "\n"; + // } + + virtual void setTolerances(real_type& rtol, real_type& atol) const + { + rtol = rtol_; + atol = atol_; + } + + virtual void setMaxSteps(IdxT& msa) const + { + msa = max_steps_; + } + + std::vector& y() + { + return y_; + } + + const std::vector& y() const + { + return y_; + } + + std::vector& yp() + { + return yp_; + } + + const std::vector& yp() const + { + return yp_; + } + + std::vector& tag() + { + return tag_; + } + + const std::vector& tag() const + { + return tag_; + } + + std::vector& yB() + { + return yB_; + } + + const std::vector& yB() const + { + return yB_; + } + + std::vector& ypB() + { + return ypB_; + } + + const std::vector& ypB() const + { + return ypB_; + } + + std::vector& param() + { + return param_; + } + + const std::vector& param() const + { + return param_; + } + + std::vector& param_up() + { + return param_up_; + } + + const std::vector& param_up() const + { + return param_up_; + } + + std::vector& param_lo() + { + return param_lo_; + } + + const std::vector& param_lo() const + { + return param_lo_; + } + + std::vector& getResidual() + { + return f_; + } + + const std::vector& getResidual() const + { + return f_; + } + + COO_Matrix& getJacobian() + { + return J_; + } + + const COO_Matrix& getJacobian() const + { + return J_; + } + + std::vector& getIntegrand() + { + return g_; + } + + const std::vector& getIntegrand() const + { + return g_; + } + + std::vector& getAdjointResidual() + { + return fB_; + } + + const std::vector& getAdjointResidual() const + { + return fB_; + } + + std::vector& getAdjointIntegrand() + { + return gB_; + } + + const std::vector& getAdjointIntegrand() const + { + return gB_; + } + + //@todo Fix ID naming + IdxT getIDcomponent() + { + return idc_; + } + + + + protected: + IdxT size_; + IdxT nnz_; + IdxT size_quad_; + IdxT size_param_; + + std::vector y_; + std::vector yp_; + std::vector tag_; + std::vector f_; + std::vector g_; + + std::vector yB_; + std::vector ypB_; + std::vector fB_; + std::vector gB_; + + COO_Matrix J_; + + std::vector param_; + std::vector param_up_; + std::vector param_lo_; + + real_type time_; + real_type alpha_; + + real_type rtol_; + real_type atol_; + + IdxT max_steps_; + + IdxT idc_; + + }; + + +} // namespace GridKit diff --git a/src/SystemModel.hpp b/src/SystemModel.hpp index 4dee38e03..e4aba2a52 100644 --- a/src/SystemModel.hpp +++ b/src/SystemModel.hpp @@ -83,8 +83,8 @@ namespace GridKit template class SystemModel : public ModelEvaluatorImpl { - typedef BaseBus bus_type; - typedef ModelEvaluatorImpl component_type; + typedef ModelEvaluator bus_type; + typedef ModelEvaluator component_type; using real_type = typename ModelEvaluatorImpl::real_type; using ModelEvaluatorImpl::size_; From ed8946867dd3f8009a31bb98704e0d8ead496094 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Mon, 10 Feb 2025 21:18:25 -0500 Subject: [PATCH 02/13] Add infinite bus to phasor dynamic components. --- src/Model/PhasorDynamics/Bus/Bus.cpp | 4 +- src/Model/PhasorDynamics/Bus/Bus.hpp | 29 ++-- src/Model/PhasorDynamics/Bus/BusInfinite.cpp | 159 +++++++++++++++++++ src/Model/PhasorDynamics/Bus/BusInfinite.hpp | 153 ++++++++++++++++++ src/Model/PhasorDynamics/Bus/CMakeLists.txt | 1 + src/Model/PhasorDynamics/BusBase.hpp | 54 ++++--- 6 files changed, 356 insertions(+), 44 deletions(-) create mode 100644 src/Model/PhasorDynamics/Bus/BusInfinite.cpp create mode 100644 src/Model/PhasorDynamics/Bus/BusInfinite.hpp diff --git a/src/Model/PhasorDynamics/Bus/Bus.cpp b/src/Model/PhasorDynamics/Bus/Bus.cpp index ff3f99696..85232b5d2 100644 --- a/src/Model/PhasorDynamics/Bus/Bus.cpp +++ b/src/Model/PhasorDynamics/Bus/Bus.cpp @@ -119,7 +119,9 @@ Bus::Bus(ScalarT Vr, ScalarT Vi) */ template Bus::Bus(BusData& data) - : Vr0_(data.Vm * cos(data.Va)), Vi0_(data.Vm * sin(data.Va)) + : BusBase(data.bus_i), + Vr0_(data.Vm * cos(data.Va)), + Vi0_(data.Vm * sin(data.Va)) { //std::cout << "Create Bus..." << std::endl; //std::cout << "Number of equations is " << size_ << std::endl; diff --git a/src/Model/PhasorDynamics/Bus/Bus.hpp b/src/Model/PhasorDynamics/Bus/Bus.hpp index ec3a398f2..3d521989d 100644 --- a/src/Model/PhasorDynamics/Bus/Bus.hpp +++ b/src/Model/PhasorDynamics/Bus/Bus.hpp @@ -105,12 +105,17 @@ namespace PhasorDynamics Bus(BusData& data); virtual ~Bus(); - virtual int allocate(); - virtual int tagDifferentiable(); - virtual int initialize(); - virtual int evaluateResidual(); - virtual int initializeAdjoint(); - virtual int evaluateAdjointResidual(); + virtual int allocate() override; + virtual int tagDifferentiable() override; + virtual int initialize() override; + virtual int evaluateResidual() override; + virtual int initializeAdjoint() override; + virtual int evaluateAdjointResidual() override; + + virtual int BusType() const override + { + return BusBase::BusType::DEFAULT; + } virtual ScalarT& Vr() { @@ -192,19 +197,7 @@ namespace PhasorDynamics return fB_[1]; } - // virtual const int BusType() const - // { - // return BaseBus::BusType::PQ; - // } - - // virtual const IdxT BusID() const - // { - // return busID_; - // } - private: - // Default initial values for voltage and phase on PQ bus - // const IdxT busID_{static_cast(-1)}; ScalarT Vr0_{0.0}; ScalarT Vi0_{0.0}; diff --git a/src/Model/PhasorDynamics/Bus/BusInfinite.cpp b/src/Model/PhasorDynamics/Bus/BusInfinite.cpp new file mode 100644 index 000000000..6aed6c62c --- /dev/null +++ b/src/Model/PhasorDynamics/Bus/BusInfinite.cpp @@ -0,0 +1,159 @@ + +#include +#include + +#include +#include "BusInfinite.hpp" + +namespace GridKit +{ +namespace PhasorDynamics +{ + +/*! + * @brief Constructor for an infinite (slack) bus. + * + * The model is using current balance in Cartesian coordinates. + * + * Arguments to be passed to BusBase: + * - Number of equations = 0 (size_) + * - Number of variables = 0 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ +template +BusInfinite::BusInfinite() +{ + //std::cout << "Create BusInfinite..." << std::endl; + //std::cout << "Number of equations is " << size_ << std::endl; + + size_ = 0; +} + +/*! + * @brief BusInfinite constructor. + * + * This constructor sets initial values for active and reactive voltage. + * + * Arguments to be passed to BusBase: + * - Number of equations = 0 (size_) + * - Number of variables = 0 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ +template +BusInfinite::BusInfinite(ScalarT Vr, ScalarT Vi) + : Vr_(Vr), Vi_(Vi) +{ + //std::cout << "Create BusInfinite..." << std::endl; + //std::cout << "Number of equations is " << size_ << std::endl; + + size_ = 0; +} + +/** + * @brief Construct a new BusInfinite + * + * Arguments to be set in BusBase: + * - Number of equations = 0 (size_) + * - Number of variables = 0 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + + * @tparam ScalarT - type of scalar variables + * @tparam IdxT - type for vector/matrix indices + * @param[in] data - structure with bus data + */ +template +BusInfinite::BusInfinite(BusData& data) + : BusBase(data.bus_i), + Vr_(data.Vm * cos(data.Va)), + Vi_(data.Vm * sin(data.Va)) +{ + size_ = 0; +} + +template +BusInfinite::~BusInfinite() +{ + //std::cout << "Destroy PQ bus ..." << std::endl; +} + +/*! + * @brief allocate method resizes local solution and residual vectors. + */ +template +int BusInfinite::allocate() +{ + //std::cout << "Nothing to allocate for infinite bus ..." << std::endl; + + return 0; +} + + +template +int BusInfinite::tagDifferentiable() +{ + return 0; +} + + +/*! + * @brief initialize method sets bus variables to stored initial values. + */ +template +int BusInfinite::initialize() +{ + // std::cout << "Initialize BusInfinite..." << std::endl; + + return 0; +} + +/*! + * @brief PQ bus does not compute residuals, so here we just reset residual values. + * + * @warning This implementation assumes bus residuals are always evaluated + * _before_ component model residuals. + * + */ +template +int BusInfinite::evaluateResidual() +{ + // std::cout << "Evaluating residual of a PQ bus ...\n"; + f_[0] = 0.0; + f_[1] = 0.0; + return 0; +} + + +/*! + * @brief initialize method sets bus variables to stored initial values. + */ +template +int BusInfinite::initializeAdjoint() +{ + // std::cout << "Initialize BusInfinite..." << std::endl; + yB_[0] = 0.0; + yB_[1] = 0.0; + ypB_[0] = 0.0; + ypB_[1] = 0.0; + + return 0; +} + +template +int BusInfinite::evaluateAdjointResidual() +{ + fB_[0] = 0.0; + fB_[1] = 0.0; + + return 0; +} + +// Available template instantiations +template class BusInfinite; +template class BusInfinite; + +} // namespace PhasorDynamic +} // namespace GridKit + diff --git a/src/Model/PhasorDynamics/Bus/BusInfinite.hpp b/src/Model/PhasorDynamics/Bus/BusInfinite.hpp new file mode 100644 index 000000000..64821ecfe --- /dev/null +++ b/src/Model/PhasorDynamics/Bus/BusInfinite.hpp @@ -0,0 +1,153 @@ + +#pragma once + +#include + + +// Forward declaration of BusData structure +namespace GridKit +{ +namespace PowerSystemData +{ + template + struct BusData; +} +} + +namespace GridKit +{ +namespace PhasorDynamics +{ + /*! + * @brief Implementation of an "infinite" bus. + * + * + * + */ + template + class BusInfinite : public BusBase + { + using BusBase::size_; + using BusBase::y_; + using BusBase::yp_; + using BusBase::yB_; + using BusBase::ypB_; + using BusBase::f_; + using BusBase::fB_; + using BusBase::tag_; + + public: + using real_type = typename BusBase::real_type; + using BusData = GridKit::PowerSystemData::BusData; + + BusInfinite(); + BusInfinite(ScalarT Vr, ScalarT Vi); + BusInfinite(BusData& data); + virtual ~BusInfinite(); + + virtual int allocate() override; + virtual int tagDifferentiable() override; + virtual int initialize() override; + virtual int evaluateResidual() override; + virtual int initializeAdjoint() override; + virtual int evaluateAdjointResidual() override; + + virtual int BusType() const override + { + return BusBase::BusType::SLACK; + } + + virtual ScalarT& Vr() + { + return Vr_; + } + + virtual const ScalarT& Vr() const + { + return Vr_; + } + + virtual ScalarT& Vi() + { + return Vi_; + } + + virtual const ScalarT& Vi() const + { + return Vi_; + } + + virtual ScalarT& Ir() + { + return Ir_; + } + + virtual const ScalarT& Ir() const + { + return Ir_; + } + + virtual ScalarT& Ii() + { + return Ii_; + } + + virtual const ScalarT& Ii() const + { + return Ii_; + } + + virtual ScalarT& VrB() + { + return VrB_; + } + + virtual const ScalarT& VrB() const + { + return VrB_; + } + + virtual ScalarT& ViB() + { + return ViB_; + } + + virtual const ScalarT& ViB() const + { + return ViB_; + } + + virtual ScalarT& IrB() + { + return IrB_; + } + + virtual const ScalarT& IrB() const + { + return IrB_; + } + + virtual ScalarT& IiB() + { + return IiB_; + } + + virtual const ScalarT& IiB() const + { + return IiB_; + } + + private: + ScalarT Vr_{0.0}; + ScalarT Vi_{0.0}; + ScalarT Ir_{0.0}; + ScalarT Ii_{0.0}; + + ScalarT VrB_{0.0}; + ScalarT ViB_{0.0}; + ScalarT IrB_{0.0}; + ScalarT IiB_{0.0}; + }; + +} // PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/Bus/CMakeLists.txt b/src/Model/PhasorDynamics/Bus/CMakeLists.txt index 356b7f517..f991b979b 100644 --- a/src/Model/PhasorDynamics/Bus/CMakeLists.txt +++ b/src/Model/PhasorDynamics/Bus/CMakeLists.txt @@ -63,6 +63,7 @@ gridkit_add_library(phasor_dynamics_bus SOURCES Bus.cpp + BusInfinite.cpp OUTPUT_NAME gridkit_phasor_dynamics_bus) diff --git a/src/Model/PhasorDynamics/BusBase.hpp b/src/Model/PhasorDynamics/BusBase.hpp index 6f69bb01d..09a02e39a 100644 --- a/src/Model/PhasorDynamics/BusBase.hpp +++ b/src/Model/PhasorDynamics/BusBase.hpp @@ -15,13 +15,20 @@ namespace PhasorDynamics class BusBase : public ModelEvaluator { public: - typedef typename ModelEvaluator::real_type real_type; + using real_type = typename ModelEvaluator::real_type; + + enum BusType{DEFAULT=1, SLACK}; BusBase() : size_(0), size_quad_(0), size_param_(0) - {} + { + } + + BusBase(IdxT bus_id) : bus_id_(bus_id) + { + } BusBase(IdxT size, IdxT size_quad, IdxT size_opt) : size_(size), @@ -42,6 +49,13 @@ namespace PhasorDynamics { } + virtual ~BusBase() + { + } + + /// Pure virtual function, returns bus type (DEFAULT or SLACK). + virtual int BusType() const = 0; + virtual IdxT size() { return size_; @@ -57,12 +71,12 @@ namespace PhasorDynamics return false; } - virtual IdxT size_quad() + virtual IdxT sizeQuad() { return size_quad_; } - virtual IdxT size_opt() + virtual IdxT sizeParam() { return size_param_; } @@ -145,22 +159,22 @@ namespace PhasorDynamics return param_; } - std::vector& param_up() + std::vector& paramUp() { return param_up_; } - const std::vector& param_up() const + const std::vector& paramUp() const { return param_up_; } - std::vector& param_lo() + std::vector& paramLo() { return param_lo_; } - const std::vector& param_lo() const + const std::vector& paramLo() const { return param_lo_; } @@ -215,26 +229,19 @@ namespace PhasorDynamics return gB_; } - //@todo Fix ID naming - IdxT getIDBusBase() + virtual const IdxT busID() const { - return idc_; + return bus_id_; } - protected: - virtual const IdxT BusID() const - { - return busID_; - } - - const IdxT busID_{static_cast(-1)}; + const IdxT bus_id_{static_cast(-1)}; - IdxT size_; - IdxT nnz_; - IdxT size_quad_; - IdxT size_param_; + IdxT size_{0}; + IdxT nnz_{0}; + IdxT size_quad_{0}; + IdxT size_param_{0}; std::vector y_; std::vector yp_; @@ -260,9 +267,6 @@ namespace PhasorDynamics real_type atol_; IdxT max_steps_; - - IdxT idc_; - }; } // namespace BusBase From edde998b474bc4621b7ca1e9a4e9dd5ea81adb66 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Tue, 11 Feb 2025 12:33:42 -0500 Subject: [PATCH 03/13] Smoke tests for phasor dynamics buses and branches. --- CMakeLists.txt | 1 + src/Model/PhasorDynamics/Bus/Bus.cpp | 107 ++++++++---------- src/Model/PhasorDynamics/Bus/Bus.hpp | 62 +--------- src/Model/PhasorDynamics/Bus/BusInfinite.cpp | 46 ++++++++ src/Model/PhasorDynamics/Bus/BusInfinite.hpp | 3 + src/Model/PhasorDynamics/Bus/CMakeLists.txt | 58 +--------- src/Model/PhasorDynamics/BusBase.hpp | 22 ++-- src/Model/PhasorDynamics/CMakeLists.txt | 57 ---------- tests/CMakeLists.txt | 3 + tests/UnitTests/CMakeLists.txt | 2 + tests/UnitTests/PhasorDynamics/CMakeLists.txt | 13 +++ tests/UnitTests/PhasorDynamics/TestBranch.cpp | 41 +++++++ tests/UnitTests/PhasorDynamics/TestBus.cpp | 49 ++++++++ 13 files changed, 222 insertions(+), 242 deletions(-) create mode 100644 tests/CMakeLists.txt create mode 100644 tests/UnitTests/CMakeLists.txt create mode 100644 tests/UnitTests/PhasorDynamics/CMakeLists.txt create mode 100644 tests/UnitTests/PhasorDynamics/TestBranch.cpp create mode 100644 tests/UnitTests/PhasorDynamics/TestBus.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fbba2cb6..e964a9d39 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,6 +150,7 @@ add_subdirectory(src) # Create examples and tests enable_testing() add_subdirectory(examples) +add_subdirectory(tests) export(EXPORT gridkit-targets FILE ${CMAKE_CURRENT_BINARY_DIR}/GridKitTargets.cmake) diff --git a/src/Model/PhasorDynamics/Bus/Bus.cpp b/src/Model/PhasorDynamics/Bus/Bus.cpp index 85232b5d2..f085b13a8 100644 --- a/src/Model/PhasorDynamics/Bus/Bus.cpp +++ b/src/Model/PhasorDynamics/Bus/Bus.cpp @@ -1,61 +1,3 @@ -/* - * - * Copyright (c) 2017, Lawrence Livermore National Security, LLC. - * Produced at the Lawrence Livermore National Laboratory. - * Written by Slaven Peles . - * LLNL-CODE-718378. - * All rights reserved. - * - * This file is part of GridKit™. For details, see github.com/LLNL/GridKit - * Please also read the LICENSE file. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the disclaimer below. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the disclaimer (as noted below) in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of the LLNS/LLNL nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL - * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY - * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * Lawrence Livermore National Laboratory is operated by Lawrence Livermore - * National Security, LLC, for the U.S. Department of Energy, National - * Nuclear Security Administration under Contract DE-AC52-07NA27344. - * - * This document was prepared as an account of work sponsored by an agency - * of the United States government. Neither the United States government nor - * Lawrence Livermore National Security, LLC, nor any of their employees - * makes any warranty, expressed or implied, or assumes any legal liability - * or responsibility for the accuracy, completeness, or usefulness of any - * information, apparatus, product, or process disclosed, or represents that - * its use would not infringe privately owned rights. Reference herein to - * any specific commercial product, process, or service by trade name, - * trademark, manufacturer, or otherwise does not necessarily constitute or - * imply its endorsement, recommendation, or favoring by the United States - * government or Lawrence Livermore National Security, LLC. The views and - * opinions of authors expressed herein do not necessarily state or reflect - * those of the United States government or Lawrence Livermore National - * Security, LLC, and shall not be used for advertising or product - * endorsement purposes. - * - */ #include #include @@ -155,6 +97,9 @@ int Bus::allocate() } +/*! + * @brief Bus variables are algebraic. + */ template int Bus::tagDifferentiable() { @@ -195,6 +140,19 @@ int Bus::evaluateResidual() return 0; } +/** + * @brief Jacobian evaluation not implemented + * + * @tparam ScalarT - data type for Jacobian elements + * @tparam IdxT - data type for matrix indices + * @return int - error code + */ +template +int Bus::evaluateJacobian() +{ + return 0; +} + /*! * @brief initialize method sets bus variables to stored initial values. @@ -211,6 +169,13 @@ int Bus::initializeAdjoint() return 0; } +/** + * @brief Bus only initializes adjoint residual elements to zero. + * + * @tparam ScalarT - data type for the integrand + * @tparam IdxT - data type for matrix/vector indices + * @return int - error code + */ template int Bus::evaluateAdjointResidual() { @@ -220,6 +185,32 @@ int Bus::evaluateAdjointResidual() return 0; } +/** + * @brief Quadrature evaluation not implemented + * + * @tparam ScalarT - data type for the integrand + * @tparam IdxT - data type for matrix/vector indices + * @return int - error code + */ +template +int Bus::evaluateIntegrand() +{ + return 0; +} + +/** + * @brief Adjoint quadrature evaluation not implemented + * + * @tparam ScalarT - data type for the integrand + * @tparam IdxT - data type for matrix/vector indices + * @return int - error code + */ +template +int Bus::evaluateAdjointIntegrand() +{ + return 0; +} + // Available template instantiations template class Bus; template class Bus; diff --git a/src/Model/PhasorDynamics/Bus/Bus.hpp b/src/Model/PhasorDynamics/Bus/Bus.hpp index 3d521989d..a1426d82a 100644 --- a/src/Model/PhasorDynamics/Bus/Bus.hpp +++ b/src/Model/PhasorDynamics/Bus/Bus.hpp @@ -1,61 +1,3 @@ -/* - * - * Copyright (c) 2017, Lawrence Livermore National Security, LLC. - * Produced at the Lawrence Livermore National Laboratory. - * Written by Slaven Peles . - * LLNL-CODE-718378. - * All rights reserved. - * - * This file is part of GridKit™. For details, see github.com/LLNL/GridKit - * Please also read the LICENSE file. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the disclaimer below. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the disclaimer (as noted below) in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of the LLNS/LLNL nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL - * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY - * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * Lawrence Livermore National Laboratory is operated by Lawrence Livermore - * National Security, LLC, for the U.S. Department of Energy, National - * Nuclear Security Administration under Contract DE-AC52-07NA27344. - * - * This document was prepared as an account of work sponsored by an agency - * of the United States government. Neither the United States government nor - * Lawrence Livermore National Security, LLC, nor any of their employees - * makes any warranty, expressed or implied, or assumes any legal liability - * or responsibility for the accuracy, completeness, or usefulness of any - * information, apparatus, product, or process disclosed, or represents that - * its use would not infringe privately owned rights. Reference herein to - * any specific commercial product, process, or service by trade name, - * trademark, manufacturer, or otherwise does not necessarily constitute or - * imply its endorsement, recommendation, or favoring by the United States - * government or Lawrence Livermore National Security, LLC. The views and - * opinions of authors expressed herein do not necessarily state or reflect - * those of the United States government or Lawrence Livermore National - * Security, LLC, and shall not be used for advertising or product - * endorsement purposes. - * - */ #pragma once @@ -109,9 +51,13 @@ namespace PhasorDynamics virtual int tagDifferentiable() override; virtual int initialize() override; virtual int evaluateResidual() override; + virtual int evaluateIntegrand() override; + virtual int evaluateJacobian() override; virtual int initializeAdjoint() override; + virtual int evaluateAdjointIntegrand() override; virtual int evaluateAdjointResidual() override; + virtual int BusType() const override { return BusBase::BusType::DEFAULT; diff --git a/src/Model/PhasorDynamics/Bus/BusInfinite.cpp b/src/Model/PhasorDynamics/Bus/BusInfinite.cpp index 6aed6c62c..139659c22 100644 --- a/src/Model/PhasorDynamics/Bus/BusInfinite.cpp +++ b/src/Model/PhasorDynamics/Bus/BusInfinite.cpp @@ -125,6 +125,18 @@ int BusInfinite::evaluateResidual() return 0; } +/** + * @brief Jacobian evaluation not implemented + * + * @tparam ScalarT - data type for Jacobian elements + * @tparam IdxT - data type for matrix indices + * @return int - error code + */ +template +int BusInfinite::evaluateJacobian() +{ + return 0; +} /*! * @brief initialize method sets bus variables to stored initial values. @@ -141,6 +153,13 @@ int BusInfinite::initializeAdjoint() return 0; } +/** + * @brief BusInfinite only initializes adjoint residual elements to zero. + * + * @tparam ScalarT - data type for the integrand + * @tparam IdxT - data type for matrix/vector indices + * @return int - error code + */ template int BusInfinite::evaluateAdjointResidual() { @@ -150,6 +169,33 @@ int BusInfinite::evaluateAdjointResidual() return 0; } +/** + * @brief Quadrature evaluation not implemented + * + * @tparam ScalarT - data type for the integrand + * @tparam IdxT - data type for matrix/vector indices + * @return int - error code + */ +template +int BusInfinite::evaluateIntegrand() +{ + return 0; +} + +/** + * @brief Adjoint quadrature evaluation not implemented + * + * @tparam ScalarT - data type for the integrand + * @tparam IdxT - data type for matrix/vector indices + * @return int - error code + */ +template +int BusInfinite::evaluateAdjointIntegrand() +{ + return 0; +} + + // Available template instantiations template class BusInfinite; template class BusInfinite; diff --git a/src/Model/PhasorDynamics/Bus/BusInfinite.hpp b/src/Model/PhasorDynamics/Bus/BusInfinite.hpp index 64821ecfe..a77385c89 100644 --- a/src/Model/PhasorDynamics/Bus/BusInfinite.hpp +++ b/src/Model/PhasorDynamics/Bus/BusInfinite.hpp @@ -49,7 +49,10 @@ namespace PhasorDynamics virtual int tagDifferentiable() override; virtual int initialize() override; virtual int evaluateResidual() override; + virtual int evaluateIntegrand() override; + virtual int evaluateJacobian() override; virtual int initializeAdjoint() override; + virtual int evaluateAdjointIntegrand() override; virtual int evaluateAdjointResidual() override; virtual int BusType() const override diff --git a/src/Model/PhasorDynamics/Bus/CMakeLists.txt b/src/Model/PhasorDynamics/Bus/CMakeLists.txt index f991b979b..636d4dd82 100644 --- a/src/Model/PhasorDynamics/Bus/CMakeLists.txt +++ b/src/Model/PhasorDynamics/Bus/CMakeLists.txt @@ -1,63 +1,7 @@ -# -# Copyright (c) 2017, Lawrence Livermore National Security, LLC. -# Produced at the Lawrence Livermore National Laboratory. -# Written by Slaven Peles . -# LLNL-CODE-718378. -# All rights reserved. -# -# This file is part of GridKit™. For details, see github.com/LLNL/GridKit -# Please also read the LICENSE file. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# - Redistributions of source code must retain the above copyright notice, -# this list of conditions and the disclaimer below. -# - Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the disclaimer (as noted below) in the -# documentation and/or other materials provided with the distribution. -# - Neither the name of the LLNS/LLNL nor the names of its contributors may -# be used to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL -# SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY -# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -# THE POSSIBILITY OF SUCH DAMAGE. -# -# Lawrence Livermore National Laboratory is operated by Lawrence Livermore -# National Security, LLC, for the U.S. Department of Energy, National -# Nuclear Security Administration under Contract DE-AC52-07NA27344. -# -# This document was prepared as an account of work sponsored by an agency -# of the United States government. Neither the United States government nor -# Lawrence Livermore National Security, LLC, nor any of their employees -# makes any warranty, expressed or implied, or assumes any legal liability -# or responsibility for the accuracy, completeness, or usefulness of any -# information, apparatus, product, or process disclosed, or represents that -# its use would not infringe privately owned rights. Reference herein to -# any specific commercial product, process, or service by trade name, -# trademark, manufacturer, or otherwise does not necessarily constitute or -# imply its endorsement, recommendation, or favoring by the United States -# government or Lawrence Livermore National Security, LLC. The views and -# opinions of authors expressed herein do not necessarily state or reflect -# those of the United States government or Lawrence Livermore National -# Security, LLC, and shall not be used for advertising or product -# endorsement purposes. -# - # [[ # Author(s): # - Cameron Rutherford +# - Slaven Peles #]] gridkit_add_library(phasor_dynamics_bus diff --git a/src/Model/PhasorDynamics/BusBase.hpp b/src/Model/PhasorDynamics/BusBase.hpp index 09a02e39a..161a04fa0 100644 --- a/src/Model/PhasorDynamics/BusBase.hpp +++ b/src/Model/PhasorDynamics/BusBase.hpp @@ -71,22 +71,20 @@ namespace PhasorDynamics return false; } - virtual IdxT sizeQuad() + virtual IdxT size_quad() { return size_quad_; } - virtual IdxT sizeParam() + virtual IdxT size_opt() { return size_param_; } - // virtual void updateTime(real_type t, real_type a) - // { - // time_ = t; - // alpha_ = a; - // std::cout << "updateTime: t = " << time_ << "\n"; - // } + virtual void updateTime(real_type /* t */, real_type /* a */) + { + // No time to update in bus models + } virtual void setTolerances(real_type& rtol, real_type& atol) const { @@ -159,22 +157,22 @@ namespace PhasorDynamics return param_; } - std::vector& paramUp() + std::vector& param_up() { return param_up_; } - const std::vector& paramUp() const + const std::vector& param_up() const { return param_up_; } - std::vector& paramLo() + std::vector& param_lo() { return param_lo_; } - const std::vector& paramLo() const + const std::vector& param_lo() const { return param_lo_; } diff --git a/src/Model/PhasorDynamics/CMakeLists.txt b/src/Model/PhasorDynamics/CMakeLists.txt index d88233100..b9e6ce521 100644 --- a/src/Model/PhasorDynamics/CMakeLists.txt +++ b/src/Model/PhasorDynamics/CMakeLists.txt @@ -1,60 +1,3 @@ -# -# Copyright (c) 2017, Lawrence Livermore National Security, LLC. -# Produced at the Lawrence Livermore National Laboratory. -# Written by Slaven Peles . -# LLNL-CODE-718378. -# All rights reserved. -# -# This file is part of GridKit™. For details, see github.com/LLNL/GridKit -# Please also read the LICENSE file. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# - Redistributions of source code must retain the above copyright notice, -# this list of conditions and the disclaimer below. -# - Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the disclaimer (as noted below) in the -# documentation and/or other materials provided with the distribution. -# - Neither the name of the LLNS/LLNL nor the names of its contributors may -# be used to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL -# SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY -# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -# THE POSSIBILITY OF SUCH DAMAGE. -# -# Lawrence Livermore National Laboratory is operated by Lawrence Livermore -# National Security, LLC, for the U.S. Department of Energy, National -# Nuclear Security Administration under Contract DE-AC52-07NA27344. -# -# This document was prepared as an account of work sponsored by an agency -# of the United States government. Neither the United States government nor -# Lawrence Livermore National Security, LLC, nor any of their employees -# makes any warranty, expressed or implied, or assumes any legal liability -# or responsibility for the accuracy, completeness, or usefulness of any -# information, apparatus, product, or process disclosed, or represents that -# its use would not infringe privately owned rights. Reference herein to -# any specific commercial product, process, or service by trade name, -# trademark, manufacturer, or otherwise does not necessarily constitute or -# imply its endorsement, recommendation, or favoring by the United States -# government or Lawrence Livermore National Security, LLC. The views and -# opinions of authors expressed herein do not necessarily state or reflect -# those of the United States government or Lawrence Livermore National -# Security, LLC, and shall not be used for advertising or product -# endorsement purposes. -# - # [[ # Author(s): # - Cameron Rutherford diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 000000000..d80cc13bc --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,3 @@ + + +add_subdirectory(UnitTests) diff --git a/tests/UnitTests/CMakeLists.txt b/tests/UnitTests/CMakeLists.txt new file mode 100644 index 000000000..970045256 --- /dev/null +++ b/tests/UnitTests/CMakeLists.txt @@ -0,0 +1,2 @@ +# +add_subdirectory(PhasorDynamics) diff --git a/tests/UnitTests/PhasorDynamics/CMakeLists.txt b/tests/UnitTests/PhasorDynamics/CMakeLists.txt new file mode 100644 index 000000000..7b098fe8c --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/CMakeLists.txt @@ -0,0 +1,13 @@ + + +add_executable(test_phasor_bus TestBus.cpp) +target_link_libraries(test_phasor_bus GRIDKIT::phasor_dynamics_bus) + +add_executable(test_phasor_branch TestBus.cpp) +target_link_libraries(test_phasor_branch GRIDKIT::phasor_dynamics_branch + GRIDKIT::phasor_dynamics_bus) + +add_test(NAME PhasorDynamicsBusTest COMMAND $) +add_test(NAME PhasorDynamicsBranchTest COMMAND $) + +install(TARGETS test_phasor_bus test_phasor_branch RUNTIME DESTINATION bin) diff --git a/tests/UnitTests/PhasorDynamics/TestBranch.cpp b/tests/UnitTests/PhasorDynamics/TestBranch.cpp new file mode 100644 index 000000000..12d38b60d --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/TestBranch.cpp @@ -0,0 +1,41 @@ +#include +#include + +#include +#include +#include + +/* + * Compute gradient of an objective function expressed as an integral over + * system trajectory. The gradient is computed numerically and using + * adjoint sensitivity analysis. + * + * The test case is a 4th order generator connected to an infinite bus. + * The objective function is total frequency deviation computed over + * system trajectory after generator short circuit fault. + * + */ +int main() +{ + using namespace GridKit; + using namespace GridKit::Testing; + + int status = 0; + + auto* bus1 = new PhasorDynamics::Bus(1.0, 0.0); + auto* bus2 = new PhasorDynamics::Bus(1.0, 0.1); + + // Create an infinite bus + PhasorDynamics::Component* branch = new PhasorDynamics::Branch(bus1, bus2); + + if (branch != nullptr) + { + delete branch; + } + else + { + status++; + } + + return status; +} \ No newline at end of file diff --git a/tests/UnitTests/PhasorDynamics/TestBus.cpp b/tests/UnitTests/PhasorDynamics/TestBus.cpp new file mode 100644 index 000000000..2c6c795d8 --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/TestBus.cpp @@ -0,0 +1,49 @@ +#include +#include + +#include +#include +#include + +/* + * Compute gradient of an objective function expressed as an integral over + * system trajectory. The gradient is computed numerically and using + * adjoint sensitivity analysis. + * + * The test case is a 4th order generator connected to an infinite bus. + * The objective function is total frequency deviation computed over + * system trajectory after generator short circuit fault. + * + */ +int main() +{ + using namespace GridKit; + using namespace GridKit::Testing; + + int status = 0; + + // Create an infinite bus + PhasorDynamics::BusBase* bus = new PhasorDynamics::Bus(1.0, 0.0); + + if (bus != nullptr) + { + delete bus; + } + else + { + status++; + } + + bus = new PhasorDynamics::BusInfinite(1.0, 0.0); + + if (bus != nullptr) + { + delete bus; + } + else + { + status++; + } + + return status; +} \ No newline at end of file From d5c11cd363f33722fbd04aa23052d3efe437cc01 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Tue, 11 Feb 2025 13:56:08 -0500 Subject: [PATCH 04/13] Setup unit testing skeleton. --- src/Model/PhasorDynamics/Component.hpp | 4 +- src/Utilities/TestHelpers.hpp | 255 ++++++++++++++++++ .../UnitTests/PhasorDynamics/BranchTests.hpp | 46 ++++ tests/UnitTests/PhasorDynamics/BusTests.hpp | 50 ++++ tests/UnitTests/PhasorDynamics/CMakeLists.txt | 4 +- tests/UnitTests/PhasorDynamics/TestBranch.cpp | 41 --- tests/UnitTests/PhasorDynamics/TestBus.cpp | 49 ---- .../PhasorDynamics/runBranchTests.cpp | 14 + .../UnitTests/PhasorDynamics/runBusTests.cpp | 14 + 9 files changed, 384 insertions(+), 93 deletions(-) create mode 100644 src/Utilities/TestHelpers.hpp create mode 100644 tests/UnitTests/PhasorDynamics/BranchTests.hpp create mode 100644 tests/UnitTests/PhasorDynamics/BusTests.hpp delete mode 100644 tests/UnitTests/PhasorDynamics/TestBranch.cpp delete mode 100644 tests/UnitTests/PhasorDynamics/TestBus.cpp create mode 100644 tests/UnitTests/PhasorDynamics/runBranchTests.cpp create mode 100644 tests/UnitTests/PhasorDynamics/runBusTests.cpp diff --git a/src/Model/PhasorDynamics/Component.hpp b/src/Model/PhasorDynamics/Component.hpp index d01e26e57..74fcb3ef7 100644 --- a/src/Model/PhasorDynamics/Component.hpp +++ b/src/Model/PhasorDynamics/Component.hpp @@ -4,6 +4,8 @@ #include namespace GridKit +{ +namespace PhasorDynamics { /*! @@ -257,5 +259,5 @@ namespace GridKit }; - +} // namespace PhasorDynamics } // namespace GridKit diff --git a/src/Utilities/TestHelpers.hpp b/src/Utilities/TestHelpers.hpp new file mode 100644 index 000000000..f0a761766 --- /dev/null +++ b/src/Utilities/TestHelpers.hpp @@ -0,0 +1,255 @@ + +/** + * @file UnitTest.hpp + * + * @author Slaven Peles , ORNL + * + */ +#pragma once + +#define THROW_NULL_DEREF throw std::runtime_error("error") + +#include +#include +#include + + +namespace GridKit +{ + +namespace Colors +{ + // must be const pointer and const dest for + // const string declarations to pass -Wwrite-strings + static const char * const RED = "\033[1;31m"; + static const char * const GREEN = "\033[1;32m"; + static const char * const YELLOW = "\033[33;1m"; + static const char * const BLUE = "\033[34;1m"; + static const char * const ORANGE = "\u001b[38;5;208m"; + static const char * const CLEAR = "\033[0m"; +} + +namespace Testing +{ + enum TestOutcome {PASS=0, FAIL, SKIP, EXPECTED_FAIL, UNEXPECTED_PASS}; + + class TestStatus + { + public: + TestStatus() + : outcome_(TestOutcome::PASS) + { + } + + TestStatus(const char* funcname) + : outcome_(TestOutcome::PASS), + funcname_(funcname) + { + } + + ~TestStatus() + { + } + + TestStatus& operator=(const bool isPass) + { + if(isPass) + outcome_ = TestOutcome::PASS; + else + outcome_ = TestOutcome::FAIL; + return *this; + } + + TestStatus& operator*=(const bool isPass) + { + if(!isPass) + outcome_ = TestOutcome::FAIL; + return *this; + } + + void skipTest() + { + outcome_ = TestOutcome::SKIP; + } + + void expectFailure() + { + expectFailure_ = true; + } + + TestOutcome report() + { + return report(funcname_); + } + + TestOutcome report(const char* funcname) + { + using namespace Colors; + + if (expectFailure_) + { + if ((outcome_ == FAIL) || (outcome_ == EXPECTED_FAIL)) + outcome_ = EXPECTED_FAIL; + else if ((outcome_ == PASS) || (outcome_ == UNEXPECTED_PASS)) + outcome_ = UNEXPECTED_PASS; + else + outcome_ = SKIP; + } + + switch(outcome_) + { + case PASS: + std::cout << "--- " << GREEN << "PASS" << CLEAR + << ": Test " << funcname << "\n"; + break; + case FAIL: + std::cout << "--- " << RED << "FAIL" << CLEAR + << ": Test " << funcname << "\n"; + break; + case SKIP: + std::cout << "--- " << YELLOW << "SKIP" << CLEAR + << ": Test " << funcname << CLEAR << "\n"; + break; + case EXPECTED_FAIL: + std::cout << "--- " << ORANGE << "FAIL" << CLEAR + << " (EXPECTED)" << ": Test " << funcname << "\n"; + break; + case UNEXPECTED_PASS: + std::cout << "--- " << BLUE << "PASS" << CLEAR + << " (UNEXPECTED)" << ": Test " << funcname << "\n"; + break; + default: + std::cout << "--- " << RED << "FAIL" << CLEAR + << "Unrecognized test result " << outcome_ + << " for test " << funcname << "\n"; + } + return outcome_; + } + + private: + TestOutcome outcome_; + const char* funcname_; + bool expectFailure_ = false; + }; + + + + struct TestingResults + { + int success = 0; + int failure = 0; + int skip = 0; + int expected_failure = 0; + int unexpected_success = 0; + + TestingResults(){} + ~TestingResults(){} + TestingResults(const TestingResults& r) + { + this->success = r.success; + this->failure = r.failure; + this->skip = r.skip; + this->expected_failure = r.expected_failure; + this->unexpected_success = r.unexpected_success; + } + + void init() + { + this->success = 0; + this->failure = 0; + this->skip = 0; + this->expected_failure = 0; + this->unexpected_success = 0; + } + + TestingResults& operator+=(const TestingResults& rhs) + { + this->success += rhs.success; + this->failure += rhs.failure; + this->skip += rhs.skip; + this->expected_failure += rhs.expected_failure; + this->unexpected_success += rhs.unexpected_success; + + return *this; + } + + TestingResults& operator+=(const TestOutcome outcome) + { + switch(outcome) + { + case PASS: + this->success++; + break; + case FAIL: + this->failure++; + break; + case SKIP: + this->skip++; + break; + case EXPECTED_FAIL: + this->expected_failure++; + break; + case UNEXPECTED_PASS: + this->unexpected_success++; + break; + default: + std::cout << "Warning: Unrecognized test outcome code " + << outcome << ". Assuming failure ...\n"; + this->failure++; + } + return *this; + } + + int summary() + { + std::cout << "\n\nTest Summary\n"; + std::cout << "----------------------------\n"; + std::cout << "\tSuccessful tests: " << success << "\n"; + std::cout << "\tFailed test: " << failure << "\n"; + std::cout << "\tSkipped tests: " << skip << "\n"; + std::cout << "\tExpected failures: " << expected_failure << "\n"; + std::cout << "\tUnexpected successes: " << unexpected_success << "\n"; + std::cout << "\n"; + + return failure; + } + }; + + TestingResults operator+(const TestingResults& lhs, const TestingResults& rhs) + { + return TestingResults(lhs) += rhs; + } + + TestingResults operator+(const TestingResults& lhs, const TestOutcome outcome) + { + return TestingResults(lhs) += outcome; + } + + TestingResults operator+(const TestOutcome outcome, const TestingResults& rhs) + { + return TestingResults(rhs) += outcome; + } + + + // /// @brief eps = 2.2e-15 for double type + // static const real_type eps_ = 10*std::numeric_limits::epsilon(); + + + // class TestBase + // { + // public: + // TestBase() = default; + // ~TestBase() = default; + + // protected: + // /// Returns true if two real numbers are equal within tolerance + // [[nodiscard]] static + // bool isEqual(const real_type a, const real_type b) + // { + // return (std::abs(a - b)/(1.0 + std::abs(b)) < eps); + // } + + // }; + +} // namespace Testing +} // namespace GridKit diff --git a/tests/UnitTests/PhasorDynamics/BranchTests.hpp b/tests/UnitTests/PhasorDynamics/BranchTests.hpp new file mode 100644 index 000000000..a85f7d4e3 --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/BranchTests.hpp @@ -0,0 +1,46 @@ +#include +#include + +#include +#include +#include +#include + +namespace GridKit +{ +namespace Testing +{ + + class BranchTests + { + public: + BranchTests() = default; + ~BranchTests() = default; + + TestOutcome smoke() + { + TestStatus success; + + auto* bus1 = new PhasorDynamics::Bus(1.0, 0.0); + auto* bus2 = new PhasorDynamics::Bus(1.0, 0.1); + + PhasorDynamics::Component* branch = + new PhasorDynamics::Branch(bus1, bus2); + + success *= (branch != nullptr); + + if (branch) + { + delete branch; + } + delete bus1; + delete bus2; + + return success.report(__func__); + } + }; + +} // namespace Testing +} // namespace GridKit + + diff --git a/tests/UnitTests/PhasorDynamics/BusTests.hpp b/tests/UnitTests/PhasorDynamics/BusTests.hpp new file mode 100644 index 000000000..bd8b7ad86 --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/BusTests.hpp @@ -0,0 +1,50 @@ +#include +#include + +#include +#include +#include +#include + + +namespace GridKit +{ +namespace Testing +{ + + class BusTests + { + public: + BusTests() = default; + ~BusTests() = default; + + TestOutcome smoke() + { + TestStatus success; + + // Create an infinite bus + PhasorDynamics::BusBase* bus1 = + new PhasorDynamics::BusInfinite(1.0, 0.0); + success *= (bus1 != nullptr); + + // Create an default bus + PhasorDynamics::BusBase* bus2 = + new PhasorDynamics::BusInfinite(1.0, 0.0); + success *= (bus2 != nullptr); + + if (bus1) + { + delete bus1; + } + if (bus2) + { + delete bus2; + } + + return success.report(__func__); + } + + }; + +} // namespace Testing +} // namespace GridKit diff --git a/tests/UnitTests/PhasorDynamics/CMakeLists.txt b/tests/UnitTests/PhasorDynamics/CMakeLists.txt index 7b098fe8c..4179b0252 100644 --- a/tests/UnitTests/PhasorDynamics/CMakeLists.txt +++ b/tests/UnitTests/PhasorDynamics/CMakeLists.txt @@ -1,9 +1,9 @@ -add_executable(test_phasor_bus TestBus.cpp) +add_executable(test_phasor_bus runBusTests.cpp) target_link_libraries(test_phasor_bus GRIDKIT::phasor_dynamics_bus) -add_executable(test_phasor_branch TestBus.cpp) +add_executable(test_phasor_branch runBranchTests.cpp) target_link_libraries(test_phasor_branch GRIDKIT::phasor_dynamics_branch GRIDKIT::phasor_dynamics_bus) diff --git a/tests/UnitTests/PhasorDynamics/TestBranch.cpp b/tests/UnitTests/PhasorDynamics/TestBranch.cpp deleted file mode 100644 index 12d38b60d..000000000 --- a/tests/UnitTests/PhasorDynamics/TestBranch.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include - -#include -#include -#include - -/* - * Compute gradient of an objective function expressed as an integral over - * system trajectory. The gradient is computed numerically and using - * adjoint sensitivity analysis. - * - * The test case is a 4th order generator connected to an infinite bus. - * The objective function is total frequency deviation computed over - * system trajectory after generator short circuit fault. - * - */ -int main() -{ - using namespace GridKit; - using namespace GridKit::Testing; - - int status = 0; - - auto* bus1 = new PhasorDynamics::Bus(1.0, 0.0); - auto* bus2 = new PhasorDynamics::Bus(1.0, 0.1); - - // Create an infinite bus - PhasorDynamics::Component* branch = new PhasorDynamics::Branch(bus1, bus2); - - if (branch != nullptr) - { - delete branch; - } - else - { - status++; - } - - return status; -} \ No newline at end of file diff --git a/tests/UnitTests/PhasorDynamics/TestBus.cpp b/tests/UnitTests/PhasorDynamics/TestBus.cpp deleted file mode 100644 index 2c6c795d8..000000000 --- a/tests/UnitTests/PhasorDynamics/TestBus.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include - -#include -#include -#include - -/* - * Compute gradient of an objective function expressed as an integral over - * system trajectory. The gradient is computed numerically and using - * adjoint sensitivity analysis. - * - * The test case is a 4th order generator connected to an infinite bus. - * The objective function is total frequency deviation computed over - * system trajectory after generator short circuit fault. - * - */ -int main() -{ - using namespace GridKit; - using namespace GridKit::Testing; - - int status = 0; - - // Create an infinite bus - PhasorDynamics::BusBase* bus = new PhasorDynamics::Bus(1.0, 0.0); - - if (bus != nullptr) - { - delete bus; - } - else - { - status++; - } - - bus = new PhasorDynamics::BusInfinite(1.0, 0.0); - - if (bus != nullptr) - { - delete bus; - } - else - { - status++; - } - - return status; -} \ No newline at end of file diff --git a/tests/UnitTests/PhasorDynamics/runBranchTests.cpp b/tests/UnitTests/PhasorDynamics/runBranchTests.cpp new file mode 100644 index 000000000..6f7f69561 --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/runBranchTests.cpp @@ -0,0 +1,14 @@ +#include "BranchTests.hpp" + +int main() +{ + using namespace GridKit; + using namespace GridKit::Testing; + + GridKit::Testing::TestingResults result; + GridKit::Testing::BranchTests test; + + result += test.smoke(); + + return result.summary(); +} \ No newline at end of file diff --git a/tests/UnitTests/PhasorDynamics/runBusTests.cpp b/tests/UnitTests/PhasorDynamics/runBusTests.cpp new file mode 100644 index 000000000..475b55d56 --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/runBusTests.cpp @@ -0,0 +1,14 @@ +#include "BusTests.hpp" + +int main() +{ + using namespace GridKit; + using namespace GridKit::Testing; + + GridKit::Testing::TestingResults result; + GridKit::Testing::BusTests test; + + result += test.smoke(); + + return result.summary(); +} \ No newline at end of file From af2d0f6446019bdcc809bc357dbba3d5c92a2f98 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Tue, 11 Feb 2025 16:55:20 -0500 Subject: [PATCH 05/13] Add simple load component. --- src/Model/PhasorDynamics/Branch/Branch.cpp | 58 ------- src/Model/PhasorDynamics/Branch/Branch.hpp | 58 ------- .../PhasorDynamics/Branch/CMakeLists.txt | 56 ------- src/Model/PhasorDynamics/CMakeLists.txt | 1 + src/Model/PhasorDynamics/Component.hpp | 7 +- src/Model/PhasorDynamics/Load/CMakeLists.txt | 13 ++ src/Model/PhasorDynamics/Load/Load.cpp | 142 ++++++++++++++++++ src/Model/PhasorDynamics/Load/Load.hpp | 109 ++++++++++++++ src/Model/PhasorDynamics/Load/README.md | 29 ++++ tests/UnitTests/PhasorDynamics/CMakeLists.txt | 11 +- tests/UnitTests/PhasorDynamics/LoadTests.hpp | 45 ++++++ .../UnitTests/PhasorDynamics/runLoadTests.cpp | 14 ++ 12 files changed, 366 insertions(+), 177 deletions(-) create mode 100644 src/Model/PhasorDynamics/Load/CMakeLists.txt create mode 100644 src/Model/PhasorDynamics/Load/Load.cpp create mode 100644 src/Model/PhasorDynamics/Load/Load.hpp create mode 100644 src/Model/PhasorDynamics/Load/README.md create mode 100644 tests/UnitTests/PhasorDynamics/LoadTests.hpp create mode 100644 tests/UnitTests/PhasorDynamics/runLoadTests.cpp diff --git a/src/Model/PhasorDynamics/Branch/Branch.cpp b/src/Model/PhasorDynamics/Branch/Branch.cpp index 0433e0caa..eeb224407 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.cpp +++ b/src/Model/PhasorDynamics/Branch/Branch.cpp @@ -1,61 +1,3 @@ -/* - * - * Copyright (c) 2017, Lawrence Livermore National Security, LLC. - * Produced at the Lawrence Livermore National Laboratory. - * Written by Slaven Peles and Duan Nan . - * LLNL-CODE-718378. - * All rights reserved. - * - * This file is part of GridKit™. For details, see github.com/LLNL/GridKit - * Please also read the LICENSE file. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the disclaimer below. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the disclaimer (as noted below) in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of the LLNS/LLNL nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL - * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY - * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * Lawrence Livermore National Laboratory is operated by Lawrence Livermore - * National Security, LLC, for the U.S. Department of Energy, National - * Nuclear Security Administration under Contract DE-AC52-07NA27344. - * - * This document was prepared as an account of work sponsored by an agency - * of the United States government. Neither the United States government nor - * Lawrence Livermore National Security, LLC, nor any of their employees - * makes any warranty, expressed or implied, or assumes any legal liability - * or responsibility for the accuracy, completeness, or usefulness of any - * information, apparatus, product, or process disclosed, or represents that - * its use would not infringe privately owned rights. Reference herein to - * any specific commercial product, process, or service by trade name, - * trademark, manufacturer, or otherwise does not necessarily constitute or - * imply its endorsement, recommendation, or favoring by the United States - * government or Lawrence Livermore National Security, LLC. The views and - * opinions of authors expressed herein do not necessarily state or reflect - * those of the United States government or Lawrence Livermore National - * Security, LLC, and shall not be used for advertising or product - * endorsement purposes. - * - */ #include #include diff --git a/src/Model/PhasorDynamics/Branch/Branch.hpp b/src/Model/PhasorDynamics/Branch/Branch.hpp index 6f3efaa25..1fb2c2460 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.hpp +++ b/src/Model/PhasorDynamics/Branch/Branch.hpp @@ -1,61 +1,3 @@ -/* - * - * Copyright (c) 2017, Lawrence Livermore National Security, LLC. - * Produced at the Lawrence Livermore National Laboratory. - * Written by Slaven Peles and Duan Nan . - * LLNL-CODE-718378. - * All rights reserved. - * - * This file is part of GridKit™. For details, see github.com/LLNL/GridKit - * Please also read the LICENSE file. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the disclaimer below. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the disclaimer (as noted below) in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of the LLNS/LLNL nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL - * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY - * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * Lawrence Livermore National Laboratory is operated by Lawrence Livermore - * National Security, LLC, for the U.S. Department of Energy, National - * Nuclear Security Administration under Contract DE-AC52-07NA27344. - * - * This document was prepared as an account of work sponsored by an agency - * of the United States government. Neither the United States government nor - * Lawrence Livermore National Security, LLC, nor any of their employees - * makes any warranty, expressed or implied, or assumes any legal liability - * or responsibility for the accuracy, completeness, or usefulness of any - * information, apparatus, product, or process disclosed, or represents that - * its use would not infringe privately owned rights. Reference herein to - * any specific commercial product, process, or service by trade name, - * trademark, manufacturer, or otherwise does not necessarily constitute or - * imply its endorsement, recommendation, or favoring by the United States - * government or Lawrence Livermore National Security, LLC. The views and - * opinions of authors expressed herein do not necessarily state or reflect - * those of the United States government or Lawrence Livermore National - * Security, LLC, and shall not be used for advertising or product - * endorsement purposes. - * - */ #pragma once diff --git a/src/Model/PhasorDynamics/Branch/CMakeLists.txt b/src/Model/PhasorDynamics/Branch/CMakeLists.txt index ba05a10a9..b3d400e28 100644 --- a/src/Model/PhasorDynamics/Branch/CMakeLists.txt +++ b/src/Model/PhasorDynamics/Branch/CMakeLists.txt @@ -1,59 +1,3 @@ -# -# Copyright (c) 2017, Lawrence Livermore National Security, LLC. -# Produced at the Lawrence Livermore National Laboratory. -# Written by Slaven Peles . -# LLNL-CODE-718378. -# All rights reserved. -# -# This file is part of GridKit™. For details, see github.com/LLNL/GridKit -# Please also read the LICENSE file. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# - Redistributions of source code must retain the above copyright notice, -# this list of conditions and the disclaimer below. -# - Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the disclaimer (as noted below) in the -# documentation and/or other materials provided with the distribution. -# - Neither the name of the LLNS/LLNL nor the names of its contributors may -# be used to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL -# SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY -# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -# THE POSSIBILITY OF SUCH DAMAGE. -# -# Lawrence Livermore National Laboratory is operated by Lawrence Livermore -# National Security, LLC, for the U.S. Department of Energy, National -# Nuclear Security Administration under Contract DE-AC52-07NA27344. -# -# This document was prepared as an account of work sponsored by an agency -# of the United States government. Neither the United States government nor -# Lawrence Livermore National Security, LLC, nor any of their employees -# makes any warranty, expressed or implied, or assumes any legal liability -# or responsibility for the accuracy, completeness, or usefulness of any -# information, apparatus, product, or process disclosed, or represents that -# its use would not infringe privately owned rights. Reference herein to -# any specific commercial product, process, or service by trade name, -# trademark, manufacturer, or otherwise does not necessarily constitute or -# imply its endorsement, recommendation, or favoring by the United States -# government or Lawrence Livermore National Security, LLC. The views and -# opinions of authors expressed herein do not necessarily state or reflect -# those of the United States government or Lawrence Livermore National -# Security, LLC, and shall not be used for advertising or product -# endorsement purposes. -# # [[ # Author(s): diff --git a/src/Model/PhasorDynamics/CMakeLists.txt b/src/Model/PhasorDynamics/CMakeLists.txt index b9e6ce521..08f9613ef 100644 --- a/src/Model/PhasorDynamics/CMakeLists.txt +++ b/src/Model/PhasorDynamics/CMakeLists.txt @@ -5,3 +5,4 @@ add_subdirectory(Branch) add_subdirectory(Bus) +add_subdirectory(Load) diff --git a/src/Model/PhasorDynamics/Component.hpp b/src/Model/PhasorDynamics/Component.hpp index 74fcb3ef7..3719d4584 100644 --- a/src/Model/PhasorDynamics/Component.hpp +++ b/src/Model/PhasorDynamics/Component.hpp @@ -217,9 +217,9 @@ namespace PhasorDynamics } //@todo Fix ID naming - IdxT getIDcomponent() + IdxT getComponentID() const { - return idc_; + return component_id_; } @@ -255,8 +255,7 @@ namespace PhasorDynamics IdxT max_steps_; - IdxT idc_; - + IdxT component_id_; }; } // namespace PhasorDynamics diff --git a/src/Model/PhasorDynamics/Load/CMakeLists.txt b/src/Model/PhasorDynamics/Load/CMakeLists.txt new file mode 100644 index 000000000..bfcfa6d0a --- /dev/null +++ b/src/Model/PhasorDynamics/Load/CMakeLists.txt @@ -0,0 +1,13 @@ + + +# [[ +# Author(s): +# - Cameron Rutherford +# ]] + +gridkit_add_library(phasor_dynamics_load + SOURCES + Load.cpp + OUTPUT_NAME + gridkit_phasor_dynamics_load) + diff --git a/src/Model/PhasorDynamics/Load/Load.cpp b/src/Model/PhasorDynamics/Load/Load.cpp new file mode 100644 index 000000000..87fd2adf7 --- /dev/null +++ b/src/Model/PhasorDynamics/Load/Load.cpp @@ -0,0 +1,142 @@ + +#include +#include +#include +#include + +#include "Load.hpp" + +namespace GridKit +{ +namespace PhasorDynamics +{ + /*! + * @brief Constructor for a pi-model load + * + * Arguments passed to ModelEvaluatorImpl: + * - Number of equations = 0 + * - Number of independent variables = 0 + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ + + template + Load::Load(bus_type* bus) : bus_(bus) + { + size_ = 0; + } + + template + Load::Load(bus_type* bus, + real_type R, + real_type X) + : bus_(bus), + R_(R), + X_(X) + + { + } + + template + Load::Load(bus_type* bus, IdxT component_id) + : bus_(bus) + + { + size_ = 0; + component_id_ = component_id; + } + + + template + Load::~Load() + { + //std::cout << "Destroy Load..." << std::endl; + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int Load::allocate() + { + //std::cout << "Allocate Load..." << std::endl; + return 0; + } + + /** + * Initialization of the load model + * + */ + template + int Load::initialize() + { + return 0; + } + + /** + * \brief Identify differential variables. + */ + template + int Load::tagDifferentiable() + { + return 0; + } + + /** + * \brief Residual contribution of the load is pushed to the bus. + * + */ + template + int Load::evaluateResidual() + { + real_type b = -X_/(R_*R_ + X_*X_); + real_type g = R_/(R_*R_ + X_*X_); + + Ir() += -g*Vr() - b*Vi(); + Ii() += b*Vr() - g*Vi(); + + return 0; + } + + template + int Load::evaluateJacobian() + { + std::cout << "Evaluate Jacobian for Load..." << std::endl; + std::cout << "Jacobian evaluation not implemented!" << std::endl; + return 0; + } + + template + int Load::evaluateIntegrand() + { + // std::cout << "Evaluate Integrand for Load..." << std::endl; + return 0; + } + + template + int Load::initializeAdjoint() + { + //std::cout << "Initialize adjoint for Load..." << std::endl; + return 0; + } + + template + int Load::evaluateAdjointResidual() + { + // std::cout << "Evaluate adjoint residual for Load..." << std::endl; + return 0; + } + + template + int Load::evaluateAdjointIntegrand() + { + // std::cout << "Evaluate adjoint Integrand for Load..." << std::endl; + return 0; + } + + // Available template instantiations + template class Load; + template class Load; + +} //namespace PhasorDynamics +} //namespace GridKit diff --git a/src/Model/PhasorDynamics/Load/Load.hpp b/src/Model/PhasorDynamics/Load/Load.hpp new file mode 100644 index 000000000..cb65b53e2 --- /dev/null +++ b/src/Model/PhasorDynamics/Load/Load.hpp @@ -0,0 +1,109 @@ + + +#pragma once + +#include + +// Forward declarations. +namespace GridKit +{ +namespace PhasorDynamics +{ + template class Bus; +} +} + +namespace GridKit +{ +namespace PhasorDynamics +{ + /*! + * @brief Implementation of a constant load. + * + */ + template + class Load : public Component + { + using Component::size_; + using Component::nnz_; + using Component::time_; + using Component::alpha_; + using Component::y_; + using Component::yp_; + using Component::tag_; + using Component::f_; + using Component::g_; + using Component::yB_; + using Component::ypB_; + using Component::fB_; + using Component::gB_; + using Component::param_; + using Component::component_id_; + + using bus_type = Bus; + using real_type = typename Component::real_type; + + public: + Load(bus_type* bus); + Load(bus_type* bus, real_type R, real_type X); + Load(bus_type* bus, IdxT component_id); + virtual ~Load(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + void updateTime(real_type /* t */, real_type /* a */) + { + } + + public: + void setR(real_type R) + { + R_ = R; + } + + void setX(real_type X) + { + // std::cout << "Setting X ...\n"; + X_ = X; + } + + private: + ScalarT& Vr() + { + return bus_->Vr(); + } + + ScalarT& Vi() + { + return bus_->Vi(); + } + + ScalarT& Ir() + { + return bus_->Ir(); + } + + ScalarT& Ii() + { + return bus_->Ii(); + } + + + private: + bus_type* bus_{nullptr}; + real_type R_{0.1}; + real_type X_{0.01}; + }; + +} // namespace PhasorDynamics +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/Load/README.md b/src/Model/PhasorDynamics/Load/README.md new file mode 100644 index 000000000..90bb7f9f7 --- /dev/null +++ b/src/Model/PhasorDynamics/Load/README.md @@ -0,0 +1,29 @@ +# Load Model + +Load modeling is one of the more complex aspects of power system dynamics. +The simplest model, which is used for this challenge problem, is to model +the load as a complex shunt impedance with the impedance given by: +``` math +Z = R + jX +``` +where $`R`$ is the load resistance, $`X`$ is the load reactance. The current +drawn by the load is then obtained as +```math +I_{\mathrm{load}} = \frac{V_{\mathrm{bus}}}{Z}, +``` +where $`V_{bus}`$ is the voltage on the bus to which the load is connected. + +After some algebra, one obtains expressions for real and imaginary components +for the currents entering the bus: +```math +I_{r} = -g V_{r} - b V_{i} +``` + +```math +I_{i} = b V_{r} - g V_{i} +``` +where +```math +g = \frac{R}{R^2+X^2} ~~~\mathrm{and}~~~ b = \frac{-X}{R^2+X^2}. +``` + diff --git a/tests/UnitTests/PhasorDynamics/CMakeLists.txt b/tests/UnitTests/PhasorDynamics/CMakeLists.txt index 4179b0252..30cd2bbbe 100644 --- a/tests/UnitTests/PhasorDynamics/CMakeLists.txt +++ b/tests/UnitTests/PhasorDynamics/CMakeLists.txt @@ -1,3 +1,7 @@ +# [[ +# Author(s): +# - Slaven Peles +#]] add_executable(test_phasor_bus runBusTests.cpp) @@ -7,7 +11,12 @@ add_executable(test_phasor_branch runBranchTests.cpp) target_link_libraries(test_phasor_branch GRIDKIT::phasor_dynamics_branch GRIDKIT::phasor_dynamics_bus) +add_executable(test_phasor_load runLoadTests.cpp) +target_link_libraries(test_phasor_load GRIDKIT::phasor_dynamics_load + GRIDKIT::phasor_dynamics_bus) + add_test(NAME PhasorDynamicsBusTest COMMAND $) add_test(NAME PhasorDynamicsBranchTest COMMAND $) +add_test(NAME PhasorDynamicsLoadTest COMMAND $) -install(TARGETS test_phasor_bus test_phasor_branch RUNTIME DESTINATION bin) +install(TARGETS test_phasor_bus test_phasor_branch test_phasor_load RUNTIME DESTINATION bin) diff --git a/tests/UnitTests/PhasorDynamics/LoadTests.hpp b/tests/UnitTests/PhasorDynamics/LoadTests.hpp new file mode 100644 index 000000000..535fc3a27 --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/LoadTests.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include + +namespace GridKit +{ +namespace Testing +{ + class LoadTests + { + public: + LoadTests() = default; + ~LoadTests() = default; + + TestOutcome smoke() + { + TestStatus success; + + auto* bus = new PhasorDynamics::Bus(1.0, 0.0); + + PhasorDynamics::Component* load = + new PhasorDynamics::Load(bus); + + success *= (load != nullptr); + + if (load) + { + delete load; + } + delete bus; + + return success.report(__func__); + } + }; + +} // namespace Testing +} // namespace GridKit + + diff --git a/tests/UnitTests/PhasorDynamics/runLoadTests.cpp b/tests/UnitTests/PhasorDynamics/runLoadTests.cpp new file mode 100644 index 000000000..ded947aeb --- /dev/null +++ b/tests/UnitTests/PhasorDynamics/runLoadTests.cpp @@ -0,0 +1,14 @@ +#include "LoadTests.hpp" + +int main() +{ + using namespace GridKit; + using namespace GridKit::Testing; + + GridKit::Testing::TestingResults result; + GridKit::Testing::LoadTests test; + + result += test.smoke(); + + return result.summary(); +} \ No newline at end of file From a9ae89d16b6fa0fe2ab8c9553bd0b64d4afbd9e5 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Tue, 11 Feb 2025 19:15:36 -0500 Subject: [PATCH 06/13] Add bus tests. --- src/Model/PhasorDynamics/Bus/BusInfinite.cpp | 11 ++- src/Model/PhasorDynamics/Bus/BusInfinite.hpp | 4 +- src/Model/PhasorDynamics/BusBase.hpp | 10 +++ src/Utilities/TestHelpers.hpp | 5 ++ src/Utilities/Testing.hpp | 14 +-- tests/UnitTests/PhasorDynamics/BusTests.hpp | 89 +++++++++++++++---- .../UnitTests/PhasorDynamics/runBusTests.cpp | 5 +- 7 files changed, 108 insertions(+), 30 deletions(-) diff --git a/src/Model/PhasorDynamics/Bus/BusInfinite.cpp b/src/Model/PhasorDynamics/Bus/BusInfinite.cpp index 139659c22..13fda2aa1 100644 --- a/src/Model/PhasorDynamics/Bus/BusInfinite.cpp +++ b/src/Model/PhasorDynamics/Bus/BusInfinite.cpp @@ -110,7 +110,12 @@ int BusInfinite::initialize() } /*! - * @brief PQ bus does not compute residuals, so here we just reset residual values. + * @brief Reset slack currents to zero. + * + * Infinite bus does not compute residuals, so here we just reset + * current values to zero. Components connected to the infinite bus + * will add their currents to Ir_ and Ii_. The resultant will be slack + * current that the infinite bus has to pick up. * * @warning This implementation assumes bus residuals are always evaluated * _before_ component model residuals. @@ -120,8 +125,8 @@ template int BusInfinite::evaluateResidual() { // std::cout << "Evaluating residual of a PQ bus ...\n"; - f_[0] = 0.0; - f_[1] = 0.0; + Ir_ = 0.0; + Ii_ = 0.0; return 0; } diff --git a/src/Model/PhasorDynamics/Bus/BusInfinite.hpp b/src/Model/PhasorDynamics/Bus/BusInfinite.hpp index a77385c89..1decde37e 100644 --- a/src/Model/PhasorDynamics/Bus/BusInfinite.hpp +++ b/src/Model/PhasorDynamics/Bus/BusInfinite.hpp @@ -80,12 +80,12 @@ namespace PhasorDynamics return Vi_; } - virtual ScalarT& Ir() + virtual ScalarT& Ir() override { return Ir_; } - virtual const ScalarT& Ir() const + virtual const ScalarT& Ir() const override { return Ir_; } diff --git a/src/Model/PhasorDynamics/BusBase.hpp b/src/Model/PhasorDynamics/BusBase.hpp index 161a04fa0..47e1c5e9c 100644 --- a/src/Model/PhasorDynamics/BusBase.hpp +++ b/src/Model/PhasorDynamics/BusBase.hpp @@ -97,6 +97,16 @@ namespace PhasorDynamics msa = max_steps_; } + virtual ScalarT& Vr() = 0; + virtual const ScalarT& Vr() const = 0; + virtual ScalarT& Vi() = 0; + virtual const ScalarT& Vi() const = 0; + virtual ScalarT& Ir() = 0; + virtual const ScalarT& Ir() const = 0; + virtual ScalarT& Ii() = 0; + virtual const ScalarT& Ii() const = 0; + + std::vector& y() { return y_; diff --git a/src/Utilities/TestHelpers.hpp b/src/Utilities/TestHelpers.hpp index f0a761766..fb84b470a 100644 --- a/src/Utilities/TestHelpers.hpp +++ b/src/Utilities/TestHelpers.hpp @@ -41,6 +41,11 @@ namespace Testing { } + TestStatus(bool success) + : outcome_(success ? TestOutcome::PASS : TestOutcome::FAIL) + { + } + TestStatus(const char* funcname) : outcome_(TestOutcome::PASS), funcname_(funcname) diff --git a/src/Utilities/Testing.hpp b/src/Utilities/Testing.hpp index f061cdbd1..b5bd9b489 100644 --- a/src/Utilities/Testing.hpp +++ b/src/Utilities/Testing.hpp @@ -69,6 +69,7 @@ #include #include #include +#include namespace { @@ -84,11 +85,14 @@ inline std::ostream &errs() { namespace GridKit { namespace Testing { -template bool isEqual(const T value, const T ref, const T tol) -{ - T error = std::abs(value - ref) / (1.0 + std::abs(ref)); - return (error < tol); -} + template + bool isEqual(const T value, + const T ref, + const T tol = std::numeric_limits::epsilon()) + { + T error = std::abs(value - ref) / (1.0 + std::abs(ref)); + return (error < tol); + } template inline bool isEqual(PowerSystemData::GenCostData a, diff --git a/tests/UnitTests/PhasorDynamics/BusTests.hpp b/tests/UnitTests/PhasorDynamics/BusTests.hpp index bd8b7ad86..a0ec744d2 100644 --- a/tests/UnitTests/PhasorDynamics/BusTests.hpp +++ b/tests/UnitTests/PhasorDynamics/BusTests.hpp @@ -11,35 +11,88 @@ namespace GridKit { namespace Testing { - + template class BusTests { public: BusTests() = default; ~BusTests() = default; - TestOutcome smoke() + /// Constructor, allocation, and initialization checks + TestOutcome constructor() { - TestStatus success; + TestStatus success = true; + + ScalarT Vr{1.0}; + ScalarT Vi{2.0}; + PhasorDynamics::BusBase* bus = nullptr; + // Create an infinite bus - PhasorDynamics::BusBase* bus1 = - new PhasorDynamics::BusInfinite(1.0, 0.0); - success *= (bus1 != nullptr); + bus = new PhasorDynamics::BusInfinite(); + success *= isEqual(bus->Vr(), 0.0); + success *= isEqual(bus->Vi(), 0.0); + delete bus; + + bus = new PhasorDynamics::BusInfinite(Vr, Vi); + success *= isEqual(bus->Vr(), Vr); + success *= isEqual(bus->Vi(), Vi); + delete bus; // Create an default bus - PhasorDynamics::BusBase* bus2 = - new PhasorDynamics::BusInfinite(1.0, 0.0); - success *= (bus2 != nullptr); - - if (bus1) - { - delete bus1; - } - if (bus2) - { - delete bus2; - } + bus = new PhasorDynamics::Bus(); + bus->allocate(); + bus->initialize(); + success *= isEqual(bus->Vr(), 0.0); + success *= isEqual(bus->Vi(), 0.0); + delete bus; + + bus = new PhasorDynamics::Bus(Vr, Vi); + bus->allocate(); + bus->initialize(); + success *= isEqual(bus->Vr(), Vr); + success *= isEqual(bus->Vi(), Vi); + delete bus; + + bus = nullptr; + + return success.report(__func__); + } + + /// Accessor method tests + TestOutcome residual() + { + TestStatus success = true; + + ScalarT Vr{1.0}; + ScalarT Vi{2.0}; + ScalarT Ir{1.0}; + ScalarT Ii{2.0}; + + PhasorDynamics::BusInfinite bus_inf; + bus_inf.Ir() = Ir; + success *= isEqual(bus_inf.Ir(), Ir); + bus_inf.Ii() = Ii; + success *= isEqual(bus_inf.Ii(), Ii); + + bus_inf.evaluateResidual(); + success *= isEqual(bus_inf.Ir(), 0.0); + success *= isEqual(bus_inf.Ii(), 0.0); + + PhasorDynamics::Bus bus(Vr,Vi); + bus.allocate(); + bus.initialize(); + success *= isEqual(bus.Vr(), Vr); + success *= isEqual(bus.Vi(), Vi); + + bus.Ir() = Ir; + success *= isEqual(bus.Ir(), Ir); + bus.Ii() = Ii; + success *= isEqual(bus.Ii(), Ii); + + bus.evaluateResidual(); + success *= isEqual(bus.Ir(), 0.0); + success *= isEqual(bus.Ii(), 0.0); return success.report(__func__); } diff --git a/tests/UnitTests/PhasorDynamics/runBusTests.cpp b/tests/UnitTests/PhasorDynamics/runBusTests.cpp index 475b55d56..0c172ae03 100644 --- a/tests/UnitTests/PhasorDynamics/runBusTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runBusTests.cpp @@ -6,9 +6,10 @@ int main() using namespace GridKit::Testing; GridKit::Testing::TestingResults result; - GridKit::Testing::BusTests test; + GridKit::Testing::BusTests test; - result += test.smoke(); + result += test.constructor(); + result += test.residual(); return result.summary(); } \ No newline at end of file From af922e979a8b905d80692f2f1d26bcacb687790d Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Tue, 11 Feb 2025 20:44:57 -0500 Subject: [PATCH 07/13] Fix warnings in Branch model. --- src/Model/PhasorDynamics/Branch/Branch.cpp | 307 +++++++++--------- src/Model/PhasorDynamics/Branch/Branch.hpp | 6 +- .../UnitTests/PhasorDynamics/BranchTests.hpp | 55 +++- .../PhasorDynamics/runBranchTests.cpp | 2 +- 4 files changed, 208 insertions(+), 162 deletions(-) diff --git a/src/Model/PhasorDynamics/Branch/Branch.cpp b/src/Model/PhasorDynamics/Branch/Branch.cpp index eeb224407..fdaf4a068 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.cpp +++ b/src/Model/PhasorDynamics/Branch/Branch.cpp @@ -6,161 +6,162 @@ #include "Branch.hpp" -namespace GridKit { -namespace PhasorDynamics { - -/*! - * @brief Constructor for a pi-model branch - * - * Arguments passed to ModelEvaluatorImpl: - * - Number of equations = 0 - * - Number of independent variables = 0 - * - Number of quadratures = 0 - * - Number of optimization parameters = 0 - */ - -template -Branch::Branch(bus_type* bus1, bus_type* bus2) - : R_(0.0), - X_(0.01), - G_(0.0), - B_(0.0), - bus1ID_(0), - bus2ID_(0), - bus1_(bus1), - bus2_(bus2) +namespace GridKit { - size_ = 0; -} - -template -Branch::Branch(real_type R, - real_type X, - real_type G, - real_type B, - bus_type* bus1, - bus_type* bus2) - : R_(R), - X_(X), - G_(G), - B_(B), - bus1ID_(0), - bus2ID_(0), - bus1_(bus1), - bus2_(bus2) +namespace PhasorDynamics { -} - -template -Branch::Branch(bus_type* bus1, bus_type* bus2, BranchData& data) - : R_(data.r), - X_(data.x), - G_(0.0), - B_(data.b), - bus1ID_(data.fbus), - bus2ID_(data.tbus), - bus1_(bus1), - bus2_(bus2) -{ - size_ = 0; -} - - -template -Branch::~Branch() -{ - //std::cout << "Destroy Branch..." << std::endl; -} - -/*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ -template -int Branch::allocate() -{ - //std::cout << "Allocate Branch..." << std::endl; - return 0; -} - -/** - * Initialization of the branch model - * - */ -template -int Branch::initialize() -{ - return 0; -} - -/** - * \brief Identify differential variables. - */ -template -int Branch::tagDifferentiable() -{ - return 0; -} - -/** - * \brief Residual contribution of the branch is pushed to the - * two terminal buses. - * - * @todo Add and verify conductance to ground (B and G) - */ -template -int Branch::evaluateResidual() -{ - // std::cout << "Evaluating branch residual ...\n"; - real_type b = -X_/(R_*R_ + X_*X_); - real_type g = R_/(R_*R_ + X_*X_); - - Ir1() += -(g + 0.5*G_)*Vr1() + (b + 0.5*B_)*Vi1() + g*Vr2() - b*Vi2(); - Ii1() += -(b + 0.5*B_)*Vr1() - (g + 0.5*G_)*Vi1() + b*Vr2() + g*Vi2(); - Ir2() += g*Vr1() - b*Vi1() - (g + 0.5*G_)*Vr2() + (b + 0.5*B_)*Vi2(); - Ii2() += b*Vr1() + g*Vi1() - (b + 0.5*B_)*Vr2() - (g + 0.5*G_)*Vi2(); - - return 0; -} - -template -int Branch::evaluateJacobian() -{ - std::cout << "Evaluate Jacobian for Branch..." << std::endl; - std::cout << "Jacobian evaluation not implemented!" << std::endl; - return 0; -} - -template -int Branch::evaluateIntegrand() -{ - // std::cout << "Evaluate Integrand for Branch..." << std::endl; - return 0; -} - -template -int Branch::initializeAdjoint() -{ - //std::cout << "Initialize adjoint for Branch..." << std::endl; - return 0; -} - -template -int Branch::evaluateAdjointResidual() -{ - // std::cout << "Evaluate adjoint residual for Branch..." << std::endl; - return 0; -} - -template -int Branch::evaluateAdjointIntegrand() -{ - // std::cout << "Evaluate adjoint Integrand for Branch..." << std::endl; - return 0; -} - -// Available template instantiations -template class Branch; -template class Branch; + /*! + * @brief Constructor for a pi-model branch + * + * Arguments passed to ModelEvaluatorImpl: + * - Number of equations = 0 + * - Number of independent variables = 0 + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ + + template + Branch::Branch(bus_type* bus1, bus_type* bus2) + : bus1_(bus1), + bus2_(bus2), + R_(0.0), + X_(0.01), + G_(0.0), + B_(0.0), + bus1ID_(0), + bus2ID_(0) + { + size_ = 0; + } + + template + Branch::Branch(bus_type* bus1, + bus_type* bus2, + real_type R, + real_type X, + real_type G, + real_type B) + : bus1_(bus1), + bus2_(bus2), + R_(R), + X_(X), + G_(G), + B_(B), + bus1ID_(0), + bus2ID_(0) + { + } + + template + Branch::Branch(bus_type* bus1, bus_type* bus2, BranchData& data) + : bus1_(bus1), + bus2_(bus2), + R_(data.r), + X_(data.x), + G_(0.0), + B_(data.b), + bus1ID_(data.fbus), + bus2ID_(data.tbus) + { + size_ = 0; + } + + + template + Branch::~Branch() + { + //std::cout << "Destroy Branch..." << std::endl; + } + + /*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ + template + int Branch::allocate() + { + //std::cout << "Allocate Branch..." << std::endl; + return 0; + } + + /** + * Initialization of the branch model + * + */ + template + int Branch::initialize() + { + return 0; + } + + /** + * \brief Identify differential variables. + */ + template + int Branch::tagDifferentiable() + { + return 0; + } + + /** + * \brief Residual contribution of the branch is pushed to the + * two terminal buses. + * + * @todo Add and verify conductance to ground (B and G) + */ + template + int Branch::evaluateResidual() + { + // std::cout << "Evaluating branch residual ...\n"; + real_type b = -X_/(R_*R_ + X_*X_); + real_type g = R_/(R_*R_ + X_*X_); + + Ir1() += -(g + 0.5*G_)*Vr1() + (b + 0.5*B_)*Vi1() + g*Vr2() - b*Vi2(); + Ii1() += -(b + 0.5*B_)*Vr1() - (g + 0.5*G_)*Vi1() + b*Vr2() + g*Vi2(); + Ir2() += g*Vr1() - b*Vi1() - (g + 0.5*G_)*Vr2() + (b + 0.5*B_)*Vi2(); + Ii2() += b*Vr1() + g*Vi1() - (b + 0.5*B_)*Vr2() - (g + 0.5*G_)*Vi2(); + + return 0; + } + + template + int Branch::evaluateJacobian() + { + std::cout << "Evaluate Jacobian for Branch..." << std::endl; + std::cout << "Jacobian evaluation not implemented!" << std::endl; + return 0; + } + + template + int Branch::evaluateIntegrand() + { + // std::cout << "Evaluate Integrand for Branch..." << std::endl; + return 0; + } + + template + int Branch::initializeAdjoint() + { + //std::cout << "Initialize adjoint for Branch..." << std::endl; + return 0; + } + + template + int Branch::evaluateAdjointResidual() + { + // std::cout << "Evaluate adjoint residual for Branch..." << std::endl; + return 0; + } + + template + int Branch::evaluateAdjointIntegrand() + { + // std::cout << "Evaluate adjoint Integrand for Branch..." << std::endl; + return 0; + } + + // Available template instantiations + template class Branch; + template class Branch; } //namespace PhasorDynamics } //namespace GridKit diff --git a/src/Model/PhasorDynamics/Branch/Branch.hpp b/src/Model/PhasorDynamics/Branch/Branch.hpp index 1fb2c2460..063e4c6cb 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.hpp +++ b/src/Model/PhasorDynamics/Branch/Branch.hpp @@ -52,7 +52,7 @@ namespace PhasorDynamics public: Branch(bus_type* bus1, bus_type* bus2); - Branch(real_type R, real_type X, real_type G, real_type B, bus_type* bus1, bus_type* bus2); + Branch(bus_type* bus1, bus_type* bus2, real_type R, real_type X, real_type G, real_type B); Branch(bus_type* bus1, bus_type* bus2, BranchData& data); virtual ~Branch(); @@ -136,14 +136,14 @@ namespace PhasorDynamics } private: + bus_type* bus1_; + bus_type* bus2_; real_type R_; real_type X_; real_type G_; real_type B_; const IdxT bus1ID_; const IdxT bus2ID_; - bus_type* bus1_; - bus_type* bus2_; }; } // namespace PhasorDynamics diff --git a/tests/UnitTests/PhasorDynamics/BranchTests.hpp b/tests/UnitTests/PhasorDynamics/BranchTests.hpp index a85f7d4e3..661e7a867 100644 --- a/tests/UnitTests/PhasorDynamics/BranchTests.hpp +++ b/tests/UnitTests/PhasorDynamics/BranchTests.hpp @@ -11,6 +11,7 @@ namespace GridKit namespace Testing { + template class BranchTests { public: @@ -19,13 +20,57 @@ namespace Testing TestOutcome smoke() { - TestStatus success; + TestStatus success = true; - auto* bus1 = new PhasorDynamics::Bus(1.0, 0.0); - auto* bus2 = new PhasorDynamics::Bus(1.0, 0.1); + auto* bus1 = new PhasorDynamics::Bus(1.0, 0.0); + auto* bus2 = new PhasorDynamics::Bus(1.0, 0.1); - PhasorDynamics::Component* branch = - new PhasorDynamics::Branch(bus1, bus2); + PhasorDynamics::Component* branch = + new PhasorDynamics::Branch(bus1, bus2); + + success *= (branch != nullptr); + + if (branch) + { + delete branch; + } + delete bus1; + delete bus2; + + return success.report(__func__); + } + + TestOutcome accessors() + { + TestStatus success = true; + + auto* bus1 = new PhasorDynamics::Bus(1.0, 0.0); + auto* bus2 = new PhasorDynamics::Bus(1.0, 0.1); + + PhasorDynamics::Component* branch = + new PhasorDynamics::Branch(bus1, bus2); + + success *= (branch != nullptr); + + if (branch) + { + delete branch; + } + delete bus1; + delete bus2; + + return success.report(__func__); + } + + TestOutcome residual() + { + TestStatus success = true; + + auto* bus1 = new PhasorDynamics::Bus(1.0, 0.0); + auto* bus2 = new PhasorDynamics::Bus(1.0, 0.1); + + PhasorDynamics::Component* branch = + new PhasorDynamics::Branch(bus1, bus2); success *= (branch != nullptr); diff --git a/tests/UnitTests/PhasorDynamics/runBranchTests.cpp b/tests/UnitTests/PhasorDynamics/runBranchTests.cpp index 6f7f69561..541035ca2 100644 --- a/tests/UnitTests/PhasorDynamics/runBranchTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runBranchTests.cpp @@ -6,7 +6,7 @@ int main() using namespace GridKit::Testing; GridKit::Testing::TestingResults result; - GridKit::Testing::BranchTests test; + GridKit::Testing::BranchTests test; result += test.smoke(); From f987e0bdcf325b5d351ea48db4a78da3adbbf57c Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Tue, 11 Feb 2025 21:43:37 -0500 Subject: [PATCH 08/13] Add load tests. --- src/Model/PhasorDynamics/Bus/BusInfinite.cpp | 7 ---- src/Model/PhasorDynamics/Component.hpp | 2 +- src/Model/PhasorDynamics/Load/Load.hpp | 2 +- tests/UnitTests/PhasorDynamics/LoadTests.hpp | 38 ++++++++++++++++--- .../UnitTests/PhasorDynamics/runLoadTests.cpp | 5 ++- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/Model/PhasorDynamics/Bus/BusInfinite.cpp b/src/Model/PhasorDynamics/Bus/BusInfinite.cpp index 13fda2aa1..ee8e6b2de 100644 --- a/src/Model/PhasorDynamics/Bus/BusInfinite.cpp +++ b/src/Model/PhasorDynamics/Bus/BusInfinite.cpp @@ -150,10 +150,6 @@ template int BusInfinite::initializeAdjoint() { // std::cout << "Initialize BusInfinite..." << std::endl; - yB_[0] = 0.0; - yB_[1] = 0.0; - ypB_[0] = 0.0; - ypB_[1] = 0.0; return 0; } @@ -168,9 +164,6 @@ int BusInfinite::initializeAdjoint() template int BusInfinite::evaluateAdjointResidual() { - fB_[0] = 0.0; - fB_[1] = 0.0; - return 0; } diff --git a/src/Model/PhasorDynamics/Component.hpp b/src/Model/PhasorDynamics/Component.hpp index 3719d4584..18a8b54b7 100644 --- a/src/Model/PhasorDynamics/Component.hpp +++ b/src/Model/PhasorDynamics/Component.hpp @@ -16,7 +16,7 @@ namespace PhasorDynamics class Component : public ModelEvaluator { public: - typedef typename ModelEvaluator::real_type real_type; + using real_type = typename ModelEvaluator::real_type; Component() : size_(0), diff --git a/src/Model/PhasorDynamics/Load/Load.hpp b/src/Model/PhasorDynamics/Load/Load.hpp index cb65b53e2..b7ffad605 100644 --- a/src/Model/PhasorDynamics/Load/Load.hpp +++ b/src/Model/PhasorDynamics/Load/Load.hpp @@ -40,7 +40,7 @@ namespace PhasorDynamics using Component::param_; using Component::component_id_; - using bus_type = Bus; + using bus_type = BusBase; using real_type = typename Component::real_type; public: diff --git a/tests/UnitTests/PhasorDynamics/LoadTests.hpp b/tests/UnitTests/PhasorDynamics/LoadTests.hpp index 535fc3a27..ecda1301d 100644 --- a/tests/UnitTests/PhasorDynamics/LoadTests.hpp +++ b/tests/UnitTests/PhasorDynamics/LoadTests.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -12,20 +13,23 @@ namespace GridKit { namespace Testing { + template class LoadTests { public: + using real_type = typename PhasorDynamics::Component::real_type; + LoadTests() = default; ~LoadTests() = default; - TestOutcome smoke() + TestOutcome constructor() { - TestStatus success; + TestStatus success = true; - auto* bus = new PhasorDynamics::Bus(1.0, 0.0); + auto* bus = new PhasorDynamics::Bus(1.0, 0.0); - PhasorDynamics::Component* load = - new PhasorDynamics::Load(bus); + PhasorDynamics::Component* load = + new PhasorDynamics::Load(bus); success *= (load != nullptr); @@ -37,6 +41,30 @@ namespace Testing return success.report(__func__); } + + TestOutcome residual() + { + TestStatus success = true; + + real_type R{2.0}; ///< Load resistance + real_type X{4.0}; ///< Load reactance + + ScalarT Vr{10.0}; ///< Bus real voltage + ScalarT Vi{20.0}; ///< Bus imaginary voltage + + const ScalarT Ir{3.0}; ///< Solution real current + const ScalarT Ii{-4.0}; ///< Solution imaginary current + + PhasorDynamics::BusInfinite bus(Vr, Vi); + + PhasorDynamics::Load load(&bus, R, X); + load.evaluateResidual(); + + success *= isEqual(bus.Ir(), Ir); + success *= isEqual(bus.Ii(), Ii); + + return success.report(__func__); + } }; } // namespace Testing diff --git a/tests/UnitTests/PhasorDynamics/runLoadTests.cpp b/tests/UnitTests/PhasorDynamics/runLoadTests.cpp index ded947aeb..471099859 100644 --- a/tests/UnitTests/PhasorDynamics/runLoadTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runLoadTests.cpp @@ -6,9 +6,10 @@ int main() using namespace GridKit::Testing; GridKit::Testing::TestingResults result; - GridKit::Testing::LoadTests test; + GridKit::Testing::LoadTests test; - result += test.smoke(); + result += test.constructor(); + result += test.residual(); return result.summary(); } \ No newline at end of file From 28a22d70b8675da90bb5d87a8f3319a0f5e238d1 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Tue, 11 Feb 2025 22:06:28 -0500 Subject: [PATCH 09/13] Minor cleanup for Branch tests. --- src/Model/PhasorDynamics/Branch/Branch.cpp | 1 - .../UnitTests/PhasorDynamics/BranchTests.hpp | 36 ++----------------- .../PhasorDynamics/runBranchTests.cpp | 4 ++- 3 files changed, 6 insertions(+), 35 deletions(-) diff --git a/src/Model/PhasorDynamics/Branch/Branch.cpp b/src/Model/PhasorDynamics/Branch/Branch.cpp index fdaf4a068..edf8ae3c7 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.cpp +++ b/src/Model/PhasorDynamics/Branch/Branch.cpp @@ -19,7 +19,6 @@ namespace PhasorDynamics * - Number of quadratures = 0 * - Number of optimization parameters = 0 */ - template Branch::Branch(bus_type* bus1, bus_type* bus2) : bus1_(bus1), diff --git a/tests/UnitTests/PhasorDynamics/BranchTests.hpp b/tests/UnitTests/PhasorDynamics/BranchTests.hpp index 661e7a867..6bd71b378 100644 --- a/tests/UnitTests/PhasorDynamics/BranchTests.hpp +++ b/tests/UnitTests/PhasorDynamics/BranchTests.hpp @@ -18,7 +18,7 @@ namespace Testing BranchTests() = default; ~BranchTests() = default; - TestOutcome smoke() + TestOutcome constructor() { TestStatus success = true; @@ -43,44 +43,14 @@ namespace Testing TestOutcome accessors() { TestStatus success = true; - - auto* bus1 = new PhasorDynamics::Bus(1.0, 0.0); - auto* bus2 = new PhasorDynamics::Bus(1.0, 0.1); - - PhasorDynamics::Component* branch = - new PhasorDynamics::Branch(bus1, bus2); - - success *= (branch != nullptr); - - if (branch) - { - delete branch; - } - delete bus1; - delete bus2; - + success.skipTest(); return success.report(__func__); } TestOutcome residual() { TestStatus success = true; - - auto* bus1 = new PhasorDynamics::Bus(1.0, 0.0); - auto* bus2 = new PhasorDynamics::Bus(1.0, 0.1); - - PhasorDynamics::Component* branch = - new PhasorDynamics::Branch(bus1, bus2); - - success *= (branch != nullptr); - - if (branch) - { - delete branch; - } - delete bus1; - delete bus2; - + success.skipTest(); return success.report(__func__); } }; diff --git a/tests/UnitTests/PhasorDynamics/runBranchTests.cpp b/tests/UnitTests/PhasorDynamics/runBranchTests.cpp index 541035ca2..ea809536b 100644 --- a/tests/UnitTests/PhasorDynamics/runBranchTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runBranchTests.cpp @@ -8,7 +8,9 @@ int main() GridKit::Testing::TestingResults result; GridKit::Testing::BranchTests test; - result += test.smoke(); + result += test.constructor(); + result += test.accessors(); + result += test.residual(); return result.summary(); } \ No newline at end of file From 581fe735fe6a66f9621f0d4fe2c2bfacfd334db6 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Mon, 17 Feb 2025 15:44:49 -0500 Subject: [PATCH 10/13] Add comprehensive Branch tests. --- src/Model/PhasorDynamics/Branch/Branch.hpp | 2 +- .../UnitTests/PhasorDynamics/BranchTests.hpp | 98 ++++++++++++++++++- 2 files changed, 94 insertions(+), 6 deletions(-) diff --git a/src/Model/PhasorDynamics/Branch/Branch.hpp b/src/Model/PhasorDynamics/Branch/Branch.hpp index 063e4c6cb..5087c7a02 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.hpp +++ b/src/Model/PhasorDynamics/Branch/Branch.hpp @@ -46,7 +46,7 @@ namespace PhasorDynamics using Component::gB_; using Component::param_; - using bus_type = Bus; + using bus_type = BusBase; using real_type = typename Component::real_type; using BranchData = GridKit::PowerSystemData::BranchData; diff --git a/tests/UnitTests/PhasorDynamics/BranchTests.hpp b/tests/UnitTests/PhasorDynamics/BranchTests.hpp index 6bd71b378..103f7af1a 100644 --- a/tests/UnitTests/PhasorDynamics/BranchTests.hpp +++ b/tests/UnitTests/PhasorDynamics/BranchTests.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -14,6 +15,9 @@ namespace Testing template class BranchTests { + private: + using real_type = typename PhasorDynamics::Component::real_type; + public: BranchTests() = default; ~BranchTests() = default; @@ -40,20 +44,104 @@ namespace Testing return success.report(__func__); } - TestOutcome accessors() + TestOutcome residual() { TestStatus success = true; - success.skipTest(); + + real_type R{2.0}; ///< Branch series resistance + real_type X{4.0}; ///< Branch series reactance + real_type G{0.2}; ///< Branch shunt conductance + real_type B{1.2}; ///< Branch shunt charging + + ScalarT Vr1{10.0}; ///< Bus-1 real voltage + ScalarT Vi1{20.0}; ///< Bus-1 imaginary voltage + ScalarT Vr2{30.0}; ///< Bus-2 real voltage + ScalarT Vi2{40.0}; ///< Bus-2 imaginary voltage + + const ScalarT Ir1{17.0}; ///< Solution: real current entering bus-1 + const ScalarT Ii1{-10.0}; ///< Solution: imaginary current entering bus-1 + const ScalarT Ir2{15.0}; ///< Solution: real current entering bus-2 + const ScalarT Ii2{-20.0}; ///< Solution: imaginary current entering bus-2 + + + PhasorDynamics::BusInfinite bus1(Vr1, Vi1); + PhasorDynamics::BusInfinite bus2(Vr2, Vi2); + + PhasorDynamics::Branch branch(&bus1, &bus2, R, X, G, B); + branch.evaluateResidual(); + + success *= isEqual(bus1.Ir(), Ir1); + success *= isEqual(bus1.Ii(), Ii1); + success *= isEqual(bus2.Ir(), Ir2); + success *= isEqual(bus2.Ii(), Ii2); + return success.report(__func__); } - TestOutcome residual() + TestOutcome accessors() { TestStatus success = true; - success.skipTest(); + + const real_type zero{0.0}; + + real_type R{2.0}; ///< Branch series resistance + real_type X{4.0}; ///< Branch series reactance + real_type G{0.2}; ///< Branch shunt conductance + real_type B{1.2}; ///< Branch shunt charging + + ScalarT Vr1{-1.0}; ///< Bus-1 real voltage + ScalarT Vi1{-1.0}; ///< Bus-1 imaginary voltage + ScalarT Vr2{1.0}; ///< Bus-2 real voltage + ScalarT Vi2{1.0}; ///< Bus-2 imaginary voltage + + const ScalarT res_R{1.0}; ///< Solution: real current entering bus-1 + const ScalarT res_X{0.5}; ///< Solution: imaginary current entering bus-1 + const ScalarT res_G{3.0}; ///< Solution: real current entering bus-2 + const ScalarT res_B{-4.0}; ///< Solution: imaginary current entering bus-2 + + + PhasorDynamics::BusInfinite bus1(Vr1, Vi1); + PhasorDynamics::BusInfinite bus2(Vr2, Vi2); + + PhasorDynamics::Branch branch(&bus1, + &bus2, + zero, + zero, + zero, + zero); + + // Test setting branch series resistance + branch.setR(R); + bus1.evaluateResidual(); // <- set Ir1 to zero + branch.evaluateResidual(); + success *= isEqual(bus1.Ir(), res_R); + branch.setR(zero); + + // Test setting branch series reactance + branch.setX(X); + bus1.evaluateResidual(); // <- set Ir1 to zero + branch.evaluateResidual(); + success *= isEqual(bus1.Ir(), res_X); + branch.setX(zero); + return success.report(__func__); + + // Test setting branch shunt conductance + branch.setG(G); + bus1.evaluateResidual(); // <- set Ir1 to zero + branch.evaluateResidual(); + success *= isEqual(bus1.Ir(), res_G); + branch.setG(zero); + + // Test setting branch shunt charging + branch.setB(B); + bus1.evaluateResidual(); // <- set Ir1 to zero + branch.evaluateResidual(); + success *= isEqual(bus1.Ir(), res_B); + branch.setB(zero); + return success.report(__func__); } - }; + }; // class BranchTest } // namespace Testing } // namespace GridKit From 4957802dd0bba0e766cb80d16896180b652d5fa8 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Mon, 17 Feb 2025 16:11:15 -0500 Subject: [PATCH 11/13] New Model::Evaluator* --- src/Model/EvaluatorDynamics.hpp | 96 ++++++++++++++++++++++++++ src/Model/PhasorDynamics/BusBase.hpp | 14 ++-- src/Model/PhasorDynamics/Component.hpp | 14 ++-- 3 files changed, 110 insertions(+), 14 deletions(-) create mode 100644 src/Model/EvaluatorDynamics.hpp diff --git a/src/Model/EvaluatorDynamics.hpp b/src/Model/EvaluatorDynamics.hpp new file mode 100644 index 000000000..ffa7ad7c5 --- /dev/null +++ b/src/Model/EvaluatorDynamics.hpp @@ -0,0 +1,96 @@ +#pragma once + +#include +#include +#include + +namespace GridKit +{ +namespace Model +{ + /*! + * @brief Abstract class describing a model. + * + */ + template + class EvaluatorDynamics + { + public: + typedef typename GridKit::ScalarTraits::real_type real_type; + + EvaluatorDynamics(){} + virtual ~EvaluatorDynamics(){} + + virtual int allocate() = 0; + virtual int initialize() = 0; + virtual int tagDifferentiable() = 0; + virtual int evaluateResidual() = 0; + virtual int evaluateJacobian() = 0; + virtual int evaluateIntegrand() = 0; + + virtual int initializeAdjoint() = 0; + virtual int evaluateAdjointResidual() = 0; + // virtual int evaluateAdjointJacobian() = 0; + virtual int evaluateAdjointIntegrand() = 0; + + virtual IdxT size() = 0; + virtual IdxT nnz() = 0; + + /** + * @brief Is the Jacobian defined. Used in IDA to determine wether DQ is used or not + * + * @return true + * @return false + */ + virtual bool hasJacobian() = 0; + + virtual IdxT sizeQuadrature() = 0; + virtual IdxT sizeParams() = 0; + virtual void updateTime(real_type t, real_type a) = 0; + virtual void setTolerances(real_type& rtol, real_type& atol) const = 0; + virtual void setMaxSteps(IdxT& msa) const = 0; + + virtual std::vector& y() = 0; + virtual const std::vector& y() const = 0; + + virtual std::vector& yp() = 0; + virtual const std::vector& yp() const = 0; + + virtual std::vector& tag() = 0; + virtual const std::vector& tag() const = 0; + + virtual std::vector& yB() = 0; + virtual const std::vector& yB() const = 0; + + virtual std::vector& ypB() = 0; + virtual const std::vector& ypB() const = 0; + + virtual std::vector& param() = 0; + virtual const std::vector& param() const = 0; + + virtual std::vector& param_up() = 0; + virtual const std::vector& param_up() const = 0; + + virtual std::vector& param_lo() = 0; + virtual const std::vector& param_lo() const = 0; + + virtual std::vector& getResidual() = 0; + virtual const std::vector& getResidual() const = 0; + + + virtual COO_Matrix& getJacobian() = 0; + virtual const COO_Matrix& getJacobian() const = 0; + + virtual std::vector& getIntegrand() = 0; + virtual const std::vector& getIntegrand() const = 0; + + virtual std::vector& getAdjointResidual() = 0; + virtual const std::vector& getAdjointResidual() const = 0; + + virtual std::vector& getAdjointIntegrand() = 0; + virtual const std::vector& getAdjointIntegrand() const = 0; + + }; + +} // namespace Model +} // namespace GridKit diff --git a/src/Model/PhasorDynamics/BusBase.hpp b/src/Model/PhasorDynamics/BusBase.hpp index 47e1c5e9c..2911fbda8 100644 --- a/src/Model/PhasorDynamics/BusBase.hpp +++ b/src/Model/PhasorDynamics/BusBase.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include namespace GridKit { @@ -12,10 +12,10 @@ namespace PhasorDynamics * */ template - class BusBase : public ModelEvaluator + class BusBase : public Model::EvaluatorDynamics { public: - using real_type = typename ModelEvaluator::real_type; + using real_type = typename Model::EvaluatorDynamics::real_type; enum BusType{DEFAULT=1, SLACK}; @@ -30,10 +30,10 @@ namespace PhasorDynamics { } - BusBase(IdxT size, IdxT size_quad, IdxT size_opt) + BusBase(IdxT size, IdxT size_quad, IdxT size_param) : size_(size), size_quad_(size_quad), - size_param_(size_opt), + size_param_(size_param), y_(size_), yp_(size_), f_(size_), @@ -71,12 +71,12 @@ namespace PhasorDynamics return false; } - virtual IdxT size_quad() + virtual IdxT sizeQuadrature() { return size_quad_; } - virtual IdxT size_opt() + virtual IdxT sizeParams() { return size_param_; } diff --git a/src/Model/PhasorDynamics/Component.hpp b/src/Model/PhasorDynamics/Component.hpp index 18a8b54b7..672e63b19 100644 --- a/src/Model/PhasorDynamics/Component.hpp +++ b/src/Model/PhasorDynamics/Component.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include namespace GridKit { @@ -13,10 +13,10 @@ namespace PhasorDynamics * */ template - class Component : public ModelEvaluator + class Component : public Model::EvaluatorDynamics { public: - using real_type = typename ModelEvaluator::real_type; + using real_type = typename Model::EvaluatorDynamics::real_type; Component() : size_(0), @@ -24,10 +24,10 @@ namespace PhasorDynamics size_param_(0) {} - Component(IdxT size, IdxT size_quad, IdxT size_opt) + Component(IdxT size, IdxT size_quad, IdxT size_param) : size_(size), size_quad_(size_quad), - size_param_(size_opt), + size_param_(size_param), y_(size_), yp_(size_), f_(size_), @@ -58,12 +58,12 @@ namespace PhasorDynamics return false; } - virtual IdxT size_quad() + virtual IdxT sizeQuadrature() { return size_quad_; } - virtual IdxT size_opt() + virtual IdxT sizeParams() { return size_param_; } From 525c5d024bad6e3759a9c149d98ee835a1caeb84 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Mon, 17 Feb 2025 16:45:21 -0500 Subject: [PATCH 12/13] Use override keyword in phasor dynamics models. --- src/Model/PhasorDynamics/Branch/Branch.hpp | 26 +++--- src/Model/PhasorDynamics/Bus/Bus.hpp | 94 ++++++++++---------- src/Model/PhasorDynamics/Bus/BusInfinite.hpp | 90 +++++++++---------- src/Model/PhasorDynamics/BusBase.hpp | 54 +++++------ src/Model/PhasorDynamics/Component.hpp | 54 +++++------ src/Model/PhasorDynamics/Load/Load.hpp | 26 +++--- 6 files changed, 172 insertions(+), 172 deletions(-) diff --git a/src/Model/PhasorDynamics/Branch/Branch.hpp b/src/Model/PhasorDynamics/Branch/Branch.hpp index 5087c7a02..cd309def9 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.hpp +++ b/src/Model/PhasorDynamics/Branch/Branch.hpp @@ -56,19 +56,19 @@ namespace PhasorDynamics Branch(bus_type* bus1, bus_type* bus2, BranchData& data); virtual ~Branch(); - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); - - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - void updateTime(real_type /* t */, real_type /* a */) + virtual int allocate() override; + virtual int initialize() override; + virtual int tagDifferentiable() override; + virtual int evaluateResidual() override; + virtual int evaluateJacobian() override; + virtual int evaluateIntegrand() override; + + virtual int initializeAdjoint() override; + virtual int evaluateAdjointResidual() override; + // virtual int evaluateAdjointJacobian() override; + virtual int evaluateAdjointIntegrand() override; + + virtual void updateTime(real_type /* t */, real_type /* a */) override { } diff --git a/src/Model/PhasorDynamics/Bus/Bus.hpp b/src/Model/PhasorDynamics/Bus/Bus.hpp index a1426d82a..1f34a4925 100644 --- a/src/Model/PhasorDynamics/Bus/Bus.hpp +++ b/src/Model/PhasorDynamics/Bus/Bus.hpp @@ -63,85 +63,85 @@ namespace PhasorDynamics return BusBase::BusType::DEFAULT; } - virtual ScalarT& Vr() + virtual ScalarT& Vr() override { return y_[0]; } - virtual const ScalarT& Vr() const + virtual const ScalarT& Vr() const override { return y_[0]; } - virtual ScalarT& Vi() + virtual ScalarT& Vi() override { return y_[1]; } - virtual const ScalarT& Vi() const + virtual const ScalarT& Vi() const override { return y_[1]; } - virtual ScalarT& Ir() + virtual ScalarT& Ir() override { return f_[0]; } - virtual const ScalarT& Ir() const + virtual const ScalarT& Ir() const override { return f_[0]; } - virtual ScalarT& Ii() + virtual ScalarT& Ii() override { return f_[1]; } - virtual const ScalarT& Ii() const + virtual const ScalarT& Ii() const override { return f_[1]; } - virtual ScalarT& VrB() - { - return yB_[0]; - } - - virtual const ScalarT& VrB() const - { - return yB_[0]; - } - - virtual ScalarT& ViB() - { - return yB_[1]; - } - - virtual const ScalarT& ViB() const - { - return yB_[1]; - } - - virtual ScalarT& IrB() - { - return fB_[0]; - } - - virtual const ScalarT& IrB() const - { - return fB_[0]; - } - - virtual ScalarT& IiB() - { - return fB_[1]; - } - - virtual const ScalarT& IiB() const - { - return fB_[1]; - } + // virtual ScalarT& VrB() override + // { + // return yB_[0]; + // } + + // virtual const ScalarT& VrB() const override + // { + // return yB_[0]; + // } + + // virtual ScalarT& ViB() override + // { + // return yB_[1]; + // } + + // virtual const ScalarT& ViB() const override + // { + // return yB_[1]; + // } + + // virtual ScalarT& IrB() override + // { + // return fB_[0]; + // } + + // virtual const ScalarT& IrB() const override + // { + // return fB_[0]; + // } + + // virtual ScalarT& IiB() override + // { + // return fB_[1]; + // } + + // virtual const ScalarT& IiB() const override + // { + // return fB_[1]; + // } private: ScalarT Vr0_{0.0}; diff --git a/src/Model/PhasorDynamics/Bus/BusInfinite.hpp b/src/Model/PhasorDynamics/Bus/BusInfinite.hpp index 1decde37e..56aa60644 100644 --- a/src/Model/PhasorDynamics/Bus/BusInfinite.hpp +++ b/src/Model/PhasorDynamics/Bus/BusInfinite.hpp @@ -60,22 +60,22 @@ namespace PhasorDynamics return BusBase::BusType::SLACK; } - virtual ScalarT& Vr() + virtual ScalarT& Vr() override { return Vr_; } - virtual const ScalarT& Vr() const + virtual const ScalarT& Vr() const override { return Vr_; } - virtual ScalarT& Vi() + virtual ScalarT& Vi() override { return Vi_; } - virtual const ScalarT& Vi() const + virtual const ScalarT& Vi() const override { return Vi_; } @@ -90,55 +90,55 @@ namespace PhasorDynamics return Ir_; } - virtual ScalarT& Ii() + virtual ScalarT& Ii() override { return Ii_; } - virtual const ScalarT& Ii() const + virtual const ScalarT& Ii() const override { return Ii_; } - virtual ScalarT& VrB() - { - return VrB_; - } - - virtual const ScalarT& VrB() const - { - return VrB_; - } - - virtual ScalarT& ViB() - { - return ViB_; - } - - virtual const ScalarT& ViB() const - { - return ViB_; - } - - virtual ScalarT& IrB() - { - return IrB_; - } - - virtual const ScalarT& IrB() const - { - return IrB_; - } - - virtual ScalarT& IiB() - { - return IiB_; - } - - virtual const ScalarT& IiB() const - { - return IiB_; - } + // virtual ScalarT& VrB() override + // { + // return VrB_; + // } + + // virtual const ScalarT& VrB() const override + // { + // return VrB_; + // } + + // virtual ScalarT& ViB() override + // { + // return ViB_; + // } + + // virtual const ScalarT& ViB() const override + // { + // return ViB_; + // } + + // virtual ScalarT& IrB() override + // { + // return IrB_; + // } + + // virtual const ScalarT& IrB() const override + // { + // return IrB_; + // } + + // virtual ScalarT& IiB() override + // { + // return IiB_; + // } + + // virtual const ScalarT& IiB() const override + // { + // return IiB_; + // } private: ScalarT Vr_{0.0}; diff --git a/src/Model/PhasorDynamics/BusBase.hpp b/src/Model/PhasorDynamics/BusBase.hpp index 2911fbda8..6a94c6476 100644 --- a/src/Model/PhasorDynamics/BusBase.hpp +++ b/src/Model/PhasorDynamics/BusBase.hpp @@ -56,7 +56,7 @@ namespace PhasorDynamics /// Pure virtual function, returns bus type (DEFAULT or SLACK). virtual int BusType() const = 0; - virtual IdxT size() + virtual IdxT size() override { return size_; } @@ -71,12 +71,12 @@ namespace PhasorDynamics return false; } - virtual IdxT sizeQuadrature() + virtual IdxT sizeQuadrature() override { return size_quad_; } - virtual IdxT sizeParams() + virtual IdxT sizeParams() override { return size_param_; } @@ -107,92 +107,92 @@ namespace PhasorDynamics virtual const ScalarT& Ii() const = 0; - std::vector& y() + std::vector& y() override { return y_; } - const std::vector& y() const + const std::vector& y() const override { return y_; } - std::vector& yp() + std::vector& yp() override { return yp_; } - const std::vector& yp() const + const std::vector& yp() const override { return yp_; } - std::vector& tag() + std::vector& tag() override { return tag_; } - const std::vector& tag() const + const std::vector& tag() const override { return tag_; } - std::vector& yB() + std::vector& yB() override { return yB_; } - const std::vector& yB() const + const std::vector& yB() const override { return yB_; } - std::vector& ypB() + std::vector& ypB() override { return ypB_; } - const std::vector& ypB() const + const std::vector& ypB() const override { return ypB_; } - std::vector& param() + std::vector& param() override { return param_; } - const std::vector& param() const + const std::vector& param() const override { return param_; } - std::vector& param_up() + std::vector& param_up() override { return param_up_; } - const std::vector& param_up() const + const std::vector& param_up() const override { return param_up_; } - std::vector& param_lo() + std::vector& param_lo() override { return param_lo_; } - const std::vector& param_lo() const + const std::vector& param_lo() const override { return param_lo_; } - std::vector& getResidual() + std::vector& getResidual() override { return f_; } - const std::vector& getResidual() const + const std::vector& getResidual() const override { return f_; } @@ -207,32 +207,32 @@ namespace PhasorDynamics return J_; } - std::vector& getIntegrand() + std::vector& getIntegrand() override { return g_; } - const std::vector& getIntegrand() const + const std::vector& getIntegrand() const override { return g_; } - std::vector& getAdjointResidual() + std::vector& getAdjointResidual() override { return fB_; } - const std::vector& getAdjointResidual() const + const std::vector& getAdjointResidual() const override { return fB_; } - std::vector& getAdjointIntegrand() + std::vector& getAdjointIntegrand() override { return gB_; } - const std::vector& getAdjointIntegrand() const + const std::vector& getAdjointIntegrand() const override { return gB_; } diff --git a/src/Model/PhasorDynamics/Component.hpp b/src/Model/PhasorDynamics/Component.hpp index 672e63b19..deb83cd88 100644 --- a/src/Model/PhasorDynamics/Component.hpp +++ b/src/Model/PhasorDynamics/Component.hpp @@ -43,7 +43,7 @@ namespace PhasorDynamics { } - virtual IdxT size() + virtual IdxT size() override { return size_; } @@ -58,12 +58,12 @@ namespace PhasorDynamics return false; } - virtual IdxT sizeQuadrature() + virtual IdxT sizeQuadrature() override { return size_quad_; } - virtual IdxT sizeParams() + virtual IdxT sizeParams() override { return size_param_; } @@ -86,92 +86,92 @@ namespace PhasorDynamics msa = max_steps_; } - std::vector& y() + std::vector& y() override { return y_; } - const std::vector& y() const + const std::vector& y() const override { return y_; } - std::vector& yp() + std::vector& yp() override { return yp_; } - const std::vector& yp() const + const std::vector& yp() const override { return yp_; } - std::vector& tag() + std::vector& tag() override { return tag_; } - const std::vector& tag() const + const std::vector& tag() const override { return tag_; } - std::vector& yB() + std::vector& yB() override { return yB_; } - const std::vector& yB() const + const std::vector& yB() const override { return yB_; } - std::vector& ypB() + std::vector& ypB() override { return ypB_; } - const std::vector& ypB() const + const std::vector& ypB() const override { return ypB_; } - std::vector& param() + std::vector& param() override { return param_; } - const std::vector& param() const + const std::vector& param() const override { return param_; } - std::vector& param_up() + std::vector& param_up() override { return param_up_; } - const std::vector& param_up() const + const std::vector& param_up() const override { return param_up_; } - std::vector& param_lo() + std::vector& param_lo() override { return param_lo_; } - const std::vector& param_lo() const + const std::vector& param_lo() const override { return param_lo_; } - std::vector& getResidual() + std::vector& getResidual() override { return f_; } - const std::vector& getResidual() const + const std::vector& getResidual() const override { return f_; } @@ -186,32 +186,32 @@ namespace PhasorDynamics return J_; } - std::vector& getIntegrand() + std::vector& getIntegrand() override { return g_; } - const std::vector& getIntegrand() const + const std::vector& getIntegrand() const override { return g_; } - std::vector& getAdjointResidual() + std::vector& getAdjointResidual() override { return fB_; } - const std::vector& getAdjointResidual() const + const std::vector& getAdjointResidual() const override { return fB_; } - std::vector& getAdjointIntegrand() + std::vector& getAdjointIntegrand() override { return gB_; } - const std::vector& getAdjointIntegrand() const + const std::vector& getAdjointIntegrand() const override { return gB_; } diff --git a/src/Model/PhasorDynamics/Load/Load.hpp b/src/Model/PhasorDynamics/Load/Load.hpp index b7ffad605..31f1d0480 100644 --- a/src/Model/PhasorDynamics/Load/Load.hpp +++ b/src/Model/PhasorDynamics/Load/Load.hpp @@ -49,19 +49,19 @@ namespace PhasorDynamics Load(bus_type* bus, IdxT component_id); virtual ~Load(); - int allocate(); - int initialize(); - int tagDifferentiable(); - int evaluateResidual(); - int evaluateJacobian(); - int evaluateIntegrand(); - - int initializeAdjoint(); - int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); - int evaluateAdjointIntegrand(); - - void updateTime(real_type /* t */, real_type /* a */) + virtual int allocate() override; + virtual int initialize() override; + virtual int tagDifferentiable() override; + virtual int evaluateResidual() override; + virtual int evaluateJacobian() override; + virtual int evaluateIntegrand() override; + + virtual int initializeAdjoint() override; + virtual int evaluateAdjointResidual() override; + // virtual int evaluateAdjointJacobian() override; + virtual int evaluateAdjointIntegrand() override; + + virtual void updateTime(real_type /* t */, real_type /* a */) override { } From 08b7eeae73a343e47a98c75ff4da4bd0b66d23b2 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Mon, 17 Feb 2025 17:36:40 -0500 Subject: [PATCH 13/13] Expand code comments. --- src/Model/PhasorDynamics/Branch/Branch.cpp | 63 +++++++++++++++++++++- src/Model/PhasorDynamics/Branch/Branch.hpp | 14 ++++- src/Model/PhasorDynamics/Load/Load.cpp | 35 ++++++++++++ 3 files changed, 108 insertions(+), 4 deletions(-) diff --git a/src/Model/PhasorDynamics/Branch/Branch.cpp b/src/Model/PhasorDynamics/Branch/Branch.cpp index edf8ae3c7..522e79906 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.cpp +++ b/src/Model/PhasorDynamics/Branch/Branch.cpp @@ -1,3 +1,11 @@ +/** + * @file Branch.hpp + * @author Slaven Peles (peless@ornl.gov) + * @brief Definition of a phasor dynamics branch model. + * + * The model uses Cartesian coordinates. + * + */ #include #include @@ -33,6 +41,18 @@ namespace PhasorDynamics size_ = 0; } + /** + * @brief Construct a new Branch + * + * @tparam ScalarT - scalar type + * @tparam IdxT - matrix/vector index type + * @param bus1 - pointer to bus-1 + * @param bus2 - pointer to bus-2 + * @param R - line series resistance + * @param X - line series reactance + * @param G - line shunt conductance + * @param B - line shunt charging + */ template Branch::Branch(bus_type* bus1, bus_type* bus2, @@ -65,7 +85,12 @@ namespace PhasorDynamics size_ = 0; } - + /** + * @brief Destroy the Branch + * + * @tparam ScalarT + * @tparam IdxT + */ template Branch::~Branch() { @@ -105,7 +130,6 @@ namespace PhasorDynamics * \brief Residual contribution of the branch is pushed to the * two terminal buses. * - * @todo Add and verify conductance to ground (B and G) */ template int Branch::evaluateResidual() @@ -122,6 +146,13 @@ namespace PhasorDynamics return 0; } + /** + * @brief Jacobian evaluation not implemented yet + * + * @tparam ScalarT - scalar data type + * @tparam IdxT - matrix index data type + * @return int - error code, 0 = success + */ template int Branch::evaluateJacobian() { @@ -130,6 +161,13 @@ namespace PhasorDynamics return 0; } + /** + * @brief Integrand (objective) evaluation not implemented yet + * + * @tparam ScalarT - scalar data type + * @tparam IdxT - matrix index data type + * @return int - error code, 0 = success + */ template int Branch::evaluateIntegrand() { @@ -137,6 +175,13 @@ namespace PhasorDynamics return 0; } + /** + * @brief Adjoint initialization not implemented yet + * + * @tparam ScalarT - scalar data type + * @tparam IdxT - matrix index data type + * @return int - error code, 0 = success + */ template int Branch::initializeAdjoint() { @@ -144,6 +189,13 @@ namespace PhasorDynamics return 0; } + /** + * @brief Adjoint residual evaluation not implemented yet + * + * @tparam ScalarT - scalar data type + * @tparam IdxT - matrix index data type + * @return int - error code, 0 = success + */ template int Branch::evaluateAdjointResidual() { @@ -151,6 +203,13 @@ namespace PhasorDynamics return 0; } + /** + * @brief Adjoint integrand (objective) evaluation not implemented yet + * + * @tparam ScalarT - scalar data type + * @tparam IdxT - matrix index data type + * @return int - error code, 0 = success + */ template int Branch::evaluateAdjointIntegrand() { diff --git a/src/Model/PhasorDynamics/Branch/Branch.hpp b/src/Model/PhasorDynamics/Branch/Branch.hpp index cd309def9..983a85ef1 100644 --- a/src/Model/PhasorDynamics/Branch/Branch.hpp +++ b/src/Model/PhasorDynamics/Branch/Branch.hpp @@ -1,4 +1,11 @@ - +/** + * @file Branch.hpp + * @author Slaven Peles (peless@ornl.gov) + * @brief Declaration of a phasor dynamics branch model. + * + * The model uses Cartesian coordinates. + * + */ #pragma once #include @@ -24,8 +31,11 @@ namespace GridKit { namespace PhasorDynamics { - /*! + /** * @brief Implementation of a pi-model branch between two buses. + * + * The model is implemented in Cartesian coordinates. Positive current + * direction is into the busses. * */ template diff --git a/src/Model/PhasorDynamics/Load/Load.cpp b/src/Model/PhasorDynamics/Load/Load.cpp index 87fd2adf7..5afb76ca0 100644 --- a/src/Model/PhasorDynamics/Load/Load.cpp +++ b/src/Model/PhasorDynamics/Load/Load.cpp @@ -98,6 +98,13 @@ namespace PhasorDynamics return 0; } + /** + * @brief Jacobian evaluation not implemented yet + * + * @tparam ScalarT - scalar data type + * @tparam IdxT - matrix index data type + * @return int - error code, 0 = success + */ template int Load::evaluateJacobian() { @@ -106,6 +113,13 @@ namespace PhasorDynamics return 0; } + /** + * @brief Integrand (objective) evaluation not implemented yet + * + * @tparam ScalarT - scalar data type + * @tparam IdxT - matrix index data type + * @return int - error code, 0 = success + */ template int Load::evaluateIntegrand() { @@ -113,6 +127,13 @@ namespace PhasorDynamics return 0; } + /** + * @brief Adjoint initialization not implemented yet + * + * @tparam ScalarT - scalar data type + * @tparam IdxT - matrix index data type + * @return int - error code, 0 = success + */ template int Load::initializeAdjoint() { @@ -120,6 +141,13 @@ namespace PhasorDynamics return 0; } + /** + * @brief Adjoint residual evaluation not implemented yet + * + * @tparam ScalarT - scalar data type + * @tparam IdxT - matrix index data type + * @return int - error code, 0 = success + */ template int Load::evaluateAdjointResidual() { @@ -127,6 +155,13 @@ namespace PhasorDynamics return 0; } + /** + * @brief Adjoint integrand (objective) evaluation not implemented yet + * + * @tparam ScalarT - scalar data type + * @tparam IdxT - matrix index data type + * @return int - error code, 0 = success + */ template int Load::evaluateAdjointIntegrand() {