From cbabd88f12aa54df3463cf585098dd0c5a178b31 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Thu, 20 Oct 2022 17:20:51 -0500 Subject: [PATCH 01/44] Add bus factory. Parse load data from the input file. Check load data when testing Matpower parser. Do not store load data in bus data structure. Changed names and order of template parameters in power system data structures. More intuitieve data structures names Changed names of data structures to distinguish Matpower specific data and general power system description data. Pass correct scalar and real types to derived bus classes. Add generator base and slack classes. Classes compile correctly, not tested yet. Infrastructure for adding buses and generators to power flow models Add steady-state generator models and factory. Constructors now read directly from GenData and BusData structures. Updated Bus classes accordingly. Usage example provided in Grid3BusSys app. Supporting infrastructure for Loads and Branches Expanded methods for adding components to the power system grid. Includes new constructors for loads and branches, as well as methods for accessing buses through their IDs. Updated Parsing Example Fixed Memory Errors in KinSol and SystemSteadyStateModel +Clean valgrind output Prototype Example of Creating a RL Circuit +Add hypergraph representation +Added Model form with appropiate indexing +Added Resistors, Capacitor, Inductor, and VoltageSource Component Models Add capability to build power flow models from Matpower input files Use more realistic test passing criterion Release 0.0.7 updates --- CircuitGraph.hpp | 119 ++++++++++ ComponentLib/CMakeLists.txt | 2 + .../PowerElectronicsComponents/CMakeLists.txt | 6 + .../Capacitor/CMakeLists.txt | 8 + .../Capacitor/Capacitor.cpp | 117 ++++++++++ .../Capacitor/Capacitor.hpp | 64 ++++++ .../CircuitComponent.hpp | 68 ++++++ .../Inductor/CMakeLists.txt | 8 + .../Inductor/Inductor.cpp | 117 ++++++++++ .../Inductor/Inductor.hpp | 66 ++++++ .../Resistor/CMakeLists.txt | 8 + .../Resistor/Resistor.cpp | 117 ++++++++++ .../Resistor/Resistor.hpp | 65 ++++++ .../VoltageSource/CMakeLists.txt | 8 + .../VoltageSource/VoltageSource.cpp | 119 ++++++++++ .../VoltageSource/VoltageSource.hpp | 63 +++++ Examples/CMakeLists.txt | 1 + Examples/Grid3Bus/3bus.mat | 47 ++++ Examples/RLCircuit/CMakeLists.txt | 12 + Examples/RLCircuit/RLCircuit.cpp | 114 +++++++++ ModelEvaluatorImpl.hpp | 8 + PowerElectronicsModel.hpp | 217 ++++++++++++++++++ SystemSteadyStateModel.hpp | 37 +++ 23 files changed, 1391 insertions(+) create mode 100644 CircuitGraph.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/Capacitor/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/Inductor/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/Resistor/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/VoltageSource/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp create mode 100644 Examples/Grid3Bus/3bus.mat create mode 100644 Examples/RLCircuit/CMakeLists.txt create mode 100644 Examples/RLCircuit/RLCircuit.cpp create mode 100644 PowerElectronicsModel.hpp diff --git a/CircuitGraph.hpp b/CircuitGraph.hpp new file mode 100644 index 000000000..e54f5a150 --- /dev/null +++ b/CircuitGraph.hpp @@ -0,0 +1,119 @@ + + +#include +#include +#include +#include +#include + +/** + * @brief A very basic hypergraph setup for circuit representation. This forms the hypergraph as a bipartite graph. Doesn't allow removing. Can only grab sets of connections to nodes + * + * @todo should replace with something better and more efficent. Should replace with a libraries setup instead. This would allow fast and easy partitioning of circuits + * + * @todo should replace N and E with Node and Component classes respectively + * + * @tparam IdxT + * @tparam Label + */ +template +class CircuitGraph +{ +private: + std::set hypernodes; + std::set hyperedges; + std::map> edgestonodes; +public: + CircuitGraph(); + ~CircuitGraph(); + bool addHyperEdge(E he); + bool addHyperNode(N hn); + bool addConnection(N hn, E he); + std::set getHyperEdgeConnections(E he); + size_t amountHyperNodes(); + size_t amountHyperEdges(); + void printBiPartiteGraph(bool verbose = false); +}; + +template +CircuitGraph::CircuitGraph() +{ +} + +template +CircuitGraph::~CircuitGraph() +{ +} + +template +bool CircuitGraph::addHyperNode(N hn) +{ + return this->hypernodes.insert(hn).second; +} + +template +bool CircuitGraph::addHyperEdge(E he) +{ + return this->hyperedges.insert(he).second; +} + + +template +bool CircuitGraph::addConnection(N hn, E he) +{ + if(this->hyperedges.count(he) == 0 || this->hypernodes.count(hn) == 0) + { + return false; + } + return this->edgestonodes[he].insert(hn).second; +} + + +template +std::set CircuitGraph::getHyperEdgeConnections(E he) +{ + return this->edgestonodes[he]; +} + + +template +size_t CircuitGraph::amountHyperNodes() +{ + return this->hypernodes.size(); +} + + +template +size_t CircuitGraph::amountHyperEdges() +{ + return this->hyperedges.size(); +} + +/** + * @brief Printing + * + * @todo need to add verbose printing for connections display + * + * @tparam IdxT + * @param verbose + */ + +template +void CircuitGraph::printBiPartiteGraph(bool verbose) +{ + + std::cout << "Amount of HyperNodes: " << this->amountHyperNodes() << std::endl; + std::cout << "Amount of HyperEdges: " << this->amountHyperEdges() << std::endl; + std::cout << "Connections per Edge:" << std::endl; + for (auto i : this->edgestonodes) + { + std::cout << i.first << " : {"; + for (auto j : i.second){ + std::cout << j << ", "; + } + std::cout << "}\n"; + + } + + +} diff --git a/ComponentLib/CMakeLists.txt b/ComponentLib/CMakeLists.txt index 0c422d5b9..29a5a7988 100644 --- a/ComponentLib/CMakeLists.txt +++ b/ComponentLib/CMakeLists.txt @@ -69,3 +69,5 @@ add_subdirectory(Generator4Governor) add_subdirectory(Generator4Param) add_subdirectory(Load) add_subdirectory(MiniGrid) +add_subdirectory(PowerElectronicsComponents) + diff --git a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt new file mode 100644 index 000000000..c3e958300 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt @@ -0,0 +1,6 @@ + + +add_subdirectory(Capacitor) +add_subdirectory(Resistor) +add_subdirectory(VoltageSource) +add_subdirectory(Inductor) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/Capacitor/CMakeLists.txt new file mode 100644 index 000000000..62efc1795 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_capacitor + SOURCES + Capacitor.cpp + OUTPUT_NAME + gridkit_powerelec_capacitor) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp new file mode 100644 index 000000000..4fcda9d9f --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -0,0 +1,117 @@ + + + +#include +#include +#include +#include "Capacitor.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant load model + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +Capacitor::Capacitor(IdxT id, ScalarT C) + : C_(C) +{ + this->size_ = 3; + this->n_intern = 1; + this->n_extern = 2; + this->extern_indices = {0,1}; + this->idc_ = id; +} + +template +Capacitor::~Capacitor() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int Capacitor::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + return 0; +} + +/** + * Initialization of the grid model + */ +template +int Capacitor::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int Capacitor::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int Capacitor::evaluateResidual() +{ + this->f_[0] = this->yp_[2]; + this->f_[1] = -this->yp_[2]; + this->f_[2] = this->y_[0] - this->y_[1] - this->y_[2] - this->C_ * this->yp_[2]; + return 0; +} + +template +int Capacitor::evaluateJacobian() +{ + + return 0; +} + +template +int Capacitor::evaluateIntegrand() +{ + return 0; +} + +template +int Capacitor::initializeAdjoint() +{ + return 0; +} + +template +int Capacitor::evaluateAdjointResidual() +{ + return 0; +} + +template +int Capacitor::evaluateAdjointIntegrand() +{ + return 0; +} + + + + +// Available template instantiations +template class Capacitor; +template class Capacitor; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp new file mode 100644 index 000000000..76cf94614 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp @@ -0,0 +1,64 @@ + + +#ifndef _CAP_HPP_ +#define _CAP_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive Capacitor class. + * + */ + template + class Capacitor : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + public: + Capacitor(IdxT id, ScalarT C); + virtual ~Capacitor(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT C_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp new file mode 100644 index 000000000..7cfb5521a --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp @@ -0,0 +1,68 @@ + + +#ifndef _CIRCCOMP_HPP_ +#define _CIRCCOMP_HPP_ + +#include +#include +#include +#include + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive CircuitComponent class. + * + */ + template + class CircuitComponent : public ModelEvaluatorImpl + { + + public: + + + void updateTime(ScalarT t, ScalarT a) + { + this->time_ = t; + this->alpha_ = a; + } + + size_t getExternSize() + { + return this->n_extern; + } + + size_t getInternalSize() + { + return this->n_intern; + } + + std::set getExternIndices() + { + return this->extern_indices; + } + + bool setExternalConnectionNodes(size_t index, IdxT id) + { + this->connection_nodes[index] = id; + return true; + } + + IdxT getNodeConnection(size_t index) + { + return this->connection_nodes.at(index); + } + + protected: + size_t n_extern; + size_t n_intern; + std::set extern_indices; + std::map connection_nodes; + + }; + + +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/Inductor/CMakeLists.txt new file mode 100644 index 000000000..4c620030f --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Inductor/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_inductor + SOURCES + Inductor.cpp + OUTPUT_NAME + gridkit_powerelec_inductor) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp new file mode 100644 index 000000000..278b0eebc --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -0,0 +1,117 @@ + + + +#include +#include +#include +#include "Inductor.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant load model + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +Inductor::Inductor(IdxT id, ScalarT L) + : L_(L) +{ + this->size_ = 3; + this->n_intern = 1; + this->n_extern = 2; + this->extern_indices = {0,1}; + this->idc_ = id; +} + +template +Inductor::~Inductor() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int Inductor::allocate() +{ + + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + return 0; +} + +/** + * Initialization of the grid model + */ +template +int Inductor::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int Inductor::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int Inductor::evaluateResidual() +{ + this->f_[0] = this->y_[2]; + this->f_[1] = -this->y_[2]; + this->f_[2] = this->y_[0] - this->y_[1] - this->L_ * this->yp_[2]; + return 0; +} + +template +int Inductor::evaluateJacobian() +{ + return 0; +} + +template +int Inductor::evaluateIntegrand() +{ + return 0; +} + +template +int Inductor::initializeAdjoint() +{ + return 0; +} + +template +int Inductor::evaluateAdjointResidual() +{ + return 0; +} + +template +int Inductor::evaluateAdjointIntegrand() +{ + return 0; +} + + + + +// Available template instantiations +template class Inductor; +template class Inductor; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp new file mode 100644 index 000000000..e959aabf1 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp @@ -0,0 +1,66 @@ + + +#ifndef _IND_HPP_ +#define _IND_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive Inductor class. + * + */ + template + class Inductor : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + + public: + Inductor(IdxT id, ScalarT L); + virtual ~Inductor(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + + private: + ScalarT L_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/Resistor/CMakeLists.txt new file mode 100644 index 000000000..9386bda83 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Resistor/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_resistor + SOURCES + Resistor.cpp + OUTPUT_NAME + gridkit_powerelec_resistor) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp new file mode 100644 index 000000000..1aa06427a --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp @@ -0,0 +1,117 @@ + + + +#include +#include +#include +#include "Resistor.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant resistor model + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +Resistor::Resistor(IdxT id, ScalarT R) + : R_(R) +{ + this->size_ = 2; + this->n_intern = 0; + this->n_extern = 2; + this->extern_indices = {0,1}; + this->idc_ = id; +} + +template +Resistor::~Resistor() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int Resistor::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + return 0; +} + +/** + * Initialization of the grid model + */ +template +int Resistor::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int Resistor::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int Resistor::evaluateResidual() +{ + + this->f_[0] = (this->y_[1] - this->y_[0])/this->R_ ; + this->f_[1] = (this->y_[0] - this->y_[1])/this->R_ ; + return 0; +} + +template +int Resistor::evaluateJacobian() +{ + return 0; +} + +template +int Resistor::evaluateIntegrand() +{ + return 0; +} + +template +int Resistor::initializeAdjoint() +{ + return 0; +} + +template +int Resistor::evaluateAdjointResidual() +{ + return 0; +} + +template +int Resistor::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class Resistor; +template class Resistor; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp new file mode 100644 index 000000000..0373e2c5c --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp @@ -0,0 +1,65 @@ + + +#ifndef _RES_HPP_ +#define _RES_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive Resistor class. + * + */ + template + class Resistor : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + public: + Resistor(IdxT id, ScalarT R); + virtual ~Resistor(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + + private: + ScalarT R_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/VoltageSource/CMakeLists.txt new file mode 100644 index 000000000..7196f4d43 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_voltagesource + SOURCES + VoltageSource.cpp + OUTPUT_NAME + gridkit_powerelec_voltagesource) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp new file mode 100644 index 000000000..c27c04bd2 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -0,0 +1,119 @@ + + + +#include +#include +#include +#include "VoltageSource.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant VoltageSource model + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +VoltageSource::VoltageSource(IdxT id, ScalarT V) + : V_(V) +{ + this->size_ = 3; + this->n_intern = 1; + this->n_extern = 2; + this->extern_indices = {0,1}; + this->idc_ = id; +} + +template +VoltageSource::~VoltageSource() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int VoltageSource::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + return 0; +} + +/** + * Initialization of the grid model + */ +template +int VoltageSource::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int VoltageSource::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int VoltageSource::evaluateResidual() +{ + //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors + // for easier development + this->f_[0] = this->y_[2]; + this->f_[1] = -this->y_[2]; + this->f_[2] = this->y_[0] - this->y_[1] - this->V_; + return 0; +} + +template +int VoltageSource::evaluateJacobian() +{ + return 0; +} + +template +int VoltageSource::evaluateIntegrand() +{ + return 0; +} + +template +int VoltageSource::initializeAdjoint() +{ + return 0; +} + +template +int VoltageSource::evaluateAdjointResidual() +{ + return 0; +} + +template +int VoltageSource::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class VoltageSource; +template class VoltageSource; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp new file mode 100644 index 000000000..dcbacf2f7 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp @@ -0,0 +1,63 @@ + + +#ifndef _VOSO_HPP_ +#define _VOSO_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive VoltageSource class. + * + */ + template + class VoltageSource : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + public: + VoltageSource(IdxT id, ScalarT V); + virtual ~VoltageSource(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT V_; + }; +} + +#endif diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index feec6623a..b42907fd3 100644 --- a/Examples/CMakeLists.txt +++ b/Examples/CMakeLists.txt @@ -56,6 +56,7 @@ # add_subdirectory(MatPowerTesting) +add_subdirectory(RLCircuit) if(TARGET SUNDIALS::kinsol) add_subdirectory(Grid3Bus) diff --git a/Examples/Grid3Bus/3bus.mat b/Examples/Grid3Bus/3bus.mat new file mode 100644 index 000000000..4663eb33c --- /dev/null +++ b/Examples/Grid3Bus/3bus.mat @@ -0,0 +1,47 @@ +( +function mpc = case5 +% Created by Reid Gomillion + +% MATPOWER + +%% MATPOWER Case Format : Version 2 +mpc.version = '2'; + +%%----- Power Flow Data -----%% +%% system MVA base +mpc.baseMVA = 100; + +%% bus data +% bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin +mpc.bus = [ + 1 3 2.0 0.0 0 0 0 1 0.0 0 0 0 0.0; + 2 1 2.5 -0.8 0 0 0 1 0.0 0 0 0 0.0; + 3 2 0 0 0 0 0 1.1 0.0 0 0 0 0.0; +]; + +%% generator data +% bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf +mpc.gen = [ + 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; + 3 2.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; +]; + +%% branch data +% fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax +mpc.branch = [ + 1 2 0 0.1 0 0 0 0 0 0 0 0 0; + 1 3 0 0.0666666 0 0 0 0 0 0 0 0 0; + 2 3 0 0.0833333 0 0 0 0 0 0 0 0 0; +]; + +%%----- OPF Data -----%% +%% generator cost data +% 1 startup shutdown n x1 y1 ... xn yn +% 2 startup shutdown n c(n-1) ... c0 +mpc.gencost = [ + 2 0 0 3 0 14 0; + 2 0 0 3 0 15 0; + 2 0 0 3 0 30 0; +]; + +) \ No newline at end of file diff --git a/Examples/RLCircuit/CMakeLists.txt b/Examples/RLCircuit/CMakeLists.txt new file mode 100644 index 000000000..5069566bf --- /dev/null +++ b/Examples/RLCircuit/CMakeLists.txt @@ -0,0 +1,12 @@ + + + + +add_executable(rlcircuit RLCircuit.cpp) +target_link_libraries(rlcircuit GRIDKIT::powerelec_capacitor + GRIDKIT::powerelec_inductor + GRIDKIT::powerelec_resistor + GRIDKIT::powerelec_voltagesource) + +add_test(NAME RLCircuit COMMAND $) +install(TARGETS rlcircuit RUNTIME DESTINATION bin) diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp new file mode 100644 index 000000000..ba9333f40 --- /dev/null +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -0,0 +1,114 @@ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + + +int main(int argc, char const *argv[]) +{ + //Basic Circuit Setup + //@todo will want to eventually put components in the hyper graph instead of indicies + + std::unique_ptr> cirg(new CircuitGraph()); + for (size_t i = 0; i < 3; i++) + { + cirg->addHyperEdge(i); + } + for (size_t i = 0; i < 5; i++) + { + cirg->addHyperNode(i); + } + + //Create Connections of Nodes to edges sets + //External nodes + cirg->addConnection(0, 0); + cirg->addConnection(0, 2); + cirg->addConnection(2, 0); + cirg->addConnection(2, 1); + cirg->addConnection(3, 1); + cirg->addConnection(3, 2); + + //Internal nodes + cirg->addConnection(1,0); + cirg->addConnection(4,2); + + + cirg->printBiPartiteGraph(); + + + //Create circuit model + ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(); + + size_t idoff = 0; + + //inductor + ModelLib::Inductor* induct = new ModelLib::Inductor(idoff,0.1); + //Form index to node uid realations + induct->setExternalConnectionNodes(0,2); + induct->setExternalConnectionNodes(2,1); + induct->setExternalConnectionNodes(1,0); + sysmodel->addComponent(induct); + + + //resistor + idoff++; + ModelLib::Resistor* resis = new ModelLib::Resistor(idoff, 1.0); + //Form index to node uid realations + resis->setExternalConnectionNodes(0,3); + resis->setExternalConnectionNodes(1,2); + sysmodel->addComponent(resis); + + //voltage source + idoff++; + ModelLib::VoltageSource* vsource = new ModelLib::VoltageSource(idoff, 0.1); + //Form index to node uid realations + vsource->setExternalConnectionNodes(0,0); + vsource->setExternalConnectionNodes(2,4); + vsource->setExternalConnectionNodes(1,3); + sysmodel->addComponent(vsource); + + + //Allocate with graph + sysmodel->allocate(*cirg); + + std::cout << sysmodel->y().size() << std::endl; + + //Create Intial points + sysmodel->y()[0] = 1.0; + sysmodel->y()[1] = 1.0; + sysmodel->y()[2] = 1.0; + sysmodel->y()[3] = 1.0; + sysmodel->y()[4] = 1.0; + + sysmodel->yp()[0] = 1.0; + sysmodel->yp()[1] = 1.0; + sysmodel->yp()[2] = 1.0; + sysmodel->yp()[3] = 1.0; + sysmodel->yp()[4] = 1.0; + + + sysmodel->initialize(); + + sysmodel->evaluateResidual(); + + std::cout << "Output: {"; + for (double i : sysmodel->getResidual()) + { + std::cout << i << ", "; + } + std::cout << "}\n"; + + + return 0; +} diff --git a/ModelEvaluatorImpl.hpp b/ModelEvaluatorImpl.hpp index a4ef43a00..94cbeb5d3 100644 --- a/ModelEvaluatorImpl.hpp +++ b/ModelEvaluatorImpl.hpp @@ -252,6 +252,12 @@ namespace ModelLib return gB_; } + //@todo Fix ID naming + IdxT getIDcomponent() + { + return idc_; + } + protected: @@ -281,6 +287,8 @@ namespace ModelLib real_type rtol_; real_type atol_; + IdxT idc_; + }; diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp new file mode 100644 index 000000000..78350ee2f --- /dev/null +++ b/PowerElectronicsModel.hpp @@ -0,0 +1,217 @@ + + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +namespace ModelLib +{ + +template +class PowerElectronicsModel : public ModelEvaluatorImpl +{ + typedef CircuitComponent component_type; + + using ModelEvaluatorImpl::size_; + // using ModelEvaluatorImpl::size_quad_; + // using ModelEvaluatorImpl::size_opt_; + using ModelEvaluatorImpl::nnz_; + // using ModelEvaluatorImpl::time_; + // using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::yp_; + // using ModelEvaluatorImpl::yB_; + // using ModelEvaluatorImpl::ypB_; + // using ModelEvaluatorImpl::tag_; + using ModelEvaluatorImpl::f_; + // using ModelEvaluatorImpl::fB_; + // using ModelEvaluatorImpl::g_; + // using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::rtol_; + using ModelEvaluatorImpl::atol_; + // using ModelEvaluatorImpl::param_; + // using ModelEvaluatorImpl::param_up_; + // using ModelEvaluatorImpl::param_lo_; + +public: + /** + * @brief Constructor for the system model + */ + PowerElectronicsModel() : ModelEvaluatorImpl(0, 0, 0) + { + // Set system model tolerances + rtol_ = 1e-5; + atol_ = 1e-5; + } + + /** + * @brief Destructor for the system model + */ + virtual ~PowerElectronicsModel() + { + for (auto comp : this->components_) delete comp; + } + + /** + * @brief allocator default + * + * @todo this should throw an exception as no allocation without a graph is allowed. Or needs to be removed from the base class + * + * @return int + */ + int allocate() + { + + return 1; + } + + int allocate(CircuitGraph cir) + { + this->graph = cir; + + // Allocate all components + this->size_ = cir.amountHyperNodes(); + for(const auto& component : components_) + { + component->allocate(); + } + + // Allocate global vectors + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); + + return 0; + } + + int initialize() + { + + // Initialize components + for(const auto& component : components_) + { + component->initialize(); + } + + for(const auto& component : components_) + { + for(IdxT j=0; jsize(); ++j) + { + component->y()[j] = y_[component->getNodeConnection(j)]; + component->yp()[j] = yp_[component->getNodeConnection(j)]; + } + } + return 0; + } + + int tagDifferentiable() + { + return 0; + } + + int evaluateResidual() + { + for (IdxT i = 0; i < this->f_.size(); i++) + { + f_[i] = 0; + } + + // Update variables + for(const auto& component : components_) + { + for(IdxT j=0; jsize(); ++j) + { + component->y()[j] = y_[component->getNodeConnection(j)]; + component->yp()[j] = yp_[component->getNodeConnection(j)]; + } + component->evaluateResidual(); + } + + // Update system residual vector + + for(const auto& component : components_) + { + for(IdxT j=0; jsize(); ++j) + { + f_[component->getNodeConnection(j)] += component->getResidual()[j]; + } + } + + return 0; + } + + int evaluateJacobian() + { + return 0; + } + + /** + * @brief Evaluate integrands for the system quadratures. + */ + int evaluateIntegrand() + { + + return 0; + } + + /** + * @brief Initialize system adjoint. + * + * Updates variables and optimization parameters, then initializes + * adjoints locally and copies them to the system adjoint vector. + */ + int initializeAdjoint() + { + return 0; + } + + /** + * @brief Compute adjoint residual for the system model. + * + * + */ + int evaluateAdjointResidual() + { + return 0; + } + + + /** + * @brief Evaluate adjoint integrand for the system model. + * + * + */ + int evaluateAdjointIntegrand() + { + return 0; + } + + void updateTime(ScalarT t, ScalarT a) + { + } + + void addComponent(component_type* component) + { + this->components_.push_back(component); + } + + CircuitGraph getGraph() + { + return this->graph; + } + +private: + std::vector components_; + + CircuitGraph graph; + +}; // class PowerElectronicsModel + +} // namespace ModelLib diff --git a/SystemSteadyStateModel.hpp b/SystemSteadyStateModel.hpp index c32dd5ec3..de2dc000e 100644 --- a/SystemSteadyStateModel.hpp +++ b/SystemSteadyStateModel.hpp @@ -127,6 +127,43 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl atol_ = 1e-5; } + SystemSteadyStateModel(GridKit::PowerSystemData::SystemModelData mp) : ModelEvaluatorImpl(0,0,0) + { + rtol_ = 1e-5; + atol_ = 1e-5; + + //buses + for(auto busdata : mp.bus) + { + auto* bus = BusFactory::create(busdata); + this->addBus(bus); + } + + //generators + for (auto gendata : mp.gen) + { + auto* gen = GeneratorFactory::create(this->getBus(gendata.bus),gendata); + this->addComponent(gen); + } + + //branches + for (auto branchdata : mp.branch) + { + auto* branch = new Branch(this->getBus(branchdata.fbus),this->getBus(branchdata.tbus),branchdata); + this->addComponent(branch); + } + + //loads + for (auto loaddata : mp.load) + { + auto* loadm = new Load(this->getBus(loaddata.bus_i),loaddata); + this->addComponent(loadm); + } + + //There appears to not be a Generator Cost Object + //TODO: Implment for GenCost + } + /** * @brief Construct a new System Steady State Model object. Allows for simple allocation. * From 16030576c1484357d7ae0cfd414b2467b2a30270 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Thu, 27 Jul 2023 16:44:39 -0400 Subject: [PATCH 02/44] Add New Components and Changes to Composition +Added InductionMotor, Linear Transformer, and SynchronousMachine +Changes to PowerElectronicsModel --- .../PowerElectronicsComponents/CMakeLists.txt | 5 +- .../Capacitor/Capacitor.cpp | 2 + .../CircuitComponent.hpp | 69 ++++++++ .../InductionMotor/CMakeLists.txt | 8 + .../InductionMotor/InductionMotor.cpp | 135 ++++++++++++++++ .../InductionMotor/InductionMotor.hpp | 69 ++++++++ .../Inductor/Inductor.cpp | 2 + .../LinearTransformer/CMakeLists.txt | 8 + .../LinearTransformer/LinearTransformer.cpp | 124 ++++++++++++++ .../LinearTransformer/LinearTransformer.hpp | 67 ++++++++ .../Resistor/Resistor.cpp | 2 + .../SynchronousMachine/CMakeLists.txt | 8 + .../SynchronousMachine/SynchronousMachine.cpp | 151 ++++++++++++++++++ .../SynchronousMachine/SynchronousMachine.hpp | 76 +++++++++ .../VoltageSource/VoltageSource.cpp | 4 +- Examples/RLCircuit/RLCircuit.cpp | 31 +--- ModelEvaluatorImpl.hpp | 5 + PowerElectronicsModel.hpp | 19 ++- 18 files changed, 743 insertions(+), 42 deletions(-) create mode 100644 ComponentLib/PowerElectronicsComponents/InductionMotor/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/LinearTransformer/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/SynchronousMachine/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp diff --git a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt index c3e958300..10f2c6fdc 100644 --- a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt +++ b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt @@ -3,4 +3,7 @@ add_subdirectory(Capacitor) add_subdirectory(Resistor) add_subdirectory(VoltageSource) -add_subdirectory(Inductor) \ No newline at end of file +add_subdirectory(Inductor) +add_subdirectory(LinearTransformer) +add_subdirectory(InductionMotor) +add_subdirectory(SynchronousMachine) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp index 4fcda9d9f..d905dda05 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -39,6 +39,8 @@ int Capacitor::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); + this->J_.resize(this->size_^2); + this->M_.resize(this->size_^2); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp index 7cfb5521a..9e1052e43 100644 --- a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp +++ b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp @@ -54,10 +54,79 @@ namespace ModelLib return this->connection_nodes.at(index); } + inline std::vector parkTransformMatrix(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = (2.0/3.0)*cos(angle); + result[1] = (2.0/3.0)*cos(anpim); + result[2] = (2.0/3.0)*cos(anpip); + result[3] = (2.0/3.0)*sin(angle); + result[4] = (2.0/3.0)*sin(anpim); + result[5] = (2.0/3.0)*sin(anpip); + result[6] = 1.0/3.0; + result[7] = 1.0/3.0; + result[8] = 1.0/3.0; + return result; + } + + inline std::vector parkTransformMatrixDerivative(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = (2.0/3.0)*sin(angle); + result[1] = (2.0/3.0)*sin(anpim); + result[2] = (2.0/3.0)*sin(anpip); + result[3] = (2.0/3.0)*-cos(angle); + result[4] = (2.0/3.0)*-cos(anpim); + result[5] = (2.0/3.0)*-cos(anpip); + result[6] = 0; + result[7] = 0; + result[8] = 0; + return result; + } + + inline std::vector inverseParkTransformMatrix(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = cos(angle); + result[1] = sin(angle); + result[2] = 1.0; + result[3] = cos(anpim); + result[4] = sin(anpim); + result[5] = 1.0; + result[6] = cos(anpip); + result[7] = sin(anpip); + result[8] = 1.0; + return result; + } + + inline std::vector inverseParkTransformMatrixDerivative(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = sin(angle); + result[1] = -cos(angle); + result[2] = 0.0; + result[3] = sin(anpim); + result[4] = -cos(anpim); + result[5] = 0.0; + result[6] = sin(anpip); + result[7] = -cos(anpip); + result[8] = 0.0; + return result; + } + protected: size_t n_extern; size_t n_intern; std::set extern_indices; + //@todo may want to replace the mapping of connection_nodes to Node objects instead of IdxT. Allows for container free setup std::map connection_nodes; }; diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/InductionMotor/CMakeLists.txt new file mode 100644 index 000000000..95ef42436 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_inductionmotor + SOURCES + InductionMotor.cpp + OUTPUT_NAME + gridkit_powerelec_inductionmotor) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp new file mode 100644 index 000000000..75782b435 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp @@ -0,0 +1,135 @@ + + + +#include +#include +#include +#include "InductionMotor.hpp" + + +namespace ModelLib { + + + +/*! + * @brief Constructor for a constant InductionMotor model + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +InductionMotor::InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, ScalarT Llr, ScalarT Rr, ScalarT Lms, ScalarT J, ScalarT P) + : Lls_(Lls), + Rs_(Rs), + Llr_(Llr), + Rr_(Rr), + Lms_(Lms), + J_(J), + P_(P) +{ + this->size_ = 10; + this->n_intern = 5; + this->n_extern = 5; + this->extern_indices = {0,1,2,3,4}; + this->idc_ = id; +} + +template +InductionMotor::~InductionMotor() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int InductionMotor::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + return 0; +} + +/** + * Initialization of the grid model + */ +template +int InductionMotor::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int InductionMotor::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int InductionMotor::evaluateResidual() +{ + //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors + // for easier development + this->f_[0] = y_[5] + y_[7]; + this->f_[1] = (-1.0/2.0) * y_[5] - (sqrt(3.0)/2.0)*y_[6] + y_[7]; + this->f_[2] = (-1.0/2.0) * y_[5] + (sqrt(3.0)/2.0)*y_[6] + y_[7]; + this->f_[3] = J_ * yp_[3] - (3.0/4.0)*P_*Lms_ * (y_[5]*y_[9] - y_[6]*y_[8]); + this->f_[4] = yp_[4] - y_[3]; + this->f_[5] = (1.0/3.0)*(2.0* y_[0] - y_[1] - y_[2]) - Rs_*y_[5] - (Lls_ + Lms_) * yp_[5] - Lms_ * yp_[6]; + this->f_[6] = (1.0/sqrt(3.0))*(-y_[1] + y_[2]) - Rs_*y_[6] - (Lls_ + Lms_) * yp_[6] - Lms_ * yp_[5]; + this->f_[7] = (y_[0] + y_[1] + y_[2])/3.0 - Rs_*y_[7] - Lls_ * yp_[7]; + this->f_[8] = Rr_*y_[8] + (Llr_ + Lms_)*yp_[8] + Lms_ * yp_[5] - (P_/2)*y_[3]*((Llr_+Lms_)*y_[9] + Lms_*y_[6]); + this->f_[9] = Rr_*y_[9] + (Llr_ + Lms_)*yp_[9] + Lms_ * yp_[6] + (P_/2)*y_[3]*((Llr_+Lms_)*y_[8] + Lms_*y_[5]); + return 0; +} + +template +int InductionMotor::evaluateJacobian() +{ + return 0; +} + +template +int InductionMotor::evaluateIntegrand() +{ + return 0; +} + +template +int InductionMotor::initializeAdjoint() +{ + return 0; +} + +template +int InductionMotor::evaluateAdjointResidual() +{ + return 0; +} + +template +int InductionMotor::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class InductionMotor; +template class InductionMotor; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp new file mode 100644 index 000000000..2547754e2 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp @@ -0,0 +1,69 @@ + + +#ifndef _IMOTOR_HPP_ +#define _IMOTOR_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive InductionMotor class. + * + */ + template + class InductionMotor : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + public: + InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, ScalarT Llr, ScalarT Rr, ScalarT Lms, ScalarT J, ScalarT P); + virtual ~InductionMotor(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT Lls_; + ScalarT Rs_; + ScalarT Llr_; + ScalarT Rr_; + ScalarT Lms_; + ScalarT J_; + ScalarT P_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index 278b0eebc..952a992d0 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -40,6 +40,8 @@ int Inductor::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); + this->J_.resize(this->size_^2); + this->M_.resize(this->size_^2); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/LinearTransformer/CMakeLists.txt new file mode 100644 index 000000000..eaf95c043 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_lineartrasnformer + SOURCES + LinearTransformer.cpp + OUTPUT_NAME + gridkit_powerelec_lineartrasnformer) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp new file mode 100644 index 000000000..4caaeae66 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp @@ -0,0 +1,124 @@ + + + +#include +#include +#include +#include "LinearTransformer.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant LinearTransformer model + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +LinearTransformer::LinearTransformer(IdxT id, ScalarT L1, ScalarT L2, ScalarT R1, ScalarT R2, ScalarT M) + : L1_(L1), + L2_(L2), + R1_(R1), + R2_(R2), + M_(M) +{ + this->size_ = 4; + this->n_intern = 2; + this->n_extern = 2; + this->extern_indices = {0,1}; + this->idc_ = id; +} + +template +LinearTransformer::~LinearTransformer() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int LinearTransformer::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + return 0; +} + +/** + * Initialization of the grid model + */ +template +int LinearTransformer::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int LinearTransformer::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int LinearTransformer::evaluateResidual() +{ + //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors + // for easier development + this->f_[0] = this->y_[2]; + this->f_[1] = this->y_[3]; + this->f_[2] = this->y_[0] - this->R1_ * this->y_[2] - this->L1_ * this->yp_[2] - this->M_ * this->yp_[3]; + this->f_[2] = this->y_[1] - this->R2_ * this->y_[3] - this->M_ * this->yp_[2] - this->L2_ * this->yp_[3]; + return 0; +} + +template +int LinearTransformer::evaluateJacobian() +{ + return 0; +} + +template +int LinearTransformer::evaluateIntegrand() +{ + return 0; +} + +template +int LinearTransformer::initializeAdjoint() +{ + return 0; +} + +template +int LinearTransformer::evaluateAdjointResidual() +{ + return 0; +} + +template +int LinearTransformer::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class LinearTransformer; +template class LinearTransformer; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp new file mode 100644 index 000000000..cf56adfa2 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp @@ -0,0 +1,67 @@ + + +#ifndef _LTRANS_HPP_ +#define _LTRANS_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive LinearTransformer class. + * + */ + template + class LinearTransformer : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + public: + LinearTransformer(IdxT id, ScalarT L1, ScalarT L2, ScalarT R1, ScalarT R2, ScalarT M); + virtual ~LinearTransformer(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT L1_; + ScalarT L2_; + ScalarT R1_; + ScalarT R2_; + ScalarT M_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp index 1aa06427a..5faad23b4 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp @@ -39,6 +39,8 @@ int Resistor::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); + this->J_.resize(this->size_^2); + this->M_.resize(this->size_^2); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/CMakeLists.txt new file mode 100644 index 000000000..bfaeace4b --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_synmachine + SOURCES + SynchronousMachine.cpp + OUTPUT_NAME + gridkit_powerelec_synmachine) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp new file mode 100644 index 000000000..05b1e59ac --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp @@ -0,0 +1,151 @@ + + + +#include +#include +#include +#include "SynchronousMachine.hpp" + + +namespace ModelLib { + + + +/*! + * @brief Constructor for a constant SynchronousMachine model + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +SynchronousMachine::SynchronousMachine(IdxT id, ScalarT Lls, std::tuple Llkq, ScalarT Llfd, ScalarT Llkd, ScalarT Lmq, ScalarT Lmd, ScalarT Rs, std::tuple Rkq, ScalarT Rfd, ScalarT Rkd, ScalarT J, ScalarT P, ScalarT mub) + : Lls_(Lls), + Llkq_(Llkq), + Llfd_(Llfd), + Llkd_(Llkd), + Lmq_(Lmq), + Lmd_(Lmd), + Rs_(Rs), + Rkq_(Rkq), + Rfd_(Rfd), + Rkd_(Rkd), + J_(J), + P_(P), + mub_(mub) +{ + this->size_ = 13; + this->n_intern = 6; + this->n_extern = 7; + this->extern_indices = {0,1,2,3,4}; + this->idc_ = id; +} + +template +SynchronousMachine::~SynchronousMachine() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int SynchronousMachine::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + return 0; +} + +/** + * Initialization of the grid model + */ +template +int SynchronousMachine::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int SynchronousMachine::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int SynchronousMachine::evaluateResidual() +{ + ScalarT rkq1 = std::get<0>(Rkq_); + ScalarT rkq2 = std::get<1>(Rkq_); + ScalarT llkq1 = std::get<0>(Llkq_); + ScalarT llkq2 = std::get<1>(Llkq_); + + ScalarT cos1 = cos((P_/2.0)*y_[5]); + ScalarT sin1 = sin((P_/2.0)*y_[5]); + ScalarT cos23m = cos((P_/2.0)*y_[5] - (2.0/3.0)*M_PI); + ScalarT sin23m = sin((P_/2.0)*y_[5] - (2.0/3.0)*M_PI); + ScalarT cos23p = cos((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); + ScalarT sin23p = sin((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); + + this->f_[0] = y_[6]*cos1 + y_[7]*sin1 + y_[8]; + this->f_[1] = y_[6]*cos23m + y_[7]*sin23m + y_[8]; + this->f_[2] = y_[6]*cos23p + y_[7]*sin23p + y_[8]; + this->f_[3] = J_ * yp_[4] - (3.0/4.0)*P_*(Lmd_ *y_[6]* (y_[7] + y_[11] + y_[12]) - Lmq_*y_[7]*(y_[6] + y_[9] + y_[0])); + this->f_[4] = yp_[5] - y_[4]; + this->f_[5] = (-2.0/3.0)*(y_[0]*cos1 +y_[1]*cos23m + y_[2]*cos23p) + Rs_*y_[6] + (Lls_ + Lmq_)*yp_[6] + Lmq_*yp_[9] + Lmq_*yp_[10] + y_[4]*(P_/2.0)*((Lls_ + Lmd_)*y_[7] + Lmd_*y_[11] + Lmd_*y_[12]); + this->f_[6] = (-2.0/3.0)*(y_[0]*sin1 -y_[1]*sin23m - y_[2]*sin23p) + Rs_*y_[7] + (Lls_ + Lmd_)*yp_[7] + Lmd_*yp_[11] + Lmd_*yp_[12] - y_[4]*(P_/2.0)*((Lls_ + Lmq_)*y_[6] + Lmq_*y_[9] + Lmq_*y_[10]); + this->f_[7] = (-1.0/3.0)*(y_[0] + y_[1] + y_[2]) + Rs_*y_[8] + Lls_*yp_[8]; + this->f_[8] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; + this->f_[9] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; + return 0; +} + +template +int SynchronousMachine::evaluateJacobian() +{ + return 0; +} + +template +int SynchronousMachine::evaluateIntegrand() +{ + return 0; +} + +template +int SynchronousMachine::initializeAdjoint() +{ + return 0; +} + +template +int SynchronousMachine::evaluateAdjointResidual() +{ + return 0; +} + +template +int SynchronousMachine::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class SynchronousMachine; +template class SynchronousMachine; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp new file mode 100644 index 000000000..a18eca9c9 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp @@ -0,0 +1,76 @@ + + +#ifndef _SYNMACH_HPP_ +#define _SYNMACH_HPP_ + +#include +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive SynchronousMachine class. + * + */ + template + class SynchronousMachine : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + public: + SynchronousMachine(IdxT id, ScalarT Lls, std::tuple Llkq, ScalarT Llfd, ScalarT Llkd, ScalarT Lmq, ScalarT Lmd, ScalarT Rs, std::tuple Rkq, ScalarT Rfd, ScalarT Rkd, ScalarT J, ScalarT P, ScalarT mub); + virtual ~SynchronousMachine(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT Lls_; + std::tuple Llkq_; + ScalarT Llfd_; + ScalarT Llkd_; + ScalarT Lmq_; + ScalarT Lmd_; + ScalarT Rs_; + std::tuple Rkq_; + ScalarT Rfd_; + ScalarT Rkd_; + ScalarT J_; + ScalarT P_; + ScalarT mub_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp index c27c04bd2..e26841a6c 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -39,6 +39,8 @@ int VoltageSource::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); + this->J_.resize(this->size_^2); + this->M_.resize(this->size_^2); return 0; } @@ -72,7 +74,7 @@ int VoltageSource::evaluateResidual() // for easier development this->f_[0] = this->y_[2]; this->f_[1] = -this->y_[2]; - this->f_[2] = this->y_[0] - this->y_[1] - this->V_; + this->f_[2] = this->y_[1] - this->y_[0] - this->V_; return 0; } diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp index ba9333f40..6d44d6b4f 100644 --- a/Examples/RLCircuit/RLCircuit.cpp +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -12,39 +12,10 @@ #include #include -#include int main(int argc, char const *argv[]) { - //Basic Circuit Setup - //@todo will want to eventually put components in the hyper graph instead of indicies - - std::unique_ptr> cirg(new CircuitGraph()); - for (size_t i = 0; i < 3; i++) - { - cirg->addHyperEdge(i); - } - for (size_t i = 0; i < 5; i++) - { - cirg->addHyperNode(i); - } - - //Create Connections of Nodes to edges sets - //External nodes - cirg->addConnection(0, 0); - cirg->addConnection(0, 2); - cirg->addConnection(2, 0); - cirg->addConnection(2, 1); - cirg->addConnection(3, 1); - cirg->addConnection(3, 2); - - //Internal nodes - cirg->addConnection(1,0); - cirg->addConnection(4,2); - - - cirg->printBiPartiteGraph(); //Create circuit model @@ -80,7 +51,7 @@ int main(int argc, char const *argv[]) //Allocate with graph - sysmodel->allocate(*cirg); + sysmodel->allocate(5); std::cout << sysmodel->y().size() << std::endl; diff --git a/ModelEvaluatorImpl.hpp b/ModelEvaluatorImpl.hpp index 94cbeb5d3..72abb858b 100644 --- a/ModelEvaluatorImpl.hpp +++ b/ModelEvaluatorImpl.hpp @@ -90,6 +90,8 @@ namespace ModelLib yp_(size_), f_(size_), g_(size_quad_), + J_(size_quad^2), + M_(size_quad^2), yB_(size_), ypB_(size_), fB_(size_), @@ -277,6 +279,9 @@ namespace ModelLib std::vector fB_; std::vector gB_; + std::vector J_; + std::vector M_; + std::vector param_; std::vector param_up_; std::vector param_lo_; diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index 78350ee2f..7a9304716 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -72,12 +72,18 @@ class PowerElectronicsModel : public ModelEvaluatorImpl return 1; } - int allocate(CircuitGraph cir) + /** + * @brief Allocate the vector data with size amount + * @todo Add capability to go through component model connection to get the size of the actual vector + * + * @param s + * @return int + */ + int allocate(IdxT s) { - this->graph = cir; // Allocate all components - this->size_ = cir.amountHyperNodes(); + this->size_ = s; for(const auto& component : components_) { component->allocate(); @@ -202,16 +208,9 @@ class PowerElectronicsModel : public ModelEvaluatorImpl this->components_.push_back(component); } - CircuitGraph getGraph() - { - return this->graph; - } - private: std::vector components_; - CircuitGraph graph; - }; // class PowerElectronicsModel } // namespace ModelLib From b9ce19fa347016ccbe7a2a15e69d0da620ae43e8 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Wed, 15 Nov 2023 20:47:04 -0500 Subject: [PATCH 03/44] Added COO Sparse Matrices, Component Jacobians, and Discrete Generator + Basic COO Sparse Matrix Implmentation + Discrete Generator Component + Resistor Jacobian + Capacitor Jacobian + Voltage Source Jacobian + Inductor Jacobian + Testing for Sparse Jacobian and Discrete Generator --- CMakeLists.txt | 3 + .../PowerElectronicsComponents/CMakeLists.txt | 3 +- .../Capacitor/Capacitor.cpp | 19 +- .../Capacitor/Capacitor.hpp | 1 + .../DiscreteGenerator/CMakeLists.txt | 8 + .../DiscreteGenerator/DiscreteGenerator.cpp | 278 ++++++++++ .../DiscreteGenerator/DiscreteGenerator.hpp | 100 ++++ .../Inductor/Inductor.cpp | 21 +- .../Inductor/Inductor.hpp | 1 + .../Resistor/Resistor.cpp | 11 +- .../Resistor/Resistor.hpp | 1 + .../VoltageSource/VoltageSource.cpp | 10 +- .../VoltageSource/VoltageSource.hpp | 1 + Examples/CMakeLists.txt | 2 + Examples/DiscreteGeneratorTest/CMakeLists.txt | 9 + Examples/DiscreteGeneratorTest/DGTest.cpp | 56 ++ Examples/RLCircuit/RLCircuit.cpp | 4 + Examples/SparseTest/CMakeLists.txt | 7 + Examples/SparseTest/SparseTest.cpp | 55 ++ ModelEvaluatorImpl.hpp | 20 +- PowerElectronicsModel.hpp | 6 + SparseMatrix/CMakeLists.txt | 7 + SparseMatrix/COO_Matrix.hpp | 515 ++++++++++++++++++ 23 files changed, 1122 insertions(+), 16 deletions(-) create mode 100644 ComponentLib/PowerElectronicsComponents/DiscreteGenerator/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp create mode 100644 Examples/DiscreteGeneratorTest/CMakeLists.txt create mode 100644 Examples/DiscreteGeneratorTest/DGTest.cpp create mode 100644 Examples/SparseTest/CMakeLists.txt create mode 100644 Examples/SparseTest/SparseTest.cpp create mode 100644 SparseMatrix/CMakeLists.txt create mode 100644 SparseMatrix/COO_Matrix.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 19048d375..ef6cbcf57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,6 +143,9 @@ add_subdirectory(ComponentLib) # General Utilities and File IO add_subdirectory(Utilities) +#Local Sparse matrix operations +add_subdirectory(SparseMatrix) + # Create solvers add_subdirectory(Solver) diff --git a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt index 10f2c6fdc..9d6ad8be1 100644 --- a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt +++ b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt @@ -6,4 +6,5 @@ add_subdirectory(VoltageSource) add_subdirectory(Inductor) add_subdirectory(LinearTransformer) add_subdirectory(InductionMotor) -add_subdirectory(SynchronousMachine) \ No newline at end of file +add_subdirectory(SynchronousMachine) +add_subdirectory(DiscreteGenerator) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp index d905dda05..ecbe9d51f 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -39,8 +39,7 @@ int Capacitor::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); - this->J_.resize(this->size_^2); - this->M_.resize(this->size_^2); + return 0; } @@ -72,13 +71,27 @@ int Capacitor::evaluateResidual() { this->f_[0] = this->yp_[2]; this->f_[1] = -this->yp_[2]; - this->f_[2] = this->y_[0] - this->y_[1] - this->y_[2] - this->C_ * this->yp_[2]; + this->f_[2] = -this->C_ * this->yp_[2] + this->y_[0] - this->y_[1] - this->y_[2]; return 0; } template int Capacitor::evaluateJacobian() { + //Create dF/dy + std::vector rcord{2,2,2}; + std::vector ccord{0,1,2}; + std::vector vals{1.0, -1.0, -1.0}; + this->J_.setValues(rcord, ccord, vals); + + //Create -dF/dy' + std::vector rcordder{0,1,2}; + std::vector ccordder{2,2,2}; + std::vector valsder{1.0, -1.0, -this->C_}; + COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); + + //Perform dF/dy + \alpha dF/dy' + this->J_.AXPY(this->alpha_, &Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp index 76cf94614..e1a9974c3 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp @@ -36,6 +36,7 @@ namespace ModelLib using CircuitComponent::ypB_; using CircuitComponent::fB_; using CircuitComponent::gB_; + using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/CMakeLists.txt new file mode 100644 index 000000000..c0ed2c7a9 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_disgen + SOURCES + DiscreteGenerator.cpp + OUTPUT_NAME + gridkit_powerelec_disgen) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp new file mode 100644 index 000000000..7770281d1 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp @@ -0,0 +1,278 @@ + + + +#include +#include +#include +#include "DiscreteGenerator.hpp" + +namespace ModelLib { + + +/*! + * @brief Constructor for a Discrete Generator + * @todo Maybe have parameters be templated in. Variables cannot be changed and are unlikely to. Allows for compile time optimizations + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +DiscreteGenerator::DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm) + : wb_(parm.wb), wc_(parm.wc), mp_(parm.mp), refmp_(parm.refmp), Vn_(parm.Vn), nq_(parm.nq), F_(parm.F), Kiv_(parm.Kiv), Kpv_(parm.Kpv), Kic_(parm.Kic), Kpc_(parm.Kpc), Cf_(parm.Cf), rLf_(parm.rLf), Lf_(parm.Lf), rLc_(parm.rLc), Lc_(parm.Lc) +{ + // internals [delta_i, Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi] + // externals [Pref, Pbus, QBus] + this->size_ = 16; + this->n_intern = 13; + this->n_extern = 3; + this->extern_indices = {0,1,2}; + this->idc_ = id; +} + +template +DiscreteGenerator::~DiscreteGenerator() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int DiscreteGenerator::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + + return 0; +} + +/** + * Initialization of the grid model + */ +template +int DiscreteGenerator::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int DiscreteGenerator::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int DiscreteGenerator::evaluateResidual() +{ + // ### Externals Componenets ### + //Reference P + ScalarT wcom = this->wb_ - this->refmp_ * this->y_[0]; + + this->f_[0] = 0; + this->f_[1] = 0; + this->f_[2] = 0; + + // ### Internal Componenets ## + f_[3] = -yp_[3] + wb_ - mp_ * y_[4] - wcom; + + f_[4] = -yp_[4] + wc_ * (y_[12] * y_[14] + y_[13] * y_[15] - y_[4]); + f_[5] = -yp_[4] + wc_ * (-y_[12] * y_[15] + y_[13] * y_[14] - y_[5]); + + ScalarT vod_star = Vn_ - nq_ * y_[5]; + ScalarT voq_star = 0; + + f_[6] = -yp_[6] + vod_star - y_[12]; + f_[7] = -yp_[7] + voq_star - y_[13]; + + ScalarT ild_star = F_ * y_[14] - wb_ * Cf_ * y_[13] + Kpv_ * (vod_star - y_[12]) + Kiv_ * y_[6] ; + ScalarT ilq_star = F_ * y_[15] + wb_ * Cf_ * y_[12] + Kpv_ * (voq_star - y_[13]) + Kiv_ * y_[7]; + + f_[8] = -yp_[8] + ild_star - y_[10]; + f_[9] = -yp_[9] + ilq_star - y_[11]; + + ScalarT vid_star = -wb_ * Lf_ * y_[11] + Kpc_ * (ild_star - y_[10]) + Kic_ * y_[8]; + ScalarT viq_star = wb_ * Lf_ * y_[10] + Kpc_ * (ilq_star - y_[11]) + Kic_ * y_[9]; + + f_[10] = -yp_[10] - (rLf_ / Lf_) * y_[10] + wcom * y_[11] + (1/Lf_) * (vid_star - y_[12]); + f_[11] = -yp_[11] - (rLf_ / Lf_) * y_[11] - wcom * y_[10] + (1/Lf_) * (viq_star - y_[13]); + + f_[12] = -yp_[12] + wcom * y_[13] + (1/Cf_) * (y_[10] - y_[14]); + f_[13] = -yp_[13] - wcom * y_[12] + (1/Cf_) * (y_[11] - y_[15]); + + f_[14] = -yp_[14] - (rLc_ / Lc_) * y_[14] + wcom * y_[15] + (1/Lc_)*(y_[12] - y_[1]); + f_[15] = -yp_[15] - (rLc_ / Lc_) * y_[15] - wcom * y_[14] + (1/Lc_)*(y_[13] - y_[2]); + return 0; +} + +/** + * @brief Compute the jacobian of the DiscreteGenerator for iteration. dF/dy - \alpha dF/dy' + * + * The matrix dF/dy should be + * [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[ mpref, 0, 0, 0, -mp, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[ 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, 0, wc*x15, wc*x16, wc*x13, wc*x14] +[ 0, 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, -wc*x16, wc*x15, wc*x14, -wc*x13] +[ 0, 0, 0, 0, 0, -nq, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0] +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0] +[ 0, 0, 0, 0, 0, -Kpv*nq, Kiv, 0, 0, 0, -1, 0, -Kpv, -Cf*wb, F, 0] +[ 0, 0, 0, 0, 0, 0, 0, Kiv, 0, 0, 0, -1, Cf*wb, -Kpv, 0, F] +[-mpref*x12, 0, 0, 0, 0, -(Kpc*Kpv*nq)/Lf, (Kiv*Kpc)/Lf, 0, Kic/Lf, 0, - Kpc/Lf - rLf/Lf, -mpref*x1, -(Kpc*Kpv + 1)/Lf, -(Cf*Kpc*wb)/Lf, (F*Kpc)/Lf, 0] +[ mpref*x11, 0, 0, 0, 0, 0, 0, (Kiv*Kpc)/Lf, 0, Kic/Lf, mpref*x1, - Kpc/Lf - rLf/Lf, (Cf*Kpc*wb)/Lf, -(Kpc*Kpv + 1)/Lf, 0, (F*Kpc)/Lf] +[-mpref*x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Cf, 0, 0, wb - mpref*x1, -1/Cf, 0] +[ mpref*x13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Cf, mpref*x1 - wb, 0, 0, -1/Cf] +[-mpref*x16, -1/Lc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Lc, 0, -rLc/Lc, wb - mpref*x1] +[ mpref*x15, 0, -1/Lc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Lc, mpref*x1 - wb, -rLc/Lc] + * 'Generated from MATLAB symbolic' + * Jacobian is mostly constant besides reference and rows 4 & 5 + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ +template +int DiscreteGenerator::evaluateJacobian() +{ + //Create dF/dy' + std::vector rcordder(13); + std::vector valsder(13,1.0); + for (int i = 0; i < 13; i++) + { + rcordder[i] = i + 3; + } + COO_Matrix Jacder = COO_Matrix(rcordder, rcordder, valsder,16,16); + + //Create dF/dy + //r = 3 + std::vector ctemp{0, 4}; + std::vector rtemp(ctemp.size(),3); + std::vector valtemp{this->refmp_, -this->mp_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 4 + ctemp = {4, 12, 13, 14, 15}; + std::fill(rtemp.begin(), rtemp.end(), 4); + valtemp = {-this->wc_, this->wc_*y_[14], this->wc_*y_[15], this->wc_*y_[12], this->wc_*y_[13]}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 5 + ctemp = {5, 12, 13, 14, 15}; + std::fill(rtemp.begin(), rtemp.end(), 5); + valtemp = {-this->wc_, -this->wc_*y_[15], this->wc_*y_[14], this->wc_*y_[13], -this->wc_*y_[12]}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 6 + ctemp = {5, 12}; + std::fill(rtemp.begin(), rtemp.end(), 6); + valtemp = {-this->nq_, -1.0}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 7 + ctemp = {13}; + std::fill(rtemp.begin(), rtemp.end(), 7); + valtemp = {-1.0}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 8 + ctemp = {5,6,10,12,13,14}; + std::fill(rtemp.begin(), rtemp.end(), 8); + valtemp = {-this->Kpv_*this->nq_, this->Kiv_, -1.0, -this->Kpv_, -this->Cf_*this->wb_, this->F_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 9 + ctemp = {7, 11, 12, 13, 15}; + std::fill(rtemp.begin(), rtemp.end(), 9); + valtemp = {this->Kiv_, -1.0, this->Cf_*this->wb_,-this->Kpv_,this->F_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 10 + ctemp = {0, 5, 6, 8, 10, 11, 12, 13, 14}; + std::fill(rtemp.begin(), rtemp.end(), 10); + valtemp = {-this->refmp_ * y_[11], -(this->Kpc_ * this->Kpv_ * this->nq_) / this->Lf_, (this->Kpc_ * this->Kiv_) / this->Lf_, this->Kic_ / this->Lf_, -(this->Kpc_ + this->rLf_) / this->Lf_, -this->refmp_ * y_[0], -(this->Kpc_ * this->Kpv_ + 1.0) / this->Lf_, -(this->Cf_ * this->Kpc_ * this->wb_) / this->Lf_, (this->F_ * this->Kpc_) / this->Lf_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 11 + ctemp = {0, 7, 9, 10, 11, 12, 13, 15}; + std::fill(rtemp.begin(), rtemp.end(), 11); + valtemp = {this->refmp_ * y_[10], (this->Kiv_ * this->Kpc_) / this->Lf_, this->Kic_ / this->Lf_, this->refmp_ * y_[0], -(this->Kpc_ + this->rLf_) / this->Lf_, (this->Cf_ * this->Kpc_ * this->wb_) / this->Lf_, -(this->Kpc_ * this->Kpv_ + 1.0) / this->Lf_, (this->F_ * this->Kpc_) / this->Lf_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 12 + ctemp = {0, 10, 13, 14}; + std::fill(rtemp.begin(), rtemp.end(), 12); + valtemp = {-this->refmp_ * y_[13], 1.0 / this->Cf_, this->wb_ - this->refmp_ * y_[0], -1.0 / this->Cf_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + + //r = 13 + ctemp = {0, 11, 12, 15}; + std::fill(rtemp.begin(), rtemp.end(), 13); + valtemp = {this->refmp_ * y_[12], 1.0 / this->Cf_, -this->wb_ + this->refmp_ * y_[0], -1.0 / this->Cf_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + + //r = 14 + ctemp = {0, 1, 12, 14, 15}; + std::fill(rtemp.begin(), rtemp.end(), 14); + valtemp = {-this->refmp_ * y_[15], -1.0 / this->Lc_, 1.0 / this->Lc_, -this->rLc_ / this->Lc_, this->wb_ - this->refmp_ * y_[0]}; + this->J_.setValues(rtemp, ctemp, valtemp); + + + //r = 15 + ctemp = {0, 2, 13, 14, 15}; + std::fill(rtemp.begin(), rtemp.end(), 15); + valtemp = {-this->refmp_ * y_[14], -1.0 / this->Lc_, 1.0 / this->Lc_, -this->wb_ + this->refmp_ * y_[0], -this->rLc_ / this->Lc_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + + //Perform dF/dy + \alpha dF/dy' + + this->J_.AXPY(-this->alpha_, &Jacder); + + return 0; +} + +template +int DiscreteGenerator::evaluateIntegrand() +{ + return 0; +} + +template +int DiscreteGenerator::initializeAdjoint() +{ + return 0; +} + +template +int DiscreteGenerator::evaluateAdjointResidual() +{ + return 0; +} + +template +int DiscreteGenerator::evaluateAdjointIntegrand() +{ + return 0; +} + + + + +// Available template instantiations +template class DiscreteGenerator; +template class DiscreteGenerator; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp new file mode 100644 index 000000000..f5ce86899 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp @@ -0,0 +1,100 @@ + + +#ifndef _CAP_HPP_ +#define _CAP_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; + + template + struct DiscreteGeneratorParameters + { + ScalarT wb; + ScalarT wc; + ScalarT mp; + ScalarT refmp; + ScalarT Vn; + ScalarT nq; + ScalarT F; + ScalarT Kiv; + ScalarT Kpv; + ScalarT Kic; + ScalarT Kpc; + ScalarT Cf; + ScalarT rLf; + ScalarT Lf; + ScalarT rLc; + ScalarT Lc; + }; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive DiscreteGenerator class. + * + */ + template + class DiscreteGenerator : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::J_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + public: + DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm); + virtual ~DiscreteGenerator(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT wb_; + ScalarT wc_; + ScalarT mp_; + ScalarT refmp_; + ScalarT Vn_; + ScalarT nq_; + ScalarT F_; + ScalarT Kiv_; + ScalarT Kpv_; + ScalarT Kic_; + ScalarT Kpc_; + ScalarT Cf_; + ScalarT rLf_; + ScalarT Lf_; + ScalarT rLc_; + ScalarT Lc_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index 952a992d0..89f903436 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -40,8 +40,7 @@ int Inductor::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); - this->J_.resize(this->size_^2); - this->M_.resize(this->size_^2); + return 0; } @@ -73,13 +72,29 @@ int Inductor::evaluateResidual() { this->f_[0] = this->y_[2]; this->f_[1] = -this->y_[2]; - this->f_[2] = this->y_[0] - this->y_[1] - this->L_ * this->yp_[2]; + this->f_[2] = - this->L_ * this->yp_[2] + this->y_[0] - this->y_[1] ; return 0; } template int Inductor::evaluateJacobian() { + + //Create dF/dy + std::vector rcord{0,1,2,2}; + std::vector ccord{2,2,0,1}; + std::vector vals{1.0, -1.0, 1.0, -1.0}; + this->J_.setValues(rcord, ccord, vals); + + //Create -dF/dy' + std::vector rcordder{2}; + std::vector ccordder{2}; + std::vector valsder{-this->L_}; + COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); + + //Perform dF/dy + \alpha dF/dy' + this->J_.AXPY(this->alpha_, &Jacder); + return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp index e959aabf1..2f2c1085b 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp @@ -36,6 +36,7 @@ namespace ModelLib using CircuitComponent::ypB_; using CircuitComponent::fB_; using CircuitComponent::gB_; + using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp index 5faad23b4..7536f2274 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp @@ -39,8 +39,7 @@ int Resistor::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); - this->J_.resize(this->size_^2); - this->M_.resize(this->size_^2); + return 0; } @@ -79,6 +78,14 @@ int Resistor::evaluateResidual() template int Resistor::evaluateJacobian() { + + //Create dF/dy + //does compiler make constant??? + std::vector rcord{0,0,1,1}; + std::vector ccord{0,1,0,1}; + std::vector vals{-1.0 / this->R_, 1.0 / this->R_, 1.0 / this->R_, -1.0 / this->R_}; + this->J_.setValues(rcord, ccord, vals); + return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp index 0373e2c5c..984d8304b 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp @@ -36,6 +36,7 @@ namespace ModelLib using CircuitComponent::ypB_; using CircuitComponent::fB_; using CircuitComponent::gB_; + using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp index e26841a6c..b7c18bd6f 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -39,8 +39,7 @@ int VoltageSource::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); - this->J_.resize(this->size_^2); - this->M_.resize(this->size_^2); + return 0; } @@ -81,6 +80,13 @@ int VoltageSource::evaluateResidual() template int VoltageSource::evaluateJacobian() { + + //Create dF/dy + std::vector rcord{0,1,2,2}; + std::vector ccord{2,2,0,1}; + std::vector vals{1.0, -1.0, -1.0, 1.0}; + this->J_.setValues(rcord, ccord, vals); + return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp index dcbacf2f7..3ac1c8699 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp @@ -36,6 +36,7 @@ namespace ModelLib using CircuitComponent::ypB_; using CircuitComponent::fB_; using CircuitComponent::gB_; + using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index b42907fd3..e15774642 100644 --- a/Examples/CMakeLists.txt +++ b/Examples/CMakeLists.txt @@ -57,6 +57,8 @@ add_subdirectory(MatPowerTesting) add_subdirectory(RLCircuit) +add_subdirectory(SparseTest) +add_subdirectory(DiscreteGeneratorTest) if(TARGET SUNDIALS::kinsol) add_subdirectory(Grid3Bus) diff --git a/Examples/DiscreteGeneratorTest/CMakeLists.txt b/Examples/DiscreteGeneratorTest/CMakeLists.txt new file mode 100644 index 000000000..b1100b91a --- /dev/null +++ b/Examples/DiscreteGeneratorTest/CMakeLists.txt @@ -0,0 +1,9 @@ + + + + +add_executable(dgtest DGTest.cpp) +target_link_libraries(dgtest GRIDKIT::powerelec_disgen) + +add_test(NAME DiscreteGeneratorTest COMMAND $) +install(TARGETS dgtest RUNTIME DESTINATION bin) diff --git a/Examples/DiscreteGeneratorTest/DGTest.cpp b/Examples/DiscreteGeneratorTest/DGTest.cpp new file mode 100644 index 000000000..7d4aeda6f --- /dev/null +++ b/Examples/DiscreteGeneratorTest/DGTest.cpp @@ -0,0 +1,56 @@ + + +#include +#include +#include +#include +#include +#include + +#include + + +int main(int argc, char const *argv[]) +{ + + ModelLib::DiscreteGeneratorParameters parms; + //Parameters from MATLAB Microgrid code for first DG + //refmp is need for reference input + parms.wb = 2.0*M_PI*50.0; + parms.wc = 31.41; + parms.mp = 9.4e-5; + parms.refmp = 9.4e-5; + parms.Vn = 380; + parms.nq = 1.3e-3; + parms.F = 0.75; + parms.Kiv = 420.0; + parms.Kpv = 0.1; + parms.Kic = 20.0 * 1.0e3; + parms.Kpc = 15.0; + parms.Cf = 50.0e-6; + parms.rLf = 0.1; + parms.Lf = 1.35e-3; + parms.rLc = 0.03; + parms.Lc = 0.35e-3; + + ModelLib::DiscreteGenerator *dg = new ModelLib::DiscreteGenerator(0, parms); + + std::vector t1(16,0.0); + std::vector t2{0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,1.3,1.4,1.5}; + + dg->allocate(); + + dg->y() = t2; + dg->yp() = t1; + + dg->evaluateResidual(); + + std::cout << "Output: {"; + for (double i : dg->getResidual()) + { + std::cout << i << ", "; + } + std::cout << "}\n"; + + return 0; +} diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp index 6d44d6b4f..4669d564e 100644 --- a/Examples/RLCircuit/RLCircuit.cpp +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -80,6 +80,10 @@ int main(int argc, char const *argv[]) } std::cout << "}\n"; + induct->updateTime(0.0, 1.0); + induct->evaluateJacobian(); + induct->getJacobian().printMatrix(true); + return 0; } diff --git a/Examples/SparseTest/CMakeLists.txt b/Examples/SparseTest/CMakeLists.txt new file mode 100644 index 000000000..d0b6f5e05 --- /dev/null +++ b/Examples/SparseTest/CMakeLists.txt @@ -0,0 +1,7 @@ + + +add_executable(spmattest SparseTest.cpp) +target_link_libraries(spmattest GRIDKIT::SparseMatrix) + +add_test(NAME SparseMatrixTest COMMAND $) +install(TARGETS spmattest RUNTIME DESTINATION bin) diff --git a/Examples/SparseTest/SparseTest.cpp b/Examples/SparseTest/SparseTest.cpp new file mode 100644 index 000000000..976759533 --- /dev/null +++ b/Examples/SparseTest/SparseTest.cpp @@ -0,0 +1,55 @@ + + +#include +#include +#include +#include +#include +#include +#include + +#include + + + + +int main(int argc, char const *argv[]) +{ + std::vector val{0.1, 0.2, 0.3, 0.4}; + std::vector x{2,1,3,1}; + std::vector y{1,3,2,2}; + size_t n = 4; + size_t m = 4; + + COO_Matrix A = COO_Matrix(x,y,val,m,n); + + std::vector valn(4); + std::vector xn(4); + std::vector yn(4); + + std::tie(xn, yn, valn) = A.getEntries(); + + for (size_t i = 0; i < valn.size(); i++) + { + std::cout << valn[i] << "\n"; + } + + std::cout << "A:\n"; + A.printMatrix(true); + + std::vector val2{0.5, 0.6, 0.7, 0.8, 1.0}; + std::vector x2{0,2,0,2,1}; + std::vector y2{3,3,2,2,3}; + COO_Matrix B = COO_Matrix(x2,y2,val2,m,n); + + std::cout << "B:\n"; + B.printMatrix(true); + + A.AXPY(2.0, &B); + + std::cout << "A + 2B:\n"; + A.printMatrix(true); + + + return 0; +} diff --git a/ModelEvaluatorImpl.hpp b/ModelEvaluatorImpl.hpp index 72abb858b..ade61feff 100644 --- a/ModelEvaluatorImpl.hpp +++ b/ModelEvaluatorImpl.hpp @@ -62,6 +62,7 @@ #include #include +#include namespace ModelLib { @@ -90,16 +91,16 @@ namespace ModelLib yp_(size_), f_(size_), g_(size_quad_), - J_(size_quad^2), - M_(size_quad^2), yB_(size_), ypB_(size_), fB_(size_), gB_(size_opt_), + J_(COO_Matrix()), param_(size_opt_), param_up_(size_opt_), param_lo_(size_opt_) - {} + { + } virtual IdxT size() { @@ -224,6 +225,16 @@ namespace ModelLib return f_; } + COO_Matrix& getJacobian() + { + return J_; + } + + const COO_Matrix& getJacobian() const + { + return J_; + } + std::vector& getIntegrand() { return g_; @@ -279,8 +290,7 @@ namespace ModelLib std::vector fB_; std::vector gB_; - std::vector J_; - std::vector M_; + COO_Matrix J_; std::vector param_; std::vector param_up_; diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index 7a9304716..018ceaeaf 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -34,6 +34,7 @@ class PowerElectronicsModel : public ModelEvaluatorImpl // using ModelEvaluatorImpl::fB_; // using ModelEvaluatorImpl::g_; // using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::J_; using ModelEvaluatorImpl::rtol_; using ModelEvaluatorImpl::atol_; // using ModelEvaluatorImpl::param_; @@ -153,6 +154,11 @@ class PowerElectronicsModel : public ModelEvaluatorImpl return 0; } + /** + * @brief Creates the Sparse COO Jacobian representing \alpha dF/dy' + dF/dy + * + * @return int + */ int evaluateJacobian() { return 0; diff --git a/SparseMatrix/CMakeLists.txt b/SparseMatrix/CMakeLists.txt new file mode 100644 index 000000000..b51d669ec --- /dev/null +++ b/SparseMatrix/CMakeLists.txt @@ -0,0 +1,7 @@ + +add_library(SparseMatrix INTERFACE) +include_directories(SparseMatrix INTERFACE ${CMAKE_CURRENT_LIST_DIR}) + +add_library(GRIDKIT::SparseMatrix ALIAS SparseMatrix) + + diff --git a/SparseMatrix/COO_Matrix.hpp b/SparseMatrix/COO_Matrix.hpp new file mode 100644 index 000000000..e4b087386 --- /dev/null +++ b/SparseMatrix/COO_Matrix.hpp @@ -0,0 +1,515 @@ + + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @brief Quick class to provide sparse matrices of COO type. Simplifies data movement + * @todo Add base class of sparse matrix for conversion to CSR + * @todo Switch Push back with buffer allocation for resizing + * @todo NonZero Values for preallocation + * @todo Fix warnings, mostly type casting of indexes. Should try to move to iterator somehow + * + * m x n sparse matrix + */ +template +class COO_Matrix +{ +private: + std::vector values; + std::vector row_indexes; + std::vector column_indexes; + Intdx rows_size; + Intdx columns_size; + bool sorted; +public: + COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n); + COO_Matrix(Intdx m, Intdx n); + COO_Matrix(); + ~COO_Matrix(); + + //could replace with binary operation for both + // --- Functions which donot sort --- + void setValues(std::vector r, std::vector c, std::vector val); + void addValues(std::vector r, std::vector c, std::vector val); + + // --- Functions which call sort --- + std::tuple, std::vector> getRowCopy(Intdx r); + std::tuple, std::vector, std::vector> getEntries(); + + // BLAS. Will sort before running + void AXPY(ScalarT alpha, COO_Matrix* a); + + // --- Permutation Operations --- + //No sorting is actually done. Only done when nesscary + void permutation(std::vector row_perm, std::vector col_perm); + void permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n); + + //Resort values + void sortSparse(); + bool isSorted(); + + std::tuple getDimensions(); + + void printMatrix(bool sort); + +private: + std::vector indexEntries(std::vector r, std::vector c); + Intdx indexStartRow(Intdx r); +}; + +/** + * @brief Set values of sparse matrix. Increases size if outside bounds + * + * @todo should error return if outside bounds instead? + * + * @tparam ScalarT + * @tparam Intdx + * @param r + * @param c + * @param val + */ +template +inline void COO_Matrix::setValues(std::vector r, std::vector c, std::vector val) +{ + std::vector indexes = this->indexEntries(r,c); + + for (int i = 0; i < indexes.size(); i++) + { + if (indexes[i] == -1) + { + if (r[i] >= this->rows_size) + { + this->rows_size = r[i]; + } + if (c[i] >= this->columns_size) + { + this->columns_size = c[i]; + } + + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(val[i]); + this->sorted = false; + } + else + { + this->values[indexes[i]] = val[i]; + } + } + +} + +/** + * @brief Add new values to sparse matrix. Will increase size if outside bounds + * + * @todo should error return if outside bounds instead? + * + * @tparam ScalarT + * @tparam Intdx + * @param r + * @param c + * @param val + */ +template +inline void COO_Matrix::addValues(std::vector r, std::vector c, std::vector val) +{ + std::vector indexes = this->indexEntries(r,c); + + for (int i = 0; i < indexes.size(); i++) + { + if (indexes[i] == -1) + { + if (r[i] >= this->rows_size) + { + this->rows_size = r[i]; + } + if (c[i] >= this->columns_size) + { + this->columns_size = c[i]; + } + + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(val[i]); + this->sorted = false; + } + else + { + this->values[indexes[i]] += val[i]; + } + } + +} + +/** + * @brief Get copy of row values + * + * @tparam ScalarT + * @tparam Intdx + * @param r + * @return std::tuple, std::vector> + */ +template +inline std::tuple, std::vector> COO_Matrix::getRowCopy(Intdx r) +{ + if (!this->sorted) + { + this->sortSparse(); + } + Intdx rowindex = this->indexStartRow(r); + + + if (rowindex == -1) + { + return {std::vector(),std::vector()}; + } + + Intdx rsize = rowindex; + do + { + rsize++; + } while (rsize < this->values.size() && this->row_indexes[rsize] == r); + + return {{this->column_indexes.begin() + rowindex, this->column_indexes.begin() + rsize},{this->values.begin() + rowindex, this->values.begin() + rsize}}; +} + +/** + * @brief Get all Entries + * + * @tparam ScalarT + * @tparam Intdx + * @return std::tuple, std::vector, std::vector> + */ +template +inline std::tuple, std::vector, std::vector> COO_Matrix::getEntries() +{ + if (!this->sorted) + { + this->sortSparse(); + } + return {this->row_indexes, this->column_indexes, this->values}; +} + +template +inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrix *a) +{ + if (alpha == 0) return; + + if (!this->sorted) + { + this->sortSparse(); + } + if (!a->isSorted()) + { + a->sortSparse(); + } + std::vector val; + std::vector r; + std::vector c; + Intdx m = 0; + Intdx n = 0; + std::tie(r,c,val) = a->getEntries(); + std::tie(m,n) = a->getDimensions(); + + this->rows_size = this->rows_size > m ? this->rows_size : m; + this->columns_size = this->columns_size > n ? this->columns_size : n; + + Intdx aiter = 0; + //iterate for all current values in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + { + //pushback values when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + { + this->row_indexes.push_back(r[aiter]); + this->column_indexes.push_back(c[aiter]); + this->values.push_back(alpha * val[aiter]); + aiter++; + } + if (aiter >= r.size()) break; + + + if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + { + this->values[i] += alpha * val[aiter]; + aiter++; + } + } + //push back rest that was not found sorted + for (Intdx i = aiter; i < static_cast(r.size()); i++) + { + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(alpha * val[i]); + } + + this->sorted = false; +} + +/** + * @brief Permutate the matrix to a different one. Only changes the coordinates + * + * @tparam ScalarT + * @tparam Intdx + * @param row_perm + * @param col_perm + */ +template +inline void COO_Matrix::permutation(std::vector row_perm, std::vector col_perm) +{ + assert(row_perm.size() = this->rows_size); + assert(col_perm.size() = this->columns_size); + + for (int i = 0; i < this->values.size(); i++) + { + this->row_indexes[i] = row_perm[this->row_indexes[i]]; + this->column_indexes[i] = col_perm[this->column_indexes[i]]; + } + this->sorted = false; +} + +/** + * @brief Permutates the matrix and can change its size efficently + * if size is shrinking and value is to be removed the negative one + * + * @tparam ScalarT + * @tparam Intdx + * @param row_perm size of m + * @param col_perm size of n + * @param m + * @param n + */ +template +inline void COO_Matrix::permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n) +{ + assert(row_perm.size() == this->rows_size); + assert(col_perm.size() == this->columns_size); + + this->rows_size = m; + this->columns_size = n; + + for (int i = 0; i < this->values.size(); i++) + { + if (row_perm[this->row_indexes[i]] == -1 || col_perm[this->column_indexes[i]] == -1) + { + this->values[i] = 0; + } + else + { + this->row_indexes[i] = row_perm[this->row_indexes[i]]; + this->column_indexes[i] = col_perm[this->column_indexes[i]]; + } + } + this->sorted = false; +} + +/** + * @brief Restructure the sparse matrix for faster accesses and modifications + * + * @tparam ScalarT + * @tparam Intdx + */ +template +inline void COO_Matrix::sortSparse() +{ + //index based sort code + // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted-vector + + + //cannot call sort since two arrays are used instead + std::vector ordervec(this->row_indexes.size()); + std::size_t n(0); + std::generate(std::begin(ordervec), std::end(ordervec), [&]{ return n++; }); + + std::sort( std::begin(ordervec), + std::end(ordervec), + [&](int i1, int i2) { return this->row_indexes[i1] < this->row_indexes[i2] || + (this->row_indexes[i1] == this->row_indexes[i2] && this->column_indexes[i1] < this->column_indexes[i2]); } ); + + + //reorder based of index-sorting. Only swap no extra memory + // https://stackoverflow.com/a/22183350 + for (size_t i = 0; i < ordervec.size(); i++) + { + //permutation swap + while (ordervec[i] != ordervec[ordervec[i]]) + { + std::swap(this->row_indexes[ordervec[i]], this->row_indexes[ordervec[ordervec[i]]]); + std::swap(this->column_indexes[ordervec[i]], this->column_indexes[ordervec[ordervec[i]]]); + std::swap(this->values[ordervec[i]], this->values[ordervec[ordervec[i]]]); + + //swap orderings + std::swap(ordervec[i], ordervec[ordervec[i]]); + } + + } + this->sorted = true; +} + +template +inline bool COO_Matrix::isSorted() +{ + return this->sorted; +} + +template +inline std::tuple COO_Matrix::getDimensions() +{ + return std::tuple(this->rows_size, this->columns_size); +} + +template +inline void COO_Matrix::printMatrix(bool sort) +{ + if (sort == true && this->sorted == false) + { + this->sortSparse(); + } + + std::cout << "Sparse COO Matrix\n"; + std::cout << "(x , y, value)\n"; + for (size_t i = 0; i < this->values.size(); i++) + { + std::cout << "(" << this->row_indexes[i] + << ", " << this->column_indexes[i] + << ", " << this->values[i] << ")\n"; + } +} + +/** + * @brief Given vector indexes return the entries + * + * @tparam ScalarT + * @tparam Intdx + * @param r + * @param c + * @return std::vector + */ +template +inline std::vector COO_Matrix::indexEntries(std::vector r, std::vector c) +{ + assert(r.size() == c.size()); + std::vector valsnew(r.size(), -1); + + //cannot assume input is sorted so linear + Intdx aiter = 0; + //should fix this + for (Intdx i = 0; i < this->row_indexes.size(); i++) + { + while(r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i])) + { + valsnew.push_back(-1); + aiter++; + } + + if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + { + valsnew.push_back(i); + aiter++; + } + + } + return valsnew; + +} + +/** + * @brief Given row index get start. If no start returns -1 + * + * @tparam ScalarT + * @tparam Intdx + * @param r + * @return Intdx + */ +template +inline Intdx COO_Matrix::indexStartRow(Intdx r) +{ + if (this->sorted) + { + //basic binary search + Intdx i1 = 0; + Intdx i2 = this->row_indexes.size()-1; + Intdx m = 0; + while (i1 <= i2) + { + m = (i2 + i1) / 2; + //rows + if (this->row_indexes[m] < r) + { + i1 = m + 1; + } + else if (r < this->row_indexes[m]) + { + i2 = m - 1; + } + else + { + break; + } + } + //drop to first index + while (this->row_indexes[m] == r) + { + m--; + } + return m; + + } + else + { + for (int i = 0; i < this->row_indexes.size(); i++) + { + if (this->row_indexes[i] == r) + { + return i; + } + } + } + return -1; +} + +template +inline COO_Matrix::COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n) +{ + this->values = v; + this->row_indexes = r; + this->column_indexes = c; + this->rows_size = m; + this->columns_size = n; + this->sorted = false; +} + +template +inline COO_Matrix::COO_Matrix(Intdx m, Intdx n) +{ + this->rows_size = m; + this->columns_size = n; + this->values = std::vector(); + this->row_indexes = std::vector(); + this->column_indexes = std::vector(); + this->sorted = false; +} + +template +inline COO_Matrix::COO_Matrix() +{ + this->rows_size = 0; + this->columns_size = 0; + this->values = std::vector(); + this->row_indexes = std::vector(); + this->column_indexes = std::vector(); + this->sorted = false; +} + +template +COO_Matrix::~COO_Matrix() +{ + +} From be22b55d5f37606edf445f758726f5d639ca6493 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Mon, 20 Nov 2023 17:21:22 -0500 Subject: [PATCH 04/44] Added Jacobian Assembly. Fixed and Added New Functionality to COO Matrices +Matrix Assembly +Refactored COO Matrix +COO can return CSR Data format --- .../Capacitor/Capacitor.cpp | 2 +- .../DiscreteGenerator/DiscreteGenerator.cpp | 2 +- .../Inductor/Inductor.cpp | 2 +- Examples/RLCircuit/RLCircuit.cpp | 9 +- Examples/SparseTest/SparseTest.cpp | 49 +- PowerElectronicsModel.hpp | 65 ++- SparseMatrix/COO_Matrix.hpp | 521 +++++++++++------- 7 files changed, 436 insertions(+), 214 deletions(-) diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp index ecbe9d51f..79faefe89 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -91,7 +91,7 @@ int Capacitor::evaluateJacobian() COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(this->alpha_, &Jacder); + this->J_.AXPY(this->alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp index 7770281d1..c66c5b0f9 100644 --- a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp +++ b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp @@ -237,7 +237,7 @@ int DiscreteGenerator::evaluateJacobian() //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(-this->alpha_, &Jacder); + this->J_.AXPY(-this->alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index 89f903436..b0b19e63b 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -93,7 +93,7 @@ int Inductor::evaluateJacobian() COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(this->alpha_, &Jacder); + this->J_.AXPY(this->alpha_, Jacder); return 0; } diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp index 4669d564e..124b50bc0 100644 --- a/Examples/RLCircuit/RLCircuit.cpp +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -80,9 +80,12 @@ int main(int argc, char const *argv[]) } std::cout << "}\n"; - induct->updateTime(0.0, 1.0); - induct->evaluateJacobian(); - induct->getJacobian().printMatrix(true); + + sysmodel->updateTime(0.0, 1.0); + sysmodel->evaluateJacobian(); + sysmodel->getJacobian().printMatrix(); + + return 0; diff --git a/Examples/SparseTest/SparseTest.cpp b/Examples/SparseTest/SparseTest.cpp index 976759533..81e5ac7dd 100644 --- a/Examples/SparseTest/SparseTest.cpp +++ b/Examples/SparseTest/SparseTest.cpp @@ -10,9 +10,6 @@ #include - - - int main(int argc, char const *argv[]) { std::vector val{0.1, 0.2, 0.3, 0.4}; @@ -35,7 +32,7 @@ int main(int argc, char const *argv[]) } std::cout << "A:\n"; - A.printMatrix(true); + A.printMatrix(); std::vector val2{0.5, 0.6, 0.7, 0.8, 1.0}; std::vector x2{0,2,0,2,1}; @@ -43,13 +40,47 @@ int main(int argc, char const *argv[]) COO_Matrix B = COO_Matrix(x2,y2,val2,m,n); std::cout << "B:\n"; - B.printMatrix(true); + B.printMatrix(); - A.AXPY(2.0, &B); + A.AXPY(2.0, B); std::cout << "A + 2B:\n"; - A.printMatrix(true); - + A.printMatrix(); + + std::vector r; + std::vector c; + std::vector v; + std::tie(r,c,v) = A.getDataToCSR(); + + for (size_t i = 0; i < r.size() - 1; i++) + { + std::cout << r[i] << std::endl; + size_t rdiff = r[i+1] - r[i]; + for (size_t j = 0; j < rdiff; j++) + { + std::cout << c[j + r[i]] << ", " << v[j + r[i]] << std::endl; + } + } + std::cout << r[r.size()-1] << std::endl; + + //Basic Verification test + std::vector rtest = {0, 2, 4, 7, 8}; + std::vector ctest = {2,3,2,3,1,2,3,2}; + std::vector valtest = {1.4, 1.0, 0.4, 2.2, 0.1, 1.6, 1.2, 0.3}; + + assert(rtest.size() == r.size()); + assert(ctest.size() == c.size()); + assert(valtest.size() == v.size()); + + int failval = 0; + for (size_t i = 0; i < rtest.size(); i++) if (r[i] != rtest[i]) failval--; + for (size_t i = 0; i < ctest.size(); i++) + { + double vdiff = v[i] - valtest[i]; + if (c[i] != ctest[i] || -1e-14 > vdiff || vdiff > 1e-14) failval--; + } - return 0; + std::cout << failval << std::endl; + + return failval; } diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index 018ceaeaf..bad48ecf0 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -23,8 +23,8 @@ class PowerElectronicsModel : public ModelEvaluatorImpl // using ModelEvaluatorImpl::size_quad_; // using ModelEvaluatorImpl::size_opt_; using ModelEvaluatorImpl::nnz_; - // using ModelEvaluatorImpl::time_; - // using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::time_; + using ModelEvaluatorImpl::alpha_; using ModelEvaluatorImpl::y_; using ModelEvaluatorImpl::yp_; // using ModelEvaluatorImpl::yB_; @@ -98,6 +98,11 @@ class PowerElectronicsModel : public ModelEvaluatorImpl return 0; } + /** + * @brief Set intial y and y' of each component + * + * @return int + */ int initialize() { @@ -106,7 +111,18 @@ class PowerElectronicsModel : public ModelEvaluatorImpl { component->initialize(); } + this->distributeVectors(); + + return 0; + } + /** + * @brief Distribute y and y' to each component based of node connection graph + * + * @return int + */ + int distributeVectors() + { for(const auto& component : components_) { for(IdxT j=0; jsize(); ++j) @@ -123,6 +139,11 @@ class PowerElectronicsModel : public ModelEvaluatorImpl return 0; } + /** + * @brief Evaluate Residuals at each component then collect them + * + * @return int + */ int evaluateResidual() { for (IdxT i = 0; i < this->f_.size(); i++) @@ -130,16 +151,7 @@ class PowerElectronicsModel : public ModelEvaluatorImpl f_[i] = 0; } - // Update variables - for(const auto& component : components_) - { - for(IdxT j=0; jsize(); ++j) - { - component->y()[j] = y_[component->getNodeConnection(j)]; - component->yp()[j] = yp_[component->getNodeConnection(j)]; - } - component->evaluateResidual(); - } + this->distributeVectors(); // Update system residual vector @@ -161,6 +173,25 @@ class PowerElectronicsModel : public ModelEvaluatorImpl */ int evaluateJacobian() { + this->J_.zeroMatrix(); + this->distributeVectors(); + + //Evaluate component jacs + for(const auto& component : components_) + { + component->evaluateJacobian(); + std::vector r; + std::vector c; + std::vector v; + std::tie(r, c, v) = component->getJacobian().getEntrieCopies(); + for (IdxT i = 0; i < static_cast(r.size()); i++) + { + r[i] = component->getNodeConnection(r[i]); + c[i] = component->getNodeConnection(c[i]); + } + this->J_.AXPY(1.0, r, c, v); + } + return 0; } @@ -205,8 +236,18 @@ class PowerElectronicsModel : public ModelEvaluatorImpl return 0; } + /** + * @brief Distribute time and time scaling for each component + * + * @param t + * @param a + */ void updateTime(ScalarT t, ScalarT a) { + for(const auto& component : components_) + { + component->updateTime(t, a); + } } void addComponent(component_type* component) diff --git a/SparseMatrix/COO_Matrix.hpp b/SparseMatrix/COO_Matrix.hpp index e4b087386..5b0ece80c 100644 --- a/SparseMatrix/COO_Matrix.hpp +++ b/SparseMatrix/COO_Matrix.hpp @@ -11,10 +11,8 @@ /** * @brief Quick class to provide sparse matrices of COO type. Simplifies data movement - * @todo Add base class of sparse matrix for conversion to CSR - * @todo Switch Push back with buffer allocation for resizing - * @todo NonZero Values for preallocation - * @todo Fix warnings, mostly type casting of indexes. Should try to move to iterator somehow + * + * @todo add functionality to keep track of multiple sorted list. Faster adding of new entries and will have a threshold to sort completely. * * m x n sparse matrix */ @@ -29,176 +27,203 @@ class COO_Matrix Intdx columns_size; bool sorted; public: + //Constructors COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n); COO_Matrix(Intdx m, Intdx n); COO_Matrix(); ~COO_Matrix(); - //could replace with binary operation for both - // --- Functions which donot sort --- - void setValues(std::vector r, std::vector c, std::vector val); - void addValues(std::vector r, std::vector c, std::vector val); + + //Operations // --- Functions which call sort --- std::tuple, std::vector> getRowCopy(Intdx r); - std::tuple, std::vector, std::vector> getEntries(); + std::tuple&, std::vector&, std::vector&> getEntries(); + std::tuple, std::vector, std::vector> getEntrieCopies(); + + std::tuple, std::vector, std::vector> getDataToCSR(); // BLAS. Will sort before running - void AXPY(ScalarT alpha, COO_Matrix* a); + void setValues(std::vector r, std::vector c, std::vector v); + void AXPY(ScalarT alpha, COO_Matrix& a); + void AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v); + void SCAL(ScalarT alpha); // --- Permutation Operations --- //No sorting is actually done. Only done when nesscary void permutation(std::vector row_perm, std::vector col_perm); void permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n); + void zeroMatrix(); + + void identityMatrix(Intdx n); + //Resort values void sortSparse(); bool isSorted(); std::tuple getDimensions(); - void printMatrix(bool sort); + void printMatrix(); private: - std::vector indexEntries(std::vector r, std::vector c); - Intdx indexStartRow(Intdx r); + Intdx indexStartRow(const std::vector &rows, Intdx r); + Intdx sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci); + void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values); + }; /** - * @brief Set values of sparse matrix. Increases size if outside bounds - * - * @todo should error return if outside bounds instead? + * @brief Get copy of row values * * @tparam ScalarT * @tparam Intdx * @param r - * @param c - * @param val + * @return std::tuple, std::vector> */ template -inline void COO_Matrix::setValues(std::vector r, std::vector c, std::vector val) +inline std::tuple, std::vector> COO_Matrix::getRowCopy(Intdx r) { - std::vector indexes = this->indexEntries(r,c); + if (!this->sorted) + { + this->sortSparse(); + } + Intdx rowindex = this->indexStartRow(r); + - for (int i = 0; i < indexes.size(); i++) + if (rowindex == -1) { - if (indexes[i] == -1) - { - if (r[i] >= this->rows_size) - { - this->rows_size = r[i]; - } - if (c[i] >= this->columns_size) - { - this->columns_size = c[i]; - } - - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(val[i]); - this->sorted = false; - } - else - { - this->values[indexes[i]] = val[i]; - } + return {std::vector(),std::vector()}; } + + Intdx rsize = rowindex; + do + { + rsize++; + } while (rsize < this->values.size() && this->row_indexes[rsize] == r); + return {{this->column_indexes.begin() + rowindex, this->column_indexes.begin() + rsize},{this->values.begin() + rowindex, this->values.begin() + rsize}}; } /** - * @brief Add new values to sparse matrix. Will increase size if outside bounds - * - * @todo should error return if outside bounds instead? + * @brief Get all Entries pointers. Will sort before returnings * * @tparam ScalarT * @tparam Intdx - * @param r - * @param c - * @param val + * @return std::tuple, std::vector, std::vector> */ template -inline void COO_Matrix::addValues(std::vector r, std::vector c, std::vector val) +inline std::tuple&, std::vector&, std::vector&> COO_Matrix::getEntries() { - std::vector indexes = this->indexEntries(r,c); - - for (int i = 0; i < indexes.size(); i++) + if (!this->sorted) { - if (indexes[i] == -1) - { - if (r[i] >= this->rows_size) - { - this->rows_size = r[i]; - } - if (c[i] >= this->columns_size) - { - this->columns_size = c[i]; - } - - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(val[i]); - this->sorted = false; - } - else - { - this->values[indexes[i]] += val[i]; - } + this->sortSparse(); } - + return {this->row_indexes, this->column_indexes, this->values}; } /** - * @brief Get copy of row values + * @brief Get copies of the data. Sorted before returning * * @tparam ScalarT * @tparam Intdx - * @param r - * @return std::tuple, std::vector> + * @return std::tuple, std::vector, std::vector> */ template -inline std::tuple, std::vector> COO_Matrix::getRowCopy(Intdx r) +inline std::tuple, std::vector, std::vector> COO_Matrix::getEntrieCopies() { if (!this->sorted) { this->sortSparse(); } - Intdx rowindex = this->indexStartRow(r); - + return {this->row_indexes, this->column_indexes, this->values}; +} - if (rowindex == -1) +/** + * @brief Returns the data into CSR Format + * + * @tparam ScalarT + * @tparam Intdx + * @return std::tuple, std::vector, std::vector> + */ +template +inline std::tuple, std::vector, std::vector> COO_Matrix::getDataToCSR() +{ + if (!this->isSorted()) this->sortSparse(); + std::vector rowsizevec(this->rows_size + 1, 0); + Intdx counter = 0; + for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) { - return {std::vector(),std::vector()}; + rowsizevec[i + 1] = rowsizevec[i]; + while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) + { + rowsizevec[i+1]++; + counter++; + } } - - Intdx rsize = rowindex; - do - { - rsize++; - } while (rsize < this->values.size() && this->row_indexes[rsize] == r); - - return {{this->column_indexes.begin() + rowindex, this->column_indexes.begin() + rsize},{this->values.begin() + rowindex, this->values.begin() + rsize}}; + return {rowsizevec, this->column_indexes, this->values}; } /** - * @brief Get all Entries + * @brief Given set of vector data it will set the values into the matrix * * @tparam ScalarT * @tparam Intdx - * @return std::tuple, std::vector, std::vector> + * @param r + * @param c + * @param v */ template -inline std::tuple, std::vector, std::vector> COO_Matrix::getEntries() +inline void COO_Matrix::setValues(std::vector r, std::vector c, std::vector v) { - if (!this->sorted) + //sort input + this->sortSparseCOO(r, c, v); + + + //Duplicated with AXPY. Could replace with function depdent on lambda expression + Intdx aiter = 0; + //iterate for all current values in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) { - this->sortSparse(); + //pushback values when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + { + this->row_indexes.push_back(r[aiter]); + this->column_indexes.push_back(c[aiter]); + this->values.push_back(v[aiter]); + aiter++; + } + if (aiter >= static_cast(r.size())) break; + + + if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + { + this->values[i] = v[aiter]; + aiter++; + } } - return {this->row_indexes, this->column_indexes, this->values}; + //push back rest that was not found sorted + for (Intdx i = aiter; i < static_cast(r.size()); i++) + { + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(v[i]); + } + + this->sorted = false; + } +/** + * @brief BLAS AXPY operation on another COO matrix. Will sort both matrices before acting + * + * @tparam ScalarT + * @tparam Intdx + * @param alpha + * @param a + */ template -inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrix *a) +inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrix& a) { if (alpha == 0) return; @@ -206,18 +231,17 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_MatrixsortSparse(); } - if (!a->isSorted()) + if (!a.isSorted()) { - a->sortSparse(); + a.sortSparse(); } - std::vector val; - std::vector r; - std::vector c; Intdx m = 0; Intdx n = 0; - std::tie(r,c,val) = a->getEntries(); - std::tie(m,n) = a->getDimensions(); + std::tuple&, std::vector&, std::vector&> tpm = a.getEntries(); + const auto& [r, c, val] = tpm; + std::tie(m,n) = a.getDimensions(); + //Increase size as nesscary this->rows_size = this->rows_size > m ? this->rows_size : m; this->columns_size = this->columns_size > n ? this->columns_size : n; @@ -233,7 +257,7 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrixvalues.push_back(alpha * val[aiter]); aiter++; } - if (aiter >= r.size()) break; + if (aiter >= static_cast(r.size())) break; if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) @@ -253,6 +277,74 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrixsorted = false; } +/** + * @brief AXPY on 3list. + * + * @tparam ScalarT + * @tparam Intdx + * @param alpha + * @param r + * @param c + * @param v + */ +template +inline void COO_Matrix::AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v) +{ + if (alpha == 0) return; + + if (!this->sorted) + { + this->sortSparse(); + } + + //sort input + this->sortSparseCOO(r, c, v); + + Intdx aiter = 0; + //iterate for all current values in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + { + //pushback values when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + { + this->row_indexes.push_back(r[aiter]); + this->column_indexes.push_back(c[aiter]); + this->values.push_back(alpha * v[aiter]); + aiter++; + } + if (aiter >= static_cast(r.size())) break; + + + if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + { + this->values[i] += alpha * v[aiter]; + aiter++; + } + } + //push back rest that was not found sorted + for (Intdx i = aiter; i < static_cast(r.size()); i++) + { + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(alpha * v[i]); + } + + this->sorted = false; +} + +/** + * @brief Scale all values + * + * @tparam ScalarT + * @tparam Intdx + * @param alpha + */ +template +inline void COO_Matrix::SCAL(ScalarT alpha) +{ + for (auto i = this->values.begin(); i < this->values.end(); i++) *i *= alpha; +} + /** * @brief Permutate the matrix to a different one. Only changes the coordinates * @@ -273,6 +365,7 @@ inline void COO_Matrix::permutation(std::vector row_perm, this->column_indexes[i] = col_perm[this->column_indexes[i]]; } this->sorted = false; + //cycle sorting maybe useful since permutations are already known } /** @@ -311,48 +404,48 @@ inline void COO_Matrix::permutationSizeMap(std::vector ro } /** - * @brief Restructure the sparse matrix for faster accesses and modifications + * @brief Turn matrix into the zero matrix. Does not actual delete memory * * @tparam ScalarT * @tparam Intdx */ template -inline void COO_Matrix::sortSparse() +inline void COO_Matrix::zeroMatrix() { - //index based sort code - // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted-vector - - - //cannot call sort since two arrays are used instead - std::vector ordervec(this->row_indexes.size()); - std::size_t n(0); - std::generate(std::begin(ordervec), std::end(ordervec), [&]{ return n++; }); - - std::sort( std::begin(ordervec), - std::end(ordervec), - [&](int i1, int i2) { return this->row_indexes[i1] < this->row_indexes[i2] || - (this->row_indexes[i1] == this->row_indexes[i2] && this->column_indexes[i1] < this->column_indexes[i2]); } ); - + //resize doesn't effect capacity if smaller + this->column_indexes.resize(0); + this->row_indexes.resize(0); + this->values.resize(0); + this->sorted = true; +} - //reorder based of index-sorting. Only swap no extra memory - // https://stackoverflow.com/a/22183350 - for (size_t i = 0; i < ordervec.size(); i++) +template +inline void COO_Matrix::identityMatrix(Intdx n) +{ + //Reset Matrix + this->zeroMatrix(); + for (Intdx i = 0; i < n; i++) { - //permutation swap - while (ordervec[i] != ordervec[ordervec[i]]) - { - std::swap(this->row_indexes[ordervec[i]], this->row_indexes[ordervec[ordervec[i]]]); - std::swap(this->column_indexes[ordervec[i]], this->column_indexes[ordervec[ordervec[i]]]); - std::swap(this->values[ordervec[i]], this->values[ordervec[ordervec[i]]]); - - //swap orderings - std::swap(ordervec[i], ordervec[ordervec[i]]); - } - + this->column_indexes[i] = i; + this->row_indexes[i] = i; + this->values[i] = 1.0; } this->sorted = true; } +/** + * @brief Restructure the sparse matrix for faster accesses and modifications + * + * @tparam ScalarT + * @tparam Intdx + */ +template +inline void COO_Matrix::sortSparse() +{ + this->sortSparseCOO(this->row_indexes, this->column_indexes, this->values); + this->sorted = true; +} + template inline bool COO_Matrix::isSorted() { @@ -365,10 +458,16 @@ inline std::tuple COO_Matrix::getDimensions() return std::tuple(this->rows_size, this->columns_size); } +/** + * @brief Print matrix that is sorted + * + * @tparam ScalarT + * @tparam Intdx + */ template -inline void COO_Matrix::printMatrix(bool sort) +inline void COO_Matrix::printMatrix() { - if (sort == true && this->sorted == false) + if (this->sorted == false) { this->sortSparse(); } @@ -384,95 +483,143 @@ inline void COO_Matrix::printMatrix(bool sort) } /** - * @brief Given vector indexes return the entries + * @brief Find the lowest row cordinate from set of provided cordinates * + * Assumes rows and columns are sorted * @tparam ScalarT * @tparam Intdx * @param r - * @param c - * @return std::vector + * @return Intdx */ template -inline std::vector COO_Matrix::indexEntries(std::vector r, std::vector c) +inline Intdx COO_Matrix::indexStartRow(const std::vector &rows, Intdx r) { - assert(r.size() == c.size()); - std::vector valsnew(r.size(), -1); - - //cannot assume input is sorted so linear - Intdx aiter = 0; - //should fix this - for (Intdx i = 0; i < this->row_indexes.size(); i++) + //Specialized Binary Search for Lowest Row + Intdx i1 = 0; + Intdx i2 = rows->size()-1; + Intdx m_smallest = -1; + Intdx m = -1; + while (i1 <= i2) { - while(r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i])) + m = (i2 + i1) / 2; + //rows + if (rows[m] < r) { - valsnew.push_back(-1); - aiter++; + i1 = m + 1; } - - if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + else if (r < rows[m]) { - valsnew.push_back(i); - aiter++; + i2 = m - 1; + } + else + { + if (i1 == i2) + { + return m_smallest; + } + + //Keep track of smallest cordinate + m_smallest = m; + i2 = m - 1; } - } - return valsnew; - + return m_smallest; } /** - * @brief Given row index get start. If no start returns -1 + * @brief Basic binary search * * @tparam ScalarT * @tparam Intdx - * @param r + * @param rows + * @param columns + * @param ri + * @param ci * @return Intdx */ template -inline Intdx COO_Matrix::indexStartRow(Intdx r) +inline Intdx COO_Matrix::sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci) { - if (this->sorted) + assert(rows.size() == columns.size()); + //basic binary search + Intdx i1 = 0; + Intdx i2 = rows.size()-1; + Intdx m = 0; + while (i1 <= i2) { - //basic binary search - Intdx i1 = 0; - Intdx i2 = this->row_indexes.size()-1; - Intdx m = 0; - while (i1 <= i2) + m = (i2 + i1) / 2; + //rows + if (rows[m] < ri) + { + i1 = m + 1; + } + else if (ri < rows[m]) + { + i2 = m - 1; + } + else { - m = (i2 + i1) / 2; - //rows - if (this->row_indexes[m] < r) + if (columns[m] < ci) { i1 = m + 1; } - else if (r < this->row_indexes[m]) + else if (ci < columns[m]) { i2 = m - 1; } - else - { - break; - } + break; } - //drop to first index - while (this->row_indexes[m] == r) - { - m--; - } - return m; - } - else + + return m; +} + +/** + * @brief Sort a disoreded set of values. Assume nothing on order. + * + * @todo simple setup. Should add better sorting since list are pre-sorted + * + * @tparam ScalarT + * @tparam Intdx + * @param rows + * @param columns + * @param values + */ +template +inline void COO_Matrix::sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values) +{ + + //index based sort code + // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted-vector + //cannot call sort since two arrays are used instead + std::vector ordervec(rows.size()); + std::size_t n(0); + std::generate(std::begin(ordervec), std::end(ordervec), [&]{ return n++; }); + + //Sort by row first then column. + std::sort( std::begin(ordervec), + std::end(ordervec), + [&](int i1, int i2) { return (rows[i1] < rows[i2]) || + (rows[i1] == rows[i2] && columns[i1] < columns[i2]); } ); + + + //reorder based of index-sorting. Only swap cost no extra memory. + // @todo see if extra memory creation is fine + // https://stackoverflow.com/a/22183350 + for (size_t i = 0; i < ordervec.size(); i++) { - for (int i = 0; i < this->row_indexes.size(); i++) + //permutation swap + while (ordervec[i] != ordervec[ordervec[i]]) { - if (this->row_indexes[i] == r) - { - return i; - } + std::swap(rows[ordervec[i]], rows[ordervec[ordervec[i]]]); + std::swap(columns[ordervec[i]], columns[ordervec[ordervec[i]]]); + std::swap(values[ordervec[i]], values[ordervec[ordervec[i]]]); + + //swap orderings + std::swap(ordervec[i], ordervec[ordervec[i]]); } + } - return -1; } template From 3f74458d8bada3f36eee2a0363c493eab2223d92 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Sun, 10 Dec 2023 22:28:24 -0500 Subject: [PATCH 05/44] Jacobian Assembly, IDA + KLU Cmake, RL Circuit + Cmake configurations for Sundials and SuiteSparse + Jacobian Assembly for components + Working RL Circuit example utilizing assembly techniques --- CMake/FindSuiteSparse.cmake | 5 +- CMakeLists.txt | 4 +- .../CircuitComponent.hpp | 2 + .../Inductor/Inductor.cpp | 12 +- .../Resistor/Resistor.cpp | 9 +- .../VoltageSource/VoltageSource.cpp | 8 +- Examples/RLCircuit/CMakeLists.txt | 3 +- Examples/RLCircuit/RLCircuit.cpp | 113 +++++++++++++----- ModelEvaluator.hpp | 16 ++- ModelEvaluatorImpl.hpp | 6 +- PowerElectronicsModel.hpp | 95 ++++++++++++--- Solver/Dynamic/CMakeLists.txt | 5 + Solver/Dynamic/Ida.cpp | 90 +++++++++++--- Solver/Dynamic/Ida.hpp | 7 +- SparseMatrix/COO_Matrix.hpp | 74 +++++++++++- SystemModel.hpp | 11 ++ 16 files changed, 378 insertions(+), 82 deletions(-) diff --git a/CMake/FindSuiteSparse.cmake b/CMake/FindSuiteSparse.cmake index 2d73feb76..5a1026935 100644 --- a/CMake/FindSuiteSparse.cmake +++ b/CMake/FindSuiteSparse.cmake @@ -69,11 +69,11 @@ Author(s): set(SUITESPARSE_MODULES amd colamd - klu) + klu + suitesparseconfig) find_library(SUITESPARSE_LIBRARY NAMES - suitesparseconfig ${SUITESPARSE_MODULES} PATHS ${SUITESPARSE_DIR} $ENV{SUITESPARSE_DIR} ${SUITESPARSE_ROOT_DIR} @@ -97,6 +97,7 @@ find_path(SUITESPARSE_INCLUDE_DIR amd.h colamd.h klu.h + SuiteSparse_config.h PATHS ${SUITESPARSE_DIR} $ENV{SUITESPARSE_DIR} ${SUITESPARSE_ROOT_DIR} ${SUITESPARSE_LIBRARY_DIR}/.. PATH_SUFFIXES diff --git a/CMakeLists.txt b/CMakeLists.txt index ef6cbcf57..badea53a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,7 +81,7 @@ option(GRIDKIT_ENABLE_IPOPT "Enable Ipopt support" ON) option(GRIDKIT_ENABLE_SUNDIALS "Enable SUNDIALS support" ON) # Enable KLU -option(GRIDKIT_ENABLE_SUNDIALS_SPARSE "Enable SUNDIALS sparse linear solvers" OFF) +option(GRIDKIT_ENABLE_SUNDIALS_SPARSE "Enable SUNDIALS sparse linear solvers" ON) set(CMAKE_MACOSX_RPATH 1) @@ -110,7 +110,7 @@ endif("${isSystemDir}" STREQUAL "-1") # TODO: Probably beter to set a debug interface target -set(CMAKE_CXX_FLAGS_DEBUG "-Wall -O0 -g") +set(CMAKE_CXX_FLAGS_DEBUG "-Wall -O0 -g -DDEBUG") set(CMAKE_CXX_STANDARD 17) diff --git a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp index 9e1052e43..fe2efdf96 100644 --- a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp +++ b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp @@ -27,6 +27,8 @@ namespace ModelLib this->time_ = t; this->alpha_ = a; } + + bool hasJacobian() { return true;} size_t getExternSize() { diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index b0b19e63b..a24b7a8e9 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -70,26 +70,30 @@ int Inductor::tagDifferentiable() template int Inductor::evaluateResidual() { + //input this->f_[0] = this->y_[2]; + //output this->f_[1] = -this->y_[2]; - this->f_[2] = - this->L_ * this->yp_[2] + this->y_[0] - this->y_[1] ; + //internal + this->f_[2] = this->L_ * this->yp_[2] + this->y_[0] - this->y_[1] ; return 0; } template int Inductor::evaluateJacobian() { - + this->J_.zeroMatrix(); + //Create dF/dy std::vector rcord{0,1,2,2}; std::vector ccord{2,2,0,1}; std::vector vals{1.0, -1.0, 1.0, -1.0}; this->J_.setValues(rcord, ccord, vals); - //Create -dF/dy' + //Create dF/dy' std::vector rcordder{2}; std::vector ccordder{2}; - std::vector valsder{-this->L_}; + std::vector valsder{this->L_}; COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp index 7536f2274..45d9a34f3 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp @@ -69,9 +69,10 @@ int Resistor::tagDifferentiable() template int Resistor::evaluateResidual() { - - this->f_[0] = (this->y_[1] - this->y_[0])/this->R_ ; - this->f_[1] = (this->y_[0] - this->y_[1])/this->R_ ; + //input + this->f_[0] = (this->y_[0] - this->y_[1])/this->R_ ; + //ouput + this->f_[1] = (this->y_[1] - this->y_[0])/this->R_ ; return 0; } @@ -83,7 +84,7 @@ int Resistor::evaluateJacobian() //does compiler make constant??? std::vector rcord{0,0,1,1}; std::vector ccord{0,1,0,1}; - std::vector vals{-1.0 / this->R_, 1.0 / this->R_, 1.0 / this->R_, -1.0 / this->R_}; + std::vector vals{1.0 / this->R_, -1.0 / this->R_, -1.0 / this->R_, 1.0 / this->R_}; this->J_.setValues(rcord, ccord, vals); return 0; diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp index b7c18bd6f..c7cb09798 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -71,20 +71,22 @@ int VoltageSource::evaluateResidual() { //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors // for easier development + //input this->f_[0] = this->y_[2]; + //ouput this->f_[1] = -this->y_[2]; - this->f_[2] = this->y_[1] - this->y_[0] - this->V_; + //internal + this->f_[2] = -this->y_[1] + this->y_[0] + this->V_; return 0; } template int VoltageSource::evaluateJacobian() { - //Create dF/dy std::vector rcord{0,1,2,2}; std::vector ccord{2,2,0,1}; - std::vector vals{1.0, -1.0, -1.0, 1.0}; + std::vector vals{1.0, -1.0, 1.0, -1.0}; this->J_.setValues(rcord, ccord, vals); return 0; diff --git a/Examples/RLCircuit/CMakeLists.txt b/Examples/RLCircuit/CMakeLists.txt index 5069566bf..476eb5e95 100644 --- a/Examples/RLCircuit/CMakeLists.txt +++ b/Examples/RLCircuit/CMakeLists.txt @@ -6,7 +6,8 @@ add_executable(rlcircuit RLCircuit.cpp) target_link_libraries(rlcircuit GRIDKIT::powerelec_capacitor GRIDKIT::powerelec_inductor GRIDKIT::powerelec_resistor - GRIDKIT::powerelec_voltagesource) + GRIDKIT::powerelec_voltagesource + GRIDKIT::solvers_dyn) add_test(NAME RLCircuit COMMAND $) install(TARGETS rlcircuit RUNTIME DESTINATION bin) diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp index 124b50bc0..c71eef06d 100644 --- a/Examples/RLCircuit/RLCircuit.cpp +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -12,68 +12,89 @@ #include #include +#include +#include int main(int argc, char const *argv[]) { - + double abstol = 1e-8; + double reltol = 1e-8; + bool usejac = true; + //TODO:setup as named parameters //Create circuit model - ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(); + ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac); size_t idoff = 0; + //RL circuit parameters + double rinit = 1.0; + double linit = 1.0; + double vinit = 1.0; + + //inductor - ModelLib::Inductor* induct = new ModelLib::Inductor(idoff,0.1); + ModelLib::Inductor* induct = new ModelLib::Inductor(idoff,linit); //Form index to node uid realations - induct->setExternalConnectionNodes(0,2); - induct->setExternalConnectionNodes(2,1); - induct->setExternalConnectionNodes(1,0); + // input + induct->setExternalConnectionNodes(0,1); + //output + induct->setExternalConnectionNodes(1,-1); + //internal + induct->setExternalConnectionNodes(2,2); + //add component sysmodel->addComponent(induct); //resistor idoff++; - ModelLib::Resistor* resis = new ModelLib::Resistor(idoff, 1.0); + ModelLib::Resistor* resis = new ModelLib::Resistor(idoff, rinit); //Form index to node uid realations - resis->setExternalConnectionNodes(0,3); - resis->setExternalConnectionNodes(1,2); + //input + resis->setExternalConnectionNodes(0,0); + //output + resis->setExternalConnectionNodes(1,1); + //add sysmodel->addComponent(resis); //voltage source idoff++; - ModelLib::VoltageSource* vsource = new ModelLib::VoltageSource(idoff, 0.1); + ModelLib::VoltageSource* vsource = new ModelLib::VoltageSource(idoff, vinit); //Form index to node uid realations - vsource->setExternalConnectionNodes(0,0); - vsource->setExternalConnectionNodes(2,4); - vsource->setExternalConnectionNodes(1,3); + //input + vsource->setExternalConnectionNodes(0,-1); + //output + vsource->setExternalConnectionNodes(1,0); + //internal + vsource->setExternalConnectionNodes(2,3); + + sysmodel->addComponent(vsource); - - //Allocate with graph - sysmodel->allocate(5); + sysmodel->allocate(4); std::cout << sysmodel->y().size() << std::endl; + //Grounding for IDA. If no grounding then circuit is \mu > 1 + //v_0 (grounded) //Create Intial points - sysmodel->y()[0] = 1.0; - sysmodel->y()[1] = 1.0; - sysmodel->y()[2] = 1.0; - sysmodel->y()[3] = 1.0; - sysmodel->y()[4] = 1.0; - - sysmodel->yp()[0] = 1.0; - sysmodel->yp()[1] = 1.0; - sysmodel->yp()[2] = 1.0; - sysmodel->yp()[3] = 1.0; - sysmodel->yp()[4] = 1.0; + sysmodel->y()[0] = vinit; //v_1 + sysmodel->y()[1] = vinit; // v_2 + sysmodel->y()[2] = 0.0; // i_L + sysmodel->y()[3] = 0.0; // i_s + + sysmodel->yp()[0] = 0.0; // v'_1 + sysmodel->yp()[1] = 0.0; // v'_2 + sysmodel->yp()[2] = -vinit / linit; // i'_s + sysmodel->yp()[3] = -vinit / linit; // i'_L + sysmodel->initialize(); - sysmodel->evaluateResidual(); - std::cout << "Output: {"; + std::cout << "Verify Intial Resisdual is Zero: {"; for (double i : sysmodel->getResidual()) { std::cout << i << ", "; @@ -83,10 +104,44 @@ int main(int argc, char const *argv[]) sysmodel->updateTime(0.0, 1.0); sysmodel->evaluateJacobian(); + std::cout << "Intial Jacobian with alpha = 1:\n"; sysmodel->getJacobian().printMatrix(); + // Create numerical integrator and configure it for the generator model + AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); + + double t_init = 0.0; + double t_final = 1.0; + + // setup simulation + idas->configureSimulation(); + idas->getDefaultInitialCondition(); + idas->initializeSimulation(t_init); + idas->runSimulation(t_final); + + std::vector& yfinial = sysmodel->y(); + + std::cout << "Final Vector y\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << yfinial[i] << "\n"; + } + + std::vector yexact(4); + + //analytical solution to the circuit + yexact[0] = vinit; + yexact[2] = (-vinit / rinit) * (exp((rinit / linit) * t_final) - 1.0); + yexact[3] = yexact[2]; + yexact[1] = vinit - rinit * yexact[2]; + + std::cout << "Element-wise Relative error at t=" << t_final << "\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << abs((yfinial[i] - yexact[i]) / yexact[i]) << "\n"; + } return 0; } diff --git a/ModelEvaluator.hpp b/ModelEvaluator.hpp index 5eda481de..50c5e8b77 100644 --- a/ModelEvaluator.hpp +++ b/ModelEvaluator.hpp @@ -62,6 +62,7 @@ #include #include +#include namespace ModelLib { @@ -88,11 +89,20 @@ namespace ModelLib virtual int initializeAdjoint() = 0; virtual int evaluateAdjointResidual() = 0; - //virtual int evaluateAdjointJacobian() = 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 size_quad() = 0; virtual IdxT size_opt() = 0; virtual void updateTime(real_type t, real_type a) = 0; @@ -125,6 +135,10 @@ namespace ModelLib 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; diff --git a/ModelEvaluatorImpl.hpp b/ModelEvaluatorImpl.hpp index ade61feff..928d26f30 100644 --- a/ModelEvaluatorImpl.hpp +++ b/ModelEvaluatorImpl.hpp @@ -62,7 +62,6 @@ #include #include -#include namespace ModelLib { @@ -112,6 +111,11 @@ namespace ModelLib return nnz_; } + virtual bool hasJacobian() + { + return false; + } + virtual IdxT size_quad() { return size_quad_; diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index bad48ecf0..47efcc7f7 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -43,13 +43,27 @@ class PowerElectronicsModel : public ModelEvaluatorImpl public: /** - * @brief Constructor for the system model + * @brief Default constructor for the system model */ PowerElectronicsModel() : ModelEvaluatorImpl(0, 0, 0) { - // Set system model tolerances - rtol_ = 1e-5; - atol_ = 1e-5; + // Set system model tolerances as default + rtol_ = 1e-4; + atol_ = 1e-4; + // By default use jacobian + usejac_ = true; + } + + /** + * @brief Constructor for the system model + */ + PowerElectronicsModel(double rt, double at, bool ju) : ModelEvaluatorImpl(0, 0, 0) + { + // Set system model tolerances from input + rtol_ = rt; + atol_ = at; + // Can choose not to use jacobain + usejac_ = ju; } /** @@ -73,6 +87,28 @@ class PowerElectronicsModel : public ModelEvaluatorImpl return 1; } + /** + * @brief Will check if each component has jacobian avalible. If one doesn't then jacobain is false. + * + * + * @return true + * @return false + */ + bool hasJacobian() + { + if (!this->usejac_) return false; + + for(const auto& component : components_) + { + if (!component->hasJacobian()) + { + return false; + } + + } + return true; + } + /** * @brief Allocate the vector data with size amount * @todo Add capability to go through component model connection to get the size of the actual vector @@ -127,8 +163,16 @@ class PowerElectronicsModel : public ModelEvaluatorImpl { for(IdxT j=0; jsize(); ++j) { - component->y()[j] = y_[component->getNodeConnection(j)]; - component->yp()[j] = yp_[component->getNodeConnection(j)]; + if(component->getNodeConnection(j) != -1) + { + component->y()[j] = y_[component->getNodeConnection(j)]; + component->yp()[j] = yp_[component->getNodeConnection(j)]; + } + else + { + component->y()[j] = 0.0; + component->yp()[j] = 0.0; + } } } return 0; @@ -148,7 +192,7 @@ class PowerElectronicsModel : public ModelEvaluatorImpl { for (IdxT i = 0; i < this->f_.size(); i++) { - f_[i] = 0; + f_[i] = 0.0; } this->distributeVectors(); @@ -157,9 +201,16 @@ class PowerElectronicsModel : public ModelEvaluatorImpl for(const auto& component : components_) { + //TODO:check return type + component->evaluateResidual(); for(IdxT j=0; jsize(); ++j) { - f_[component->getNodeConnection(j)] += component->getResidual()[j]; + //@todo should do a different grounding check + if (component->getNodeConnection(j) != -1) + { + f_[component->getNodeConnection(j)] += component->getResidual()[j]; + } + } } @@ -180,16 +231,27 @@ class PowerElectronicsModel : public ModelEvaluatorImpl for(const auto& component : components_) { component->evaluateJacobian(); - std::vector r; - std::vector c; - std::vector v; - std::tie(r, c, v) = component->getJacobian().getEntrieCopies(); + + //get references to local jacobain + std::tuple&, std::vector&, std::vector&> tpm = component->getJacobian().getEntries(); + const auto& [r, c, v] = tpm; + + //Create copies of data to handle groundings + std::vector rgr; + std::vector cgr; + std::vector vgr; for (IdxT i = 0; i < static_cast(r.size()); i++) { - r[i] = component->getNodeConnection(r[i]); - c[i] = component->getNodeConnection(c[i]); + if (component->getNodeConnection(r[i]) != -1 && component->getNodeConnection(c[i]) != -1) + { + rgr.push_back(component->getNodeConnection(r[i])); + cgr.push_back(component->getNodeConnection(c[i])); + vgr.push_back(v[i]); + } } - this->J_.AXPY(1.0, r, c, v); + + //AXPY to Global Jacobian + this->J_.AXPY(1.0, rgr, cgr, vgr); } return 0; @@ -248,6 +310,8 @@ class PowerElectronicsModel : public ModelEvaluatorImpl { component->updateTime(t, a); } + this->time_ = t; + this->alpha_ = a; } void addComponent(component_type* component) @@ -257,6 +321,7 @@ class PowerElectronicsModel : public ModelEvaluatorImpl private: std::vector components_; + bool usejac_; }; // class PowerElectronicsModel diff --git a/Solver/Dynamic/CMakeLists.txt b/Solver/Dynamic/CMakeLists.txt index 759829967..85c7ea920 100644 --- a/Solver/Dynamic/CMakeLists.txt +++ b/Solver/Dynamic/CMakeLists.txt @@ -66,6 +66,11 @@ gridkit_add_library(solvers_dyn LINK_LIBRARIES PUBLIC SUNDIALS::nvecserial PUBLIC SUNDIALS::idas + PUBLIC SUNDIALS::sunlinsolklu + PUBLIC suitesparseconfig + PUBLIC klu + PUBLIC amd + PUBLIC colamd OUTPUT_NAME gridkit_solvers_dyn) diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index c71a8fd07..5137119f1 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -61,10 +61,13 @@ #include #include -// #include #include /* access to IDADls interface */ #include +//Sundials Sparse KLU +#include +#include + #include "ModelEvaluator.hpp" #include "Ida.hpp" @@ -103,6 +106,9 @@ namespace Sundials yp_ = N_VClone(yy_); checkAllocation((void*) yp_, "N_VClone"); + //get intial conditions + this->getDefaultInitialCondition(); + // Create vectors to store restart initial condition yy0_ = N_VClone(yy_); checkAllocation((void*) yy0_, "N_VClone"); @@ -144,14 +150,7 @@ namespace Sundials } // Set up linear solver - JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); - - linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); - checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); - - retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "IDASetLinearSolver"); + this->configureLinearSolver(); return retval; } @@ -160,16 +159,32 @@ namespace Sundials int Ida::configureLinearSolver() { int retval = 0; + if (model_->hasJacobian()) + { + JacobianMat_ = SUNSparseMatrix(model_->size(), model_->size(), model_->size() * model_->size(), CSR_MAT, context_); + checkAllocation((void*) JacobianMat_, "SUNSparseMatrix"); - // Set up linear solver - JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); + linearSolver_ = SUNLinSol_KLU(yy_, JacobianMat_, context_); + checkAllocation((void*) linearSolver_, "SUNLinSol_KLU"); - linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); - checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); + retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "IDASetLinearSolver"); - retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "IDASetLinearSolver"); + retval = IDASetJacFn(solver_, this->Jac); + checkOutput(retval, "IDASetJacFn"); + } + else + { + JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); + + linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); + checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); + + retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "IDASetLinearSolver"); + + } return retval; } @@ -525,8 +540,49 @@ namespace Sundials return 0; } + template + int Ida::Jac(realtype t, realtype cj, N_Vector yy, N_Vector yp, N_Vector resvec, SUNMatrix J, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) + { - template + ModelLib::ModelEvaluator* model = static_cast*>(user_data); + + + model->updateTime(t, cj); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); + + model->evaluateJacobian(); + COO_Matrix Jac = model->getJacobian(); + + //Get reference to the jacobian entries + std::tuple&, std::vector&, std::vector&> tpm = Jac.getEntries(); + const auto [r, c, val] = tpm; + + //get the CSR row pointers from COO matrix + std::vector csrrowdata = Jac.getCSRRowData(); + + SUNMatZero(J); + + //Set row pointers + sunindextype *rowptrs = SUNSparseMatrix_IndexPointers(J); + for (unsigned int i = 0; i < csrrowdata.size() ; i++) + { + rowptrs[i] = csrrowdata[i]; + } + + sunindextype *colvals = SUNSparseMatrix_IndexValues(J); + realtype *data = SUNSparseMatrix_Data(J); + //Copy data from model jac to sundials + for (unsigned int i = 0; i < c.size(); i++ ) + { + colvals[i] = c[i]; + data[i] = val[i]; + } + + return 0; + } + + template int Ida::Integrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector rhsQ, void *user_data) { ModelLib::ModelEvaluator* model = static_cast*>(user_data); diff --git a/Solver/Dynamic/Ida.hpp b/Solver/Dynamic/Ida.hpp index 3fa3368c9..a4cea9561 100644 --- a/Solver/Dynamic/Ida.hpp +++ b/Solver/Dynamic/Ida.hpp @@ -65,7 +65,7 @@ #include #include #include /* access to sparse SUNMatrix */ -// #include /* access to KLU linear solver */ +#include /* access to KLU linear solver */ #include /* access to dense linear solver */ #include "ModelEvaluator.hpp" @@ -165,6 +165,11 @@ namespace AnalysisManager static int Residual(realtype t, N_Vector yy, N_Vector yp, N_Vector rr, void *user_data); + + static int Jac(realtype t, realtype cj, + N_Vector yy, N_Vector yp, N_Vector resvec, + SUNMatrix J, void *user_data, + N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); static int Integrand(realtype t, N_Vector yy, N_Vector yp, diff --git a/SparseMatrix/COO_Matrix.hpp b/SparseMatrix/COO_Matrix.hpp index 5b0ece80c..c256e015c 100644 --- a/SparseMatrix/COO_Matrix.hpp +++ b/SparseMatrix/COO_Matrix.hpp @@ -40,8 +40,10 @@ class COO_Matrix std::tuple, std::vector> getRowCopy(Intdx r); std::tuple&, std::vector&, std::vector&> getEntries(); std::tuple, std::vector, std::vector> getEntrieCopies(); + std::tuple, std::vector, std::vector> getEntrieCopiesSubMatrix(std::vector submap); std::tuple, std::vector, std::vector> getDataToCSR(); + std::vector getCSRRowData(); // BLAS. Will sort before running void setValues(std::vector r, std::vector c, std::vector v); @@ -61,15 +63,19 @@ class COO_Matrix //Resort values void sortSparse(); bool isSorted(); + Intdx nnz(); std::tuple getDimensions(); void printMatrix(); + + static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values); + private: Intdx indexStartRow(const std::vector &rows, Intdx r); Intdx sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci); - void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values); + bool checkIncreaseSize(Intdx r, Intdx c); }; @@ -164,6 +170,35 @@ inline std::tuple, std::vector, std::vector> return {rowsizevec, this->column_indexes, this->values}; } +/** + * @brief Only creates the row data + * + * @todo swap this with having the matrix store the data and updates. This can then be passed by reference + * + * @todo fails, fix + * + * @tparam ScalarT + * @tparam Intdx + * @return std::vector + */ +template +inline std::vector COO_Matrix::getCSRRowData() +{ + if (!this->isSorted()) this->sortSparse(); + std::vector rowsizevec(this->rows_size + 1, 0); + Intdx counter = 0; + for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) + { + rowsizevec[i + 1] = rowsizevec[i]; + while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) + { + rowsizevec[i+1]++; + counter++; + } + } + return rowsizevec; +} + /** * @brief Given set of vector data it will set the values into the matrix * @@ -191,6 +226,7 @@ inline void COO_Matrix::setValues(std::vector r, std::vec this->row_indexes.push_back(r[aiter]); this->column_indexes.push_back(c[aiter]); this->values.push_back(v[aiter]); + this->checkIncreaseSize(r[aiter], c[aiter]); aiter++; } if (aiter >= static_cast(r.size())) break; @@ -208,6 +244,8 @@ inline void COO_Matrix::setValues(std::vector r, std::vec this->row_indexes.push_back(r[i]); this->column_indexes.push_back(c[i]); this->values.push_back(v[i]); + + this->checkIncreaseSize(r[i], c[i]); } this->sorted = false; @@ -256,6 +294,8 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrixcolumn_indexes.push_back(c[aiter]); this->values.push_back(alpha * val[aiter]); aiter++; + + this->checkIncreaseSize(r[aiter], c[aiter]); } if (aiter >= static_cast(r.size())) break; @@ -272,6 +312,8 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrixrow_indexes.push_back(r[i]); this->column_indexes.push_back(c[i]); this->values.push_back(alpha * val[i]); + + this->checkIncreaseSize(r[i], c[i]); } this->sorted = false; @@ -310,6 +352,8 @@ inline void COO_Matrix::AXPY(ScalarT alpha, std::vector r this->row_indexes.push_back(r[aiter]); this->column_indexes.push_back(c[aiter]); this->values.push_back(alpha * v[aiter]); + + this->checkIncreaseSize(r[aiter], c[aiter]); aiter++; } if (aiter >= static_cast(r.size())) break; @@ -327,6 +371,8 @@ inline void COO_Matrix::AXPY(ScalarT alpha, std::vector r this->row_indexes.push_back(r[i]); this->column_indexes.push_back(c[i]); this->values.push_back(alpha * v[i]); + + this->checkIncreaseSize(r[i], c[i]); } this->sorted = false; @@ -452,6 +498,12 @@ inline bool COO_Matrix::isSorted() return this->sorted; } +template +inline Intdx COO_Matrix::nnz() +{ + return static_cast(this->values.size); +} + template inline std::tuple COO_Matrix::getDimensions() { @@ -574,10 +626,28 @@ inline Intdx COO_Matrix::sparseCordBinarySearch(const std::vecto return m; } +template +inline bool COO_Matrix::checkIncreaseSize(Intdx r, Intdx c) +{ + bool changed = false; + if (r + 1 > this->rows_size) + { + this->rows_size = r + 1; + changed = true; + } + if (c + 1 > this->columns_size) + { + this->columns_size = c + 1; + changed = true; + } + + return changed; +} + /** * @brief Sort a disoreded set of values. Assume nothing on order. * - * @todo simple setup. Should add better sorting since list are pre-sorted + * @todo simple setup. Should add stable sorting since list are pre-sorted * * @tparam ScalarT * @tparam Intdx diff --git a/SystemModel.hpp b/SystemModel.hpp index 34c7ff120..77bbdd20b 100644 --- a/SystemModel.hpp +++ b/SystemModel.hpp @@ -183,6 +183,17 @@ class SystemModel : public ModelEvaluatorImpl return 0; } + /** + * @brief Assume that jacobian is not avalible + * + * @return true + * @return false + */ + bool hasJacobian() + { + return false; + } + /** * @brief Initialize buses first, then all the other components. * From a42761cfedfebfb2632bc1c0bea18b55c2241a1b Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Tue, 30 Jan 2024 16:19:33 -0500 Subject: [PATCH 06/44] Added the Transmission Line Component --- .../PowerElectronicsComponents/CMakeLists.txt | 3 +- .../TransmissionLine/CMakeLists.txt | 8 + .../TransmissionLine/TransmissionLine.cpp | 201 ++++++++++++++++++ .../TransmissionLine/TransmissionLine.hpp | 71 +++++++ Examples/RLCircuit/RLCircuit.cpp | 1 - 5 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 ComponentLib/PowerElectronicsComponents/TransmissionLine/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp diff --git a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt index 9d6ad8be1..8b96aaa66 100644 --- a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt +++ b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt @@ -7,4 +7,5 @@ add_subdirectory(Inductor) add_subdirectory(LinearTransformer) add_subdirectory(InductionMotor) add_subdirectory(SynchronousMachine) -add_subdirectory(DiscreteGenerator) \ No newline at end of file +add_subdirectory(DiscreteGenerator) +add_subdirectory(TransmissionLine) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/TransmissionLine/CMakeLists.txt new file mode 100644 index 000000000..6e2cea4f4 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_tranline + SOURCES + TransmissionLine.cpp + OUTPUT_NAME + gridkit_powerelec_tranline) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp new file mode 100644 index 000000000..62965c68e --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp @@ -0,0 +1,201 @@ + +#include +#include +#include +#include "TransmissionLine.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant TransmissionLine model + * + * Calls default ModelEvaluatorImpl constructor. + * + * This is the Medium distance form with the use of the admittance matrix. + * Since the line is of medium length then there is no real part for shunt admittance + */ + +template +TransmissionLine::TransmissionLine(IdxT id, ScalarT R,ScalarT X, ScalarT B) + : R_(R), X_(X), B_(B) +{ + // internals [Iret1, Iimt1, Iret2, Iimt2] + // externals [Vre11, Vim11, Vre12, Vim12, Vre21, Vim21, Vre22, Vim22] + this->size_ = 12; + this->n_intern = 4; + this->n_extern = 8; + this->extern_indices = {0,1,2,3,4,5,6,7}; + this->idc_ = id; + + ScalarT magImpendence = 1 / (R_*R_ + X_*X_); + YReMat_ = magImpendence * R_; + YImMatOff_ = magImpendence * X_; + YImMatDi_ = B_ / (2.0) - YImMatOff_; +} + +template +TransmissionLine::~TransmissionLine() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int TransmissionLine::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + + return 0; +} + +/** + * Initialization of the grid model + */ +template +int TransmissionLine::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int TransmissionLine::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Evaluate residual of transmission line + * + * The complex admittance matrix is: + * [[ Y/2 + 1/Z, -1/Z]; + * [ -1/Z, Y/2 + 1/Z]] = + * [[R/|Z|, -R/|Z|]; + * [-R/|Z|, R/|Z|]] + + * i [[B/2 - X/|Z|, X/|Z|]; + * [X/|Z|, B/2 - X/|Z|]] + * = Dre + i Dim + * + * Then + * Ire = Dre Vre - Dim Vim + * Iim = Dre Vim + Dim Vre + * + * To express this for Modified Nodal Analysis the Voltages of the admittance matrix are put into voltage drops + */ +template +int TransmissionLine::evaluateResidual() +{ + //input + this->f_[0] = y_[8] ; + this->f_[1] = y_[9] ; + + this->f_[2] = y_[10] ; + this->f_[3] = y_[11] ; + //ouput + this->f_[4] = -y_[8] ; + this->f_[5] = -y_[9] ; + + this->f_[6] = -y_[10] ; + this->f_[7] = -y_[11] ; + + //Voltage drop accross terminals + ScalarT V1re = y_[0] - y_[4]; + ScalarT V1im = y_[1] - y_[5]; + ScalarT V2re = y_[2] - y_[6]; + ScalarT V2im = y_[3] - y_[7]; + + //Internal variables + //row 1 + this->f_[8] = YReMat_ * (V1re - V2re) - (YImMatDi_ * V1im + YImMatOff_ * V2im) - y_[8] ; + this->f_[9] = YReMat_ * (V1im - V2im) + (YImMatDi_ * V1re + YImMatOff_ * V2re) - y_[9] ; + + //row2 + this->f_[10] = YReMat_ * (V2re - V1re) - (YImMatOff_ * V1im + YImMatDi_ * V2im) - y_[10]; + this->f_[11] = YReMat_ * (V2im - V1im) + (YImMatOff_ * V1re + YImMatDi_ * V2re) - y_[11]; + + + return 0; +} + +/** + * @brief Generate Jacobian for Transmission Line + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ +template +int TransmissionLine::evaluateJacobian() +{ + + //Create dF/dy + std::vector rtemp{0,1,2,3,4,5,6,7,8,9,10,11}; + std::vector ctemp{8,9,10,11,8,9,10,11,8,9,10,11}; + std::vector vals{1.0,1.0,1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0}; + this->J_.setValues(rtemp, ctemp, vals); + + + std::vector ccord{0,1,2,3,4,5,6,7}; + + std::vector rcord(ccord.size(),8); + vals = {YReMat_, -YImMatDi_ ,-YReMat_, -YImMatOff_,-YReMat_, YImMatDi_ ,YReMat_, YImMatOff_}; + this->J_.setValues(rtemp, ctemp, vals); + + + std::fill(rcord.begin(), rcord.end(), 9); + vals = {YImMatDi_ ,YReMat_, YImMatOff_, -YReMat_,-YImMatDi_ ,-YReMat_, -YImMatOff_, YReMat_}; + this->J_.setValues(rtemp, ctemp, vals); + + + std::fill(rcord.begin(), rcord.end(), 10); + vals = {-YReMat_, -YImMatDi_ ,YReMat_, -YImMatOff_,YReMat_, YImMatDi_ ,-YReMat_, YImMatOff_}; + this->J_.setValues(rtemp, ctemp, vals); + + + std::fill(rcord.begin(), rcord.end(), 11); + vals = {YImMatDi_ ,-YReMat_, YImMatOff_, YReMat_,-YImMatDi_ ,YReMat_, -YImMatOff_, -YReMat_}; + this->J_.setValues(rtemp, ctemp, vals); + + return 0; +} + +template +int TransmissionLine::evaluateIntegrand() +{ + return 0; +} + +template +int TransmissionLine::initializeAdjoint() +{ + return 0; +} + +template +int TransmissionLine::evaluateAdjointResidual() +{ + return 0; +} + +template +int TransmissionLine::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class TransmissionLine; +template class TransmissionLine; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp new file mode 100644 index 000000000..0f729d449 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp @@ -0,0 +1,71 @@ + + +#ifndef _TRANLINE_HPP_ +#define _TRANLINE_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive TransmissionLine class. + * + */ + template + class TransmissionLine : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::J_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + public: + TransmissionLine(IdxT id, ScalarT R, ScalarT X, ScalarT B); + virtual ~TransmissionLine(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + + private: + ScalarT R_; + ScalarT X_; + ScalarT B_; + ScalarT YReMat_; + ScalarT YImMatDi_; + ScalarT YImMatOff_; + }; +} + +#endif diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp index c71eef06d..e902b1242 100644 --- a/Examples/RLCircuit/RLCircuit.cpp +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -89,7 +89,6 @@ int main(int argc, char const *argv[]) sysmodel->yp()[2] = -vinit / linit; // i'_s sysmodel->yp()[3] = -vinit / linit; // i'_L - sysmodel->initialize(); sysmodel->evaluateResidual(); From fcf1cb95ae8d2067794b6a7a0aff116d1d69415e Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Mon, 19 Feb 2024 13:31:19 -0500 Subject: [PATCH 07/44] Added Microgrid Example - Added MicrogridBusDQ - Added MicrogridLine - Added MicrogridLoad - Updated DiscreteGenerator - Added Output Testing for DG - Added Microgrid Assmebly Example - Updated Capacitor, Inductor, and Voltage residuals - Updated RLCircuit Example --- .../PowerElectronicsComponents/CMakeLists.txt | 5 +- .../Capacitor/Capacitor.cpp | 13 +- .../DiscreteGenerator/DiscreteGenerator.cpp | 211 ++++++---- .../DiscreteGenerator/DiscreteGenerator.hpp | 5 +- .../Inductor/Inductor.cpp | 10 +- .../MicrogridBusDQ/CMakeLists.txt | 8 + .../MicrogridBusDQ/MicrogridBusDQ.cpp | 132 +++++++ .../MicrogridBusDQ/MicrogridBusDQ.hpp | 66 ++++ .../MicrogridLine/CMakeLists.txt | 8 + .../MicrogridLine/MicrogridLine.cpp | 172 +++++++++ .../MicrogridLine/MicrogridLine.hpp | 67 ++++ .../MicrogridLoad/CMakeLists.txt | 8 + .../MicrogridLoad/MicrogridLoad.cpp | 169 ++++++++ .../MicrogridLoad/MicrogridLoad.hpp | 67 ++++ .../VoltageSource/VoltageSource.cpp | 8 +- Examples/CMakeLists.txt | 1 + Examples/DiscreteGeneratorTest/CMakeLists.txt | 5 +- Examples/DiscreteGeneratorTest/DGTest.cpp | 30 +- Examples/Microgrid/CMakeLists.txt | 13 + Examples/Microgrid/Microgrid.cpp | 361 ++++++++++++++++++ Examples/RLCircuit/RLCircuit.cpp | 8 +- SparseMatrix/COO_Matrix.hpp | 9 + 22 files changed, 1279 insertions(+), 97 deletions(-) create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridLine/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridLoad/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.hpp create mode 100644 Examples/Microgrid/CMakeLists.txt create mode 100644 Examples/Microgrid/Microgrid.cpp diff --git a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt index 8b96aaa66..3fba4be7f 100644 --- a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt +++ b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt @@ -8,4 +8,7 @@ add_subdirectory(LinearTransformer) add_subdirectory(InductionMotor) add_subdirectory(SynchronousMachine) add_subdirectory(DiscreteGenerator) -add_subdirectory(TransmissionLine) \ No newline at end of file +add_subdirectory(TransmissionLine) +add_subdirectory(MicrogridLoad) +add_subdirectory(MicrogridLine) +add_subdirectory(MicrogridBusDQ) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp index 79faefe89..b6287b359 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -69,15 +69,20 @@ int Capacitor::tagDifferentiable() template int Capacitor::evaluateResidual() { - this->f_[0] = this->yp_[2]; - this->f_[1] = -this->yp_[2]; - this->f_[2] = -this->C_ * this->yp_[2] + this->y_[0] - this->y_[1] - this->y_[2]; + //input + this->f_[0] = C_ * this->yp_[2]; + //output + this->f_[1] = -C_ * this->yp_[2]; + + //internal + this->f_[2] = -C_ * this->yp_[2] + this->y_[0] - this->y_[1] - this->y_[2]; return 0; } template int Capacitor::evaluateJacobian() { + this->J_.zeroMatrix(); //Create dF/dy std::vector rcord{2,2,2}; std::vector ccord{0,1,2}; @@ -87,7 +92,7 @@ int Capacitor::evaluateJacobian() //Create -dF/dy' std::vector rcordder{0,1,2}; std::vector ccordder{2,2,2}; - std::vector valsder{1.0, -1.0, -this->C_}; + std::vector valsder{C_, -C_, -this->C_}; COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp index c66c5b0f9..607ec5312 100644 --- a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp +++ b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp @@ -17,11 +17,11 @@ namespace ModelLib { */ template -DiscreteGenerator::DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm) - : wb_(parm.wb), wc_(parm.wc), mp_(parm.mp), refmp_(parm.refmp), Vn_(parm.Vn), nq_(parm.nq), F_(parm.F), Kiv_(parm.Kiv), Kpv_(parm.Kpv), Kic_(parm.Kic), Kpc_(parm.Kpc), Cf_(parm.Cf), rLf_(parm.rLf), Lf_(parm.Lf), rLc_(parm.rLc), Lc_(parm.Lc) +DiscreteGenerator::DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm, bool reference_frame) + : wb_(parm.wb), wc_(parm.wc), mp_(parm.mp), Vn_(parm.Vn), nq_(parm.nq), F_(parm.F), Kiv_(parm.Kiv), Kpv_(parm.Kpv), Kic_(parm.Kic), Kpc_(parm.Kpc), Cf_(parm.Cf), rLf_(parm.rLf), Lf_(parm.Lf), rLc_(parm.rLc), Lc_(parm.Lc), refframe_(reference_frame) { - // internals [delta_i, Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi] - // externals [Pref, Pbus, QBus] + // internals [\delta_i, Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi] + // externals [\omega_ref, vba_out, vbb_out] this->size_ = 16; this->n_intern = 13; this->n_extern = 3; @@ -74,42 +74,64 @@ template int DiscreteGenerator::evaluateResidual() { // ### Externals Componenets ### - //Reference P - ScalarT wcom = this->wb_ - this->refmp_ * this->y_[0]; - this->f_[0] = 0; - this->f_[1] = 0; - this->f_[2] = 0; + ScalarT omega = wb_ - mp_ * y_[4]; + //ref common ref motor angle + if (refframe_) + { + f_[0] = omega - y_[0]; + } + else + { + f_[0] = 0.0; + } + + + //output + //current transformed to common frame + f_[1] = cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15]; + f_[2] = sin(y_[3]) * y_[14] + cos(y_[3]) * y_[15]; - // ### Internal Componenets ## - f_[3] = -yp_[3] + wb_ - mp_ * y_[4] - wcom; + //Take incoming voltages to current rotator reference frame + ScalarT vbd_in = cos(y_[3]) * y_[1] + sin(y_[3]) * y_[2]; + ScalarT vbq_in = -sin(y_[3]) * y_[1] + cos(y_[3]) * y_[2]; + // ### Internal Componenets ## + // Rotator difference angle + f_[3] = -yp_[3] + omega - y_[0]; + + // P and Q equations f_[4] = -yp_[4] + wc_ * (y_[12] * y_[14] + y_[13] * y_[15] - y_[4]); - f_[5] = -yp_[4] + wc_ * (-y_[12] * y_[15] + y_[13] * y_[14] - y_[5]); + f_[5] = -yp_[5] + wc_ * (-y_[12] * y_[15] + y_[13] * y_[14] - y_[5]); + //Voltage control ScalarT vod_star = Vn_ - nq_ * y_[5]; - ScalarT voq_star = 0; + ScalarT voq_star = 0.0; f_[6] = -yp_[6] + vod_star - y_[12]; f_[7] = -yp_[7] + voq_star - y_[13]; - ScalarT ild_star = F_ * y_[14] - wb_ * Cf_ * y_[13] + Kpv_ * (vod_star - y_[12]) + Kiv_ * y_[6] ; + + ScalarT ild_star = F_ * y_[14] - wb_ * Cf_ * y_[13] + Kpv_ * (vod_star - y_[12]) + Kiv_ * y_[6]; ScalarT ilq_star = F_ * y_[15] + wb_ * Cf_ * y_[12] + Kpv_ * (voq_star - y_[13]) + Kiv_ * y_[7]; + //Current control f_[8] = -yp_[8] + ild_star - y_[10]; f_[9] = -yp_[9] + ilq_star - y_[11]; ScalarT vid_star = -wb_ * Lf_ * y_[11] + Kpc_ * (ild_star - y_[10]) + Kic_ * y_[8]; ScalarT viq_star = wb_ * Lf_ * y_[10] + Kpc_ * (ilq_star - y_[11]) + Kic_ * y_[9]; - f_[10] = -yp_[10] - (rLf_ / Lf_) * y_[10] + wcom * y_[11] + (1/Lf_) * (vid_star - y_[12]); - f_[11] = -yp_[11] - (rLf_ / Lf_) * y_[11] - wcom * y_[10] + (1/Lf_) * (viq_star - y_[13]); + //Output LC Filter + f_[10] = -yp_[10] - (rLf_ / Lf_) * y_[10] + omega * y_[11] + (vid_star - y_[12]) / Lf_; + f_[11] = -yp_[11] - (rLf_ / Lf_) * y_[11] - omega * y_[10] + (viq_star - y_[13]) / Lf_; - f_[12] = -yp_[12] + wcom * y_[13] + (1/Cf_) * (y_[10] - y_[14]); - f_[13] = -yp_[13] - wcom * y_[12] + (1/Cf_) * (y_[11] - y_[15]); + f_[12] = -yp_[12] + omega * y_[13] + (y_[10] - y_[14]) / Cf_; + f_[13] = -yp_[13] - omega * y_[12] + (y_[11] - y_[15]) / Cf_; - f_[14] = -yp_[14] - (rLc_ / Lc_) * y_[14] + wcom * y_[15] + (1/Lc_)*(y_[12] - y_[1]); - f_[15] = -yp_[15] - (rLc_ / Lc_) * y_[15] - wcom * y_[14] + (1/Lc_)*(y_[13] - y_[2]); + //Output Connector + f_[14] = -yp_[14] - (rLc_ / Lc_) * y_[14] + omega * y_[15] + (y_[12] - vbd_in) / Lc_; + f_[15] = -yp_[15] - (rLc_ / Lc_) * y_[15] - omega * y_[14] + (y_[13] - vbq_in) / Lc_; return 0; } @@ -117,24 +139,24 @@ int DiscreteGenerator::evaluateResidual() * @brief Compute the jacobian of the DiscreteGenerator for iteration. dF/dy - \alpha dF/dy' * * The matrix dF/dy should be - * [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -[ mpref, 0, 0, 0, -mp, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -[ 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, 0, wc*x15, wc*x16, wc*x13, wc*x14] -[ 0, 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, -wc*x16, wc*x15, wc*x14, -wc*x13] -[ 0, 0, 0, 0, 0, -nq, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0] -[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0] -[ 0, 0, 0, 0, 0, -Kpv*nq, Kiv, 0, 0, 0, -1, 0, -Kpv, -Cf*wb, F, 0] -[ 0, 0, 0, 0, 0, 0, 0, Kiv, 0, 0, 0, -1, Cf*wb, -Kpv, 0, F] -[-mpref*x12, 0, 0, 0, 0, -(Kpc*Kpv*nq)/Lf, (Kiv*Kpc)/Lf, 0, Kic/Lf, 0, - Kpc/Lf - rLf/Lf, -mpref*x1, -(Kpc*Kpv + 1)/Lf, -(Cf*Kpc*wb)/Lf, (F*Kpc)/Lf, 0] -[ mpref*x11, 0, 0, 0, 0, 0, 0, (Kiv*Kpc)/Lf, 0, Kic/Lf, mpref*x1, - Kpc/Lf - rLf/Lf, (Cf*Kpc*wb)/Lf, -(Kpc*Kpv + 1)/Lf, 0, (F*Kpc)/Lf] -[-mpref*x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Cf, 0, 0, wb - mpref*x1, -1/Cf, 0] -[ mpref*x13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Cf, mpref*x1 - wb, 0, 0, -1/Cf] -[-mpref*x16, -1/Lc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Lc, 0, -rLc/Lc, wb - mpref*x1] -[ mpref*x15, 0, -1/Lc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Lc, mpref*x1 - wb, -rLc/Lc] + * +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[-1, 0, 0, 0, -mp, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[ 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, 0, wc*x15, wc*x16, wc*x13, wc*x14] +[ 0, 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, -wc*x16, wc*x15, wc*x14, -wc*x13] +[ 0, 0, 0, 0, 0, -nq, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0] +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0] +[ 0, 0, 0, 0, 0, -Kpv*nq, Kiv, 0, 0, 0, -1, 0, -Kpv, -Cf*wb, F, 0] +[ 0, 0, 0, 0, 0, 0, 0, Kiv, 0, 0, 0, -1, Cf*wb, -Kpv, 0, F] +[ 0, 0, 0, 0, -mp*x12, -(Kpc*Kpv*nq)/Lf, (Kiv*Kpc)/Lf, 0, Kic/Lf, 0, - Kpc/Lf - rLf/Lf, -mp*x5, -(Kpc*Kpv + 1)/Lf, -(Cf*Kpc*wb)/Lf, (F*Kpc)/Lf, 0] +[ 0, 0, 0, 0, mp*x11, 0, 0, (Kiv*Kpc)/Lf, 0, Kic/Lf, mp*x5, - Kpc/Lf - rLf/Lf, (Cf*Kpc*wb)/Lf, -(Kpc*Kpv + 1)/Lf, 0, (F*Kpc)/Lf] +[ 0, 0, 0, 0, -mp*x14, 0, 0, 0, 0, 0, 1/Cf, 0, 0, wb - mp*x5, -1/Cf, 0] +[ 0, 0, 0, 0, mp*x13, 0, 0, 0, 0, 0, 0, 1/Cf, mp*x5 - wb, 0, 0, -1/Cf] +[ 0, -cos(x4)/Lc, -sin(x4)/Lc, -(x3*cos(x4) - x2*sin(x4))/Lc, -mp*x16, 0, 0, 0, 0, 0, 0, 0, 1/Lc, 0, -rLc/Lc, wb - mp*x5] +[ 0, sin(x4)/Lc, -cos(x4)/Lc, (x2*cos(x4) + x3*sin(x4))/Lc, mp*x15, 0, 0, 0, 0, 0, 0, 0, 0, 1/Lc, mp*x5 - wb, -rLc/Lc] * 'Generated from MATLAB symbolic' - * Jacobian is mostly constant besides reference and rows 4 & 5 * * @tparam ScalarT * @tparam IdxT @@ -145,99 +167,146 @@ int DiscreteGenerator::evaluateJacobian() { //Create dF/dy' std::vector rcordder(13); - std::vector valsder(13,1.0); + std::vector valsder(13, -1.0); for (int i = 0; i < 13; i++) { rcordder[i] = i + 3; } COO_Matrix Jacder = COO_Matrix(rcordder, rcordder, valsder,16,16); + std::vector ctemp{}; + std::vector rtemp{}; + std::vector valtemp{}; + + + //Create dF/dy + //r = 1 + + ctemp = {3, 14, 15}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(1); + valtemp = { - sin(y_[3]) * y_[14] - cos(y_[3]) * y_[15], cos(y_[3]),sin(y_[3])}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 2 + + ctemp = {3, 14, 15}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(2); + valtemp = { - cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15], -sin(y_[3]),cos(y_[3])}; + this->J_.setValues(rtemp, ctemp, valtemp); + //r = 3 - std::vector ctemp{0, 4}; - std::vector rtemp(ctemp.size(),3); - std::vector valtemp{this->refmp_, -this->mp_}; + + ctemp = {0, 4}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(3); + valtemp = {-1.0, -mp_}; this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 0 + if (refframe_) + { + ctemp = {0, 4}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(0); + valtemp = {-1.0, -mp_}; + this->J_.setValues(rtemp, ctemp, valtemp); + } + //r = 4 ctemp = {4, 12, 13, 14, 15}; - std::fill(rtemp.begin(), rtemp.end(), 4); - valtemp = {-this->wc_, this->wc_*y_[14], this->wc_*y_[15], this->wc_*y_[12], this->wc_*y_[13]}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(4); + valtemp = {-wc_, wc_*y_[14], wc_*y_[15], wc_*y_[12], wc_*y_[13]}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 5 ctemp = {5, 12, 13, 14, 15}; - std::fill(rtemp.begin(), rtemp.end(), 5); - valtemp = {-this->wc_, -this->wc_*y_[15], this->wc_*y_[14], this->wc_*y_[13], -this->wc_*y_[12]}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(5); + valtemp = {-wc_, -wc_*y_[15], wc_*y_[14], wc_*y_[13], -wc_*y_[12]}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 6 ctemp = {5, 12}; - std::fill(rtemp.begin(), rtemp.end(), 6); - valtemp = {-this->nq_, -1.0}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(6); + valtemp = {-nq_, -1.0}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 7 ctemp = {13}; - std::fill(rtemp.begin(), rtemp.end(), 7); + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(7); valtemp = {-1.0}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 8 ctemp = {5,6,10,12,13,14}; - std::fill(rtemp.begin(), rtemp.end(), 8); - valtemp = {-this->Kpv_*this->nq_, this->Kiv_, -1.0, -this->Kpv_, -this->Cf_*this->wb_, this->F_}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(8); + valtemp = {-Kpv_*nq_, Kiv_, -1.0, -Kpv_, -Cf_*wb_, F_}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 9 ctemp = {7, 11, 12, 13, 15}; - std::fill(rtemp.begin(), rtemp.end(), 9); - valtemp = {this->Kiv_, -1.0, this->Cf_*this->wb_,-this->Kpv_,this->F_}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(9); + valtemp = {Kiv_, -1.0, Cf_*wb_,-Kpv_,F_}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 10 - ctemp = {0, 5, 6, 8, 10, 11, 12, 13, 14}; - std::fill(rtemp.begin(), rtemp.end(), 10); - valtemp = {-this->refmp_ * y_[11], -(this->Kpc_ * this->Kpv_ * this->nq_) / this->Lf_, (this->Kpc_ * this->Kiv_) / this->Lf_, this->Kic_ / this->Lf_, -(this->Kpc_ + this->rLf_) / this->Lf_, -this->refmp_ * y_[0], -(this->Kpc_ * this->Kpv_ + 1.0) / this->Lf_, -(this->Cf_ * this->Kpc_ * this->wb_) / this->Lf_, (this->F_ * this->Kpc_) / this->Lf_}; + ctemp = {4, 5, 6, 8, 10, 11, 12, 13, 14}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(10); + valtemp = {-mp_ * y_[11], -(Kpc_ * Kpv_ * nq_) / Lf_, (Kpc_ * Kiv_) / Lf_, Kic_ / Lf_, -(Kpc_ + rLf_) / Lf_, -mp_ * y_[4], -(Kpc_ * Kpv_ + 1.0) / Lf_, -(Cf_ * Kpc_ * wb_) / Lf_, (F_ * Kpc_) / Lf_}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 11 - ctemp = {0, 7, 9, 10, 11, 12, 13, 15}; - std::fill(rtemp.begin(), rtemp.end(), 11); - valtemp = {this->refmp_ * y_[10], (this->Kiv_ * this->Kpc_) / this->Lf_, this->Kic_ / this->Lf_, this->refmp_ * y_[0], -(this->Kpc_ + this->rLf_) / this->Lf_, (this->Cf_ * this->Kpc_ * this->wb_) / this->Lf_, -(this->Kpc_ * this->Kpv_ + 1.0) / this->Lf_, (this->F_ * this->Kpc_) / this->Lf_}; + ctemp = {4, 7, 9, 10, 11, 12, 13, 15}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(11); + valtemp = {mp_ * y_[10], (Kiv_ * Kpc_) / Lf_, Kic_ / Lf_, mp_ * y_[4], -(Kpc_ + rLf_) / Lf_, (Cf_ * Kpc_ * wb_) / Lf_, -(Kpc_ * Kpv_ + 1.0) / Lf_, (F_ * Kpc_) / Lf_}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 12 - ctemp = {0, 10, 13, 14}; - std::fill(rtemp.begin(), rtemp.end(), 12); - valtemp = {-this->refmp_ * y_[13], 1.0 / this->Cf_, this->wb_ - this->refmp_ * y_[0], -1.0 / this->Cf_}; + ctemp = {4, 10, 13, 14}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(12); + valtemp = {-mp_ * y_[13], 1.0 / Cf_, wb_ - mp_ * y_[4], -1.0 / Cf_}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 13 - ctemp = {0, 11, 12, 15}; - std::fill(rtemp.begin(), rtemp.end(), 13); - valtemp = {this->refmp_ * y_[12], 1.0 / this->Cf_, -this->wb_ + this->refmp_ * y_[0], -1.0 / this->Cf_}; + ctemp = {4, 11, 12, 15}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(13); + valtemp = {mp_ * y_[12], 1.0 / Cf_, -wb_ + mp_ * y_[4], -1.0 / Cf_}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 14 - ctemp = {0, 1, 12, 14, 15}; - std::fill(rtemp.begin(), rtemp.end(), 14); - valtemp = {-this->refmp_ * y_[15], -1.0 / this->Lc_, 1.0 / this->Lc_, -this->rLc_ / this->Lc_, this->wb_ - this->refmp_ * y_[0]}; + ctemp = {1, 2, 3, 4, 12, 14, 15}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(14); + valtemp = {(1.0/Lc_) * -cos(y_[3]) , (1.0/Lc_) * -sin(y_[3]) , (1.0/Lc_) * (sin(y_[3]) * y_[1] - cos(y_[3]) * y_[2]), -mp_ * y_[15], 1.0 / Lc_, -rLc_ / Lc_, wb_ - mp_ * y_[4]}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 15 - ctemp = {0, 2, 13, 14, 15}; - std::fill(rtemp.begin(), rtemp.end(), 15); - valtemp = {-this->refmp_ * y_[14], -1.0 / this->Lc_, 1.0 / this->Lc_, -this->wb_ + this->refmp_ * y_[0], -this->rLc_ / this->Lc_}; + ctemp = {1, 2, 3, 4, 13, 14, 15}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(15); + valtemp = {(1.0/Lc_) * sin(y_[3]) , (1.0/Lc_) * -cos(y_[3]), (1.0/Lc_) * (cos(y_[3]) * y_[1] + sin(y_[3]) * y_[2]), mp_ * y_[14], 1.0 / Lc_, -wb_ + mp_ * y_[4], -rLc_ / Lc_}; this->J_.setValues(rtemp, ctemp, valtemp); //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(-this->alpha_, Jacder); + this->J_.AXPY(this->alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp index f5ce86899..bca984460 100644 --- a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp +++ b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp @@ -18,7 +18,6 @@ namespace ModelLib ScalarT wb; ScalarT wc; ScalarT mp; - ScalarT refmp; ScalarT Vn; ScalarT nq; ScalarT F; @@ -63,7 +62,7 @@ namespace ModelLib public: - DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm); + DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm, bool reference_frame); virtual ~DiscreteGenerator(); int allocate(); @@ -81,7 +80,6 @@ namespace ModelLib ScalarT wb_; ScalarT wc_; ScalarT mp_; - ScalarT refmp_; ScalarT Vn_; ScalarT nq_; ScalarT F_; @@ -94,6 +92,7 @@ namespace ModelLib ScalarT Lf_; ScalarT rLc_; ScalarT Lc_; + bool refframe_; }; } diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index a24b7a8e9..885153d41 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -71,11 +71,11 @@ template int Inductor::evaluateResidual() { //input - this->f_[0] = this->y_[2]; + this->f_[0] = -this->y_[2]; //output - this->f_[1] = -this->y_[2]; + this->f_[1] = this->y_[2]; //internal - this->f_[2] = this->L_ * this->yp_[2] + this->y_[0] - this->y_[1] ; + this->f_[2] = -this->L_ * this->yp_[2] + this->y_[1] - this->y_[0] ; return 0; } @@ -87,13 +87,13 @@ int Inductor::evaluateJacobian() //Create dF/dy std::vector rcord{0,1,2,2}; std::vector ccord{2,2,0,1}; - std::vector vals{1.0, -1.0, 1.0, -1.0}; + std::vector vals{-1.0, 1.0, -1.0, 1.0}; this->J_.setValues(rcord, ccord, vals); //Create dF/dy' std::vector rcordder{2}; std::vector ccordder{2}; - std::vector valsder{this->L_}; + std::vector valsder{-this->L_}; COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/CMakeLists.txt new file mode 100644 index 000000000..1bfb8dc3d --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_mircobusdq + SOURCES + MicrogridBusDQ.cpp + OUTPUT_NAME + gridkit_powerelec_mircobusdq) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp new file mode 100644 index 000000000..206108221 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -0,0 +1,132 @@ + +#include +#include +#include +#include "MicrogridBusDQ.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant MicrogridBusDQ model + * + * Calls default ModelEvaluatorImpl constructor. + * + * Each microgrid line has a virtual resistance RN + */ + +template +MicrogridBusDQ::MicrogridBusDQ(IdxT id, ScalarT RN) + : RN_(RN) +{ + // externals [vbus_d, vbus_q] + this->size_ = 2; + this->n_intern = 0; + this->n_extern = 2; + this->extern_indices = {0,1}; + this->idc_ = id; +} + +template +MicrogridBusDQ::~MicrogridBusDQ() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int MicrogridBusDQ::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + + return 0; +} + +/** + * Initialization of the grid model + */ +template +int MicrogridBusDQ::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int MicrogridBusDQ::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Evaluate residual of microgrid line + * This model has "Virtual resistors" on both ends with parameters RN1 and RN2 + * + */ +template +int MicrogridBusDQ::evaluateResidual() +{ + //bus voltage + f_[0] = -y_[0] / RN_; + f_[1] = -y_[1] / RN_; + + return 0; +} + +/** + * @brief Generate Jacobian for Transmission Line + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ +template +int MicrogridBusDQ::evaluateJacobian() +{ + this->J_.zeroMatrix(); + + //Create dF/dy + std::vector rtemp{0,1}; + std::vector ctemp{0,1}; + std::vector vals{-1.0 / RN_,-1.0 / RN_}; + this->J_.setValues(rtemp, ctemp, vals); + + return 0; +} + +template +int MicrogridBusDQ::evaluateIntegrand() +{ + return 0; +} + +template +int MicrogridBusDQ::initializeAdjoint() +{ + return 0; +} + +template +int MicrogridBusDQ::evaluateAdjointResidual() +{ + return 0; +} + +template +int MicrogridBusDQ::evaluateAdjointIntegrand() +{ + return 0; +} + + +// Available template instantiations +template class MicrogridBusDQ; +template class MicrogridBusDQ; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp new file mode 100644 index 000000000..44154da38 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp @@ -0,0 +1,66 @@ + + +#ifndef _VIRBUSDQ_HPP_ +#define _VIRBUSDQ_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive MicrogridBusDQ class. + * + */ + template + class MicrogridBusDQ : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::J_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + public: + MicrogridBusDQ(IdxT id, ScalarT RN); + virtual ~MicrogridBusDQ(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + + private: + ScalarT RN_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/MicrogridLine/CMakeLists.txt new file mode 100644 index 000000000..d59cebb9c --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_mircoline + SOURCES + MicrogridLine.cpp + OUTPUT_NAME + gridkit_powerelec_mircoline) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp new file mode 100644 index 000000000..e040ceb70 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp @@ -0,0 +1,172 @@ + +#include +#include +#include +#include "MicrogridLine.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant MicrogridLine model + * + * Calls default ModelEvaluatorImpl constructor. + * + * Each microgrid line has a virtual resistance RN + */ + +template +MicrogridLine::MicrogridLine(IdxT id, ScalarT R,ScalarT L) + : R_(R), L_(L) +{ + // internals [id, iq] + // externals [\omegaref, vbd_in, vbq_in, vbd_out, vbq_out] + this->size_ = 7; + this->n_intern = 2; + this->n_extern = 5; + this->extern_indices = {0,1,2,3,4}; + this->idc_ = id; +} + +template +MicrogridLine::~MicrogridLine() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int MicrogridLine::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + + return 0; +} + +/** + * Initialization of the grid model + */ +template +int MicrogridLine::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int MicrogridLine::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Evaluate residual of microgrid line + * This model has "Virtual resistors" on both ends with parameters RN1 and RN2 + * + */ +template +int MicrogridLine::evaluateResidual() +{ + //ref motor + this->f_[0] = 0.0; + + //input + this->f_[1] = -y_[5] ; + this->f_[2] = -y_[6] ; + + //output + this->f_[3] = y_[5] ; + this->f_[4] = y_[6] ; + + //Internal variables + this->f_[5] = -yp_[5] - (R_ / L_) * y_[5] + y_[0]*y_[6] + (y_[1] - y_[3])/L_; + this->f_[6] = -yp_[6] - (R_ / L_) * y_[6] - y_[0]*y_[5] + (y_[2] - y_[4])/L_; + + + return 0; +} + +/** + * @brief Generate Jacobian for Transmission Line + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ +template +int MicrogridLine::evaluateJacobian() +{ + this->J_.zeroMatrix(); + + //Create dF/dy + std::vector rtemp{1,2,3,4}; + std::vector ctemp{5,6,5,6}; + std::vector vals{-1.0,-1.0,1.0,1.0}; + this->J_.setValues(rtemp, ctemp, vals); + + + std::vector ccord{0, 1, 3, 5, 6}; + + std::vector rcord(ccord.size(),5); + vals = {y_[6], (1.0 / L_) , -(1.0 / L_), - (R_ / L_) , y_[0]}; + this->J_.setValues(rcord, ccord, vals); + + + std::vector ccor2{0, 2, 4, 5, 6}; + std::fill(rcord.begin(), rcord.end(), 6); + vals = {-y_[5], (1.0 / L_) , -(1.0 / L_), -y_[0], - (R_ / L_)}; + this->J_.setValues(rcord, ccor2, vals); + + + //Create -dF/dy' + std::vector rcordder{5,6}; + std::vector ccordder{5,6}; + std::vector valsder{-1.0, -1.0}; + COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,7,7); + + //Perform dF/dy + \alpha dF/dy' + this->J_.AXPY(this->alpha_, Jacder); + + + return 0; +} + +template +int MicrogridLine::evaluateIntegrand() +{ + return 0; +} + +template +int MicrogridLine::initializeAdjoint() +{ + return 0; +} + +template +int MicrogridLine::evaluateAdjointResidual() +{ + return 0; +} + +template +int MicrogridLine::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class MicrogridLine; +template class MicrogridLine; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp new file mode 100644 index 000000000..11ef78617 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp @@ -0,0 +1,67 @@ + + +#ifndef _TRANLINE_HPP_ +#define _TRANLINE_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive MicrogridLine class. + * + */ + template + class MicrogridLine : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::J_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + public: + MicrogridLine(IdxT id, ScalarT R, ScalarT L); + virtual ~MicrogridLine(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + + private: + ScalarT R_; + ScalarT L_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/CMakeLists.txt new file mode 100644 index 000000000..313d47688 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_microload + SOURCES + MicrogridLoad.cpp + OUTPUT_NAME + gridkit_powerelec_microload) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp new file mode 100644 index 000000000..c39f53388 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp @@ -0,0 +1,169 @@ + +#include +#include +#include +#include "MicrogridLoad.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant MicrogridLoad model + * + * Calls default ModelEvaluatorImpl constructor. + * + * This is the Medium distance form with the use of the admittance matrix. + * Since the line is of medium length then there is no real part for shunt admittance + */ + +template +MicrogridLoad::MicrogridLoad(IdxT id, ScalarT R,ScalarT L) + : R_(R), L_(L) +{ + // internals [id, iq] + // externals [\omegaref, vbd_out, vbq_out] + this->size_ = 5; + this->n_intern = 2; + this->n_extern = 3; + this->extern_indices = {0,1,2}; + this->idc_ = id; + +} + +template +MicrogridLoad::~MicrogridLoad() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int MicrogridLoad::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + + return 0; +} + +/** + * Initialization of the grid model + */ +template +int MicrogridLoad::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int MicrogridLoad::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Eval Micro Load + */ +template +int MicrogridLoad::evaluateResidual() +{ + //ref motor + this->f_[0] = 0.0; + + //only input for loads + + //input + this->f_[1] = -y_[3] ; + this->f_[2] = -y_[4] ; + + //Internal variables + this->f_[3] = -yp_[3] - (R_ / L_) * y_[3] + y_[0]*y_[4] + y_[1] / L_; + this->f_[4] = -yp_[4] - (R_ / L_) * y_[4] - y_[0]*y_[3] + y_[2] / L_; + + + return 0; +} + +/** + * @brief Generate Jacobian for Micro Load + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ +template +int MicrogridLoad::evaluateJacobian() +{ + this->J_.zeroMatrix(); + + //Create dF/dy + std::vector rtemp{1,2}; + std::vector ctemp{3,4}; + std::vector vals{-1.0,-1.0}; + this->J_.setValues(rtemp, ctemp, vals); + + + std::vector ccord{0, 1, 3, 4}; + + std::vector rcord(ccord.size(),3); + vals = {y_[4], (1.0 / L_) , - (R_ / L_) , y_[0]}; + this->J_.setValues(rcord, ccord, vals); + + + std::vector ccor2{0, 2, 3, 4}; + std::fill(rcord.begin(), rcord.end(), 4); + vals = {-y_[3], (1.0 / L_) , -y_[0], - (R_ / L_)}; + this->J_.setValues(rcord, ccor2, vals); + + + //Create -dF/dy' + std::vector rcordder{3,4}; + std::vector ccordder{3,4}; + std::vector valsder{-1.0, -1.0}; + COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,5,5); + + //Perform dF/dy + \alpha dF/dy' + this->J_.AXPY(this->alpha_, Jacder); + + return 0; +} + +template +int MicrogridLoad::evaluateIntegrand() +{ + return 0; +} + +template +int MicrogridLoad::initializeAdjoint() +{ + return 0; +} + +template +int MicrogridLoad::evaluateAdjointResidual() +{ + return 0; +} + +template +int MicrogridLoad::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class MicrogridLoad; +template class MicrogridLoad; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.hpp b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.hpp new file mode 100644 index 000000000..22694f614 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.hpp @@ -0,0 +1,67 @@ + + +#ifndef _TRANLOAD_HPP_ +#define _TRANLOAD_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive MicrogridLoad class. + * + */ + template + class MicrogridLoad : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::J_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + public: + MicrogridLoad(IdxT id, ScalarT R, ScalarT L); + virtual ~MicrogridLoad(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + + private: + ScalarT R_; + ScalarT L_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp index c7cb09798..e58e50556 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -72,11 +72,11 @@ int VoltageSource::evaluateResidual() //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors // for easier development //input - this->f_[0] = this->y_[2]; + this->f_[0] = -this->y_[2]; //ouput - this->f_[1] = -this->y_[2]; + this->f_[1] = this->y_[2]; //internal - this->f_[2] = -this->y_[1] + this->y_[0] + this->V_; + this->f_[2] = this->y_[1] - this->y_[0] - this->V_; return 0; } @@ -86,7 +86,7 @@ int VoltageSource::evaluateJacobian() //Create dF/dy std::vector rcord{0,1,2,2}; std::vector ccord{2,2,0,1}; - std::vector vals{1.0, -1.0, 1.0, -1.0}; + std::vector vals{-1.0, 1.0, -1.0, 1.0}; this->J_.setValues(rcord, ccord, vals); return 0; diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index e15774642..2c53fcc25 100644 --- a/Examples/CMakeLists.txt +++ b/Examples/CMakeLists.txt @@ -57,6 +57,7 @@ add_subdirectory(MatPowerTesting) add_subdirectory(RLCircuit) +add_subdirectory(Microgrid) add_subdirectory(SparseTest) add_subdirectory(DiscreteGeneratorTest) diff --git a/Examples/DiscreteGeneratorTest/CMakeLists.txt b/Examples/DiscreteGeneratorTest/CMakeLists.txt index b1100b91a..9238fb346 100644 --- a/Examples/DiscreteGeneratorTest/CMakeLists.txt +++ b/Examples/DiscreteGeneratorTest/CMakeLists.txt @@ -3,7 +3,10 @@ add_executable(dgtest DGTest.cpp) -target_link_libraries(dgtest GRIDKIT::powerelec_disgen) +target_link_libraries(dgtest GRIDKIT::powerelec_disgen + GRIDKIT::powerelec_mircoline + GRIDKIT::powerelec_microload + GRIDKIT::solvers_dyn) add_test(NAME DiscreteGeneratorTest COMMAND $) install(TARGETS dgtest RUNTIME DESTINATION bin) diff --git a/Examples/DiscreteGeneratorTest/DGTest.cpp b/Examples/DiscreteGeneratorTest/DGTest.cpp index 7d4aeda6f..d3dd2c68b 100644 --- a/Examples/DiscreteGeneratorTest/DGTest.cpp +++ b/Examples/DiscreteGeneratorTest/DGTest.cpp @@ -15,11 +15,9 @@ int main(int argc, char const *argv[]) ModelLib::DiscreteGeneratorParameters parms; //Parameters from MATLAB Microgrid code for first DG - //refmp is need for reference input parms.wb = 2.0*M_PI*50.0; parms.wc = 31.41; parms.mp = 9.4e-5; - parms.refmp = 9.4e-5; parms.Vn = 380; parms.nq = 1.3e-3; parms.F = 0.75; @@ -33,7 +31,7 @@ int main(int argc, char const *argv[]) parms.rLc = 0.03; parms.Lc = 0.35e-3; - ModelLib::DiscreteGenerator *dg = new ModelLib::DiscreteGenerator(0, parms); + ModelLib::DiscreteGenerator *dg = new ModelLib::DiscreteGenerator(0, parms, true); std::vector t1(16,0.0); std::vector t2{0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,1.3,1.4,1.5}; @@ -48,9 +46,33 @@ int main(int argc, char const *argv[]) std::cout << "Output: {"; for (double i : dg->getResidual()) { - std::cout << i << ", "; + printf("%e ,", i); } std::cout << "}\n"; + //Generated from matlab code with same parameters and inputs + std::vector true_vec{3.141592277589793e+02, + 8.941907747838389e-01, + 1.846733023014284e+00, + 3.141592277589793e+02, + 1.014543000000000e+02, + -1.507680000000000e+01, + 3.787993500000000e+02, + -1.300000000000000e+00, + 2.899095146477517e+02, + 2.939138495559215e+02, + 1.507210571826699e+07, + 1.659799832843673e+07, + -7.591593003913325e+03, + -8.376991073310774e+03, + 3.337988298081817e+03, + 2.684419146397466e+03}; + + std::cout << "Test the Relative Error\n"; + for (size_t i = 0; i < true_vec.size(); i++) + { + printf("%e ,\n", (true_vec[i] - dg->getResidual()[i]) / true_vec[i]); + } + return 0; } diff --git a/Examples/Microgrid/CMakeLists.txt b/Examples/Microgrid/CMakeLists.txt new file mode 100644 index 000000000..0958144c4 --- /dev/null +++ b/Examples/Microgrid/CMakeLists.txt @@ -0,0 +1,13 @@ + + + + +add_executable(microgrid Microgrid.cpp) +target_link_libraries(microgrid GRIDKIT::powerelec_disgen + GRIDKIT::powerelec_mircoline + GRIDKIT::powerelec_microload + GRIDKIT::solvers_dyn + GRIDKIT::powerelec_mircobusdq) + +add_test(NAME Microgrid COMMAND $) +install(TARGETS microgrid RUNTIME DESTINATION bin) diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp new file mode 100644 index 000000000..a0cf8dc9b --- /dev/null +++ b/Examples/Microgrid/Microgrid.cpp @@ -0,0 +1,361 @@ + + +#include +#include +#include +#include +#include + + +#include +#include +#include +#include + +#include +#include +#include + + +int main(int argc, char const *argv[]) +{ + double abstol = 1.0e-4; + double reltol = 1.0e-4; + bool usejac = true; + + //TODO:setup as named parameters + //Create circuit model + ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac); + + //Modeled after the problem in the paper + double RN = 1.0e4; + + //DG Params + + ModelLib::DiscreteGeneratorParameters parms1; + parms1.wb = 2.0*M_PI*50.0; + parms1.wc = 31.41; + parms1.mp = 9.4e-5; + parms1.Vn = 380; + parms1.nq = 1.3e-3; + parms1.F = 0.75; + parms1.Kiv = 420.0; + parms1.Kpv = 0.1; + parms1.Kic = 20.0 * 1.0e3; + parms1.Kpc = 15.0; + parms1.Cf = 50.0e-6; + parms1.rLf = 0.1; + parms1.Lf = 1.35e-3; + parms1.rLc = 0.03; + parms1.Lc = 0.35e-3; + + ModelLib::DiscreteGeneratorParameters parms2; + //Parameters from MATLAB Microgrid code for first DG + parms2.wb = 2.0*M_PI*50.0; + parms2.wc = 31.41; + parms2.mp = 12.5e-5; + parms2.Vn = 380; + parms2.nq = 1.5e-3; + parms2.F = 0.75; + parms2.Kiv = 390.0; + parms2.Kpv = 0.05; + parms2.Kic = 16.0 * 1.0e3; + parms2.Kpc = 10.5; + parms2.Cf = 50.0e-6; + parms2.rLf = 0.1; + parms2.Lf = 1.35e-3; + parms2.rLc = 0.03; + parms2.Lc = 0.35e-3; + + //Line params + double rline1 = 0.23; + double Lline1 = 0.1 / (2.0 * M_PI * 50.0); + + double rline2 = 0.35; + double Lline2 = 0.58 / (2.0 * M_PI * 50.0); + + double rline3 = 0.23; + double Lline3 = 0.1 / (2.0 * M_PI * 50.0); + + //load parms + double rload1 = 3.0; + double Lload1 = 2.0 / (2.0 * M_PI * 50.0); + + double rload2 = 2.0; + double Lload2 = 1.0 / (2.0 * M_PI * 50.0); + + + //indexing sets + size_t Nsize = 2; + // DGs + Lines + Loads + size_t vec_size_internals = 13*(2*Nsize) + (2 + 4*(Nsize - 1)) + 2*Nsize; + // \omegaref + BusDQ + size_t vec_size_externals = 1 + 2*(2*Nsize); + size_t dqbus1 = vec_size_externals + 1; + size_t dqbus2 = vec_size_externals + 3; + size_t dqbus3 = vec_size_externals + 5; + size_t dqbus4 = vec_size_externals + 7; + + size_t vec_size_total = vec_size_internals + vec_size_externals; + + + size_t indexv = 0; + + //dg 1 + ModelLib::DiscreteGenerator *dg1 = new ModelLib::DiscreteGenerator(0, parms1, true); + //ref motor + dg1->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg1->setExternalConnectionNodes(1,dqbus1); + dg1->setExternalConnectionNodes(2,dqbus1 + 1); + //internal connections + for (size_t i = 0; i < 13; i++) + { + + dg1->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg1); + + //dg 2 + ModelLib::DiscreteGenerator *dg2 = new ModelLib::DiscreteGenerator(1, parms1, false); + //ref motor + dg2->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg2->setExternalConnectionNodes(1,dqbus2); + dg2->setExternalConnectionNodes(2,dqbus2 + 1); + //internal connections + for (size_t i = 0; i < 13; i++) + { + + dg2->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg2); + + + //dg 3 + ModelLib::DiscreteGenerator *dg3 = new ModelLib::DiscreteGenerator(2, parms2, false); + //ref motor + dg3->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg3->setExternalConnectionNodes(1,dqbus3); + dg3->setExternalConnectionNodes(2,dqbus3 + 1); + //internal connections + for (size_t i = 0; i < 13; i++) + { + + dg3->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg3); + + + //dg 4 + ModelLib::DiscreteGenerator *dg4 = new ModelLib::DiscreteGenerator(3, parms2, false); + //ref motor + dg4->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg4->setExternalConnectionNodes(1,dqbus4); + dg4->setExternalConnectionNodes(2,dqbus4 + 1); + + //internal connections + for (size_t i = 0; i < 13; i++) + { + + dg4->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg4); + + // Lines + + //line 1 + ModelLib::MicrogridLine *l1 = new ModelLib::MicrogridLine(4, rline1, Lline1); + //ref motor + l1->setExternalConnectionNodes(0,vec_size_internals); + //input connections + l1->setExternalConnectionNodes(1,dqbus1); + l1->setExternalConnectionNodes(2,dqbus1 + 1); + //output connections + l1->setExternalConnectionNodes(3,dqbus2); + l1->setExternalConnectionNodes(4,dqbus2 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + l1->setExternalConnectionNodes(5 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(l1); + + + //line 2 + ModelLib::MicrogridLine *l2 = new ModelLib::MicrogridLine(5, rline2, Lline2); + //ref motor + l2->setExternalConnectionNodes(0,vec_size_internals); + //input connections + l2->setExternalConnectionNodes(1,dqbus2); + l2->setExternalConnectionNodes(2,dqbus2 + 1); + //output connections + l2->setExternalConnectionNodes(3,dqbus3); + l2->setExternalConnectionNodes(4,dqbus3 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + l2->setExternalConnectionNodes(5 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(l2); + + //line 3 + ModelLib::MicrogridLine *l3 = new ModelLib::MicrogridLine(6, rline3, Lline3); + //ref motor + l3->setExternalConnectionNodes(0,vec_size_internals); + //input connections + l3->setExternalConnectionNodes(1,dqbus3); + l3->setExternalConnectionNodes(2,dqbus3 + 1); + //output connections + l3->setExternalConnectionNodes(3,dqbus4); + l3->setExternalConnectionNodes(4,dqbus4 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + l3->setExternalConnectionNodes(5 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(l3); + + // loads + + //load 1 + ModelLib::MicrogridLoad *load1 = new ModelLib::MicrogridLoad(7, rload1, Lload1); + //ref motor + load1->setExternalConnectionNodes(0,vec_size_internals); + //input connections + load1->setExternalConnectionNodes(1,dqbus1); + load1->setExternalConnectionNodes(2,dqbus1 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + load1->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(load1); + + //load 2 + ModelLib::MicrogridLoad *load2 = new ModelLib::MicrogridLoad(8, rload2, Lload2); + //ref motor + load2->setExternalConnectionNodes(0,vec_size_internals); + //input connections + load2->setExternalConnectionNodes(1,dqbus3); + load2->setExternalConnectionNodes(2,dqbus3 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + load2->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(load2); + + //Virtual PQ Buses + ModelLib::MicrogridBusDQ *bus1 = new ModelLib::MicrogridBusDQ(9, RN); + + bus1->setExternalConnectionNodes(0,dqbus1); + bus1->setExternalConnectionNodes(1,dqbus1 + 1); + sysmodel->addComponent(bus1); + + ModelLib::MicrogridBusDQ *bus2 = new ModelLib::MicrogridBusDQ(10, RN); + + bus2->setExternalConnectionNodes(0,dqbus2); + bus2->setExternalConnectionNodes(1,dqbus2 + 1); + sysmodel->addComponent(bus2); + + ModelLib::MicrogridBusDQ *bus3 = new ModelLib::MicrogridBusDQ(11, RN); + + bus3->setExternalConnectionNodes(0,dqbus3); + bus3->setExternalConnectionNodes(1,dqbus3 + 1); + sysmodel->addComponent(bus3); + + ModelLib::MicrogridBusDQ *bus4 = new ModelLib::MicrogridBusDQ(12, RN); + + bus4->setExternalConnectionNodes(0,dqbus4); + bus4->setExternalConnectionNodes(1,dqbus4 + 1); + sysmodel->addComponent(bus4); + + sysmodel->allocate(vec_size_total); + + std::cout << sysmodel->y().size() << std::endl; + std::cout << vec_size_internals << ", " << vec_size_externals << "\n"; + + //Create Intial points for states + for (size_t i = 0; i < vec_size_total; i++) + { + sysmodel->y()[i] = 0.0; + sysmodel->yp()[i] = 0.0; + } + + // Create Intial derivatives specifics generated in MATLAB + //DGs + for (size_t i = 0; i < 2; i++) + { + sysmodel->yp()[13*i + 3] = parms1.Vn; + sysmodel->yp()[13*i + 5] = parms1.Kpv * parms1.Vn; + sysmodel->yp()[13*i + 7] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; + } + for (size_t i = 2; i < 4; i++) + { + sysmodel->yp()[13*i + 3] = parms2.Vn; + sysmodel->yp()[13*i + 5] = parms2.Kpv * parms2.Vn; + sysmodel->yp()[13*i + 7] = (parms2.Kpc * parms2.Kpv * parms2.Vn) / parms2.Lf; + } + + //since the intial P_com = 0 + sysmodel->y()[62] = parms1.wb; + + + + sysmodel->initialize(); + sysmodel->evaluateResidual(); + + std::vector& fres = sysmodel->getResidual(); + std::cout << "Verify Intial Resisdual is Zero: {\n"; + for (size_t i = 0; i < fres.size(); i++) + { + printf("%u : %e \n", i, fres[i]); + } + std::cout << "}\n"; + + sysmodel->updateTime(0.0, 1.0e-8); + sysmodel->evaluateJacobian(); + std::cout << "Intial Jacobian with alpha:\n"; + // std::cout << sysmodel->getJacobian().frobnorm() << "\n"; + + + // //Create numerical integrator and configure it for the generator model + // AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); + + // double t_init = 0.0; + // double t_final = 1.0; + + // // setup simulation + // idas->configureSimulation(); + // idas->getDefaultInitialCondition(); + // idas->initializeSimulation(t_init); + + // idas->runSimulation(t_final); + + // std::vector& yfinial = sysmodel->y(); + + // std::cout << "Final Vector y\n"; + // for (size_t i = 0; i < yfinial.size(); i++) + // { + // std::cout << yfinial[i] << "\n"; + // } + + return 0; +} diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp index e902b1242..55fe476b9 100644 --- a/Examples/RLCircuit/RLCircuit.cpp +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -18,8 +18,8 @@ int main(int argc, char const *argv[]) { - double abstol = 1e-8; - double reltol = 1e-8; + double abstol = 1.0e-8; + double reltol = 1.0e-8; bool usejac = true; //TODO:setup as named parameters @@ -132,9 +132,9 @@ int main(int argc, char const *argv[]) //analytical solution to the circuit yexact[0] = vinit; - yexact[2] = (-vinit / rinit) * (exp((rinit / linit) * t_final) - 1.0); + yexact[2] = (vinit / rinit) * (exp(-(rinit / linit) * t_final) - 1.0); yexact[3] = yexact[2]; - yexact[1] = vinit - rinit * yexact[2]; + yexact[1] = vinit + rinit * yexact[2]; std::cout << "Element-wise Relative error at t=" << t_final << "\n"; for (size_t i = 0; i < yfinial.size(); i++) diff --git a/SparseMatrix/COO_Matrix.hpp b/SparseMatrix/COO_Matrix.hpp index c256e015c..716748fa8 100644 --- a/SparseMatrix/COO_Matrix.hpp +++ b/SparseMatrix/COO_Matrix.hpp @@ -50,6 +50,7 @@ class COO_Matrix void AXPY(ScalarT alpha, COO_Matrix& a); void AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v); void SCAL(ScalarT alpha); + ScalarT frobnorm(); // --- Permutation Operations --- //No sorting is actually done. Only done when nesscary @@ -391,6 +392,14 @@ inline void COO_Matrix::SCAL(ScalarT alpha) for (auto i = this->values.begin(); i < this->values.end(); i++) *i *= alpha; } +template +inline ScalarT COO_Matrix::frobnorm() +{ + ScalarT totsum = 0.0; + for (auto i = this->values.begin(); i < this->values.end(); i++) totsum += abs(*i)^2; + return totsum; +} + /** * @brief Permutate the matrix to a different one. Only changes the coordinates * From 1aa8865e43eac65425baa14b61385ff0a56dd063 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Mon, 19 Feb 2024 18:53:44 -0500 Subject: [PATCH 08/44] Working Microgrid (Finite Difference) - "grounded" the rotor difference in reference - Comparing agianst reference from MATLAB --- Examples/Microgrid/Microgrid.cpp | 168 +++++++++++++++++++++++-------- Solver/Dynamic/Ida.cpp | 6 +- 2 files changed, 130 insertions(+), 44 deletions(-) diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp index a0cf8dc9b..5f788080a 100644 --- a/Examples/Microgrid/Microgrid.cpp +++ b/Examples/Microgrid/Microgrid.cpp @@ -19,9 +19,9 @@ int main(int argc, char const *argv[]) { - double abstol = 1.0e-4; - double reltol = 1.0e-4; - bool usejac = true; + double abstol = 1.0e-8; + double reltol = 1.0e-8; + bool usejac = false; //TODO:setup as named parameters //Create circuit model @@ -36,14 +36,14 @@ int main(int argc, char const *argv[]) parms1.wb = 2.0*M_PI*50.0; parms1.wc = 31.41; parms1.mp = 9.4e-5; - parms1.Vn = 380; + parms1.Vn = 380.0; parms1.nq = 1.3e-3; parms1.F = 0.75; parms1.Kiv = 420.0; parms1.Kpv = 0.1; - parms1.Kic = 20.0 * 1.0e3; + parms1.Kic = 2.0e4; parms1.Kpc = 15.0; - parms1.Cf = 50.0e-6; + parms1.Cf = 5.0e-5; parms1.rLf = 0.1; parms1.Lf = 1.35e-3; parms1.rLc = 0.03; @@ -54,12 +54,12 @@ int main(int argc, char const *argv[]) parms2.wb = 2.0*M_PI*50.0; parms2.wc = 31.41; parms2.mp = 12.5e-5; - parms2.Vn = 380; + parms2.Vn = 380.0; parms2.nq = 1.5e-3; parms2.F = 0.75; parms2.Kiv = 390.0; parms2.Kpv = 0.05; - parms2.Kic = 16.0 * 1.0e3; + parms2.Kic = 16.0e3; parms2.Kpc = 10.5; parms2.Cf = 50.0e-6; parms2.rLf = 0.1; @@ -87,14 +87,14 @@ int main(int argc, char const *argv[]) //indexing sets size_t Nsize = 2; - // DGs + Lines + Loads - size_t vec_size_internals = 13*(2*Nsize) + (2 + 4*(Nsize - 1)) + 2*Nsize; + // DGs + - refframe Lines + Loads + size_t vec_size_internals = 13*(2*Nsize) - 1 + (2 + 4*(Nsize - 1)) + 2*Nsize; // \omegaref + BusDQ size_t vec_size_externals = 1 + 2*(2*Nsize); - size_t dqbus1 = vec_size_externals + 1; - size_t dqbus2 = vec_size_externals + 3; - size_t dqbus3 = vec_size_externals + 5; - size_t dqbus4 = vec_size_externals + 7; + size_t dqbus1 = vec_size_internals + 1; + size_t dqbus2 = vec_size_internals + 3; + size_t dqbus3 = vec_size_internals + 5; + size_t dqbus4 = vec_size_internals + 7; size_t vec_size_total = vec_size_internals + vec_size_externals; @@ -108,13 +108,15 @@ int main(int argc, char const *argv[]) //outputs dg1->setExternalConnectionNodes(1,dqbus1); dg1->setExternalConnectionNodes(2,dqbus1 + 1); + //"grounding" of the difference + dg1->setExternalConnectionNodes(3,-1); //internal connections - for (size_t i = 0; i < 13; i++) + for (size_t i = 0; i < 12; i++) { - dg1->setExternalConnectionNodes(3 + i,indexv + i); + dg1->setExternalConnectionNodes(4 + i,indexv + i); } - indexv += 13; + indexv += 12; sysmodel->addComponent(dg1); //dg 2 @@ -300,22 +302,22 @@ int main(int argc, char const *argv[]) } // Create Intial derivatives specifics generated in MATLAB - //DGs - for (size_t i = 0; i < 2; i++) - { - sysmodel->yp()[13*i + 3] = parms1.Vn; - sysmodel->yp()[13*i + 5] = parms1.Kpv * parms1.Vn; - sysmodel->yp()[13*i + 7] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; - } + //DGs 1 + sysmodel->yp()[2] = parms1.Vn; + sysmodel->yp()[4] = parms1.Kpv * parms1.Vn; + sysmodel->yp()[6] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; + sysmodel->yp()[12 + 3] = parms1.Vn; + sysmodel->yp()[12 + 5] = parms1.Kpv * parms1.Vn; + sysmodel->yp()[12 + 7] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; for (size_t i = 2; i < 4; i++) { - sysmodel->yp()[13*i + 3] = parms2.Vn; - sysmodel->yp()[13*i + 5] = parms2.Kpv * parms2.Vn; - sysmodel->yp()[13*i + 7] = (parms2.Kpc * parms2.Kpv * parms2.Vn) / parms2.Lf; + sysmodel->yp()[13*i - 1 + 3] = parms2.Vn; + sysmodel->yp()[13*i - 1 + 5] = parms2.Kpv * parms2.Vn; + sysmodel->yp()[13*i - 1 + 7] = (parms2.Kpc * parms2.Kpv * parms2.Vn) / parms2.Lf; } //since the intial P_com = 0 - sysmodel->y()[62] = parms1.wb; + sysmodel->y()[vec_size_internals] = parms1.wb; @@ -336,26 +338,106 @@ int main(int argc, char const *argv[]) // std::cout << sysmodel->getJacobian().frobnorm() << "\n"; - // //Create numerical integrator and configure it for the generator model - // AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); + //Create numerical integrator and configure it for the generator model + AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); + + double t_init = 0.0; + double t_final = 1.0; - // double t_init = 0.0; - // double t_final = 1.0; + // setup simulation + idas->configureSimulation(); + idas->getDefaultInitialCondition(); + idas->initializeSimulation(t_init); - // // setup simulation - // idas->configureSimulation(); - // idas->getDefaultInitialCondition(); - // idas->initializeSimulation(t_init); + idas->runSimulation(t_final); - // idas->runSimulation(t_final); + std::vector& yfinial = sysmodel->y(); - // std::vector& yfinial = sysmodel->y(); + std::cout << "Final Vector y\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << yfinial[i] << "\n"; + } - // std::cout << "Final Vector y\n"; - // for (size_t i = 0; i < yfinial.size(); i++) - // { - // std::cout << yfinial[i] << "\n"; - // } + //Generate from MATLAB code ODE form with tolerances of 1e-12 + std::vectortrue_vec{ + 2.297543153595780e+04, + 1.275311524125022e+04, + 3.763060183116022e-02, + -2.098153459325261e-02, + 1.848285659119097e-02, + -1.563291404944864e-04, + 6.321941907011718e+01, + -2.942264300846256e+01, + 3.634209302905854e+02, + -2.668928293656362e-06, + 6.321941919221522e+01, + -3.509200178595996e+01, + -7.555954467454730e-03, + 2.297580486511343e+04, + 8.742028429066131e+03, + 3.710079564796484e-02, + -1.421122598056797e-02, + 1.874079517807597e-02, + -9.891304812687215e-05, + 6.232933298360234e+01, + -1.796494061423331e+01, + 3.686353885026506e+02, + 3.465673854181523e-05, + 6.232933406188410e+01, + -2.371564475187742e+01, + -8.273939686941580e-02, + 1.727775042678524e+04, + 1.649365247247288e+04, + 3.116555157570849e-02, + -2.985990066758010e-02, + 2.250012115906506e-02, + -2.643873146501096e-04, + 4.861823510250247e+01, + -4.088592755441309e+01, + 3.552597163751238e+02, + -1.496407194199739e-04, + 4.861823504694532e+01, + -4.642797132602495e+01, + -8.445727984408551e-02, + 1.727723725566433e+04, + 9.182386962936238e+03, + 3.024959333190777e-02, + -1.617250828202081e-02, + 2.318056864131751e-02, + -1.295918667730514e-04, + 4.718938244522050e+01, + -1.935782085675469e+01, + 3.662262287803608e+02, + 1.076423957830039e-04, + 4.718938116520511e+01, + -2.507094256286497e+01, + -1.881248349415025e+01, + 2.114714832305742e+01, + 4.329946674909793e+01, + -3.037887936225145e+00, + -4.487023117352992e+01, + 2.895883729832657e+01, + 8.199613345691378e+01, + -5.623856502948122e+01, + 1.327498499660322e+02, + -8.228065162347022e+01, + 3.119995747945993e+02, + 3.576922945168803e+02, + -5.850795361581618e+00, + 3.641193316268954e+02, + -8.846325267612976e+00, + 3.472146752739036e+02, + -3.272400970143252e+01, + 3.604108939430972e+02, + -3.492842627398574e+01 + }; + + std::cout << "Test the Relative Error\n"; + for (size_t i = 0; i < true_vec.size(); i++) + { + printf("%u : %e ,\n", i, abs(true_vec[i] - yfinial[i]) / abs(true_vec[i])); + } return 0; } diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index 5137119f1..1bae455f1 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -134,6 +134,10 @@ namespace Sundials retval = IDASStolerances(solver_, rtol, atol); checkOutput(retval, "IDASStolerances"); + /// \todo Need to set max number of steps based on user input! + retval = IDASetMaxNumSteps(solver_, 5000); + checkOutput(retval, "IDASetMaxNumSteps"); + // Tag differential variables std::vector& tag = model_->tag(); if (static_cast(tag.size()) == model_->size()) @@ -415,7 +419,7 @@ namespace Sundials checkOutput(retval, "IDASetUserDataB"); /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumStepsB(solver_, backwardID_, 2000); + retval = IDASetMaxNumStepsB(solver_, backwardID_, 200); checkOutput(retval, "IDASetMaxNumSteps"); // Set up linear solver From 723c785609eecba5e2e4db85b9e9c36a49e6d946 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Thu, 22 Feb 2024 14:11:25 -0500 Subject: [PATCH 09/44] Fixed the Jacobian in Microgrid Example --- .../DiscreteGenerator/DiscreteGenerator.cpp | 5 +++-- Examples/Microgrid/Microgrid.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp index 607ec5312..038a24ea2 100644 --- a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp +++ b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp @@ -165,6 +165,7 @@ int DiscreteGenerator::evaluateResidual() template int DiscreteGenerator::evaluateJacobian() { + this->J_.zeroMatrix(); //Create dF/dy' std::vector rcordder(13); std::vector valsder(13, -1.0); @@ -186,7 +187,7 @@ int DiscreteGenerator::evaluateJacobian() ctemp = {3, 14, 15}; rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(1); - valtemp = { - sin(y_[3]) * y_[14] - cos(y_[3]) * y_[15], cos(y_[3]),sin(y_[3])}; + valtemp = { - sin(y_[3]) * y_[14] - cos(y_[3]) * y_[15], cos(y_[3]),-sin(y_[3])}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 2 @@ -194,7 +195,7 @@ int DiscreteGenerator::evaluateJacobian() ctemp = {3, 14, 15}; rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(2); - valtemp = { - cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15], -sin(y_[3]),cos(y_[3])}; + valtemp = { cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15], sin(y_[3]),cos(y_[3])}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 3 diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp index 5f788080a..dddd4f291 100644 --- a/Examples/Microgrid/Microgrid.cpp +++ b/Examples/Microgrid/Microgrid.cpp @@ -21,7 +21,7 @@ int main(int argc, char const *argv[]) { double abstol = 1.0e-8; double reltol = 1.0e-8; - bool usejac = false; + bool usejac = true; //TODO:setup as named parameters //Create circuit model From a3e5af89f4ef8c5e6c95addb4bf56aab37fe3f01 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Thu, 22 Feb 2024 14:26:46 -0500 Subject: [PATCH 10/44] Added a max step size control for model objects --- Examples/Microgrid/Microgrid.cpp | 3 ++- ModelEvaluator.hpp | 1 + ModelEvaluatorImpl.hpp | 7 +++++++ PowerElectronicsModel.hpp | 7 +++++-- Solver/Dynamic/Ida.cpp | 5 ++++- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp index dddd4f291..acc8be386 100644 --- a/Examples/Microgrid/Microgrid.cpp +++ b/Examples/Microgrid/Microgrid.cpp @@ -21,11 +21,12 @@ int main(int argc, char const *argv[]) { double abstol = 1.0e-8; double reltol = 1.0e-8; + size_t max_step_amount = 3000; bool usejac = true; //TODO:setup as named parameters //Create circuit model - ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac); + ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac, max_step_amount); //Modeled after the problem in the paper double RN = 1.0e4; diff --git a/ModelEvaluator.hpp b/ModelEvaluator.hpp index 50c5e8b77..ad56fbd48 100644 --- a/ModelEvaluator.hpp +++ b/ModelEvaluator.hpp @@ -107,6 +107,7 @@ namespace ModelLib virtual IdxT size_opt() = 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; diff --git a/ModelEvaluatorImpl.hpp b/ModelEvaluatorImpl.hpp index 928d26f30..0f8969f0b 100644 --- a/ModelEvaluatorImpl.hpp +++ b/ModelEvaluatorImpl.hpp @@ -139,6 +139,11 @@ namespace ModelLib atol = atol_; } + virtual void setMaxSteps(IdxT& msa) const + { + msa = max_steps_; + } + std::vector& y() { return y_; @@ -306,6 +311,8 @@ namespace ModelLib real_type rtol_; real_type atol_; + IdxT max_steps_; + IdxT idc_; }; diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index 47efcc7f7..04508607f 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -50,18 +50,21 @@ class PowerElectronicsModel : public ModelEvaluatorImpl // Set system model tolerances as default rtol_ = 1e-4; atol_ = 1e-4; + this->max_steps_ = 2000; // By default use jacobian - usejac_ = true; + usejac_ = false; + } /** * @brief Constructor for the system model */ - PowerElectronicsModel(double rt, double at, bool ju) : ModelEvaluatorImpl(0, 0, 0) + PowerElectronicsModel(double rt=1e-4, double at=1e-4, bool ju=false, IdxT msa=2000) : ModelEvaluatorImpl(0, 0, 0) { // Set system model tolerances from input rtol_ = rt; atol_ = at; + this->max_steps_ = msa; // Can choose not to use jacobain usejac_ = ju; } diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index 1bae455f1..2be2913a9 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -133,9 +133,12 @@ namespace Sundials model_->setTolerances(rtol, atol); ///< \todo Function name should be "getTolerances"! retval = IDASStolerances(solver_, rtol, atol); checkOutput(retval, "IDASStolerances"); + + IdxT msa; + model_->setMaxSteps(msa); /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumSteps(solver_, 5000); + retval = IDASetMaxNumSteps(solver_, msa); checkOutput(retval, "IDASetMaxNumSteps"); // Tag differential variables From c3f071e04ff0168268f34e3314f77219e53e48ba Mon Sep 17 00:00:00 2001 From: Reid Date: Tue, 12 Mar 2024 11:50:38 -0400 Subject: [PATCH 11/44] Update Solver/Dynamic/CMakeLists.txt Co-authored-by: pelesh --- Solver/Dynamic/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Solver/Dynamic/CMakeLists.txt b/Solver/Dynamic/CMakeLists.txt index 85c7ea920..ab38756c5 100644 --- a/Solver/Dynamic/CMakeLists.txt +++ b/Solver/Dynamic/CMakeLists.txt @@ -67,10 +67,6 @@ gridkit_add_library(solvers_dyn PUBLIC SUNDIALS::nvecserial PUBLIC SUNDIALS::idas PUBLIC SUNDIALS::sunlinsolklu - PUBLIC suitesparseconfig - PUBLIC klu - PUBLIC amd - PUBLIC colamd OUTPUT_NAME gridkit_solvers_dyn) From 7be79c700b006c2e6ad88d74896041db9d47112e Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Tue, 12 Mar 2024 12:47:37 -0400 Subject: [PATCH 12/44] Updated name DiscreteGenerator -> DistributedGenerator - Updated name of generator - Some formatting updates --- .../PowerElectronicsComponents/CMakeLists.txt | 2 +- .../CMakeLists.txt | 2 +- .../DistributedGenerator.cpp} | 30 +- .../DistributedGenerator.hpp} | 10 +- .../MicrogridLine/MicrogridLine.hpp | 13 +- Examples/CMakeLists.txt | 2 +- .../CMakeLists.txt | 2 +- .../DGTest.cpp | 6 +- Examples/Microgrid/Microgrid.cpp | 14 +- ModelEvaluatorImpl.hpp | 99 +- PowerElectronicsModel.hpp | 532 ++++---- Solver/Dynamic/Ida.cpp | 1075 ++++++++--------- 12 files changed, 882 insertions(+), 905 deletions(-) rename ComponentLib/PowerElectronicsComponents/{DiscreteGenerator => DistributedGenerator}/CMakeLists.txt (76%) rename ComponentLib/PowerElectronicsComponents/{DiscreteGenerator/DiscreteGenerator.cpp => DistributedGenerator/DistributedGenerator.cpp} (92%) rename ComponentLib/PowerElectronicsComponents/{DiscreteGenerator/DiscreteGenerator.hpp => DistributedGenerator/DistributedGenerator.hpp} (87%) rename Examples/{DiscreteGeneratorTest => DistributedGeneratorTest}/CMakeLists.txt (77%) rename Examples/{DiscreteGeneratorTest => DistributedGeneratorTest}/DGTest.cpp (84%) diff --git a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt index 3fba4be7f..2cfe97bc2 100644 --- a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt +++ b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt @@ -7,7 +7,7 @@ add_subdirectory(Inductor) add_subdirectory(LinearTransformer) add_subdirectory(InductionMotor) add_subdirectory(SynchronousMachine) -add_subdirectory(DiscreteGenerator) +add_subdirectory(DistributedGenerator) add_subdirectory(TransmissionLine) add_subdirectory(MicrogridLoad) add_subdirectory(MicrogridLine) diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/CMakeLists.txt similarity index 76% rename from ComponentLib/PowerElectronicsComponents/DiscreteGenerator/CMakeLists.txt rename to ComponentLib/PowerElectronicsComponents/DistributedGenerator/CMakeLists.txt index c0ed2c7a9..22652f53b 100644 --- a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/CMakeLists.txt +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/CMakeLists.txt @@ -3,6 +3,6 @@ gridkit_add_library(powerelec_disgen SOURCES - DiscreteGenerator.cpp + DistributedGenerator.cpp OUTPUT_NAME gridkit_powerelec_disgen) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp similarity index 92% rename from ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp rename to ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp index 038a24ea2..d8d424b62 100644 --- a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp @@ -4,7 +4,7 @@ #include #include #include -#include "DiscreteGenerator.hpp" +#include "DistributedGenerator.hpp" namespace ModelLib { @@ -17,7 +17,7 @@ namespace ModelLib { */ template -DiscreteGenerator::DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm, bool reference_frame) +DistributedGenerator::DistributedGenerator(IdxT id, DistributedGeneratorParameters parm, bool reference_frame) : wb_(parm.wb), wc_(parm.wc), mp_(parm.mp), Vn_(parm.Vn), nq_(parm.nq), F_(parm.F), Kiv_(parm.Kiv), Kpv_(parm.Kpv), Kic_(parm.Kic), Kpc_(parm.Kpc), Cf_(parm.Cf), rLf_(parm.rLf), Lf_(parm.Lf), rLc_(parm.rLc), Lc_(parm.Lc), refframe_(reference_frame) { // internals [\delta_i, Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi] @@ -30,7 +30,7 @@ DiscreteGenerator::DiscreteGenerator(IdxT id, DiscreteGeneratorPa } template -DiscreteGenerator::~DiscreteGenerator() +DistributedGenerator::~DistributedGenerator() { } @@ -38,7 +38,7 @@ DiscreteGenerator::~DiscreteGenerator() * @brief allocate method computes sparsity pattern of the Jacobian. */ template -int DiscreteGenerator::allocate() +int DistributedGenerator::allocate() { this->y_.resize(this->size_); this->yp_.resize(this->size_); @@ -51,7 +51,7 @@ int DiscreteGenerator::allocate() * Initialization of the grid model */ template -int DiscreteGenerator::initialize() +int DistributedGenerator::initialize() { return 0; } @@ -60,7 +60,7 @@ int DiscreteGenerator::initialize() * \brief Identify differential variables */ template -int DiscreteGenerator::tagDifferentiable() +int DistributedGenerator::tagDifferentiable() { return 0; } @@ -71,7 +71,7 @@ int DiscreteGenerator::tagDifferentiable() * Must be connected to a PQ bus. */ template -int DiscreteGenerator::evaluateResidual() +int DistributedGenerator::evaluateResidual() { // ### Externals Componenets ### @@ -136,7 +136,7 @@ int DiscreteGenerator::evaluateResidual() } /** - * @brief Compute the jacobian of the DiscreteGenerator for iteration. dF/dy - \alpha dF/dy' + * @brief Compute the jacobian of the DistributedGenerator for iteration. dF/dy - \alpha dF/dy' * * The matrix dF/dy should be * @@ -163,7 +163,7 @@ int DiscreteGenerator::evaluateResidual() * @return int */ template -int DiscreteGenerator::evaluateJacobian() +int DistributedGenerator::evaluateJacobian() { this->J_.zeroMatrix(); //Create dF/dy' @@ -313,25 +313,25 @@ int DiscreteGenerator::evaluateJacobian() } template -int DiscreteGenerator::evaluateIntegrand() +int DistributedGenerator::evaluateIntegrand() { return 0; } template -int DiscreteGenerator::initializeAdjoint() +int DistributedGenerator::initializeAdjoint() { return 0; } template -int DiscreteGenerator::evaluateAdjointResidual() +int DistributedGenerator::evaluateAdjointResidual() { return 0; } template -int DiscreteGenerator::evaluateAdjointIntegrand() +int DistributedGenerator::evaluateAdjointIntegrand() { return 0; } @@ -340,8 +340,8 @@ int DiscreteGenerator::evaluateAdjointIntegrand() // Available template instantiations -template class DiscreteGenerator; -template class DiscreteGenerator; +template class DistributedGenerator; +template class DistributedGenerator; } //namespace ModelLib diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp similarity index 87% rename from ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp rename to ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp index bca984460..94b297a55 100644 --- a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp @@ -13,7 +13,7 @@ namespace ModelLib template class BaseBus; template - struct DiscreteGeneratorParameters + struct DistributedGeneratorParameters { ScalarT wb; ScalarT wc; @@ -37,11 +37,11 @@ namespace ModelLib namespace ModelLib { /*! - * @brief Declaration of a passive DiscreteGenerator class. + * @brief Declaration of a passive DistributedGenerator class. * */ template - class DiscreteGenerator : public CircuitComponent + class DistributedGenerator : public CircuitComponent { using CircuitComponent::size_; using CircuitComponent::nnz_; @@ -62,8 +62,8 @@ namespace ModelLib public: - DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm, bool reference_frame); - virtual ~DiscreteGenerator(); + DistributedGenerator(IdxT id, DistributedGeneratorParameters parm, bool reference_frame); + virtual ~DistributedGenerator(); int allocate(); int initialize(); diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp index 11ef78617..bc683045a 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp @@ -7,20 +7,19 @@ #include #include - namespace ModelLib { - template class BaseBus; + template + class BaseBus; } - namespace ModelLib { /*! * @brief Declaration of a passive MicrogridLine class. * */ - template + template class MicrogridLine : public CircuitComponent { using CircuitComponent::size_; @@ -40,7 +39,6 @@ namespace ModelLib using CircuitComponent::param_; using CircuitComponent::idc_; - public: MicrogridLine(IdxT id, ScalarT R, ScalarT L); virtual ~MicrogridLine(); @@ -54,12 +52,11 @@ namespace ModelLib int initializeAdjoint(); int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); + // int evaluateAdjointJacobian(); int evaluateAdjointIntegrand(); - private: - ScalarT R_; + ScalarT R_; ScalarT L_; }; } diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index 2c53fcc25..0965f5688 100644 --- a/Examples/CMakeLists.txt +++ b/Examples/CMakeLists.txt @@ -59,7 +59,7 @@ add_subdirectory(MatPowerTesting) add_subdirectory(RLCircuit) add_subdirectory(Microgrid) add_subdirectory(SparseTest) -add_subdirectory(DiscreteGeneratorTest) +add_subdirectory(DistributedGeneratorTest) if(TARGET SUNDIALS::kinsol) add_subdirectory(Grid3Bus) diff --git a/Examples/DiscreteGeneratorTest/CMakeLists.txt b/Examples/DistributedGeneratorTest/CMakeLists.txt similarity index 77% rename from Examples/DiscreteGeneratorTest/CMakeLists.txt rename to Examples/DistributedGeneratorTest/CMakeLists.txt index 9238fb346..d158e4c58 100644 --- a/Examples/DiscreteGeneratorTest/CMakeLists.txt +++ b/Examples/DistributedGeneratorTest/CMakeLists.txt @@ -8,5 +8,5 @@ target_link_libraries(dgtest GRIDKIT::powerelec_disgen GRIDKIT::powerelec_microload GRIDKIT::solvers_dyn) -add_test(NAME DiscreteGeneratorTest COMMAND $) +add_test(NAME DistributedGeneratorTest COMMAND $) install(TARGETS dgtest RUNTIME DESTINATION bin) diff --git a/Examples/DiscreteGeneratorTest/DGTest.cpp b/Examples/DistributedGeneratorTest/DGTest.cpp similarity index 84% rename from Examples/DiscreteGeneratorTest/DGTest.cpp rename to Examples/DistributedGeneratorTest/DGTest.cpp index d3dd2c68b..8d682e88c 100644 --- a/Examples/DiscreteGeneratorTest/DGTest.cpp +++ b/Examples/DistributedGeneratorTest/DGTest.cpp @@ -7,13 +7,13 @@ #include #include -#include +#include int main(int argc, char const *argv[]) { - ModelLib::DiscreteGeneratorParameters parms; + ModelLib::DistributedGeneratorParameters parms; //Parameters from MATLAB Microgrid code for first DG parms.wb = 2.0*M_PI*50.0; parms.wc = 31.41; @@ -31,7 +31,7 @@ int main(int argc, char const *argv[]) parms.rLc = 0.03; parms.Lc = 0.35e-3; - ModelLib::DiscreteGenerator *dg = new ModelLib::DiscreteGenerator(0, parms, true); + ModelLib::DistributedGenerator *dg = new ModelLib::DistributedGenerator(0, parms, true); std::vector t1(16,0.0); std::vector t2{0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,1.3,1.4,1.5}; diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp index acc8be386..b263495ad 100644 --- a/Examples/Microgrid/Microgrid.cpp +++ b/Examples/Microgrid/Microgrid.cpp @@ -7,7 +7,7 @@ #include -#include +#include #include #include #include @@ -33,7 +33,7 @@ int main(int argc, char const *argv[]) //DG Params - ModelLib::DiscreteGeneratorParameters parms1; + ModelLib::DistributedGeneratorParameters parms1; parms1.wb = 2.0*M_PI*50.0; parms1.wc = 31.41; parms1.mp = 9.4e-5; @@ -50,7 +50,7 @@ int main(int argc, char const *argv[]) parms1.rLc = 0.03; parms1.Lc = 0.35e-3; - ModelLib::DiscreteGeneratorParameters parms2; + ModelLib::DistributedGeneratorParameters parms2; //Parameters from MATLAB Microgrid code for first DG parms2.wb = 2.0*M_PI*50.0; parms2.wc = 31.41; @@ -103,7 +103,7 @@ int main(int argc, char const *argv[]) size_t indexv = 0; //dg 1 - ModelLib::DiscreteGenerator *dg1 = new ModelLib::DiscreteGenerator(0, parms1, true); + ModelLib::DistributedGenerator *dg1 = new ModelLib::DistributedGenerator(0, parms1, true); //ref motor dg1->setExternalConnectionNodes(0,vec_size_internals); //outputs @@ -121,7 +121,7 @@ int main(int argc, char const *argv[]) sysmodel->addComponent(dg1); //dg 2 - ModelLib::DiscreteGenerator *dg2 = new ModelLib::DiscreteGenerator(1, parms1, false); + ModelLib::DistributedGenerator *dg2 = new ModelLib::DistributedGenerator(1, parms1, false); //ref motor dg2->setExternalConnectionNodes(0,vec_size_internals); //outputs @@ -138,7 +138,7 @@ int main(int argc, char const *argv[]) //dg 3 - ModelLib::DiscreteGenerator *dg3 = new ModelLib::DiscreteGenerator(2, parms2, false); + ModelLib::DistributedGenerator *dg3 = new ModelLib::DistributedGenerator(2, parms2, false); //ref motor dg3->setExternalConnectionNodes(0,vec_size_internals); //outputs @@ -155,7 +155,7 @@ int main(int argc, char const *argv[]) //dg 4 - ModelLib::DiscreteGenerator *dg4 = new ModelLib::DiscreteGenerator(3, parms2, false); + ModelLib::DistributedGenerator *dg4 = new ModelLib::DistributedGenerator(3, parms2, false); //ref motor dg4->setExternalConnectionNodes(0,vec_size_internals); //outputs diff --git a/ModelEvaluatorImpl.hpp b/ModelEvaluatorImpl.hpp index 0f8969f0b..3e9a4cef6 100644 --- a/ModelEvaluatorImpl.hpp +++ b/ModelEvaluatorImpl.hpp @@ -77,27 +77,28 @@ namespace ModelLib typedef typename ModelEvaluator::real_type real_type; ModelEvaluatorImpl() - : size_(0), - size_quad_(0), - size_opt_(0) - {} + : size_(0), + size_quad_(0), + size_opt_(0) + { + } ModelEvaluatorImpl(IdxT size, IdxT size_quad, IdxT size_opt) - : size_(size), - size_quad_(size_quad), - size_opt_(size_opt), - y_(size_), - yp_(size_), - f_(size_), - g_(size_quad_), - yB_(size_), - ypB_(size_), - fB_(size_), - gB_(size_opt_), - J_(COO_Matrix()), - param_(size_opt_), - param_up_(size_opt_), - param_lo_(size_opt_) + : size_(size), + size_quad_(size_quad), + size_opt_(size_opt), + y_(size_), + yp_(size_), + f_(size_), + g_(size_quad_), + yB_(size_), + ypB_(size_), + fB_(size_), + gB_(size_opt_), + J_(COO_Matrix()), + param_(size_opt_), + param_up_(size_opt_), + param_lo_(size_opt_) { } @@ -133,143 +134,143 @@ namespace ModelLib // std::cout << "updateTime: t = " << time_ << "\n"; // } - virtual void setTolerances(real_type& rtol, real_type& atol) const + virtual void setTolerances(real_type &rtol, real_type &atol) const { rtol = rtol_; atol = atol_; } - virtual void setMaxSteps(IdxT& msa) const + virtual void setMaxSteps(IdxT &msa) const { msa = max_steps_; } - std::vector& y() + std::vector &y() { return y_; } - const std::vector& y() const + const std::vector &y() const { return y_; } - std::vector& yp() + std::vector &yp() { return yp_; } - const std::vector& yp() const + const std::vector &yp() const { return yp_; } - std::vector& tag() + std::vector &tag() { return tag_; } - const std::vector& tag() const + const std::vector &tag() const { return tag_; } - std::vector& yB() + std::vector &yB() { return yB_; } - const std::vector& yB() const + const std::vector &yB() const { return yB_; } - std::vector& ypB() + std::vector &ypB() { return ypB_; } - const std::vector& ypB() const + const std::vector &ypB() const { return ypB_; } - std::vector& param() + std::vector ¶m() { return param_; } - const std::vector& param() const + const std::vector ¶m() const { return param_; } - std::vector& param_up() + std::vector ¶m_up() { return param_up_; } - const std::vector& param_up() const + const std::vector ¶m_up() const { return param_up_; } - std::vector& param_lo() + std::vector ¶m_lo() { return param_lo_; } - const std::vector& param_lo() const + const std::vector ¶m_lo() const { return param_lo_; } - std::vector& getResidual() + std::vector &getResidual() { return f_; } - const std::vector& getResidual() const + const std::vector &getResidual() const { return f_; } - COO_Matrix& getJacobian() + COO_Matrix &getJacobian() { return J_; } - const COO_Matrix& getJacobian() const + const COO_Matrix &getJacobian() const { return J_; } - std::vector& getIntegrand() + std::vector &getIntegrand() { return g_; } - const std::vector& getIntegrand() const + const std::vector &getIntegrand() const { return g_; } - std::vector& getAdjointResidual() + std::vector &getAdjointResidual() { return fB_; } - const std::vector& getAdjointResidual() const + const std::vector &getAdjointResidual() const { return fB_; } - std::vector& getAdjointIntegrand() + std::vector &getAdjointIntegrand() { return gB_; } - const std::vector& getAdjointIntegrand() const + const std::vector &getAdjointIntegrand() const { return gB_; } @@ -280,8 +281,6 @@ namespace ModelLib return idc_; } - - protected: IdxT size_; IdxT nnz_; @@ -314,10 +313,8 @@ namespace ModelLib IdxT max_steps_; IdxT idc_; - }; - } // namespace ModelLib #endif // _MODEL_EVALUATOR_IMPL_HPP_ \ No newline at end of file diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index 04508607f..d74b92cf0 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -14,318 +14,316 @@ namespace ModelLib { -template -class PowerElectronicsModel : public ModelEvaluatorImpl -{ - typedef CircuitComponent component_type; - - using ModelEvaluatorImpl::size_; - // using ModelEvaluatorImpl::size_quad_; - // using ModelEvaluatorImpl::size_opt_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::alpha_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::yp_; - // using ModelEvaluatorImpl::yB_; - // using ModelEvaluatorImpl::ypB_; - // using ModelEvaluatorImpl::tag_; - using ModelEvaluatorImpl::f_; - // using ModelEvaluatorImpl::fB_; - // using ModelEvaluatorImpl::g_; - // using ModelEvaluatorImpl::gB_; - using ModelEvaluatorImpl::J_; - using ModelEvaluatorImpl::rtol_; - using ModelEvaluatorImpl::atol_; - // using ModelEvaluatorImpl::param_; - // using ModelEvaluatorImpl::param_up_; - // using ModelEvaluatorImpl::param_lo_; - -public: - /** - * @brief Default constructor for the system model - */ - PowerElectronicsModel() : ModelEvaluatorImpl(0, 0, 0) - { - // Set system model tolerances as default - rtol_ = 1e-4; - atol_ = 1e-4; - this->max_steps_ = 2000; - // By default use jacobian - usejac_ = false; - - } - - /** - * @brief Constructor for the system model - */ - PowerElectronicsModel(double rt=1e-4, double at=1e-4, bool ju=false, IdxT msa=2000) : ModelEvaluatorImpl(0, 0, 0) - { - // Set system model tolerances from input - rtol_ = rt; - atol_ = at; - this->max_steps_ = msa; - // Can choose not to use jacobain - usejac_ = ju; - } - - /** - * @brief Destructor for the system model - */ - virtual ~PowerElectronicsModel() - { - for (auto comp : this->components_) delete comp; - } - - /** - * @brief allocator default - * - * @todo this should throw an exception as no allocation without a graph is allowed. Or needs to be removed from the base class - * - * @return int - */ - int allocate() - { - - return 1; - } - - /** - * @brief Will check if each component has jacobian avalible. If one doesn't then jacobain is false. - * - * - * @return true - * @return false - */ - bool hasJacobian() + template + class PowerElectronicsModel : public ModelEvaluatorImpl { - if (!this->usejac_) return false; - - for(const auto& component : components_) + typedef CircuitComponent component_type; + + using ModelEvaluatorImpl::size_; + // using ModelEvaluatorImpl::size_quad_; + // using ModelEvaluatorImpl::size_opt_; + using ModelEvaluatorImpl::nnz_; + using ModelEvaluatorImpl::time_; + using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::yp_; + // using ModelEvaluatorImpl::yB_; + // using ModelEvaluatorImpl::ypB_; + // using ModelEvaluatorImpl::tag_; + using ModelEvaluatorImpl::f_; + // using ModelEvaluatorImpl::fB_; + // using ModelEvaluatorImpl::g_; + // using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::J_; + using ModelEvaluatorImpl::rtol_; + using ModelEvaluatorImpl::atol_; + // using ModelEvaluatorImpl::param_; + // using ModelEvaluatorImpl::param_up_; + // using ModelEvaluatorImpl::param_lo_; + + public: + /** + * @brief Default constructor for the system model + */ + PowerElectronicsModel() : ModelEvaluatorImpl(0, 0, 0) { - if (!component->hasJacobian()) - { + // Set system model tolerances as default + rtol_ = 1e-4; + atol_ = 1e-4; + this->max_steps_ = 2000; + // By default use jacobian + usejac_ = false; + } + + /** + * @brief Constructor for the system model + */ + PowerElectronicsModel(double rt = 1e-4, double at = 1e-4, bool ju = false, IdxT msa = 2000) : ModelEvaluatorImpl(0, 0, 0) + { + // Set system model tolerances from input + rtol_ = rt; + atol_ = at; + this->max_steps_ = msa; + // Can choose not to use jacobain + usejac_ = ju; + } + + /** + * @brief Destructor for the system model + */ + virtual ~PowerElectronicsModel() + { + for (auto comp : this->components_) + delete comp; + } + + /** + * @brief allocator default + * + * @todo this should throw an exception as no allocation without a graph is allowed. Or needs to be removed from the base class + * + * @return int + */ + int allocate() + { + + return 1; + } + + /** + * @brief Will check if each component has jacobian avalible. If one doesn't then jacobain is false. + * + * + * @return true + * @return false + */ + bool hasJacobian() + { + if (!this->usejac_) return false; + + for (const auto &component : components_) + { + if (!component->hasJacobian()) + { + return false; + } } - + return true; } - return true; - } - - /** - * @brief Allocate the vector data with size amount - * @todo Add capability to go through component model connection to get the size of the actual vector - * - * @param s - * @return int - */ - int allocate(IdxT s) - { - // Allocate all components - this->size_ = s; - for(const auto& component : components_) + /** + * @brief Allocate the vector data with size amount + * @todo Add capability to go through component model connection to get the size of the actual vector + * + * @param s + * @return int + */ + int allocate(IdxT s) { - component->allocate(); - } - // Allocate global vectors - y_.resize(size_); - yp_.resize(size_); - f_.resize(size_); + // Allocate all components + this->size_ = s; + for (const auto &component : components_) + { + component->allocate(); + } - return 0; - } + // Allocate global vectors + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); - /** - * @brief Set intial y and y' of each component - * - * @return int - */ - int initialize() - { + return 0; + } - // Initialize components - for(const auto& component : components_) + /** + * @brief Set intial y and y' of each component + * + * @return int + */ + int initialize() { - component->initialize(); + + // Initialize components + for (const auto &component : components_) + { + component->initialize(); + } + this->distributeVectors(); + + return 0; } - this->distributeVectors(); - - return 0; - } - - /** - * @brief Distribute y and y' to each component based of node connection graph - * - * @return int - */ - int distributeVectors() - { - for(const auto& component : components_) + + /** + * @brief Distribute y and y' to each component based of node connection graph + * + * @return int + */ + int distributeVectors() { - for(IdxT j=0; jsize(); ++j) + for (const auto &component : components_) { - if(component->getNodeConnection(j) != -1) + for (IdxT j = 0; j < component->size(); ++j) { - component->y()[j] = y_[component->getNodeConnection(j)]; - component->yp()[j] = yp_[component->getNodeConnection(j)]; - } - else - { - component->y()[j] = 0.0; - component->yp()[j] = 0.0; + if (component->getNodeConnection(j) != -1) + { + component->y()[j] = y_[component->getNodeConnection(j)]; + component->yp()[j] = yp_[component->getNodeConnection(j)]; + } + else + { + component->y()[j] = 0.0; + component->yp()[j] = 0.0; + } } } + return 0; } - return 0; - } - int tagDifferentiable() - { - return 0; - } - - /** - * @brief Evaluate Residuals at each component then collect them - * - * @return int - */ - int evaluateResidual() - { - for (IdxT i = 0; i < this->f_.size(); i++) + int tagDifferentiable() { - f_[i] = 0.0; + return 0; } - - this->distributeVectors(); - // Update system residual vector - - for(const auto& component : components_) + /** + * @brief Evaluate Residuals at each component then collect them + * + * @return int + */ + int evaluateResidual() { - //TODO:check return type - component->evaluateResidual(); - for(IdxT j=0; jsize(); ++j) + for (IdxT i = 0; i < this->f_.size(); i++) + { + f_[i] = 0.0; + } + + this->distributeVectors(); + + // Update system residual vector + + for (const auto &component : components_) { - //@todo should do a different grounding check - if (component->getNodeConnection(j) != -1) + // TODO:check return type + component->evaluateResidual(); + for (IdxT j = 0; j < component->size(); ++j) { - f_[component->getNodeConnection(j)] += component->getResidual()[j]; + //@todo should do a different grounding check + if (component->getNodeConnection(j) != -1) + { + f_[component->getNodeConnection(j)] += component->getResidual()[j]; + } } - } + + return 0; } - return 0; - } - - /** - * @brief Creates the Sparse COO Jacobian representing \alpha dF/dy' + dF/dy - * - * @return int - */ - int evaluateJacobian() - { - this->J_.zeroMatrix(); - this->distributeVectors(); - - //Evaluate component jacs - for(const auto& component : components_) + /** + * @brief Creates the Sparse COO Jacobian representing \alpha dF/dy' + dF/dy + * + * @return int + */ + int evaluateJacobian() { - component->evaluateJacobian(); - - //get references to local jacobain - std::tuple&, std::vector&, std::vector&> tpm = component->getJacobian().getEntries(); - const auto& [r, c, v] = tpm; + this->J_.zeroMatrix(); + this->distributeVectors(); - //Create copies of data to handle groundings - std::vector rgr; - std::vector cgr; - std::vector vgr; - for (IdxT i = 0; i < static_cast(r.size()); i++) + // Evaluate component jacs + for (const auto &component : components_) { - if (component->getNodeConnection(r[i]) != -1 && component->getNodeConnection(c[i]) != -1) + component->evaluateJacobian(); + + // get references to local jacobain + std::tuple &, std::vector &, std::vector &> tpm = component->getJacobian().getEntries(); + const auto &[r, c, v] = tpm; + + // Create copies of data to handle groundings + std::vector rgr; + std::vector cgr; + std::vector vgr; + for (IdxT i = 0; i < static_cast(r.size()); i++) { - rgr.push_back(component->getNodeConnection(r[i])); - cgr.push_back(component->getNodeConnection(c[i])); - vgr.push_back(v[i]); + if (component->getNodeConnection(r[i]) != -1 && component->getNodeConnection(c[i]) != -1) + { + rgr.push_back(component->getNodeConnection(r[i])); + cgr.push_back(component->getNodeConnection(c[i])); + vgr.push_back(v[i]); + } } + + // AXPY to Global Jacobian + this->J_.AXPY(1.0, rgr, cgr, vgr); } - - //AXPY to Global Jacobian - this->J_.AXPY(1.0, rgr, cgr, vgr); + + return 0; } - - return 0; - } - - /** - * @brief Evaluate integrands for the system quadratures. - */ - int evaluateIntegrand() - { - return 0; - } + /** + * @brief Evaluate integrands for the system quadratures. + */ + int evaluateIntegrand() + { - /** - * @brief Initialize system adjoint. - * - * Updates variables and optimization parameters, then initializes - * adjoints locally and copies them to the system adjoint vector. - */ - int initializeAdjoint() - { - return 0; - } - - /** - * @brief Compute adjoint residual for the system model. - * - * - */ - int evaluateAdjointResidual() - { - return 0; - } + return 0; + } + /** + * @brief Initialize system adjoint. + * + * Updates variables and optimization parameters, then initializes + * adjoints locally and copies them to the system adjoint vector. + */ + int initializeAdjoint() + { + return 0; + } - /** - * @brief Evaluate adjoint integrand for the system model. - * - * - */ - int evaluateAdjointIntegrand() - { - return 0; - } - - /** - * @brief Distribute time and time scaling for each component - * - * @param t - * @param a - */ - void updateTime(ScalarT t, ScalarT a) - { - for(const auto& component : components_) + /** + * @brief Compute adjoint residual for the system model. + * + * + */ + int evaluateAdjointResidual() { - component->updateTime(t, a); + return 0; } - this->time_ = t; - this->alpha_ = a; - } - void addComponent(component_type* component) - { - this->components_.push_back(component); - } + /** + * @brief Evaluate adjoint integrand for the system model. + * + * + */ + int evaluateAdjointIntegrand() + { + return 0; + } + + /** + * @brief Distribute time and time scaling for each component + * + * @param t + * @param a + */ + void updateTime(ScalarT t, ScalarT a) + { + for (const auto &component : components_) + { + component->updateTime(t, a); + } + this->time_ = t; + this->alpha_ = a; + } + + void addComponent(component_type *component) + { + this->components_.push_back(component); + } -private: - std::vector components_; - bool usejac_; + private: + std::vector components_; + bool usejac_; -}; // class PowerElectronicsModel + }; // class PowerElectronicsModel } // namespace ModelLib diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index 2be2913a9..e7b144610 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -57,718 +57,703 @@ * */ - #include #include -#include /* access to IDADls interface */ +#include /* access to IDADls interface */ #include -//Sundials Sparse KLU +// Sundials Sparse KLU #include -#include +#include #include "ModelEvaluator.hpp" #include "Ida.hpp" - namespace AnalysisManager { -namespace Sundials -{ - - template - Ida::Ida(ModelLib::ModelEvaluator* model) : DynamicSolver(model) + namespace Sundials { - int retval = 0; - // Create the SUNDIALS context that all SUNDIALS objects require - retval = SUNContext_Create(NULL, &context_); - checkOutput(retval, "SUNContext"); - solver_ = IDACreate(context_); - tag_ = NULL; - } + template + Ida::Ida(ModelLib::ModelEvaluator *model) : DynamicSolver(model) + { + int retval = 0; - template - Ida::~Ida() - { - } + // Create the SUNDIALS context that all SUNDIALS objects require + retval = SUNContext_Create(NULL, &context_); + checkOutput(retval, "SUNContext"); + solver_ = IDACreate(context_); + tag_ = NULL; + } - template - int Ida::configureSimulation() - { - int retval = 0; + template + Ida::~Ida() + { + } - // Allocate solution vectors - yy_ = N_VNew_Serial(model_->size(), context_); - checkAllocation((void*) yy_, "N_VNew_Serial"); - yp_ = N_VClone(yy_); - checkAllocation((void*) yp_, "N_VClone"); + template + int Ida::configureSimulation() + { + int retval = 0; - //get intial conditions - this->getDefaultInitialCondition(); + // Allocate solution vectors + yy_ = N_VNew_Serial(model_->size(), context_); + checkAllocation((void *)yy_, "N_VNew_Serial"); + yp_ = N_VClone(yy_); + checkAllocation((void *)yp_, "N_VClone"); - // Create vectors to store restart initial condition - yy0_ = N_VClone(yy_); - checkAllocation((void*) yy0_, "N_VClone"); - yp0_ = N_VClone(yy_); - checkAllocation((void*) yp0_, "N_VClone"); + // get intial conditions + this->getDefaultInitialCondition(); - // Dummy initial time; will be overridden. - const realtype t0 = RCONST(0.0); + // Create vectors to store restart initial condition + yy0_ = N_VClone(yy_); + checkAllocation((void *)yy0_, "N_VClone"); + yp0_ = N_VClone(yy_); + checkAllocation((void *)yp0_, "N_VClone"); - // Allocate and initialize IDA workspace - retval = IDAInit(solver_, this->Residual, t0, yy_, yp_); - checkOutput(retval, "IDAInit"); + // Dummy initial time; will be overridden. + const realtype t0 = RCONST(0.0); - // Set pointer to model data - retval = IDASetUserData(solver_, model_); - checkOutput(retval, "IDASetUserData"); + // Allocate and initialize IDA workspace + retval = IDAInit(solver_, this->Residual, t0, yy_, yp_); + checkOutput(retval, "IDAInit"); - // Set tolerances - realtype rtol; - realtype atol; + // Set pointer to model data + retval = IDASetUserData(solver_, model_); + checkOutput(retval, "IDASetUserData"); - model_->setTolerances(rtol, atol); ///< \todo Function name should be "getTolerances"! - retval = IDASStolerances(solver_, rtol, atol); - checkOutput(retval, "IDASStolerances"); - - IdxT msa; - model_->setMaxSteps(msa); + // Set tolerances + realtype rtol; + realtype atol; - /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumSteps(solver_, msa); - checkOutput(retval, "IDASetMaxNumSteps"); + model_->setTolerances(rtol, atol); ///< \todo Function name should be "getTolerances"! + retval = IDASStolerances(solver_, rtol, atol); + checkOutput(retval, "IDASStolerances"); - // Tag differential variables - std::vector& tag = model_->tag(); - if (static_cast(tag.size()) == model_->size()) - { - tag_ = N_VClone(yy_); - checkAllocation((void*) tag_, "N_VClone"); - model_->tagDifferentiable(); - copyVec(tag, tag_); + IdxT msa; + model_->setMaxSteps(msa); - retval = IDASetId(solver_, tag_); - checkOutput(retval, "IDASetId"); - retval = IDASetSuppressAlg(solver_, SUNTRUE); - checkOutput(retval, "IDASetSuppressAlg"); - } + /// \todo Need to set max number of steps based on user input! + retval = IDASetMaxNumSteps(solver_, msa); + checkOutput(retval, "IDASetMaxNumSteps"); - // Set up linear solver - this->configureLinearSolver(); + // Tag differential variables + std::vector &tag = model_->tag(); + if (static_cast(tag.size()) == model_->size()) + { + tag_ = N_VClone(yy_); + checkAllocation((void *)tag_, "N_VClone"); + model_->tagDifferentiable(); + copyVec(tag, tag_); + + retval = IDASetId(solver_, tag_); + checkOutput(retval, "IDASetId"); + retval = IDASetSuppressAlg(solver_, SUNTRUE); + checkOutput(retval, "IDASetSuppressAlg"); + } - return retval; - } + // Set up linear solver + this->configureLinearSolver(); - template - int Ida::configureLinearSolver() - { - int retval = 0; - if (model_->hasJacobian()) + return retval; + } + + template + int Ida::configureLinearSolver() { - JacobianMat_ = SUNSparseMatrix(model_->size(), model_->size(), model_->size() * model_->size(), CSR_MAT, context_); - checkAllocation((void*) JacobianMat_, "SUNSparseMatrix"); + int retval = 0; + //Setup KLU for when Jacobian is needed + if (model_->hasJacobian()) + { + JacobianMat_ = SUNSparseMatrix(model_->size(), model_->size(), model_->size() * model_->size(), CSR_MAT, context_); + checkAllocation((void *)JacobianMat_, "SUNSparseMatrix"); - linearSolver_ = SUNLinSol_KLU(yy_, JacobianMat_, context_); - checkAllocation((void*) linearSolver_, "SUNLinSol_KLU"); + linearSolver_ = SUNLinSol_KLU(yy_, JacobianMat_, context_); + checkAllocation((void *)linearSolver_, "SUNLinSol_KLU"); - retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "IDASetLinearSolver"); + retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "IDASetLinearSolver"); - retval = IDASetJacFn(solver_, this->Jac); - checkOutput(retval, "IDASetJacFn"); - } - else - { - JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); + retval = IDASetJacFn(solver_, this->Jac); + checkOutput(retval, "IDASetJacFn"); + } + else + { + JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void *)JacobianMat_, "SUNDenseMatrix"); - linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); - checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); + linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); + checkAllocation((void *)linearSolver_, "SUNLinSol_Dense"); - retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "IDASetLinearSolver"); + retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "IDASetLinearSolver"); + } + return retval; } - return retval; - } + template + int Ida::getDefaultInitialCondition() + { + model_->initialize(); - template - int Ida::getDefaultInitialCondition() - { - model_->initialize(); + copyVec(model_->y(), yy_); + copyVec(model_->yp(), yp_); - copyVec(model_->y(), yy_); - copyVec(model_->yp(), yp_); + return 0; + } - return 0; - } + template + int Ida::setIntegrationTime(real_type t_init, real_type t_final, int nout) + { + t_init_ = t_init; + t_final_ = t_final; + nout_ = nout; + return 0; + } - template - int Ida::setIntegrationTime(real_type t_init, real_type t_final, int nout) - { - t_init_ = t_init; - t_final_ = t_final; - nout_ = nout; - return 0; - } - - template - int Ida::initializeSimulation(real_type t0, bool findConsistent) - { - int retval = 0; + template + int Ida::initializeSimulation(real_type t0, bool findConsistent) + { + int retval = 0; - // Need to reinitialize IDA to set to get correct initial conditions - retval = IDAReInit(solver_, t0, yy_, yp_); - checkOutput(retval, "IDAReInit"); + // Need to reinitialize IDA to set to get correct initial conditions + retval = IDAReInit(solver_, t0, yy_, yp_); + checkOutput(retval, "IDAReInit"); - // Find a consistent set of initial conditions for DAE - if (findConsistent) - { - int initType = IDA_Y_INIT; + // Find a consistent set of initial conditions for DAE + if (findConsistent) + { + int initType = IDA_Y_INIT; - if (tag_) - initType = IDA_YA_YDP_INIT; + if (tag_) + initType = IDA_YA_YDP_INIT; - retval = IDACalcIC(solver_, initType, 0.1); - checkOutput(retval, "IDACalcIC"); - } + retval = IDACalcIC(solver_, initType, 0.1); + checkOutput(retval, "IDACalcIC"); + } - return retval; - } + return retval; + } - template - int Ida::runSimulation(real_type tf, int nout) - { - int retval = 0; - int iout = 0; - real_type tret; - real_type dt = tf/nout; - real_type tout = dt; - - /* In loop, call IDASolve, print results, and test for error. - * Break out of loop when NOUT preset output times have been reached. */ - //printOutput(0.0); - while(nout > iout) - { - retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); - checkOutput(retval, "IDASolve"); - //printOutput(tout); - - if (retval == IDA_SUCCESS) + template + int Ida::runSimulation(real_type tf, int nout) + { + int retval = 0; + int iout = 0; + real_type tret; + real_type dt = tf / nout; + real_type tout = dt; + + /* In loop, call IDASolve, print results, and test for error. + * Break out of loop when NOUT preset output times have been reached. */ + // printOutput(0.0); + while (nout > iout) { - ++iout; - tout += dt; + retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); + checkOutput(retval, "IDASolve"); + // printOutput(tout); + + if (retval == IDA_SUCCESS) + { + ++iout; + tout += dt; + } } + // std::cout << "\n"; + return retval; } - //std::cout << "\n"; - return retval; - } - - template - int Ida::deleteSimulation() - { - IDAFree(&solver_); - SUNLinSolFree(linearSolver_); - N_VDestroy(yy_); - N_VDestroy(yp_); - return 0; - } - - - template - int Ida::configureQuadrature() - { - int retval = 0; - // Create and initialize quadratures - q_ = N_VNew_Serial(model_->size_quad(), context_); - checkAllocation((void*) q_, "N_VNew_Serial"); + template + int Ida::deleteSimulation() + { + IDAFree(&solver_); + SUNLinSolFree(linearSolver_); + N_VDestroy(yy_); + N_VDestroy(yp_); + return 0; + } - // Set integrand function and allocate quadrature workspace - retval = IDAQuadInit(solver_, this->Integrand, q_); - checkOutput(retval, "IDAQuadInit"); + template + int Ida::configureQuadrature() + { + int retval = 0; - // Set tolerances and error control for quadratures - real_type rtol, atol; - model_->setTolerances(rtol, atol); + // Create and initialize quadratures + q_ = N_VNew_Serial(model_->size_quad(), context_); + checkAllocation((void *)q_, "N_VNew_Serial"); - // Set tolerances for quadrature stricter than for integration - retval = IDAQuadSStolerances(solver_, rtol*0.1, atol*0.1); - checkOutput(retval, "IDAQuadSStolerances"); + // Set integrand function and allocate quadrature workspace + retval = IDAQuadInit(solver_, this->Integrand, q_); + checkOutput(retval, "IDAQuadInit"); - // Include quadrature in eror checking - retval = IDASetQuadErrCon(solver_, SUNTRUE); - checkOutput(retval, "IDASetQuadErrCon"); + // Set tolerances and error control for quadratures + real_type rtol, atol; + model_->setTolerances(rtol, atol); - return retval; - } + // Set tolerances for quadrature stricter than for integration + retval = IDAQuadSStolerances(solver_, rtol * 0.1, atol * 0.1); + checkOutput(retval, "IDAQuadSStolerances"); + // Include quadrature in eror checking + retval = IDASetQuadErrCon(solver_, SUNTRUE); + checkOutput(retval, "IDASetQuadErrCon"); - template - int Ida::initializeQuadrature() - { - int retval = 0; - - // Set all quadratures to zero - N_VConst(RCONST(0.0), q_); + return retval; + } - // Initialize quadratures - retval = IDAQuadReInit(solver_, q_); - checkOutput(retval, "IDAQuadInit"); + template + int Ida::initializeQuadrature() + { + int retval = 0; - return retval; - } + // Set all quadratures to zero + N_VConst(RCONST(0.0), q_); + // Initialize quadratures + retval = IDAQuadReInit(solver_, q_); + checkOutput(retval, "IDAQuadInit"); - template - int Ida::runSimulationQuadrature(real_type tf, int nout) - { - int retval = 0; - real_type tret; - - //std::cout << "Forward integration for initial value problem ... \n"; + return retval; + } - real_type dt = tf/nout; - real_type tout = dt; - //printOutput(0.0); - //printSpecial(0.0, yy_); - for(int i = 0; i < nout; ++i) + template + int Ida::runSimulationQuadrature(real_type tf, int nout) { - retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); - checkOutput(retval, "IDASolve"); - //printSpecial(tout, yy_); - //printOutput(tout); + int retval = 0; + real_type tret; + + // std::cout << "Forward integration for initial value problem ... \n"; - if (retval == IDA_SUCCESS) + real_type dt = tf / nout; + real_type tout = dt; + // printOutput(0.0); + // printSpecial(0.0, yy_); + for (int i = 0; i < nout; ++i) { - tout += dt; + retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); + checkOutput(retval, "IDASolve"); + // printSpecial(tout, yy_); + // printOutput(tout); + + if (retval == IDA_SUCCESS) + { + tout += dt; + } + + retval = IDAGetQuad(solver_, &tret, q_); + checkOutput(retval, "IDAGetQuad"); } - retval = IDAGetQuad(solver_, &tret, q_); - checkOutput(retval, "IDAGetQuad"); + return retval; } - return retval; - } - - - template - int Ida::deleteQuadrature() - { - IDAQuadFree(solver_); - N_VDestroy(q_); - - return 0; - } - + template + int Ida::deleteQuadrature() + { + IDAQuadFree(solver_); + N_VDestroy(q_); - template - int Ida::configureAdjoint() - { - // Allocate adjoint vector, derivatives and quadrature - yyB_ = N_VNew_Serial(model_->size(), context_); - checkAllocation((void*) yyB_, "N_VNew_Serial"); + return 0; + } - ypB_ = N_VClone(yyB_); - checkAllocation((void*) ypB_, "N_VClone"); + template + int Ida::configureAdjoint() + { + // Allocate adjoint vector, derivatives and quadrature + yyB_ = N_VNew_Serial(model_->size(), context_); + checkAllocation((void *)yyB_, "N_VNew_Serial"); - qB_ = N_VNew_Serial(model_->size_opt(), context_); - checkAllocation((void*) qB_, "N_VNew_Serial"); + ypB_ = N_VClone(yyB_); + checkAllocation((void *)ypB_, "N_VClone"); - return 0; - } + qB_ = N_VNew_Serial(model_->size_opt(), context_); + checkAllocation((void *)qB_, "N_VNew_Serial"); - template - int Ida::initializeAdjoint(IdxT steps) - { - int retval = 0; + return 0; + } - // Create adjoint workspace - retval = IDAAdjInit(solver_, steps, IDA_HERMITE); - checkOutput(retval, "IDAAdjInit"); + template + int Ida::initializeAdjoint(IdxT steps) + { + int retval = 0; - return retval; - } + // Create adjoint workspace + retval = IDAAdjInit(solver_, steps, IDA_HERMITE); + checkOutput(retval, "IDAAdjInit"); - template - int Ida::initializeBackwardSimulation(real_type tf) - { - int retval = 0; - realtype rtol; - realtype atol; + return retval; + } - model_->initializeAdjoint(); + template + int Ida::initializeBackwardSimulation(real_type tf) + { + int retval = 0; + realtype rtol; + realtype atol; - copyVec(model_->yB(), yyB_); - copyVec(model_->ypB(), ypB_); - N_VConst(0.0, qB_); + model_->initializeAdjoint(); - retval = IDACreateB(solver_, &backwardID_); - checkOutput(retval, "IDACreateB"); + copyVec(model_->yB(), yyB_); + copyVec(model_->ypB(), ypB_); + N_VConst(0.0, qB_); - // IDAInitB must be called after forward simulation run. - retval = IDAInitB(solver_, backwardID_, this->adjointResidual, tf, yyB_, ypB_); - checkOutput(retval, "IDAInitB"); + retval = IDACreateB(solver_, &backwardID_); + checkOutput(retval, "IDACreateB"); - model_->setTolerances(rtol, atol); - retval = IDASStolerancesB(solver_, backwardID_, rtol, atol); - checkOutput(retval, "IDASStolerancesB"); + // IDAInitB must be called after forward simulation run. + retval = IDAInitB(solver_, backwardID_, this->adjointResidual, tf, yyB_, ypB_); + checkOutput(retval, "IDAInitB"); - retval = IDASetUserDataB(solver_, backwardID_, model_); - checkOutput(retval, "IDASetUserDataB"); + model_->setTolerances(rtol, atol); + retval = IDASStolerancesB(solver_, backwardID_, rtol, atol); + checkOutput(retval, "IDASStolerancesB"); - /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumStepsB(solver_, backwardID_, 200); - checkOutput(retval, "IDASetMaxNumSteps"); + retval = IDASetUserDataB(solver_, backwardID_, model_); + checkOutput(retval, "IDASetUserDataB"); - // Set up linear solver - JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMatB_, "SUNDenseMatrix"); + /// \todo Need to set max number of steps based on user input! + retval = IDASetMaxNumStepsB(solver_, backwardID_, 200); + checkOutput(retval, "IDASetMaxNumSteps"); - linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); - checkAllocation((void*) linearSolverB_, "SUNLinSol_Dense"); + // Set up linear solver + JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void *)JacobianMatB_, "SUNDenseMatrix"); - retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); - checkOutput(retval, "IDASetLinearSolverB"); + linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); + checkAllocation((void *)linearSolverB_, "SUNLinSol_Dense"); + retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); + checkOutput(retval, "IDASetLinearSolverB"); - // Also reinitialize quadratures. - retval = IDAQuadInitB(solver_, backwardID_, this->adjointIntegrand, qB_); - checkOutput(retval, "IDAQuadInitB"); + // Also reinitialize quadratures. + retval = IDAQuadInitB(solver_, backwardID_, this->adjointIntegrand, qB_); + checkOutput(retval, "IDAQuadInitB"); - //retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol*1.1, atol*1.1); - retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol*0.1, atol*0.1); - checkOutput(retval, "IDAQuadSStolerancesB"); + // retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol*1.1, atol*1.1); + retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol * 0.1, atol * 0.1); + checkOutput(retval, "IDAQuadSStolerancesB"); - // Include quadratures in error control - retval = IDASetQuadErrConB(solver_, backwardID_, SUNTRUE); - checkOutput(retval, "IDASetQuadErrConB"); + // Include quadratures in error control + retval = IDASetQuadErrConB(solver_, backwardID_, SUNTRUE); + checkOutput(retval, "IDASetQuadErrConB"); + return retval; + } - return retval; - } + template + int Ida::configureLinearSolverBackward() + { + int retval = 0; - template - int Ida::configureLinearSolverBackward() - { - int retval = 0; + // Create Jacobian matrix + JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void *)JacobianMatB_, "SUNDenseMatrix"); - // Create Jacobian matrix - JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMatB_, "SUNDenseMatrix"); + // Create linear solver + linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); + checkAllocation((void *)linearSolverB_, "SUNLinSol_Dense"); - // Create linear solver - linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); - checkAllocation((void*) linearSolverB_, "SUNLinSol_Dense"); + // Attach linear solver to IDA + retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); + checkOutput(retval, "IDASetLinearSolverB"); - // Attach linear solver to IDA - retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); - checkOutput(retval, "IDASetLinearSolverB"); + return retval; + } - return retval; - } + template + int Ida::runForwardSimulation(real_type tf, int nout) + { + int retval = 0; + int ncheck; + real_type time; - template - int Ida::runForwardSimulation(real_type tf, int nout) - { - int retval = 0; - int ncheck; - real_type time; + // std::cout << "Forward integration for adjoint analysis ... \n"; - //std::cout << "Forward integration for adjoint analysis ... \n"; + real_type dt = tf / nout; + real_type tout = dt; + for (int i = 0; i < nout; ++i) + { + retval = IDASolveF(solver_, tout, &time, yy_, yp_, IDA_NORMAL, &ncheck); + checkOutput(retval, "IDASolveF"); - real_type dt = tf/nout; - real_type tout = dt; - for(int i = 0; i < nout; ++i) - { - retval = IDASolveF(solver_, tout, &time, yy_, yp_, IDA_NORMAL, &ncheck); - checkOutput(retval, "IDASolveF"); + if (retval == IDA_SUCCESS) + { + tout += dt; + } - if (retval == IDA_SUCCESS) - { - tout += dt; + retval = IDAGetQuad(solver_, &time, q_); + checkOutput(retval, "IDASolve"); } - retval = IDAGetQuad(solver_, &time, q_); - checkOutput(retval, "IDASolve"); + return retval; } - return retval; - } + template + int Ida::runBackwardSimulation(real_type t_init) + { + int retval = 0; + long int nstB; + real_type time; - template - int Ida::runBackwardSimulation(real_type t_init) - { - int retval = 0; - long int nstB; - real_type time; + // std::cout << "Backward integration for adjoint analysis ... "; - //std::cout << "Backward integration for adjoint analysis ... "; + retval = IDASolveB(solver_, t_init, IDA_NORMAL); + checkOutput(retval, "IDASolveB"); - retval = IDASolveB(solver_, t_init, IDA_NORMAL); - checkOutput(retval, "IDASolveB"); + IDAGetNumSteps(IDAGetAdjIDABmem(solver_, backwardID_), &nstB); + // std::cout << "done ( nst = " << nstB << " )\n"; - IDAGetNumSteps(IDAGetAdjIDABmem(solver_, backwardID_), &nstB); - //std::cout << "done ( nst = " << nstB << " )\n"; + retval = IDAGetB(solver_, backwardID_, &time, yyB_, ypB_); + checkOutput(retval, "IDAGetB"); - retval = IDAGetB(solver_, backwardID_, &time, yyB_, ypB_); - checkOutput(retval, "IDAGetB"); + retval = IDAGetQuadB(solver_, backwardID_, &time, qB_); + checkOutput(retval, "IDAGetQuadB"); - retval = IDAGetQuadB(solver_, backwardID_, &time, qB_); - checkOutput(retval, "IDAGetQuadB"); + return retval; + } - return retval; - } + template + int Ida::deleteAdjoint() + { + IDAAdjFree(solver_); + return 0; + } - template - int Ida::deleteAdjoint() - { - IDAAdjFree(solver_); - return 0; - } + template + int Ida::Residual(realtype tres, N_Vector yy, N_Vector yp, N_Vector rr, void *user_data) + { + ModelLib::ModelEvaluator *model = static_cast *>(user_data); - template - int Ida::Residual(realtype tres, N_Vector yy, N_Vector yp, N_Vector rr, void *user_data) - { - ModelLib::ModelEvaluator* model = static_cast*>(user_data); + model->updateTime(tres, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); - model->updateTime(tres, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); + model->evaluateResidual(); + const std::vector &f = model->getResidual(); + copyVec(f, rr); - model->evaluateResidual(); - const std::vector& f = model->getResidual(); - copyVec(f, rr); + return 0; + } - return 0; - } + template + int Ida::Jac(realtype t, realtype cj, N_Vector yy, N_Vector yp, N_Vector resvec, SUNMatrix J, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) + { - template - int Ida::Jac(realtype t, realtype cj, N_Vector yy, N_Vector yp, N_Vector resvec, SUNMatrix J, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) - { + ModelLib::ModelEvaluator *model = static_cast *>(user_data); - ModelLib::ModelEvaluator* model = static_cast*>(user_data); + model->updateTime(t, cj); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); + model->evaluateJacobian(); + COO_Matrix Jac = model->getJacobian(); - model->updateTime(t, cj); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); + // Get reference to the jacobian entries + std::tuple &, std::vector &, std::vector &> tpm = Jac.getEntries(); + const auto [r, c, val] = tpm; - model->evaluateJacobian(); - COO_Matrix Jac = model->getJacobian(); - - //Get reference to the jacobian entries - std::tuple&, std::vector&, std::vector&> tpm = Jac.getEntries(); - const auto [r, c, val] = tpm; + // get the CSR row pointers from COO matrix + std::vector csrrowdata = Jac.getCSRRowData(); - //get the CSR row pointers from COO matrix - std::vector csrrowdata = Jac.getCSRRowData(); + SUNMatZero(J); - SUNMatZero(J); + // Set row pointers + sunindextype *rowptrs = SUNSparseMatrix_IndexPointers(J); + for (unsigned int i = 0; i < csrrowdata.size(); i++) + { + rowptrs[i] = csrrowdata[i]; + } - //Set row pointers - sunindextype *rowptrs = SUNSparseMatrix_IndexPointers(J); - for (unsigned int i = 0; i < csrrowdata.size() ; i++) - { - rowptrs[i] = csrrowdata[i]; - } + sunindextype *colvals = SUNSparseMatrix_IndexValues(J); + realtype *data = SUNSparseMatrix_Data(J); + // Copy data from model jac to sundials + for (unsigned int i = 0; i < c.size(); i++) + { + colvals[i] = c[i]; + data[i] = val[i]; + } - sunindextype *colvals = SUNSparseMatrix_IndexValues(J); - realtype *data = SUNSparseMatrix_Data(J); - //Copy data from model jac to sundials - for (unsigned int i = 0; i < c.size(); i++ ) - { - colvals[i] = c[i]; - data[i] = val[i]; + return 0; } - return 0; - } - - template - int Ida::Integrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector rhsQ, void *user_data) - { - ModelLib::ModelEvaluator* model = static_cast*>(user_data); - - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); - - model->evaluateIntegrand(); - const std::vector& g = model->getIntegrand(); - copyVec(g, rhsQ); + template + int Ida::Integrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector rhsQ, void *user_data) + { + ModelLib::ModelEvaluator *model = static_cast *>(user_data); - return 0; - } + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); - template - int Ida::adjointResidual(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rrB, void *user_data) - { - ModelLib::ModelEvaluator* model = static_cast*>(user_data); + model->evaluateIntegrand(); + const std::vector &g = model->getIntegrand(); + copyVec(g, rhsQ); - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); - copyVec(yyB, model->yB()); - copyVec(ypB, model->ypB()); + return 0; + } - model->evaluateAdjointResidual(); - const std::vector& fB = model->getAdjointResidual(); - copyVec(fB, rrB); + template + int Ida::adjointResidual(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rrB, void *user_data) + { + ModelLib::ModelEvaluator *model = static_cast *>(user_data); - return 0; - } + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); + copyVec(yyB, model->yB()); + copyVec(ypB, model->ypB()); + model->evaluateAdjointResidual(); + const std::vector &fB = model->getAdjointResidual(); + copyVec(fB, rrB); - template - int Ida::adjointIntegrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rhsQB, void *user_data) - { - ModelLib::ModelEvaluator* model = static_cast*>(user_data); + return 0; + } - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); - copyVec(yyB, model->yB()); - copyVec(ypB, model->ypB()); + template + int Ida::adjointIntegrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rhsQB, void *user_data) + { + ModelLib::ModelEvaluator *model = static_cast *>(user_data); - model->evaluateAdjointIntegrand(); - const std::vector& gB = model->getAdjointIntegrand(); - copyVec(gB, rhsQB); + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); + copyVec(yyB, model->yB()); + copyVec(ypB, model->ypB()); - return 0; - } + model->evaluateAdjointIntegrand(); + const std::vector &gB = model->getAdjointIntegrand(); + copyVec(gB, rhsQB); + return 0; + } - template - void Ida::copyVec(const N_Vector x, std::vector< ScalarT >& y) - { - const ScalarT* xdata = NV_DATA_S(x); - for(unsigned int i = 0; i < y.size(); ++i) + template + void Ida::copyVec(const N_Vector x, std::vector &y) { - y[i] = xdata[i]; + const ScalarT *xdata = NV_DATA_S(x); + for (unsigned int i = 0; i < y.size(); ++i) + { + y[i] = xdata[i]; + } } - } - - template - void Ida::copyVec(const std::vector< ScalarT >& x, N_Vector y) - { - ScalarT* ydata = NV_DATA_S(y); - for(unsigned int i = 0; i < x.size(); ++i) + template + void Ida::copyVec(const std::vector &x, N_Vector y) { - ydata[i] = x[i]; + ScalarT *ydata = NV_DATA_S(y); + for (unsigned int i = 0; i < x.size(); ++i) + { + ydata[i] = x[i]; + } } - } - template - void Ida::copyVec(const std::vector< bool >& x, N_Vector y) - { - ScalarT* ydata = NV_DATA_S(y); - for(unsigned int i = 0; i < x.size(); ++i) + template + void Ida::copyVec(const std::vector &x, N_Vector y) { - if (x[i]) - ydata[i] = 1.0; - else - ydata[i] = 0.0; + ScalarT *ydata = NV_DATA_S(y); + for (unsigned int i = 0; i < x.size(); ++i) + { + if (x[i]) + ydata[i] = 1.0; + else + ydata[i] = 0.0; + } } - } - - - template - void Ida::printOutput(realtype t) - { - realtype *yval = N_VGetArrayPointer_Serial(yy_); - realtype *ypval = N_VGetArrayPointer_Serial(yp_); - std::cout << std::setprecision(5) << std::setw(7) << t << " "; - for (IdxT i = 0; i < model_->size(); ++i) + template + void Ida::printOutput(realtype t) { - std::cout << yval[i] << " "; + realtype *yval = N_VGetArrayPointer_Serial(yy_); + realtype *ypval = N_VGetArrayPointer_Serial(yp_); + + std::cout << std::setprecision(5) << std::setw(7) << t << " "; + for (IdxT i = 0; i < model_->size(); ++i) + { + std::cout << yval[i] << " "; + } + for (IdxT i = 0; i < model_->size(); ++i) + { + std::cout << ypval[i] << " "; + } + std::cout << "\n"; } - for (IdxT i = 0; i < model_->size(); ++i) + + template + void Ida::printSpecial(realtype t, N_Vector y) { - std::cout << ypval[i] << " "; + realtype *yval = N_VGetArrayPointer_Serial(y); + IdxT N = static_cast(N_VGetLength_Serial(y)); + std::cout << "{"; + std::cout << std::setprecision(5) << std::setw(7) << t; + for (IdxT i = 0; i < N; ++i) + { + std::cout << ", " << yval[i]; + } + std::cout << "},\n"; } - std::cout << "\n"; - } - template - void Ida::printSpecial(realtype t, N_Vector y) - { - realtype *yval = N_VGetArrayPointer_Serial(y); - IdxT N = static_cast(N_VGetLength_Serial(y)); - std::cout << "{"; - std::cout << std::setprecision(5) << std::setw(7) << t; - for (IdxT i = 0; i < N; ++i) + template + void Ida::printFinalStats() { - std::cout << ", " << yval[i]; + int retval = 0; + void *mem = solver_; + long int nst; + long int nre; + long int nje; + long int nni; + long int netf; + long int ncfn; + + retval = IDAGetNumSteps(mem, &nst); + checkOutput(retval, "IDAGetNumSteps"); + retval = IDAGetNumResEvals(mem, &nre); + checkOutput(retval, "IDAGetNumResEvals"); + retval = IDAGetNumJacEvals(mem, &nje); + checkOutput(retval, "IDAGetNumJacEvals"); + retval = IDAGetNumNonlinSolvIters(mem, &nni); + checkOutput(retval, "IDAGetNumNonlinSolvIters"); + retval = IDAGetNumErrTestFails(mem, &netf); + checkOutput(retval, "IDAGetNumErrTestFails"); + retval = IDAGetNumNonlinSolvConvFails(mem, &ncfn); + checkOutput(retval, "IDAGetNumNonlinSolvConvFails"); + + // std::cout << "\nFinal Run Statistics: \n\n"; + std::cout << "Number of steps = " << nst << "\n"; + std::cout << "Number of residual evaluations = " << nre << "\n"; + // std::cout << "Number of Jacobian evaluations = " << nje << "\n"; + std::cout << "Number of nonlinear iterations = " << nni << "\n"; + std::cout << "Number of error test failures = " << netf << "\n"; + std::cout << "Number of nonlinear conv. failures = " << ncfn << "\n"; } - std::cout << "},\n"; - } - template - void Ida::printFinalStats() - { - int retval = 0; - void* mem = solver_; - long int nst; - long int nre; - long int nje; - long int nni; - long int netf; - long int ncfn; - - retval = IDAGetNumSteps(mem, &nst); - checkOutput(retval, "IDAGetNumSteps"); - retval = IDAGetNumResEvals(mem, &nre); - checkOutput(retval, "IDAGetNumResEvals"); - retval = IDAGetNumJacEvals(mem, &nje); - checkOutput(retval, "IDAGetNumJacEvals"); - retval = IDAGetNumNonlinSolvIters(mem, &nni); - checkOutput(retval, "IDAGetNumNonlinSolvIters"); - retval = IDAGetNumErrTestFails(mem, &netf); - checkOutput(retval, "IDAGetNumErrTestFails"); - retval = IDAGetNumNonlinSolvConvFails(mem, &ncfn); - checkOutput(retval, "IDAGetNumNonlinSolvConvFails"); - - // std::cout << "\nFinal Run Statistics: \n\n"; - std::cout << "Number of steps = " << nst << "\n"; - std::cout << "Number of residual evaluations = " << nre << "\n"; - //std::cout << "Number of Jacobian evaluations = " << nje << "\n"; - std::cout << "Number of nonlinear iterations = " << nni << "\n"; - std::cout << "Number of error test failures = " << netf << "\n"; - std::cout << "Number of nonlinear conv. failures = " << ncfn << "\n"; - } - - - template - void Ida::checkAllocation(void* v, const char* functionName) - { - if (v == NULL) + template + void Ida::checkAllocation(void *v, const char *functionName) { - std::cerr << "\nERROR: Function " << functionName << " failed -- returned NULL pointer!\n\n"; - throw SundialsException(); + if (v == NULL) + { + std::cerr << "\nERROR: Function " << functionName << " failed -- returned NULL pointer!\n\n"; + throw SundialsException(); + } } - } - template - void Ida::checkOutput(int retval, const char* functionName) - { - if (retval < 0) + template + void Ida::checkOutput(int retval, const char *functionName) { - std::cerr << "\nERROR: Function " << functionName << " failed with flag " << retval << "!\n\n"; - throw SundialsException(); + if (retval < 0) + { + std::cerr << "\nERROR: Function " << functionName << " failed with flag " << retval << "!\n\n"; + throw SundialsException(); + } } - } - // Compiler will prevent building modules with data type incompatible with realtype - template class Ida; - template class Ida; - template class Ida; + // Compiler will prevent building modules with data type incompatible with realtype + template class Ida; + template class Ida; + template class Ida; -} // namespace Sundials + } // namespace Sundials } // namespace AnalysisManager From d715372dfb35becece29d41d871bb7e8a361459a Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Tue, 12 Mar 2024 16:23:16 -0400 Subject: [PATCH 13/44] Fixed Some Bugs - Fixed SpMatTest - Updates on rebase --- Examples/Grid3Bus/Grid3BusSys.cpp | 43 ++++++++++++++++++++----------- SparseMatrix/COO_Matrix.hpp | 2 +- SystemSteadyStateModel.hpp | 39 +--------------------------- 3 files changed, 30 insertions(+), 54 deletions(-) diff --git a/Examples/Grid3Bus/Grid3BusSys.cpp b/Examples/Grid3Bus/Grid3BusSys.cpp index a379f4015..c959aa9e0 100644 --- a/Examples/Grid3Bus/Grid3BusSys.cpp +++ b/Examples/Grid3Bus/Grid3BusSys.cpp @@ -101,8 +101,8 @@ mpc.baseMVA = 100; %% bus data % bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin mpc.bus = [ - 1 3 2.0 0.0 0 0 0 1 0.0 0 0 0 0.0; - 2 1 2.5 -0.8 0 0 0 1 0.0 0 0 0 0.0; + 1 3 2.0 0.0 0 0 0 1.0 0.0 0 0 0 0.0; + 2 1 2.5 -0.8 0 0 0 1.0 0.0 0 0 0 0.0; 3 2 0 0 0 0 0 1.1 0.0 0 0 0 0.0; ]; @@ -213,6 +213,7 @@ int parser_case() // allocate model sysmodel->allocate(); + sysmodel->initialize(); std::cout << "Model size: " << sysmodel->size() << "\n\n"; // Create numerical solver and attach the model to it. @@ -271,51 +272,51 @@ int hardwired_case() // Next create and add buses ... // Create a slack bus, fix V=1, theta=0, bus ID = 1 - BusData bd1; + BusData bd1 = {}; bd1.bus_i = 1; bd1.type = 3; bd1.Vm = 1.0; bd1.Va = 0.0; auto* bus1 = BusFactory::create(bd1); sysmodel->addBus(bus1); //Create a PQ bus, initialize V=1, theta=0, bus ID = 2 - BusData bd2; + BusData bd2 = {}; bd2.bus_i = 2; bd2.type = 1; bd2.Vm = 1.0; bd2.Va = 0.0; auto* bus2 = BusFactory::create(bd2); sysmodel->addBus(bus2); // Create a PV bus, fix V=1.1, initialize theta=0, and set power injection Pg=2 - BusData bd3; + BusData bd3 = {}; bd3.bus_i = 3; bd3.type = 2; bd3.Vm = 1.1; bd3.Va = 0.0; auto* bus3 = BusFactory::create(bd3); sysmodel->addBus(bus3); // Create and add generators ... // Create and add slack generator connected to bus1 - GenData gd1; + GenData gd1 = {}; gd1.bus = 1; auto* gen1 = GeneratorFactory::create(sysmodel->getBus(gd1.bus), gd1); sysmodel->addComponent(gen1); // Create and add PV generator connected to bus3 - GenData gd3; + GenData gd3 = {}; gd3.Pg = 2.0; gd3.bus = 3; auto* gen3 = GeneratorFactory::create(sysmodel->getBus(gd3.bus), gd3); sysmodel->addComponent(gen3); // Create and add branches ... // Branch 1-2 - BranchData brd12; + BranchData brd12 = {}; brd12.fbus = 1; brd12.tbus = 2; brd12.x = 1.0/10.0; brd12.r = 0.0; brd12.b = 0.0; Branch* branch12 = new Branch(sysmodel->getBus(brd12.fbus), sysmodel->getBus(brd12.tbus), brd12); sysmodel->addComponent(branch12); // Branch 1-3 - BranchData brd13; + BranchData brd13 = {}; brd13.fbus = 1; brd13.tbus = 3; brd13.x = 1.0/15.0; brd13.r = 0.0; brd13.b = 0.0; Branch* branch13 = new Branch(sysmodel->getBus(brd13.fbus), sysmodel->getBus(brd13.tbus), brd13); sysmodel->addComponent(branch13); // Branch 2-3 - BranchData brd23; + BranchData brd23 = {}; brd23.fbus = 2; brd23.tbus = 3; brd23.x = 1.0/12.0; brd23.r = 0.0; brd23.b = 0.0; Branch* branch23 = new Branch(sysmodel->getBus(brd23.fbus), sysmodel->getBus(brd23.tbus), brd23); sysmodel->addComponent(branch23); @@ -323,19 +324,20 @@ int hardwired_case() // Create and add loads ... // Load on bus1 - LoadData ld1; + LoadData ld1 = {}; ld1.bus_i = 1; ld1.Pd = 2.0; ld1.Qd = 0.0; Load* load1 = new Load(sysmodel->getBus(ld1.bus_i), ld1); sysmodel->addComponent(load1); // Load on bus2 - LoadData ld2; + LoadData ld2 = {}; ld2.bus_i = 2; ld2.Pd = 2.5; ld2.Qd = -0.8; Load* load2 = new Load(sysmodel->getBus(ld2.bus_i), ld2); sysmodel->addComponent(load2); // allocate model sysmodel->allocate(); + sysmodel->initialize(); std::cout << "Model size: " << sysmodel->size() << "\n\n"; // Create numerical solver and attach the model to it. @@ -351,7 +353,7 @@ int hardwired_case() // Print solution double th2 = bus2->theta() * 180.0/M_PI; double V2 = bus2->V(); - double th3 = bus3->theta() * 180.0/M_PI; + double th3 = bus3->theta() * 180.0/M_PI; std::cout << "Solution:\n"; @@ -387,8 +389,19 @@ int main() std::cout << std::string(32,'-') << std::endl; resolve += monolithic_case(); std::cout << std::string(32,'-') << std::endl; - resolve += hardwired_case(); - std::cout << std::string(32,'-') << std::endl; resolve += parser_case(); + std::cout << std::string(32,'-') << std::endl; + resolve += hardwired_case(); + + if (resolve) + { + std::cout << "Failure!\n"; + } + else + { + std::cout << "Success!\n"; + } + + return resolve; } diff --git a/SparseMatrix/COO_Matrix.hpp b/SparseMatrix/COO_Matrix.hpp index 716748fa8..dc99d7b9e 100644 --- a/SparseMatrix/COO_Matrix.hpp +++ b/SparseMatrix/COO_Matrix.hpp @@ -294,9 +294,9 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrixrow_indexes.push_back(r[aiter]); this->column_indexes.push_back(c[aiter]); this->values.push_back(alpha * val[aiter]); - aiter++; this->checkIncreaseSize(r[aiter], c[aiter]); + aiter++; } if (aiter >= static_cast(r.size())) break; diff --git a/SystemSteadyStateModel.hpp b/SystemSteadyStateModel.hpp index de2dc000e..ca1af16f0 100644 --- a/SystemSteadyStateModel.hpp +++ b/SystemSteadyStateModel.hpp @@ -127,43 +127,6 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl atol_ = 1e-5; } - SystemSteadyStateModel(GridKit::PowerSystemData::SystemModelData mp) : ModelEvaluatorImpl(0,0,0) - { - rtol_ = 1e-5; - atol_ = 1e-5; - - //buses - for(auto busdata : mp.bus) - { - auto* bus = BusFactory::create(busdata); - this->addBus(bus); - } - - //generators - for (auto gendata : mp.gen) - { - auto* gen = GeneratorFactory::create(this->getBus(gendata.bus),gendata); - this->addComponent(gen); - } - - //branches - for (auto branchdata : mp.branch) - { - auto* branch = new Branch(this->getBus(branchdata.fbus),this->getBus(branchdata.tbus),branchdata); - this->addComponent(branch); - } - - //loads - for (auto loaddata : mp.load) - { - auto* loadm = new Load(this->getBus(loaddata.bus_i),loaddata); - this->addComponent(loadm); - } - - //There appears to not be a Generator Cost Object - //TODO: Implment for GenCost - } - /** * @brief Construct a new System Steady State Model object. Allows for simple allocation. * @@ -463,4 +426,4 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl }; // class SystemSteadyStateModel -} // namespace ModelLib +} // namespace ModelLib \ No newline at end of file From 001d3c2d80de9a312bf4176c887087757fc97909 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Fri, 15 Mar 2024 15:26:50 -0400 Subject: [PATCH 14/44] Fixed Memory Error with Grid3BusSys - Intalized Pg data --- ComponentLib/Bus/BusPV.cpp | 2 +- ComponentLib/Bus/BusSlack.cpp | 4 ++++ Examples/Grid3Bus/Grid3BusSys.cpp | 21 +++++++++++---------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/ComponentLib/Bus/BusPV.cpp b/ComponentLib/Bus/BusPV.cpp index 5daafa102..a4e8c0cb2 100644 --- a/ComponentLib/Bus/BusPV.cpp +++ b/ComponentLib/Bus/BusPV.cpp @@ -105,7 +105,7 @@ BusPV::BusPV(ScalarT V, ScalarT theta0, ScalarT Pg) template BusPV::BusPV(BusData& data) - : BaseBus(data.bus_i), V_(data.Vm), theta0_(data.Va) + : BaseBus(data.bus_i), V_(data.Vm), theta0_(data.Va), Pg_(0.0) { //std::cout << "Create BusPV ..." << std::endl; //std::cout << "Number of equations is " << size_ << std::endl; diff --git a/ComponentLib/Bus/BusSlack.cpp b/ComponentLib/Bus/BusSlack.cpp index 80a5ae091..54318de74 100644 --- a/ComponentLib/Bus/BusSlack.cpp +++ b/ComponentLib/Bus/BusSlack.cpp @@ -97,6 +97,8 @@ BusSlack::BusSlack(ScalarT V, ScalarT theta) { //std::cout << "Create BusSlack..." << std::endl; //std::cout << "Number of equations is " << size_ << std::endl; + P() = 0.0; + Q() = 0.0; size_ = 0; } @@ -106,6 +108,8 @@ BusSlack::BusSlack(BusData& data) { //std::cout << "Create BusSlack..." << std::endl; //std::cout << "Number of equations is " << size_ << std::endl; + P() = 0.0; + Q() = 0.0; size_ = 0; } diff --git a/Examples/Grid3Bus/Grid3BusSys.cpp b/Examples/Grid3Bus/Grid3BusSys.cpp index c959aa9e0..bf11aa6ab 100644 --- a/Examples/Grid3Bus/Grid3BusSys.cpp +++ b/Examples/Grid3Bus/Grid3BusSys.cpp @@ -153,6 +153,7 @@ int monolithic_case() // allocate model model->allocate(); + model->initialize(); std::cout << "Model size: " << model->size() << "\n\n"; // Create numerical solver and attach the model to it. @@ -272,51 +273,51 @@ int hardwired_case() // Next create and add buses ... // Create a slack bus, fix V=1, theta=0, bus ID = 1 - BusData bd1 = {}; + BusData bd1; bd1.bus_i = 1; bd1.type = 3; bd1.Vm = 1.0; bd1.Va = 0.0; auto* bus1 = BusFactory::create(bd1); sysmodel->addBus(bus1); //Create a PQ bus, initialize V=1, theta=0, bus ID = 2 - BusData bd2 = {}; + BusData bd2; bd2.bus_i = 2; bd2.type = 1; bd2.Vm = 1.0; bd2.Va = 0.0; auto* bus2 = BusFactory::create(bd2); sysmodel->addBus(bus2); // Create a PV bus, fix V=1.1, initialize theta=0, and set power injection Pg=2 - BusData bd3 = {}; + BusData bd3; bd3.bus_i = 3; bd3.type = 2; bd3.Vm = 1.1; bd3.Va = 0.0; auto* bus3 = BusFactory::create(bd3); sysmodel->addBus(bus3); // Create and add generators ... // Create and add slack generator connected to bus1 - GenData gd1 = {}; + GenData gd1; gd1.bus = 1; auto* gen1 = GeneratorFactory::create(sysmodel->getBus(gd1.bus), gd1); sysmodel->addComponent(gen1); // Create and add PV generator connected to bus3 - GenData gd3 = {}; + GenData gd3; gd3.Pg = 2.0; gd3.bus = 3; auto* gen3 = GeneratorFactory::create(sysmodel->getBus(gd3.bus), gd3); sysmodel->addComponent(gen3); // Create and add branches ... // Branch 1-2 - BranchData brd12 = {}; + BranchData brd12; brd12.fbus = 1; brd12.tbus = 2; brd12.x = 1.0/10.0; brd12.r = 0.0; brd12.b = 0.0; Branch* branch12 = new Branch(sysmodel->getBus(brd12.fbus), sysmodel->getBus(brd12.tbus), brd12); sysmodel->addComponent(branch12); // Branch 1-3 - BranchData brd13 = {}; + BranchData brd13; brd13.fbus = 1; brd13.tbus = 3; brd13.x = 1.0/15.0; brd13.r = 0.0; brd13.b = 0.0; Branch* branch13 = new Branch(sysmodel->getBus(brd13.fbus), sysmodel->getBus(brd13.tbus), brd13); sysmodel->addComponent(branch13); // Branch 2-3 - BranchData brd23 = {}; + BranchData brd23; brd23.fbus = 2; brd23.tbus = 3; brd23.x = 1.0/12.0; brd23.r = 0.0; brd23.b = 0.0; Branch* branch23 = new Branch(sysmodel->getBus(brd23.fbus), sysmodel->getBus(brd23.tbus), brd23); sysmodel->addComponent(branch23); @@ -324,13 +325,13 @@ int hardwired_case() // Create and add loads ... // Load on bus1 - LoadData ld1 = {}; + LoadData ld1; ld1.bus_i = 1; ld1.Pd = 2.0; ld1.Qd = 0.0; Load* load1 = new Load(sysmodel->getBus(ld1.bus_i), ld1); sysmodel->addComponent(load1); // Load on bus2 - LoadData ld2 = {}; + LoadData ld2; ld2.bus_i = 2; ld2.Pd = 2.5; ld2.Qd = -0.8; Load* load2 = new Load(sysmodel->getBus(ld2.bus_i), ld2); sysmodel->addComponent(load2); From d258ad5721617f017fa1d35fe501a05b857a3376 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Fri, 22 Mar 2024 14:38:01 -0400 Subject: [PATCH 15/44] Fixed Unitalized Variable Stepsize --- Examples/GenInfiniteBus/GenInfiniteBus.cpp | 1 + SystemModel.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/Examples/GenInfiniteBus/GenInfiniteBus.cpp b/Examples/GenInfiniteBus/GenInfiniteBus.cpp index d4305ae05..f366a5a8a 100644 --- a/Examples/GenInfiniteBus/GenInfiniteBus.cpp +++ b/Examples/GenInfiniteBus/GenInfiniteBus.cpp @@ -93,6 +93,7 @@ int main() // allocate model components model->allocate(); + // Create numerical integrator and configure it for the generator model Ida* idas = new Ida(model); diff --git a/SystemModel.hpp b/SystemModel.hpp index 77bbdd20b..14b7e4e97 100644 --- a/SystemModel.hpp +++ b/SystemModel.hpp @@ -117,6 +117,7 @@ class SystemModel : public ModelEvaluatorImpl // Set system model tolerances rtol_ = 1e-7; atol_ = 1e-9; + this->max_steps_=2000; } /** From c8de3071b318e0514fc00e6079ab5b3b592956f6 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Tue, 9 Apr 2024 13:32:24 -0400 Subject: [PATCH 16/44] Fix max number of backward steps in IDA solver. --- Solver/Dynamic/Ida.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index e7b144610..3ae6854c4 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -415,7 +415,7 @@ namespace AnalysisManager checkOutput(retval, "IDASetUserDataB"); /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumStepsB(solver_, backwardID_, 200); + retval = IDASetMaxNumStepsB(solver_, backwardID_, 2000); checkOutput(retval, "IDASetMaxNumSteps"); // Set up linear solver From 31e6f68d2a2c112aec01aa0fa34068c847ff731b Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Tue, 9 Apr 2024 15:29:01 -0400 Subject: [PATCH 17/44] Fixing indentation from tabs to spaces --- .../Capacitor/Capacitor.cpp | 2 +- .../CircuitComponent.hpp | 204 ++--- .../DistributedGenerator.cpp | 2 +- .../DistributedGenerator.hpp | 2 +- .../InductionMotor/InductionMotor.cpp | 34 +- .../InductionMotor/InductionMotor.hpp | 14 +- .../Inductor/Inductor.cpp | 2 +- .../LinearTransformer/LinearTransformer.cpp | 18 +- .../LinearTransformer/LinearTransformer.hpp | 10 +- .../MicrogridBusDQ/MicrogridBusDQ.cpp | 2 +- .../MicrogridLine/MicrogridLine.cpp | 4 +- .../MicrogridLoad/MicrogridLoad.cpp | 4 +- .../Resistor/Resistor.cpp | 4 +- .../Resistor/Resistor.hpp | 2 +- .../SynchronousMachine/SynchronousMachine.cpp | 64 +- .../SynchronousMachine/SynchronousMachine.hpp | 26 +- .../TransmissionLine/TransmissionLine.cpp | 4 +- .../TransmissionLine/TransmissionLine.hpp | 2 +- .../VoltageSource/VoltageSource.cpp | 8 +- .../VoltageSource/VoltageSource.hpp | 2 +- Examples/Grid3Bus/Grid3BusSys.cpp | 22 +- Examples/Microgrid/Microgrid.cpp | 676 +++++++------- Examples/RLCircuit/RLCircuit.cpp | 228 ++--- Examples/SparseTest/SparseTest.cpp | 142 +-- SparseMatrix/COO_Matrix.hpp | 834 +++++++++--------- 25 files changed, 1156 insertions(+), 1156 deletions(-) diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp index b6287b359..148c7c086 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -18,7 +18,7 @@ template Capacitor::Capacitor(IdxT id, ScalarT C) : C_(C) { - this->size_ = 3; + this->size_ = 3; this->n_intern = 1; this->n_extern = 2; this->extern_indices = {0,1}; diff --git a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp index fe2efdf96..2d43e06e0 100644 --- a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp +++ b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp @@ -27,113 +27,113 @@ namespace ModelLib this->time_ = t; this->alpha_ = a; } - + bool hasJacobian() { return true;} - size_t getExternSize() - { - return this->n_extern; - } - - size_t getInternalSize() - { - return this->n_intern; - } - - std::set getExternIndices() - { - return this->extern_indices; - } - - bool setExternalConnectionNodes(size_t index, IdxT id) - { - this->connection_nodes[index] = id; - return true; - } - - IdxT getNodeConnection(size_t index) - { - return this->connection_nodes.at(index); - } - - inline std::vector parkTransformMatrix(ScalarT angle) - { - std::vector result(9); - ScalarT anpim = angle - (2.0/3.0)*M_PI; - ScalarT anpip = angle + (2.0/3.0)*M_PI; - result[0] = (2.0/3.0)*cos(angle); - result[1] = (2.0/3.0)*cos(anpim); - result[2] = (2.0/3.0)*cos(anpip); - result[3] = (2.0/3.0)*sin(angle); - result[4] = (2.0/3.0)*sin(anpim); - result[5] = (2.0/3.0)*sin(anpip); - result[6] = 1.0/3.0; - result[7] = 1.0/3.0; - result[8] = 1.0/3.0; - return result; - } - - inline std::vector parkTransformMatrixDerivative(ScalarT angle) - { - std::vector result(9); - ScalarT anpim = angle - (2.0/3.0)*M_PI; - ScalarT anpip = angle + (2.0/3.0)*M_PI; - result[0] = (2.0/3.0)*sin(angle); - result[1] = (2.0/3.0)*sin(anpim); - result[2] = (2.0/3.0)*sin(anpip); - result[3] = (2.0/3.0)*-cos(angle); - result[4] = (2.0/3.0)*-cos(anpim); - result[5] = (2.0/3.0)*-cos(anpip); - result[6] = 0; - result[7] = 0; - result[8] = 0; - return result; - } - - inline std::vector inverseParkTransformMatrix(ScalarT angle) - { - std::vector result(9); - ScalarT anpim = angle - (2.0/3.0)*M_PI; - ScalarT anpip = angle + (2.0/3.0)*M_PI; - result[0] = cos(angle); - result[1] = sin(angle); - result[2] = 1.0; - result[3] = cos(anpim); - result[4] = sin(anpim); - result[5] = 1.0; - result[6] = cos(anpip); - result[7] = sin(anpip); - result[8] = 1.0; - return result; - } - - inline std::vector inverseParkTransformMatrixDerivative(ScalarT angle) - { - std::vector result(9); - ScalarT anpim = angle - (2.0/3.0)*M_PI; - ScalarT anpip = angle + (2.0/3.0)*M_PI; - result[0] = sin(angle); - result[1] = -cos(angle); - result[2] = 0.0; - result[3] = sin(anpim); - result[4] = -cos(anpim); - result[5] = 0.0; - result[6] = sin(anpip); - result[7] = -cos(anpip); - result[8] = 0.0; - return result; - } - - protected: - size_t n_extern; - size_t n_intern; - std::set extern_indices; - //@todo may want to replace the mapping of connection_nodes to Node objects instead of IdxT. Allows for container free setup - std::map connection_nodes; + size_t getExternSize() + { + return this->n_extern; + } + + size_t getInternalSize() + { + return this->n_intern; + } + + std::set getExternIndices() + { + return this->extern_indices; + } + + bool setExternalConnectionNodes(size_t index, IdxT id) + { + this->connection_nodes[index] = id; + return true; + } + + IdxT getNodeConnection(size_t index) + { + return this->connection_nodes.at(index); + } + + inline std::vector parkTransformMatrix(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = (2.0/3.0)*cos(angle); + result[1] = (2.0/3.0)*cos(anpim); + result[2] = (2.0/3.0)*cos(anpip); + result[3] = (2.0/3.0)*sin(angle); + result[4] = (2.0/3.0)*sin(anpim); + result[5] = (2.0/3.0)*sin(anpip); + result[6] = 1.0/3.0; + result[7] = 1.0/3.0; + result[8] = 1.0/3.0; + return result; + } + + inline std::vector parkTransformMatrixDerivative(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = (2.0/3.0)*sin(angle); + result[1] = (2.0/3.0)*sin(anpim); + result[2] = (2.0/3.0)*sin(anpip); + result[3] = (2.0/3.0)*-cos(angle); + result[4] = (2.0/3.0)*-cos(anpim); + result[5] = (2.0/3.0)*-cos(anpip); + result[6] = 0; + result[7] = 0; + result[8] = 0; + return result; + } + + inline std::vector inverseParkTransformMatrix(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = cos(angle); + result[1] = sin(angle); + result[2] = 1.0; + result[3] = cos(anpim); + result[4] = sin(anpim); + result[5] = 1.0; + result[6] = cos(anpip); + result[7] = sin(anpip); + result[8] = 1.0; + return result; + } + + inline std::vector inverseParkTransformMatrixDerivative(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = sin(angle); + result[1] = -cos(angle); + result[2] = 0.0; + result[3] = sin(anpim); + result[4] = -cos(anpim); + result[5] = 0.0; + result[6] = sin(anpip); + result[7] = -cos(anpip); + result[8] = 0.0; + return result; + } + + protected: + size_t n_extern; + size_t n_intern; + std::set extern_indices; + //@todo may want to replace the mapping of connection_nodes to Node objects instead of IdxT. Allows for container free setup + std::map connection_nodes; }; - + } #endif diff --git a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp index d8d424b62..ee23eb7b7 100644 --- a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp @@ -22,7 +22,7 @@ DistributedGenerator::DistributedGenerator(IdxT id, DistributedGe { // internals [\delta_i, Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi] // externals [\omega_ref, vba_out, vbb_out] - this->size_ = 16; + this->size_ = 16; this->n_intern = 13; this->n_extern = 3; this->extern_indices = {0,1,2}; diff --git a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp index 94b297a55..65e71b2b9 100644 --- a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp @@ -69,7 +69,7 @@ namespace ModelLib int initialize(); int tagDifferentiable(); int evaluateResidual(); - int evaluateJacobian(); + int evaluateJacobian(); int evaluateIntegrand(); int initializeAdjoint(); int evaluateAdjointResidual(); diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp index 75782b435..c9b452f79 100644 --- a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp @@ -20,14 +20,14 @@ namespace ModelLib { template InductionMotor::InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, ScalarT Llr, ScalarT Rr, ScalarT Lms, ScalarT J, ScalarT P) : Lls_(Lls), - Rs_(Rs), - Llr_(Llr), - Rr_(Rr), - Lms_(Lms), - J_(J), - P_(P) + Rs_(Rs), + Llr_(Llr), + Rr_(Rr), + Lms_(Lms), + J_(J), + P_(P) { - this->size_ = 10; + this->size_ = 10; this->n_intern = 5; this->n_extern = 5; this->extern_indices = {0,1,2,3,4}; @@ -77,18 +77,18 @@ int InductionMotor::tagDifferentiable() template int InductionMotor::evaluateResidual() { - //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors - // for easier development + //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors + // for easier development this->f_[0] = y_[5] + y_[7]; this->f_[1] = (-1.0/2.0) * y_[5] - (sqrt(3.0)/2.0)*y_[6] + y_[7]; - this->f_[2] = (-1.0/2.0) * y_[5] + (sqrt(3.0)/2.0)*y_[6] + y_[7]; - this->f_[3] = J_ * yp_[3] - (3.0/4.0)*P_*Lms_ * (y_[5]*y_[9] - y_[6]*y_[8]); - this->f_[4] = yp_[4] - y_[3]; - this->f_[5] = (1.0/3.0)*(2.0* y_[0] - y_[1] - y_[2]) - Rs_*y_[5] - (Lls_ + Lms_) * yp_[5] - Lms_ * yp_[6]; - this->f_[6] = (1.0/sqrt(3.0))*(-y_[1] + y_[2]) - Rs_*y_[6] - (Lls_ + Lms_) * yp_[6] - Lms_ * yp_[5]; - this->f_[7] = (y_[0] + y_[1] + y_[2])/3.0 - Rs_*y_[7] - Lls_ * yp_[7]; - this->f_[8] = Rr_*y_[8] + (Llr_ + Lms_)*yp_[8] + Lms_ * yp_[5] - (P_/2)*y_[3]*((Llr_+Lms_)*y_[9] + Lms_*y_[6]); - this->f_[9] = Rr_*y_[9] + (Llr_ + Lms_)*yp_[9] + Lms_ * yp_[6] + (P_/2)*y_[3]*((Llr_+Lms_)*y_[8] + Lms_*y_[5]); + this->f_[2] = (-1.0/2.0) * y_[5] + (sqrt(3.0)/2.0)*y_[6] + y_[7]; + this->f_[3] = J_ * yp_[3] - (3.0/4.0)*P_*Lms_ * (y_[5]*y_[9] - y_[6]*y_[8]); + this->f_[4] = yp_[4] - y_[3]; + this->f_[5] = (1.0/3.0)*(2.0* y_[0] - y_[1] - y_[2]) - Rs_*y_[5] - (Lls_ + Lms_) * yp_[5] - Lms_ * yp_[6]; + this->f_[6] = (1.0/sqrt(3.0))*(-y_[1] + y_[2]) - Rs_*y_[6] - (Lls_ + Lms_) * yp_[6] - Lms_ * yp_[5]; + this->f_[7] = (y_[0] + y_[1] + y_[2])/3.0 - Rs_*y_[7] - Lls_ * yp_[7]; + this->f_[8] = Rr_*y_[8] + (Llr_ + Lms_)*yp_[8] + Lms_ * yp_[5] - (P_/2)*y_[3]*((Llr_+Lms_)*y_[9] + Lms_*y_[6]); + this->f_[9] = Rr_*y_[9] + (Llr_ + Lms_)*yp_[9] + Lms_ * yp_[6] + (P_/2)*y_[3]*((Llr_+Lms_)*y_[8] + Lms_*y_[5]); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp index 2547754e2..96ac6cc49 100644 --- a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp @@ -56,13 +56,13 @@ namespace ModelLib int evaluateAdjointIntegrand(); private: - ScalarT Lls_; - ScalarT Rs_; - ScalarT Llr_; - ScalarT Rr_; - ScalarT Lms_; - ScalarT J_; - ScalarT P_; + ScalarT Lls_; + ScalarT Rs_; + ScalarT Llr_; + ScalarT Rr_; + ScalarT Lms_; + ScalarT J_; + ScalarT P_; }; } diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index 885153d41..05cc66c51 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -18,7 +18,7 @@ template Inductor::Inductor(IdxT id, ScalarT L) : L_(L) { - this->size_ = 3; + this->size_ = 3; this->n_intern = 1; this->n_extern = 2; this->extern_indices = {0,1}; diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp index 4caaeae66..aa147493f 100644 --- a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp @@ -17,12 +17,12 @@ namespace ModelLib { template LinearTransformer::LinearTransformer(IdxT id, ScalarT L1, ScalarT L2, ScalarT R1, ScalarT R2, ScalarT M) : L1_(L1), - L2_(L2), - R1_(R1), - R2_(R2), - M_(M) + L2_(L2), + R1_(R1), + R2_(R2), + M_(M) { - this->size_ = 4; + this->size_ = 4; this->n_intern = 2; this->n_extern = 2; this->extern_indices = {0,1}; @@ -72,12 +72,12 @@ int LinearTransformer::tagDifferentiable() template int LinearTransformer::evaluateResidual() { - //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors - // for easier development + //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors + // for easier development this->f_[0] = this->y_[2]; this->f_[1] = this->y_[3]; - this->f_[2] = this->y_[0] - this->R1_ * this->y_[2] - this->L1_ * this->yp_[2] - this->M_ * this->yp_[3]; - this->f_[2] = this->y_[1] - this->R2_ * this->y_[3] - this->M_ * this->yp_[2] - this->L2_ * this->yp_[3]; + this->f_[2] = this->y_[0] - this->R1_ * this->y_[2] - this->L1_ * this->yp_[2] - this->M_ * this->yp_[3]; + this->f_[2] = this->y_[1] - this->R2_ * this->y_[3] - this->M_ * this->yp_[2] - this->L2_ * this->yp_[3]; return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp index cf56adfa2..0c0895383 100644 --- a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp @@ -56,11 +56,11 @@ namespace ModelLib int evaluateAdjointIntegrand(); private: - ScalarT L1_; - ScalarT L2_; - ScalarT R1_; - ScalarT R2_; - ScalarT M_; + ScalarT L1_; + ScalarT L2_; + ScalarT R1_; + ScalarT R2_; + ScalarT M_; }; } diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp index 206108221..a8327e341 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -19,7 +19,7 @@ MicrogridBusDQ::MicrogridBusDQ(IdxT id, ScalarT RN) : RN_(RN) { // externals [vbus_d, vbus_q] - this->size_ = 2; + this->size_ = 2; this->n_intern = 0; this->n_extern = 2; this->extern_indices = {0,1}; diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp index e040ceb70..05b1b5e66 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp @@ -20,7 +20,7 @@ MicrogridLine::MicrogridLine(IdxT id, ScalarT R,ScalarT L) { // internals [id, iq] // externals [\omegaref, vbd_in, vbq_in, vbd_out, vbq_out] - this->size_ = 7; + this->size_ = 7; this->n_intern = 2; this->n_extern = 5; this->extern_indices = {0,1,2,3,4}; @@ -74,7 +74,7 @@ int MicrogridLine::evaluateResidual() //ref motor this->f_[0] = 0.0; - //input + //input this->f_[1] = -y_[5] ; this->f_[2] = -y_[6] ; diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp index c39f53388..502170e3b 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp @@ -21,7 +21,7 @@ MicrogridLoad::MicrogridLoad(IdxT id, ScalarT R,ScalarT L) { // internals [id, iq] // externals [\omegaref, vbd_out, vbq_out] - this->size_ = 5; + this->size_ = 5; this->n_intern = 2; this->n_extern = 3; this->extern_indices = {0,1,2}; @@ -76,7 +76,7 @@ int MicrogridLoad::evaluateResidual() //only input for loads - //input + //input this->f_[1] = -y_[3] ; this->f_[2] = -y_[4] ; diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp index 45d9a34f3..d3acbb87f 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp @@ -18,7 +18,7 @@ template Resistor::Resistor(IdxT id, ScalarT R) : R_(R) { - this->size_ = 2; + this->size_ = 2; this->n_intern = 0; this->n_extern = 2; this->extern_indices = {0,1}; @@ -69,7 +69,7 @@ int Resistor::tagDifferentiable() template int Resistor::evaluateResidual() { - //input + //input this->f_[0] = (this->y_[0] - this->y_[1])/this->R_ ; //ouput this->f_[1] = (this->y_[1] - this->y_[0])/this->R_ ; diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp index 984d8304b..b9e01415d 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp @@ -59,7 +59,7 @@ namespace ModelLib private: - ScalarT R_; + ScalarT R_; }; } diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp index 05b1e59ac..8e9be323a 100644 --- a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp @@ -20,20 +20,20 @@ namespace ModelLib { template SynchronousMachine::SynchronousMachine(IdxT id, ScalarT Lls, std::tuple Llkq, ScalarT Llfd, ScalarT Llkd, ScalarT Lmq, ScalarT Lmd, ScalarT Rs, std::tuple Rkq, ScalarT Rfd, ScalarT Rkd, ScalarT J, ScalarT P, ScalarT mub) : Lls_(Lls), - Llkq_(Llkq), - Llfd_(Llfd), - Llkd_(Llkd), - Lmq_(Lmq), - Lmd_(Lmd), - Rs_(Rs), - Rkq_(Rkq), - Rfd_(Rfd), - Rkd_(Rkd), - J_(J), - P_(P), - mub_(mub) + Llkq_(Llkq), + Llfd_(Llfd), + Llkd_(Llkd), + Lmq_(Lmq), + Lmd_(Lmd), + Rs_(Rs), + Rkq_(Rkq), + Rfd_(Rfd), + Rkd_(Rkd), + J_(J), + P_(P), + mub_(mub) { - this->size_ = 13; + this->size_ = 13; this->n_intern = 6; this->n_extern = 7; this->extern_indices = {0,1,2,3,4}; @@ -83,28 +83,28 @@ int SynchronousMachine::tagDifferentiable() template int SynchronousMachine::evaluateResidual() { - ScalarT rkq1 = std::get<0>(Rkq_); - ScalarT rkq2 = std::get<1>(Rkq_); - ScalarT llkq1 = std::get<0>(Llkq_); - ScalarT llkq2 = std::get<1>(Llkq_); - - ScalarT cos1 = cos((P_/2.0)*y_[5]); - ScalarT sin1 = sin((P_/2.0)*y_[5]); - ScalarT cos23m = cos((P_/2.0)*y_[5] - (2.0/3.0)*M_PI); - ScalarT sin23m = sin((P_/2.0)*y_[5] - (2.0/3.0)*M_PI); - ScalarT cos23p = cos((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); - ScalarT sin23p = sin((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); + ScalarT rkq1 = std::get<0>(Rkq_); + ScalarT rkq2 = std::get<1>(Rkq_); + ScalarT llkq1 = std::get<0>(Llkq_); + ScalarT llkq2 = std::get<1>(Llkq_); + + ScalarT cos1 = cos((P_/2.0)*y_[5]); + ScalarT sin1 = sin((P_/2.0)*y_[5]); + ScalarT cos23m = cos((P_/2.0)*y_[5] - (2.0/3.0)*M_PI); + ScalarT sin23m = sin((P_/2.0)*y_[5] - (2.0/3.0)*M_PI); + ScalarT cos23p = cos((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); + ScalarT sin23p = sin((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); this->f_[0] = y_[6]*cos1 + y_[7]*sin1 + y_[8]; this->f_[1] = y_[6]*cos23m + y_[7]*sin23m + y_[8]; - this->f_[2] = y_[6]*cos23p + y_[7]*sin23p + y_[8]; - this->f_[3] = J_ * yp_[4] - (3.0/4.0)*P_*(Lmd_ *y_[6]* (y_[7] + y_[11] + y_[12]) - Lmq_*y_[7]*(y_[6] + y_[9] + y_[0])); - this->f_[4] = yp_[5] - y_[4]; - this->f_[5] = (-2.0/3.0)*(y_[0]*cos1 +y_[1]*cos23m + y_[2]*cos23p) + Rs_*y_[6] + (Lls_ + Lmq_)*yp_[6] + Lmq_*yp_[9] + Lmq_*yp_[10] + y_[4]*(P_/2.0)*((Lls_ + Lmd_)*y_[7] + Lmd_*y_[11] + Lmd_*y_[12]); - this->f_[6] = (-2.0/3.0)*(y_[0]*sin1 -y_[1]*sin23m - y_[2]*sin23p) + Rs_*y_[7] + (Lls_ + Lmd_)*yp_[7] + Lmd_*yp_[11] + Lmd_*yp_[12] - y_[4]*(P_/2.0)*((Lls_ + Lmq_)*y_[6] + Lmq_*y_[9] + Lmq_*y_[10]); - this->f_[7] = (-1.0/3.0)*(y_[0] + y_[1] + y_[2]) + Rs_*y_[8] + Lls_*yp_[8]; - this->f_[8] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; - this->f_[9] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; + this->f_[2] = y_[6]*cos23p + y_[7]*sin23p + y_[8]; + this->f_[3] = J_ * yp_[4] - (3.0/4.0)*P_*(Lmd_ *y_[6]* (y_[7] + y_[11] + y_[12]) - Lmq_*y_[7]*(y_[6] + y_[9] + y_[0])); + this->f_[4] = yp_[5] - y_[4]; + this->f_[5] = (-2.0/3.0)*(y_[0]*cos1 +y_[1]*cos23m + y_[2]*cos23p) + Rs_*y_[6] + (Lls_ + Lmq_)*yp_[6] + Lmq_*yp_[9] + Lmq_*yp_[10] + y_[4]*(P_/2.0)*((Lls_ + Lmd_)*y_[7] + Lmd_*y_[11] + Lmd_*y_[12]); + this->f_[6] = (-2.0/3.0)*(y_[0]*sin1 -y_[1]*sin23m - y_[2]*sin23p) + Rs_*y_[7] + (Lls_ + Lmd_)*yp_[7] + Lmd_*yp_[11] + Lmd_*yp_[12] - y_[4]*(P_/2.0)*((Lls_ + Lmq_)*y_[6] + Lmq_*y_[9] + Lmq_*y_[10]); + this->f_[7] = (-1.0/3.0)*(y_[0] + y_[1] + y_[2]) + Rs_*y_[8] + Lls_*yp_[8]; + this->f_[8] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; + this->f_[9] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp index a18eca9c9..b1ab24415 100644 --- a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp @@ -57,19 +57,19 @@ namespace ModelLib int evaluateAdjointIntegrand(); private: - ScalarT Lls_; - std::tuple Llkq_; - ScalarT Llfd_; - ScalarT Llkd_; - ScalarT Lmq_; - ScalarT Lmd_; - ScalarT Rs_; - std::tuple Rkq_; - ScalarT Rfd_; - ScalarT Rkd_; - ScalarT J_; - ScalarT P_; - ScalarT mub_; + ScalarT Lls_; + std::tuple Llkq_; + ScalarT Llfd_; + ScalarT Llkd_; + ScalarT Lmq_; + ScalarT Lmd_; + ScalarT Rs_; + std::tuple Rkq_; + ScalarT Rfd_; + ScalarT Rkd_; + ScalarT J_; + ScalarT P_; + ScalarT mub_; }; } diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp index 62965c68e..4158be388 100644 --- a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp @@ -21,7 +21,7 @@ TransmissionLine::TransmissionLine(IdxT id, ScalarT R,ScalarT X, { // internals [Iret1, Iimt1, Iret2, Iimt2] // externals [Vre11, Vim11, Vre12, Vim12, Vre21, Vim21, Vre22, Vim22] - this->size_ = 12; + this->size_ = 12; this->n_intern = 4; this->n_extern = 8; this->extern_indices = {0,1,2,3,4,5,6,7}; @@ -90,7 +90,7 @@ int TransmissionLine::tagDifferentiable() template int TransmissionLine::evaluateResidual() { - //input + //input this->f_[0] = y_[8] ; this->f_[1] = y_[9] ; diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp index 0f729d449..4acac0c58 100644 --- a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp @@ -59,7 +59,7 @@ namespace ModelLib private: - ScalarT R_; + ScalarT R_; ScalarT X_; ScalarT B_; ScalarT YReMat_; diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp index e58e50556..b8a659ba9 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -18,7 +18,7 @@ template VoltageSource::VoltageSource(IdxT id, ScalarT V) : V_(V) { - this->size_ = 3; + this->size_ = 3; this->n_intern = 1; this->n_extern = 2; this->extern_indices = {0,1}; @@ -69,14 +69,14 @@ int VoltageSource::tagDifferentiable() template int VoltageSource::evaluateResidual() { - //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors - // for easier development + //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors + // for easier development //input this->f_[0] = -this->y_[2]; //ouput this->f_[1] = this->y_[2]; //internal - this->f_[2] = this->y_[1] - this->y_[0] - this->V_; + this->f_[2] = this->y_[1] - this->y_[0] - this->V_; return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp index 3ac1c8699..17ba8f8c3 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp @@ -57,7 +57,7 @@ namespace ModelLib int evaluateAdjointIntegrand(); private: - ScalarT V_; + ScalarT V_; }; } diff --git a/Examples/Grid3Bus/Grid3BusSys.cpp b/Examples/Grid3Bus/Grid3BusSys.cpp index bf11aa6ab..64f616623 100644 --- a/Examples/Grid3Bus/Grid3BusSys.cpp +++ b/Examples/Grid3Bus/Grid3BusSys.cpp @@ -101,24 +101,24 @@ mpc.baseMVA = 100; %% bus data % bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin mpc.bus = [ - 1 3 2.0 0.0 0 0 0 1.0 0.0 0 0 0 0.0; - 2 1 2.5 -0.8 0 0 0 1.0 0.0 0 0 0 0.0; - 3 2 0 0 0 0 0 1.1 0.0 0 0 0 0.0; + 1 3 2.0 0.0 0 0 0 1.0 0.0 0 0 0 0.0; + 2 1 2.5 -0.8 0 0 0 1.0 0.0 0 0 0 0.0; + 3 2 0 0 0 0 0 1.1 0.0 0 0 0 0.0; ]; %% generator data % bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf mpc.gen = [ - 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; - 3 2.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; + 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; + 3 2.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; ]; %% branch data % fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax mpc.branch = [ - 1 2 0 0.1 0 0 0 0 0 0 0 0 0; - 1 3 0 0.0666666 0 0 0 0 0 0 0 0 0; - 2 3 0 0.0833333 0 0 0 0 0 0 0 0 0; + 1 2 0 0.1 0 0 0 0 0 0 0 0 0; + 1 3 0 0.0666666 0 0 0 0 0 0 0 0 0; + 2 3 0 0.0833333 0 0 0 0 0 0 0 0 0; ]; %%----- OPF Data -----%% @@ -126,9 +126,9 @@ mpc.branch = [ % 1 startup shutdown n x1 y1 ... xn yn % 2 startup shutdown n c(n-1) ... c0 mpc.gencost = [ - 2 0 0 3 0 14 0; - 2 0 0 3 0 15 0; - 2 0 0 3 0 30 0; + 2 0 0 3 0 14 0; + 2 0 0 3 0 15 0; + 2 0 0 3 0 30 0; ]; )"; diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp index b263495ad..8107c3e66 100644 --- a/Examples/Microgrid/Microgrid.cpp +++ b/Examples/Microgrid/Microgrid.cpp @@ -19,328 +19,328 @@ int main(int argc, char const *argv[]) { - double abstol = 1.0e-8; - double reltol = 1.0e-8; - size_t max_step_amount = 3000; - bool usejac = true; - - //TODO:setup as named parameters - //Create circuit model - ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac, max_step_amount); - - //Modeled after the problem in the paper - double RN = 1.0e4; - - //DG Params - - ModelLib::DistributedGeneratorParameters parms1; - parms1.wb = 2.0*M_PI*50.0; - parms1.wc = 31.41; - parms1.mp = 9.4e-5; - parms1.Vn = 380.0; - parms1.nq = 1.3e-3; - parms1.F = 0.75; - parms1.Kiv = 420.0; - parms1.Kpv = 0.1; - parms1.Kic = 2.0e4; - parms1.Kpc = 15.0; - parms1.Cf = 5.0e-5; - parms1.rLf = 0.1; - parms1.Lf = 1.35e-3; - parms1.rLc = 0.03; - parms1.Lc = 0.35e-3; - - ModelLib::DistributedGeneratorParameters parms2; - //Parameters from MATLAB Microgrid code for first DG - parms2.wb = 2.0*M_PI*50.0; - parms2.wc = 31.41; - parms2.mp = 12.5e-5; - parms2.Vn = 380.0; - parms2.nq = 1.5e-3; - parms2.F = 0.75; - parms2.Kiv = 390.0; - parms2.Kpv = 0.05; - parms2.Kic = 16.0e3; - parms2.Kpc = 10.5; - parms2.Cf = 50.0e-6; - parms2.rLf = 0.1; - parms2.Lf = 1.35e-3; - parms2.rLc = 0.03; - parms2.Lc = 0.35e-3; - - //Line params - double rline1 = 0.23; - double Lline1 = 0.1 / (2.0 * M_PI * 50.0); - - double rline2 = 0.35; - double Lline2 = 0.58 / (2.0 * M_PI * 50.0); - - double rline3 = 0.23; - double Lline3 = 0.1 / (2.0 * M_PI * 50.0); - - //load parms - double rload1 = 3.0; - double Lload1 = 2.0 / (2.0 * M_PI * 50.0); - - double rload2 = 2.0; - double Lload2 = 1.0 / (2.0 * M_PI * 50.0); - - - //indexing sets - size_t Nsize = 2; - // DGs + - refframe Lines + Loads - size_t vec_size_internals = 13*(2*Nsize) - 1 + (2 + 4*(Nsize - 1)) + 2*Nsize; - // \omegaref + BusDQ - size_t vec_size_externals = 1 + 2*(2*Nsize); - size_t dqbus1 = vec_size_internals + 1; - size_t dqbus2 = vec_size_internals + 3; - size_t dqbus3 = vec_size_internals + 5; - size_t dqbus4 = vec_size_internals + 7; - - size_t vec_size_total = vec_size_internals + vec_size_externals; - - - size_t indexv = 0; - - //dg 1 - ModelLib::DistributedGenerator *dg1 = new ModelLib::DistributedGenerator(0, parms1, true); - //ref motor - dg1->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg1->setExternalConnectionNodes(1,dqbus1); - dg1->setExternalConnectionNodes(2,dqbus1 + 1); - //"grounding" of the difference - dg1->setExternalConnectionNodes(3,-1); - //internal connections - for (size_t i = 0; i < 12; i++) - { - - dg1->setExternalConnectionNodes(4 + i,indexv + i); - } - indexv += 12; - sysmodel->addComponent(dg1); - - //dg 2 - ModelLib::DistributedGenerator *dg2 = new ModelLib::DistributedGenerator(1, parms1, false); - //ref motor - dg2->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg2->setExternalConnectionNodes(1,dqbus2); - dg2->setExternalConnectionNodes(2,dqbus2 + 1); - //internal connections - for (size_t i = 0; i < 13; i++) - { - - dg2->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 13; - sysmodel->addComponent(dg2); - - - //dg 3 - ModelLib::DistributedGenerator *dg3 = new ModelLib::DistributedGenerator(2, parms2, false); - //ref motor - dg3->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg3->setExternalConnectionNodes(1,dqbus3); - dg3->setExternalConnectionNodes(2,dqbus3 + 1); - //internal connections - for (size_t i = 0; i < 13; i++) - { - - dg3->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 13; - sysmodel->addComponent(dg3); - - - //dg 4 - ModelLib::DistributedGenerator *dg4 = new ModelLib::DistributedGenerator(3, parms2, false); - //ref motor - dg4->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg4->setExternalConnectionNodes(1,dqbus4); - dg4->setExternalConnectionNodes(2,dqbus4 + 1); - - //internal connections - for (size_t i = 0; i < 13; i++) - { - - dg4->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 13; - sysmodel->addComponent(dg4); - - // Lines - - //line 1 - ModelLib::MicrogridLine *l1 = new ModelLib::MicrogridLine(4, rline1, Lline1); - //ref motor - l1->setExternalConnectionNodes(0,vec_size_internals); - //input connections - l1->setExternalConnectionNodes(1,dqbus1); - l1->setExternalConnectionNodes(2,dqbus1 + 1); - //output connections - l1->setExternalConnectionNodes(3,dqbus2); - l1->setExternalConnectionNodes(4,dqbus2 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - l1->setExternalConnectionNodes(5 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(l1); - - - //line 2 - ModelLib::MicrogridLine *l2 = new ModelLib::MicrogridLine(5, rline2, Lline2); - //ref motor - l2->setExternalConnectionNodes(0,vec_size_internals); - //input connections - l2->setExternalConnectionNodes(1,dqbus2); - l2->setExternalConnectionNodes(2,dqbus2 + 1); - //output connections - l2->setExternalConnectionNodes(3,dqbus3); - l2->setExternalConnectionNodes(4,dqbus3 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - l2->setExternalConnectionNodes(5 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(l2); - - //line 3 - ModelLib::MicrogridLine *l3 = new ModelLib::MicrogridLine(6, rline3, Lline3); - //ref motor - l3->setExternalConnectionNodes(0,vec_size_internals); - //input connections - l3->setExternalConnectionNodes(1,dqbus3); - l3->setExternalConnectionNodes(2,dqbus3 + 1); - //output connections - l3->setExternalConnectionNodes(3,dqbus4); - l3->setExternalConnectionNodes(4,dqbus4 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - l3->setExternalConnectionNodes(5 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(l3); - - // loads - - //load 1 - ModelLib::MicrogridLoad *load1 = new ModelLib::MicrogridLoad(7, rload1, Lload1); - //ref motor - load1->setExternalConnectionNodes(0,vec_size_internals); - //input connections - load1->setExternalConnectionNodes(1,dqbus1); - load1->setExternalConnectionNodes(2,dqbus1 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - load1->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(load1); - - //load 2 - ModelLib::MicrogridLoad *load2 = new ModelLib::MicrogridLoad(8, rload2, Lload2); - //ref motor - load2->setExternalConnectionNodes(0,vec_size_internals); - //input connections - load2->setExternalConnectionNodes(1,dqbus3); - load2->setExternalConnectionNodes(2,dqbus3 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - load2->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(load2); - - //Virtual PQ Buses - ModelLib::MicrogridBusDQ *bus1 = new ModelLib::MicrogridBusDQ(9, RN); - - bus1->setExternalConnectionNodes(0,dqbus1); - bus1->setExternalConnectionNodes(1,dqbus1 + 1); - sysmodel->addComponent(bus1); - - ModelLib::MicrogridBusDQ *bus2 = new ModelLib::MicrogridBusDQ(10, RN); - - bus2->setExternalConnectionNodes(0,dqbus2); - bus2->setExternalConnectionNodes(1,dqbus2 + 1); - sysmodel->addComponent(bus2); - - ModelLib::MicrogridBusDQ *bus3 = new ModelLib::MicrogridBusDQ(11, RN); - - bus3->setExternalConnectionNodes(0,dqbus3); - bus3->setExternalConnectionNodes(1,dqbus3 + 1); - sysmodel->addComponent(bus3); - - ModelLib::MicrogridBusDQ *bus4 = new ModelLib::MicrogridBusDQ(12, RN); - - bus4->setExternalConnectionNodes(0,dqbus4); - bus4->setExternalConnectionNodes(1,dqbus4 + 1); - sysmodel->addComponent(bus4); - - sysmodel->allocate(vec_size_total); - - std::cout << sysmodel->y().size() << std::endl; - std::cout << vec_size_internals << ", " << vec_size_externals << "\n"; - - //Create Intial points for states - for (size_t i = 0; i < vec_size_total; i++) - { - sysmodel->y()[i] = 0.0; - sysmodel->yp()[i] = 0.0; - } - - // Create Intial derivatives specifics generated in MATLAB - //DGs 1 - sysmodel->yp()[2] = parms1.Vn; - sysmodel->yp()[4] = parms1.Kpv * parms1.Vn; - sysmodel->yp()[6] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; - sysmodel->yp()[12 + 3] = parms1.Vn; - sysmodel->yp()[12 + 5] = parms1.Kpv * parms1.Vn; - sysmodel->yp()[12 + 7] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; - for (size_t i = 2; i < 4; i++) - { - sysmodel->yp()[13*i - 1 + 3] = parms2.Vn; - sysmodel->yp()[13*i - 1 + 5] = parms2.Kpv * parms2.Vn; - sysmodel->yp()[13*i - 1 + 7] = (parms2.Kpc * parms2.Kpv * parms2.Vn) / parms2.Lf; - } - - //since the intial P_com = 0 - sysmodel->y()[vec_size_internals] = parms1.wb; - - - - sysmodel->initialize(); - sysmodel->evaluateResidual(); - - std::vector& fres = sysmodel->getResidual(); - std::cout << "Verify Intial Resisdual is Zero: {\n"; - for (size_t i = 0; i < fres.size(); i++) - { - printf("%u : %e \n", i, fres[i]); - } - std::cout << "}\n"; - - sysmodel->updateTime(0.0, 1.0e-8); - sysmodel->evaluateJacobian(); - std::cout << "Intial Jacobian with alpha:\n"; - // std::cout << sysmodel->getJacobian().frobnorm() << "\n"; - - - //Create numerical integrator and configure it for the generator model - AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); + double abstol = 1.0e-8; + double reltol = 1.0e-8; + size_t max_step_amount = 3000; + bool usejac = true; + + //TODO:setup as named parameters + //Create circuit model + ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac, max_step_amount); + + //Modeled after the problem in the paper + double RN = 1.0e4; + + //DG Params + + ModelLib::DistributedGeneratorParameters parms1; + parms1.wb = 2.0*M_PI*50.0; + parms1.wc = 31.41; + parms1.mp = 9.4e-5; + parms1.Vn = 380.0; + parms1.nq = 1.3e-3; + parms1.F = 0.75; + parms1.Kiv = 420.0; + parms1.Kpv = 0.1; + parms1.Kic = 2.0e4; + parms1.Kpc = 15.0; + parms1.Cf = 5.0e-5; + parms1.rLf = 0.1; + parms1.Lf = 1.35e-3; + parms1.rLc = 0.03; + parms1.Lc = 0.35e-3; + + ModelLib::DistributedGeneratorParameters parms2; + //Parameters from MATLAB Microgrid code for first DG + parms2.wb = 2.0*M_PI*50.0; + parms2.wc = 31.41; + parms2.mp = 12.5e-5; + parms2.Vn = 380.0; + parms2.nq = 1.5e-3; + parms2.F = 0.75; + parms2.Kiv = 390.0; + parms2.Kpv = 0.05; + parms2.Kic = 16.0e3; + parms2.Kpc = 10.5; + parms2.Cf = 50.0e-6; + parms2.rLf = 0.1; + parms2.Lf = 1.35e-3; + parms2.rLc = 0.03; + parms2.Lc = 0.35e-3; + + //Line params + double rline1 = 0.23; + double Lline1 = 0.1 / (2.0 * M_PI * 50.0); + + double rline2 = 0.35; + double Lline2 = 0.58 / (2.0 * M_PI * 50.0); + + double rline3 = 0.23; + double Lline3 = 0.1 / (2.0 * M_PI * 50.0); + + //load parms + double rload1 = 3.0; + double Lload1 = 2.0 / (2.0 * M_PI * 50.0); + + double rload2 = 2.0; + double Lload2 = 1.0 / (2.0 * M_PI * 50.0); + + + //indexing sets + size_t Nsize = 2; + // DGs + - refframe Lines + Loads + size_t vec_size_internals = 13*(2*Nsize) - 1 + (2 + 4*(Nsize - 1)) + 2*Nsize; + // \omegaref + BusDQ + size_t vec_size_externals = 1 + 2*(2*Nsize); + size_t dqbus1 = vec_size_internals + 1; + size_t dqbus2 = vec_size_internals + 3; + size_t dqbus3 = vec_size_internals + 5; + size_t dqbus4 = vec_size_internals + 7; + + size_t vec_size_total = vec_size_internals + vec_size_externals; + + + size_t indexv = 0; + + //dg 1 + ModelLib::DistributedGenerator *dg1 = new ModelLib::DistributedGenerator(0, parms1, true); + //ref motor + dg1->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg1->setExternalConnectionNodes(1,dqbus1); + dg1->setExternalConnectionNodes(2,dqbus1 + 1); + //"grounding" of the difference + dg1->setExternalConnectionNodes(3,-1); + //internal connections + for (size_t i = 0; i < 12; i++) + { + + dg1->setExternalConnectionNodes(4 + i,indexv + i); + } + indexv += 12; + sysmodel->addComponent(dg1); + + //dg 2 + ModelLib::DistributedGenerator *dg2 = new ModelLib::DistributedGenerator(1, parms1, false); + //ref motor + dg2->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg2->setExternalConnectionNodes(1,dqbus2); + dg2->setExternalConnectionNodes(2,dqbus2 + 1); + //internal connections + for (size_t i = 0; i < 13; i++) + { + + dg2->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg2); + + + //dg 3 + ModelLib::DistributedGenerator *dg3 = new ModelLib::DistributedGenerator(2, parms2, false); + //ref motor + dg3->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg3->setExternalConnectionNodes(1,dqbus3); + dg3->setExternalConnectionNodes(2,dqbus3 + 1); + //internal connections + for (size_t i = 0; i < 13; i++) + { + + dg3->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg3); + + + //dg 4 + ModelLib::DistributedGenerator *dg4 = new ModelLib::DistributedGenerator(3, parms2, false); + //ref motor + dg4->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg4->setExternalConnectionNodes(1,dqbus4); + dg4->setExternalConnectionNodes(2,dqbus4 + 1); + + //internal connections + for (size_t i = 0; i < 13; i++) + { + + dg4->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg4); + + // Lines + + //line 1 + ModelLib::MicrogridLine *l1 = new ModelLib::MicrogridLine(4, rline1, Lline1); + //ref motor + l1->setExternalConnectionNodes(0,vec_size_internals); + //input connections + l1->setExternalConnectionNodes(1,dqbus1); + l1->setExternalConnectionNodes(2,dqbus1 + 1); + //output connections + l1->setExternalConnectionNodes(3,dqbus2); + l1->setExternalConnectionNodes(4,dqbus2 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + l1->setExternalConnectionNodes(5 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(l1); + + + //line 2 + ModelLib::MicrogridLine *l2 = new ModelLib::MicrogridLine(5, rline2, Lline2); + //ref motor + l2->setExternalConnectionNodes(0,vec_size_internals); + //input connections + l2->setExternalConnectionNodes(1,dqbus2); + l2->setExternalConnectionNodes(2,dqbus2 + 1); + //output connections + l2->setExternalConnectionNodes(3,dqbus3); + l2->setExternalConnectionNodes(4,dqbus3 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + l2->setExternalConnectionNodes(5 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(l2); + + //line 3 + ModelLib::MicrogridLine *l3 = new ModelLib::MicrogridLine(6, rline3, Lline3); + //ref motor + l3->setExternalConnectionNodes(0,vec_size_internals); + //input connections + l3->setExternalConnectionNodes(1,dqbus3); + l3->setExternalConnectionNodes(2,dqbus3 + 1); + //output connections + l3->setExternalConnectionNodes(3,dqbus4); + l3->setExternalConnectionNodes(4,dqbus4 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + l3->setExternalConnectionNodes(5 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(l3); + + // loads + + //load 1 + ModelLib::MicrogridLoad *load1 = new ModelLib::MicrogridLoad(7, rload1, Lload1); + //ref motor + load1->setExternalConnectionNodes(0,vec_size_internals); + //input connections + load1->setExternalConnectionNodes(1,dqbus1); + load1->setExternalConnectionNodes(2,dqbus1 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + load1->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(load1); + + //load 2 + ModelLib::MicrogridLoad *load2 = new ModelLib::MicrogridLoad(8, rload2, Lload2); + //ref motor + load2->setExternalConnectionNodes(0,vec_size_internals); + //input connections + load2->setExternalConnectionNodes(1,dqbus3); + load2->setExternalConnectionNodes(2,dqbus3 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + load2->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(load2); + + //Virtual PQ Buses + ModelLib::MicrogridBusDQ *bus1 = new ModelLib::MicrogridBusDQ(9, RN); + + bus1->setExternalConnectionNodes(0,dqbus1); + bus1->setExternalConnectionNodes(1,dqbus1 + 1); + sysmodel->addComponent(bus1); + + ModelLib::MicrogridBusDQ *bus2 = new ModelLib::MicrogridBusDQ(10, RN); + + bus2->setExternalConnectionNodes(0,dqbus2); + bus2->setExternalConnectionNodes(1,dqbus2 + 1); + sysmodel->addComponent(bus2); + + ModelLib::MicrogridBusDQ *bus3 = new ModelLib::MicrogridBusDQ(11, RN); + + bus3->setExternalConnectionNodes(0,dqbus3); + bus3->setExternalConnectionNodes(1,dqbus3 + 1); + sysmodel->addComponent(bus3); + + ModelLib::MicrogridBusDQ *bus4 = new ModelLib::MicrogridBusDQ(12, RN); + + bus4->setExternalConnectionNodes(0,dqbus4); + bus4->setExternalConnectionNodes(1,dqbus4 + 1); + sysmodel->addComponent(bus4); + + sysmodel->allocate(vec_size_total); + + std::cout << sysmodel->y().size() << std::endl; + std::cout << vec_size_internals << ", " << vec_size_externals << "\n"; + + //Create Intial points for states + for (size_t i = 0; i < vec_size_total; i++) + { + sysmodel->y()[i] = 0.0; + sysmodel->yp()[i] = 0.0; + } + + // Create Intial derivatives specifics generated in MATLAB + //DGs 1 + sysmodel->yp()[2] = parms1.Vn; + sysmodel->yp()[4] = parms1.Kpv * parms1.Vn; + sysmodel->yp()[6] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; + sysmodel->yp()[12 + 3] = parms1.Vn; + sysmodel->yp()[12 + 5] = parms1.Kpv * parms1.Vn; + sysmodel->yp()[12 + 7] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; + for (size_t i = 2; i < 4; i++) + { + sysmodel->yp()[13*i - 1 + 3] = parms2.Vn; + sysmodel->yp()[13*i - 1 + 5] = parms2.Kpv * parms2.Vn; + sysmodel->yp()[13*i - 1 + 7] = (parms2.Kpc * parms2.Kpv * parms2.Vn) / parms2.Lf; + } + + //since the intial P_com = 0 + sysmodel->y()[vec_size_internals] = parms1.wb; + + + + sysmodel->initialize(); + sysmodel->evaluateResidual(); + + std::vector& fres = sysmodel->getResidual(); + std::cout << "Verify Intial Resisdual is Zero: {\n"; + for (size_t i = 0; i < fres.size(); i++) + { + printf("%u : %e \n", i, fres[i]); + } + std::cout << "}\n"; + + sysmodel->updateTime(0.0, 1.0e-8); + sysmodel->evaluateJacobian(); + std::cout << "Intial Jacobian with alpha:\n"; + // std::cout << sysmodel->getJacobian().frobnorm() << "\n"; + + + //Create numerical integrator and configure it for the generator model + AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); double t_init = 0.0; double t_final = 1.0; @@ -352,17 +352,17 @@ int main(int argc, char const *argv[]) idas->runSimulation(t_final); - std::vector& yfinial = sysmodel->y(); + std::vector& yfinial = sysmodel->y(); - std::cout << "Final Vector y\n"; - for (size_t i = 0; i < yfinial.size(); i++) - { - std::cout << yfinial[i] << "\n"; - } + std::cout << "Final Vector y\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << yfinial[i] << "\n"; + } - //Generate from MATLAB code ODE form with tolerances of 1e-12 - std::vectortrue_vec{ - 2.297543153595780e+04, + //Generate from MATLAB code ODE form with tolerances of 1e-12 + std::vectortrue_vec{ + 2.297543153595780e+04, 1.275311524125022e+04, 3.763060183116022e-02, -2.098153459325261e-02, @@ -432,13 +432,13 @@ int main(int argc, char const *argv[]) -3.272400970143252e+01, 3.604108939430972e+02, -3.492842627398574e+01 - }; + }; - std::cout << "Test the Relative Error\n"; - for (size_t i = 0; i < true_vec.size(); i++) - { - printf("%u : %e ,\n", i, abs(true_vec[i] - yfinial[i]) / abs(true_vec[i])); - } + std::cout << "Test the Relative Error\n"; + for (size_t i = 0; i < true_vec.size(); i++) + { + printf("%u : %e ,\n", i, abs(true_vec[i] - yfinial[i]) / abs(true_vec[i])); + } - return 0; + return 0; } diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp index 55fe476b9..770307d8c 100644 --- a/Examples/RLCircuit/RLCircuit.cpp +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -18,97 +18,97 @@ int main(int argc, char const *argv[]) { - double abstol = 1.0e-8; - double reltol = 1.0e-8; - bool usejac = true; - - //TODO:setup as named parameters - //Create circuit model - ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac); - - size_t idoff = 0; - - //RL circuit parameters - double rinit = 1.0; - double linit = 1.0; - double vinit = 1.0; - - - //inductor - ModelLib::Inductor* induct = new ModelLib::Inductor(idoff,linit); - //Form index to node uid realations - // input - induct->setExternalConnectionNodes(0,1); - //output - induct->setExternalConnectionNodes(1,-1); - //internal - induct->setExternalConnectionNodes(2,2); - //add component - sysmodel->addComponent(induct); - - - //resistor - idoff++; - ModelLib::Resistor* resis = new ModelLib::Resistor(idoff, rinit); - //Form index to node uid realations - //input - resis->setExternalConnectionNodes(0,0); - //output - resis->setExternalConnectionNodes(1,1); - //add - sysmodel->addComponent(resis); - - //voltage source - idoff++; - ModelLib::VoltageSource* vsource = new ModelLib::VoltageSource(idoff, vinit); - //Form index to node uid realations - //input - vsource->setExternalConnectionNodes(0,-1); - //output - vsource->setExternalConnectionNodes(1,0); - //internal - vsource->setExternalConnectionNodes(2,3); - - - sysmodel->addComponent(vsource); - - sysmodel->allocate(4); - - std::cout << sysmodel->y().size() << std::endl; - - //Grounding for IDA. If no grounding then circuit is \mu > 1 - //v_0 (grounded) - //Create Intial points - sysmodel->y()[0] = vinit; //v_1 - sysmodel->y()[1] = vinit; // v_2 - sysmodel->y()[2] = 0.0; // i_L - sysmodel->y()[3] = 0.0; // i_s - - sysmodel->yp()[0] = 0.0; // v'_1 - sysmodel->yp()[1] = 0.0; // v'_2 - sysmodel->yp()[2] = -vinit / linit; // i'_s - sysmodel->yp()[3] = -vinit / linit; // i'_L - - - sysmodel->initialize(); - sysmodel->evaluateResidual(); - - std::cout << "Verify Intial Resisdual is Zero: {"; - for (double i : sysmodel->getResidual()) - { - std::cout << i << ", "; - } - std::cout << "}\n"; - - - sysmodel->updateTime(0.0, 1.0); - sysmodel->evaluateJacobian(); - std::cout << "Intial Jacobian with alpha = 1:\n"; - sysmodel->getJacobian().printMatrix(); - - - // Create numerical integrator and configure it for the generator model - AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); + double abstol = 1.0e-8; + double reltol = 1.0e-8; + bool usejac = true; + + //TODO:setup as named parameters + //Create circuit model + ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac); + + size_t idoff = 0; + + //RL circuit parameters + double rinit = 1.0; + double linit = 1.0; + double vinit = 1.0; + + + //inductor + ModelLib::Inductor* induct = new ModelLib::Inductor(idoff,linit); + //Form index to node uid realations + // input + induct->setExternalConnectionNodes(0,1); + //output + induct->setExternalConnectionNodes(1,-1); + //internal + induct->setExternalConnectionNodes(2,2); + //add component + sysmodel->addComponent(induct); + + + //resistor + idoff++; + ModelLib::Resistor* resis = new ModelLib::Resistor(idoff, rinit); + //Form index to node uid realations + //input + resis->setExternalConnectionNodes(0,0); + //output + resis->setExternalConnectionNodes(1,1); + //add + sysmodel->addComponent(resis); + + //voltage source + idoff++; + ModelLib::VoltageSource* vsource = new ModelLib::VoltageSource(idoff, vinit); + //Form index to node uid realations + //input + vsource->setExternalConnectionNodes(0,-1); + //output + vsource->setExternalConnectionNodes(1,0); + //internal + vsource->setExternalConnectionNodes(2,3); + + + sysmodel->addComponent(vsource); + + sysmodel->allocate(4); + + std::cout << sysmodel->y().size() << std::endl; + + //Grounding for IDA. If no grounding then circuit is \mu > 1 + //v_0 (grounded) + //Create Intial points + sysmodel->y()[0] = vinit; //v_1 + sysmodel->y()[1] = vinit; // v_2 + sysmodel->y()[2] = 0.0; // i_L + sysmodel->y()[3] = 0.0; // i_s + + sysmodel->yp()[0] = 0.0; // v'_1 + sysmodel->yp()[1] = 0.0; // v'_2 + sysmodel->yp()[2] = -vinit / linit; // i'_s + sysmodel->yp()[3] = -vinit / linit; // i'_L + + + sysmodel->initialize(); + sysmodel->evaluateResidual(); + + std::cout << "Verify Intial Resisdual is Zero: {"; + for (double i : sysmodel->getResidual()) + { + std::cout << i << ", "; + } + std::cout << "}\n"; + + + sysmodel->updateTime(0.0, 1.0); + sysmodel->evaluateJacobian(); + std::cout << "Intial Jacobian with alpha = 1:\n"; + sysmodel->getJacobian().printMatrix(); + + + // Create numerical integrator and configure it for the generator model + AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); double t_init = 0.0; double t_final = 1.0; @@ -120,27 +120,27 @@ int main(int argc, char const *argv[]) idas->runSimulation(t_final); - std::vector& yfinial = sysmodel->y(); - - std::cout << "Final Vector y\n"; - for (size_t i = 0; i < yfinial.size(); i++) - { - std::cout << yfinial[i] << "\n"; - } - - std::vector yexact(4); - - //analytical solution to the circuit - yexact[0] = vinit; - yexact[2] = (vinit / rinit) * (exp(-(rinit / linit) * t_final) - 1.0); - yexact[3] = yexact[2]; - yexact[1] = vinit + rinit * yexact[2]; - - std::cout << "Element-wise Relative error at t=" << t_final << "\n"; - for (size_t i = 0; i < yfinial.size(); i++) - { - std::cout << abs((yfinial[i] - yexact[i]) / yexact[i]) << "\n"; - } - - return 0; + std::vector& yfinial = sysmodel->y(); + + std::cout << "Final Vector y\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << yfinial[i] << "\n"; + } + + std::vector yexact(4); + + //analytical solution to the circuit + yexact[0] = vinit; + yexact[2] = (vinit / rinit) * (exp(-(rinit / linit) * t_final) - 1.0); + yexact[3] = yexact[2]; + yexact[1] = vinit + rinit * yexact[2]; + + std::cout << "Element-wise Relative error at t=" << t_final << "\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << abs((yfinial[i] - yexact[i]) / yexact[i]) << "\n"; + } + + return 0; } diff --git a/Examples/SparseTest/SparseTest.cpp b/Examples/SparseTest/SparseTest.cpp index 81e5ac7dd..399151434 100644 --- a/Examples/SparseTest/SparseTest.cpp +++ b/Examples/SparseTest/SparseTest.cpp @@ -12,75 +12,75 @@ int main(int argc, char const *argv[]) { - std::vector val{0.1, 0.2, 0.3, 0.4}; - std::vector x{2,1,3,1}; - std::vector y{1,3,2,2}; - size_t n = 4; - size_t m = 4; - - COO_Matrix A = COO_Matrix(x,y,val,m,n); - - std::vector valn(4); - std::vector xn(4); - std::vector yn(4); - - std::tie(xn, yn, valn) = A.getEntries(); - - for (size_t i = 0; i < valn.size(); i++) - { - std::cout << valn[i] << "\n"; - } - - std::cout << "A:\n"; - A.printMatrix(); - - std::vector val2{0.5, 0.6, 0.7, 0.8, 1.0}; - std::vector x2{0,2,0,2,1}; - std::vector y2{3,3,2,2,3}; - COO_Matrix B = COO_Matrix(x2,y2,val2,m,n); - - std::cout << "B:\n"; - B.printMatrix(); - - A.AXPY(2.0, B); - - std::cout << "A + 2B:\n"; - A.printMatrix(); - - std::vector r; - std::vector c; - std::vector v; - std::tie(r,c,v) = A.getDataToCSR(); - - for (size_t i = 0; i < r.size() - 1; i++) - { - std::cout << r[i] << std::endl; - size_t rdiff = r[i+1] - r[i]; - for (size_t j = 0; j < rdiff; j++) - { - std::cout << c[j + r[i]] << ", " << v[j + r[i]] << std::endl; - } - } - std::cout << r[r.size()-1] << std::endl; - - //Basic Verification test - std::vector rtest = {0, 2, 4, 7, 8}; - std::vector ctest = {2,3,2,3,1,2,3,2}; - std::vector valtest = {1.4, 1.0, 0.4, 2.2, 0.1, 1.6, 1.2, 0.3}; - - assert(rtest.size() == r.size()); - assert(ctest.size() == c.size()); - assert(valtest.size() == v.size()); - - int failval = 0; - for (size_t i = 0; i < rtest.size(); i++) if (r[i] != rtest[i]) failval--; - for (size_t i = 0; i < ctest.size(); i++) - { - double vdiff = v[i] - valtest[i]; - if (c[i] != ctest[i] || -1e-14 > vdiff || vdiff > 1e-14) failval--; - } - - std::cout << failval << std::endl; - - return failval; + std::vector val{0.1, 0.2, 0.3, 0.4}; + std::vector x{2,1,3,1}; + std::vector y{1,3,2,2}; + size_t n = 4; + size_t m = 4; + + COO_Matrix A = COO_Matrix(x,y,val,m,n); + + std::vector valn(4); + std::vector xn(4); + std::vector yn(4); + + std::tie(xn, yn, valn) = A.getEntries(); + + for (size_t i = 0; i < valn.size(); i++) + { + std::cout << valn[i] << "\n"; + } + + std::cout << "A:\n"; + A.printMatrix(); + + std::vector val2{0.5, 0.6, 0.7, 0.8, 1.0}; + std::vector x2{0,2,0,2,1}; + std::vector y2{3,3,2,2,3}; + COO_Matrix B = COO_Matrix(x2,y2,val2,m,n); + + std::cout << "B:\n"; + B.printMatrix(); + + A.AXPY(2.0, B); + + std::cout << "A + 2B:\n"; + A.printMatrix(); + + std::vector r; + std::vector c; + std::vector v; + std::tie(r,c,v) = A.getDataToCSR(); + + for (size_t i = 0; i < r.size() - 1; i++) + { + std::cout << r[i] << std::endl; + size_t rdiff = r[i+1] - r[i]; + for (size_t j = 0; j < rdiff; j++) + { + std::cout << c[j + r[i]] << ", " << v[j + r[i]] << std::endl; + } + } + std::cout << r[r.size()-1] << std::endl; + + //Basic Verification test + std::vector rtest = {0, 2, 4, 7, 8}; + std::vector ctest = {2,3,2,3,1,2,3,2}; + std::vector valtest = {1.4, 1.0, 0.4, 2.2, 0.1, 1.6, 1.2, 0.3}; + + assert(rtest.size() == r.size()); + assert(ctest.size() == c.size()); + assert(valtest.size() == v.size()); + + int failval = 0; + for (size_t i = 0; i < rtest.size(); i++) if (r[i] != rtest[i]) failval--; + for (size_t i = 0; i < ctest.size(); i++) + { + double vdiff = v[i] - valtest[i]; + if (c[i] != ctest[i] || -1e-14 > vdiff || vdiff > 1e-14) failval--; + } + + std::cout << failval << std::endl; + + return failval; } diff --git a/SparseMatrix/COO_Matrix.hpp b/SparseMatrix/COO_Matrix.hpp index dc99d7b9e..70da77a1e 100644 --- a/SparseMatrix/COO_Matrix.hpp +++ b/SparseMatrix/COO_Matrix.hpp @@ -20,63 +20,63 @@ template class COO_Matrix { private: - std::vector values; - std::vector row_indexes; - std::vector column_indexes; - Intdx rows_size; - Intdx columns_size; - bool sorted; + std::vector values; + std::vector row_indexes; + std::vector column_indexes; + Intdx rows_size; + Intdx columns_size; + bool sorted; public: - //Constructors - COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n); - COO_Matrix(Intdx m, Intdx n); - COO_Matrix(); - ~COO_Matrix(); + //Constructors + COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n); + COO_Matrix(Intdx m, Intdx n); + COO_Matrix(); + ~COO_Matrix(); - //Operations + //Operations - // --- Functions which call sort --- - std::tuple, std::vector> getRowCopy(Intdx r); - std::tuple&, std::vector&, std::vector&> getEntries(); - std::tuple, std::vector, std::vector> getEntrieCopies(); - std::tuple, std::vector, std::vector> getEntrieCopiesSubMatrix(std::vector submap); + // --- Functions which call sort --- + std::tuple, std::vector> getRowCopy(Intdx r); + std::tuple&, std::vector&, std::vector&> getEntries(); + std::tuple, std::vector, std::vector> getEntrieCopies(); + std::tuple, std::vector, std::vector> getEntrieCopiesSubMatrix(std::vector submap); - std::tuple, std::vector, std::vector> getDataToCSR(); - std::vector getCSRRowData(); + std::tuple, std::vector, std::vector> getDataToCSR(); + std::vector getCSRRowData(); - // BLAS. Will sort before running - void setValues(std::vector r, std::vector c, std::vector v); - void AXPY(ScalarT alpha, COO_Matrix& a); - void AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v); - void SCAL(ScalarT alpha); - ScalarT frobnorm(); + // BLAS. Will sort before running + void setValues(std::vector r, std::vector c, std::vector v); + void AXPY(ScalarT alpha, COO_Matrix& a); + void AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v); + void SCAL(ScalarT alpha); + ScalarT frobnorm(); - // --- Permutation Operations --- - //No sorting is actually done. Only done when nesscary - void permutation(std::vector row_perm, std::vector col_perm); - void permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n); + // --- Permutation Operations --- + //No sorting is actually done. Only done when nesscary + void permutation(std::vector row_perm, std::vector col_perm); + void permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n); - void zeroMatrix(); + void zeroMatrix(); - void identityMatrix(Intdx n); + void identityMatrix(Intdx n); - //Resort values - void sortSparse(); - bool isSorted(); - Intdx nnz(); + //Resort values + void sortSparse(); + bool isSorted(); + Intdx nnz(); - std::tuple getDimensions(); + std::tuple getDimensions(); - void printMatrix(); + void printMatrix(); - - static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values); + + static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values); private: - Intdx indexStartRow(const std::vector &rows, Intdx r); - Intdx sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci); - bool checkIncreaseSize(Intdx r, Intdx c); + Intdx indexStartRow(const std::vector &rows, Intdx r); + Intdx sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci); + bool checkIncreaseSize(Intdx r, Intdx c); }; @@ -91,25 +91,25 @@ class COO_Matrix template inline std::tuple, std::vector> COO_Matrix::getRowCopy(Intdx r) { - if (!this->sorted) - { - this->sortSparse(); - } - Intdx rowindex = this->indexStartRow(r); - - - if (rowindex == -1) - { - return {std::vector(),std::vector()}; - } - - Intdx rsize = rowindex; - do - { - rsize++; - } while (rsize < this->values.size() && this->row_indexes[rsize] == r); - - return {{this->column_indexes.begin() + rowindex, this->column_indexes.begin() + rsize},{this->values.begin() + rowindex, this->values.begin() + rsize}}; + if (!this->sorted) + { + this->sortSparse(); + } + Intdx rowindex = this->indexStartRow(r); + + + if (rowindex == -1) + { + return {std::vector(),std::vector()}; + } + + Intdx rsize = rowindex; + do + { + rsize++; + } while (rsize < this->values.size() && this->row_indexes[rsize] == r); + + return {{this->column_indexes.begin() + rowindex, this->column_indexes.begin() + rsize},{this->values.begin() + rowindex, this->values.begin() + rsize}}; } /** @@ -122,11 +122,11 @@ inline std::tuple, std::vector> COO_Matrix inline std::tuple&, std::vector&, std::vector&> COO_Matrix::getEntries() { - if (!this->sorted) - { - this->sortSparse(); - } - return {this->row_indexes, this->column_indexes, this->values}; + if (!this->sorted) + { + this->sortSparse(); + } + return {this->row_indexes, this->column_indexes, this->values}; } /** @@ -139,11 +139,11 @@ inline std::tuple&, std::vector&, std::vector template inline std::tuple, std::vector, std::vector> COO_Matrix::getEntrieCopies() { - if (!this->sorted) - { - this->sortSparse(); - } - return {this->row_indexes, this->column_indexes, this->values}; + if (!this->sorted) + { + this->sortSparse(); + } + return {this->row_indexes, this->column_indexes, this->values}; } /** @@ -156,19 +156,19 @@ inline std::tuple, std::vector, std::vector> template inline std::tuple, std::vector, std::vector> COO_Matrix::getDataToCSR() { - if (!this->isSorted()) this->sortSparse(); - std::vector rowsizevec(this->rows_size + 1, 0); - Intdx counter = 0; - for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) - { - rowsizevec[i + 1] = rowsizevec[i]; - while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) - { - rowsizevec[i+1]++; - counter++; - } - } - return {rowsizevec, this->column_indexes, this->values}; + if (!this->isSorted()) this->sortSparse(); + std::vector rowsizevec(this->rows_size + 1, 0); + Intdx counter = 0; + for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) + { + rowsizevec[i + 1] = rowsizevec[i]; + while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) + { + rowsizevec[i+1]++; + counter++; + } + } + return {rowsizevec, this->column_indexes, this->values}; } /** @@ -185,19 +185,19 @@ inline std::tuple, std::vector, std::vector> template inline std::vector COO_Matrix::getCSRRowData() { - if (!this->isSorted()) this->sortSparse(); - std::vector rowsizevec(this->rows_size + 1, 0); - Intdx counter = 0; - for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) - { - rowsizevec[i + 1] = rowsizevec[i]; - while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) - { - rowsizevec[i+1]++; - counter++; - } - } - return rowsizevec; + if (!this->isSorted()) this->sortSparse(); + std::vector rowsizevec(this->rows_size + 1, 0); + Intdx counter = 0; + for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) + { + rowsizevec[i + 1] = rowsizevec[i]; + while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) + { + rowsizevec[i+1]++; + counter++; + } + } + return rowsizevec; } /** @@ -212,44 +212,44 @@ inline std::vector COO_Matrix::getCSRRowData() template inline void COO_Matrix::setValues(std::vector r, std::vector c, std::vector v) { - //sort input - this->sortSparseCOO(r, c, v); - - - //Duplicated with AXPY. Could replace with function depdent on lambda expression - Intdx aiter = 0; - //iterate for all current values in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) - { - //pushback values when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) - { - this->row_indexes.push_back(r[aiter]); - this->column_indexes.push_back(c[aiter]); - this->values.push_back(v[aiter]); - this->checkIncreaseSize(r[aiter], c[aiter]); - aiter++; - } - if (aiter >= static_cast(r.size())) break; - - - if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) - { - this->values[i] = v[aiter]; - aiter++; - } - } - //push back rest that was not found sorted - for (Intdx i = aiter; i < static_cast(r.size()); i++) - { - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(v[i]); - - this->checkIncreaseSize(r[i], c[i]); - } - - this->sorted = false; + //sort input + this->sortSparseCOO(r, c, v); + + + //Duplicated with AXPY. Could replace with function depdent on lambda expression + Intdx aiter = 0; + //iterate for all current values in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + { + //pushback values when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + { + this->row_indexes.push_back(r[aiter]); + this->column_indexes.push_back(c[aiter]); + this->values.push_back(v[aiter]); + this->checkIncreaseSize(r[aiter], c[aiter]); + aiter++; + } + if (aiter >= static_cast(r.size())) break; + + + if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + { + this->values[i] = v[aiter]; + aiter++; + } + } + //push back rest that was not found sorted + for (Intdx i = aiter; i < static_cast(r.size()); i++) + { + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(v[i]); + + this->checkIncreaseSize(r[i], c[i]); + } + + this->sorted = false; } @@ -264,60 +264,60 @@ inline void COO_Matrix::setValues(std::vector r, std::vec template inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrix& a) { - if (alpha == 0) return; - - if (!this->sorted) - { - this->sortSparse(); - } - if (!a.isSorted()) - { - a.sortSparse(); - } - Intdx m = 0; - Intdx n = 0; - std::tuple&, std::vector&, std::vector&> tpm = a.getEntries(); - const auto& [r, c, val] = tpm; - std::tie(m,n) = a.getDimensions(); - - //Increase size as nesscary - this->rows_size = this->rows_size > m ? this->rows_size : m; - this->columns_size = this->columns_size > n ? this->columns_size : n; - - Intdx aiter = 0; - //iterate for all current values in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) - { - //pushback values when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) - { - this->row_indexes.push_back(r[aiter]); - this->column_indexes.push_back(c[aiter]); - this->values.push_back(alpha * val[aiter]); - - this->checkIncreaseSize(r[aiter], c[aiter]); - aiter++; - } - if (aiter >= static_cast(r.size())) break; - - - if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) - { - this->values[i] += alpha * val[aiter]; - aiter++; - } - } - //push back rest that was not found sorted - for (Intdx i = aiter; i < static_cast(r.size()); i++) - { - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(alpha * val[i]); - - this->checkIncreaseSize(r[i], c[i]); - } - - this->sorted = false; + if (alpha == 0) return; + + if (!this->sorted) + { + this->sortSparse(); + } + if (!a.isSorted()) + { + a.sortSparse(); + } + Intdx m = 0; + Intdx n = 0; + std::tuple&, std::vector&, std::vector&> tpm = a.getEntries(); + const auto& [r, c, val] = tpm; + std::tie(m,n) = a.getDimensions(); + + //Increase size as nesscary + this->rows_size = this->rows_size > m ? this->rows_size : m; + this->columns_size = this->columns_size > n ? this->columns_size : n; + + Intdx aiter = 0; + //iterate for all current values in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + { + //pushback values when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + { + this->row_indexes.push_back(r[aiter]); + this->column_indexes.push_back(c[aiter]); + this->values.push_back(alpha * val[aiter]); + + this->checkIncreaseSize(r[aiter], c[aiter]); + aiter++; + } + if (aiter >= static_cast(r.size())) break; + + + if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + { + this->values[i] += alpha * val[aiter]; + aiter++; + } + } + //push back rest that was not found sorted + for (Intdx i = aiter; i < static_cast(r.size()); i++) + { + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(alpha * val[i]); + + this->checkIncreaseSize(r[i], c[i]); + } + + this->sorted = false; } /** @@ -333,50 +333,50 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrix inline void COO_Matrix::AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v) { - if (alpha == 0) return; - - if (!this->sorted) - { - this->sortSparse(); - } - - //sort input - this->sortSparseCOO(r, c, v); - - Intdx aiter = 0; - //iterate for all current values in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) - { - //pushback values when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) - { - this->row_indexes.push_back(r[aiter]); - this->column_indexes.push_back(c[aiter]); - this->values.push_back(alpha * v[aiter]); - - this->checkIncreaseSize(r[aiter], c[aiter]); - aiter++; - } - if (aiter >= static_cast(r.size())) break; - - - if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) - { - this->values[i] += alpha * v[aiter]; - aiter++; - } - } - //push back rest that was not found sorted - for (Intdx i = aiter; i < static_cast(r.size()); i++) - { - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(alpha * v[i]); - - this->checkIncreaseSize(r[i], c[i]); - } - - this->sorted = false; + if (alpha == 0) return; + + if (!this->sorted) + { + this->sortSparse(); + } + + //sort input + this->sortSparseCOO(r, c, v); + + Intdx aiter = 0; + //iterate for all current values in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + { + //pushback values when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + { + this->row_indexes.push_back(r[aiter]); + this->column_indexes.push_back(c[aiter]); + this->values.push_back(alpha * v[aiter]); + + this->checkIncreaseSize(r[aiter], c[aiter]); + aiter++; + } + if (aiter >= static_cast(r.size())) break; + + + if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + { + this->values[i] += alpha * v[aiter]; + aiter++; + } + } + //push back rest that was not found sorted + for (Intdx i = aiter; i < static_cast(r.size()); i++) + { + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(alpha * v[i]); + + this->checkIncreaseSize(r[i], c[i]); + } + + this->sorted = false; } /** @@ -389,15 +389,15 @@ inline void COO_Matrix::AXPY(ScalarT alpha, std::vector r template inline void COO_Matrix::SCAL(ScalarT alpha) { - for (auto i = this->values.begin(); i < this->values.end(); i++) *i *= alpha; + for (auto i = this->values.begin(); i < this->values.end(); i++) *i *= alpha; } template inline ScalarT COO_Matrix::frobnorm() { - ScalarT totsum = 0.0; - for (auto i = this->values.begin(); i < this->values.end(); i++) totsum += abs(*i)^2; - return totsum; + ScalarT totsum = 0.0; + for (auto i = this->values.begin(); i < this->values.end(); i++) totsum += abs(*i)^2; + return totsum; } /** @@ -411,16 +411,16 @@ inline ScalarT COO_Matrix::frobnorm() template inline void COO_Matrix::permutation(std::vector row_perm, std::vector col_perm) { - assert(row_perm.size() = this->rows_size); - assert(col_perm.size() = this->columns_size); - - for (int i = 0; i < this->values.size(); i++) - { - this->row_indexes[i] = row_perm[this->row_indexes[i]]; - this->column_indexes[i] = col_perm[this->column_indexes[i]]; - } - this->sorted = false; - //cycle sorting maybe useful since permutations are already known + assert(row_perm.size() = this->rows_size); + assert(col_perm.size() = this->columns_size); + + for (int i = 0; i < this->values.size(); i++) + { + this->row_indexes[i] = row_perm[this->row_indexes[i]]; + this->column_indexes[i] = col_perm[this->column_indexes[i]]; + } + this->sorted = false; + //cycle sorting maybe useful since permutations are already known } /** @@ -437,25 +437,25 @@ inline void COO_Matrix::permutation(std::vector row_perm, template inline void COO_Matrix::permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n) { - assert(row_perm.size() == this->rows_size); - assert(col_perm.size() == this->columns_size); - - this->rows_size = m; - this->columns_size = n; - - for (int i = 0; i < this->values.size(); i++) - { - if (row_perm[this->row_indexes[i]] == -1 || col_perm[this->column_indexes[i]] == -1) - { - this->values[i] = 0; - } - else - { - this->row_indexes[i] = row_perm[this->row_indexes[i]]; - this->column_indexes[i] = col_perm[this->column_indexes[i]]; - } - } - this->sorted = false; + assert(row_perm.size() == this->rows_size); + assert(col_perm.size() == this->columns_size); + + this->rows_size = m; + this->columns_size = n; + + for (int i = 0; i < this->values.size(); i++) + { + if (row_perm[this->row_indexes[i]] == -1 || col_perm[this->column_indexes[i]] == -1) + { + this->values[i] = 0; + } + else + { + this->row_indexes[i] = row_perm[this->row_indexes[i]]; + this->column_indexes[i] = col_perm[this->column_indexes[i]]; + } + } + this->sorted = false; } /** @@ -467,25 +467,25 @@ inline void COO_Matrix::permutationSizeMap(std::vector ro template inline void COO_Matrix::zeroMatrix() { - //resize doesn't effect capacity if smaller - this->column_indexes.resize(0); - this->row_indexes.resize(0); - this->values.resize(0); - this->sorted = true; + //resize doesn't effect capacity if smaller + this->column_indexes.resize(0); + this->row_indexes.resize(0); + this->values.resize(0); + this->sorted = true; } template inline void COO_Matrix::identityMatrix(Intdx n) { - //Reset Matrix - this->zeroMatrix(); - for (Intdx i = 0; i < n; i++) - { - this->column_indexes[i] = i; - this->row_indexes[i] = i; - this->values[i] = 1.0; - } - this->sorted = true; + //Reset Matrix + this->zeroMatrix(); + for (Intdx i = 0; i < n; i++) + { + this->column_indexes[i] = i; + this->row_indexes[i] = i; + this->values[i] = 1.0; + } + this->sorted = true; } /** @@ -497,26 +497,26 @@ inline void COO_Matrix::identityMatrix(Intdx n) template inline void COO_Matrix::sortSparse() { - this->sortSparseCOO(this->row_indexes, this->column_indexes, this->values); - this->sorted = true; + this->sortSparseCOO(this->row_indexes, this->column_indexes, this->values); + this->sorted = true; } template inline bool COO_Matrix::isSorted() { - return this->sorted; + return this->sorted; } template inline Intdx COO_Matrix::nnz() { - return static_cast(this->values.size); + return static_cast(this->values.size); } template inline std::tuple COO_Matrix::getDimensions() { - return std::tuple(this->rows_size, this->columns_size); + return std::tuple(this->rows_size, this->columns_size); } /** @@ -528,19 +528,19 @@ inline std::tuple COO_Matrix::getDimensions() template inline void COO_Matrix::printMatrix() { - if (this->sorted == false) - { - this->sortSparse(); - } - - std::cout << "Sparse COO Matrix\n"; - std::cout << "(x , y, value)\n"; - for (size_t i = 0; i < this->values.size(); i++) - { - std::cout << "(" << this->row_indexes[i] - << ", " << this->column_indexes[i] - << ", " << this->values[i] << ")\n"; - } + if (this->sorted == false) + { + this->sortSparse(); + } + + std::cout << "Sparse COO Matrix\n"; + std::cout << "(x , y, value)\n"; + for (size_t i = 0; i < this->values.size(); i++) + { + std::cout << "(" << this->row_indexes[i] + << ", " << this->column_indexes[i] + << ", " << this->values[i] << ")\n"; + } } /** @@ -555,36 +555,36 @@ inline void COO_Matrix::printMatrix() template inline Intdx COO_Matrix::indexStartRow(const std::vector &rows, Intdx r) { - //Specialized Binary Search for Lowest Row - Intdx i1 = 0; - Intdx i2 = rows->size()-1; - Intdx m_smallest = -1; - Intdx m = -1; - while (i1 <= i2) - { - m = (i2 + i1) / 2; - //rows - if (rows[m] < r) - { - i1 = m + 1; - } - else if (r < rows[m]) - { - i2 = m - 1; - } - else - { - if (i1 == i2) - { - return m_smallest; - } - - //Keep track of smallest cordinate - m_smallest = m; - i2 = m - 1; - } - } - return m_smallest; + //Specialized Binary Search for Lowest Row + Intdx i1 = 0; + Intdx i2 = rows->size()-1; + Intdx m_smallest = -1; + Intdx m = -1; + while (i1 <= i2) + { + m = (i2 + i1) / 2; + //rows + if (rows[m] < r) + { + i1 = m + 1; + } + else if (r < rows[m]) + { + i2 = m - 1; + } + else + { + if (i1 == i2) + { + return m_smallest; + } + + //Keep track of smallest cordinate + m_smallest = m; + i2 = m - 1; + } + } + return m_smallest; } /** @@ -601,56 +601,56 @@ inline Intdx COO_Matrix::indexStartRow(const std::vector template inline Intdx COO_Matrix::sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci) { - assert(rows.size() == columns.size()); - //basic binary search - Intdx i1 = 0; - Intdx i2 = rows.size()-1; - Intdx m = 0; - while (i1 <= i2) - { - m = (i2 + i1) / 2; - //rows - if (rows[m] < ri) - { - i1 = m + 1; - } - else if (ri < rows[m]) - { - i2 = m - 1; - } - else - { - if (columns[m] < ci) - { - i1 = m + 1; - } - else if (ci < columns[m]) - { - i2 = m - 1; - } - break; - } - } - - return m; + assert(rows.size() == columns.size()); + //basic binary search + Intdx i1 = 0; + Intdx i2 = rows.size()-1; + Intdx m = 0; + while (i1 <= i2) + { + m = (i2 + i1) / 2; + //rows + if (rows[m] < ri) + { + i1 = m + 1; + } + else if (ri < rows[m]) + { + i2 = m - 1; + } + else + { + if (columns[m] < ci) + { + i1 = m + 1; + } + else if (ci < columns[m]) + { + i2 = m - 1; + } + break; + } + } + + return m; } template inline bool COO_Matrix::checkIncreaseSize(Intdx r, Intdx c) { - bool changed = false; - if (r + 1 > this->rows_size) - { - this->rows_size = r + 1; - changed = true; - } - if (c + 1 > this->columns_size) - { - this->columns_size = c + 1; - changed = true; - } - - return changed; + bool changed = false; + if (r + 1 > this->rows_size) + { + this->rows_size = r + 1; + changed = true; + } + if (c + 1 > this->columns_size) + { + this->columns_size = c + 1; + changed = true; + } + + return changed; } /** @@ -667,75 +667,75 @@ inline bool COO_Matrix::checkIncreaseSize(Intdx r, Intdx c) template inline void COO_Matrix::sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values) { - - //index based sort code - // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted-vector - //cannot call sort since two arrays are used instead + + //index based sort code + // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted-vector + //cannot call sort since two arrays are used instead std::vector ordervec(rows.size()); std::size_t n(0); std::generate(std::begin(ordervec), std::end(ordervec), [&]{ return n++; }); - //Sort by row first then column. + //Sort by row first then column. std::sort( std::begin(ordervec), std::end(ordervec), [&](int i1, int i2) { return (rows[i1] < rows[i2]) || - (rows[i1] == rows[i2] && columns[i1] < columns[i2]); } ); - - - //reorder based of index-sorting. Only swap cost no extra memory. - // @todo see if extra memory creation is fine - // https://stackoverflow.com/a/22183350 - for (size_t i = 0; i < ordervec.size(); i++) - { - //permutation swap - while (ordervec[i] != ordervec[ordervec[i]]) - { - std::swap(rows[ordervec[i]], rows[ordervec[ordervec[i]]]); - std::swap(columns[ordervec[i]], columns[ordervec[ordervec[i]]]); - std::swap(values[ordervec[i]], values[ordervec[ordervec[i]]]); - - //swap orderings - std::swap(ordervec[i], ordervec[ordervec[i]]); - } - - } + (rows[i1] == rows[i2] && columns[i1] < columns[i2]); } ); + + + //reorder based of index-sorting. Only swap cost no extra memory. + // @todo see if extra memory creation is fine + // https://stackoverflow.com/a/22183350 + for (size_t i = 0; i < ordervec.size(); i++) + { + //permutation swap + while (ordervec[i] != ordervec[ordervec[i]]) + { + std::swap(rows[ordervec[i]], rows[ordervec[ordervec[i]]]); + std::swap(columns[ordervec[i]], columns[ordervec[ordervec[i]]]); + std::swap(values[ordervec[i]], values[ordervec[ordervec[i]]]); + + //swap orderings + std::swap(ordervec[i], ordervec[ordervec[i]]); + } + + } } template inline COO_Matrix::COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n) { - this->values = v; - this->row_indexes = r; - this->column_indexes = c; - this->rows_size = m; - this->columns_size = n; - this->sorted = false; + this->values = v; + this->row_indexes = r; + this->column_indexes = c; + this->rows_size = m; + this->columns_size = n; + this->sorted = false; } template inline COO_Matrix::COO_Matrix(Intdx m, Intdx n) { - this->rows_size = m; - this->columns_size = n; - this->values = std::vector(); - this->row_indexes = std::vector(); - this->column_indexes = std::vector(); - this->sorted = false; + this->rows_size = m; + this->columns_size = n; + this->values = std::vector(); + this->row_indexes = std::vector(); + this->column_indexes = std::vector(); + this->sorted = false; } template inline COO_Matrix::COO_Matrix() { - this->rows_size = 0; - this->columns_size = 0; - this->values = std::vector(); - this->row_indexes = std::vector(); - this->column_indexes = std::vector(); - this->sorted = false; + this->rows_size = 0; + this->columns_size = 0; + this->values = std::vector(); + this->row_indexes = std::vector(); + this->column_indexes = std::vector(); + this->sorted = false; } template COO_Matrix::~COO_Matrix() { - + } From f8d6943fda095c46aa8878857a6d50718f3dd4f8 Mon Sep 17 00:00:00 2001 From: Reid Date: Tue, 9 Apr 2024 21:57:45 -0400 Subject: [PATCH 18/44] Formatting Fix Composer-Dev (#6) * Merge Ida Fix * Fixed Whitespace Editor Changes * Tabs to Spaces Ida.cpp --- ModelEvaluatorImpl.hpp | 99 ++-- Solver/Dynamic/Ida.cpp | 1069 ++++++++++++++++++++-------------------- 2 files changed, 593 insertions(+), 575 deletions(-) diff --git a/ModelEvaluatorImpl.hpp b/ModelEvaluatorImpl.hpp index 3e9a4cef6..0f8969f0b 100644 --- a/ModelEvaluatorImpl.hpp +++ b/ModelEvaluatorImpl.hpp @@ -77,28 +77,27 @@ namespace ModelLib typedef typename ModelEvaluator::real_type real_type; ModelEvaluatorImpl() - : size_(0), - size_quad_(0), - size_opt_(0) - { - } + : size_(0), + size_quad_(0), + size_opt_(0) + {} ModelEvaluatorImpl(IdxT size, IdxT size_quad, IdxT size_opt) - : size_(size), - size_quad_(size_quad), - size_opt_(size_opt), - y_(size_), - yp_(size_), - f_(size_), - g_(size_quad_), - yB_(size_), - ypB_(size_), - fB_(size_), - gB_(size_opt_), - J_(COO_Matrix()), - param_(size_opt_), - param_up_(size_opt_), - param_lo_(size_opt_) + : size_(size), + size_quad_(size_quad), + size_opt_(size_opt), + y_(size_), + yp_(size_), + f_(size_), + g_(size_quad_), + yB_(size_), + ypB_(size_), + fB_(size_), + gB_(size_opt_), + J_(COO_Matrix()), + param_(size_opt_), + param_up_(size_opt_), + param_lo_(size_opt_) { } @@ -134,143 +133,143 @@ namespace ModelLib // std::cout << "updateTime: t = " << time_ << "\n"; // } - virtual void setTolerances(real_type &rtol, real_type &atol) const + virtual void setTolerances(real_type& rtol, real_type& atol) const { rtol = rtol_; atol = atol_; } - virtual void setMaxSteps(IdxT &msa) const + virtual void setMaxSteps(IdxT& msa) const { msa = max_steps_; } - std::vector &y() + std::vector& y() { return y_; } - const std::vector &y() const + const std::vector& y() const { return y_; } - std::vector &yp() + std::vector& yp() { return yp_; } - const std::vector &yp() const + const std::vector& yp() const { return yp_; } - std::vector &tag() + std::vector& tag() { return tag_; } - const std::vector &tag() const + const std::vector& tag() const { return tag_; } - std::vector &yB() + std::vector& yB() { return yB_; } - const std::vector &yB() const + const std::vector& yB() const { return yB_; } - std::vector &ypB() + std::vector& ypB() { return ypB_; } - const std::vector &ypB() const + const std::vector& ypB() const { return ypB_; } - std::vector ¶m() + std::vector& param() { return param_; } - const std::vector ¶m() const + const std::vector& param() const { return param_; } - std::vector ¶m_up() + std::vector& param_up() { return param_up_; } - const std::vector ¶m_up() const + const std::vector& param_up() const { return param_up_; } - std::vector ¶m_lo() + std::vector& param_lo() { return param_lo_; } - const std::vector ¶m_lo() const + const std::vector& param_lo() const { return param_lo_; } - std::vector &getResidual() + std::vector& getResidual() { return f_; } - const std::vector &getResidual() const + const std::vector& getResidual() const { return f_; } - COO_Matrix &getJacobian() + COO_Matrix& getJacobian() { return J_; } - const COO_Matrix &getJacobian() const + const COO_Matrix& getJacobian() const { return J_; } - std::vector &getIntegrand() + std::vector& getIntegrand() { return g_; } - const std::vector &getIntegrand() const + const std::vector& getIntegrand() const { return g_; } - std::vector &getAdjointResidual() + std::vector& getAdjointResidual() { return fB_; } - const std::vector &getAdjointResidual() const + const std::vector& getAdjointResidual() const { return fB_; } - std::vector &getAdjointIntegrand() + std::vector& getAdjointIntegrand() { return gB_; } - const std::vector &getAdjointIntegrand() const + const std::vector& getAdjointIntegrand() const { return gB_; } @@ -281,6 +280,8 @@ namespace ModelLib return idc_; } + + protected: IdxT size_; IdxT nnz_; @@ -313,8 +314,10 @@ namespace ModelLib IdxT max_steps_; IdxT idc_; + }; + } // namespace ModelLib #endif // _MODEL_EVALUATOR_IMPL_HPP_ \ No newline at end of file diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index 3ae6854c4..fbe7c8973 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -57,703 +57,718 @@ * */ + #include #include -#include /* access to IDADls interface */ +#include /* access to IDADls interface */ #include -// Sundials Sparse KLU +//Sundials Sparse KLU #include -#include +#include #include "ModelEvaluator.hpp" #include "Ida.hpp" + namespace AnalysisManager { - namespace Sundials - { +namespace Sundials +{ - template - Ida::Ida(ModelLib::ModelEvaluator *model) : DynamicSolver(model) - { - int retval = 0; + template + Ida::Ida(ModelLib::ModelEvaluator* model) : DynamicSolver(model) + { + int retval = 0; - // Create the SUNDIALS context that all SUNDIALS objects require - retval = SUNContext_Create(NULL, &context_); - checkOutput(retval, "SUNContext"); - solver_ = IDACreate(context_); - tag_ = NULL; - } + // Create the SUNDIALS context that all SUNDIALS objects require + retval = SUNContext_Create(NULL, &context_); + checkOutput(retval, "SUNContext"); + solver_ = IDACreate(context_); + tag_ = NULL; + } - template - Ida::~Ida() - { - } + template + Ida::~Ida() + { + } - template - int Ida::configureSimulation() - { - int retval = 0; + template + int Ida::configureSimulation() + { + int retval = 0; - // Allocate solution vectors - yy_ = N_VNew_Serial(model_->size(), context_); - checkAllocation((void *)yy_, "N_VNew_Serial"); - yp_ = N_VClone(yy_); - checkAllocation((void *)yp_, "N_VClone"); + // Allocate solution vectors + yy_ = N_VNew_Serial(model_->size(), context_); + checkAllocation((void*) yy_, "N_VNew_Serial"); + yp_ = N_VClone(yy_); + checkAllocation((void*) yp_, "N_VClone"); - // get intial conditions - this->getDefaultInitialCondition(); + //get intial conditions + this->getDefaultInitialCondition(); - // Create vectors to store restart initial condition - yy0_ = N_VClone(yy_); - checkAllocation((void *)yy0_, "N_VClone"); - yp0_ = N_VClone(yy_); - checkAllocation((void *)yp0_, "N_VClone"); + // Create vectors to store restart initial condition + yy0_ = N_VClone(yy_); + checkAllocation((void*) yy0_, "N_VClone"); + yp0_ = N_VClone(yy_); + checkAllocation((void*) yp0_, "N_VClone"); - // Dummy initial time; will be overridden. - const realtype t0 = RCONST(0.0); + // Dummy initial time; will be overridden. + const realtype t0 = RCONST(0.0); - // Allocate and initialize IDA workspace - retval = IDAInit(solver_, this->Residual, t0, yy_, yp_); - checkOutput(retval, "IDAInit"); + // Allocate and initialize IDA workspace + retval = IDAInit(solver_, this->Residual, t0, yy_, yp_); + checkOutput(retval, "IDAInit"); - // Set pointer to model data - retval = IDASetUserData(solver_, model_); - checkOutput(retval, "IDASetUserData"); + // Set pointer to model data + retval = IDASetUserData(solver_, model_); + checkOutput(retval, "IDASetUserData"); - // Set tolerances - realtype rtol; - realtype atol; + // Set tolerances + realtype rtol; + realtype atol; - model_->setTolerances(rtol, atol); ///< \todo Function name should be "getTolerances"! - retval = IDASStolerances(solver_, rtol, atol); - checkOutput(retval, "IDASStolerances"); + model_->setTolerances(rtol, atol); ///< \todo Function name should be "getTolerances"! + retval = IDASStolerances(solver_, rtol, atol); + checkOutput(retval, "IDASStolerances"); + + IdxT msa; + model_->setMaxSteps(msa); - IdxT msa; - model_->setMaxSteps(msa); + /// \todo Need to set max number of steps based on user input! + retval = IDASetMaxNumSteps(solver_, msa); + checkOutput(retval, "IDASetMaxNumSteps"); - /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumSteps(solver_, msa); - checkOutput(retval, "IDASetMaxNumSteps"); + // Tag differential variables + std::vector& tag = model_->tag(); + if (static_cast(tag.size()) == model_->size()) + { + tag_ = N_VClone(yy_); + checkAllocation((void*) tag_, "N_VClone"); + model_->tagDifferentiable(); + copyVec(tag, tag_); - // Tag differential variables - std::vector &tag = model_->tag(); - if (static_cast(tag.size()) == model_->size()) - { - tag_ = N_VClone(yy_); - checkAllocation((void *)tag_, "N_VClone"); - model_->tagDifferentiable(); - copyVec(tag, tag_); - - retval = IDASetId(solver_, tag_); - checkOutput(retval, "IDASetId"); - retval = IDASetSuppressAlg(solver_, SUNTRUE); - checkOutput(retval, "IDASetSuppressAlg"); - } + retval = IDASetId(solver_, tag_); + checkOutput(retval, "IDASetId"); + retval = IDASetSuppressAlg(solver_, SUNTRUE); + checkOutput(retval, "IDASetSuppressAlg"); + } - // Set up linear solver - this->configureLinearSolver(); + // Set up linear solver + this->configureLinearSolver(); - return retval; - } + return retval; + } - template - int Ida::configureLinearSolver() + template + int Ida::configureLinearSolver() + { + int retval = 0; + if (model_->hasJacobian()) { - int retval = 0; - //Setup KLU for when Jacobian is needed - if (model_->hasJacobian()) - { - JacobianMat_ = SUNSparseMatrix(model_->size(), model_->size(), model_->size() * model_->size(), CSR_MAT, context_); - checkAllocation((void *)JacobianMat_, "SUNSparseMatrix"); + JacobianMat_ = SUNSparseMatrix(model_->size(), model_->size(), model_->size() * model_->size(), CSR_MAT, context_); + checkAllocation((void*) JacobianMat_, "SUNSparseMatrix"); - linearSolver_ = SUNLinSol_KLU(yy_, JacobianMat_, context_); - checkAllocation((void *)linearSolver_, "SUNLinSol_KLU"); + linearSolver_ = SUNLinSol_KLU(yy_, JacobianMat_, context_); + checkAllocation((void*) linearSolver_, "SUNLinSol_KLU"); - retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "IDASetLinearSolver"); + retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "IDASetLinearSolver"); - retval = IDASetJacFn(solver_, this->Jac); - checkOutput(retval, "IDASetJacFn"); - } - else - { - JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void *)JacobianMat_, "SUNDenseMatrix"); + retval = IDASetJacFn(solver_, this->Jac); + checkOutput(retval, "IDASetJacFn"); + } + else + { + JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); - linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); - checkAllocation((void *)linearSolver_, "SUNLinSol_Dense"); + linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); + checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); - retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "IDASetLinearSolver"); - } + retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "IDASetLinearSolver"); - return retval; } - template - int Ida::getDefaultInitialCondition() - { - model_->initialize(); + return retval; + } - copyVec(model_->y(), yy_); - copyVec(model_->yp(), yp_); + template + int Ida::getDefaultInitialCondition() + { + model_->initialize(); - return 0; - } + copyVec(model_->y(), yy_); + copyVec(model_->yp(), yp_); - template - int Ida::setIntegrationTime(real_type t_init, real_type t_final, int nout) - { - t_init_ = t_init; - t_final_ = t_final; - nout_ = nout; - return 0; - } + return 0; + } - template - int Ida::initializeSimulation(real_type t0, bool findConsistent) - { - int retval = 0; + template + int Ida::setIntegrationTime(real_type t_init, real_type t_final, int nout) + { + t_init_ = t_init; + t_final_ = t_final; + nout_ = nout; + return 0; + } + + template + int Ida::initializeSimulation(real_type t0, bool findConsistent) + { + int retval = 0; - // Need to reinitialize IDA to set to get correct initial conditions - retval = IDAReInit(solver_, t0, yy_, yp_); - checkOutput(retval, "IDAReInit"); + // Need to reinitialize IDA to set to get correct initial conditions + retval = IDAReInit(solver_, t0, yy_, yp_); + checkOutput(retval, "IDAReInit"); - // Find a consistent set of initial conditions for DAE - if (findConsistent) - { - int initType = IDA_Y_INIT; - - if (tag_) - initType = IDA_YA_YDP_INIT; + // Find a consistent set of initial conditions for DAE + if (findConsistent) + { + int initType = IDA_Y_INIT; - retval = IDACalcIC(solver_, initType, 0.1); - checkOutput(retval, "IDACalcIC"); - } + if (tag_) + initType = IDA_YA_YDP_INIT; - return retval; + retval = IDACalcIC(solver_, initType, 0.1); + checkOutput(retval, "IDACalcIC"); } - template - int Ida::runSimulation(real_type tf, int nout) - { - int retval = 0; - int iout = 0; - real_type tret; - real_type dt = tf / nout; - real_type tout = dt; - - /* In loop, call IDASolve, print results, and test for error. - * Break out of loop when NOUT preset output times have been reached. */ - // printOutput(0.0); - while (nout > iout) + return retval; + } + + template + int Ida::runSimulation(real_type tf, int nout) + { + int retval = 0; + int iout = 0; + real_type tret; + real_type dt = tf/nout; + real_type tout = dt; + + /* In loop, call IDASolve, print results, and test for error. + * Break out of loop when NOUT preset output times have been reached. */ + //printOutput(0.0); + while(nout > iout) + { + retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); + checkOutput(retval, "IDASolve"); + //printOutput(tout); + + if (retval == IDA_SUCCESS) { - retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); - checkOutput(retval, "IDASolve"); - // printOutput(tout); - - if (retval == IDA_SUCCESS) - { - ++iout; - tout += dt; - } + ++iout; + tout += dt; } - // std::cout << "\n"; - return retval; } + //std::cout << "\n"; + return retval; + } - template - int Ida::deleteSimulation() - { - IDAFree(&solver_); - SUNLinSolFree(linearSolver_); - N_VDestroy(yy_); - N_VDestroy(yp_); - return 0; - } + template + int Ida::deleteSimulation() + { + IDAFree(&solver_); + SUNLinSolFree(linearSolver_); + N_VDestroy(yy_); + N_VDestroy(yp_); + return 0; + } - template - int Ida::configureQuadrature() - { - int retval = 0; - // Create and initialize quadratures - q_ = N_VNew_Serial(model_->size_quad(), context_); - checkAllocation((void *)q_, "N_VNew_Serial"); + template + int Ida::configureQuadrature() + { + int retval = 0; - // Set integrand function and allocate quadrature workspace - retval = IDAQuadInit(solver_, this->Integrand, q_); - checkOutput(retval, "IDAQuadInit"); + // Create and initialize quadratures + q_ = N_VNew_Serial(model_->size_quad(), context_); + checkAllocation((void*) q_, "N_VNew_Serial"); - // Set tolerances and error control for quadratures - real_type rtol, atol; - model_->setTolerances(rtol, atol); + // Set integrand function and allocate quadrature workspace + retval = IDAQuadInit(solver_, this->Integrand, q_); + checkOutput(retval, "IDAQuadInit"); - // Set tolerances for quadrature stricter than for integration - retval = IDAQuadSStolerances(solver_, rtol * 0.1, atol * 0.1); - checkOutput(retval, "IDAQuadSStolerances"); + // Set tolerances and error control for quadratures + real_type rtol, atol; + model_->setTolerances(rtol, atol); - // Include quadrature in eror checking - retval = IDASetQuadErrCon(solver_, SUNTRUE); - checkOutput(retval, "IDASetQuadErrCon"); + // Set tolerances for quadrature stricter than for integration + retval = IDAQuadSStolerances(solver_, rtol*0.1, atol*0.1); + checkOutput(retval, "IDAQuadSStolerances"); - return retval; - } + // Include quadrature in eror checking + retval = IDASetQuadErrCon(solver_, SUNTRUE); + checkOutput(retval, "IDASetQuadErrCon"); - template - int Ida::initializeQuadrature() - { - int retval = 0; + return retval; + } - // Set all quadratures to zero - N_VConst(RCONST(0.0), q_); - // Initialize quadratures - retval = IDAQuadReInit(solver_, q_); - checkOutput(retval, "IDAQuadInit"); + template + int Ida::initializeQuadrature() + { + int retval = 0; - return retval; - } + // Set all quadratures to zero + N_VConst(RCONST(0.0), q_); - template - int Ida::runSimulationQuadrature(real_type tf, int nout) - { - int retval = 0; - real_type tret; + // Initialize quadratures + retval = IDAQuadReInit(solver_, q_); + checkOutput(retval, "IDAQuadInit"); - // std::cout << "Forward integration for initial value problem ... \n"; + return retval; + } - real_type dt = tf / nout; - real_type tout = dt; - // printOutput(0.0); - // printSpecial(0.0, yy_); - for (int i = 0; i < nout; ++i) + + template + int Ida::runSimulationQuadrature(real_type tf, int nout) + { + int retval = 0; + real_type tret; + + //std::cout << "Forward integration for initial value problem ... \n"; + + real_type dt = tf/nout; + real_type tout = dt; + //printOutput(0.0); + //printSpecial(0.0, yy_); + for(int i = 0; i < nout; ++i) + { + retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); + checkOutput(retval, "IDASolve"); + //printSpecial(tout, yy_); + //printOutput(tout); + + if (retval == IDA_SUCCESS) { - retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); - checkOutput(retval, "IDASolve"); - // printSpecial(tout, yy_); - // printOutput(tout); - - if (retval == IDA_SUCCESS) - { - tout += dt; - } - - retval = IDAGetQuad(solver_, &tret, q_); - checkOutput(retval, "IDAGetQuad"); + tout += dt; } - return retval; + retval = IDAGetQuad(solver_, &tret, q_); + checkOutput(retval, "IDAGetQuad"); } - template - int Ida::deleteQuadrature() - { - IDAQuadFree(solver_); - N_VDestroy(q_); + return retval; + } - return 0; - } - template - int Ida::configureAdjoint() - { - // Allocate adjoint vector, derivatives and quadrature - yyB_ = N_VNew_Serial(model_->size(), context_); - checkAllocation((void *)yyB_, "N_VNew_Serial"); + template + int Ida::deleteQuadrature() + { + IDAQuadFree(solver_); + N_VDestroy(q_); - ypB_ = N_VClone(yyB_); - checkAllocation((void *)ypB_, "N_VClone"); + return 0; + } - qB_ = N_VNew_Serial(model_->size_opt(), context_); - checkAllocation((void *)qB_, "N_VNew_Serial"); - return 0; - } + template + int Ida::configureAdjoint() + { + // Allocate adjoint vector, derivatives and quadrature + yyB_ = N_VNew_Serial(model_->size(), context_); + checkAllocation((void*) yyB_, "N_VNew_Serial"); - template - int Ida::initializeAdjoint(IdxT steps) - { - int retval = 0; + ypB_ = N_VClone(yyB_); + checkAllocation((void*) ypB_, "N_VClone"); - // Create adjoint workspace - retval = IDAAdjInit(solver_, steps, IDA_HERMITE); - checkOutput(retval, "IDAAdjInit"); + qB_ = N_VNew_Serial(model_->size_opt(), context_); + checkAllocation((void*) qB_, "N_VNew_Serial"); - return retval; - } + return 0; + } - template - int Ida::initializeBackwardSimulation(real_type tf) - { - int retval = 0; - realtype rtol; - realtype atol; + template + int Ida::initializeAdjoint(IdxT steps) + { + int retval = 0; + + // Create adjoint workspace + retval = IDAAdjInit(solver_, steps, IDA_HERMITE); + checkOutput(retval, "IDAAdjInit"); + + return retval; + } + + template + int Ida::initializeBackwardSimulation(real_type tf) + { + int retval = 0; + realtype rtol; + realtype atol; - model_->initializeAdjoint(); + model_->initializeAdjoint(); - copyVec(model_->yB(), yyB_); - copyVec(model_->ypB(), ypB_); - N_VConst(0.0, qB_); + copyVec(model_->yB(), yyB_); + copyVec(model_->ypB(), ypB_); + N_VConst(0.0, qB_); - retval = IDACreateB(solver_, &backwardID_); - checkOutput(retval, "IDACreateB"); + retval = IDACreateB(solver_, &backwardID_); + checkOutput(retval, "IDACreateB"); - // IDAInitB must be called after forward simulation run. - retval = IDAInitB(solver_, backwardID_, this->adjointResidual, tf, yyB_, ypB_); - checkOutput(retval, "IDAInitB"); + // IDAInitB must be called after forward simulation run. + retval = IDAInitB(solver_, backwardID_, this->adjointResidual, tf, yyB_, ypB_); + checkOutput(retval, "IDAInitB"); - model_->setTolerances(rtol, atol); - retval = IDASStolerancesB(solver_, backwardID_, rtol, atol); - checkOutput(retval, "IDASStolerancesB"); + model_->setTolerances(rtol, atol); + retval = IDASStolerancesB(solver_, backwardID_, rtol, atol); + checkOutput(retval, "IDASStolerancesB"); - retval = IDASetUserDataB(solver_, backwardID_, model_); - checkOutput(retval, "IDASetUserDataB"); + retval = IDASetUserDataB(solver_, backwardID_, model_); + checkOutput(retval, "IDASetUserDataB"); /// \todo Need to set max number of steps based on user input! retval = IDASetMaxNumStepsB(solver_, backwardID_, 2000); checkOutput(retval, "IDASetMaxNumSteps"); - // Set up linear solver - JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void *)JacobianMatB_, "SUNDenseMatrix"); + // Set up linear solver + JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void*) JacobianMatB_, "SUNDenseMatrix"); - linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); - checkAllocation((void *)linearSolverB_, "SUNLinSol_Dense"); + linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); + checkAllocation((void*) linearSolverB_, "SUNLinSol_Dense"); - retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); - checkOutput(retval, "IDASetLinearSolverB"); + retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); + checkOutput(retval, "IDASetLinearSolverB"); - // Also reinitialize quadratures. - retval = IDAQuadInitB(solver_, backwardID_, this->adjointIntegrand, qB_); - checkOutput(retval, "IDAQuadInitB"); - // retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol*1.1, atol*1.1); - retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol * 0.1, atol * 0.1); - checkOutput(retval, "IDAQuadSStolerancesB"); + // Also reinitialize quadratures. + retval = IDAQuadInitB(solver_, backwardID_, this->adjointIntegrand, qB_); + checkOutput(retval, "IDAQuadInitB"); - // Include quadratures in error control - retval = IDASetQuadErrConB(solver_, backwardID_, SUNTRUE); - checkOutput(retval, "IDASetQuadErrConB"); + //retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol*1.1, atol*1.1); + retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol*0.1, atol*0.1); + checkOutput(retval, "IDAQuadSStolerancesB"); - return retval; - } + // Include quadratures in error control + retval = IDASetQuadErrConB(solver_, backwardID_, SUNTRUE); + checkOutput(retval, "IDASetQuadErrConB"); - template - int Ida::configureLinearSolverBackward() - { - int retval = 0; - // Create Jacobian matrix - JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void *)JacobianMatB_, "SUNDenseMatrix"); + return retval; + } - // Create linear solver - linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); - checkAllocation((void *)linearSolverB_, "SUNLinSol_Dense"); + template + int Ida::configureLinearSolverBackward() + { + int retval = 0; - // Attach linear solver to IDA - retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); - checkOutput(retval, "IDASetLinearSolverB"); + // Create Jacobian matrix + JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void*) JacobianMatB_, "SUNDenseMatrix"); - return retval; - } + // Create linear solver + linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); + checkAllocation((void*) linearSolverB_, "SUNLinSol_Dense"); - template - int Ida::runForwardSimulation(real_type tf, int nout) - { - int retval = 0; - int ncheck; - real_type time; + // Attach linear solver to IDA + retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); + checkOutput(retval, "IDASetLinearSolverB"); - // std::cout << "Forward integration for adjoint analysis ... \n"; + return retval; + } - real_type dt = tf / nout; - real_type tout = dt; - for (int i = 0; i < nout; ++i) - { - retval = IDASolveF(solver_, tout, &time, yy_, yp_, IDA_NORMAL, &ncheck); - checkOutput(retval, "IDASolveF"); + template + int Ida::runForwardSimulation(real_type tf, int nout) + { + int retval = 0; + int ncheck; + real_type time; + + //std::cout << "Forward integration for adjoint analysis ... \n"; - if (retval == IDA_SUCCESS) - { - tout += dt; - } + real_type dt = tf/nout; + real_type tout = dt; + for(int i = 0; i < nout; ++i) + { + retval = IDASolveF(solver_, tout, &time, yy_, yp_, IDA_NORMAL, &ncheck); + checkOutput(retval, "IDASolveF"); - retval = IDAGetQuad(solver_, &time, q_); - checkOutput(retval, "IDASolve"); + if (retval == IDA_SUCCESS) + { + tout += dt; } - return retval; + retval = IDAGetQuad(solver_, &time, q_); + checkOutput(retval, "IDASolve"); } - template - int Ida::runBackwardSimulation(real_type t_init) - { - int retval = 0; - long int nstB; - real_type time; + return retval; + } - // std::cout << "Backward integration for adjoint analysis ... "; + template + int Ida::runBackwardSimulation(real_type t_init) + { + int retval = 0; + long int nstB; + real_type time; - retval = IDASolveB(solver_, t_init, IDA_NORMAL); - checkOutput(retval, "IDASolveB"); + //std::cout << "Backward integration for adjoint analysis ... "; - IDAGetNumSteps(IDAGetAdjIDABmem(solver_, backwardID_), &nstB); - // std::cout << "done ( nst = " << nstB << " )\n"; + retval = IDASolveB(solver_, t_init, IDA_NORMAL); + checkOutput(retval, "IDASolveB"); - retval = IDAGetB(solver_, backwardID_, &time, yyB_, ypB_); - checkOutput(retval, "IDAGetB"); + IDAGetNumSteps(IDAGetAdjIDABmem(solver_, backwardID_), &nstB); + //std::cout << "done ( nst = " << nstB << " )\n"; - retval = IDAGetQuadB(solver_, backwardID_, &time, qB_); - checkOutput(retval, "IDAGetQuadB"); + retval = IDAGetB(solver_, backwardID_, &time, yyB_, ypB_); + checkOutput(retval, "IDAGetB"); - return retval; - } + retval = IDAGetQuadB(solver_, backwardID_, &time, qB_); + checkOutput(retval, "IDAGetQuadB"); - template - int Ida::deleteAdjoint() - { - IDAAdjFree(solver_); - return 0; - } - - template - int Ida::Residual(realtype tres, N_Vector yy, N_Vector yp, N_Vector rr, void *user_data) - { - ModelLib::ModelEvaluator *model = static_cast *>(user_data); + return retval; + } - model->updateTime(tres, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); + template + int Ida::deleteAdjoint() + { + IDAAdjFree(solver_); + return 0; + } - model->evaluateResidual(); - const std::vector &f = model->getResidual(); - copyVec(f, rr); + template + int Ida::Residual(realtype tres, N_Vector yy, N_Vector yp, N_Vector rr, void *user_data) + { + ModelLib::ModelEvaluator* model = static_cast*>(user_data); - return 0; - } + model->updateTime(tres, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); - template - int Ida::Jac(realtype t, realtype cj, N_Vector yy, N_Vector yp, N_Vector resvec, SUNMatrix J, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) - { + model->evaluateResidual(); + const std::vector& f = model->getResidual(); + copyVec(f, rr); - ModelLib::ModelEvaluator *model = static_cast *>(user_data); + return 0; + } - model->updateTime(t, cj); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); + template + int Ida::Jac(realtype t, realtype cj, N_Vector yy, N_Vector yp, N_Vector resvec, SUNMatrix J, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) + { - model->evaluateJacobian(); - COO_Matrix Jac = model->getJacobian(); + ModelLib::ModelEvaluator* model = static_cast*>(user_data); - // Get reference to the jacobian entries - std::tuple &, std::vector &, std::vector &> tpm = Jac.getEntries(); - const auto [r, c, val] = tpm; - // get the CSR row pointers from COO matrix - std::vector csrrowdata = Jac.getCSRRowData(); + model->updateTime(t, cj); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); - SUNMatZero(J); + model->evaluateJacobian(); + COO_Matrix Jac = model->getJacobian(); + + //Get reference to the jacobian entries + std::tuple&, std::vector&, std::vector&> tpm = Jac.getEntries(); + const auto [r, c, val] = tpm; - // Set row pointers - sunindextype *rowptrs = SUNSparseMatrix_IndexPointers(J); - for (unsigned int i = 0; i < csrrowdata.size(); i++) - { - rowptrs[i] = csrrowdata[i]; - } + //get the CSR row pointers from COO matrix + std::vector csrrowdata = Jac.getCSRRowData(); - sunindextype *colvals = SUNSparseMatrix_IndexValues(J); - realtype *data = SUNSparseMatrix_Data(J); - // Copy data from model jac to sundials - for (unsigned int i = 0; i < c.size(); i++) - { - colvals[i] = c[i]; - data[i] = val[i]; - } + SUNMatZero(J); - return 0; + //Set row pointers + sunindextype *rowptrs = SUNSparseMatrix_IndexPointers(J); + for (unsigned int i = 0; i < csrrowdata.size() ; i++) + { + rowptrs[i] = csrrowdata[i]; } - template - int Ida::Integrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector rhsQ, void *user_data) + sunindextype *colvals = SUNSparseMatrix_IndexValues(J); + realtype *data = SUNSparseMatrix_Data(J); + //Copy data from model jac to sundials + for (unsigned int i = 0; i < c.size(); i++ ) { - ModelLib::ModelEvaluator *model = static_cast *>(user_data); + colvals[i] = c[i]; + data[i] = val[i]; + } - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); + return 0; + } - model->evaluateIntegrand(); - const std::vector &g = model->getIntegrand(); - copyVec(g, rhsQ); + template + int Ida::Integrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector rhsQ, void *user_data) + { + ModelLib::ModelEvaluator* model = static_cast*>(user_data); - return 0; - } + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); - template - int Ida::adjointResidual(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rrB, void *user_data) - { - ModelLib::ModelEvaluator *model = static_cast *>(user_data); + model->evaluateIntegrand(); + const std::vector& g = model->getIntegrand(); + copyVec(g, rhsQ); - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); - copyVec(yyB, model->yB()); - copyVec(ypB, model->ypB()); + return 0; + } - model->evaluateAdjointResidual(); - const std::vector &fB = model->getAdjointResidual(); - copyVec(fB, rrB); + template + int Ida::adjointResidual(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rrB, void *user_data) + { + ModelLib::ModelEvaluator* model = static_cast*>(user_data); - return 0; - } + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); + copyVec(yyB, model->yB()); + copyVec(ypB, model->ypB()); - template - int Ida::adjointIntegrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rhsQB, void *user_data) - { - ModelLib::ModelEvaluator *model = static_cast *>(user_data); + model->evaluateAdjointResidual(); + const std::vector& fB = model->getAdjointResidual(); + copyVec(fB, rrB); - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); - copyVec(yyB, model->yB()); - copyVec(ypB, model->ypB()); + return 0; + } - model->evaluateAdjointIntegrand(); - const std::vector &gB = model->getAdjointIntegrand(); - copyVec(gB, rhsQB); - return 0; - } + template + int Ida::adjointIntegrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rhsQB, void *user_data) + { + ModelLib::ModelEvaluator* model = static_cast*>(user_data); + + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); + copyVec(yyB, model->yB()); + copyVec(ypB, model->ypB()); + + model->evaluateAdjointIntegrand(); + const std::vector& gB = model->getAdjointIntegrand(); + copyVec(gB, rhsQB); + + return 0; + } + - template - void Ida::copyVec(const N_Vector x, std::vector &y) + template + void Ida::copyVec(const N_Vector x, std::vector< ScalarT >& y) + { + const ScalarT* xdata = NV_DATA_S(x); + for(unsigned int i = 0; i < y.size(); ++i) { - const ScalarT *xdata = NV_DATA_S(x); - for (unsigned int i = 0; i < y.size(); ++i) - { - y[i] = xdata[i]; - } + y[i] = xdata[i]; } + } + - template - void Ida::copyVec(const std::vector &x, N_Vector y) + template + void Ida::copyVec(const std::vector< ScalarT >& x, N_Vector y) + { + ScalarT* ydata = NV_DATA_S(y); + for(unsigned int i = 0; i < x.size(); ++i) { - ScalarT *ydata = NV_DATA_S(y); - for (unsigned int i = 0; i < x.size(); ++i) - { - ydata[i] = x[i]; - } + ydata[i] = x[i]; } + } - template - void Ida::copyVec(const std::vector &x, N_Vector y) + template + void Ida::copyVec(const std::vector< bool >& x, N_Vector y) + { + ScalarT* ydata = NV_DATA_S(y); + for(unsigned int i = 0; i < x.size(); ++i) { - ScalarT *ydata = NV_DATA_S(y); - for (unsigned int i = 0; i < x.size(); ++i) - { - if (x[i]) - ydata[i] = 1.0; - else - ydata[i] = 0.0; - } + if (x[i]) + ydata[i] = 1.0; + else + ydata[i] = 0.0; } + } - template - void Ida::printOutput(realtype t) - { - realtype *yval = N_VGetArrayPointer_Serial(yy_); - realtype *ypval = N_VGetArrayPointer_Serial(yp_); - std::cout << std::setprecision(5) << std::setw(7) << t << " "; - for (IdxT i = 0; i < model_->size(); ++i) - { - std::cout << yval[i] << " "; - } - for (IdxT i = 0; i < model_->size(); ++i) - { - std::cout << ypval[i] << " "; - } - std::cout << "\n"; - } + template + void Ida::printOutput(realtype t) + { + realtype *yval = N_VGetArrayPointer_Serial(yy_); + realtype *ypval = N_VGetArrayPointer_Serial(yp_); - template - void Ida::printSpecial(realtype t, N_Vector y) + std::cout << std::setprecision(5) << std::setw(7) << t << " "; + for (IdxT i = 0; i < model_->size(); ++i) { - realtype *yval = N_VGetArrayPointer_Serial(y); - IdxT N = static_cast(N_VGetLength_Serial(y)); - std::cout << "{"; - std::cout << std::setprecision(5) << std::setw(7) << t; - for (IdxT i = 0; i < N; ++i) - { - std::cout << ", " << yval[i]; - } - std::cout << "},\n"; + std::cout << yval[i] << " "; + } + for (IdxT i = 0; i < model_->size(); ++i) + { + std::cout << ypval[i] << " "; } + std::cout << "\n"; + } - template - void Ida::printFinalStats() + template + void Ida::printSpecial(realtype t, N_Vector y) + { + realtype *yval = N_VGetArrayPointer_Serial(y); + IdxT N = static_cast(N_VGetLength_Serial(y)); + std::cout << "{"; + std::cout << std::setprecision(5) << std::setw(7) << t; + for (IdxT i = 0; i < N; ++i) { - int retval = 0; - void *mem = solver_; - long int nst; - long int nre; - long int nje; - long int nni; - long int netf; - long int ncfn; - - retval = IDAGetNumSteps(mem, &nst); - checkOutput(retval, "IDAGetNumSteps"); - retval = IDAGetNumResEvals(mem, &nre); - checkOutput(retval, "IDAGetNumResEvals"); - retval = IDAGetNumJacEvals(mem, &nje); - checkOutput(retval, "IDAGetNumJacEvals"); - retval = IDAGetNumNonlinSolvIters(mem, &nni); - checkOutput(retval, "IDAGetNumNonlinSolvIters"); - retval = IDAGetNumErrTestFails(mem, &netf); - checkOutput(retval, "IDAGetNumErrTestFails"); - retval = IDAGetNumNonlinSolvConvFails(mem, &ncfn); - checkOutput(retval, "IDAGetNumNonlinSolvConvFails"); - - // std::cout << "\nFinal Run Statistics: \n\n"; - std::cout << "Number of steps = " << nst << "\n"; - std::cout << "Number of residual evaluations = " << nre << "\n"; - // std::cout << "Number of Jacobian evaluations = " << nje << "\n"; - std::cout << "Number of nonlinear iterations = " << nni << "\n"; - std::cout << "Number of error test failures = " << netf << "\n"; - std::cout << "Number of nonlinear conv. failures = " << ncfn << "\n"; + std::cout << ", " << yval[i]; } + std::cout << "},\n"; + } - template - void Ida::checkAllocation(void *v, const char *functionName) + template + void Ida::printFinalStats() + { + int retval = 0; + void* mem = solver_; + long int nst; + long int nre; + long int nje; + long int nni; + long int netf; + long int ncfn; + + retval = IDAGetNumSteps(mem, &nst); + checkOutput(retval, "IDAGetNumSteps"); + retval = IDAGetNumResEvals(mem, &nre); + checkOutput(retval, "IDAGetNumResEvals"); + retval = IDAGetNumJacEvals(mem, &nje); + checkOutput(retval, "IDAGetNumJacEvals"); + retval = IDAGetNumNonlinSolvIters(mem, &nni); + checkOutput(retval, "IDAGetNumNonlinSolvIters"); + retval = IDAGetNumErrTestFails(mem, &netf); + checkOutput(retval, "IDAGetNumErrTestFails"); + retval = IDAGetNumNonlinSolvConvFails(mem, &ncfn); + checkOutput(retval, "IDAGetNumNonlinSolvConvFails"); + + // std::cout << "\nFinal Run Statistics: \n\n"; + std::cout << "Number of steps = " << nst << "\n"; + std::cout << "Number of residual evaluations = " << nre << "\n"; + //std::cout << "Number of Jacobian evaluations = " << nje << "\n"; + std::cout << "Number of nonlinear iterations = " << nni << "\n"; + std::cout << "Number of error test failures = " << netf << "\n"; + std::cout << "Number of nonlinear conv. failures = " << ncfn << "\n"; + } + + + template + void Ida::checkAllocation(void* v, const char* functionName) + { + if (v == NULL) { - if (v == NULL) - { - std::cerr << "\nERROR: Function " << functionName << " failed -- returned NULL pointer!\n\n"; - throw SundialsException(); - } + std::cerr << "\nERROR: Function " << functionName << " failed -- returned NULL pointer!\n\n"; + throw SundialsException(); } + } - template - void Ida::checkOutput(int retval, const char *functionName) + template + void Ida::checkOutput(int retval, const char* functionName) + { + if (retval < 0) { - if (retval < 0) - { - std::cerr << "\nERROR: Function " << functionName << " failed with flag " << retval << "!\n\n"; - throw SundialsException(); - } + std::cerr << "\nERROR: Function " << functionName << " failed with flag " << retval << "!\n\n"; + throw SundialsException(); } + } - // Compiler will prevent building modules with data type incompatible with realtype - template class Ida; - template class Ida; - template class Ida; + // Compiler will prevent building modules with data type incompatible with realtype + template class Ida; + template class Ida; + template class Ida; - } // namespace Sundials +} // namespace Sundials } // namespace AnalysisManager From 8f55e94e2018fcfcabc7f4cf50097fa498d14cbf Mon Sep 17 00:00:00 2001 From: pelesh Date: Wed, 10 Apr 2024 12:02:53 -0400 Subject: [PATCH 19/44] Remove parts of generator model from BusPV (#7) * Remove parts of generator model from BusPV. --- ComponentLib/Bus/BusPV.cpp | 16 +++++------ ComponentLib/Bus/BusPV.hpp | 9 +++--- ComponentLib/Generator/GeneratorPV.hpp | 8 ++++-- Examples/Grid3Bus/Grid3BusSys.cpp | 39 ++++++++++++++------------ 4 files changed, 38 insertions(+), 34 deletions(-) diff --git a/ComponentLib/Bus/BusPV.cpp b/ComponentLib/Bus/BusPV.cpp index 5daafa102..d5a05dc98 100644 --- a/ComponentLib/Bus/BusPV.cpp +++ b/ComponentLib/Bus/BusPV.cpp @@ -74,7 +74,7 @@ namespace ModelLib { */ template BusPV::BusPV() - : BaseBus(0), V_(0.0), theta0_(0.0), Pg_(0.0) + : BaseBus(0), V_(0.0), theta0_(0.0) { //std::cout << "Create BusPV..." << std::endl; //std::cout << "Number of equations is " << size_ << std::endl; @@ -83,9 +83,7 @@ BusPV::BusPV() } /*! - * @brief BusPV constructor. - * - * This constructor sets initial values for voltage and phase angle. + * @brief Constructor for a PV bus * * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: * - Number of equations = 1 (size_) @@ -94,10 +92,10 @@ BusPV::BusPV() * - Number of optimization parameters = 0 */ template -BusPV::BusPV(ScalarT V, ScalarT theta0, ScalarT Pg) - : BaseBus(0), V_(V), theta0_(theta0), Pg_(Pg) +BusPV::BusPV(ScalarT V, ScalarT theta0) + : BaseBus(0), V_(V), theta0_(theta0) { - //std::cout << "Create BusPV ..." << std::endl; + //std::cout << "Create BusPV..." << std::endl; //std::cout << "Number of equations is " << size_ << std::endl; size_ = 1; @@ -171,8 +169,8 @@ template int BusPV::evaluateResidual() { // std::cout << "Evaluating residual of a PV bus ...\n"; - P() = Pg_; - Q() = 0.0; + P() = 0.0; // <-- Residual P + Q() = 0.0; // <-- Output Qg, the reactive power generator needs to supply return 0; } diff --git a/ComponentLib/Bus/BusPV.hpp b/ComponentLib/Bus/BusPV.hpp index fd0291b69..cf645d591 100644 --- a/ComponentLib/Bus/BusPV.hpp +++ b/ComponentLib/Bus/BusPV.hpp @@ -91,7 +91,7 @@ namespace ModelLib using BusData = GridKit::PowerSystemData::BusData; BusPV(); - BusPV(ScalarT V, ScalarT theta0, ScalarT P); + BusPV(ScalarT V, ScalarT theta0); BusPV(BusData& data); virtual ~BusPV(); @@ -197,10 +197,9 @@ namespace ModelLib } private: - ScalarT V_; - ScalarT theta0_; ///< Default initial value for phase - ScalarT Pg_; ///< Generator injection - ScalarT Q_; + ScalarT V_; ///< Bus voltage magnitude + ScalarT theta0_; ///< Default initial value for phase + ScalarT Q_; ///< Reactive power that generator needs to provide ScalarT VB_; ScalarT thetaB_; diff --git a/ComponentLib/Generator/GeneratorPV.hpp b/ComponentLib/Generator/GeneratorPV.hpp index 5e3be2041..c34df84ad 100644 --- a/ComponentLib/Generator/GeneratorPV.hpp +++ b/ComponentLib/Generator/GeneratorPV.hpp @@ -124,14 +124,18 @@ namespace ModelLib return P_; } + /// @brief Reactive power excess on PV bus + /// @return reference to negative PV generator reactive power virtual ScalarT& Q() { - return bus_->Q(); + return (bus_->Q()); } + /// @brief Reactive power excess on PV bus + /// @return const reference to negative PV generator reactive power virtual const ScalarT& Q() const { - return bus_->Q(); + return (bus_->Q()); } private: diff --git a/Examples/Grid3Bus/Grid3BusSys.cpp b/Examples/Grid3Bus/Grid3BusSys.cpp index a379f4015..02985ff1d 100644 --- a/Examples/Grid3Bus/Grid3BusSys.cpp +++ b/Examples/Grid3Bus/Grid3BusSys.cpp @@ -140,6 +140,9 @@ using namespace AnalysisManager; using namespace GridKit::Testing; using namespace GridKit::PowerSystemData; +constexpr double theta2_ref = -4.87979; // [deg] +constexpr double V2_ref = 1.08281; // [p.u.] +constexpr double theta3_ref = 1.46241; // [deg] /** * Testing the monlithic case via the class MiniGrid @@ -170,17 +173,17 @@ int monolithic_case() double V2 = model->V2(); double th3 = model->th3() * 180.0/M_PI; std::cout << "Solution:\n"; - std::cout << " theta2 = " << th2 << " deg, expected = " << " -4.87979 deg\n"; - std::cout << " V2 = " << V2 << " p.u., expected = " << " 1.08281 p.u.\n"; - std::cout << " theta3 = " << th3 << " deg, expected = " << " 1.46241 deg\n\n"; + std::cout << " theta2 = " << th2 << " deg, expected = " << theta2_ref << " deg\n"; + std::cout << " V2 = " << V2 << " p.u., expected = " << V2_ref << " p.u.\n"; + std::cout << " theta3 = " << th3 << " deg, expected = " << theta3_ref << " deg\n\n"; // Print solver performance statistics kinsol->printFinalStats(); int retval1 = 0; - retval1 += !isEqual(th2, -4.87979, 1e-4); - retval1 += !isEqual(V2, 1.08281, 1e-4); - retval1 += !isEqual(th3, 1.46241, 1e-4); + retval1 += !isEqual(th2, theta2_ref, 1e-4); + retval1 += !isEqual(V2, V2_ref , 1e-4); + retval1 += !isEqual(th3, theta3_ref, 1e-4); if(retval1 == 0) std::cout << "\nSuccess!\n\n\n"; @@ -232,17 +235,17 @@ int parser_case() std::cout << "Solution:\n"; - std::cout << " theta2 = " << th2 << " deg, expected = " << " -4.87979 deg\n"; - std::cout << " V2 = " << V2 << " p.u., expected = " << " 1.08281 p.u.\n"; - std::cout << " theta3 = " << th3 << " deg, expected = " << " 1.46241 deg\n\n"; + std::cout << " theta2 = " << th2 << " deg, expected = " << theta2_ref << " deg\n"; + std::cout << " V2 = " << V2 << " p.u., expected = " << V2_ref << " p.u.\n"; + std::cout << " theta3 = " << th3 << " deg, expected = " << theta3_ref << " deg\n\n"; // Print solver performance statistics kinsol->printFinalStats(); int retval2 = 0; - retval2 += !isEqual(th2, -4.87979, 1e-4); - retval2 += !isEqual(V2, 1.08281, 1e-4); - retval2 += !isEqual(th3, 1.46241, 1e-4); + retval2 += !isEqual(th2, theta2_ref, 1e-4); + retval2 += !isEqual(V2, V2_ref , 1e-4); + retval2 += !isEqual(th3, theta3_ref, 1e-4); if(retval2 == 0) std::cout << "\nSuccess!\n\n\n"; @@ -355,17 +358,17 @@ int hardwired_case() std::cout << "Solution:\n"; - std::cout << " theta2 = " << th2 << " deg, expected = " << " -4.87979 deg\n"; - std::cout << " V2 = " << V2 << " p.u., expected = " << " 1.08281 p.u.\n"; - std::cout << " theta3 = " << th3 << " deg, expected = " << " 1.46241 deg\n\n"; + std::cout << " theta2 = " << th2 << " deg, expected = " << theta2_ref << " deg\n"; + std::cout << " V2 = " << V2 << " p.u., expected = " << V2_ref << " p.u.\n"; + std::cout << " theta3 = " << th3 << " deg, expected = " << theta3_ref << " deg\n\n"; // Print solver performance statistics kinsol->printFinalStats(); int retval2 = 0; - retval2 += !isEqual(th2, -4.87979, 1e-4); - retval2 += !isEqual(V2, 1.08281, 1e-4); - retval2 += !isEqual(th3, 1.46241, 1e-4); + retval2 += !isEqual(th2, theta2_ref, 1e-4); + retval2 += !isEqual(V2, V2_ref , 1e-4); + retval2 += !isEqual(th3, theta3_ref, 1e-4); if(retval2 == 0) std::cout << "\nSuccess!\n\n\n"; From 7bb9374692d5343d86d5206e4e6d0c30516aa236 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Wed, 10 Apr 2024 15:27:28 -0400 Subject: [PATCH 20/44] Formatting updates + Fixed Warnings - Update format - Fixed casting warnings --- .../Capacitor/Capacitor.cpp | 8 +- .../CircuitComponent.hpp | 18 +- .../DistributedGenerator.cpp | 11 +- .../DistributedGenerator.hpp | 30 +- .../InductionMotor/InductionMotor.cpp | 6 +- .../Inductor/Inductor.cpp | 8 +- .../LinearTransformer/LinearTransformer.cpp | 6 +- .../MicrogridBusDQ/MicrogridBusDQ.cpp | 6 +- .../MicrogridLine/MicrogridLine.cpp | 8 +- .../MicrogridLoad/MicrogridLoad.cpp | 8 +- .../Resistor/Resistor.cpp | 6 +- .../SynchronousMachine/SynchronousMachine.cpp | 6 +- .../TransmissionLine/TransmissionLine.cpp | 6 +- .../VoltageSource/VoltageSource.cpp | 6 +- Examples/DistributedGeneratorTest/DGTest.cpp | 30 +- Examples/Grid3Bus/Grid3BusSys.cpp | 12 +- Examples/Microgrid/Microgrid.cpp | 91 ++--- Examples/SparseTest/SparseTest.cpp | 24 +- PowerElectronicsModel.hpp | 11 +- Solver/Dynamic/Ida.cpp | 6 +- SparseMatrix/COO_Matrix.hpp | 325 ++++++++++-------- 21 files changed, 339 insertions(+), 293 deletions(-) diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp index 148c7c086..f8f26f6da 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -19,9 +19,9 @@ Capacitor::Capacitor(IdxT id, ScalarT C) : C_(C) { this->size_ = 3; - this->n_intern = 1; - this->n_extern = 2; - this->extern_indices = {0,1}; + this->n_intern_ = 1; + this->n_extern_ = 2; + this->extern_indices_ = {0,1}; this->idc_ = id; } @@ -96,7 +96,7 @@ int Capacitor::evaluateJacobian() COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(this->alpha_, Jacder); + this->J_.axpy(this->alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp index 2d43e06e0..5a1a2702e 100644 --- a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp +++ b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp @@ -32,28 +32,28 @@ namespace ModelLib size_t getExternSize() { - return this->n_extern; + return this->n_extern_; } size_t getInternalSize() { - return this->n_intern; + return this->n_intern_; } std::set getExternIndices() { - return this->extern_indices; + return this->extern_indices_; } bool setExternalConnectionNodes(size_t index, IdxT id) { - this->connection_nodes[index] = id; + this->connection_nodes_[index] = id; return true; } IdxT getNodeConnection(size_t index) { - return this->connection_nodes.at(index); + return this->connection_nodes_.at(index); } inline std::vector parkTransformMatrix(ScalarT angle) @@ -125,11 +125,11 @@ namespace ModelLib } protected: - size_t n_extern; - size_t n_intern; - std::set extern_indices; + size_t n_extern_; + size_t n_intern_; + std::set extern_indices_; //@todo may want to replace the mapping of connection_nodes to Node objects instead of IdxT. Allows for container free setup - std::map connection_nodes; + std::map connection_nodes_; }; diff --git a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp index ee23eb7b7..f0b6864a0 100644 --- a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp @@ -18,14 +18,14 @@ namespace ModelLib { template DistributedGenerator::DistributedGenerator(IdxT id, DistributedGeneratorParameters parm, bool reference_frame) - : wb_(parm.wb), wc_(parm.wc), mp_(parm.mp), Vn_(parm.Vn), nq_(parm.nq), F_(parm.F), Kiv_(parm.Kiv), Kpv_(parm.Kpv), Kic_(parm.Kic), Kpc_(parm.Kpc), Cf_(parm.Cf), rLf_(parm.rLf), Lf_(parm.Lf), rLc_(parm.rLc), Lc_(parm.Lc), refframe_(reference_frame) + : wb_(parm.wb_), wc_(parm.wc_), mp_(parm.mp_), Vn_(parm.Vn_), nq_(parm.nq_), F_(parm.F_), Kiv_(parm.Kiv_), Kpv_(parm.Kpv_), Kic_(parm.Kic_), Kpc_(parm.Kpc_), Cf_(parm.Cf_), rLf_(parm.rLf_), Lf_(parm.Lf_), rLc_(parm.rLc_), Lc_(parm.Lc_), refframe_(reference_frame) { // internals [\delta_i, Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi] // externals [\omega_ref, vba_out, vbb_out] this->size_ = 16; - this->n_intern = 13; - this->n_extern = 3; - this->extern_indices = {0,1,2}; + this->n_intern_ = 13; + this->n_extern_ = 3; + this->extern_indices_ = {0,1,2}; this->idc_ = id; } @@ -77,6 +77,7 @@ int DistributedGenerator::evaluateResidual() ScalarT omega = wb_ - mp_ * y_[4]; //ref common ref motor angle + /// @todo fix boolian conditional, unclear result if (refframe_) { f_[0] = omega - y_[0]; @@ -307,7 +308,7 @@ int DistributedGenerator::evaluateJacobian() //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(this->alpha_, Jacder); + this->J_.axpy(this->alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp index 65e71b2b9..6dd297d7a 100644 --- a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp @@ -15,21 +15,21 @@ namespace ModelLib template struct DistributedGeneratorParameters { - ScalarT wb; - ScalarT wc; - ScalarT mp; - ScalarT Vn; - ScalarT nq; - ScalarT F; - ScalarT Kiv; - ScalarT Kpv; - ScalarT Kic; - ScalarT Kpc; - ScalarT Cf; - ScalarT rLf; - ScalarT Lf; - ScalarT rLc; - ScalarT Lc; + ScalarT wb_; + ScalarT wc_; + ScalarT mp_; + ScalarT Vn_; + ScalarT nq_; + ScalarT F_; + ScalarT Kiv_; + ScalarT Kpv_; + ScalarT Kic_; + ScalarT Kpc_; + ScalarT Cf_; + ScalarT rLf_; + ScalarT Lf_; + ScalarT rLc_; + ScalarT Lc_; }; } diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp index c9b452f79..af64888cb 100644 --- a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp @@ -28,9 +28,9 @@ InductionMotor::InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, P_(P) { this->size_ = 10; - this->n_intern = 5; - this->n_extern = 5; - this->extern_indices = {0,1,2,3,4}; + this->n_intern_ = 5; + this->n_extern_ = 5; + this->extern_indices_ = {0,1,2,3,4}; this->idc_ = id; } diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index 05cc66c51..7048efb6e 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -19,9 +19,9 @@ Inductor::Inductor(IdxT id, ScalarT L) : L_(L) { this->size_ = 3; - this->n_intern = 1; - this->n_extern = 2; - this->extern_indices = {0,1}; + this->n_intern_ = 1; + this->n_extern_ = 2; + this->extern_indices_ = {0,1}; this->idc_ = id; } @@ -97,7 +97,7 @@ int Inductor::evaluateJacobian() COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(this->alpha_, Jacder); + this->J_.axpy(this->alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp index aa147493f..fc2a65661 100644 --- a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp @@ -23,9 +23,9 @@ LinearTransformer::LinearTransformer(IdxT id, ScalarT L1, ScalarT M_(M) { this->size_ = 4; - this->n_intern = 2; - this->n_extern = 2; - this->extern_indices = {0,1}; + this->n_intern_ = 2; + this->n_extern_ = 2; + this->extern_indices_ = {0,1}; this->idc_ = id; } diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp index a8327e341..442d5814f 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -20,9 +20,9 @@ MicrogridBusDQ::MicrogridBusDQ(IdxT id, ScalarT RN) { // externals [vbus_d, vbus_q] this->size_ = 2; - this->n_intern = 0; - this->n_extern = 2; - this->extern_indices = {0,1}; + this->n_intern_ = 0; + this->n_extern_ = 2; + this->extern_indices_ = {0,1}; this->idc_ = id; } diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp index 05b1b5e66..4661e4fba 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp @@ -21,9 +21,9 @@ MicrogridLine::MicrogridLine(IdxT id, ScalarT R,ScalarT L) // internals [id, iq] // externals [\omegaref, vbd_in, vbq_in, vbd_out, vbq_out] this->size_ = 7; - this->n_intern = 2; - this->n_extern = 5; - this->extern_indices = {0,1,2,3,4}; + this->n_intern_ = 2; + this->n_extern_ = 5; + this->extern_indices_ = {0,1,2,3,4}; this->idc_ = id; } @@ -129,7 +129,7 @@ int MicrogridLine::evaluateJacobian() COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,7,7); //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(this->alpha_, Jacder); + this->J_.axpy(this->alpha_, Jacder); return 0; diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp index 502170e3b..337390965 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp @@ -22,9 +22,9 @@ MicrogridLoad::MicrogridLoad(IdxT id, ScalarT R,ScalarT L) // internals [id, iq] // externals [\omegaref, vbd_out, vbq_out] this->size_ = 5; - this->n_intern = 2; - this->n_extern = 3; - this->extern_indices = {0,1,2}; + this->n_intern_ = 2; + this->n_extern_ = 3; + this->extern_indices_ = {0,1,2}; this->idc_ = id; } @@ -127,7 +127,7 @@ int MicrogridLoad::evaluateJacobian() COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,5,5); //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(this->alpha_, Jacder); + this->J_.axpy(this->alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp index d3acbb87f..fcdb9227c 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp @@ -19,9 +19,9 @@ Resistor::Resistor(IdxT id, ScalarT R) : R_(R) { this->size_ = 2; - this->n_intern = 0; - this->n_extern = 2; - this->extern_indices = {0,1}; + this->n_intern_ = 0; + this->n_extern_ = 2; + this->extern_indices_ = {0,1}; this->idc_ = id; } diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp index 8e9be323a..5e1c44076 100644 --- a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp @@ -34,9 +34,9 @@ SynchronousMachine::SynchronousMachine(IdxT id, ScalarT Lls, std: mub_(mub) { this->size_ = 13; - this->n_intern = 6; - this->n_extern = 7; - this->extern_indices = {0,1,2,3,4}; + this->n_intern_ = 6; + this->n_extern_ = 7; + this->extern_indices_ = {0,1,2,3,4}; this->idc_ = id; } diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp index 4158be388..f7fad07aa 100644 --- a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp @@ -22,9 +22,9 @@ TransmissionLine::TransmissionLine(IdxT id, ScalarT R,ScalarT X, // internals [Iret1, Iimt1, Iret2, Iimt2] // externals [Vre11, Vim11, Vre12, Vim12, Vre21, Vim21, Vre22, Vim22] this->size_ = 12; - this->n_intern = 4; - this->n_extern = 8; - this->extern_indices = {0,1,2,3,4,5,6,7}; + this->n_intern_ = 4; + this->n_extern_ = 8; + this->extern_indices_ = {0,1,2,3,4,5,6,7}; this->idc_ = id; ScalarT magImpendence = 1 / (R_*R_ + X_*X_); diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp index b8a659ba9..f77381dcc 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -19,9 +19,9 @@ VoltageSource::VoltageSource(IdxT id, ScalarT V) : V_(V) { this->size_ = 3; - this->n_intern = 1; - this->n_extern = 2; - this->extern_indices = {0,1}; + this->n_intern_ = 1; + this->n_extern_ = 2; + this->extern_indices_ = {0,1}; this->idc_ = id; } diff --git a/Examples/DistributedGeneratorTest/DGTest.cpp b/Examples/DistributedGeneratorTest/DGTest.cpp index 8d682e88c..b65d7c57c 100644 --- a/Examples/DistributedGeneratorTest/DGTest.cpp +++ b/Examples/DistributedGeneratorTest/DGTest.cpp @@ -15,21 +15,21 @@ int main(int argc, char const *argv[]) ModelLib::DistributedGeneratorParameters parms; //Parameters from MATLAB Microgrid code for first DG - parms.wb = 2.0*M_PI*50.0; - parms.wc = 31.41; - parms.mp = 9.4e-5; - parms.Vn = 380; - parms.nq = 1.3e-3; - parms.F = 0.75; - parms.Kiv = 420.0; - parms.Kpv = 0.1; - parms.Kic = 20.0 * 1.0e3; - parms.Kpc = 15.0; - parms.Cf = 50.0e-6; - parms.rLf = 0.1; - parms.Lf = 1.35e-3; - parms.rLc = 0.03; - parms.Lc = 0.35e-3; + parms.wb_ = 2.0*M_PI*50.0; + parms.wc_ = 31.41; + parms.mp_ = 9.4e-5; + parms.Vn_ = 380; + parms.nq_ = 1.3e-3; + parms.F_ = 0.75; + parms.Kiv_ = 420.0; + parms.Kpv_ = 0.1; + parms.Kic_ = 20.0 * 1.0e3; + parms.Kpc_ = 15.0; + parms.Cf_ = 50.0e-6; + parms.rLf_ = 0.1; + parms.Lf_ = 1.35e-3; + parms.rLc_ = 0.03; + parms.Lc_ = 0.35e-3; ModelLib::DistributedGenerator *dg = new ModelLib::DistributedGenerator(0, parms, true); diff --git a/Examples/Grid3Bus/Grid3BusSys.cpp b/Examples/Grid3Bus/Grid3BusSys.cpp index 64f616623..47e6907d8 100644 --- a/Examples/Grid3Bus/Grid3BusSys.cpp +++ b/Examples/Grid3Bus/Grid3BusSys.cpp @@ -145,7 +145,7 @@ using namespace GridKit::PowerSystemData; * Testing the monlithic case via the class MiniGrid * @return returns 0 if pass o.w. fails */ -int monolithic_case() +int monolithicCase() { std::cout << "\nSolving power flow for a 3-bus monolithic model ...\n\n"; // Create a 3-bus model @@ -198,7 +198,7 @@ int monolithic_case() * Run the Testing case for parser setup * @return returns 0 if pass o.w. fail */ -int parser_case() +int parserCase() { std::cout << "Solving same problem, but assembled from components via a parser ...\n\n"; @@ -264,7 +264,7 @@ int parser_case() * Hardwired Test Case * @return 0 if pass otherwise fails */ -int hardwired_case() +int hardwiredCase() { std::cout << "Solving same problem, but assembled from components manually ...\n\n"; @@ -388,11 +388,11 @@ int main() //return the results of each case int resolve = 0; std::cout << std::string(32,'-') << std::endl; - resolve += monolithic_case(); + resolve |= monolithicCase(); std::cout << std::string(32,'-') << std::endl; - resolve += parser_case(); + resolve |= parserCase(); std::cout << std::string(32,'-') << std::endl; - resolve += hardwired_case(); + resolve |= hardwiredCase(); if (resolve) { diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp index 8107c3e66..4cbf765f0 100644 --- a/Examples/Microgrid/Microgrid.cpp +++ b/Examples/Microgrid/Microgrid.cpp @@ -1,5 +1,6 @@ + #include #include #include @@ -34,39 +35,39 @@ int main(int argc, char const *argv[]) //DG Params ModelLib::DistributedGeneratorParameters parms1; - parms1.wb = 2.0*M_PI*50.0; - parms1.wc = 31.41; - parms1.mp = 9.4e-5; - parms1.Vn = 380.0; - parms1.nq = 1.3e-3; - parms1.F = 0.75; - parms1.Kiv = 420.0; - parms1.Kpv = 0.1; - parms1.Kic = 2.0e4; - parms1.Kpc = 15.0; - parms1.Cf = 5.0e-5; - parms1.rLf = 0.1; - parms1.Lf = 1.35e-3; - parms1.rLc = 0.03; - parms1.Lc = 0.35e-3; + parms1.wb_ = 2.0*M_PI*50.0; + parms1.wc_ = 31.41; + parms1.mp_ = 9.4e-5; + parms1.Vn_ = 380.0; + parms1.nq_ = 1.3e-3; + parms1.F_ = 0.75; + parms1.Kiv_ = 420.0; + parms1.Kpv_ = 0.1; + parms1.Kic_ = 2.0e4; + parms1.Kpc_ = 15.0; + parms1.Cf_ = 5.0e-5; + parms1.rLf_ = 0.1; + parms1.Lf_ = 1.35e-3; + parms1.rLc_ = 0.03; + parms1.Lc_ = 0.35e-3; ModelLib::DistributedGeneratorParameters parms2; //Parameters from MATLAB Microgrid code for first DG - parms2.wb = 2.0*M_PI*50.0; - parms2.wc = 31.41; - parms2.mp = 12.5e-5; - parms2.Vn = 380.0; - parms2.nq = 1.5e-3; - parms2.F = 0.75; - parms2.Kiv = 390.0; - parms2.Kpv = 0.05; - parms2.Kic = 16.0e3; - parms2.Kpc = 10.5; - parms2.Cf = 50.0e-6; - parms2.rLf = 0.1; - parms2.Lf = 1.35e-3; - parms2.rLc = 0.03; - parms2.Lc = 0.35e-3; + parms2.wb_ = 2.0*M_PI*50.0; + parms2.wc_ = 31.41; + parms2.mp_ = 12.5e-5; + parms2.Vn_ = 380.0; + parms2.nq_ = 1.5e-3; + parms2.F_ = 0.75; + parms2.Kiv_ = 390.0; + parms2.Kpv_ = 0.05; + parms2.Kic_ = 16.0e3; + parms2.Kpc_ = 10.5; + parms2.Cf_ = 50.0e-6; + parms2.rLf_ = 0.1; + parms2.Lf_ = 1.35e-3; + parms2.rLc_ = 0.03; + parms2.Lc_ = 0.35e-3; //Line params double rline1 = 0.23; @@ -304,21 +305,21 @@ int main(int argc, char const *argv[]) // Create Intial derivatives specifics generated in MATLAB //DGs 1 - sysmodel->yp()[2] = parms1.Vn; - sysmodel->yp()[4] = parms1.Kpv * parms1.Vn; - sysmodel->yp()[6] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; - sysmodel->yp()[12 + 3] = parms1.Vn; - sysmodel->yp()[12 + 5] = parms1.Kpv * parms1.Vn; - sysmodel->yp()[12 + 7] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; + sysmodel->yp()[2] = parms1.Vn_; + sysmodel->yp()[4] = parms1.Kpv_ * parms1.Vn_; + sysmodel->yp()[6] = (parms1.Kpc_ * parms1.Kpv_ * parms1.Vn_) / parms1.Lf_; + sysmodel->yp()[12 + 3] = parms1.Vn_; + sysmodel->yp()[12 + 5] = parms1.Kpv_ * parms1.Vn_; + sysmodel->yp()[12 + 7] = (parms1.Kpc_ * parms1.Kpv_ * parms1.Vn_) / parms1.Lf_; for (size_t i = 2; i < 4; i++) { - sysmodel->yp()[13*i - 1 + 3] = parms2.Vn; - sysmodel->yp()[13*i - 1 + 5] = parms2.Kpv * parms2.Vn; - sysmodel->yp()[13*i - 1 + 7] = (parms2.Kpc * parms2.Kpv * parms2.Vn) / parms2.Lf; + sysmodel->yp()[13*i - 1 + 3] = parms2.Vn_; + sysmodel->yp()[13*i - 1 + 5] = parms2.Kpv_ * parms2.Vn_; + sysmodel->yp()[13*i - 1 + 7] = (parms2.Kpc_ * parms2.Kpv_ * parms2.Vn_) / parms2.Lf_; } //since the intial P_com = 0 - sysmodel->y()[vec_size_internals] = parms1.wb; + sysmodel->y()[vec_size_internals] = parms1.wb_; @@ -329,7 +330,7 @@ int main(int argc, char const *argv[]) std::cout << "Verify Intial Resisdual is Zero: {\n"; for (size_t i = 0; i < fres.size(); i++) { - printf("%u : %e \n", i, fres[i]); + printf("%lu : %e \n", i, fres[i]); } std::cout << "}\n"; @@ -435,10 +436,10 @@ int main(int argc, char const *argv[]) }; std::cout << "Test the Relative Error\n"; - for (size_t i = 0; i < true_vec.size(); i++) - { - printf("%u : %e ,\n", i, abs(true_vec[i] - yfinial[i]) / abs(true_vec[i])); - } + for (size_t i = 0; i < true_vec.size(); i++) + { + printf("%lu : %e ,\n", i, abs(true_vec[i] - yfinial[i]) / abs(true_vec[i])); + } return 0; } diff --git a/Examples/SparseTest/SparseTest.cpp b/Examples/SparseTest/SparseTest.cpp index 399151434..c563dbd49 100644 --- a/Examples/SparseTest/SparseTest.cpp +++ b/Examples/SparseTest/SparseTest.cpp @@ -42,7 +42,7 @@ int main(int argc, char const *argv[]) std::cout << "B:\n"; B.printMatrix(); - A.AXPY(2.0, B); + A.axpy(2.0, B); std::cout << "A + 2B:\n"; A.printMatrix(); @@ -73,14 +73,30 @@ int main(int argc, char const *argv[]) assert(valtest.size() == v.size()); int failval = 0; - for (size_t i = 0; i < rtest.size(); i++) if (r[i] != rtest[i]) failval--; + for (size_t i = 0; i < rtest.size(); i++) + { + if (r[i] != rtest[i]) + { + failval--; + } + } for (size_t i = 0; i < ctest.size(); i++) { double vdiff = v[i] - valtest[i]; - if (c[i] != ctest[i] || -1e-14 > vdiff || vdiff > 1e-14) failval--; + if (c[i] != ctest[i] || -1e-14 > vdiff || vdiff > 1e-14) + { + failval--; + } } - std::cout << failval << std::endl; + if (failval == 0) + { + std::cout << "Success!" << std::endl; + } + else + { + std::cout << "Failed!" << std::endl; + } return failval; } diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index d74b92cf0..ca7e4dbdf 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -166,7 +166,7 @@ namespace ModelLib { for (IdxT j = 0; j < component->size(); ++j) { - if (component->getNodeConnection(j) != -1) + if (component->getNodeConnection(j) != neg1_) { component->y()[j] = y_[component->getNodeConnection(j)]; component->yp()[j] = yp_[component->getNodeConnection(j)]; @@ -209,7 +209,7 @@ namespace ModelLib for (IdxT j = 0; j < component->size(); ++j) { //@todo should do a different grounding check - if (component->getNodeConnection(j) != -1) + if (component->getNodeConnection(j) != neg1_) { f_[component->getNodeConnection(j)] += component->getResidual()[j]; } @@ -244,7 +244,7 @@ namespace ModelLib std::vector vgr; for (IdxT i = 0; i < static_cast(r.size()); i++) { - if (component->getNodeConnection(r[i]) != -1 && component->getNodeConnection(c[i]) != -1) + if (component->getNodeConnection(r[i]) != neg1_ && component->getNodeConnection(c[i]) != neg1_) { rgr.push_back(component->getNodeConnection(r[i])); cgr.push_back(component->getNodeConnection(c[i])); @@ -253,7 +253,7 @@ namespace ModelLib } // AXPY to Global Jacobian - this->J_.AXPY(1.0, rgr, cgr, vgr); + this->J_.axpy(1.0, rgr, cgr, vgr); } return 0; @@ -321,6 +321,9 @@ namespace ModelLib } private: + + static constexpr IdxT neg1_ = static_cast(-1); + std::vector components_; bool usejac_; diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index fbe7c8973..c97c60cb8 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -421,9 +421,9 @@ namespace Sundials retval = IDASetUserDataB(solver_, backwardID_, model_); checkOutput(retval, "IDASetUserDataB"); - /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumStepsB(solver_, backwardID_, 2000); - checkOutput(retval, "IDASetMaxNumSteps"); + /// \todo Need to set max number of steps based on user input! + retval = IDASetMaxNumStepsB(solver_, backwardID_, 2000); + checkOutput(retval, "IDASetMaxNumSteps"); // Set up linear solver JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); diff --git a/SparseMatrix/COO_Matrix.hpp b/SparseMatrix/COO_Matrix.hpp index 70da77a1e..9036085a5 100644 --- a/SparseMatrix/COO_Matrix.hpp +++ b/SparseMatrix/COO_Matrix.hpp @@ -12,7 +12,7 @@ /** * @brief Quick class to provide sparse matrices of COO type. Simplifies data movement * - * @todo add functionality to keep track of multiple sorted list. Faster adding of new entries and will have a threshold to sort completely. + * @todo add functionality to keep track of multiple sorted_ list. Faster adding of new entries and will have a threshold to sort completely. * * m x n sparse matrix */ @@ -20,12 +20,12 @@ template class COO_Matrix { private: - std::vector values; - std::vector row_indexes; - std::vector column_indexes; - Intdx rows_size; - Intdx columns_size; - bool sorted; + std::vector values_; + std::vector row_indexes_; + std::vector column_indexes_; + Intdx rows_size_; + Intdx columns_size_; + bool sorted_; public: //Constructors COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n); @@ -47,9 +47,9 @@ class COO_Matrix // BLAS. Will sort before running void setValues(std::vector r, std::vector c, std::vector v); - void AXPY(ScalarT alpha, COO_Matrix& a); - void AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v); - void SCAL(ScalarT alpha); + void axpy(ScalarT alpha, COO_Matrix& a); + void axpy(ScalarT alpha, std::vector r, std::vector c, std::vector v); + void scal(ScalarT alpha); ScalarT frobnorm(); // --- Permutation Operations --- @@ -61,7 +61,7 @@ class COO_Matrix void identityMatrix(Intdx n); - //Resort values + //Resort values_ void sortSparse(); bool isSorted(); Intdx nnz(); @@ -71,7 +71,7 @@ class COO_Matrix void printMatrix(); - static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values); + static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &vals); private: Intdx indexStartRow(const std::vector &rows, Intdx r); @@ -81,7 +81,7 @@ class COO_Matrix }; /** - * @brief Get copy of row values + * @brief Get copy of row values_ * * @tparam ScalarT * @tparam Intdx @@ -91,7 +91,7 @@ class COO_Matrix template inline std::tuple, std::vector> COO_Matrix::getRowCopy(Intdx r) { - if (!this->sorted) + if (!this->sorted_) { this->sortSparse(); } @@ -107,9 +107,9 @@ inline std::tuple, std::vector> COO_Matrixvalues.size() && this->row_indexes[rsize] == r); + } while (rsize < this->values_.size() && this->row_indexes_[rsize] == r); - return {{this->column_indexes.begin() + rowindex, this->column_indexes.begin() + rsize},{this->values.begin() + rowindex, this->values.begin() + rsize}}; + return {{this->column_indexes_.begin() + rowindex, this->column_indexes_.begin() + rsize},{this->values_.begin() + rowindex, this->values_.begin() + rsize}}; } /** @@ -122,15 +122,15 @@ inline std::tuple, std::vector> COO_Matrix inline std::tuple&, std::vector&, std::vector&> COO_Matrix::getEntries() { - if (!this->sorted) + if (!this->sorted_) { this->sortSparse(); } - return {this->row_indexes, this->column_indexes, this->values}; + return {this->row_indexes_, this->column_indexes_, this->values_}; } /** - * @brief Get copies of the data. Sorted before returning + * @brief Get copies of the data. Sorted_ before returning * * @tparam ScalarT * @tparam Intdx @@ -139,11 +139,11 @@ inline std::tuple&, std::vector&, std::vector template inline std::tuple, std::vector, std::vector> COO_Matrix::getEntrieCopies() { - if (!this->sorted) + if (!this->sorted_) { this->sortSparse(); } - return {this->row_indexes, this->column_indexes, this->values}; + return {this->row_indexes_, this->column_indexes_, this->values_}; } /** @@ -157,18 +157,18 @@ template inline std::tuple, std::vector, std::vector> COO_Matrix::getDataToCSR() { if (!this->isSorted()) this->sortSparse(); - std::vector rowsizevec(this->rows_size + 1, 0); + std::vector rowsizevec(this->rows_size_ + 1, 0); Intdx counter = 0; for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) { rowsizevec[i + 1] = rowsizevec[i]; - while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) + while (counter < static_cast(this->row_indexes_.size()) && i == this->row_indexes_[counter]) { rowsizevec[i+1]++; counter++; } } - return {rowsizevec, this->column_indexes, this->values}; + return {rowsizevec, this->column_indexes_, this->values_}; } /** @@ -176,7 +176,6 @@ inline std::tuple, std::vector, std::vector> * * @todo swap this with having the matrix store the data and updates. This can then be passed by reference * - * @todo fails, fix * * @tparam ScalarT * @tparam Intdx @@ -186,12 +185,12 @@ template inline std::vector COO_Matrix::getCSRRowData() { if (!this->isSorted()) this->sortSparse(); - std::vector rowsizevec(this->rows_size + 1, 0); + std::vector rowsizevec(this->rows_size_ + 1, 0); Intdx counter = 0; for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) { rowsizevec[i + 1] = rowsizevec[i]; - while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) + while (counter < static_cast(this->row_indexes_.size()) && i == this->row_indexes_[counter]) { rowsizevec[i+1]++; counter++; @@ -201,7 +200,7 @@ inline std::vector COO_Matrix::getCSRRowData() } /** - * @brief Given set of vector data it will set the values into the matrix + * @brief Given set of vector data it will set the values_ into the matrix * * @tparam ScalarT * @tparam Intdx @@ -216,45 +215,48 @@ inline void COO_Matrix::setValues(std::vector r, std::vec this->sortSparseCOO(r, c, v); - //Duplicated with AXPY. Could replace with function depdent on lambda expression + //Duplicated with axpy. Could replace with function depdent on lambda expression Intdx aiter = 0; - //iterate for all current values in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + //iterate for all current values_ in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes_.size()); i++) { - //pushback values when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + //pushback values_ when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) { - this->row_indexes.push_back(r[aiter]); - this->column_indexes.push_back(c[aiter]); - this->values.push_back(v[aiter]); + this->row_indexes_.push_back(r[aiter]); + this->column_indexes_.push_back(c[aiter]); + this->values_.push_back(v[aiter]); this->checkIncreaseSize(r[aiter], c[aiter]); aiter++; } - if (aiter >= static_cast(r.size())) break; + if (aiter >= static_cast(r.size())) + { + break; + } - if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + if (r[aiter] == this->row_indexes_[i] && c[aiter] == this->column_indexes_[i]) { - this->values[i] = v[aiter]; + this->values_[i] = v[aiter]; aiter++; } } //push back rest that was not found sorted for (Intdx i = aiter; i < static_cast(r.size()); i++) { - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(v[i]); + this->row_indexes_.push_back(r[i]); + this->column_indexes_.push_back(c[i]); + this->values_.push_back(v[i]); this->checkIncreaseSize(r[i], c[i]); } - this->sorted = false; + this->sorted_ = false; } /** - * @brief BLAS AXPY operation on another COO matrix. Will sort both matrices before acting + * @brief BLAS axpy operation on another COO matrix. Will sort both matrices before acting * * @tparam ScalarT * @tparam Intdx @@ -262,11 +264,14 @@ inline void COO_Matrix::setValues(std::vector r, std::vec * @param a */ template -inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrix& a) +inline void COO_Matrix::axpy(ScalarT alpha, COO_Matrix& a) { - if (alpha == 0) return; + if (alpha == 0) + { + return; + } - if (!this->sorted) + if (!this->sorted_) { this->sortSparse(); } @@ -281,47 +286,50 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrixrows_size = this->rows_size > m ? this->rows_size : m; - this->columns_size = this->columns_size > n ? this->columns_size : n; + this->rows_size_ = this->rows_size_ > m ? this->rows_size_ : m; + this->columns_size_ = this->columns_size_ > n ? this->columns_size_ : n; Intdx aiter = 0; - //iterate for all current values in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + //iterate for all current values_ in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes_.size()); i++) { - //pushback values when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + //pushback values_ when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) { - this->row_indexes.push_back(r[aiter]); - this->column_indexes.push_back(c[aiter]); - this->values.push_back(alpha * val[aiter]); + this->row_indexes_.push_back(r[aiter]); + this->column_indexes_.push_back(c[aiter]); + this->values_.push_back(alpha * val[aiter]); this->checkIncreaseSize(r[aiter], c[aiter]); aiter++; } - if (aiter >= static_cast(r.size())) break; + if (aiter >= static_cast(r.size())) + { + break; + } - if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + if (r[aiter] == this->row_indexes_[i] && c[aiter] == this->column_indexes_[i]) { - this->values[i] += alpha * val[aiter]; + this->values_[i] += alpha * val[aiter]; aiter++; } } - //push back rest that was not found sorted + //push back rest that was not found sorted_ for (Intdx i = aiter; i < static_cast(r.size()); i++) { - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(alpha * val[i]); + this->row_indexes_.push_back(r[i]); + this->column_indexes_.push_back(c[i]); + this->values_.push_back(alpha * val[i]); this->checkIncreaseSize(r[i], c[i]); } - this->sorted = false; + this->sorted_ = false; } /** - * @brief AXPY on 3list. + * @brief axpy on 3list. * * @tparam ScalarT * @tparam Intdx @@ -331,11 +339,11 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrix -inline void COO_Matrix::AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v) +inline void COO_Matrix::axpy(ScalarT alpha, std::vector r, std::vector c, std::vector v) { if (alpha == 0) return; - if (!this->sorted) + if (!this->sorted_) { this->sortSparse(); } @@ -344,59 +352,75 @@ inline void COO_Matrix::AXPY(ScalarT alpha, std::vector r this->sortSparseCOO(r, c, v); Intdx aiter = 0; - //iterate for all current values in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + //iterate for all current values_ in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes_.size()); i++) { - //pushback values when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + //pushback values_ when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) { - this->row_indexes.push_back(r[aiter]); - this->column_indexes.push_back(c[aiter]); - this->values.push_back(alpha * v[aiter]); + this->row_indexes_.push_back(r[aiter]); + this->column_indexes_.push_back(c[aiter]); + this->values_.push_back(alpha * v[aiter]); this->checkIncreaseSize(r[aiter], c[aiter]); aiter++; } - if (aiter >= static_cast(r.size())) break; + if (aiter >= static_cast(r.size())) + { + break; + } - if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + if (r[aiter] == this->row_indexes_[i] && c[aiter] == this->column_indexes_[i]) { - this->values[i] += alpha * v[aiter]; + this->values_[i] += alpha * v[aiter]; aiter++; } } - //push back rest that was not found sorted + //push back rest that was not found sorted_ for (Intdx i = aiter; i < static_cast(r.size()); i++) { - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(alpha * v[i]); + this->row_indexes_.push_back(r[i]); + this->column_indexes_.push_back(c[i]); + this->values_.push_back(alpha * v[i]); this->checkIncreaseSize(r[i], c[i]); } - this->sorted = false; + this->sorted_ = false; } /** - * @brief Scale all values + * @brief Scale all values_ * * @tparam ScalarT * @tparam Intdx * @param alpha */ template -inline void COO_Matrix::SCAL(ScalarT alpha) +inline void COO_Matrix::scal(ScalarT alpha) { - for (auto i = this->values.begin(); i < this->values.end(); i++) *i *= alpha; + for (auto i = this->values_.begin(); i < this->values_.end(); i++) + { + *i *= alpha; + } } +/** + * @brief Frobenius Norm of the Matrix + * + * @tparam ScalarT + * @tparam Intdx + * @return ScalarT + */ template inline ScalarT COO_Matrix::frobnorm() { ScalarT totsum = 0.0; - for (auto i = this->values.begin(); i < this->values.end(); i++) totsum += abs(*i)^2; + for (auto i = this->values_.begin(); i < this->values_.end(); i++) + { + totsum += abs(*i)^2; + } return totsum; } @@ -411,15 +435,15 @@ inline ScalarT COO_Matrix::frobnorm() template inline void COO_Matrix::permutation(std::vector row_perm, std::vector col_perm) { - assert(row_perm.size() = this->rows_size); - assert(col_perm.size() = this->columns_size); + assert(row_perm.size() = this->rows_size_); + assert(col_perm.size() = this->columns_size_); - for (int i = 0; i < this->values.size(); i++) + for (int i = 0; i < this->values_.size(); i++) { - this->row_indexes[i] = row_perm[this->row_indexes[i]]; - this->column_indexes[i] = col_perm[this->column_indexes[i]]; + this->row_indexes_[i] = row_perm[this->row_indexes_[i]]; + this->column_indexes_[i] = col_perm[this->column_indexes_[i]]; } - this->sorted = false; + this->sorted_ = false; //cycle sorting maybe useful since permutations are already known } @@ -437,25 +461,25 @@ inline void COO_Matrix::permutation(std::vector row_perm, template inline void COO_Matrix::permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n) { - assert(row_perm.size() == this->rows_size); - assert(col_perm.size() == this->columns_size); + assert(row_perm.size() == this->rows_size_); + assert(col_perm.size() == this->columns_size_); - this->rows_size = m; - this->columns_size = n; + this->rows_size_ = m; + this->columns_size_ = n; - for (int i = 0; i < this->values.size(); i++) + for (int i = 0; i < this->values_.size(); i++) { - if (row_perm[this->row_indexes[i]] == -1 || col_perm[this->column_indexes[i]] == -1) + if (row_perm[this->row_indexes_[i]] == -1 || col_perm[this->column_indexes_[i]] == -1) { - this->values[i] = 0; + this->values_[i] = 0; } else { - this->row_indexes[i] = row_perm[this->row_indexes[i]]; - this->column_indexes[i] = col_perm[this->column_indexes[i]]; + this->row_indexes_[i] = row_perm[this->row_indexes_[i]]; + this->column_indexes_[i] = col_perm[this->column_indexes_[i]]; } } - this->sorted = false; + this->sorted_ = false; } /** @@ -468,10 +492,10 @@ template inline void COO_Matrix::zeroMatrix() { //resize doesn't effect capacity if smaller - this->column_indexes.resize(0); - this->row_indexes.resize(0); - this->values.resize(0); - this->sorted = true; + this->column_indexes_.resize(0); + this->row_indexes_.resize(0); + this->values_.resize(0); + this->sorted_ = true; } template @@ -481,11 +505,11 @@ inline void COO_Matrix::identityMatrix(Intdx n) this->zeroMatrix(); for (Intdx i = 0; i < n; i++) { - this->column_indexes[i] = i; - this->row_indexes[i] = i; - this->values[i] = 1.0; + this->column_indexes_[i] = i; + this->row_indexes_[i] = i; + this->values_[i] = 1.0; } - this->sorted = true; + this->sorted_ = true; } /** @@ -497,30 +521,30 @@ inline void COO_Matrix::identityMatrix(Intdx n) template inline void COO_Matrix::sortSparse() { - this->sortSparseCOO(this->row_indexes, this->column_indexes, this->values); - this->sorted = true; + this->sortSparseCOO(this->row_indexes_, this->column_indexes_, this->values_); + this->sorted_ = true; } template inline bool COO_Matrix::isSorted() { - return this->sorted; + return this->sorted_; } template inline Intdx COO_Matrix::nnz() { - return static_cast(this->values.size); + return static_cast(this->values_.size); } template inline std::tuple COO_Matrix::getDimensions() { - return std::tuple(this->rows_size, this->columns_size); + return std::tuple(this->rows_size_, this->columns_size_); } /** - * @brief Print matrix that is sorted + * @brief Print matrix that is sorted_ * * @tparam ScalarT * @tparam Intdx @@ -528,25 +552,26 @@ inline std::tuple COO_Matrix::getDimensions() template inline void COO_Matrix::printMatrix() { - if (this->sorted == false) + if (this->sorted_ == false) { this->sortSparse(); } std::cout << "Sparse COO Matrix\n"; std::cout << "(x , y, value)\n"; - for (size_t i = 0; i < this->values.size(); i++) + for (size_t i = 0; i < this->values_.size(); i++) { - std::cout << "(" << this->row_indexes[i] - << ", " << this->column_indexes[i] - << ", " << this->values[i] << ")\n"; + std::cout << "(" << this->row_indexes_[i] + << ", " << this->column_indexes_[i] + << ", " << this->values_[i] << ")\n"; } + std::cout << std::flush; } /** * @brief Find the lowest row cordinate from set of provided cordinates * - * Assumes rows and columns are sorted + * Assumes rows and columns are sorted_ * @tparam ScalarT * @tparam Intdx * @param r @@ -639,14 +664,14 @@ template inline bool COO_Matrix::checkIncreaseSize(Intdx r, Intdx c) { bool changed = false; - if (r + 1 > this->rows_size) + if (r + 1 > this->rows_size_) { - this->rows_size = r + 1; + this->rows_size_ = r + 1; changed = true; } - if (c + 1 > this->columns_size) + if (c + 1 > this->columns_size_) { - this->columns_size = c + 1; + this->columns_size_ = c + 1; changed = true; } @@ -654,22 +679,22 @@ inline bool COO_Matrix::checkIncreaseSize(Intdx r, Intdx c) } /** - * @brief Sort a disoreded set of values. Assume nothing on order. + * @brief Sort a disoreded set of values_. Assume nothing on order. * - * @todo simple setup. Should add stable sorting since list are pre-sorted + * @todo simple setup. Should add stable sorting since list are pre-sorted_ * * @tparam ScalarT * @tparam Intdx * @param rows * @param columns - * @param values + * @param values_ */ template -inline void COO_Matrix::sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values) +inline void COO_Matrix::sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &vals) { //index based sort code - // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted-vector + // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted_-vector //cannot call sort since two arrays are used instead std::vector ordervec(rows.size()); std::size_t n(0); @@ -692,7 +717,7 @@ inline void COO_Matrix::sortSparseCOO(std::vector &rows, { std::swap(rows[ordervec[i]], rows[ordervec[ordervec[i]]]); std::swap(columns[ordervec[i]], columns[ordervec[ordervec[i]]]); - std::swap(values[ordervec[i]], values[ordervec[ordervec[i]]]); + std::swap(vals[ordervec[i]], vals[ordervec[ordervec[i]]]); //swap orderings std::swap(ordervec[i], ordervec[ordervec[i]]); @@ -704,34 +729,34 @@ inline void COO_Matrix::sortSparseCOO(std::vector &rows, template inline COO_Matrix::COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n) { - this->values = v; - this->row_indexes = r; - this->column_indexes = c; - this->rows_size = m; - this->columns_size = n; - this->sorted = false; + this->values_ = v; + this->row_indexes_ = r; + this->column_indexes_ = c; + this->rows_size_ = m; + this->columns_size_ = n; + this->sorted_ = false; } template inline COO_Matrix::COO_Matrix(Intdx m, Intdx n) { - this->rows_size = m; - this->columns_size = n; - this->values = std::vector(); - this->row_indexes = std::vector(); - this->column_indexes = std::vector(); - this->sorted = false; + this->rows_size_ = m; + this->columns_size_ = n; + this->values_ = std::vector(); + this->row_indexes_ = std::vector(); + this->column_indexes_ = std::vector(); + this->sorted_ = false; } template inline COO_Matrix::COO_Matrix() { - this->rows_size = 0; - this->columns_size = 0; - this->values = std::vector(); - this->row_indexes = std::vector(); - this->column_indexes = std::vector(); - this->sorted = false; + this->rows_size_ = 0; + this->columns_size_ = 0; + this->values_ = std::vector(); + this->row_indexes_ = std::vector(); + this->column_indexes_ = std::vector(); + this->sorted_ = false; } template From 425b7d0c2f1b709a7c2d4a029b83fc312565299a Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Thu, 20 Oct 2022 17:20:51 -0500 Subject: [PATCH 21/44] Add bus factory. Parse load data from the input file. Check load data when testing Matpower parser. Do not store load data in bus data structure. Changed names and order of template parameters in power system data structures. More intuitieve data structures names Changed names of data structures to distinguish Matpower specific data and general power system description data. Pass correct scalar and real types to derived bus classes. Add generator base and slack classes. Classes compile correctly, not tested yet. Infrastructure for adding buses and generators to power flow models Add steady-state generator models and factory. Constructors now read directly from GenData and BusData structures. Updated Bus classes accordingly. Usage example provided in Grid3BusSys app. Supporting infrastructure for Loads and Branches Expanded methods for adding components to the power system grid. Includes new constructors for loads and branches, as well as methods for accessing buses through their IDs. Updated Parsing Example Fixed Memory Errors in KinSol and SystemSteadyStateModel +Clean valgrind output Prototype Example of Creating a RL Circuit +Add hypergraph representation +Added Model form with appropiate indexing +Added Resistors, Capacitor, Inductor, and VoltageSource Component Models Add capability to build power flow models from Matpower input files Use more realistic test passing criterion Release 0.0.7 updates --- CircuitGraph.hpp | 119 ++++++++++ ComponentLib/CMakeLists.txt | 2 + .../PowerElectronicsComponents/CMakeLists.txt | 6 + .../Capacitor/CMakeLists.txt | 8 + .../Capacitor/Capacitor.cpp | 117 ++++++++++ .../Capacitor/Capacitor.hpp | 64 ++++++ .../CircuitComponent.hpp | 68 ++++++ .../Inductor/CMakeLists.txt | 8 + .../Inductor/Inductor.cpp | 117 ++++++++++ .../Inductor/Inductor.hpp | 66 ++++++ .../Resistor/CMakeLists.txt | 8 + .../Resistor/Resistor.cpp | 117 ++++++++++ .../Resistor/Resistor.hpp | 65 ++++++ .../VoltageSource/CMakeLists.txt | 8 + .../VoltageSource/VoltageSource.cpp | 119 ++++++++++ .../VoltageSource/VoltageSource.hpp | 63 +++++ Examples/CMakeLists.txt | 1 + Examples/Grid3Bus/3bus.mat | 47 ++++ Examples/RLCircuit/CMakeLists.txt | 12 + Examples/RLCircuit/RLCircuit.cpp | 114 +++++++++ ModelEvaluatorImpl.hpp | 8 + PowerElectronicsModel.hpp | 217 ++++++++++++++++++ SystemSteadyStateModel.hpp | 37 +++ 23 files changed, 1391 insertions(+) create mode 100644 CircuitGraph.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/Capacitor/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/Inductor/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/Resistor/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/VoltageSource/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp create mode 100644 Examples/Grid3Bus/3bus.mat create mode 100644 Examples/RLCircuit/CMakeLists.txt create mode 100644 Examples/RLCircuit/RLCircuit.cpp create mode 100644 PowerElectronicsModel.hpp diff --git a/CircuitGraph.hpp b/CircuitGraph.hpp new file mode 100644 index 000000000..e54f5a150 --- /dev/null +++ b/CircuitGraph.hpp @@ -0,0 +1,119 @@ + + +#include +#include +#include +#include +#include + +/** + * @brief A very basic hypergraph setup for circuit representation. This forms the hypergraph as a bipartite graph. Doesn't allow removing. Can only grab sets of connections to nodes + * + * @todo should replace with something better and more efficent. Should replace with a libraries setup instead. This would allow fast and easy partitioning of circuits + * + * @todo should replace N and E with Node and Component classes respectively + * + * @tparam IdxT + * @tparam Label + */ +template +class CircuitGraph +{ +private: + std::set hypernodes; + std::set hyperedges; + std::map> edgestonodes; +public: + CircuitGraph(); + ~CircuitGraph(); + bool addHyperEdge(E he); + bool addHyperNode(N hn); + bool addConnection(N hn, E he); + std::set getHyperEdgeConnections(E he); + size_t amountHyperNodes(); + size_t amountHyperEdges(); + void printBiPartiteGraph(bool verbose = false); +}; + +template +CircuitGraph::CircuitGraph() +{ +} + +template +CircuitGraph::~CircuitGraph() +{ +} + +template +bool CircuitGraph::addHyperNode(N hn) +{ + return this->hypernodes.insert(hn).second; +} + +template +bool CircuitGraph::addHyperEdge(E he) +{ + return this->hyperedges.insert(he).second; +} + + +template +bool CircuitGraph::addConnection(N hn, E he) +{ + if(this->hyperedges.count(he) == 0 || this->hypernodes.count(hn) == 0) + { + return false; + } + return this->edgestonodes[he].insert(hn).second; +} + + +template +std::set CircuitGraph::getHyperEdgeConnections(E he) +{ + return this->edgestonodes[he]; +} + + +template +size_t CircuitGraph::amountHyperNodes() +{ + return this->hypernodes.size(); +} + + +template +size_t CircuitGraph::amountHyperEdges() +{ + return this->hyperedges.size(); +} + +/** + * @brief Printing + * + * @todo need to add verbose printing for connections display + * + * @tparam IdxT + * @param verbose + */ + +template +void CircuitGraph::printBiPartiteGraph(bool verbose) +{ + + std::cout << "Amount of HyperNodes: " << this->amountHyperNodes() << std::endl; + std::cout << "Amount of HyperEdges: " << this->amountHyperEdges() << std::endl; + std::cout << "Connections per Edge:" << std::endl; + for (auto i : this->edgestonodes) + { + std::cout << i.first << " : {"; + for (auto j : i.second){ + std::cout << j << ", "; + } + std::cout << "}\n"; + + } + + +} diff --git a/ComponentLib/CMakeLists.txt b/ComponentLib/CMakeLists.txt index 0c422d5b9..29a5a7988 100644 --- a/ComponentLib/CMakeLists.txt +++ b/ComponentLib/CMakeLists.txt @@ -69,3 +69,5 @@ add_subdirectory(Generator4Governor) add_subdirectory(Generator4Param) add_subdirectory(Load) add_subdirectory(MiniGrid) +add_subdirectory(PowerElectronicsComponents) + diff --git a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt new file mode 100644 index 000000000..c3e958300 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt @@ -0,0 +1,6 @@ + + +add_subdirectory(Capacitor) +add_subdirectory(Resistor) +add_subdirectory(VoltageSource) +add_subdirectory(Inductor) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/Capacitor/CMakeLists.txt new file mode 100644 index 000000000..62efc1795 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_capacitor + SOURCES + Capacitor.cpp + OUTPUT_NAME + gridkit_powerelec_capacitor) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp new file mode 100644 index 000000000..4fcda9d9f --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -0,0 +1,117 @@ + + + +#include +#include +#include +#include "Capacitor.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant load model + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +Capacitor::Capacitor(IdxT id, ScalarT C) + : C_(C) +{ + this->size_ = 3; + this->n_intern = 1; + this->n_extern = 2; + this->extern_indices = {0,1}; + this->idc_ = id; +} + +template +Capacitor::~Capacitor() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int Capacitor::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + return 0; +} + +/** + * Initialization of the grid model + */ +template +int Capacitor::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int Capacitor::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int Capacitor::evaluateResidual() +{ + this->f_[0] = this->yp_[2]; + this->f_[1] = -this->yp_[2]; + this->f_[2] = this->y_[0] - this->y_[1] - this->y_[2] - this->C_ * this->yp_[2]; + return 0; +} + +template +int Capacitor::evaluateJacobian() +{ + + return 0; +} + +template +int Capacitor::evaluateIntegrand() +{ + return 0; +} + +template +int Capacitor::initializeAdjoint() +{ + return 0; +} + +template +int Capacitor::evaluateAdjointResidual() +{ + return 0; +} + +template +int Capacitor::evaluateAdjointIntegrand() +{ + return 0; +} + + + + +// Available template instantiations +template class Capacitor; +template class Capacitor; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp new file mode 100644 index 000000000..76cf94614 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp @@ -0,0 +1,64 @@ + + +#ifndef _CAP_HPP_ +#define _CAP_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive Capacitor class. + * + */ + template + class Capacitor : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + public: + Capacitor(IdxT id, ScalarT C); + virtual ~Capacitor(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT C_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp new file mode 100644 index 000000000..7cfb5521a --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp @@ -0,0 +1,68 @@ + + +#ifndef _CIRCCOMP_HPP_ +#define _CIRCCOMP_HPP_ + +#include +#include +#include +#include + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive CircuitComponent class. + * + */ + template + class CircuitComponent : public ModelEvaluatorImpl + { + + public: + + + void updateTime(ScalarT t, ScalarT a) + { + this->time_ = t; + this->alpha_ = a; + } + + size_t getExternSize() + { + return this->n_extern; + } + + size_t getInternalSize() + { + return this->n_intern; + } + + std::set getExternIndices() + { + return this->extern_indices; + } + + bool setExternalConnectionNodes(size_t index, IdxT id) + { + this->connection_nodes[index] = id; + return true; + } + + IdxT getNodeConnection(size_t index) + { + return this->connection_nodes.at(index); + } + + protected: + size_t n_extern; + size_t n_intern; + std::set extern_indices; + std::map connection_nodes; + + }; + + +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/Inductor/CMakeLists.txt new file mode 100644 index 000000000..4c620030f --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Inductor/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_inductor + SOURCES + Inductor.cpp + OUTPUT_NAME + gridkit_powerelec_inductor) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp new file mode 100644 index 000000000..278b0eebc --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -0,0 +1,117 @@ + + + +#include +#include +#include +#include "Inductor.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant load model + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +Inductor::Inductor(IdxT id, ScalarT L) + : L_(L) +{ + this->size_ = 3; + this->n_intern = 1; + this->n_extern = 2; + this->extern_indices = {0,1}; + this->idc_ = id; +} + +template +Inductor::~Inductor() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int Inductor::allocate() +{ + + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + return 0; +} + +/** + * Initialization of the grid model + */ +template +int Inductor::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int Inductor::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int Inductor::evaluateResidual() +{ + this->f_[0] = this->y_[2]; + this->f_[1] = -this->y_[2]; + this->f_[2] = this->y_[0] - this->y_[1] - this->L_ * this->yp_[2]; + return 0; +} + +template +int Inductor::evaluateJacobian() +{ + return 0; +} + +template +int Inductor::evaluateIntegrand() +{ + return 0; +} + +template +int Inductor::initializeAdjoint() +{ + return 0; +} + +template +int Inductor::evaluateAdjointResidual() +{ + return 0; +} + +template +int Inductor::evaluateAdjointIntegrand() +{ + return 0; +} + + + + +// Available template instantiations +template class Inductor; +template class Inductor; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp new file mode 100644 index 000000000..e959aabf1 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp @@ -0,0 +1,66 @@ + + +#ifndef _IND_HPP_ +#define _IND_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive Inductor class. + * + */ + template + class Inductor : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + + public: + Inductor(IdxT id, ScalarT L); + virtual ~Inductor(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + + private: + ScalarT L_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/Resistor/CMakeLists.txt new file mode 100644 index 000000000..9386bda83 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Resistor/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_resistor + SOURCES + Resistor.cpp + OUTPUT_NAME + gridkit_powerelec_resistor) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp new file mode 100644 index 000000000..1aa06427a --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp @@ -0,0 +1,117 @@ + + + +#include +#include +#include +#include "Resistor.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant resistor model + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +Resistor::Resistor(IdxT id, ScalarT R) + : R_(R) +{ + this->size_ = 2; + this->n_intern = 0; + this->n_extern = 2; + this->extern_indices = {0,1}; + this->idc_ = id; +} + +template +Resistor::~Resistor() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int Resistor::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + return 0; +} + +/** + * Initialization of the grid model + */ +template +int Resistor::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int Resistor::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int Resistor::evaluateResidual() +{ + + this->f_[0] = (this->y_[1] - this->y_[0])/this->R_ ; + this->f_[1] = (this->y_[0] - this->y_[1])/this->R_ ; + return 0; +} + +template +int Resistor::evaluateJacobian() +{ + return 0; +} + +template +int Resistor::evaluateIntegrand() +{ + return 0; +} + +template +int Resistor::initializeAdjoint() +{ + return 0; +} + +template +int Resistor::evaluateAdjointResidual() +{ + return 0; +} + +template +int Resistor::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class Resistor; +template class Resistor; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp new file mode 100644 index 000000000..0373e2c5c --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp @@ -0,0 +1,65 @@ + + +#ifndef _RES_HPP_ +#define _RES_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive Resistor class. + * + */ + template + class Resistor : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + public: + Resistor(IdxT id, ScalarT R); + virtual ~Resistor(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + + private: + ScalarT R_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/VoltageSource/CMakeLists.txt new file mode 100644 index 000000000..7196f4d43 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_voltagesource + SOURCES + VoltageSource.cpp + OUTPUT_NAME + gridkit_powerelec_voltagesource) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp new file mode 100644 index 000000000..c27c04bd2 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -0,0 +1,119 @@ + + + +#include +#include +#include +#include "VoltageSource.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant VoltageSource model + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +VoltageSource::VoltageSource(IdxT id, ScalarT V) + : V_(V) +{ + this->size_ = 3; + this->n_intern = 1; + this->n_extern = 2; + this->extern_indices = {0,1}; + this->idc_ = id; +} + +template +VoltageSource::~VoltageSource() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int VoltageSource::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + return 0; +} + +/** + * Initialization of the grid model + */ +template +int VoltageSource::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int VoltageSource::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int VoltageSource::evaluateResidual() +{ + //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors + // for easier development + this->f_[0] = this->y_[2]; + this->f_[1] = -this->y_[2]; + this->f_[2] = this->y_[0] - this->y_[1] - this->V_; + return 0; +} + +template +int VoltageSource::evaluateJacobian() +{ + return 0; +} + +template +int VoltageSource::evaluateIntegrand() +{ + return 0; +} + +template +int VoltageSource::initializeAdjoint() +{ + return 0; +} + +template +int VoltageSource::evaluateAdjointResidual() +{ + return 0; +} + +template +int VoltageSource::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class VoltageSource; +template class VoltageSource; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp new file mode 100644 index 000000000..dcbacf2f7 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp @@ -0,0 +1,63 @@ + + +#ifndef _VOSO_HPP_ +#define _VOSO_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive VoltageSource class. + * + */ + template + class VoltageSource : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + public: + VoltageSource(IdxT id, ScalarT V); + virtual ~VoltageSource(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT V_; + }; +} + +#endif diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index feec6623a..b42907fd3 100644 --- a/Examples/CMakeLists.txt +++ b/Examples/CMakeLists.txt @@ -56,6 +56,7 @@ # add_subdirectory(MatPowerTesting) +add_subdirectory(RLCircuit) if(TARGET SUNDIALS::kinsol) add_subdirectory(Grid3Bus) diff --git a/Examples/Grid3Bus/3bus.mat b/Examples/Grid3Bus/3bus.mat new file mode 100644 index 000000000..4663eb33c --- /dev/null +++ b/Examples/Grid3Bus/3bus.mat @@ -0,0 +1,47 @@ +( +function mpc = case5 +% Created by Reid Gomillion + +% MATPOWER + +%% MATPOWER Case Format : Version 2 +mpc.version = '2'; + +%%----- Power Flow Data -----%% +%% system MVA base +mpc.baseMVA = 100; + +%% bus data +% bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin +mpc.bus = [ + 1 3 2.0 0.0 0 0 0 1 0.0 0 0 0 0.0; + 2 1 2.5 -0.8 0 0 0 1 0.0 0 0 0 0.0; + 3 2 0 0 0 0 0 1.1 0.0 0 0 0 0.0; +]; + +%% generator data +% bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf +mpc.gen = [ + 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; + 3 2.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; +]; + +%% branch data +% fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax +mpc.branch = [ + 1 2 0 0.1 0 0 0 0 0 0 0 0 0; + 1 3 0 0.0666666 0 0 0 0 0 0 0 0 0; + 2 3 0 0.0833333 0 0 0 0 0 0 0 0 0; +]; + +%%----- OPF Data -----%% +%% generator cost data +% 1 startup shutdown n x1 y1 ... xn yn +% 2 startup shutdown n c(n-1) ... c0 +mpc.gencost = [ + 2 0 0 3 0 14 0; + 2 0 0 3 0 15 0; + 2 0 0 3 0 30 0; +]; + +) \ No newline at end of file diff --git a/Examples/RLCircuit/CMakeLists.txt b/Examples/RLCircuit/CMakeLists.txt new file mode 100644 index 000000000..5069566bf --- /dev/null +++ b/Examples/RLCircuit/CMakeLists.txt @@ -0,0 +1,12 @@ + + + + +add_executable(rlcircuit RLCircuit.cpp) +target_link_libraries(rlcircuit GRIDKIT::powerelec_capacitor + GRIDKIT::powerelec_inductor + GRIDKIT::powerelec_resistor + GRIDKIT::powerelec_voltagesource) + +add_test(NAME RLCircuit COMMAND $) +install(TARGETS rlcircuit RUNTIME DESTINATION bin) diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp new file mode 100644 index 000000000..ba9333f40 --- /dev/null +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -0,0 +1,114 @@ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + + +int main(int argc, char const *argv[]) +{ + //Basic Circuit Setup + //@todo will want to eventually put components in the hyper graph instead of indicies + + std::unique_ptr> cirg(new CircuitGraph()); + for (size_t i = 0; i < 3; i++) + { + cirg->addHyperEdge(i); + } + for (size_t i = 0; i < 5; i++) + { + cirg->addHyperNode(i); + } + + //Create Connections of Nodes to edges sets + //External nodes + cirg->addConnection(0, 0); + cirg->addConnection(0, 2); + cirg->addConnection(2, 0); + cirg->addConnection(2, 1); + cirg->addConnection(3, 1); + cirg->addConnection(3, 2); + + //Internal nodes + cirg->addConnection(1,0); + cirg->addConnection(4,2); + + + cirg->printBiPartiteGraph(); + + + //Create circuit model + ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(); + + size_t idoff = 0; + + //inductor + ModelLib::Inductor* induct = new ModelLib::Inductor(idoff,0.1); + //Form index to node uid realations + induct->setExternalConnectionNodes(0,2); + induct->setExternalConnectionNodes(2,1); + induct->setExternalConnectionNodes(1,0); + sysmodel->addComponent(induct); + + + //resistor + idoff++; + ModelLib::Resistor* resis = new ModelLib::Resistor(idoff, 1.0); + //Form index to node uid realations + resis->setExternalConnectionNodes(0,3); + resis->setExternalConnectionNodes(1,2); + sysmodel->addComponent(resis); + + //voltage source + idoff++; + ModelLib::VoltageSource* vsource = new ModelLib::VoltageSource(idoff, 0.1); + //Form index to node uid realations + vsource->setExternalConnectionNodes(0,0); + vsource->setExternalConnectionNodes(2,4); + vsource->setExternalConnectionNodes(1,3); + sysmodel->addComponent(vsource); + + + //Allocate with graph + sysmodel->allocate(*cirg); + + std::cout << sysmodel->y().size() << std::endl; + + //Create Intial points + sysmodel->y()[0] = 1.0; + sysmodel->y()[1] = 1.0; + sysmodel->y()[2] = 1.0; + sysmodel->y()[3] = 1.0; + sysmodel->y()[4] = 1.0; + + sysmodel->yp()[0] = 1.0; + sysmodel->yp()[1] = 1.0; + sysmodel->yp()[2] = 1.0; + sysmodel->yp()[3] = 1.0; + sysmodel->yp()[4] = 1.0; + + + sysmodel->initialize(); + + sysmodel->evaluateResidual(); + + std::cout << "Output: {"; + for (double i : sysmodel->getResidual()) + { + std::cout << i << ", "; + } + std::cout << "}\n"; + + + return 0; +} diff --git a/ModelEvaluatorImpl.hpp b/ModelEvaluatorImpl.hpp index a4ef43a00..94cbeb5d3 100644 --- a/ModelEvaluatorImpl.hpp +++ b/ModelEvaluatorImpl.hpp @@ -252,6 +252,12 @@ namespace ModelLib return gB_; } + //@todo Fix ID naming + IdxT getIDcomponent() + { + return idc_; + } + protected: @@ -281,6 +287,8 @@ namespace ModelLib real_type rtol_; real_type atol_; + IdxT idc_; + }; diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp new file mode 100644 index 000000000..78350ee2f --- /dev/null +++ b/PowerElectronicsModel.hpp @@ -0,0 +1,217 @@ + + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +namespace ModelLib +{ + +template +class PowerElectronicsModel : public ModelEvaluatorImpl +{ + typedef CircuitComponent component_type; + + using ModelEvaluatorImpl::size_; + // using ModelEvaluatorImpl::size_quad_; + // using ModelEvaluatorImpl::size_opt_; + using ModelEvaluatorImpl::nnz_; + // using ModelEvaluatorImpl::time_; + // using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::yp_; + // using ModelEvaluatorImpl::yB_; + // using ModelEvaluatorImpl::ypB_; + // using ModelEvaluatorImpl::tag_; + using ModelEvaluatorImpl::f_; + // using ModelEvaluatorImpl::fB_; + // using ModelEvaluatorImpl::g_; + // using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::rtol_; + using ModelEvaluatorImpl::atol_; + // using ModelEvaluatorImpl::param_; + // using ModelEvaluatorImpl::param_up_; + // using ModelEvaluatorImpl::param_lo_; + +public: + /** + * @brief Constructor for the system model + */ + PowerElectronicsModel() : ModelEvaluatorImpl(0, 0, 0) + { + // Set system model tolerances + rtol_ = 1e-5; + atol_ = 1e-5; + } + + /** + * @brief Destructor for the system model + */ + virtual ~PowerElectronicsModel() + { + for (auto comp : this->components_) delete comp; + } + + /** + * @brief allocator default + * + * @todo this should throw an exception as no allocation without a graph is allowed. Or needs to be removed from the base class + * + * @return int + */ + int allocate() + { + + return 1; + } + + int allocate(CircuitGraph cir) + { + this->graph = cir; + + // Allocate all components + this->size_ = cir.amountHyperNodes(); + for(const auto& component : components_) + { + component->allocate(); + } + + // Allocate global vectors + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); + + return 0; + } + + int initialize() + { + + // Initialize components + for(const auto& component : components_) + { + component->initialize(); + } + + for(const auto& component : components_) + { + for(IdxT j=0; jsize(); ++j) + { + component->y()[j] = y_[component->getNodeConnection(j)]; + component->yp()[j] = yp_[component->getNodeConnection(j)]; + } + } + return 0; + } + + int tagDifferentiable() + { + return 0; + } + + int evaluateResidual() + { + for (IdxT i = 0; i < this->f_.size(); i++) + { + f_[i] = 0; + } + + // Update variables + for(const auto& component : components_) + { + for(IdxT j=0; jsize(); ++j) + { + component->y()[j] = y_[component->getNodeConnection(j)]; + component->yp()[j] = yp_[component->getNodeConnection(j)]; + } + component->evaluateResidual(); + } + + // Update system residual vector + + for(const auto& component : components_) + { + for(IdxT j=0; jsize(); ++j) + { + f_[component->getNodeConnection(j)] += component->getResidual()[j]; + } + } + + return 0; + } + + int evaluateJacobian() + { + return 0; + } + + /** + * @brief Evaluate integrands for the system quadratures. + */ + int evaluateIntegrand() + { + + return 0; + } + + /** + * @brief Initialize system adjoint. + * + * Updates variables and optimization parameters, then initializes + * adjoints locally and copies them to the system adjoint vector. + */ + int initializeAdjoint() + { + return 0; + } + + /** + * @brief Compute adjoint residual for the system model. + * + * + */ + int evaluateAdjointResidual() + { + return 0; + } + + + /** + * @brief Evaluate adjoint integrand for the system model. + * + * + */ + int evaluateAdjointIntegrand() + { + return 0; + } + + void updateTime(ScalarT t, ScalarT a) + { + } + + void addComponent(component_type* component) + { + this->components_.push_back(component); + } + + CircuitGraph getGraph() + { + return this->graph; + } + +private: + std::vector components_; + + CircuitGraph graph; + +}; // class PowerElectronicsModel + +} // namespace ModelLib diff --git a/SystemSteadyStateModel.hpp b/SystemSteadyStateModel.hpp index c32dd5ec3..de2dc000e 100644 --- a/SystemSteadyStateModel.hpp +++ b/SystemSteadyStateModel.hpp @@ -127,6 +127,43 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl atol_ = 1e-5; } + SystemSteadyStateModel(GridKit::PowerSystemData::SystemModelData mp) : ModelEvaluatorImpl(0,0,0) + { + rtol_ = 1e-5; + atol_ = 1e-5; + + //buses + for(auto busdata : mp.bus) + { + auto* bus = BusFactory::create(busdata); + this->addBus(bus); + } + + //generators + for (auto gendata : mp.gen) + { + auto* gen = GeneratorFactory::create(this->getBus(gendata.bus),gendata); + this->addComponent(gen); + } + + //branches + for (auto branchdata : mp.branch) + { + auto* branch = new Branch(this->getBus(branchdata.fbus),this->getBus(branchdata.tbus),branchdata); + this->addComponent(branch); + } + + //loads + for (auto loaddata : mp.load) + { + auto* loadm = new Load(this->getBus(loaddata.bus_i),loaddata); + this->addComponent(loadm); + } + + //There appears to not be a Generator Cost Object + //TODO: Implment for GenCost + } + /** * @brief Construct a new System Steady State Model object. Allows for simple allocation. * From e0c778e87942d2ddf3e17a8a743d87175a884680 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Thu, 27 Jul 2023 16:44:39 -0400 Subject: [PATCH 22/44] Add New Components and Changes to Composition +Added InductionMotor, Linear Transformer, and SynchronousMachine +Changes to PowerElectronicsModel --- .../PowerElectronicsComponents/CMakeLists.txt | 5 +- .../Capacitor/Capacitor.cpp | 2 + .../CircuitComponent.hpp | 69 ++++++++ .../InductionMotor/CMakeLists.txt | 8 + .../InductionMotor/InductionMotor.cpp | 135 ++++++++++++++++ .../InductionMotor/InductionMotor.hpp | 69 ++++++++ .../Inductor/Inductor.cpp | 2 + .../LinearTransformer/CMakeLists.txt | 8 + .../LinearTransformer/LinearTransformer.cpp | 124 ++++++++++++++ .../LinearTransformer/LinearTransformer.hpp | 67 ++++++++ .../Resistor/Resistor.cpp | 2 + .../SynchronousMachine/CMakeLists.txt | 8 + .../SynchronousMachine/SynchronousMachine.cpp | 151 ++++++++++++++++++ .../SynchronousMachine/SynchronousMachine.hpp | 76 +++++++++ .../VoltageSource/VoltageSource.cpp | 4 +- Examples/RLCircuit/RLCircuit.cpp | 31 +--- ModelEvaluatorImpl.hpp | 5 + PowerElectronicsModel.hpp | 19 ++- 18 files changed, 743 insertions(+), 42 deletions(-) create mode 100644 ComponentLib/PowerElectronicsComponents/InductionMotor/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/LinearTransformer/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/SynchronousMachine/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp diff --git a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt index c3e958300..10f2c6fdc 100644 --- a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt +++ b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt @@ -3,4 +3,7 @@ add_subdirectory(Capacitor) add_subdirectory(Resistor) add_subdirectory(VoltageSource) -add_subdirectory(Inductor) \ No newline at end of file +add_subdirectory(Inductor) +add_subdirectory(LinearTransformer) +add_subdirectory(InductionMotor) +add_subdirectory(SynchronousMachine) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp index 4fcda9d9f..d905dda05 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -39,6 +39,8 @@ int Capacitor::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); + this->J_.resize(this->size_^2); + this->M_.resize(this->size_^2); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp index 7cfb5521a..9e1052e43 100644 --- a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp +++ b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp @@ -54,10 +54,79 @@ namespace ModelLib return this->connection_nodes.at(index); } + inline std::vector parkTransformMatrix(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = (2.0/3.0)*cos(angle); + result[1] = (2.0/3.0)*cos(anpim); + result[2] = (2.0/3.0)*cos(anpip); + result[3] = (2.0/3.0)*sin(angle); + result[4] = (2.0/3.0)*sin(anpim); + result[5] = (2.0/3.0)*sin(anpip); + result[6] = 1.0/3.0; + result[7] = 1.0/3.0; + result[8] = 1.0/3.0; + return result; + } + + inline std::vector parkTransformMatrixDerivative(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = (2.0/3.0)*sin(angle); + result[1] = (2.0/3.0)*sin(anpim); + result[2] = (2.0/3.0)*sin(anpip); + result[3] = (2.0/3.0)*-cos(angle); + result[4] = (2.0/3.0)*-cos(anpim); + result[5] = (2.0/3.0)*-cos(anpip); + result[6] = 0; + result[7] = 0; + result[8] = 0; + return result; + } + + inline std::vector inverseParkTransformMatrix(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = cos(angle); + result[1] = sin(angle); + result[2] = 1.0; + result[3] = cos(anpim); + result[4] = sin(anpim); + result[5] = 1.0; + result[6] = cos(anpip); + result[7] = sin(anpip); + result[8] = 1.0; + return result; + } + + inline std::vector inverseParkTransformMatrixDerivative(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = sin(angle); + result[1] = -cos(angle); + result[2] = 0.0; + result[3] = sin(anpim); + result[4] = -cos(anpim); + result[5] = 0.0; + result[6] = sin(anpip); + result[7] = -cos(anpip); + result[8] = 0.0; + return result; + } + protected: size_t n_extern; size_t n_intern; std::set extern_indices; + //@todo may want to replace the mapping of connection_nodes to Node objects instead of IdxT. Allows for container free setup std::map connection_nodes; }; diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/InductionMotor/CMakeLists.txt new file mode 100644 index 000000000..95ef42436 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_inductionmotor + SOURCES + InductionMotor.cpp + OUTPUT_NAME + gridkit_powerelec_inductionmotor) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp new file mode 100644 index 000000000..75782b435 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp @@ -0,0 +1,135 @@ + + + +#include +#include +#include +#include "InductionMotor.hpp" + + +namespace ModelLib { + + + +/*! + * @brief Constructor for a constant InductionMotor model + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +InductionMotor::InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, ScalarT Llr, ScalarT Rr, ScalarT Lms, ScalarT J, ScalarT P) + : Lls_(Lls), + Rs_(Rs), + Llr_(Llr), + Rr_(Rr), + Lms_(Lms), + J_(J), + P_(P) +{ + this->size_ = 10; + this->n_intern = 5; + this->n_extern = 5; + this->extern_indices = {0,1,2,3,4}; + this->idc_ = id; +} + +template +InductionMotor::~InductionMotor() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int InductionMotor::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + return 0; +} + +/** + * Initialization of the grid model + */ +template +int InductionMotor::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int InductionMotor::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int InductionMotor::evaluateResidual() +{ + //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors + // for easier development + this->f_[0] = y_[5] + y_[7]; + this->f_[1] = (-1.0/2.0) * y_[5] - (sqrt(3.0)/2.0)*y_[6] + y_[7]; + this->f_[2] = (-1.0/2.0) * y_[5] + (sqrt(3.0)/2.0)*y_[6] + y_[7]; + this->f_[3] = J_ * yp_[3] - (3.0/4.0)*P_*Lms_ * (y_[5]*y_[9] - y_[6]*y_[8]); + this->f_[4] = yp_[4] - y_[3]; + this->f_[5] = (1.0/3.0)*(2.0* y_[0] - y_[1] - y_[2]) - Rs_*y_[5] - (Lls_ + Lms_) * yp_[5] - Lms_ * yp_[6]; + this->f_[6] = (1.0/sqrt(3.0))*(-y_[1] + y_[2]) - Rs_*y_[6] - (Lls_ + Lms_) * yp_[6] - Lms_ * yp_[5]; + this->f_[7] = (y_[0] + y_[1] + y_[2])/3.0 - Rs_*y_[7] - Lls_ * yp_[7]; + this->f_[8] = Rr_*y_[8] + (Llr_ + Lms_)*yp_[8] + Lms_ * yp_[5] - (P_/2)*y_[3]*((Llr_+Lms_)*y_[9] + Lms_*y_[6]); + this->f_[9] = Rr_*y_[9] + (Llr_ + Lms_)*yp_[9] + Lms_ * yp_[6] + (P_/2)*y_[3]*((Llr_+Lms_)*y_[8] + Lms_*y_[5]); + return 0; +} + +template +int InductionMotor::evaluateJacobian() +{ + return 0; +} + +template +int InductionMotor::evaluateIntegrand() +{ + return 0; +} + +template +int InductionMotor::initializeAdjoint() +{ + return 0; +} + +template +int InductionMotor::evaluateAdjointResidual() +{ + return 0; +} + +template +int InductionMotor::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class InductionMotor; +template class InductionMotor; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp new file mode 100644 index 000000000..2547754e2 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp @@ -0,0 +1,69 @@ + + +#ifndef _IMOTOR_HPP_ +#define _IMOTOR_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive InductionMotor class. + * + */ + template + class InductionMotor : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + public: + InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, ScalarT Llr, ScalarT Rr, ScalarT Lms, ScalarT J, ScalarT P); + virtual ~InductionMotor(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT Lls_; + ScalarT Rs_; + ScalarT Llr_; + ScalarT Rr_; + ScalarT Lms_; + ScalarT J_; + ScalarT P_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index 278b0eebc..952a992d0 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -40,6 +40,8 @@ int Inductor::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); + this->J_.resize(this->size_^2); + this->M_.resize(this->size_^2); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/LinearTransformer/CMakeLists.txt new file mode 100644 index 000000000..eaf95c043 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_lineartrasnformer + SOURCES + LinearTransformer.cpp + OUTPUT_NAME + gridkit_powerelec_lineartrasnformer) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp new file mode 100644 index 000000000..4caaeae66 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp @@ -0,0 +1,124 @@ + + + +#include +#include +#include +#include "LinearTransformer.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant LinearTransformer model + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +LinearTransformer::LinearTransformer(IdxT id, ScalarT L1, ScalarT L2, ScalarT R1, ScalarT R2, ScalarT M) + : L1_(L1), + L2_(L2), + R1_(R1), + R2_(R2), + M_(M) +{ + this->size_ = 4; + this->n_intern = 2; + this->n_extern = 2; + this->extern_indices = {0,1}; + this->idc_ = id; +} + +template +LinearTransformer::~LinearTransformer() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int LinearTransformer::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + return 0; +} + +/** + * Initialization of the grid model + */ +template +int LinearTransformer::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int LinearTransformer::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int LinearTransformer::evaluateResidual() +{ + //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors + // for easier development + this->f_[0] = this->y_[2]; + this->f_[1] = this->y_[3]; + this->f_[2] = this->y_[0] - this->R1_ * this->y_[2] - this->L1_ * this->yp_[2] - this->M_ * this->yp_[3]; + this->f_[2] = this->y_[1] - this->R2_ * this->y_[3] - this->M_ * this->yp_[2] - this->L2_ * this->yp_[3]; + return 0; +} + +template +int LinearTransformer::evaluateJacobian() +{ + return 0; +} + +template +int LinearTransformer::evaluateIntegrand() +{ + return 0; +} + +template +int LinearTransformer::initializeAdjoint() +{ + return 0; +} + +template +int LinearTransformer::evaluateAdjointResidual() +{ + return 0; +} + +template +int LinearTransformer::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class LinearTransformer; +template class LinearTransformer; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp new file mode 100644 index 000000000..cf56adfa2 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp @@ -0,0 +1,67 @@ + + +#ifndef _LTRANS_HPP_ +#define _LTRANS_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive LinearTransformer class. + * + */ + template + class LinearTransformer : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + public: + LinearTransformer(IdxT id, ScalarT L1, ScalarT L2, ScalarT R1, ScalarT R2, ScalarT M); + virtual ~LinearTransformer(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT L1_; + ScalarT L2_; + ScalarT R1_; + ScalarT R2_; + ScalarT M_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp index 1aa06427a..5faad23b4 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp @@ -39,6 +39,8 @@ int Resistor::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); + this->J_.resize(this->size_^2); + this->M_.resize(this->size_^2); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/CMakeLists.txt new file mode 100644 index 000000000..bfaeace4b --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_synmachine + SOURCES + SynchronousMachine.cpp + OUTPUT_NAME + gridkit_powerelec_synmachine) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp new file mode 100644 index 000000000..05b1e59ac --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp @@ -0,0 +1,151 @@ + + + +#include +#include +#include +#include "SynchronousMachine.hpp" + + +namespace ModelLib { + + + +/*! + * @brief Constructor for a constant SynchronousMachine model + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +SynchronousMachine::SynchronousMachine(IdxT id, ScalarT Lls, std::tuple Llkq, ScalarT Llfd, ScalarT Llkd, ScalarT Lmq, ScalarT Lmd, ScalarT Rs, std::tuple Rkq, ScalarT Rfd, ScalarT Rkd, ScalarT J, ScalarT P, ScalarT mub) + : Lls_(Lls), + Llkq_(Llkq), + Llfd_(Llfd), + Llkd_(Llkd), + Lmq_(Lmq), + Lmd_(Lmd), + Rs_(Rs), + Rkq_(Rkq), + Rfd_(Rfd), + Rkd_(Rkd), + J_(J), + P_(P), + mub_(mub) +{ + this->size_ = 13; + this->n_intern = 6; + this->n_extern = 7; + this->extern_indices = {0,1,2,3,4}; + this->idc_ = id; +} + +template +SynchronousMachine::~SynchronousMachine() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int SynchronousMachine::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + return 0; +} + +/** + * Initialization of the grid model + */ +template +int SynchronousMachine::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int SynchronousMachine::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int SynchronousMachine::evaluateResidual() +{ + ScalarT rkq1 = std::get<0>(Rkq_); + ScalarT rkq2 = std::get<1>(Rkq_); + ScalarT llkq1 = std::get<0>(Llkq_); + ScalarT llkq2 = std::get<1>(Llkq_); + + ScalarT cos1 = cos((P_/2.0)*y_[5]); + ScalarT sin1 = sin((P_/2.0)*y_[5]); + ScalarT cos23m = cos((P_/2.0)*y_[5] - (2.0/3.0)*M_PI); + ScalarT sin23m = sin((P_/2.0)*y_[5] - (2.0/3.0)*M_PI); + ScalarT cos23p = cos((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); + ScalarT sin23p = sin((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); + + this->f_[0] = y_[6]*cos1 + y_[7]*sin1 + y_[8]; + this->f_[1] = y_[6]*cos23m + y_[7]*sin23m + y_[8]; + this->f_[2] = y_[6]*cos23p + y_[7]*sin23p + y_[8]; + this->f_[3] = J_ * yp_[4] - (3.0/4.0)*P_*(Lmd_ *y_[6]* (y_[7] + y_[11] + y_[12]) - Lmq_*y_[7]*(y_[6] + y_[9] + y_[0])); + this->f_[4] = yp_[5] - y_[4]; + this->f_[5] = (-2.0/3.0)*(y_[0]*cos1 +y_[1]*cos23m + y_[2]*cos23p) + Rs_*y_[6] + (Lls_ + Lmq_)*yp_[6] + Lmq_*yp_[9] + Lmq_*yp_[10] + y_[4]*(P_/2.0)*((Lls_ + Lmd_)*y_[7] + Lmd_*y_[11] + Lmd_*y_[12]); + this->f_[6] = (-2.0/3.0)*(y_[0]*sin1 -y_[1]*sin23m - y_[2]*sin23p) + Rs_*y_[7] + (Lls_ + Lmd_)*yp_[7] + Lmd_*yp_[11] + Lmd_*yp_[12] - y_[4]*(P_/2.0)*((Lls_ + Lmq_)*y_[6] + Lmq_*y_[9] + Lmq_*y_[10]); + this->f_[7] = (-1.0/3.0)*(y_[0] + y_[1] + y_[2]) + Rs_*y_[8] + Lls_*yp_[8]; + this->f_[8] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; + this->f_[9] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; + return 0; +} + +template +int SynchronousMachine::evaluateJacobian() +{ + return 0; +} + +template +int SynchronousMachine::evaluateIntegrand() +{ + return 0; +} + +template +int SynchronousMachine::initializeAdjoint() +{ + return 0; +} + +template +int SynchronousMachine::evaluateAdjointResidual() +{ + return 0; +} + +template +int SynchronousMachine::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class SynchronousMachine; +template class SynchronousMachine; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp new file mode 100644 index 000000000..a18eca9c9 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp @@ -0,0 +1,76 @@ + + +#ifndef _SYNMACH_HPP_ +#define _SYNMACH_HPP_ + +#include +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive SynchronousMachine class. + * + */ + template + class SynchronousMachine : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + public: + SynchronousMachine(IdxT id, ScalarT Lls, std::tuple Llkq, ScalarT Llfd, ScalarT Llkd, ScalarT Lmq, ScalarT Lmd, ScalarT Rs, std::tuple Rkq, ScalarT Rfd, ScalarT Rkd, ScalarT J, ScalarT P, ScalarT mub); + virtual ~SynchronousMachine(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT Lls_; + std::tuple Llkq_; + ScalarT Llfd_; + ScalarT Llkd_; + ScalarT Lmq_; + ScalarT Lmd_; + ScalarT Rs_; + std::tuple Rkq_; + ScalarT Rfd_; + ScalarT Rkd_; + ScalarT J_; + ScalarT P_; + ScalarT mub_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp index c27c04bd2..e26841a6c 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -39,6 +39,8 @@ int VoltageSource::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); + this->J_.resize(this->size_^2); + this->M_.resize(this->size_^2); return 0; } @@ -72,7 +74,7 @@ int VoltageSource::evaluateResidual() // for easier development this->f_[0] = this->y_[2]; this->f_[1] = -this->y_[2]; - this->f_[2] = this->y_[0] - this->y_[1] - this->V_; + this->f_[2] = this->y_[1] - this->y_[0] - this->V_; return 0; } diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp index ba9333f40..6d44d6b4f 100644 --- a/Examples/RLCircuit/RLCircuit.cpp +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -12,39 +12,10 @@ #include #include -#include int main(int argc, char const *argv[]) { - //Basic Circuit Setup - //@todo will want to eventually put components in the hyper graph instead of indicies - - std::unique_ptr> cirg(new CircuitGraph()); - for (size_t i = 0; i < 3; i++) - { - cirg->addHyperEdge(i); - } - for (size_t i = 0; i < 5; i++) - { - cirg->addHyperNode(i); - } - - //Create Connections of Nodes to edges sets - //External nodes - cirg->addConnection(0, 0); - cirg->addConnection(0, 2); - cirg->addConnection(2, 0); - cirg->addConnection(2, 1); - cirg->addConnection(3, 1); - cirg->addConnection(3, 2); - - //Internal nodes - cirg->addConnection(1,0); - cirg->addConnection(4,2); - - - cirg->printBiPartiteGraph(); //Create circuit model @@ -80,7 +51,7 @@ int main(int argc, char const *argv[]) //Allocate with graph - sysmodel->allocate(*cirg); + sysmodel->allocate(5); std::cout << sysmodel->y().size() << std::endl; diff --git a/ModelEvaluatorImpl.hpp b/ModelEvaluatorImpl.hpp index 94cbeb5d3..72abb858b 100644 --- a/ModelEvaluatorImpl.hpp +++ b/ModelEvaluatorImpl.hpp @@ -90,6 +90,8 @@ namespace ModelLib yp_(size_), f_(size_), g_(size_quad_), + J_(size_quad^2), + M_(size_quad^2), yB_(size_), ypB_(size_), fB_(size_), @@ -277,6 +279,9 @@ namespace ModelLib std::vector fB_; std::vector gB_; + std::vector J_; + std::vector M_; + std::vector param_; std::vector param_up_; std::vector param_lo_; diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index 78350ee2f..7a9304716 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -72,12 +72,18 @@ class PowerElectronicsModel : public ModelEvaluatorImpl return 1; } - int allocate(CircuitGraph cir) + /** + * @brief Allocate the vector data with size amount + * @todo Add capability to go through component model connection to get the size of the actual vector + * + * @param s + * @return int + */ + int allocate(IdxT s) { - this->graph = cir; // Allocate all components - this->size_ = cir.amountHyperNodes(); + this->size_ = s; for(const auto& component : components_) { component->allocate(); @@ -202,16 +208,9 @@ class PowerElectronicsModel : public ModelEvaluatorImpl this->components_.push_back(component); } - CircuitGraph getGraph() - { - return this->graph; - } - private: std::vector components_; - CircuitGraph graph; - }; // class PowerElectronicsModel } // namespace ModelLib From b57ec429fdf0aa3175bc637dbb8c287351e2a2f0 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Wed, 15 Nov 2023 20:47:04 -0500 Subject: [PATCH 23/44] Added COO Sparse Matrices, Component Jacobians, and Discrete Generator + Basic COO Sparse Matrix Implmentation + Discrete Generator Component + Resistor Jacobian + Capacitor Jacobian + Voltage Source Jacobian + Inductor Jacobian + Testing for Sparse Jacobian and Discrete Generator --- CMakeLists.txt | 3 + .../PowerElectronicsComponents/CMakeLists.txt | 3 +- .../Capacitor/Capacitor.cpp | 19 +- .../Capacitor/Capacitor.hpp | 1 + .../DiscreteGenerator/CMakeLists.txt | 8 + .../DiscreteGenerator/DiscreteGenerator.cpp | 278 ++++++++++ .../DiscreteGenerator/DiscreteGenerator.hpp | 100 ++++ .../Inductor/Inductor.cpp | 21 +- .../Inductor/Inductor.hpp | 1 + .../Resistor/Resistor.cpp | 11 +- .../Resistor/Resistor.hpp | 1 + .../VoltageSource/VoltageSource.cpp | 10 +- .../VoltageSource/VoltageSource.hpp | 1 + Examples/CMakeLists.txt | 2 + Examples/DiscreteGeneratorTest/CMakeLists.txt | 9 + Examples/DiscreteGeneratorTest/DGTest.cpp | 56 ++ Examples/RLCircuit/RLCircuit.cpp | 4 + Examples/SparseTest/CMakeLists.txt | 7 + Examples/SparseTest/SparseTest.cpp | 55 ++ ModelEvaluatorImpl.hpp | 20 +- PowerElectronicsModel.hpp | 6 + SparseMatrix/CMakeLists.txt | 7 + SparseMatrix/COO_Matrix.hpp | 515 ++++++++++++++++++ 23 files changed, 1122 insertions(+), 16 deletions(-) create mode 100644 ComponentLib/PowerElectronicsComponents/DiscreteGenerator/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp create mode 100644 Examples/DiscreteGeneratorTest/CMakeLists.txt create mode 100644 Examples/DiscreteGeneratorTest/DGTest.cpp create mode 100644 Examples/SparseTest/CMakeLists.txt create mode 100644 Examples/SparseTest/SparseTest.cpp create mode 100644 SparseMatrix/CMakeLists.txt create mode 100644 SparseMatrix/COO_Matrix.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 19048d375..ef6cbcf57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,6 +143,9 @@ add_subdirectory(ComponentLib) # General Utilities and File IO add_subdirectory(Utilities) +#Local Sparse matrix operations +add_subdirectory(SparseMatrix) + # Create solvers add_subdirectory(Solver) diff --git a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt index 10f2c6fdc..9d6ad8be1 100644 --- a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt +++ b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt @@ -6,4 +6,5 @@ add_subdirectory(VoltageSource) add_subdirectory(Inductor) add_subdirectory(LinearTransformer) add_subdirectory(InductionMotor) -add_subdirectory(SynchronousMachine) \ No newline at end of file +add_subdirectory(SynchronousMachine) +add_subdirectory(DiscreteGenerator) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp index d905dda05..ecbe9d51f 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -39,8 +39,7 @@ int Capacitor::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); - this->J_.resize(this->size_^2); - this->M_.resize(this->size_^2); + return 0; } @@ -72,13 +71,27 @@ int Capacitor::evaluateResidual() { this->f_[0] = this->yp_[2]; this->f_[1] = -this->yp_[2]; - this->f_[2] = this->y_[0] - this->y_[1] - this->y_[2] - this->C_ * this->yp_[2]; + this->f_[2] = -this->C_ * this->yp_[2] + this->y_[0] - this->y_[1] - this->y_[2]; return 0; } template int Capacitor::evaluateJacobian() { + //Create dF/dy + std::vector rcord{2,2,2}; + std::vector ccord{0,1,2}; + std::vector vals{1.0, -1.0, -1.0}; + this->J_.setValues(rcord, ccord, vals); + + //Create -dF/dy' + std::vector rcordder{0,1,2}; + std::vector ccordder{2,2,2}; + std::vector valsder{1.0, -1.0, -this->C_}; + COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); + + //Perform dF/dy + \alpha dF/dy' + this->J_.AXPY(this->alpha_, &Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp index 76cf94614..e1a9974c3 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp @@ -36,6 +36,7 @@ namespace ModelLib using CircuitComponent::ypB_; using CircuitComponent::fB_; using CircuitComponent::gB_; + using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/CMakeLists.txt new file mode 100644 index 000000000..c0ed2c7a9 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_disgen + SOURCES + DiscreteGenerator.cpp + OUTPUT_NAME + gridkit_powerelec_disgen) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp new file mode 100644 index 000000000..7770281d1 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp @@ -0,0 +1,278 @@ + + + +#include +#include +#include +#include "DiscreteGenerator.hpp" + +namespace ModelLib { + + +/*! + * @brief Constructor for a Discrete Generator + * @todo Maybe have parameters be templated in. Variables cannot be changed and are unlikely to. Allows for compile time optimizations + * + * Calls default ModelEvaluatorImpl constructor. + */ + +template +DiscreteGenerator::DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm) + : wb_(parm.wb), wc_(parm.wc), mp_(parm.mp), refmp_(parm.refmp), Vn_(parm.Vn), nq_(parm.nq), F_(parm.F), Kiv_(parm.Kiv), Kpv_(parm.Kpv), Kic_(parm.Kic), Kpc_(parm.Kpc), Cf_(parm.Cf), rLf_(parm.rLf), Lf_(parm.Lf), rLc_(parm.rLc), Lc_(parm.Lc) +{ + // internals [delta_i, Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi] + // externals [Pref, Pbus, QBus] + this->size_ = 16; + this->n_intern = 13; + this->n_extern = 3; + this->extern_indices = {0,1,2}; + this->idc_ = id; +} + +template +DiscreteGenerator::~DiscreteGenerator() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int DiscreteGenerator::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + + return 0; +} + +/** + * Initialization of the grid model + */ +template +int DiscreteGenerator::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int DiscreteGenerator::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Contributes to the bus residual. + * + * Must be connected to a PQ bus. + */ +template +int DiscreteGenerator::evaluateResidual() +{ + // ### Externals Componenets ### + //Reference P + ScalarT wcom = this->wb_ - this->refmp_ * this->y_[0]; + + this->f_[0] = 0; + this->f_[1] = 0; + this->f_[2] = 0; + + // ### Internal Componenets ## + f_[3] = -yp_[3] + wb_ - mp_ * y_[4] - wcom; + + f_[4] = -yp_[4] + wc_ * (y_[12] * y_[14] + y_[13] * y_[15] - y_[4]); + f_[5] = -yp_[4] + wc_ * (-y_[12] * y_[15] + y_[13] * y_[14] - y_[5]); + + ScalarT vod_star = Vn_ - nq_ * y_[5]; + ScalarT voq_star = 0; + + f_[6] = -yp_[6] + vod_star - y_[12]; + f_[7] = -yp_[7] + voq_star - y_[13]; + + ScalarT ild_star = F_ * y_[14] - wb_ * Cf_ * y_[13] + Kpv_ * (vod_star - y_[12]) + Kiv_ * y_[6] ; + ScalarT ilq_star = F_ * y_[15] + wb_ * Cf_ * y_[12] + Kpv_ * (voq_star - y_[13]) + Kiv_ * y_[7]; + + f_[8] = -yp_[8] + ild_star - y_[10]; + f_[9] = -yp_[9] + ilq_star - y_[11]; + + ScalarT vid_star = -wb_ * Lf_ * y_[11] + Kpc_ * (ild_star - y_[10]) + Kic_ * y_[8]; + ScalarT viq_star = wb_ * Lf_ * y_[10] + Kpc_ * (ilq_star - y_[11]) + Kic_ * y_[9]; + + f_[10] = -yp_[10] - (rLf_ / Lf_) * y_[10] + wcom * y_[11] + (1/Lf_) * (vid_star - y_[12]); + f_[11] = -yp_[11] - (rLf_ / Lf_) * y_[11] - wcom * y_[10] + (1/Lf_) * (viq_star - y_[13]); + + f_[12] = -yp_[12] + wcom * y_[13] + (1/Cf_) * (y_[10] - y_[14]); + f_[13] = -yp_[13] - wcom * y_[12] + (1/Cf_) * (y_[11] - y_[15]); + + f_[14] = -yp_[14] - (rLc_ / Lc_) * y_[14] + wcom * y_[15] + (1/Lc_)*(y_[12] - y_[1]); + f_[15] = -yp_[15] - (rLc_ / Lc_) * y_[15] - wcom * y_[14] + (1/Lc_)*(y_[13] - y_[2]); + return 0; +} + +/** + * @brief Compute the jacobian of the DiscreteGenerator for iteration. dF/dy - \alpha dF/dy' + * + * The matrix dF/dy should be + * [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[ mpref, 0, 0, 0, -mp, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[ 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, 0, wc*x15, wc*x16, wc*x13, wc*x14] +[ 0, 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, -wc*x16, wc*x15, wc*x14, -wc*x13] +[ 0, 0, 0, 0, 0, -nq, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0] +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0] +[ 0, 0, 0, 0, 0, -Kpv*nq, Kiv, 0, 0, 0, -1, 0, -Kpv, -Cf*wb, F, 0] +[ 0, 0, 0, 0, 0, 0, 0, Kiv, 0, 0, 0, -1, Cf*wb, -Kpv, 0, F] +[-mpref*x12, 0, 0, 0, 0, -(Kpc*Kpv*nq)/Lf, (Kiv*Kpc)/Lf, 0, Kic/Lf, 0, - Kpc/Lf - rLf/Lf, -mpref*x1, -(Kpc*Kpv + 1)/Lf, -(Cf*Kpc*wb)/Lf, (F*Kpc)/Lf, 0] +[ mpref*x11, 0, 0, 0, 0, 0, 0, (Kiv*Kpc)/Lf, 0, Kic/Lf, mpref*x1, - Kpc/Lf - rLf/Lf, (Cf*Kpc*wb)/Lf, -(Kpc*Kpv + 1)/Lf, 0, (F*Kpc)/Lf] +[-mpref*x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Cf, 0, 0, wb - mpref*x1, -1/Cf, 0] +[ mpref*x13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Cf, mpref*x1 - wb, 0, 0, -1/Cf] +[-mpref*x16, -1/Lc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Lc, 0, -rLc/Lc, wb - mpref*x1] +[ mpref*x15, 0, -1/Lc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Lc, mpref*x1 - wb, -rLc/Lc] + * 'Generated from MATLAB symbolic' + * Jacobian is mostly constant besides reference and rows 4 & 5 + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ +template +int DiscreteGenerator::evaluateJacobian() +{ + //Create dF/dy' + std::vector rcordder(13); + std::vector valsder(13,1.0); + for (int i = 0; i < 13; i++) + { + rcordder[i] = i + 3; + } + COO_Matrix Jacder = COO_Matrix(rcordder, rcordder, valsder,16,16); + + //Create dF/dy + //r = 3 + std::vector ctemp{0, 4}; + std::vector rtemp(ctemp.size(),3); + std::vector valtemp{this->refmp_, -this->mp_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 4 + ctemp = {4, 12, 13, 14, 15}; + std::fill(rtemp.begin(), rtemp.end(), 4); + valtemp = {-this->wc_, this->wc_*y_[14], this->wc_*y_[15], this->wc_*y_[12], this->wc_*y_[13]}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 5 + ctemp = {5, 12, 13, 14, 15}; + std::fill(rtemp.begin(), rtemp.end(), 5); + valtemp = {-this->wc_, -this->wc_*y_[15], this->wc_*y_[14], this->wc_*y_[13], -this->wc_*y_[12]}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 6 + ctemp = {5, 12}; + std::fill(rtemp.begin(), rtemp.end(), 6); + valtemp = {-this->nq_, -1.0}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 7 + ctemp = {13}; + std::fill(rtemp.begin(), rtemp.end(), 7); + valtemp = {-1.0}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 8 + ctemp = {5,6,10,12,13,14}; + std::fill(rtemp.begin(), rtemp.end(), 8); + valtemp = {-this->Kpv_*this->nq_, this->Kiv_, -1.0, -this->Kpv_, -this->Cf_*this->wb_, this->F_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 9 + ctemp = {7, 11, 12, 13, 15}; + std::fill(rtemp.begin(), rtemp.end(), 9); + valtemp = {this->Kiv_, -1.0, this->Cf_*this->wb_,-this->Kpv_,this->F_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 10 + ctemp = {0, 5, 6, 8, 10, 11, 12, 13, 14}; + std::fill(rtemp.begin(), rtemp.end(), 10); + valtemp = {-this->refmp_ * y_[11], -(this->Kpc_ * this->Kpv_ * this->nq_) / this->Lf_, (this->Kpc_ * this->Kiv_) / this->Lf_, this->Kic_ / this->Lf_, -(this->Kpc_ + this->rLf_) / this->Lf_, -this->refmp_ * y_[0], -(this->Kpc_ * this->Kpv_ + 1.0) / this->Lf_, -(this->Cf_ * this->Kpc_ * this->wb_) / this->Lf_, (this->F_ * this->Kpc_) / this->Lf_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 11 + ctemp = {0, 7, 9, 10, 11, 12, 13, 15}; + std::fill(rtemp.begin(), rtemp.end(), 11); + valtemp = {this->refmp_ * y_[10], (this->Kiv_ * this->Kpc_) / this->Lf_, this->Kic_ / this->Lf_, this->refmp_ * y_[0], -(this->Kpc_ + this->rLf_) / this->Lf_, (this->Cf_ * this->Kpc_ * this->wb_) / this->Lf_, -(this->Kpc_ * this->Kpv_ + 1.0) / this->Lf_, (this->F_ * this->Kpc_) / this->Lf_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 12 + ctemp = {0, 10, 13, 14}; + std::fill(rtemp.begin(), rtemp.end(), 12); + valtemp = {-this->refmp_ * y_[13], 1.0 / this->Cf_, this->wb_ - this->refmp_ * y_[0], -1.0 / this->Cf_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + + //r = 13 + ctemp = {0, 11, 12, 15}; + std::fill(rtemp.begin(), rtemp.end(), 13); + valtemp = {this->refmp_ * y_[12], 1.0 / this->Cf_, -this->wb_ + this->refmp_ * y_[0], -1.0 / this->Cf_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + + //r = 14 + ctemp = {0, 1, 12, 14, 15}; + std::fill(rtemp.begin(), rtemp.end(), 14); + valtemp = {-this->refmp_ * y_[15], -1.0 / this->Lc_, 1.0 / this->Lc_, -this->rLc_ / this->Lc_, this->wb_ - this->refmp_ * y_[0]}; + this->J_.setValues(rtemp, ctemp, valtemp); + + + //r = 15 + ctemp = {0, 2, 13, 14, 15}; + std::fill(rtemp.begin(), rtemp.end(), 15); + valtemp = {-this->refmp_ * y_[14], -1.0 / this->Lc_, 1.0 / this->Lc_, -this->wb_ + this->refmp_ * y_[0], -this->rLc_ / this->Lc_}; + this->J_.setValues(rtemp, ctemp, valtemp); + + + //Perform dF/dy + \alpha dF/dy' + + this->J_.AXPY(-this->alpha_, &Jacder); + + return 0; +} + +template +int DiscreteGenerator::evaluateIntegrand() +{ + return 0; +} + +template +int DiscreteGenerator::initializeAdjoint() +{ + return 0; +} + +template +int DiscreteGenerator::evaluateAdjointResidual() +{ + return 0; +} + +template +int DiscreteGenerator::evaluateAdjointIntegrand() +{ + return 0; +} + + + + +// Available template instantiations +template class DiscreteGenerator; +template class DiscreteGenerator; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp new file mode 100644 index 000000000..f5ce86899 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp @@ -0,0 +1,100 @@ + + +#ifndef _CAP_HPP_ +#define _CAP_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; + + template + struct DiscreteGeneratorParameters + { + ScalarT wb; + ScalarT wc; + ScalarT mp; + ScalarT refmp; + ScalarT Vn; + ScalarT nq; + ScalarT F; + ScalarT Kiv; + ScalarT Kpv; + ScalarT Kic; + ScalarT Kpc; + ScalarT Cf; + ScalarT rLf; + ScalarT Lf; + ScalarT rLc; + ScalarT Lc; + }; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive DiscreteGenerator class. + * + */ + template + class DiscreteGenerator : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::J_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + public: + DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm); + virtual ~DiscreteGenerator(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + private: + ScalarT wb_; + ScalarT wc_; + ScalarT mp_; + ScalarT refmp_; + ScalarT Vn_; + ScalarT nq_; + ScalarT F_; + ScalarT Kiv_; + ScalarT Kpv_; + ScalarT Kic_; + ScalarT Kpc_; + ScalarT Cf_; + ScalarT rLf_; + ScalarT Lf_; + ScalarT rLc_; + ScalarT Lc_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index 952a992d0..89f903436 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -40,8 +40,7 @@ int Inductor::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); - this->J_.resize(this->size_^2); - this->M_.resize(this->size_^2); + return 0; } @@ -73,13 +72,29 @@ int Inductor::evaluateResidual() { this->f_[0] = this->y_[2]; this->f_[1] = -this->y_[2]; - this->f_[2] = this->y_[0] - this->y_[1] - this->L_ * this->yp_[2]; + this->f_[2] = - this->L_ * this->yp_[2] + this->y_[0] - this->y_[1] ; return 0; } template int Inductor::evaluateJacobian() { + + //Create dF/dy + std::vector rcord{0,1,2,2}; + std::vector ccord{2,2,0,1}; + std::vector vals{1.0, -1.0, 1.0, -1.0}; + this->J_.setValues(rcord, ccord, vals); + + //Create -dF/dy' + std::vector rcordder{2}; + std::vector ccordder{2}; + std::vector valsder{-this->L_}; + COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); + + //Perform dF/dy + \alpha dF/dy' + this->J_.AXPY(this->alpha_, &Jacder); + return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp index e959aabf1..2f2c1085b 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp @@ -36,6 +36,7 @@ namespace ModelLib using CircuitComponent::ypB_; using CircuitComponent::fB_; using CircuitComponent::gB_; + using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp index 5faad23b4..7536f2274 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp @@ -39,8 +39,7 @@ int Resistor::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); - this->J_.resize(this->size_^2); - this->M_.resize(this->size_^2); + return 0; } @@ -79,6 +78,14 @@ int Resistor::evaluateResidual() template int Resistor::evaluateJacobian() { + + //Create dF/dy + //does compiler make constant??? + std::vector rcord{0,0,1,1}; + std::vector ccord{0,1,0,1}; + std::vector vals{-1.0 / this->R_, 1.0 / this->R_, 1.0 / this->R_, -1.0 / this->R_}; + this->J_.setValues(rcord, ccord, vals); + return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp index 0373e2c5c..984d8304b 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp @@ -36,6 +36,7 @@ namespace ModelLib using CircuitComponent::ypB_; using CircuitComponent::fB_; using CircuitComponent::gB_; + using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp index e26841a6c..b7c18bd6f 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -39,8 +39,7 @@ int VoltageSource::allocate() this->y_.resize(this->size_); this->yp_.resize(this->size_); this->f_.resize(this->size_); - this->J_.resize(this->size_^2); - this->M_.resize(this->size_^2); + return 0; } @@ -81,6 +80,13 @@ int VoltageSource::evaluateResidual() template int VoltageSource::evaluateJacobian() { + + //Create dF/dy + std::vector rcord{0,1,2,2}; + std::vector ccord{2,2,0,1}; + std::vector vals{1.0, -1.0, -1.0, 1.0}; + this->J_.setValues(rcord, ccord, vals); + return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp index dcbacf2f7..3ac1c8699 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp @@ -36,6 +36,7 @@ namespace ModelLib using CircuitComponent::ypB_; using CircuitComponent::fB_; using CircuitComponent::gB_; + using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index b42907fd3..e15774642 100644 --- a/Examples/CMakeLists.txt +++ b/Examples/CMakeLists.txt @@ -57,6 +57,8 @@ add_subdirectory(MatPowerTesting) add_subdirectory(RLCircuit) +add_subdirectory(SparseTest) +add_subdirectory(DiscreteGeneratorTest) if(TARGET SUNDIALS::kinsol) add_subdirectory(Grid3Bus) diff --git a/Examples/DiscreteGeneratorTest/CMakeLists.txt b/Examples/DiscreteGeneratorTest/CMakeLists.txt new file mode 100644 index 000000000..b1100b91a --- /dev/null +++ b/Examples/DiscreteGeneratorTest/CMakeLists.txt @@ -0,0 +1,9 @@ + + + + +add_executable(dgtest DGTest.cpp) +target_link_libraries(dgtest GRIDKIT::powerelec_disgen) + +add_test(NAME DiscreteGeneratorTest COMMAND $) +install(TARGETS dgtest RUNTIME DESTINATION bin) diff --git a/Examples/DiscreteGeneratorTest/DGTest.cpp b/Examples/DiscreteGeneratorTest/DGTest.cpp new file mode 100644 index 000000000..7d4aeda6f --- /dev/null +++ b/Examples/DiscreteGeneratorTest/DGTest.cpp @@ -0,0 +1,56 @@ + + +#include +#include +#include +#include +#include +#include + +#include + + +int main(int argc, char const *argv[]) +{ + + ModelLib::DiscreteGeneratorParameters parms; + //Parameters from MATLAB Microgrid code for first DG + //refmp is need for reference input + parms.wb = 2.0*M_PI*50.0; + parms.wc = 31.41; + parms.mp = 9.4e-5; + parms.refmp = 9.4e-5; + parms.Vn = 380; + parms.nq = 1.3e-3; + parms.F = 0.75; + parms.Kiv = 420.0; + parms.Kpv = 0.1; + parms.Kic = 20.0 * 1.0e3; + parms.Kpc = 15.0; + parms.Cf = 50.0e-6; + parms.rLf = 0.1; + parms.Lf = 1.35e-3; + parms.rLc = 0.03; + parms.Lc = 0.35e-3; + + ModelLib::DiscreteGenerator *dg = new ModelLib::DiscreteGenerator(0, parms); + + std::vector t1(16,0.0); + std::vector t2{0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,1.3,1.4,1.5}; + + dg->allocate(); + + dg->y() = t2; + dg->yp() = t1; + + dg->evaluateResidual(); + + std::cout << "Output: {"; + for (double i : dg->getResidual()) + { + std::cout << i << ", "; + } + std::cout << "}\n"; + + return 0; +} diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp index 6d44d6b4f..4669d564e 100644 --- a/Examples/RLCircuit/RLCircuit.cpp +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -80,6 +80,10 @@ int main(int argc, char const *argv[]) } std::cout << "}\n"; + induct->updateTime(0.0, 1.0); + induct->evaluateJacobian(); + induct->getJacobian().printMatrix(true); + return 0; } diff --git a/Examples/SparseTest/CMakeLists.txt b/Examples/SparseTest/CMakeLists.txt new file mode 100644 index 000000000..d0b6f5e05 --- /dev/null +++ b/Examples/SparseTest/CMakeLists.txt @@ -0,0 +1,7 @@ + + +add_executable(spmattest SparseTest.cpp) +target_link_libraries(spmattest GRIDKIT::SparseMatrix) + +add_test(NAME SparseMatrixTest COMMAND $) +install(TARGETS spmattest RUNTIME DESTINATION bin) diff --git a/Examples/SparseTest/SparseTest.cpp b/Examples/SparseTest/SparseTest.cpp new file mode 100644 index 000000000..976759533 --- /dev/null +++ b/Examples/SparseTest/SparseTest.cpp @@ -0,0 +1,55 @@ + + +#include +#include +#include +#include +#include +#include +#include + +#include + + + + +int main(int argc, char const *argv[]) +{ + std::vector val{0.1, 0.2, 0.3, 0.4}; + std::vector x{2,1,3,1}; + std::vector y{1,3,2,2}; + size_t n = 4; + size_t m = 4; + + COO_Matrix A = COO_Matrix(x,y,val,m,n); + + std::vector valn(4); + std::vector xn(4); + std::vector yn(4); + + std::tie(xn, yn, valn) = A.getEntries(); + + for (size_t i = 0; i < valn.size(); i++) + { + std::cout << valn[i] << "\n"; + } + + std::cout << "A:\n"; + A.printMatrix(true); + + std::vector val2{0.5, 0.6, 0.7, 0.8, 1.0}; + std::vector x2{0,2,0,2,1}; + std::vector y2{3,3,2,2,3}; + COO_Matrix B = COO_Matrix(x2,y2,val2,m,n); + + std::cout << "B:\n"; + B.printMatrix(true); + + A.AXPY(2.0, &B); + + std::cout << "A + 2B:\n"; + A.printMatrix(true); + + + return 0; +} diff --git a/ModelEvaluatorImpl.hpp b/ModelEvaluatorImpl.hpp index 72abb858b..ade61feff 100644 --- a/ModelEvaluatorImpl.hpp +++ b/ModelEvaluatorImpl.hpp @@ -62,6 +62,7 @@ #include #include +#include namespace ModelLib { @@ -90,16 +91,16 @@ namespace ModelLib yp_(size_), f_(size_), g_(size_quad_), - J_(size_quad^2), - M_(size_quad^2), yB_(size_), ypB_(size_), fB_(size_), gB_(size_opt_), + J_(COO_Matrix()), param_(size_opt_), param_up_(size_opt_), param_lo_(size_opt_) - {} + { + } virtual IdxT size() { @@ -224,6 +225,16 @@ namespace ModelLib return f_; } + COO_Matrix& getJacobian() + { + return J_; + } + + const COO_Matrix& getJacobian() const + { + return J_; + } + std::vector& getIntegrand() { return g_; @@ -279,8 +290,7 @@ namespace ModelLib std::vector fB_; std::vector gB_; - std::vector J_; - std::vector M_; + COO_Matrix J_; std::vector param_; std::vector param_up_; diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index 7a9304716..018ceaeaf 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -34,6 +34,7 @@ class PowerElectronicsModel : public ModelEvaluatorImpl // using ModelEvaluatorImpl::fB_; // using ModelEvaluatorImpl::g_; // using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::J_; using ModelEvaluatorImpl::rtol_; using ModelEvaluatorImpl::atol_; // using ModelEvaluatorImpl::param_; @@ -153,6 +154,11 @@ class PowerElectronicsModel : public ModelEvaluatorImpl return 0; } + /** + * @brief Creates the Sparse COO Jacobian representing \alpha dF/dy' + dF/dy + * + * @return int + */ int evaluateJacobian() { return 0; diff --git a/SparseMatrix/CMakeLists.txt b/SparseMatrix/CMakeLists.txt new file mode 100644 index 000000000..b51d669ec --- /dev/null +++ b/SparseMatrix/CMakeLists.txt @@ -0,0 +1,7 @@ + +add_library(SparseMatrix INTERFACE) +include_directories(SparseMatrix INTERFACE ${CMAKE_CURRENT_LIST_DIR}) + +add_library(GRIDKIT::SparseMatrix ALIAS SparseMatrix) + + diff --git a/SparseMatrix/COO_Matrix.hpp b/SparseMatrix/COO_Matrix.hpp new file mode 100644 index 000000000..e4b087386 --- /dev/null +++ b/SparseMatrix/COO_Matrix.hpp @@ -0,0 +1,515 @@ + + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @brief Quick class to provide sparse matrices of COO type. Simplifies data movement + * @todo Add base class of sparse matrix for conversion to CSR + * @todo Switch Push back with buffer allocation for resizing + * @todo NonZero Values for preallocation + * @todo Fix warnings, mostly type casting of indexes. Should try to move to iterator somehow + * + * m x n sparse matrix + */ +template +class COO_Matrix +{ +private: + std::vector values; + std::vector row_indexes; + std::vector column_indexes; + Intdx rows_size; + Intdx columns_size; + bool sorted; +public: + COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n); + COO_Matrix(Intdx m, Intdx n); + COO_Matrix(); + ~COO_Matrix(); + + //could replace with binary operation for both + // --- Functions which donot sort --- + void setValues(std::vector r, std::vector c, std::vector val); + void addValues(std::vector r, std::vector c, std::vector val); + + // --- Functions which call sort --- + std::tuple, std::vector> getRowCopy(Intdx r); + std::tuple, std::vector, std::vector> getEntries(); + + // BLAS. Will sort before running + void AXPY(ScalarT alpha, COO_Matrix* a); + + // --- Permutation Operations --- + //No sorting is actually done. Only done when nesscary + void permutation(std::vector row_perm, std::vector col_perm); + void permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n); + + //Resort values + void sortSparse(); + bool isSorted(); + + std::tuple getDimensions(); + + void printMatrix(bool sort); + +private: + std::vector indexEntries(std::vector r, std::vector c); + Intdx indexStartRow(Intdx r); +}; + +/** + * @brief Set values of sparse matrix. Increases size if outside bounds + * + * @todo should error return if outside bounds instead? + * + * @tparam ScalarT + * @tparam Intdx + * @param r + * @param c + * @param val + */ +template +inline void COO_Matrix::setValues(std::vector r, std::vector c, std::vector val) +{ + std::vector indexes = this->indexEntries(r,c); + + for (int i = 0; i < indexes.size(); i++) + { + if (indexes[i] == -1) + { + if (r[i] >= this->rows_size) + { + this->rows_size = r[i]; + } + if (c[i] >= this->columns_size) + { + this->columns_size = c[i]; + } + + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(val[i]); + this->sorted = false; + } + else + { + this->values[indexes[i]] = val[i]; + } + } + +} + +/** + * @brief Add new values to sparse matrix. Will increase size if outside bounds + * + * @todo should error return if outside bounds instead? + * + * @tparam ScalarT + * @tparam Intdx + * @param r + * @param c + * @param val + */ +template +inline void COO_Matrix::addValues(std::vector r, std::vector c, std::vector val) +{ + std::vector indexes = this->indexEntries(r,c); + + for (int i = 0; i < indexes.size(); i++) + { + if (indexes[i] == -1) + { + if (r[i] >= this->rows_size) + { + this->rows_size = r[i]; + } + if (c[i] >= this->columns_size) + { + this->columns_size = c[i]; + } + + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(val[i]); + this->sorted = false; + } + else + { + this->values[indexes[i]] += val[i]; + } + } + +} + +/** + * @brief Get copy of row values + * + * @tparam ScalarT + * @tparam Intdx + * @param r + * @return std::tuple, std::vector> + */ +template +inline std::tuple, std::vector> COO_Matrix::getRowCopy(Intdx r) +{ + if (!this->sorted) + { + this->sortSparse(); + } + Intdx rowindex = this->indexStartRow(r); + + + if (rowindex == -1) + { + return {std::vector(),std::vector()}; + } + + Intdx rsize = rowindex; + do + { + rsize++; + } while (rsize < this->values.size() && this->row_indexes[rsize] == r); + + return {{this->column_indexes.begin() + rowindex, this->column_indexes.begin() + rsize},{this->values.begin() + rowindex, this->values.begin() + rsize}}; +} + +/** + * @brief Get all Entries + * + * @tparam ScalarT + * @tparam Intdx + * @return std::tuple, std::vector, std::vector> + */ +template +inline std::tuple, std::vector, std::vector> COO_Matrix::getEntries() +{ + if (!this->sorted) + { + this->sortSparse(); + } + return {this->row_indexes, this->column_indexes, this->values}; +} + +template +inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrix *a) +{ + if (alpha == 0) return; + + if (!this->sorted) + { + this->sortSparse(); + } + if (!a->isSorted()) + { + a->sortSparse(); + } + std::vector val; + std::vector r; + std::vector c; + Intdx m = 0; + Intdx n = 0; + std::tie(r,c,val) = a->getEntries(); + std::tie(m,n) = a->getDimensions(); + + this->rows_size = this->rows_size > m ? this->rows_size : m; + this->columns_size = this->columns_size > n ? this->columns_size : n; + + Intdx aiter = 0; + //iterate for all current values in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + { + //pushback values when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + { + this->row_indexes.push_back(r[aiter]); + this->column_indexes.push_back(c[aiter]); + this->values.push_back(alpha * val[aiter]); + aiter++; + } + if (aiter >= r.size()) break; + + + if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + { + this->values[i] += alpha * val[aiter]; + aiter++; + } + } + //push back rest that was not found sorted + for (Intdx i = aiter; i < static_cast(r.size()); i++) + { + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(alpha * val[i]); + } + + this->sorted = false; +} + +/** + * @brief Permutate the matrix to a different one. Only changes the coordinates + * + * @tparam ScalarT + * @tparam Intdx + * @param row_perm + * @param col_perm + */ +template +inline void COO_Matrix::permutation(std::vector row_perm, std::vector col_perm) +{ + assert(row_perm.size() = this->rows_size); + assert(col_perm.size() = this->columns_size); + + for (int i = 0; i < this->values.size(); i++) + { + this->row_indexes[i] = row_perm[this->row_indexes[i]]; + this->column_indexes[i] = col_perm[this->column_indexes[i]]; + } + this->sorted = false; +} + +/** + * @brief Permutates the matrix and can change its size efficently + * if size is shrinking and value is to be removed the negative one + * + * @tparam ScalarT + * @tparam Intdx + * @param row_perm size of m + * @param col_perm size of n + * @param m + * @param n + */ +template +inline void COO_Matrix::permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n) +{ + assert(row_perm.size() == this->rows_size); + assert(col_perm.size() == this->columns_size); + + this->rows_size = m; + this->columns_size = n; + + for (int i = 0; i < this->values.size(); i++) + { + if (row_perm[this->row_indexes[i]] == -1 || col_perm[this->column_indexes[i]] == -1) + { + this->values[i] = 0; + } + else + { + this->row_indexes[i] = row_perm[this->row_indexes[i]]; + this->column_indexes[i] = col_perm[this->column_indexes[i]]; + } + } + this->sorted = false; +} + +/** + * @brief Restructure the sparse matrix for faster accesses and modifications + * + * @tparam ScalarT + * @tparam Intdx + */ +template +inline void COO_Matrix::sortSparse() +{ + //index based sort code + // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted-vector + + + //cannot call sort since two arrays are used instead + std::vector ordervec(this->row_indexes.size()); + std::size_t n(0); + std::generate(std::begin(ordervec), std::end(ordervec), [&]{ return n++; }); + + std::sort( std::begin(ordervec), + std::end(ordervec), + [&](int i1, int i2) { return this->row_indexes[i1] < this->row_indexes[i2] || + (this->row_indexes[i1] == this->row_indexes[i2] && this->column_indexes[i1] < this->column_indexes[i2]); } ); + + + //reorder based of index-sorting. Only swap no extra memory + // https://stackoverflow.com/a/22183350 + for (size_t i = 0; i < ordervec.size(); i++) + { + //permutation swap + while (ordervec[i] != ordervec[ordervec[i]]) + { + std::swap(this->row_indexes[ordervec[i]], this->row_indexes[ordervec[ordervec[i]]]); + std::swap(this->column_indexes[ordervec[i]], this->column_indexes[ordervec[ordervec[i]]]); + std::swap(this->values[ordervec[i]], this->values[ordervec[ordervec[i]]]); + + //swap orderings + std::swap(ordervec[i], ordervec[ordervec[i]]); + } + + } + this->sorted = true; +} + +template +inline bool COO_Matrix::isSorted() +{ + return this->sorted; +} + +template +inline std::tuple COO_Matrix::getDimensions() +{ + return std::tuple(this->rows_size, this->columns_size); +} + +template +inline void COO_Matrix::printMatrix(bool sort) +{ + if (sort == true && this->sorted == false) + { + this->sortSparse(); + } + + std::cout << "Sparse COO Matrix\n"; + std::cout << "(x , y, value)\n"; + for (size_t i = 0; i < this->values.size(); i++) + { + std::cout << "(" << this->row_indexes[i] + << ", " << this->column_indexes[i] + << ", " << this->values[i] << ")\n"; + } +} + +/** + * @brief Given vector indexes return the entries + * + * @tparam ScalarT + * @tparam Intdx + * @param r + * @param c + * @return std::vector + */ +template +inline std::vector COO_Matrix::indexEntries(std::vector r, std::vector c) +{ + assert(r.size() == c.size()); + std::vector valsnew(r.size(), -1); + + //cannot assume input is sorted so linear + Intdx aiter = 0; + //should fix this + for (Intdx i = 0; i < this->row_indexes.size(); i++) + { + while(r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i])) + { + valsnew.push_back(-1); + aiter++; + } + + if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + { + valsnew.push_back(i); + aiter++; + } + + } + return valsnew; + +} + +/** + * @brief Given row index get start. If no start returns -1 + * + * @tparam ScalarT + * @tparam Intdx + * @param r + * @return Intdx + */ +template +inline Intdx COO_Matrix::indexStartRow(Intdx r) +{ + if (this->sorted) + { + //basic binary search + Intdx i1 = 0; + Intdx i2 = this->row_indexes.size()-1; + Intdx m = 0; + while (i1 <= i2) + { + m = (i2 + i1) / 2; + //rows + if (this->row_indexes[m] < r) + { + i1 = m + 1; + } + else if (r < this->row_indexes[m]) + { + i2 = m - 1; + } + else + { + break; + } + } + //drop to first index + while (this->row_indexes[m] == r) + { + m--; + } + return m; + + } + else + { + for (int i = 0; i < this->row_indexes.size(); i++) + { + if (this->row_indexes[i] == r) + { + return i; + } + } + } + return -1; +} + +template +inline COO_Matrix::COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n) +{ + this->values = v; + this->row_indexes = r; + this->column_indexes = c; + this->rows_size = m; + this->columns_size = n; + this->sorted = false; +} + +template +inline COO_Matrix::COO_Matrix(Intdx m, Intdx n) +{ + this->rows_size = m; + this->columns_size = n; + this->values = std::vector(); + this->row_indexes = std::vector(); + this->column_indexes = std::vector(); + this->sorted = false; +} + +template +inline COO_Matrix::COO_Matrix() +{ + this->rows_size = 0; + this->columns_size = 0; + this->values = std::vector(); + this->row_indexes = std::vector(); + this->column_indexes = std::vector(); + this->sorted = false; +} + +template +COO_Matrix::~COO_Matrix() +{ + +} From de2307c4b2f22914a30a47ac8155ec253a9d5738 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Mon, 20 Nov 2023 17:21:22 -0500 Subject: [PATCH 24/44] Added Jacobian Assembly. Fixed and Added New Functionality to COO Matrices +Matrix Assembly +Refactored COO Matrix +COO can return CSR Data format --- .../Capacitor/Capacitor.cpp | 2 +- .../DiscreteGenerator/DiscreteGenerator.cpp | 2 +- .../Inductor/Inductor.cpp | 2 +- Examples/RLCircuit/RLCircuit.cpp | 9 +- Examples/SparseTest/SparseTest.cpp | 49 +- PowerElectronicsModel.hpp | 65 ++- SparseMatrix/COO_Matrix.hpp | 521 +++++++++++------- 7 files changed, 436 insertions(+), 214 deletions(-) diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp index ecbe9d51f..79faefe89 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -91,7 +91,7 @@ int Capacitor::evaluateJacobian() COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(this->alpha_, &Jacder); + this->J_.AXPY(this->alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp index 7770281d1..c66c5b0f9 100644 --- a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp +++ b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp @@ -237,7 +237,7 @@ int DiscreteGenerator::evaluateJacobian() //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(-this->alpha_, &Jacder); + this->J_.AXPY(-this->alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index 89f903436..b0b19e63b 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -93,7 +93,7 @@ int Inductor::evaluateJacobian() COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(this->alpha_, &Jacder); + this->J_.AXPY(this->alpha_, Jacder); return 0; } diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp index 4669d564e..124b50bc0 100644 --- a/Examples/RLCircuit/RLCircuit.cpp +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -80,9 +80,12 @@ int main(int argc, char const *argv[]) } std::cout << "}\n"; - induct->updateTime(0.0, 1.0); - induct->evaluateJacobian(); - induct->getJacobian().printMatrix(true); + + sysmodel->updateTime(0.0, 1.0); + sysmodel->evaluateJacobian(); + sysmodel->getJacobian().printMatrix(); + + return 0; diff --git a/Examples/SparseTest/SparseTest.cpp b/Examples/SparseTest/SparseTest.cpp index 976759533..81e5ac7dd 100644 --- a/Examples/SparseTest/SparseTest.cpp +++ b/Examples/SparseTest/SparseTest.cpp @@ -10,9 +10,6 @@ #include - - - int main(int argc, char const *argv[]) { std::vector val{0.1, 0.2, 0.3, 0.4}; @@ -35,7 +32,7 @@ int main(int argc, char const *argv[]) } std::cout << "A:\n"; - A.printMatrix(true); + A.printMatrix(); std::vector val2{0.5, 0.6, 0.7, 0.8, 1.0}; std::vector x2{0,2,0,2,1}; @@ -43,13 +40,47 @@ int main(int argc, char const *argv[]) COO_Matrix B = COO_Matrix(x2,y2,val2,m,n); std::cout << "B:\n"; - B.printMatrix(true); + B.printMatrix(); - A.AXPY(2.0, &B); + A.AXPY(2.0, B); std::cout << "A + 2B:\n"; - A.printMatrix(true); - + A.printMatrix(); + + std::vector r; + std::vector c; + std::vector v; + std::tie(r,c,v) = A.getDataToCSR(); + + for (size_t i = 0; i < r.size() - 1; i++) + { + std::cout << r[i] << std::endl; + size_t rdiff = r[i+1] - r[i]; + for (size_t j = 0; j < rdiff; j++) + { + std::cout << c[j + r[i]] << ", " << v[j + r[i]] << std::endl; + } + } + std::cout << r[r.size()-1] << std::endl; + + //Basic Verification test + std::vector rtest = {0, 2, 4, 7, 8}; + std::vector ctest = {2,3,2,3,1,2,3,2}; + std::vector valtest = {1.4, 1.0, 0.4, 2.2, 0.1, 1.6, 1.2, 0.3}; + + assert(rtest.size() == r.size()); + assert(ctest.size() == c.size()); + assert(valtest.size() == v.size()); + + int failval = 0; + for (size_t i = 0; i < rtest.size(); i++) if (r[i] != rtest[i]) failval--; + for (size_t i = 0; i < ctest.size(); i++) + { + double vdiff = v[i] - valtest[i]; + if (c[i] != ctest[i] || -1e-14 > vdiff || vdiff > 1e-14) failval--; + } - return 0; + std::cout << failval << std::endl; + + return failval; } diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index 018ceaeaf..bad48ecf0 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -23,8 +23,8 @@ class PowerElectronicsModel : public ModelEvaluatorImpl // using ModelEvaluatorImpl::size_quad_; // using ModelEvaluatorImpl::size_opt_; using ModelEvaluatorImpl::nnz_; - // using ModelEvaluatorImpl::time_; - // using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::time_; + using ModelEvaluatorImpl::alpha_; using ModelEvaluatorImpl::y_; using ModelEvaluatorImpl::yp_; // using ModelEvaluatorImpl::yB_; @@ -98,6 +98,11 @@ class PowerElectronicsModel : public ModelEvaluatorImpl return 0; } + /** + * @brief Set intial y and y' of each component + * + * @return int + */ int initialize() { @@ -106,7 +111,18 @@ class PowerElectronicsModel : public ModelEvaluatorImpl { component->initialize(); } + this->distributeVectors(); + + return 0; + } + /** + * @brief Distribute y and y' to each component based of node connection graph + * + * @return int + */ + int distributeVectors() + { for(const auto& component : components_) { for(IdxT j=0; jsize(); ++j) @@ -123,6 +139,11 @@ class PowerElectronicsModel : public ModelEvaluatorImpl return 0; } + /** + * @brief Evaluate Residuals at each component then collect them + * + * @return int + */ int evaluateResidual() { for (IdxT i = 0; i < this->f_.size(); i++) @@ -130,16 +151,7 @@ class PowerElectronicsModel : public ModelEvaluatorImpl f_[i] = 0; } - // Update variables - for(const auto& component : components_) - { - for(IdxT j=0; jsize(); ++j) - { - component->y()[j] = y_[component->getNodeConnection(j)]; - component->yp()[j] = yp_[component->getNodeConnection(j)]; - } - component->evaluateResidual(); - } + this->distributeVectors(); // Update system residual vector @@ -161,6 +173,25 @@ class PowerElectronicsModel : public ModelEvaluatorImpl */ int evaluateJacobian() { + this->J_.zeroMatrix(); + this->distributeVectors(); + + //Evaluate component jacs + for(const auto& component : components_) + { + component->evaluateJacobian(); + std::vector r; + std::vector c; + std::vector v; + std::tie(r, c, v) = component->getJacobian().getEntrieCopies(); + for (IdxT i = 0; i < static_cast(r.size()); i++) + { + r[i] = component->getNodeConnection(r[i]); + c[i] = component->getNodeConnection(c[i]); + } + this->J_.AXPY(1.0, r, c, v); + } + return 0; } @@ -205,8 +236,18 @@ class PowerElectronicsModel : public ModelEvaluatorImpl return 0; } + /** + * @brief Distribute time and time scaling for each component + * + * @param t + * @param a + */ void updateTime(ScalarT t, ScalarT a) { + for(const auto& component : components_) + { + component->updateTime(t, a); + } } void addComponent(component_type* component) diff --git a/SparseMatrix/COO_Matrix.hpp b/SparseMatrix/COO_Matrix.hpp index e4b087386..5b0ece80c 100644 --- a/SparseMatrix/COO_Matrix.hpp +++ b/SparseMatrix/COO_Matrix.hpp @@ -11,10 +11,8 @@ /** * @brief Quick class to provide sparse matrices of COO type. Simplifies data movement - * @todo Add base class of sparse matrix for conversion to CSR - * @todo Switch Push back with buffer allocation for resizing - * @todo NonZero Values for preallocation - * @todo Fix warnings, mostly type casting of indexes. Should try to move to iterator somehow + * + * @todo add functionality to keep track of multiple sorted list. Faster adding of new entries and will have a threshold to sort completely. * * m x n sparse matrix */ @@ -29,176 +27,203 @@ class COO_Matrix Intdx columns_size; bool sorted; public: + //Constructors COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n); COO_Matrix(Intdx m, Intdx n); COO_Matrix(); ~COO_Matrix(); - //could replace with binary operation for both - // --- Functions which donot sort --- - void setValues(std::vector r, std::vector c, std::vector val); - void addValues(std::vector r, std::vector c, std::vector val); + + //Operations // --- Functions which call sort --- std::tuple, std::vector> getRowCopy(Intdx r); - std::tuple, std::vector, std::vector> getEntries(); + std::tuple&, std::vector&, std::vector&> getEntries(); + std::tuple, std::vector, std::vector> getEntrieCopies(); + + std::tuple, std::vector, std::vector> getDataToCSR(); // BLAS. Will sort before running - void AXPY(ScalarT alpha, COO_Matrix* a); + void setValues(std::vector r, std::vector c, std::vector v); + void AXPY(ScalarT alpha, COO_Matrix& a); + void AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v); + void SCAL(ScalarT alpha); // --- Permutation Operations --- //No sorting is actually done. Only done when nesscary void permutation(std::vector row_perm, std::vector col_perm); void permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n); + void zeroMatrix(); + + void identityMatrix(Intdx n); + //Resort values void sortSparse(); bool isSorted(); std::tuple getDimensions(); - void printMatrix(bool sort); + void printMatrix(); private: - std::vector indexEntries(std::vector r, std::vector c); - Intdx indexStartRow(Intdx r); + Intdx indexStartRow(const std::vector &rows, Intdx r); + Intdx sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci); + void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values); + }; /** - * @brief Set values of sparse matrix. Increases size if outside bounds - * - * @todo should error return if outside bounds instead? + * @brief Get copy of row values * * @tparam ScalarT * @tparam Intdx * @param r - * @param c - * @param val + * @return std::tuple, std::vector> */ template -inline void COO_Matrix::setValues(std::vector r, std::vector c, std::vector val) +inline std::tuple, std::vector> COO_Matrix::getRowCopy(Intdx r) { - std::vector indexes = this->indexEntries(r,c); + if (!this->sorted) + { + this->sortSparse(); + } + Intdx rowindex = this->indexStartRow(r); + - for (int i = 0; i < indexes.size(); i++) + if (rowindex == -1) { - if (indexes[i] == -1) - { - if (r[i] >= this->rows_size) - { - this->rows_size = r[i]; - } - if (c[i] >= this->columns_size) - { - this->columns_size = c[i]; - } - - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(val[i]); - this->sorted = false; - } - else - { - this->values[indexes[i]] = val[i]; - } + return {std::vector(),std::vector()}; } + + Intdx rsize = rowindex; + do + { + rsize++; + } while (rsize < this->values.size() && this->row_indexes[rsize] == r); + return {{this->column_indexes.begin() + rowindex, this->column_indexes.begin() + rsize},{this->values.begin() + rowindex, this->values.begin() + rsize}}; } /** - * @brief Add new values to sparse matrix. Will increase size if outside bounds - * - * @todo should error return if outside bounds instead? + * @brief Get all Entries pointers. Will sort before returnings * * @tparam ScalarT * @tparam Intdx - * @param r - * @param c - * @param val + * @return std::tuple, std::vector, std::vector> */ template -inline void COO_Matrix::addValues(std::vector r, std::vector c, std::vector val) +inline std::tuple&, std::vector&, std::vector&> COO_Matrix::getEntries() { - std::vector indexes = this->indexEntries(r,c); - - for (int i = 0; i < indexes.size(); i++) + if (!this->sorted) { - if (indexes[i] == -1) - { - if (r[i] >= this->rows_size) - { - this->rows_size = r[i]; - } - if (c[i] >= this->columns_size) - { - this->columns_size = c[i]; - } - - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(val[i]); - this->sorted = false; - } - else - { - this->values[indexes[i]] += val[i]; - } + this->sortSparse(); } - + return {this->row_indexes, this->column_indexes, this->values}; } /** - * @brief Get copy of row values + * @brief Get copies of the data. Sorted before returning * * @tparam ScalarT * @tparam Intdx - * @param r - * @return std::tuple, std::vector> + * @return std::tuple, std::vector, std::vector> */ template -inline std::tuple, std::vector> COO_Matrix::getRowCopy(Intdx r) +inline std::tuple, std::vector, std::vector> COO_Matrix::getEntrieCopies() { if (!this->sorted) { this->sortSparse(); } - Intdx rowindex = this->indexStartRow(r); - + return {this->row_indexes, this->column_indexes, this->values}; +} - if (rowindex == -1) +/** + * @brief Returns the data into CSR Format + * + * @tparam ScalarT + * @tparam Intdx + * @return std::tuple, std::vector, std::vector> + */ +template +inline std::tuple, std::vector, std::vector> COO_Matrix::getDataToCSR() +{ + if (!this->isSorted()) this->sortSparse(); + std::vector rowsizevec(this->rows_size + 1, 0); + Intdx counter = 0; + for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) { - return {std::vector(),std::vector()}; + rowsizevec[i + 1] = rowsizevec[i]; + while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) + { + rowsizevec[i+1]++; + counter++; + } } - - Intdx rsize = rowindex; - do - { - rsize++; - } while (rsize < this->values.size() && this->row_indexes[rsize] == r); - - return {{this->column_indexes.begin() + rowindex, this->column_indexes.begin() + rsize},{this->values.begin() + rowindex, this->values.begin() + rsize}}; + return {rowsizevec, this->column_indexes, this->values}; } /** - * @brief Get all Entries + * @brief Given set of vector data it will set the values into the matrix * * @tparam ScalarT * @tparam Intdx - * @return std::tuple, std::vector, std::vector> + * @param r + * @param c + * @param v */ template -inline std::tuple, std::vector, std::vector> COO_Matrix::getEntries() +inline void COO_Matrix::setValues(std::vector r, std::vector c, std::vector v) { - if (!this->sorted) + //sort input + this->sortSparseCOO(r, c, v); + + + //Duplicated with AXPY. Could replace with function depdent on lambda expression + Intdx aiter = 0; + //iterate for all current values in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) { - this->sortSparse(); + //pushback values when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + { + this->row_indexes.push_back(r[aiter]); + this->column_indexes.push_back(c[aiter]); + this->values.push_back(v[aiter]); + aiter++; + } + if (aiter >= static_cast(r.size())) break; + + + if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + { + this->values[i] = v[aiter]; + aiter++; + } } - return {this->row_indexes, this->column_indexes, this->values}; + //push back rest that was not found sorted + for (Intdx i = aiter; i < static_cast(r.size()); i++) + { + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(v[i]); + } + + this->sorted = false; + } +/** + * @brief BLAS AXPY operation on another COO matrix. Will sort both matrices before acting + * + * @tparam ScalarT + * @tparam Intdx + * @param alpha + * @param a + */ template -inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrix *a) +inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrix& a) { if (alpha == 0) return; @@ -206,18 +231,17 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_MatrixsortSparse(); } - if (!a->isSorted()) + if (!a.isSorted()) { - a->sortSparse(); + a.sortSparse(); } - std::vector val; - std::vector r; - std::vector c; Intdx m = 0; Intdx n = 0; - std::tie(r,c,val) = a->getEntries(); - std::tie(m,n) = a->getDimensions(); + std::tuple&, std::vector&, std::vector&> tpm = a.getEntries(); + const auto& [r, c, val] = tpm; + std::tie(m,n) = a.getDimensions(); + //Increase size as nesscary this->rows_size = this->rows_size > m ? this->rows_size : m; this->columns_size = this->columns_size > n ? this->columns_size : n; @@ -233,7 +257,7 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrixvalues.push_back(alpha * val[aiter]); aiter++; } - if (aiter >= r.size()) break; + if (aiter >= static_cast(r.size())) break; if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) @@ -253,6 +277,74 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrixsorted = false; } +/** + * @brief AXPY on 3list. + * + * @tparam ScalarT + * @tparam Intdx + * @param alpha + * @param r + * @param c + * @param v + */ +template +inline void COO_Matrix::AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v) +{ + if (alpha == 0) return; + + if (!this->sorted) + { + this->sortSparse(); + } + + //sort input + this->sortSparseCOO(r, c, v); + + Intdx aiter = 0; + //iterate for all current values in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + { + //pushback values when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + { + this->row_indexes.push_back(r[aiter]); + this->column_indexes.push_back(c[aiter]); + this->values.push_back(alpha * v[aiter]); + aiter++; + } + if (aiter >= static_cast(r.size())) break; + + + if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + { + this->values[i] += alpha * v[aiter]; + aiter++; + } + } + //push back rest that was not found sorted + for (Intdx i = aiter; i < static_cast(r.size()); i++) + { + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(alpha * v[i]); + } + + this->sorted = false; +} + +/** + * @brief Scale all values + * + * @tparam ScalarT + * @tparam Intdx + * @param alpha + */ +template +inline void COO_Matrix::SCAL(ScalarT alpha) +{ + for (auto i = this->values.begin(); i < this->values.end(); i++) *i *= alpha; +} + /** * @brief Permutate the matrix to a different one. Only changes the coordinates * @@ -273,6 +365,7 @@ inline void COO_Matrix::permutation(std::vector row_perm, this->column_indexes[i] = col_perm[this->column_indexes[i]]; } this->sorted = false; + //cycle sorting maybe useful since permutations are already known } /** @@ -311,48 +404,48 @@ inline void COO_Matrix::permutationSizeMap(std::vector ro } /** - * @brief Restructure the sparse matrix for faster accesses and modifications + * @brief Turn matrix into the zero matrix. Does not actual delete memory * * @tparam ScalarT * @tparam Intdx */ template -inline void COO_Matrix::sortSparse() +inline void COO_Matrix::zeroMatrix() { - //index based sort code - // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted-vector - - - //cannot call sort since two arrays are used instead - std::vector ordervec(this->row_indexes.size()); - std::size_t n(0); - std::generate(std::begin(ordervec), std::end(ordervec), [&]{ return n++; }); - - std::sort( std::begin(ordervec), - std::end(ordervec), - [&](int i1, int i2) { return this->row_indexes[i1] < this->row_indexes[i2] || - (this->row_indexes[i1] == this->row_indexes[i2] && this->column_indexes[i1] < this->column_indexes[i2]); } ); - + //resize doesn't effect capacity if smaller + this->column_indexes.resize(0); + this->row_indexes.resize(0); + this->values.resize(0); + this->sorted = true; +} - //reorder based of index-sorting. Only swap no extra memory - // https://stackoverflow.com/a/22183350 - for (size_t i = 0; i < ordervec.size(); i++) +template +inline void COO_Matrix::identityMatrix(Intdx n) +{ + //Reset Matrix + this->zeroMatrix(); + for (Intdx i = 0; i < n; i++) { - //permutation swap - while (ordervec[i] != ordervec[ordervec[i]]) - { - std::swap(this->row_indexes[ordervec[i]], this->row_indexes[ordervec[ordervec[i]]]); - std::swap(this->column_indexes[ordervec[i]], this->column_indexes[ordervec[ordervec[i]]]); - std::swap(this->values[ordervec[i]], this->values[ordervec[ordervec[i]]]); - - //swap orderings - std::swap(ordervec[i], ordervec[ordervec[i]]); - } - + this->column_indexes[i] = i; + this->row_indexes[i] = i; + this->values[i] = 1.0; } this->sorted = true; } +/** + * @brief Restructure the sparse matrix for faster accesses and modifications + * + * @tparam ScalarT + * @tparam Intdx + */ +template +inline void COO_Matrix::sortSparse() +{ + this->sortSparseCOO(this->row_indexes, this->column_indexes, this->values); + this->sorted = true; +} + template inline bool COO_Matrix::isSorted() { @@ -365,10 +458,16 @@ inline std::tuple COO_Matrix::getDimensions() return std::tuple(this->rows_size, this->columns_size); } +/** + * @brief Print matrix that is sorted + * + * @tparam ScalarT + * @tparam Intdx + */ template -inline void COO_Matrix::printMatrix(bool sort) +inline void COO_Matrix::printMatrix() { - if (sort == true && this->sorted == false) + if (this->sorted == false) { this->sortSparse(); } @@ -384,95 +483,143 @@ inline void COO_Matrix::printMatrix(bool sort) } /** - * @brief Given vector indexes return the entries + * @brief Find the lowest row cordinate from set of provided cordinates * + * Assumes rows and columns are sorted * @tparam ScalarT * @tparam Intdx * @param r - * @param c - * @return std::vector + * @return Intdx */ template -inline std::vector COO_Matrix::indexEntries(std::vector r, std::vector c) +inline Intdx COO_Matrix::indexStartRow(const std::vector &rows, Intdx r) { - assert(r.size() == c.size()); - std::vector valsnew(r.size(), -1); - - //cannot assume input is sorted so linear - Intdx aiter = 0; - //should fix this - for (Intdx i = 0; i < this->row_indexes.size(); i++) + //Specialized Binary Search for Lowest Row + Intdx i1 = 0; + Intdx i2 = rows->size()-1; + Intdx m_smallest = -1; + Intdx m = -1; + while (i1 <= i2) { - while(r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i])) + m = (i2 + i1) / 2; + //rows + if (rows[m] < r) { - valsnew.push_back(-1); - aiter++; + i1 = m + 1; } - - if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + else if (r < rows[m]) { - valsnew.push_back(i); - aiter++; + i2 = m - 1; + } + else + { + if (i1 == i2) + { + return m_smallest; + } + + //Keep track of smallest cordinate + m_smallest = m; + i2 = m - 1; } - } - return valsnew; - + return m_smallest; } /** - * @brief Given row index get start. If no start returns -1 + * @brief Basic binary search * * @tparam ScalarT * @tparam Intdx - * @param r + * @param rows + * @param columns + * @param ri + * @param ci * @return Intdx */ template -inline Intdx COO_Matrix::indexStartRow(Intdx r) +inline Intdx COO_Matrix::sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci) { - if (this->sorted) + assert(rows.size() == columns.size()); + //basic binary search + Intdx i1 = 0; + Intdx i2 = rows.size()-1; + Intdx m = 0; + while (i1 <= i2) { - //basic binary search - Intdx i1 = 0; - Intdx i2 = this->row_indexes.size()-1; - Intdx m = 0; - while (i1 <= i2) + m = (i2 + i1) / 2; + //rows + if (rows[m] < ri) + { + i1 = m + 1; + } + else if (ri < rows[m]) + { + i2 = m - 1; + } + else { - m = (i2 + i1) / 2; - //rows - if (this->row_indexes[m] < r) + if (columns[m] < ci) { i1 = m + 1; } - else if (r < this->row_indexes[m]) + else if (ci < columns[m]) { i2 = m - 1; } - else - { - break; - } + break; } - //drop to first index - while (this->row_indexes[m] == r) - { - m--; - } - return m; - } - else + + return m; +} + +/** + * @brief Sort a disoreded set of values. Assume nothing on order. + * + * @todo simple setup. Should add better sorting since list are pre-sorted + * + * @tparam ScalarT + * @tparam Intdx + * @param rows + * @param columns + * @param values + */ +template +inline void COO_Matrix::sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values) +{ + + //index based sort code + // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted-vector + //cannot call sort since two arrays are used instead + std::vector ordervec(rows.size()); + std::size_t n(0); + std::generate(std::begin(ordervec), std::end(ordervec), [&]{ return n++; }); + + //Sort by row first then column. + std::sort( std::begin(ordervec), + std::end(ordervec), + [&](int i1, int i2) { return (rows[i1] < rows[i2]) || + (rows[i1] == rows[i2] && columns[i1] < columns[i2]); } ); + + + //reorder based of index-sorting. Only swap cost no extra memory. + // @todo see if extra memory creation is fine + // https://stackoverflow.com/a/22183350 + for (size_t i = 0; i < ordervec.size(); i++) { - for (int i = 0; i < this->row_indexes.size(); i++) + //permutation swap + while (ordervec[i] != ordervec[ordervec[i]]) { - if (this->row_indexes[i] == r) - { - return i; - } + std::swap(rows[ordervec[i]], rows[ordervec[ordervec[i]]]); + std::swap(columns[ordervec[i]], columns[ordervec[ordervec[i]]]); + std::swap(values[ordervec[i]], values[ordervec[ordervec[i]]]); + + //swap orderings + std::swap(ordervec[i], ordervec[ordervec[i]]); } + } - return -1; } template From 1dc614c18515ff80e0a4be594e92e354deef6636 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Sun, 10 Dec 2023 22:28:24 -0500 Subject: [PATCH 25/44] Jacobian Assembly, IDA + KLU Cmake, RL Circuit + Cmake configurations for Sundials and SuiteSparse + Jacobian Assembly for components + Working RL Circuit example utilizing assembly techniques --- CMake/FindSuiteSparse.cmake | 5 +- CMakeLists.txt | 4 +- .../CircuitComponent.hpp | 2 + .../Inductor/Inductor.cpp | 12 +- .../Resistor/Resistor.cpp | 9 +- .../VoltageSource/VoltageSource.cpp | 8 +- Examples/RLCircuit/CMakeLists.txt | 3 +- Examples/RLCircuit/RLCircuit.cpp | 113 +++++++++++++----- ModelEvaluator.hpp | 16 ++- ModelEvaluatorImpl.hpp | 6 +- PowerElectronicsModel.hpp | 95 ++++++++++++--- Solver/Dynamic/CMakeLists.txt | 5 + Solver/Dynamic/Ida.cpp | 90 +++++++++++--- Solver/Dynamic/Ida.hpp | 7 +- SparseMatrix/COO_Matrix.hpp | 74 +++++++++++- SystemModel.hpp | 11 ++ 16 files changed, 378 insertions(+), 82 deletions(-) diff --git a/CMake/FindSuiteSparse.cmake b/CMake/FindSuiteSparse.cmake index 2d73feb76..5a1026935 100644 --- a/CMake/FindSuiteSparse.cmake +++ b/CMake/FindSuiteSparse.cmake @@ -69,11 +69,11 @@ Author(s): set(SUITESPARSE_MODULES amd colamd - klu) + klu + suitesparseconfig) find_library(SUITESPARSE_LIBRARY NAMES - suitesparseconfig ${SUITESPARSE_MODULES} PATHS ${SUITESPARSE_DIR} $ENV{SUITESPARSE_DIR} ${SUITESPARSE_ROOT_DIR} @@ -97,6 +97,7 @@ find_path(SUITESPARSE_INCLUDE_DIR amd.h colamd.h klu.h + SuiteSparse_config.h PATHS ${SUITESPARSE_DIR} $ENV{SUITESPARSE_DIR} ${SUITESPARSE_ROOT_DIR} ${SUITESPARSE_LIBRARY_DIR}/.. PATH_SUFFIXES diff --git a/CMakeLists.txt b/CMakeLists.txt index ef6cbcf57..badea53a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,7 +81,7 @@ option(GRIDKIT_ENABLE_IPOPT "Enable Ipopt support" ON) option(GRIDKIT_ENABLE_SUNDIALS "Enable SUNDIALS support" ON) # Enable KLU -option(GRIDKIT_ENABLE_SUNDIALS_SPARSE "Enable SUNDIALS sparse linear solvers" OFF) +option(GRIDKIT_ENABLE_SUNDIALS_SPARSE "Enable SUNDIALS sparse linear solvers" ON) set(CMAKE_MACOSX_RPATH 1) @@ -110,7 +110,7 @@ endif("${isSystemDir}" STREQUAL "-1") # TODO: Probably beter to set a debug interface target -set(CMAKE_CXX_FLAGS_DEBUG "-Wall -O0 -g") +set(CMAKE_CXX_FLAGS_DEBUG "-Wall -O0 -g -DDEBUG") set(CMAKE_CXX_STANDARD 17) diff --git a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp index 9e1052e43..fe2efdf96 100644 --- a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp +++ b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp @@ -27,6 +27,8 @@ namespace ModelLib this->time_ = t; this->alpha_ = a; } + + bool hasJacobian() { return true;} size_t getExternSize() { diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index b0b19e63b..a24b7a8e9 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -70,26 +70,30 @@ int Inductor::tagDifferentiable() template int Inductor::evaluateResidual() { + //input this->f_[0] = this->y_[2]; + //output this->f_[1] = -this->y_[2]; - this->f_[2] = - this->L_ * this->yp_[2] + this->y_[0] - this->y_[1] ; + //internal + this->f_[2] = this->L_ * this->yp_[2] + this->y_[0] - this->y_[1] ; return 0; } template int Inductor::evaluateJacobian() { - + this->J_.zeroMatrix(); + //Create dF/dy std::vector rcord{0,1,2,2}; std::vector ccord{2,2,0,1}; std::vector vals{1.0, -1.0, 1.0, -1.0}; this->J_.setValues(rcord, ccord, vals); - //Create -dF/dy' + //Create dF/dy' std::vector rcordder{2}; std::vector ccordder{2}; - std::vector valsder{-this->L_}; + std::vector valsder{this->L_}; COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp index 7536f2274..45d9a34f3 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp @@ -69,9 +69,10 @@ int Resistor::tagDifferentiable() template int Resistor::evaluateResidual() { - - this->f_[0] = (this->y_[1] - this->y_[0])/this->R_ ; - this->f_[1] = (this->y_[0] - this->y_[1])/this->R_ ; + //input + this->f_[0] = (this->y_[0] - this->y_[1])/this->R_ ; + //ouput + this->f_[1] = (this->y_[1] - this->y_[0])/this->R_ ; return 0; } @@ -83,7 +84,7 @@ int Resistor::evaluateJacobian() //does compiler make constant??? std::vector rcord{0,0,1,1}; std::vector ccord{0,1,0,1}; - std::vector vals{-1.0 / this->R_, 1.0 / this->R_, 1.0 / this->R_, -1.0 / this->R_}; + std::vector vals{1.0 / this->R_, -1.0 / this->R_, -1.0 / this->R_, 1.0 / this->R_}; this->J_.setValues(rcord, ccord, vals); return 0; diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp index b7c18bd6f..c7cb09798 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -71,20 +71,22 @@ int VoltageSource::evaluateResidual() { //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors // for easier development + //input this->f_[0] = this->y_[2]; + //ouput this->f_[1] = -this->y_[2]; - this->f_[2] = this->y_[1] - this->y_[0] - this->V_; + //internal + this->f_[2] = -this->y_[1] + this->y_[0] + this->V_; return 0; } template int VoltageSource::evaluateJacobian() { - //Create dF/dy std::vector rcord{0,1,2,2}; std::vector ccord{2,2,0,1}; - std::vector vals{1.0, -1.0, -1.0, 1.0}; + std::vector vals{1.0, -1.0, 1.0, -1.0}; this->J_.setValues(rcord, ccord, vals); return 0; diff --git a/Examples/RLCircuit/CMakeLists.txt b/Examples/RLCircuit/CMakeLists.txt index 5069566bf..476eb5e95 100644 --- a/Examples/RLCircuit/CMakeLists.txt +++ b/Examples/RLCircuit/CMakeLists.txt @@ -6,7 +6,8 @@ add_executable(rlcircuit RLCircuit.cpp) target_link_libraries(rlcircuit GRIDKIT::powerelec_capacitor GRIDKIT::powerelec_inductor GRIDKIT::powerelec_resistor - GRIDKIT::powerelec_voltagesource) + GRIDKIT::powerelec_voltagesource + GRIDKIT::solvers_dyn) add_test(NAME RLCircuit COMMAND $) install(TARGETS rlcircuit RUNTIME DESTINATION bin) diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp index 124b50bc0..c71eef06d 100644 --- a/Examples/RLCircuit/RLCircuit.cpp +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -12,68 +12,89 @@ #include #include +#include +#include int main(int argc, char const *argv[]) { - + double abstol = 1e-8; + double reltol = 1e-8; + bool usejac = true; + //TODO:setup as named parameters //Create circuit model - ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(); + ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac); size_t idoff = 0; + //RL circuit parameters + double rinit = 1.0; + double linit = 1.0; + double vinit = 1.0; + + //inductor - ModelLib::Inductor* induct = new ModelLib::Inductor(idoff,0.1); + ModelLib::Inductor* induct = new ModelLib::Inductor(idoff,linit); //Form index to node uid realations - induct->setExternalConnectionNodes(0,2); - induct->setExternalConnectionNodes(2,1); - induct->setExternalConnectionNodes(1,0); + // input + induct->setExternalConnectionNodes(0,1); + //output + induct->setExternalConnectionNodes(1,-1); + //internal + induct->setExternalConnectionNodes(2,2); + //add component sysmodel->addComponent(induct); //resistor idoff++; - ModelLib::Resistor* resis = new ModelLib::Resistor(idoff, 1.0); + ModelLib::Resistor* resis = new ModelLib::Resistor(idoff, rinit); //Form index to node uid realations - resis->setExternalConnectionNodes(0,3); - resis->setExternalConnectionNodes(1,2); + //input + resis->setExternalConnectionNodes(0,0); + //output + resis->setExternalConnectionNodes(1,1); + //add sysmodel->addComponent(resis); //voltage source idoff++; - ModelLib::VoltageSource* vsource = new ModelLib::VoltageSource(idoff, 0.1); + ModelLib::VoltageSource* vsource = new ModelLib::VoltageSource(idoff, vinit); //Form index to node uid realations - vsource->setExternalConnectionNodes(0,0); - vsource->setExternalConnectionNodes(2,4); - vsource->setExternalConnectionNodes(1,3); + //input + vsource->setExternalConnectionNodes(0,-1); + //output + vsource->setExternalConnectionNodes(1,0); + //internal + vsource->setExternalConnectionNodes(2,3); + + sysmodel->addComponent(vsource); - - //Allocate with graph - sysmodel->allocate(5); + sysmodel->allocate(4); std::cout << sysmodel->y().size() << std::endl; + //Grounding for IDA. If no grounding then circuit is \mu > 1 + //v_0 (grounded) //Create Intial points - sysmodel->y()[0] = 1.0; - sysmodel->y()[1] = 1.0; - sysmodel->y()[2] = 1.0; - sysmodel->y()[3] = 1.0; - sysmodel->y()[4] = 1.0; - - sysmodel->yp()[0] = 1.0; - sysmodel->yp()[1] = 1.0; - sysmodel->yp()[2] = 1.0; - sysmodel->yp()[3] = 1.0; - sysmodel->yp()[4] = 1.0; + sysmodel->y()[0] = vinit; //v_1 + sysmodel->y()[1] = vinit; // v_2 + sysmodel->y()[2] = 0.0; // i_L + sysmodel->y()[3] = 0.0; // i_s + + sysmodel->yp()[0] = 0.0; // v'_1 + sysmodel->yp()[1] = 0.0; // v'_2 + sysmodel->yp()[2] = -vinit / linit; // i'_s + sysmodel->yp()[3] = -vinit / linit; // i'_L + sysmodel->initialize(); - sysmodel->evaluateResidual(); - std::cout << "Output: {"; + std::cout << "Verify Intial Resisdual is Zero: {"; for (double i : sysmodel->getResidual()) { std::cout << i << ", "; @@ -83,10 +104,44 @@ int main(int argc, char const *argv[]) sysmodel->updateTime(0.0, 1.0); sysmodel->evaluateJacobian(); + std::cout << "Intial Jacobian with alpha = 1:\n"; sysmodel->getJacobian().printMatrix(); + // Create numerical integrator and configure it for the generator model + AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); + + double t_init = 0.0; + double t_final = 1.0; + + // setup simulation + idas->configureSimulation(); + idas->getDefaultInitialCondition(); + idas->initializeSimulation(t_init); + idas->runSimulation(t_final); + + std::vector& yfinial = sysmodel->y(); + + std::cout << "Final Vector y\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << yfinial[i] << "\n"; + } + + std::vector yexact(4); + + //analytical solution to the circuit + yexact[0] = vinit; + yexact[2] = (-vinit / rinit) * (exp((rinit / linit) * t_final) - 1.0); + yexact[3] = yexact[2]; + yexact[1] = vinit - rinit * yexact[2]; + + std::cout << "Element-wise Relative error at t=" << t_final << "\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << abs((yfinial[i] - yexact[i]) / yexact[i]) << "\n"; + } return 0; } diff --git a/ModelEvaluator.hpp b/ModelEvaluator.hpp index 5eda481de..50c5e8b77 100644 --- a/ModelEvaluator.hpp +++ b/ModelEvaluator.hpp @@ -62,6 +62,7 @@ #include #include +#include namespace ModelLib { @@ -88,11 +89,20 @@ namespace ModelLib virtual int initializeAdjoint() = 0; virtual int evaluateAdjointResidual() = 0; - //virtual int evaluateAdjointJacobian() = 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 size_quad() = 0; virtual IdxT size_opt() = 0; virtual void updateTime(real_type t, real_type a) = 0; @@ -125,6 +135,10 @@ namespace ModelLib 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; diff --git a/ModelEvaluatorImpl.hpp b/ModelEvaluatorImpl.hpp index ade61feff..928d26f30 100644 --- a/ModelEvaluatorImpl.hpp +++ b/ModelEvaluatorImpl.hpp @@ -62,7 +62,6 @@ #include #include -#include namespace ModelLib { @@ -112,6 +111,11 @@ namespace ModelLib return nnz_; } + virtual bool hasJacobian() + { + return false; + } + virtual IdxT size_quad() { return size_quad_; diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index bad48ecf0..47efcc7f7 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -43,13 +43,27 @@ class PowerElectronicsModel : public ModelEvaluatorImpl public: /** - * @brief Constructor for the system model + * @brief Default constructor for the system model */ PowerElectronicsModel() : ModelEvaluatorImpl(0, 0, 0) { - // Set system model tolerances - rtol_ = 1e-5; - atol_ = 1e-5; + // Set system model tolerances as default + rtol_ = 1e-4; + atol_ = 1e-4; + // By default use jacobian + usejac_ = true; + } + + /** + * @brief Constructor for the system model + */ + PowerElectronicsModel(double rt, double at, bool ju) : ModelEvaluatorImpl(0, 0, 0) + { + // Set system model tolerances from input + rtol_ = rt; + atol_ = at; + // Can choose not to use jacobain + usejac_ = ju; } /** @@ -73,6 +87,28 @@ class PowerElectronicsModel : public ModelEvaluatorImpl return 1; } + /** + * @brief Will check if each component has jacobian avalible. If one doesn't then jacobain is false. + * + * + * @return true + * @return false + */ + bool hasJacobian() + { + if (!this->usejac_) return false; + + for(const auto& component : components_) + { + if (!component->hasJacobian()) + { + return false; + } + + } + return true; + } + /** * @brief Allocate the vector data with size amount * @todo Add capability to go through component model connection to get the size of the actual vector @@ -127,8 +163,16 @@ class PowerElectronicsModel : public ModelEvaluatorImpl { for(IdxT j=0; jsize(); ++j) { - component->y()[j] = y_[component->getNodeConnection(j)]; - component->yp()[j] = yp_[component->getNodeConnection(j)]; + if(component->getNodeConnection(j) != -1) + { + component->y()[j] = y_[component->getNodeConnection(j)]; + component->yp()[j] = yp_[component->getNodeConnection(j)]; + } + else + { + component->y()[j] = 0.0; + component->yp()[j] = 0.0; + } } } return 0; @@ -148,7 +192,7 @@ class PowerElectronicsModel : public ModelEvaluatorImpl { for (IdxT i = 0; i < this->f_.size(); i++) { - f_[i] = 0; + f_[i] = 0.0; } this->distributeVectors(); @@ -157,9 +201,16 @@ class PowerElectronicsModel : public ModelEvaluatorImpl for(const auto& component : components_) { + //TODO:check return type + component->evaluateResidual(); for(IdxT j=0; jsize(); ++j) { - f_[component->getNodeConnection(j)] += component->getResidual()[j]; + //@todo should do a different grounding check + if (component->getNodeConnection(j) != -1) + { + f_[component->getNodeConnection(j)] += component->getResidual()[j]; + } + } } @@ -180,16 +231,27 @@ class PowerElectronicsModel : public ModelEvaluatorImpl for(const auto& component : components_) { component->evaluateJacobian(); - std::vector r; - std::vector c; - std::vector v; - std::tie(r, c, v) = component->getJacobian().getEntrieCopies(); + + //get references to local jacobain + std::tuple&, std::vector&, std::vector&> tpm = component->getJacobian().getEntries(); + const auto& [r, c, v] = tpm; + + //Create copies of data to handle groundings + std::vector rgr; + std::vector cgr; + std::vector vgr; for (IdxT i = 0; i < static_cast(r.size()); i++) { - r[i] = component->getNodeConnection(r[i]); - c[i] = component->getNodeConnection(c[i]); + if (component->getNodeConnection(r[i]) != -1 && component->getNodeConnection(c[i]) != -1) + { + rgr.push_back(component->getNodeConnection(r[i])); + cgr.push_back(component->getNodeConnection(c[i])); + vgr.push_back(v[i]); + } } - this->J_.AXPY(1.0, r, c, v); + + //AXPY to Global Jacobian + this->J_.AXPY(1.0, rgr, cgr, vgr); } return 0; @@ -248,6 +310,8 @@ class PowerElectronicsModel : public ModelEvaluatorImpl { component->updateTime(t, a); } + this->time_ = t; + this->alpha_ = a; } void addComponent(component_type* component) @@ -257,6 +321,7 @@ class PowerElectronicsModel : public ModelEvaluatorImpl private: std::vector components_; + bool usejac_; }; // class PowerElectronicsModel diff --git a/Solver/Dynamic/CMakeLists.txt b/Solver/Dynamic/CMakeLists.txt index 759829967..85c7ea920 100644 --- a/Solver/Dynamic/CMakeLists.txt +++ b/Solver/Dynamic/CMakeLists.txt @@ -66,6 +66,11 @@ gridkit_add_library(solvers_dyn LINK_LIBRARIES PUBLIC SUNDIALS::nvecserial PUBLIC SUNDIALS::idas + PUBLIC SUNDIALS::sunlinsolklu + PUBLIC suitesparseconfig + PUBLIC klu + PUBLIC amd + PUBLIC colamd OUTPUT_NAME gridkit_solvers_dyn) diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index c71a8fd07..5137119f1 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -61,10 +61,13 @@ #include #include -// #include #include /* access to IDADls interface */ #include +//Sundials Sparse KLU +#include +#include + #include "ModelEvaluator.hpp" #include "Ida.hpp" @@ -103,6 +106,9 @@ namespace Sundials yp_ = N_VClone(yy_); checkAllocation((void*) yp_, "N_VClone"); + //get intial conditions + this->getDefaultInitialCondition(); + // Create vectors to store restart initial condition yy0_ = N_VClone(yy_); checkAllocation((void*) yy0_, "N_VClone"); @@ -144,14 +150,7 @@ namespace Sundials } // Set up linear solver - JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); - - linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); - checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); - - retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "IDASetLinearSolver"); + this->configureLinearSolver(); return retval; } @@ -160,16 +159,32 @@ namespace Sundials int Ida::configureLinearSolver() { int retval = 0; + if (model_->hasJacobian()) + { + JacobianMat_ = SUNSparseMatrix(model_->size(), model_->size(), model_->size() * model_->size(), CSR_MAT, context_); + checkAllocation((void*) JacobianMat_, "SUNSparseMatrix"); - // Set up linear solver - JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); + linearSolver_ = SUNLinSol_KLU(yy_, JacobianMat_, context_); + checkAllocation((void*) linearSolver_, "SUNLinSol_KLU"); - linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); - checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); + retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "IDASetLinearSolver"); - retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "IDASetLinearSolver"); + retval = IDASetJacFn(solver_, this->Jac); + checkOutput(retval, "IDASetJacFn"); + } + else + { + JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); + + linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); + checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); + + retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "IDASetLinearSolver"); + + } return retval; } @@ -525,8 +540,49 @@ namespace Sundials return 0; } + template + int Ida::Jac(realtype t, realtype cj, N_Vector yy, N_Vector yp, N_Vector resvec, SUNMatrix J, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) + { - template + ModelLib::ModelEvaluator* model = static_cast*>(user_data); + + + model->updateTime(t, cj); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); + + model->evaluateJacobian(); + COO_Matrix Jac = model->getJacobian(); + + //Get reference to the jacobian entries + std::tuple&, std::vector&, std::vector&> tpm = Jac.getEntries(); + const auto [r, c, val] = tpm; + + //get the CSR row pointers from COO matrix + std::vector csrrowdata = Jac.getCSRRowData(); + + SUNMatZero(J); + + //Set row pointers + sunindextype *rowptrs = SUNSparseMatrix_IndexPointers(J); + for (unsigned int i = 0; i < csrrowdata.size() ; i++) + { + rowptrs[i] = csrrowdata[i]; + } + + sunindextype *colvals = SUNSparseMatrix_IndexValues(J); + realtype *data = SUNSparseMatrix_Data(J); + //Copy data from model jac to sundials + for (unsigned int i = 0; i < c.size(); i++ ) + { + colvals[i] = c[i]; + data[i] = val[i]; + } + + return 0; + } + + template int Ida::Integrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector rhsQ, void *user_data) { ModelLib::ModelEvaluator* model = static_cast*>(user_data); diff --git a/Solver/Dynamic/Ida.hpp b/Solver/Dynamic/Ida.hpp index 3fa3368c9..a4cea9561 100644 --- a/Solver/Dynamic/Ida.hpp +++ b/Solver/Dynamic/Ida.hpp @@ -65,7 +65,7 @@ #include #include #include /* access to sparse SUNMatrix */ -// #include /* access to KLU linear solver */ +#include /* access to KLU linear solver */ #include /* access to dense linear solver */ #include "ModelEvaluator.hpp" @@ -165,6 +165,11 @@ namespace AnalysisManager static int Residual(realtype t, N_Vector yy, N_Vector yp, N_Vector rr, void *user_data); + + static int Jac(realtype t, realtype cj, + N_Vector yy, N_Vector yp, N_Vector resvec, + SUNMatrix J, void *user_data, + N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); static int Integrand(realtype t, N_Vector yy, N_Vector yp, diff --git a/SparseMatrix/COO_Matrix.hpp b/SparseMatrix/COO_Matrix.hpp index 5b0ece80c..c256e015c 100644 --- a/SparseMatrix/COO_Matrix.hpp +++ b/SparseMatrix/COO_Matrix.hpp @@ -40,8 +40,10 @@ class COO_Matrix std::tuple, std::vector> getRowCopy(Intdx r); std::tuple&, std::vector&, std::vector&> getEntries(); std::tuple, std::vector, std::vector> getEntrieCopies(); + std::tuple, std::vector, std::vector> getEntrieCopiesSubMatrix(std::vector submap); std::tuple, std::vector, std::vector> getDataToCSR(); + std::vector getCSRRowData(); // BLAS. Will sort before running void setValues(std::vector r, std::vector c, std::vector v); @@ -61,15 +63,19 @@ class COO_Matrix //Resort values void sortSparse(); bool isSorted(); + Intdx nnz(); std::tuple getDimensions(); void printMatrix(); + + static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values); + private: Intdx indexStartRow(const std::vector &rows, Intdx r); Intdx sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci); - void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values); + bool checkIncreaseSize(Intdx r, Intdx c); }; @@ -164,6 +170,35 @@ inline std::tuple, std::vector, std::vector> return {rowsizevec, this->column_indexes, this->values}; } +/** + * @brief Only creates the row data + * + * @todo swap this with having the matrix store the data and updates. This can then be passed by reference + * + * @todo fails, fix + * + * @tparam ScalarT + * @tparam Intdx + * @return std::vector + */ +template +inline std::vector COO_Matrix::getCSRRowData() +{ + if (!this->isSorted()) this->sortSparse(); + std::vector rowsizevec(this->rows_size + 1, 0); + Intdx counter = 0; + for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) + { + rowsizevec[i + 1] = rowsizevec[i]; + while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) + { + rowsizevec[i+1]++; + counter++; + } + } + return rowsizevec; +} + /** * @brief Given set of vector data it will set the values into the matrix * @@ -191,6 +226,7 @@ inline void COO_Matrix::setValues(std::vector r, std::vec this->row_indexes.push_back(r[aiter]); this->column_indexes.push_back(c[aiter]); this->values.push_back(v[aiter]); + this->checkIncreaseSize(r[aiter], c[aiter]); aiter++; } if (aiter >= static_cast(r.size())) break; @@ -208,6 +244,8 @@ inline void COO_Matrix::setValues(std::vector r, std::vec this->row_indexes.push_back(r[i]); this->column_indexes.push_back(c[i]); this->values.push_back(v[i]); + + this->checkIncreaseSize(r[i], c[i]); } this->sorted = false; @@ -256,6 +294,8 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrixcolumn_indexes.push_back(c[aiter]); this->values.push_back(alpha * val[aiter]); aiter++; + + this->checkIncreaseSize(r[aiter], c[aiter]); } if (aiter >= static_cast(r.size())) break; @@ -272,6 +312,8 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrixrow_indexes.push_back(r[i]); this->column_indexes.push_back(c[i]); this->values.push_back(alpha * val[i]); + + this->checkIncreaseSize(r[i], c[i]); } this->sorted = false; @@ -310,6 +352,8 @@ inline void COO_Matrix::AXPY(ScalarT alpha, std::vector r this->row_indexes.push_back(r[aiter]); this->column_indexes.push_back(c[aiter]); this->values.push_back(alpha * v[aiter]); + + this->checkIncreaseSize(r[aiter], c[aiter]); aiter++; } if (aiter >= static_cast(r.size())) break; @@ -327,6 +371,8 @@ inline void COO_Matrix::AXPY(ScalarT alpha, std::vector r this->row_indexes.push_back(r[i]); this->column_indexes.push_back(c[i]); this->values.push_back(alpha * v[i]); + + this->checkIncreaseSize(r[i], c[i]); } this->sorted = false; @@ -452,6 +498,12 @@ inline bool COO_Matrix::isSorted() return this->sorted; } +template +inline Intdx COO_Matrix::nnz() +{ + return static_cast(this->values.size); +} + template inline std::tuple COO_Matrix::getDimensions() { @@ -574,10 +626,28 @@ inline Intdx COO_Matrix::sparseCordBinarySearch(const std::vecto return m; } +template +inline bool COO_Matrix::checkIncreaseSize(Intdx r, Intdx c) +{ + bool changed = false; + if (r + 1 > this->rows_size) + { + this->rows_size = r + 1; + changed = true; + } + if (c + 1 > this->columns_size) + { + this->columns_size = c + 1; + changed = true; + } + + return changed; +} + /** * @brief Sort a disoreded set of values. Assume nothing on order. * - * @todo simple setup. Should add better sorting since list are pre-sorted + * @todo simple setup. Should add stable sorting since list are pre-sorted * * @tparam ScalarT * @tparam Intdx diff --git a/SystemModel.hpp b/SystemModel.hpp index 34c7ff120..77bbdd20b 100644 --- a/SystemModel.hpp +++ b/SystemModel.hpp @@ -183,6 +183,17 @@ class SystemModel : public ModelEvaluatorImpl return 0; } + /** + * @brief Assume that jacobian is not avalible + * + * @return true + * @return false + */ + bool hasJacobian() + { + return false; + } + /** * @brief Initialize buses first, then all the other components. * From e0051832bc582e764ac513cd302331597e2dbe4f Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Tue, 30 Jan 2024 16:19:33 -0500 Subject: [PATCH 26/44] Added the Transmission Line Component --- .../PowerElectronicsComponents/CMakeLists.txt | 3 +- .../TransmissionLine/CMakeLists.txt | 8 + .../TransmissionLine/TransmissionLine.cpp | 201 ++++++++++++++++++ .../TransmissionLine/TransmissionLine.hpp | 71 +++++++ Examples/RLCircuit/RLCircuit.cpp | 1 - 5 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 ComponentLib/PowerElectronicsComponents/TransmissionLine/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp diff --git a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt index 9d6ad8be1..8b96aaa66 100644 --- a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt +++ b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt @@ -7,4 +7,5 @@ add_subdirectory(Inductor) add_subdirectory(LinearTransformer) add_subdirectory(InductionMotor) add_subdirectory(SynchronousMachine) -add_subdirectory(DiscreteGenerator) \ No newline at end of file +add_subdirectory(DiscreteGenerator) +add_subdirectory(TransmissionLine) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/TransmissionLine/CMakeLists.txt new file mode 100644 index 000000000..6e2cea4f4 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_tranline + SOURCES + TransmissionLine.cpp + OUTPUT_NAME + gridkit_powerelec_tranline) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp new file mode 100644 index 000000000..62965c68e --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp @@ -0,0 +1,201 @@ + +#include +#include +#include +#include "TransmissionLine.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant TransmissionLine model + * + * Calls default ModelEvaluatorImpl constructor. + * + * This is the Medium distance form with the use of the admittance matrix. + * Since the line is of medium length then there is no real part for shunt admittance + */ + +template +TransmissionLine::TransmissionLine(IdxT id, ScalarT R,ScalarT X, ScalarT B) + : R_(R), X_(X), B_(B) +{ + // internals [Iret1, Iimt1, Iret2, Iimt2] + // externals [Vre11, Vim11, Vre12, Vim12, Vre21, Vim21, Vre22, Vim22] + this->size_ = 12; + this->n_intern = 4; + this->n_extern = 8; + this->extern_indices = {0,1,2,3,4,5,6,7}; + this->idc_ = id; + + ScalarT magImpendence = 1 / (R_*R_ + X_*X_); + YReMat_ = magImpendence * R_; + YImMatOff_ = magImpendence * X_; + YImMatDi_ = B_ / (2.0) - YImMatOff_; +} + +template +TransmissionLine::~TransmissionLine() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int TransmissionLine::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + + return 0; +} + +/** + * Initialization of the grid model + */ +template +int TransmissionLine::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int TransmissionLine::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Evaluate residual of transmission line + * + * The complex admittance matrix is: + * [[ Y/2 + 1/Z, -1/Z]; + * [ -1/Z, Y/2 + 1/Z]] = + * [[R/|Z|, -R/|Z|]; + * [-R/|Z|, R/|Z|]] + + * i [[B/2 - X/|Z|, X/|Z|]; + * [X/|Z|, B/2 - X/|Z|]] + * = Dre + i Dim + * + * Then + * Ire = Dre Vre - Dim Vim + * Iim = Dre Vim + Dim Vre + * + * To express this for Modified Nodal Analysis the Voltages of the admittance matrix are put into voltage drops + */ +template +int TransmissionLine::evaluateResidual() +{ + //input + this->f_[0] = y_[8] ; + this->f_[1] = y_[9] ; + + this->f_[2] = y_[10] ; + this->f_[3] = y_[11] ; + //ouput + this->f_[4] = -y_[8] ; + this->f_[5] = -y_[9] ; + + this->f_[6] = -y_[10] ; + this->f_[7] = -y_[11] ; + + //Voltage drop accross terminals + ScalarT V1re = y_[0] - y_[4]; + ScalarT V1im = y_[1] - y_[5]; + ScalarT V2re = y_[2] - y_[6]; + ScalarT V2im = y_[3] - y_[7]; + + //Internal variables + //row 1 + this->f_[8] = YReMat_ * (V1re - V2re) - (YImMatDi_ * V1im + YImMatOff_ * V2im) - y_[8] ; + this->f_[9] = YReMat_ * (V1im - V2im) + (YImMatDi_ * V1re + YImMatOff_ * V2re) - y_[9] ; + + //row2 + this->f_[10] = YReMat_ * (V2re - V1re) - (YImMatOff_ * V1im + YImMatDi_ * V2im) - y_[10]; + this->f_[11] = YReMat_ * (V2im - V1im) + (YImMatOff_ * V1re + YImMatDi_ * V2re) - y_[11]; + + + return 0; +} + +/** + * @brief Generate Jacobian for Transmission Line + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ +template +int TransmissionLine::evaluateJacobian() +{ + + //Create dF/dy + std::vector rtemp{0,1,2,3,4,5,6,7,8,9,10,11}; + std::vector ctemp{8,9,10,11,8,9,10,11,8,9,10,11}; + std::vector vals{1.0,1.0,1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0}; + this->J_.setValues(rtemp, ctemp, vals); + + + std::vector ccord{0,1,2,3,4,5,6,7}; + + std::vector rcord(ccord.size(),8); + vals = {YReMat_, -YImMatDi_ ,-YReMat_, -YImMatOff_,-YReMat_, YImMatDi_ ,YReMat_, YImMatOff_}; + this->J_.setValues(rtemp, ctemp, vals); + + + std::fill(rcord.begin(), rcord.end(), 9); + vals = {YImMatDi_ ,YReMat_, YImMatOff_, -YReMat_,-YImMatDi_ ,-YReMat_, -YImMatOff_, YReMat_}; + this->J_.setValues(rtemp, ctemp, vals); + + + std::fill(rcord.begin(), rcord.end(), 10); + vals = {-YReMat_, -YImMatDi_ ,YReMat_, -YImMatOff_,YReMat_, YImMatDi_ ,-YReMat_, YImMatOff_}; + this->J_.setValues(rtemp, ctemp, vals); + + + std::fill(rcord.begin(), rcord.end(), 11); + vals = {YImMatDi_ ,-YReMat_, YImMatOff_, YReMat_,-YImMatDi_ ,YReMat_, -YImMatOff_, -YReMat_}; + this->J_.setValues(rtemp, ctemp, vals); + + return 0; +} + +template +int TransmissionLine::evaluateIntegrand() +{ + return 0; +} + +template +int TransmissionLine::initializeAdjoint() +{ + return 0; +} + +template +int TransmissionLine::evaluateAdjointResidual() +{ + return 0; +} + +template +int TransmissionLine::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class TransmissionLine; +template class TransmissionLine; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp new file mode 100644 index 000000000..0f729d449 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp @@ -0,0 +1,71 @@ + + +#ifndef _TRANLINE_HPP_ +#define _TRANLINE_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive TransmissionLine class. + * + */ + template + class TransmissionLine : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::J_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + public: + TransmissionLine(IdxT id, ScalarT R, ScalarT X, ScalarT B); + virtual ~TransmissionLine(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + + private: + ScalarT R_; + ScalarT X_; + ScalarT B_; + ScalarT YReMat_; + ScalarT YImMatDi_; + ScalarT YImMatOff_; + }; +} + +#endif diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp index c71eef06d..e902b1242 100644 --- a/Examples/RLCircuit/RLCircuit.cpp +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -89,7 +89,6 @@ int main(int argc, char const *argv[]) sysmodel->yp()[2] = -vinit / linit; // i'_s sysmodel->yp()[3] = -vinit / linit; // i'_L - sysmodel->initialize(); sysmodel->evaluateResidual(); From eb6fde47cf0bb7df36e4df6e213cd2e6c557d373 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Mon, 19 Feb 2024 13:31:19 -0500 Subject: [PATCH 27/44] Added Microgrid Example - Added MicrogridBusDQ - Added MicrogridLine - Added MicrogridLoad - Updated DiscreteGenerator - Added Output Testing for DG - Added Microgrid Assmebly Example - Updated Capacitor, Inductor, and Voltage residuals - Updated RLCircuit Example --- .../PowerElectronicsComponents/CMakeLists.txt | 5 +- .../Capacitor/Capacitor.cpp | 13 +- .../DiscreteGenerator/DiscreteGenerator.cpp | 211 ++++++---- .../DiscreteGenerator/DiscreteGenerator.hpp | 5 +- .../Inductor/Inductor.cpp | 10 +- .../MicrogridBusDQ/CMakeLists.txt | 8 + .../MicrogridBusDQ/MicrogridBusDQ.cpp | 132 +++++++ .../MicrogridBusDQ/MicrogridBusDQ.hpp | 66 ++++ .../MicrogridLine/CMakeLists.txt | 8 + .../MicrogridLine/MicrogridLine.cpp | 172 +++++++++ .../MicrogridLine/MicrogridLine.hpp | 67 ++++ .../MicrogridLoad/CMakeLists.txt | 8 + .../MicrogridLoad/MicrogridLoad.cpp | 169 ++++++++ .../MicrogridLoad/MicrogridLoad.hpp | 67 ++++ .../VoltageSource/VoltageSource.cpp | 8 +- Examples/CMakeLists.txt | 1 + Examples/DiscreteGeneratorTest/CMakeLists.txt | 5 +- Examples/DiscreteGeneratorTest/DGTest.cpp | 30 +- Examples/Microgrid/CMakeLists.txt | 13 + Examples/Microgrid/Microgrid.cpp | 361 ++++++++++++++++++ Examples/RLCircuit/RLCircuit.cpp | 8 +- SparseMatrix/COO_Matrix.hpp | 9 + 22 files changed, 1279 insertions(+), 97 deletions(-) create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridLine/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridLoad/CMakeLists.txt create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp create mode 100644 ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.hpp create mode 100644 Examples/Microgrid/CMakeLists.txt create mode 100644 Examples/Microgrid/Microgrid.cpp diff --git a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt index 8b96aaa66..3fba4be7f 100644 --- a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt +++ b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt @@ -8,4 +8,7 @@ add_subdirectory(LinearTransformer) add_subdirectory(InductionMotor) add_subdirectory(SynchronousMachine) add_subdirectory(DiscreteGenerator) -add_subdirectory(TransmissionLine) \ No newline at end of file +add_subdirectory(TransmissionLine) +add_subdirectory(MicrogridLoad) +add_subdirectory(MicrogridLine) +add_subdirectory(MicrogridBusDQ) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp index 79faefe89..b6287b359 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -69,15 +69,20 @@ int Capacitor::tagDifferentiable() template int Capacitor::evaluateResidual() { - this->f_[0] = this->yp_[2]; - this->f_[1] = -this->yp_[2]; - this->f_[2] = -this->C_ * this->yp_[2] + this->y_[0] - this->y_[1] - this->y_[2]; + //input + this->f_[0] = C_ * this->yp_[2]; + //output + this->f_[1] = -C_ * this->yp_[2]; + + //internal + this->f_[2] = -C_ * this->yp_[2] + this->y_[0] - this->y_[1] - this->y_[2]; return 0; } template int Capacitor::evaluateJacobian() { + this->J_.zeroMatrix(); //Create dF/dy std::vector rcord{2,2,2}; std::vector ccord{0,1,2}; @@ -87,7 +92,7 @@ int Capacitor::evaluateJacobian() //Create -dF/dy' std::vector rcordder{0,1,2}; std::vector ccordder{2,2,2}; - std::vector valsder{1.0, -1.0, -this->C_}; + std::vector valsder{C_, -C_, -this->C_}; COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp index c66c5b0f9..607ec5312 100644 --- a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp +++ b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp @@ -17,11 +17,11 @@ namespace ModelLib { */ template -DiscreteGenerator::DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm) - : wb_(parm.wb), wc_(parm.wc), mp_(parm.mp), refmp_(parm.refmp), Vn_(parm.Vn), nq_(parm.nq), F_(parm.F), Kiv_(parm.Kiv), Kpv_(parm.Kpv), Kic_(parm.Kic), Kpc_(parm.Kpc), Cf_(parm.Cf), rLf_(parm.rLf), Lf_(parm.Lf), rLc_(parm.rLc), Lc_(parm.Lc) +DiscreteGenerator::DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm, bool reference_frame) + : wb_(parm.wb), wc_(parm.wc), mp_(parm.mp), Vn_(parm.Vn), nq_(parm.nq), F_(parm.F), Kiv_(parm.Kiv), Kpv_(parm.Kpv), Kic_(parm.Kic), Kpc_(parm.Kpc), Cf_(parm.Cf), rLf_(parm.rLf), Lf_(parm.Lf), rLc_(parm.rLc), Lc_(parm.Lc), refframe_(reference_frame) { - // internals [delta_i, Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi] - // externals [Pref, Pbus, QBus] + // internals [\delta_i, Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi] + // externals [\omega_ref, vba_out, vbb_out] this->size_ = 16; this->n_intern = 13; this->n_extern = 3; @@ -74,42 +74,64 @@ template int DiscreteGenerator::evaluateResidual() { // ### Externals Componenets ### - //Reference P - ScalarT wcom = this->wb_ - this->refmp_ * this->y_[0]; - this->f_[0] = 0; - this->f_[1] = 0; - this->f_[2] = 0; + ScalarT omega = wb_ - mp_ * y_[4]; + //ref common ref motor angle + if (refframe_) + { + f_[0] = omega - y_[0]; + } + else + { + f_[0] = 0.0; + } + + + //output + //current transformed to common frame + f_[1] = cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15]; + f_[2] = sin(y_[3]) * y_[14] + cos(y_[3]) * y_[15]; - // ### Internal Componenets ## - f_[3] = -yp_[3] + wb_ - mp_ * y_[4] - wcom; + //Take incoming voltages to current rotator reference frame + ScalarT vbd_in = cos(y_[3]) * y_[1] + sin(y_[3]) * y_[2]; + ScalarT vbq_in = -sin(y_[3]) * y_[1] + cos(y_[3]) * y_[2]; + // ### Internal Componenets ## + // Rotator difference angle + f_[3] = -yp_[3] + omega - y_[0]; + + // P and Q equations f_[4] = -yp_[4] + wc_ * (y_[12] * y_[14] + y_[13] * y_[15] - y_[4]); - f_[5] = -yp_[4] + wc_ * (-y_[12] * y_[15] + y_[13] * y_[14] - y_[5]); + f_[5] = -yp_[5] + wc_ * (-y_[12] * y_[15] + y_[13] * y_[14] - y_[5]); + //Voltage control ScalarT vod_star = Vn_ - nq_ * y_[5]; - ScalarT voq_star = 0; + ScalarT voq_star = 0.0; f_[6] = -yp_[6] + vod_star - y_[12]; f_[7] = -yp_[7] + voq_star - y_[13]; - ScalarT ild_star = F_ * y_[14] - wb_ * Cf_ * y_[13] + Kpv_ * (vod_star - y_[12]) + Kiv_ * y_[6] ; + + ScalarT ild_star = F_ * y_[14] - wb_ * Cf_ * y_[13] + Kpv_ * (vod_star - y_[12]) + Kiv_ * y_[6]; ScalarT ilq_star = F_ * y_[15] + wb_ * Cf_ * y_[12] + Kpv_ * (voq_star - y_[13]) + Kiv_ * y_[7]; + //Current control f_[8] = -yp_[8] + ild_star - y_[10]; f_[9] = -yp_[9] + ilq_star - y_[11]; ScalarT vid_star = -wb_ * Lf_ * y_[11] + Kpc_ * (ild_star - y_[10]) + Kic_ * y_[8]; ScalarT viq_star = wb_ * Lf_ * y_[10] + Kpc_ * (ilq_star - y_[11]) + Kic_ * y_[9]; - f_[10] = -yp_[10] - (rLf_ / Lf_) * y_[10] + wcom * y_[11] + (1/Lf_) * (vid_star - y_[12]); - f_[11] = -yp_[11] - (rLf_ / Lf_) * y_[11] - wcom * y_[10] + (1/Lf_) * (viq_star - y_[13]); + //Output LC Filter + f_[10] = -yp_[10] - (rLf_ / Lf_) * y_[10] + omega * y_[11] + (vid_star - y_[12]) / Lf_; + f_[11] = -yp_[11] - (rLf_ / Lf_) * y_[11] - omega * y_[10] + (viq_star - y_[13]) / Lf_; - f_[12] = -yp_[12] + wcom * y_[13] + (1/Cf_) * (y_[10] - y_[14]); - f_[13] = -yp_[13] - wcom * y_[12] + (1/Cf_) * (y_[11] - y_[15]); + f_[12] = -yp_[12] + omega * y_[13] + (y_[10] - y_[14]) / Cf_; + f_[13] = -yp_[13] - omega * y_[12] + (y_[11] - y_[15]) / Cf_; - f_[14] = -yp_[14] - (rLc_ / Lc_) * y_[14] + wcom * y_[15] + (1/Lc_)*(y_[12] - y_[1]); - f_[15] = -yp_[15] - (rLc_ / Lc_) * y_[15] - wcom * y_[14] + (1/Lc_)*(y_[13] - y_[2]); + //Output Connector + f_[14] = -yp_[14] - (rLc_ / Lc_) * y_[14] + omega * y_[15] + (y_[12] - vbd_in) / Lc_; + f_[15] = -yp_[15] - (rLc_ / Lc_) * y_[15] - omega * y_[14] + (y_[13] - vbq_in) / Lc_; return 0; } @@ -117,24 +139,24 @@ int DiscreteGenerator::evaluateResidual() * @brief Compute the jacobian of the DiscreteGenerator for iteration. dF/dy - \alpha dF/dy' * * The matrix dF/dy should be - * [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -[ mpref, 0, 0, 0, -mp, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -[ 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, 0, wc*x15, wc*x16, wc*x13, wc*x14] -[ 0, 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, -wc*x16, wc*x15, wc*x14, -wc*x13] -[ 0, 0, 0, 0, 0, -nq, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0] -[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0] -[ 0, 0, 0, 0, 0, -Kpv*nq, Kiv, 0, 0, 0, -1, 0, -Kpv, -Cf*wb, F, 0] -[ 0, 0, 0, 0, 0, 0, 0, Kiv, 0, 0, 0, -1, Cf*wb, -Kpv, 0, F] -[-mpref*x12, 0, 0, 0, 0, -(Kpc*Kpv*nq)/Lf, (Kiv*Kpc)/Lf, 0, Kic/Lf, 0, - Kpc/Lf - rLf/Lf, -mpref*x1, -(Kpc*Kpv + 1)/Lf, -(Cf*Kpc*wb)/Lf, (F*Kpc)/Lf, 0] -[ mpref*x11, 0, 0, 0, 0, 0, 0, (Kiv*Kpc)/Lf, 0, Kic/Lf, mpref*x1, - Kpc/Lf - rLf/Lf, (Cf*Kpc*wb)/Lf, -(Kpc*Kpv + 1)/Lf, 0, (F*Kpc)/Lf] -[-mpref*x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Cf, 0, 0, wb - mpref*x1, -1/Cf, 0] -[ mpref*x13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Cf, mpref*x1 - wb, 0, 0, -1/Cf] -[-mpref*x16, -1/Lc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Lc, 0, -rLc/Lc, wb - mpref*x1] -[ mpref*x15, 0, -1/Lc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1/Lc, mpref*x1 - wb, -rLc/Lc] + * +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[-1, 0, 0, 0, -mp, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[ 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, 0, wc*x15, wc*x16, wc*x13, wc*x14] +[ 0, 0, 0, 0, 0, -wc, 0, 0, 0, 0, 0, 0, -wc*x16, wc*x15, wc*x14, -wc*x13] +[ 0, 0, 0, 0, 0, -nq, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0] +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0] +[ 0, 0, 0, 0, 0, -Kpv*nq, Kiv, 0, 0, 0, -1, 0, -Kpv, -Cf*wb, F, 0] +[ 0, 0, 0, 0, 0, 0, 0, Kiv, 0, 0, 0, -1, Cf*wb, -Kpv, 0, F] +[ 0, 0, 0, 0, -mp*x12, -(Kpc*Kpv*nq)/Lf, (Kiv*Kpc)/Lf, 0, Kic/Lf, 0, - Kpc/Lf - rLf/Lf, -mp*x5, -(Kpc*Kpv + 1)/Lf, -(Cf*Kpc*wb)/Lf, (F*Kpc)/Lf, 0] +[ 0, 0, 0, 0, mp*x11, 0, 0, (Kiv*Kpc)/Lf, 0, Kic/Lf, mp*x5, - Kpc/Lf - rLf/Lf, (Cf*Kpc*wb)/Lf, -(Kpc*Kpv + 1)/Lf, 0, (F*Kpc)/Lf] +[ 0, 0, 0, 0, -mp*x14, 0, 0, 0, 0, 0, 1/Cf, 0, 0, wb - mp*x5, -1/Cf, 0] +[ 0, 0, 0, 0, mp*x13, 0, 0, 0, 0, 0, 0, 1/Cf, mp*x5 - wb, 0, 0, -1/Cf] +[ 0, -cos(x4)/Lc, -sin(x4)/Lc, -(x3*cos(x4) - x2*sin(x4))/Lc, -mp*x16, 0, 0, 0, 0, 0, 0, 0, 1/Lc, 0, -rLc/Lc, wb - mp*x5] +[ 0, sin(x4)/Lc, -cos(x4)/Lc, (x2*cos(x4) + x3*sin(x4))/Lc, mp*x15, 0, 0, 0, 0, 0, 0, 0, 0, 1/Lc, mp*x5 - wb, -rLc/Lc] * 'Generated from MATLAB symbolic' - * Jacobian is mostly constant besides reference and rows 4 & 5 * * @tparam ScalarT * @tparam IdxT @@ -145,99 +167,146 @@ int DiscreteGenerator::evaluateJacobian() { //Create dF/dy' std::vector rcordder(13); - std::vector valsder(13,1.0); + std::vector valsder(13, -1.0); for (int i = 0; i < 13; i++) { rcordder[i] = i + 3; } COO_Matrix Jacder = COO_Matrix(rcordder, rcordder, valsder,16,16); + std::vector ctemp{}; + std::vector rtemp{}; + std::vector valtemp{}; + + + //Create dF/dy + //r = 1 + + ctemp = {3, 14, 15}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(1); + valtemp = { - sin(y_[3]) * y_[14] - cos(y_[3]) * y_[15], cos(y_[3]),sin(y_[3])}; + this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 2 + + ctemp = {3, 14, 15}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(2); + valtemp = { - cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15], -sin(y_[3]),cos(y_[3])}; + this->J_.setValues(rtemp, ctemp, valtemp); + //r = 3 - std::vector ctemp{0, 4}; - std::vector rtemp(ctemp.size(),3); - std::vector valtemp{this->refmp_, -this->mp_}; + + ctemp = {0, 4}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(3); + valtemp = {-1.0, -mp_}; this->J_.setValues(rtemp, ctemp, valtemp); + + //r = 0 + if (refframe_) + { + ctemp = {0, 4}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(0); + valtemp = {-1.0, -mp_}; + this->J_.setValues(rtemp, ctemp, valtemp); + } + //r = 4 ctemp = {4, 12, 13, 14, 15}; - std::fill(rtemp.begin(), rtemp.end(), 4); - valtemp = {-this->wc_, this->wc_*y_[14], this->wc_*y_[15], this->wc_*y_[12], this->wc_*y_[13]}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(4); + valtemp = {-wc_, wc_*y_[14], wc_*y_[15], wc_*y_[12], wc_*y_[13]}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 5 ctemp = {5, 12, 13, 14, 15}; - std::fill(rtemp.begin(), rtemp.end(), 5); - valtemp = {-this->wc_, -this->wc_*y_[15], this->wc_*y_[14], this->wc_*y_[13], -this->wc_*y_[12]}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(5); + valtemp = {-wc_, -wc_*y_[15], wc_*y_[14], wc_*y_[13], -wc_*y_[12]}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 6 ctemp = {5, 12}; - std::fill(rtemp.begin(), rtemp.end(), 6); - valtemp = {-this->nq_, -1.0}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(6); + valtemp = {-nq_, -1.0}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 7 ctemp = {13}; - std::fill(rtemp.begin(), rtemp.end(), 7); + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(7); valtemp = {-1.0}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 8 ctemp = {5,6,10,12,13,14}; - std::fill(rtemp.begin(), rtemp.end(), 8); - valtemp = {-this->Kpv_*this->nq_, this->Kiv_, -1.0, -this->Kpv_, -this->Cf_*this->wb_, this->F_}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(8); + valtemp = {-Kpv_*nq_, Kiv_, -1.0, -Kpv_, -Cf_*wb_, F_}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 9 ctemp = {7, 11, 12, 13, 15}; - std::fill(rtemp.begin(), rtemp.end(), 9); - valtemp = {this->Kiv_, -1.0, this->Cf_*this->wb_,-this->Kpv_,this->F_}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(9); + valtemp = {Kiv_, -1.0, Cf_*wb_,-Kpv_,F_}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 10 - ctemp = {0, 5, 6, 8, 10, 11, 12, 13, 14}; - std::fill(rtemp.begin(), rtemp.end(), 10); - valtemp = {-this->refmp_ * y_[11], -(this->Kpc_ * this->Kpv_ * this->nq_) / this->Lf_, (this->Kpc_ * this->Kiv_) / this->Lf_, this->Kic_ / this->Lf_, -(this->Kpc_ + this->rLf_) / this->Lf_, -this->refmp_ * y_[0], -(this->Kpc_ * this->Kpv_ + 1.0) / this->Lf_, -(this->Cf_ * this->Kpc_ * this->wb_) / this->Lf_, (this->F_ * this->Kpc_) / this->Lf_}; + ctemp = {4, 5, 6, 8, 10, 11, 12, 13, 14}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(10); + valtemp = {-mp_ * y_[11], -(Kpc_ * Kpv_ * nq_) / Lf_, (Kpc_ * Kiv_) / Lf_, Kic_ / Lf_, -(Kpc_ + rLf_) / Lf_, -mp_ * y_[4], -(Kpc_ * Kpv_ + 1.0) / Lf_, -(Cf_ * Kpc_ * wb_) / Lf_, (F_ * Kpc_) / Lf_}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 11 - ctemp = {0, 7, 9, 10, 11, 12, 13, 15}; - std::fill(rtemp.begin(), rtemp.end(), 11); - valtemp = {this->refmp_ * y_[10], (this->Kiv_ * this->Kpc_) / this->Lf_, this->Kic_ / this->Lf_, this->refmp_ * y_[0], -(this->Kpc_ + this->rLf_) / this->Lf_, (this->Cf_ * this->Kpc_ * this->wb_) / this->Lf_, -(this->Kpc_ * this->Kpv_ + 1.0) / this->Lf_, (this->F_ * this->Kpc_) / this->Lf_}; + ctemp = {4, 7, 9, 10, 11, 12, 13, 15}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(11); + valtemp = {mp_ * y_[10], (Kiv_ * Kpc_) / Lf_, Kic_ / Lf_, mp_ * y_[4], -(Kpc_ + rLf_) / Lf_, (Cf_ * Kpc_ * wb_) / Lf_, -(Kpc_ * Kpv_ + 1.0) / Lf_, (F_ * Kpc_) / Lf_}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 12 - ctemp = {0, 10, 13, 14}; - std::fill(rtemp.begin(), rtemp.end(), 12); - valtemp = {-this->refmp_ * y_[13], 1.0 / this->Cf_, this->wb_ - this->refmp_ * y_[0], -1.0 / this->Cf_}; + ctemp = {4, 10, 13, 14}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(12); + valtemp = {-mp_ * y_[13], 1.0 / Cf_, wb_ - mp_ * y_[4], -1.0 / Cf_}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 13 - ctemp = {0, 11, 12, 15}; - std::fill(rtemp.begin(), rtemp.end(), 13); - valtemp = {this->refmp_ * y_[12], 1.0 / this->Cf_, -this->wb_ + this->refmp_ * y_[0], -1.0 / this->Cf_}; + ctemp = {4, 11, 12, 15}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(13); + valtemp = {mp_ * y_[12], 1.0 / Cf_, -wb_ + mp_ * y_[4], -1.0 / Cf_}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 14 - ctemp = {0, 1, 12, 14, 15}; - std::fill(rtemp.begin(), rtemp.end(), 14); - valtemp = {-this->refmp_ * y_[15], -1.0 / this->Lc_, 1.0 / this->Lc_, -this->rLc_ / this->Lc_, this->wb_ - this->refmp_ * y_[0]}; + ctemp = {1, 2, 3, 4, 12, 14, 15}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(14); + valtemp = {(1.0/Lc_) * -cos(y_[3]) , (1.0/Lc_) * -sin(y_[3]) , (1.0/Lc_) * (sin(y_[3]) * y_[1] - cos(y_[3]) * y_[2]), -mp_ * y_[15], 1.0 / Lc_, -rLc_ / Lc_, wb_ - mp_ * y_[4]}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 15 - ctemp = {0, 2, 13, 14, 15}; - std::fill(rtemp.begin(), rtemp.end(), 15); - valtemp = {-this->refmp_ * y_[14], -1.0 / this->Lc_, 1.0 / this->Lc_, -this->wb_ + this->refmp_ * y_[0], -this->rLc_ / this->Lc_}; + ctemp = {1, 2, 3, 4, 13, 14, 15}; + rtemp.clear(); + for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(15); + valtemp = {(1.0/Lc_) * sin(y_[3]) , (1.0/Lc_) * -cos(y_[3]), (1.0/Lc_) * (cos(y_[3]) * y_[1] + sin(y_[3]) * y_[2]), mp_ * y_[14], 1.0 / Lc_, -wb_ + mp_ * y_[4], -rLc_ / Lc_}; this->J_.setValues(rtemp, ctemp, valtemp); //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(-this->alpha_, Jacder); + this->J_.AXPY(this->alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp index f5ce86899..bca984460 100644 --- a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp +++ b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp @@ -18,7 +18,6 @@ namespace ModelLib ScalarT wb; ScalarT wc; ScalarT mp; - ScalarT refmp; ScalarT Vn; ScalarT nq; ScalarT F; @@ -63,7 +62,7 @@ namespace ModelLib public: - DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm); + DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm, bool reference_frame); virtual ~DiscreteGenerator(); int allocate(); @@ -81,7 +80,6 @@ namespace ModelLib ScalarT wb_; ScalarT wc_; ScalarT mp_; - ScalarT refmp_; ScalarT Vn_; ScalarT nq_; ScalarT F_; @@ -94,6 +92,7 @@ namespace ModelLib ScalarT Lf_; ScalarT rLc_; ScalarT Lc_; + bool refframe_; }; } diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index a24b7a8e9..885153d41 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -71,11 +71,11 @@ template int Inductor::evaluateResidual() { //input - this->f_[0] = this->y_[2]; + this->f_[0] = -this->y_[2]; //output - this->f_[1] = -this->y_[2]; + this->f_[1] = this->y_[2]; //internal - this->f_[2] = this->L_ * this->yp_[2] + this->y_[0] - this->y_[1] ; + this->f_[2] = -this->L_ * this->yp_[2] + this->y_[1] - this->y_[0] ; return 0; } @@ -87,13 +87,13 @@ int Inductor::evaluateJacobian() //Create dF/dy std::vector rcord{0,1,2,2}; std::vector ccord{2,2,0,1}; - std::vector vals{1.0, -1.0, 1.0, -1.0}; + std::vector vals{-1.0, 1.0, -1.0, 1.0}; this->J_.setValues(rcord, ccord, vals); //Create dF/dy' std::vector rcordder{2}; std::vector ccordder{2}; - std::vector valsder{this->L_}; + std::vector valsder{-this->L_}; COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/CMakeLists.txt new file mode 100644 index 000000000..1bfb8dc3d --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_mircobusdq + SOURCES + MicrogridBusDQ.cpp + OUTPUT_NAME + gridkit_powerelec_mircobusdq) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp new file mode 100644 index 000000000..206108221 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -0,0 +1,132 @@ + +#include +#include +#include +#include "MicrogridBusDQ.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant MicrogridBusDQ model + * + * Calls default ModelEvaluatorImpl constructor. + * + * Each microgrid line has a virtual resistance RN + */ + +template +MicrogridBusDQ::MicrogridBusDQ(IdxT id, ScalarT RN) + : RN_(RN) +{ + // externals [vbus_d, vbus_q] + this->size_ = 2; + this->n_intern = 0; + this->n_extern = 2; + this->extern_indices = {0,1}; + this->idc_ = id; +} + +template +MicrogridBusDQ::~MicrogridBusDQ() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int MicrogridBusDQ::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + + return 0; +} + +/** + * Initialization of the grid model + */ +template +int MicrogridBusDQ::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int MicrogridBusDQ::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Evaluate residual of microgrid line + * This model has "Virtual resistors" on both ends with parameters RN1 and RN2 + * + */ +template +int MicrogridBusDQ::evaluateResidual() +{ + //bus voltage + f_[0] = -y_[0] / RN_; + f_[1] = -y_[1] / RN_; + + return 0; +} + +/** + * @brief Generate Jacobian for Transmission Line + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ +template +int MicrogridBusDQ::evaluateJacobian() +{ + this->J_.zeroMatrix(); + + //Create dF/dy + std::vector rtemp{0,1}; + std::vector ctemp{0,1}; + std::vector vals{-1.0 / RN_,-1.0 / RN_}; + this->J_.setValues(rtemp, ctemp, vals); + + return 0; +} + +template +int MicrogridBusDQ::evaluateIntegrand() +{ + return 0; +} + +template +int MicrogridBusDQ::initializeAdjoint() +{ + return 0; +} + +template +int MicrogridBusDQ::evaluateAdjointResidual() +{ + return 0; +} + +template +int MicrogridBusDQ::evaluateAdjointIntegrand() +{ + return 0; +} + + +// Available template instantiations +template class MicrogridBusDQ; +template class MicrogridBusDQ; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp new file mode 100644 index 000000000..44154da38 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp @@ -0,0 +1,66 @@ + + +#ifndef _VIRBUSDQ_HPP_ +#define _VIRBUSDQ_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive MicrogridBusDQ class. + * + */ + template + class MicrogridBusDQ : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::J_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + public: + MicrogridBusDQ(IdxT id, ScalarT RN); + virtual ~MicrogridBusDQ(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + + private: + ScalarT RN_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/MicrogridLine/CMakeLists.txt new file mode 100644 index 000000000..d59cebb9c --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_mircoline + SOURCES + MicrogridLine.cpp + OUTPUT_NAME + gridkit_powerelec_mircoline) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp new file mode 100644 index 000000000..e040ceb70 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp @@ -0,0 +1,172 @@ + +#include +#include +#include +#include "MicrogridLine.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant MicrogridLine model + * + * Calls default ModelEvaluatorImpl constructor. + * + * Each microgrid line has a virtual resistance RN + */ + +template +MicrogridLine::MicrogridLine(IdxT id, ScalarT R,ScalarT L) + : R_(R), L_(L) +{ + // internals [id, iq] + // externals [\omegaref, vbd_in, vbq_in, vbd_out, vbq_out] + this->size_ = 7; + this->n_intern = 2; + this->n_extern = 5; + this->extern_indices = {0,1,2,3,4}; + this->idc_ = id; +} + +template +MicrogridLine::~MicrogridLine() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int MicrogridLine::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + + return 0; +} + +/** + * Initialization of the grid model + */ +template +int MicrogridLine::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int MicrogridLine::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Evaluate residual of microgrid line + * This model has "Virtual resistors" on both ends with parameters RN1 and RN2 + * + */ +template +int MicrogridLine::evaluateResidual() +{ + //ref motor + this->f_[0] = 0.0; + + //input + this->f_[1] = -y_[5] ; + this->f_[2] = -y_[6] ; + + //output + this->f_[3] = y_[5] ; + this->f_[4] = y_[6] ; + + //Internal variables + this->f_[5] = -yp_[5] - (R_ / L_) * y_[5] + y_[0]*y_[6] + (y_[1] - y_[3])/L_; + this->f_[6] = -yp_[6] - (R_ / L_) * y_[6] - y_[0]*y_[5] + (y_[2] - y_[4])/L_; + + + return 0; +} + +/** + * @brief Generate Jacobian for Transmission Line + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ +template +int MicrogridLine::evaluateJacobian() +{ + this->J_.zeroMatrix(); + + //Create dF/dy + std::vector rtemp{1,2,3,4}; + std::vector ctemp{5,6,5,6}; + std::vector vals{-1.0,-1.0,1.0,1.0}; + this->J_.setValues(rtemp, ctemp, vals); + + + std::vector ccord{0, 1, 3, 5, 6}; + + std::vector rcord(ccord.size(),5); + vals = {y_[6], (1.0 / L_) , -(1.0 / L_), - (R_ / L_) , y_[0]}; + this->J_.setValues(rcord, ccord, vals); + + + std::vector ccor2{0, 2, 4, 5, 6}; + std::fill(rcord.begin(), rcord.end(), 6); + vals = {-y_[5], (1.0 / L_) , -(1.0 / L_), -y_[0], - (R_ / L_)}; + this->J_.setValues(rcord, ccor2, vals); + + + //Create -dF/dy' + std::vector rcordder{5,6}; + std::vector ccordder{5,6}; + std::vector valsder{-1.0, -1.0}; + COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,7,7); + + //Perform dF/dy + \alpha dF/dy' + this->J_.AXPY(this->alpha_, Jacder); + + + return 0; +} + +template +int MicrogridLine::evaluateIntegrand() +{ + return 0; +} + +template +int MicrogridLine::initializeAdjoint() +{ + return 0; +} + +template +int MicrogridLine::evaluateAdjointResidual() +{ + return 0; +} + +template +int MicrogridLine::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class MicrogridLine; +template class MicrogridLine; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp new file mode 100644 index 000000000..11ef78617 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp @@ -0,0 +1,67 @@ + + +#ifndef _TRANLINE_HPP_ +#define _TRANLINE_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive MicrogridLine class. + * + */ + template + class MicrogridLine : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::J_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + public: + MicrogridLine(IdxT id, ScalarT R, ScalarT L); + virtual ~MicrogridLine(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + + private: + ScalarT R_; + ScalarT L_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/CMakeLists.txt new file mode 100644 index 000000000..313d47688 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +gridkit_add_library(powerelec_microload + SOURCES + MicrogridLoad.cpp + OUTPUT_NAME + gridkit_powerelec_microload) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp new file mode 100644 index 000000000..c39f53388 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp @@ -0,0 +1,169 @@ + +#include +#include +#include +#include "MicrogridLoad.hpp" + +namespace ModelLib { + +/*! + * @brief Constructor for a constant MicrogridLoad model + * + * Calls default ModelEvaluatorImpl constructor. + * + * This is the Medium distance form with the use of the admittance matrix. + * Since the line is of medium length then there is no real part for shunt admittance + */ + +template +MicrogridLoad::MicrogridLoad(IdxT id, ScalarT R,ScalarT L) + : R_(R), L_(L) +{ + // internals [id, iq] + // externals [\omegaref, vbd_out, vbq_out] + this->size_ = 5; + this->n_intern = 2; + this->n_extern = 3; + this->extern_indices = {0,1,2}; + this->idc_ = id; + +} + +template +MicrogridLoad::~MicrogridLoad() +{ +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int MicrogridLoad::allocate() +{ + this->y_.resize(this->size_); + this->yp_.resize(this->size_); + this->f_.resize(this->size_); + + return 0; +} + +/** + * Initialization of the grid model + */ +template +int MicrogridLoad::initialize() +{ + return 0; +} + +/* + * \brief Identify differential variables + */ +template +int MicrogridLoad::tagDifferentiable() +{ + return 0; +} + +/** + * @brief Eval Micro Load + */ +template +int MicrogridLoad::evaluateResidual() +{ + //ref motor + this->f_[0] = 0.0; + + //only input for loads + + //input + this->f_[1] = -y_[3] ; + this->f_[2] = -y_[4] ; + + //Internal variables + this->f_[3] = -yp_[3] - (R_ / L_) * y_[3] + y_[0]*y_[4] + y_[1] / L_; + this->f_[4] = -yp_[4] - (R_ / L_) * y_[4] - y_[0]*y_[3] + y_[2] / L_; + + + return 0; +} + +/** + * @brief Generate Jacobian for Micro Load + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ +template +int MicrogridLoad::evaluateJacobian() +{ + this->J_.zeroMatrix(); + + //Create dF/dy + std::vector rtemp{1,2}; + std::vector ctemp{3,4}; + std::vector vals{-1.0,-1.0}; + this->J_.setValues(rtemp, ctemp, vals); + + + std::vector ccord{0, 1, 3, 4}; + + std::vector rcord(ccord.size(),3); + vals = {y_[4], (1.0 / L_) , - (R_ / L_) , y_[0]}; + this->J_.setValues(rcord, ccord, vals); + + + std::vector ccor2{0, 2, 3, 4}; + std::fill(rcord.begin(), rcord.end(), 4); + vals = {-y_[3], (1.0 / L_) , -y_[0], - (R_ / L_)}; + this->J_.setValues(rcord, ccor2, vals); + + + //Create -dF/dy' + std::vector rcordder{3,4}; + std::vector ccordder{3,4}; + std::vector valsder{-1.0, -1.0}; + COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,5,5); + + //Perform dF/dy + \alpha dF/dy' + this->J_.AXPY(this->alpha_, Jacder); + + return 0; +} + +template +int MicrogridLoad::evaluateIntegrand() +{ + return 0; +} + +template +int MicrogridLoad::initializeAdjoint() +{ + return 0; +} + +template +int MicrogridLoad::evaluateAdjointResidual() +{ + return 0; +} + +template +int MicrogridLoad::evaluateAdjointIntegrand() +{ + return 0; +} + + + + + +// Available template instantiations +template class MicrogridLoad; +template class MicrogridLoad; + + +} //namespace ModelLib + diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.hpp b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.hpp new file mode 100644 index 000000000..22694f614 --- /dev/null +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.hpp @@ -0,0 +1,67 @@ + + +#ifndef _TRANLOAD_HPP_ +#define _TRANLOAD_HPP_ + +#include +#include +#include + + +namespace ModelLib +{ + template class BaseBus; +} + + +namespace ModelLib +{ + /*! + * @brief Declaration of a passive MicrogridLoad class. + * + */ + template + class MicrogridLoad : public CircuitComponent + { + using CircuitComponent::size_; + using CircuitComponent::nnz_; + using CircuitComponent::time_; + using CircuitComponent::alpha_; + using CircuitComponent::y_; + using CircuitComponent::yp_; + using CircuitComponent::tag_; + using CircuitComponent::f_; + using CircuitComponent::g_; + using CircuitComponent::yB_; + using CircuitComponent::ypB_; + using CircuitComponent::fB_; + using CircuitComponent::gB_; + using CircuitComponent::J_; + using CircuitComponent::param_; + using CircuitComponent::idc_; + + + public: + MicrogridLoad(IdxT id, ScalarT R, ScalarT L); + virtual ~MicrogridLoad(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + + private: + ScalarT R_; + ScalarT L_; + }; +} + +#endif diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp index c7cb09798..e58e50556 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -72,11 +72,11 @@ int VoltageSource::evaluateResidual() //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors // for easier development //input - this->f_[0] = this->y_[2]; + this->f_[0] = -this->y_[2]; //ouput - this->f_[1] = -this->y_[2]; + this->f_[1] = this->y_[2]; //internal - this->f_[2] = -this->y_[1] + this->y_[0] + this->V_; + this->f_[2] = this->y_[1] - this->y_[0] - this->V_; return 0; } @@ -86,7 +86,7 @@ int VoltageSource::evaluateJacobian() //Create dF/dy std::vector rcord{0,1,2,2}; std::vector ccord{2,2,0,1}; - std::vector vals{1.0, -1.0, 1.0, -1.0}; + std::vector vals{-1.0, 1.0, -1.0, 1.0}; this->J_.setValues(rcord, ccord, vals); return 0; diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index e15774642..2c53fcc25 100644 --- a/Examples/CMakeLists.txt +++ b/Examples/CMakeLists.txt @@ -57,6 +57,7 @@ add_subdirectory(MatPowerTesting) add_subdirectory(RLCircuit) +add_subdirectory(Microgrid) add_subdirectory(SparseTest) add_subdirectory(DiscreteGeneratorTest) diff --git a/Examples/DiscreteGeneratorTest/CMakeLists.txt b/Examples/DiscreteGeneratorTest/CMakeLists.txt index b1100b91a..9238fb346 100644 --- a/Examples/DiscreteGeneratorTest/CMakeLists.txt +++ b/Examples/DiscreteGeneratorTest/CMakeLists.txt @@ -3,7 +3,10 @@ add_executable(dgtest DGTest.cpp) -target_link_libraries(dgtest GRIDKIT::powerelec_disgen) +target_link_libraries(dgtest GRIDKIT::powerelec_disgen + GRIDKIT::powerelec_mircoline + GRIDKIT::powerelec_microload + GRIDKIT::solvers_dyn) add_test(NAME DiscreteGeneratorTest COMMAND $) install(TARGETS dgtest RUNTIME DESTINATION bin) diff --git a/Examples/DiscreteGeneratorTest/DGTest.cpp b/Examples/DiscreteGeneratorTest/DGTest.cpp index 7d4aeda6f..d3dd2c68b 100644 --- a/Examples/DiscreteGeneratorTest/DGTest.cpp +++ b/Examples/DiscreteGeneratorTest/DGTest.cpp @@ -15,11 +15,9 @@ int main(int argc, char const *argv[]) ModelLib::DiscreteGeneratorParameters parms; //Parameters from MATLAB Microgrid code for first DG - //refmp is need for reference input parms.wb = 2.0*M_PI*50.0; parms.wc = 31.41; parms.mp = 9.4e-5; - parms.refmp = 9.4e-5; parms.Vn = 380; parms.nq = 1.3e-3; parms.F = 0.75; @@ -33,7 +31,7 @@ int main(int argc, char const *argv[]) parms.rLc = 0.03; parms.Lc = 0.35e-3; - ModelLib::DiscreteGenerator *dg = new ModelLib::DiscreteGenerator(0, parms); + ModelLib::DiscreteGenerator *dg = new ModelLib::DiscreteGenerator(0, parms, true); std::vector t1(16,0.0); std::vector t2{0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,1.3,1.4,1.5}; @@ -48,9 +46,33 @@ int main(int argc, char const *argv[]) std::cout << "Output: {"; for (double i : dg->getResidual()) { - std::cout << i << ", "; + printf("%e ,", i); } std::cout << "}\n"; + //Generated from matlab code with same parameters and inputs + std::vector true_vec{3.141592277589793e+02, + 8.941907747838389e-01, + 1.846733023014284e+00, + 3.141592277589793e+02, + 1.014543000000000e+02, + -1.507680000000000e+01, + 3.787993500000000e+02, + -1.300000000000000e+00, + 2.899095146477517e+02, + 2.939138495559215e+02, + 1.507210571826699e+07, + 1.659799832843673e+07, + -7.591593003913325e+03, + -8.376991073310774e+03, + 3.337988298081817e+03, + 2.684419146397466e+03}; + + std::cout << "Test the Relative Error\n"; + for (size_t i = 0; i < true_vec.size(); i++) + { + printf("%e ,\n", (true_vec[i] - dg->getResidual()[i]) / true_vec[i]); + } + return 0; } diff --git a/Examples/Microgrid/CMakeLists.txt b/Examples/Microgrid/CMakeLists.txt new file mode 100644 index 000000000..0958144c4 --- /dev/null +++ b/Examples/Microgrid/CMakeLists.txt @@ -0,0 +1,13 @@ + + + + +add_executable(microgrid Microgrid.cpp) +target_link_libraries(microgrid GRIDKIT::powerelec_disgen + GRIDKIT::powerelec_mircoline + GRIDKIT::powerelec_microload + GRIDKIT::solvers_dyn + GRIDKIT::powerelec_mircobusdq) + +add_test(NAME Microgrid COMMAND $) +install(TARGETS microgrid RUNTIME DESTINATION bin) diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp new file mode 100644 index 000000000..a0cf8dc9b --- /dev/null +++ b/Examples/Microgrid/Microgrid.cpp @@ -0,0 +1,361 @@ + + +#include +#include +#include +#include +#include + + +#include +#include +#include +#include + +#include +#include +#include + + +int main(int argc, char const *argv[]) +{ + double abstol = 1.0e-4; + double reltol = 1.0e-4; + bool usejac = true; + + //TODO:setup as named parameters + //Create circuit model + ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac); + + //Modeled after the problem in the paper + double RN = 1.0e4; + + //DG Params + + ModelLib::DiscreteGeneratorParameters parms1; + parms1.wb = 2.0*M_PI*50.0; + parms1.wc = 31.41; + parms1.mp = 9.4e-5; + parms1.Vn = 380; + parms1.nq = 1.3e-3; + parms1.F = 0.75; + parms1.Kiv = 420.0; + parms1.Kpv = 0.1; + parms1.Kic = 20.0 * 1.0e3; + parms1.Kpc = 15.0; + parms1.Cf = 50.0e-6; + parms1.rLf = 0.1; + parms1.Lf = 1.35e-3; + parms1.rLc = 0.03; + parms1.Lc = 0.35e-3; + + ModelLib::DiscreteGeneratorParameters parms2; + //Parameters from MATLAB Microgrid code for first DG + parms2.wb = 2.0*M_PI*50.0; + parms2.wc = 31.41; + parms2.mp = 12.5e-5; + parms2.Vn = 380; + parms2.nq = 1.5e-3; + parms2.F = 0.75; + parms2.Kiv = 390.0; + parms2.Kpv = 0.05; + parms2.Kic = 16.0 * 1.0e3; + parms2.Kpc = 10.5; + parms2.Cf = 50.0e-6; + parms2.rLf = 0.1; + parms2.Lf = 1.35e-3; + parms2.rLc = 0.03; + parms2.Lc = 0.35e-3; + + //Line params + double rline1 = 0.23; + double Lline1 = 0.1 / (2.0 * M_PI * 50.0); + + double rline2 = 0.35; + double Lline2 = 0.58 / (2.0 * M_PI * 50.0); + + double rline3 = 0.23; + double Lline3 = 0.1 / (2.0 * M_PI * 50.0); + + //load parms + double rload1 = 3.0; + double Lload1 = 2.0 / (2.0 * M_PI * 50.0); + + double rload2 = 2.0; + double Lload2 = 1.0 / (2.0 * M_PI * 50.0); + + + //indexing sets + size_t Nsize = 2; + // DGs + Lines + Loads + size_t vec_size_internals = 13*(2*Nsize) + (2 + 4*(Nsize - 1)) + 2*Nsize; + // \omegaref + BusDQ + size_t vec_size_externals = 1 + 2*(2*Nsize); + size_t dqbus1 = vec_size_externals + 1; + size_t dqbus2 = vec_size_externals + 3; + size_t dqbus3 = vec_size_externals + 5; + size_t dqbus4 = vec_size_externals + 7; + + size_t vec_size_total = vec_size_internals + vec_size_externals; + + + size_t indexv = 0; + + //dg 1 + ModelLib::DiscreteGenerator *dg1 = new ModelLib::DiscreteGenerator(0, parms1, true); + //ref motor + dg1->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg1->setExternalConnectionNodes(1,dqbus1); + dg1->setExternalConnectionNodes(2,dqbus1 + 1); + //internal connections + for (size_t i = 0; i < 13; i++) + { + + dg1->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg1); + + //dg 2 + ModelLib::DiscreteGenerator *dg2 = new ModelLib::DiscreteGenerator(1, parms1, false); + //ref motor + dg2->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg2->setExternalConnectionNodes(1,dqbus2); + dg2->setExternalConnectionNodes(2,dqbus2 + 1); + //internal connections + for (size_t i = 0; i < 13; i++) + { + + dg2->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg2); + + + //dg 3 + ModelLib::DiscreteGenerator *dg3 = new ModelLib::DiscreteGenerator(2, parms2, false); + //ref motor + dg3->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg3->setExternalConnectionNodes(1,dqbus3); + dg3->setExternalConnectionNodes(2,dqbus3 + 1); + //internal connections + for (size_t i = 0; i < 13; i++) + { + + dg3->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg3); + + + //dg 4 + ModelLib::DiscreteGenerator *dg4 = new ModelLib::DiscreteGenerator(3, parms2, false); + //ref motor + dg4->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg4->setExternalConnectionNodes(1,dqbus4); + dg4->setExternalConnectionNodes(2,dqbus4 + 1); + + //internal connections + for (size_t i = 0; i < 13; i++) + { + + dg4->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg4); + + // Lines + + //line 1 + ModelLib::MicrogridLine *l1 = new ModelLib::MicrogridLine(4, rline1, Lline1); + //ref motor + l1->setExternalConnectionNodes(0,vec_size_internals); + //input connections + l1->setExternalConnectionNodes(1,dqbus1); + l1->setExternalConnectionNodes(2,dqbus1 + 1); + //output connections + l1->setExternalConnectionNodes(3,dqbus2); + l1->setExternalConnectionNodes(4,dqbus2 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + l1->setExternalConnectionNodes(5 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(l1); + + + //line 2 + ModelLib::MicrogridLine *l2 = new ModelLib::MicrogridLine(5, rline2, Lline2); + //ref motor + l2->setExternalConnectionNodes(0,vec_size_internals); + //input connections + l2->setExternalConnectionNodes(1,dqbus2); + l2->setExternalConnectionNodes(2,dqbus2 + 1); + //output connections + l2->setExternalConnectionNodes(3,dqbus3); + l2->setExternalConnectionNodes(4,dqbus3 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + l2->setExternalConnectionNodes(5 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(l2); + + //line 3 + ModelLib::MicrogridLine *l3 = new ModelLib::MicrogridLine(6, rline3, Lline3); + //ref motor + l3->setExternalConnectionNodes(0,vec_size_internals); + //input connections + l3->setExternalConnectionNodes(1,dqbus3); + l3->setExternalConnectionNodes(2,dqbus3 + 1); + //output connections + l3->setExternalConnectionNodes(3,dqbus4); + l3->setExternalConnectionNodes(4,dqbus4 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + l3->setExternalConnectionNodes(5 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(l3); + + // loads + + //load 1 + ModelLib::MicrogridLoad *load1 = new ModelLib::MicrogridLoad(7, rload1, Lload1); + //ref motor + load1->setExternalConnectionNodes(0,vec_size_internals); + //input connections + load1->setExternalConnectionNodes(1,dqbus1); + load1->setExternalConnectionNodes(2,dqbus1 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + load1->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(load1); + + //load 2 + ModelLib::MicrogridLoad *load2 = new ModelLib::MicrogridLoad(8, rload2, Lload2); + //ref motor + load2->setExternalConnectionNodes(0,vec_size_internals); + //input connections + load2->setExternalConnectionNodes(1,dqbus3); + load2->setExternalConnectionNodes(2,dqbus3 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + load2->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(load2); + + //Virtual PQ Buses + ModelLib::MicrogridBusDQ *bus1 = new ModelLib::MicrogridBusDQ(9, RN); + + bus1->setExternalConnectionNodes(0,dqbus1); + bus1->setExternalConnectionNodes(1,dqbus1 + 1); + sysmodel->addComponent(bus1); + + ModelLib::MicrogridBusDQ *bus2 = new ModelLib::MicrogridBusDQ(10, RN); + + bus2->setExternalConnectionNodes(0,dqbus2); + bus2->setExternalConnectionNodes(1,dqbus2 + 1); + sysmodel->addComponent(bus2); + + ModelLib::MicrogridBusDQ *bus3 = new ModelLib::MicrogridBusDQ(11, RN); + + bus3->setExternalConnectionNodes(0,dqbus3); + bus3->setExternalConnectionNodes(1,dqbus3 + 1); + sysmodel->addComponent(bus3); + + ModelLib::MicrogridBusDQ *bus4 = new ModelLib::MicrogridBusDQ(12, RN); + + bus4->setExternalConnectionNodes(0,dqbus4); + bus4->setExternalConnectionNodes(1,dqbus4 + 1); + sysmodel->addComponent(bus4); + + sysmodel->allocate(vec_size_total); + + std::cout << sysmodel->y().size() << std::endl; + std::cout << vec_size_internals << ", " << vec_size_externals << "\n"; + + //Create Intial points for states + for (size_t i = 0; i < vec_size_total; i++) + { + sysmodel->y()[i] = 0.0; + sysmodel->yp()[i] = 0.0; + } + + // Create Intial derivatives specifics generated in MATLAB + //DGs + for (size_t i = 0; i < 2; i++) + { + sysmodel->yp()[13*i + 3] = parms1.Vn; + sysmodel->yp()[13*i + 5] = parms1.Kpv * parms1.Vn; + sysmodel->yp()[13*i + 7] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; + } + for (size_t i = 2; i < 4; i++) + { + sysmodel->yp()[13*i + 3] = parms2.Vn; + sysmodel->yp()[13*i + 5] = parms2.Kpv * parms2.Vn; + sysmodel->yp()[13*i + 7] = (parms2.Kpc * parms2.Kpv * parms2.Vn) / parms2.Lf; + } + + //since the intial P_com = 0 + sysmodel->y()[62] = parms1.wb; + + + + sysmodel->initialize(); + sysmodel->evaluateResidual(); + + std::vector& fres = sysmodel->getResidual(); + std::cout << "Verify Intial Resisdual is Zero: {\n"; + for (size_t i = 0; i < fres.size(); i++) + { + printf("%u : %e \n", i, fres[i]); + } + std::cout << "}\n"; + + sysmodel->updateTime(0.0, 1.0e-8); + sysmodel->evaluateJacobian(); + std::cout << "Intial Jacobian with alpha:\n"; + // std::cout << sysmodel->getJacobian().frobnorm() << "\n"; + + + // //Create numerical integrator and configure it for the generator model + // AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); + + // double t_init = 0.0; + // double t_final = 1.0; + + // // setup simulation + // idas->configureSimulation(); + // idas->getDefaultInitialCondition(); + // idas->initializeSimulation(t_init); + + // idas->runSimulation(t_final); + + // std::vector& yfinial = sysmodel->y(); + + // std::cout << "Final Vector y\n"; + // for (size_t i = 0; i < yfinial.size(); i++) + // { + // std::cout << yfinial[i] << "\n"; + // } + + return 0; +} diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp index e902b1242..55fe476b9 100644 --- a/Examples/RLCircuit/RLCircuit.cpp +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -18,8 +18,8 @@ int main(int argc, char const *argv[]) { - double abstol = 1e-8; - double reltol = 1e-8; + double abstol = 1.0e-8; + double reltol = 1.0e-8; bool usejac = true; //TODO:setup as named parameters @@ -132,9 +132,9 @@ int main(int argc, char const *argv[]) //analytical solution to the circuit yexact[0] = vinit; - yexact[2] = (-vinit / rinit) * (exp((rinit / linit) * t_final) - 1.0); + yexact[2] = (vinit / rinit) * (exp(-(rinit / linit) * t_final) - 1.0); yexact[3] = yexact[2]; - yexact[1] = vinit - rinit * yexact[2]; + yexact[1] = vinit + rinit * yexact[2]; std::cout << "Element-wise Relative error at t=" << t_final << "\n"; for (size_t i = 0; i < yfinial.size(); i++) diff --git a/SparseMatrix/COO_Matrix.hpp b/SparseMatrix/COO_Matrix.hpp index c256e015c..716748fa8 100644 --- a/SparseMatrix/COO_Matrix.hpp +++ b/SparseMatrix/COO_Matrix.hpp @@ -50,6 +50,7 @@ class COO_Matrix void AXPY(ScalarT alpha, COO_Matrix& a); void AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v); void SCAL(ScalarT alpha); + ScalarT frobnorm(); // --- Permutation Operations --- //No sorting is actually done. Only done when nesscary @@ -391,6 +392,14 @@ inline void COO_Matrix::SCAL(ScalarT alpha) for (auto i = this->values.begin(); i < this->values.end(); i++) *i *= alpha; } +template +inline ScalarT COO_Matrix::frobnorm() +{ + ScalarT totsum = 0.0; + for (auto i = this->values.begin(); i < this->values.end(); i++) totsum += abs(*i)^2; + return totsum; +} + /** * @brief Permutate the matrix to a different one. Only changes the coordinates * From 1952b25d56ac7df775f860a64b56f37709f2b969 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Mon, 19 Feb 2024 18:53:44 -0500 Subject: [PATCH 28/44] Working Microgrid (Finite Difference) - "grounded" the rotor difference in reference - Comparing agianst reference from MATLAB --- Examples/Microgrid/Microgrid.cpp | 168 +++++++++++++++++++++++-------- Solver/Dynamic/Ida.cpp | 6 +- 2 files changed, 130 insertions(+), 44 deletions(-) diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp index a0cf8dc9b..5f788080a 100644 --- a/Examples/Microgrid/Microgrid.cpp +++ b/Examples/Microgrid/Microgrid.cpp @@ -19,9 +19,9 @@ int main(int argc, char const *argv[]) { - double abstol = 1.0e-4; - double reltol = 1.0e-4; - bool usejac = true; + double abstol = 1.0e-8; + double reltol = 1.0e-8; + bool usejac = false; //TODO:setup as named parameters //Create circuit model @@ -36,14 +36,14 @@ int main(int argc, char const *argv[]) parms1.wb = 2.0*M_PI*50.0; parms1.wc = 31.41; parms1.mp = 9.4e-5; - parms1.Vn = 380; + parms1.Vn = 380.0; parms1.nq = 1.3e-3; parms1.F = 0.75; parms1.Kiv = 420.0; parms1.Kpv = 0.1; - parms1.Kic = 20.0 * 1.0e3; + parms1.Kic = 2.0e4; parms1.Kpc = 15.0; - parms1.Cf = 50.0e-6; + parms1.Cf = 5.0e-5; parms1.rLf = 0.1; parms1.Lf = 1.35e-3; parms1.rLc = 0.03; @@ -54,12 +54,12 @@ int main(int argc, char const *argv[]) parms2.wb = 2.0*M_PI*50.0; parms2.wc = 31.41; parms2.mp = 12.5e-5; - parms2.Vn = 380; + parms2.Vn = 380.0; parms2.nq = 1.5e-3; parms2.F = 0.75; parms2.Kiv = 390.0; parms2.Kpv = 0.05; - parms2.Kic = 16.0 * 1.0e3; + parms2.Kic = 16.0e3; parms2.Kpc = 10.5; parms2.Cf = 50.0e-6; parms2.rLf = 0.1; @@ -87,14 +87,14 @@ int main(int argc, char const *argv[]) //indexing sets size_t Nsize = 2; - // DGs + Lines + Loads - size_t vec_size_internals = 13*(2*Nsize) + (2 + 4*(Nsize - 1)) + 2*Nsize; + // DGs + - refframe Lines + Loads + size_t vec_size_internals = 13*(2*Nsize) - 1 + (2 + 4*(Nsize - 1)) + 2*Nsize; // \omegaref + BusDQ size_t vec_size_externals = 1 + 2*(2*Nsize); - size_t dqbus1 = vec_size_externals + 1; - size_t dqbus2 = vec_size_externals + 3; - size_t dqbus3 = vec_size_externals + 5; - size_t dqbus4 = vec_size_externals + 7; + size_t dqbus1 = vec_size_internals + 1; + size_t dqbus2 = vec_size_internals + 3; + size_t dqbus3 = vec_size_internals + 5; + size_t dqbus4 = vec_size_internals + 7; size_t vec_size_total = vec_size_internals + vec_size_externals; @@ -108,13 +108,15 @@ int main(int argc, char const *argv[]) //outputs dg1->setExternalConnectionNodes(1,dqbus1); dg1->setExternalConnectionNodes(2,dqbus1 + 1); + //"grounding" of the difference + dg1->setExternalConnectionNodes(3,-1); //internal connections - for (size_t i = 0; i < 13; i++) + for (size_t i = 0; i < 12; i++) { - dg1->setExternalConnectionNodes(3 + i,indexv + i); + dg1->setExternalConnectionNodes(4 + i,indexv + i); } - indexv += 13; + indexv += 12; sysmodel->addComponent(dg1); //dg 2 @@ -300,22 +302,22 @@ int main(int argc, char const *argv[]) } // Create Intial derivatives specifics generated in MATLAB - //DGs - for (size_t i = 0; i < 2; i++) - { - sysmodel->yp()[13*i + 3] = parms1.Vn; - sysmodel->yp()[13*i + 5] = parms1.Kpv * parms1.Vn; - sysmodel->yp()[13*i + 7] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; - } + //DGs 1 + sysmodel->yp()[2] = parms1.Vn; + sysmodel->yp()[4] = parms1.Kpv * parms1.Vn; + sysmodel->yp()[6] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; + sysmodel->yp()[12 + 3] = parms1.Vn; + sysmodel->yp()[12 + 5] = parms1.Kpv * parms1.Vn; + sysmodel->yp()[12 + 7] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; for (size_t i = 2; i < 4; i++) { - sysmodel->yp()[13*i + 3] = parms2.Vn; - sysmodel->yp()[13*i + 5] = parms2.Kpv * parms2.Vn; - sysmodel->yp()[13*i + 7] = (parms2.Kpc * parms2.Kpv * parms2.Vn) / parms2.Lf; + sysmodel->yp()[13*i - 1 + 3] = parms2.Vn; + sysmodel->yp()[13*i - 1 + 5] = parms2.Kpv * parms2.Vn; + sysmodel->yp()[13*i - 1 + 7] = (parms2.Kpc * parms2.Kpv * parms2.Vn) / parms2.Lf; } //since the intial P_com = 0 - sysmodel->y()[62] = parms1.wb; + sysmodel->y()[vec_size_internals] = parms1.wb; @@ -336,26 +338,106 @@ int main(int argc, char const *argv[]) // std::cout << sysmodel->getJacobian().frobnorm() << "\n"; - // //Create numerical integrator and configure it for the generator model - // AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); + //Create numerical integrator and configure it for the generator model + AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); + + double t_init = 0.0; + double t_final = 1.0; - // double t_init = 0.0; - // double t_final = 1.0; + // setup simulation + idas->configureSimulation(); + idas->getDefaultInitialCondition(); + idas->initializeSimulation(t_init); - // // setup simulation - // idas->configureSimulation(); - // idas->getDefaultInitialCondition(); - // idas->initializeSimulation(t_init); + idas->runSimulation(t_final); - // idas->runSimulation(t_final); + std::vector& yfinial = sysmodel->y(); - // std::vector& yfinial = sysmodel->y(); + std::cout << "Final Vector y\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << yfinial[i] << "\n"; + } - // std::cout << "Final Vector y\n"; - // for (size_t i = 0; i < yfinial.size(); i++) - // { - // std::cout << yfinial[i] << "\n"; - // } + //Generate from MATLAB code ODE form with tolerances of 1e-12 + std::vectortrue_vec{ + 2.297543153595780e+04, + 1.275311524125022e+04, + 3.763060183116022e-02, + -2.098153459325261e-02, + 1.848285659119097e-02, + -1.563291404944864e-04, + 6.321941907011718e+01, + -2.942264300846256e+01, + 3.634209302905854e+02, + -2.668928293656362e-06, + 6.321941919221522e+01, + -3.509200178595996e+01, + -7.555954467454730e-03, + 2.297580486511343e+04, + 8.742028429066131e+03, + 3.710079564796484e-02, + -1.421122598056797e-02, + 1.874079517807597e-02, + -9.891304812687215e-05, + 6.232933298360234e+01, + -1.796494061423331e+01, + 3.686353885026506e+02, + 3.465673854181523e-05, + 6.232933406188410e+01, + -2.371564475187742e+01, + -8.273939686941580e-02, + 1.727775042678524e+04, + 1.649365247247288e+04, + 3.116555157570849e-02, + -2.985990066758010e-02, + 2.250012115906506e-02, + -2.643873146501096e-04, + 4.861823510250247e+01, + -4.088592755441309e+01, + 3.552597163751238e+02, + -1.496407194199739e-04, + 4.861823504694532e+01, + -4.642797132602495e+01, + -8.445727984408551e-02, + 1.727723725566433e+04, + 9.182386962936238e+03, + 3.024959333190777e-02, + -1.617250828202081e-02, + 2.318056864131751e-02, + -1.295918667730514e-04, + 4.718938244522050e+01, + -1.935782085675469e+01, + 3.662262287803608e+02, + 1.076423957830039e-04, + 4.718938116520511e+01, + -2.507094256286497e+01, + -1.881248349415025e+01, + 2.114714832305742e+01, + 4.329946674909793e+01, + -3.037887936225145e+00, + -4.487023117352992e+01, + 2.895883729832657e+01, + 8.199613345691378e+01, + -5.623856502948122e+01, + 1.327498499660322e+02, + -8.228065162347022e+01, + 3.119995747945993e+02, + 3.576922945168803e+02, + -5.850795361581618e+00, + 3.641193316268954e+02, + -8.846325267612976e+00, + 3.472146752739036e+02, + -3.272400970143252e+01, + 3.604108939430972e+02, + -3.492842627398574e+01 + }; + + std::cout << "Test the Relative Error\n"; + for (size_t i = 0; i < true_vec.size(); i++) + { + printf("%u : %e ,\n", i, abs(true_vec[i] - yfinial[i]) / abs(true_vec[i])); + } return 0; } diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index 5137119f1..1bae455f1 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -134,6 +134,10 @@ namespace Sundials retval = IDASStolerances(solver_, rtol, atol); checkOutput(retval, "IDASStolerances"); + /// \todo Need to set max number of steps based on user input! + retval = IDASetMaxNumSteps(solver_, 5000); + checkOutput(retval, "IDASetMaxNumSteps"); + // Tag differential variables std::vector& tag = model_->tag(); if (static_cast(tag.size()) == model_->size()) @@ -415,7 +419,7 @@ namespace Sundials checkOutput(retval, "IDASetUserDataB"); /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumStepsB(solver_, backwardID_, 2000); + retval = IDASetMaxNumStepsB(solver_, backwardID_, 200); checkOutput(retval, "IDASetMaxNumSteps"); // Set up linear solver From efc71f8f327eae60c7a8832fffee70213dd6f736 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Thu, 22 Feb 2024 14:11:25 -0500 Subject: [PATCH 29/44] Fixed the Jacobian in Microgrid Example --- .../DiscreteGenerator/DiscreteGenerator.cpp | 5 +++-- Examples/Microgrid/Microgrid.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp index 607ec5312..038a24ea2 100644 --- a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp +++ b/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp @@ -165,6 +165,7 @@ int DiscreteGenerator::evaluateResidual() template int DiscreteGenerator::evaluateJacobian() { + this->J_.zeroMatrix(); //Create dF/dy' std::vector rcordder(13); std::vector valsder(13, -1.0); @@ -186,7 +187,7 @@ int DiscreteGenerator::evaluateJacobian() ctemp = {3, 14, 15}; rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(1); - valtemp = { - sin(y_[3]) * y_[14] - cos(y_[3]) * y_[15], cos(y_[3]),sin(y_[3])}; + valtemp = { - sin(y_[3]) * y_[14] - cos(y_[3]) * y_[15], cos(y_[3]),-sin(y_[3])}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 2 @@ -194,7 +195,7 @@ int DiscreteGenerator::evaluateJacobian() ctemp = {3, 14, 15}; rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(2); - valtemp = { - cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15], -sin(y_[3]),cos(y_[3])}; + valtemp = { cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15], sin(y_[3]),cos(y_[3])}; this->J_.setValues(rtemp, ctemp, valtemp); //r = 3 diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp index 5f788080a..dddd4f291 100644 --- a/Examples/Microgrid/Microgrid.cpp +++ b/Examples/Microgrid/Microgrid.cpp @@ -21,7 +21,7 @@ int main(int argc, char const *argv[]) { double abstol = 1.0e-8; double reltol = 1.0e-8; - bool usejac = false; + bool usejac = true; //TODO:setup as named parameters //Create circuit model From 9f9907773765a71d0f0cbf3006da89aab6a2a092 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Thu, 22 Feb 2024 14:26:46 -0500 Subject: [PATCH 30/44] Added a max step size control for model objects --- Examples/Microgrid/Microgrid.cpp | 3 ++- ModelEvaluator.hpp | 1 + ModelEvaluatorImpl.hpp | 7 +++++++ PowerElectronicsModel.hpp | 7 +++++-- Solver/Dynamic/Ida.cpp | 5 ++++- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp index dddd4f291..acc8be386 100644 --- a/Examples/Microgrid/Microgrid.cpp +++ b/Examples/Microgrid/Microgrid.cpp @@ -21,11 +21,12 @@ int main(int argc, char const *argv[]) { double abstol = 1.0e-8; double reltol = 1.0e-8; + size_t max_step_amount = 3000; bool usejac = true; //TODO:setup as named parameters //Create circuit model - ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac); + ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac, max_step_amount); //Modeled after the problem in the paper double RN = 1.0e4; diff --git a/ModelEvaluator.hpp b/ModelEvaluator.hpp index 50c5e8b77..ad56fbd48 100644 --- a/ModelEvaluator.hpp +++ b/ModelEvaluator.hpp @@ -107,6 +107,7 @@ namespace ModelLib virtual IdxT size_opt() = 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; diff --git a/ModelEvaluatorImpl.hpp b/ModelEvaluatorImpl.hpp index 928d26f30..0f8969f0b 100644 --- a/ModelEvaluatorImpl.hpp +++ b/ModelEvaluatorImpl.hpp @@ -139,6 +139,11 @@ namespace ModelLib atol = atol_; } + virtual void setMaxSteps(IdxT& msa) const + { + msa = max_steps_; + } + std::vector& y() { return y_; @@ -306,6 +311,8 @@ namespace ModelLib real_type rtol_; real_type atol_; + IdxT max_steps_; + IdxT idc_; }; diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index 47efcc7f7..04508607f 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -50,18 +50,21 @@ class PowerElectronicsModel : public ModelEvaluatorImpl // Set system model tolerances as default rtol_ = 1e-4; atol_ = 1e-4; + this->max_steps_ = 2000; // By default use jacobian - usejac_ = true; + usejac_ = false; + } /** * @brief Constructor for the system model */ - PowerElectronicsModel(double rt, double at, bool ju) : ModelEvaluatorImpl(0, 0, 0) + PowerElectronicsModel(double rt=1e-4, double at=1e-4, bool ju=false, IdxT msa=2000) : ModelEvaluatorImpl(0, 0, 0) { // Set system model tolerances from input rtol_ = rt; atol_ = at; + this->max_steps_ = msa; // Can choose not to use jacobain usejac_ = ju; } diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index 1bae455f1..2be2913a9 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -133,9 +133,12 @@ namespace Sundials model_->setTolerances(rtol, atol); ///< \todo Function name should be "getTolerances"! retval = IDASStolerances(solver_, rtol, atol); checkOutput(retval, "IDASStolerances"); + + IdxT msa; + model_->setMaxSteps(msa); /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumSteps(solver_, 5000); + retval = IDASetMaxNumSteps(solver_, msa); checkOutput(retval, "IDASetMaxNumSteps"); // Tag differential variables From 60b328c5f91cf7f9749c7aba761d79f74e005bbe Mon Sep 17 00:00:00 2001 From: Reid Date: Tue, 12 Mar 2024 11:50:38 -0400 Subject: [PATCH 31/44] Update Solver/Dynamic/CMakeLists.txt Co-authored-by: pelesh --- Solver/Dynamic/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Solver/Dynamic/CMakeLists.txt b/Solver/Dynamic/CMakeLists.txt index 85c7ea920..ab38756c5 100644 --- a/Solver/Dynamic/CMakeLists.txt +++ b/Solver/Dynamic/CMakeLists.txt @@ -67,10 +67,6 @@ gridkit_add_library(solvers_dyn PUBLIC SUNDIALS::nvecserial PUBLIC SUNDIALS::idas PUBLIC SUNDIALS::sunlinsolklu - PUBLIC suitesparseconfig - PUBLIC klu - PUBLIC amd - PUBLIC colamd OUTPUT_NAME gridkit_solvers_dyn) From 6c223b3e6548c9774b32c314c3712030117ef4d6 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Tue, 12 Mar 2024 12:47:37 -0400 Subject: [PATCH 32/44] Updated name DiscreteGenerator -> DistributedGenerator - Updated name of generator - Some formatting updates --- .../PowerElectronicsComponents/CMakeLists.txt | 2 +- .../CMakeLists.txt | 2 +- .../DistributedGenerator.cpp} | 30 +- .../DistributedGenerator.hpp} | 10 +- .../MicrogridLine/MicrogridLine.hpp | 13 +- Examples/CMakeLists.txt | 2 +- .../CMakeLists.txt | 2 +- .../DGTest.cpp | 6 +- Examples/Microgrid/Microgrid.cpp | 14 +- ModelEvaluatorImpl.hpp | 99 +- PowerElectronicsModel.hpp | 532 ++++---- Solver/Dynamic/Ida.cpp | 1075 ++++++++--------- 12 files changed, 882 insertions(+), 905 deletions(-) rename ComponentLib/PowerElectronicsComponents/{DiscreteGenerator => DistributedGenerator}/CMakeLists.txt (76%) rename ComponentLib/PowerElectronicsComponents/{DiscreteGenerator/DiscreteGenerator.cpp => DistributedGenerator/DistributedGenerator.cpp} (92%) rename ComponentLib/PowerElectronicsComponents/{DiscreteGenerator/DiscreteGenerator.hpp => DistributedGenerator/DistributedGenerator.hpp} (87%) rename Examples/{DiscreteGeneratorTest => DistributedGeneratorTest}/CMakeLists.txt (77%) rename Examples/{DiscreteGeneratorTest => DistributedGeneratorTest}/DGTest.cpp (84%) diff --git a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt index 3fba4be7f..2cfe97bc2 100644 --- a/ComponentLib/PowerElectronicsComponents/CMakeLists.txt +++ b/ComponentLib/PowerElectronicsComponents/CMakeLists.txt @@ -7,7 +7,7 @@ add_subdirectory(Inductor) add_subdirectory(LinearTransformer) add_subdirectory(InductionMotor) add_subdirectory(SynchronousMachine) -add_subdirectory(DiscreteGenerator) +add_subdirectory(DistributedGenerator) add_subdirectory(TransmissionLine) add_subdirectory(MicrogridLoad) add_subdirectory(MicrogridLine) diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/CMakeLists.txt b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/CMakeLists.txt similarity index 76% rename from ComponentLib/PowerElectronicsComponents/DiscreteGenerator/CMakeLists.txt rename to ComponentLib/PowerElectronicsComponents/DistributedGenerator/CMakeLists.txt index c0ed2c7a9..22652f53b 100644 --- a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/CMakeLists.txt +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/CMakeLists.txt @@ -3,6 +3,6 @@ gridkit_add_library(powerelec_disgen SOURCES - DiscreteGenerator.cpp + DistributedGenerator.cpp OUTPUT_NAME gridkit_powerelec_disgen) \ No newline at end of file diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp similarity index 92% rename from ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp rename to ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp index 038a24ea2..d8d424b62 100644 --- a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.cpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp @@ -4,7 +4,7 @@ #include #include #include -#include "DiscreteGenerator.hpp" +#include "DistributedGenerator.hpp" namespace ModelLib { @@ -17,7 +17,7 @@ namespace ModelLib { */ template -DiscreteGenerator::DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm, bool reference_frame) +DistributedGenerator::DistributedGenerator(IdxT id, DistributedGeneratorParameters parm, bool reference_frame) : wb_(parm.wb), wc_(parm.wc), mp_(parm.mp), Vn_(parm.Vn), nq_(parm.nq), F_(parm.F), Kiv_(parm.Kiv), Kpv_(parm.Kpv), Kic_(parm.Kic), Kpc_(parm.Kpc), Cf_(parm.Cf), rLf_(parm.rLf), Lf_(parm.Lf), rLc_(parm.rLc), Lc_(parm.Lc), refframe_(reference_frame) { // internals [\delta_i, Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi] @@ -30,7 +30,7 @@ DiscreteGenerator::DiscreteGenerator(IdxT id, DiscreteGeneratorPa } template -DiscreteGenerator::~DiscreteGenerator() +DistributedGenerator::~DistributedGenerator() { } @@ -38,7 +38,7 @@ DiscreteGenerator::~DiscreteGenerator() * @brief allocate method computes sparsity pattern of the Jacobian. */ template -int DiscreteGenerator::allocate() +int DistributedGenerator::allocate() { this->y_.resize(this->size_); this->yp_.resize(this->size_); @@ -51,7 +51,7 @@ int DiscreteGenerator::allocate() * Initialization of the grid model */ template -int DiscreteGenerator::initialize() +int DistributedGenerator::initialize() { return 0; } @@ -60,7 +60,7 @@ int DiscreteGenerator::initialize() * \brief Identify differential variables */ template -int DiscreteGenerator::tagDifferentiable() +int DistributedGenerator::tagDifferentiable() { return 0; } @@ -71,7 +71,7 @@ int DiscreteGenerator::tagDifferentiable() * Must be connected to a PQ bus. */ template -int DiscreteGenerator::evaluateResidual() +int DistributedGenerator::evaluateResidual() { // ### Externals Componenets ### @@ -136,7 +136,7 @@ int DiscreteGenerator::evaluateResidual() } /** - * @brief Compute the jacobian of the DiscreteGenerator for iteration. dF/dy - \alpha dF/dy' + * @brief Compute the jacobian of the DistributedGenerator for iteration. dF/dy - \alpha dF/dy' * * The matrix dF/dy should be * @@ -163,7 +163,7 @@ int DiscreteGenerator::evaluateResidual() * @return int */ template -int DiscreteGenerator::evaluateJacobian() +int DistributedGenerator::evaluateJacobian() { this->J_.zeroMatrix(); //Create dF/dy' @@ -313,25 +313,25 @@ int DiscreteGenerator::evaluateJacobian() } template -int DiscreteGenerator::evaluateIntegrand() +int DistributedGenerator::evaluateIntegrand() { return 0; } template -int DiscreteGenerator::initializeAdjoint() +int DistributedGenerator::initializeAdjoint() { return 0; } template -int DiscreteGenerator::evaluateAdjointResidual() +int DistributedGenerator::evaluateAdjointResidual() { return 0; } template -int DiscreteGenerator::evaluateAdjointIntegrand() +int DistributedGenerator::evaluateAdjointIntegrand() { return 0; } @@ -340,8 +340,8 @@ int DiscreteGenerator::evaluateAdjointIntegrand() // Available template instantiations -template class DiscreteGenerator; -template class DiscreteGenerator; +template class DistributedGenerator; +template class DistributedGenerator; } //namespace ModelLib diff --git a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp similarity index 87% rename from ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp rename to ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp index bca984460..94b297a55 100644 --- a/ComponentLib/PowerElectronicsComponents/DiscreteGenerator/DiscreteGenerator.hpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp @@ -13,7 +13,7 @@ namespace ModelLib template class BaseBus; template - struct DiscreteGeneratorParameters + struct DistributedGeneratorParameters { ScalarT wb; ScalarT wc; @@ -37,11 +37,11 @@ namespace ModelLib namespace ModelLib { /*! - * @brief Declaration of a passive DiscreteGenerator class. + * @brief Declaration of a passive DistributedGenerator class. * */ template - class DiscreteGenerator : public CircuitComponent + class DistributedGenerator : public CircuitComponent { using CircuitComponent::size_; using CircuitComponent::nnz_; @@ -62,8 +62,8 @@ namespace ModelLib public: - DiscreteGenerator(IdxT id, DiscreteGeneratorParameters parm, bool reference_frame); - virtual ~DiscreteGenerator(); + DistributedGenerator(IdxT id, DistributedGeneratorParameters parm, bool reference_frame); + virtual ~DistributedGenerator(); int allocate(); int initialize(); diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp index 11ef78617..bc683045a 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp @@ -7,20 +7,19 @@ #include #include - namespace ModelLib { - template class BaseBus; + template + class BaseBus; } - namespace ModelLib { /*! * @brief Declaration of a passive MicrogridLine class. * */ - template + template class MicrogridLine : public CircuitComponent { using CircuitComponent::size_; @@ -40,7 +39,6 @@ namespace ModelLib using CircuitComponent::param_; using CircuitComponent::idc_; - public: MicrogridLine(IdxT id, ScalarT R, ScalarT L); virtual ~MicrogridLine(); @@ -54,12 +52,11 @@ namespace ModelLib int initializeAdjoint(); int evaluateAdjointResidual(); - //int evaluateAdjointJacobian(); + // int evaluateAdjointJacobian(); int evaluateAdjointIntegrand(); - private: - ScalarT R_; + ScalarT R_; ScalarT L_; }; } diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index 2c53fcc25..0965f5688 100644 --- a/Examples/CMakeLists.txt +++ b/Examples/CMakeLists.txt @@ -59,7 +59,7 @@ add_subdirectory(MatPowerTesting) add_subdirectory(RLCircuit) add_subdirectory(Microgrid) add_subdirectory(SparseTest) -add_subdirectory(DiscreteGeneratorTest) +add_subdirectory(DistributedGeneratorTest) if(TARGET SUNDIALS::kinsol) add_subdirectory(Grid3Bus) diff --git a/Examples/DiscreteGeneratorTest/CMakeLists.txt b/Examples/DistributedGeneratorTest/CMakeLists.txt similarity index 77% rename from Examples/DiscreteGeneratorTest/CMakeLists.txt rename to Examples/DistributedGeneratorTest/CMakeLists.txt index 9238fb346..d158e4c58 100644 --- a/Examples/DiscreteGeneratorTest/CMakeLists.txt +++ b/Examples/DistributedGeneratorTest/CMakeLists.txt @@ -8,5 +8,5 @@ target_link_libraries(dgtest GRIDKIT::powerelec_disgen GRIDKIT::powerelec_microload GRIDKIT::solvers_dyn) -add_test(NAME DiscreteGeneratorTest COMMAND $) +add_test(NAME DistributedGeneratorTest COMMAND $) install(TARGETS dgtest RUNTIME DESTINATION bin) diff --git a/Examples/DiscreteGeneratorTest/DGTest.cpp b/Examples/DistributedGeneratorTest/DGTest.cpp similarity index 84% rename from Examples/DiscreteGeneratorTest/DGTest.cpp rename to Examples/DistributedGeneratorTest/DGTest.cpp index d3dd2c68b..8d682e88c 100644 --- a/Examples/DiscreteGeneratorTest/DGTest.cpp +++ b/Examples/DistributedGeneratorTest/DGTest.cpp @@ -7,13 +7,13 @@ #include #include -#include +#include int main(int argc, char const *argv[]) { - ModelLib::DiscreteGeneratorParameters parms; + ModelLib::DistributedGeneratorParameters parms; //Parameters from MATLAB Microgrid code for first DG parms.wb = 2.0*M_PI*50.0; parms.wc = 31.41; @@ -31,7 +31,7 @@ int main(int argc, char const *argv[]) parms.rLc = 0.03; parms.Lc = 0.35e-3; - ModelLib::DiscreteGenerator *dg = new ModelLib::DiscreteGenerator(0, parms, true); + ModelLib::DistributedGenerator *dg = new ModelLib::DistributedGenerator(0, parms, true); std::vector t1(16,0.0); std::vector t2{0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,1.3,1.4,1.5}; diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp index acc8be386..b263495ad 100644 --- a/Examples/Microgrid/Microgrid.cpp +++ b/Examples/Microgrid/Microgrid.cpp @@ -7,7 +7,7 @@ #include -#include +#include #include #include #include @@ -33,7 +33,7 @@ int main(int argc, char const *argv[]) //DG Params - ModelLib::DiscreteGeneratorParameters parms1; + ModelLib::DistributedGeneratorParameters parms1; parms1.wb = 2.0*M_PI*50.0; parms1.wc = 31.41; parms1.mp = 9.4e-5; @@ -50,7 +50,7 @@ int main(int argc, char const *argv[]) parms1.rLc = 0.03; parms1.Lc = 0.35e-3; - ModelLib::DiscreteGeneratorParameters parms2; + ModelLib::DistributedGeneratorParameters parms2; //Parameters from MATLAB Microgrid code for first DG parms2.wb = 2.0*M_PI*50.0; parms2.wc = 31.41; @@ -103,7 +103,7 @@ int main(int argc, char const *argv[]) size_t indexv = 0; //dg 1 - ModelLib::DiscreteGenerator *dg1 = new ModelLib::DiscreteGenerator(0, parms1, true); + ModelLib::DistributedGenerator *dg1 = new ModelLib::DistributedGenerator(0, parms1, true); //ref motor dg1->setExternalConnectionNodes(0,vec_size_internals); //outputs @@ -121,7 +121,7 @@ int main(int argc, char const *argv[]) sysmodel->addComponent(dg1); //dg 2 - ModelLib::DiscreteGenerator *dg2 = new ModelLib::DiscreteGenerator(1, parms1, false); + ModelLib::DistributedGenerator *dg2 = new ModelLib::DistributedGenerator(1, parms1, false); //ref motor dg2->setExternalConnectionNodes(0,vec_size_internals); //outputs @@ -138,7 +138,7 @@ int main(int argc, char const *argv[]) //dg 3 - ModelLib::DiscreteGenerator *dg3 = new ModelLib::DiscreteGenerator(2, parms2, false); + ModelLib::DistributedGenerator *dg3 = new ModelLib::DistributedGenerator(2, parms2, false); //ref motor dg3->setExternalConnectionNodes(0,vec_size_internals); //outputs @@ -155,7 +155,7 @@ int main(int argc, char const *argv[]) //dg 4 - ModelLib::DiscreteGenerator *dg4 = new ModelLib::DiscreteGenerator(3, parms2, false); + ModelLib::DistributedGenerator *dg4 = new ModelLib::DistributedGenerator(3, parms2, false); //ref motor dg4->setExternalConnectionNodes(0,vec_size_internals); //outputs diff --git a/ModelEvaluatorImpl.hpp b/ModelEvaluatorImpl.hpp index 0f8969f0b..3e9a4cef6 100644 --- a/ModelEvaluatorImpl.hpp +++ b/ModelEvaluatorImpl.hpp @@ -77,27 +77,28 @@ namespace ModelLib typedef typename ModelEvaluator::real_type real_type; ModelEvaluatorImpl() - : size_(0), - size_quad_(0), - size_opt_(0) - {} + : size_(0), + size_quad_(0), + size_opt_(0) + { + } ModelEvaluatorImpl(IdxT size, IdxT size_quad, IdxT size_opt) - : size_(size), - size_quad_(size_quad), - size_opt_(size_opt), - y_(size_), - yp_(size_), - f_(size_), - g_(size_quad_), - yB_(size_), - ypB_(size_), - fB_(size_), - gB_(size_opt_), - J_(COO_Matrix()), - param_(size_opt_), - param_up_(size_opt_), - param_lo_(size_opt_) + : size_(size), + size_quad_(size_quad), + size_opt_(size_opt), + y_(size_), + yp_(size_), + f_(size_), + g_(size_quad_), + yB_(size_), + ypB_(size_), + fB_(size_), + gB_(size_opt_), + J_(COO_Matrix()), + param_(size_opt_), + param_up_(size_opt_), + param_lo_(size_opt_) { } @@ -133,143 +134,143 @@ namespace ModelLib // std::cout << "updateTime: t = " << time_ << "\n"; // } - virtual void setTolerances(real_type& rtol, real_type& atol) const + virtual void setTolerances(real_type &rtol, real_type &atol) const { rtol = rtol_; atol = atol_; } - virtual void setMaxSteps(IdxT& msa) const + virtual void setMaxSteps(IdxT &msa) const { msa = max_steps_; } - std::vector& y() + std::vector &y() { return y_; } - const std::vector& y() const + const std::vector &y() const { return y_; } - std::vector& yp() + std::vector &yp() { return yp_; } - const std::vector& yp() const + const std::vector &yp() const { return yp_; } - std::vector& tag() + std::vector &tag() { return tag_; } - const std::vector& tag() const + const std::vector &tag() const { return tag_; } - std::vector& yB() + std::vector &yB() { return yB_; } - const std::vector& yB() const + const std::vector &yB() const { return yB_; } - std::vector& ypB() + std::vector &ypB() { return ypB_; } - const std::vector& ypB() const + const std::vector &ypB() const { return ypB_; } - std::vector& param() + std::vector ¶m() { return param_; } - const std::vector& param() const + const std::vector ¶m() const { return param_; } - std::vector& param_up() + std::vector ¶m_up() { return param_up_; } - const std::vector& param_up() const + const std::vector ¶m_up() const { return param_up_; } - std::vector& param_lo() + std::vector ¶m_lo() { return param_lo_; } - const std::vector& param_lo() const + const std::vector ¶m_lo() const { return param_lo_; } - std::vector& getResidual() + std::vector &getResidual() { return f_; } - const std::vector& getResidual() const + const std::vector &getResidual() const { return f_; } - COO_Matrix& getJacobian() + COO_Matrix &getJacobian() { return J_; } - const COO_Matrix& getJacobian() const + const COO_Matrix &getJacobian() const { return J_; } - std::vector& getIntegrand() + std::vector &getIntegrand() { return g_; } - const std::vector& getIntegrand() const + const std::vector &getIntegrand() const { return g_; } - std::vector& getAdjointResidual() + std::vector &getAdjointResidual() { return fB_; } - const std::vector& getAdjointResidual() const + const std::vector &getAdjointResidual() const { return fB_; } - std::vector& getAdjointIntegrand() + std::vector &getAdjointIntegrand() { return gB_; } - const std::vector& getAdjointIntegrand() const + const std::vector &getAdjointIntegrand() const { return gB_; } @@ -280,8 +281,6 @@ namespace ModelLib return idc_; } - - protected: IdxT size_; IdxT nnz_; @@ -314,10 +313,8 @@ namespace ModelLib IdxT max_steps_; IdxT idc_; - }; - } // namespace ModelLib #endif // _MODEL_EVALUATOR_IMPL_HPP_ \ No newline at end of file diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index 04508607f..d74b92cf0 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -14,318 +14,316 @@ namespace ModelLib { -template -class PowerElectronicsModel : public ModelEvaluatorImpl -{ - typedef CircuitComponent component_type; - - using ModelEvaluatorImpl::size_; - // using ModelEvaluatorImpl::size_quad_; - // using ModelEvaluatorImpl::size_opt_; - using ModelEvaluatorImpl::nnz_; - using ModelEvaluatorImpl::time_; - using ModelEvaluatorImpl::alpha_; - using ModelEvaluatorImpl::y_; - using ModelEvaluatorImpl::yp_; - // using ModelEvaluatorImpl::yB_; - // using ModelEvaluatorImpl::ypB_; - // using ModelEvaluatorImpl::tag_; - using ModelEvaluatorImpl::f_; - // using ModelEvaluatorImpl::fB_; - // using ModelEvaluatorImpl::g_; - // using ModelEvaluatorImpl::gB_; - using ModelEvaluatorImpl::J_; - using ModelEvaluatorImpl::rtol_; - using ModelEvaluatorImpl::atol_; - // using ModelEvaluatorImpl::param_; - // using ModelEvaluatorImpl::param_up_; - // using ModelEvaluatorImpl::param_lo_; - -public: - /** - * @brief Default constructor for the system model - */ - PowerElectronicsModel() : ModelEvaluatorImpl(0, 0, 0) - { - // Set system model tolerances as default - rtol_ = 1e-4; - atol_ = 1e-4; - this->max_steps_ = 2000; - // By default use jacobian - usejac_ = false; - - } - - /** - * @brief Constructor for the system model - */ - PowerElectronicsModel(double rt=1e-4, double at=1e-4, bool ju=false, IdxT msa=2000) : ModelEvaluatorImpl(0, 0, 0) - { - // Set system model tolerances from input - rtol_ = rt; - atol_ = at; - this->max_steps_ = msa; - // Can choose not to use jacobain - usejac_ = ju; - } - - /** - * @brief Destructor for the system model - */ - virtual ~PowerElectronicsModel() - { - for (auto comp : this->components_) delete comp; - } - - /** - * @brief allocator default - * - * @todo this should throw an exception as no allocation without a graph is allowed. Or needs to be removed from the base class - * - * @return int - */ - int allocate() - { - - return 1; - } - - /** - * @brief Will check if each component has jacobian avalible. If one doesn't then jacobain is false. - * - * - * @return true - * @return false - */ - bool hasJacobian() + template + class PowerElectronicsModel : public ModelEvaluatorImpl { - if (!this->usejac_) return false; - - for(const auto& component : components_) + typedef CircuitComponent component_type; + + using ModelEvaluatorImpl::size_; + // using ModelEvaluatorImpl::size_quad_; + // using ModelEvaluatorImpl::size_opt_; + using ModelEvaluatorImpl::nnz_; + using ModelEvaluatorImpl::time_; + using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::yp_; + // using ModelEvaluatorImpl::yB_; + // using ModelEvaluatorImpl::ypB_; + // using ModelEvaluatorImpl::tag_; + using ModelEvaluatorImpl::f_; + // using ModelEvaluatorImpl::fB_; + // using ModelEvaluatorImpl::g_; + // using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::J_; + using ModelEvaluatorImpl::rtol_; + using ModelEvaluatorImpl::atol_; + // using ModelEvaluatorImpl::param_; + // using ModelEvaluatorImpl::param_up_; + // using ModelEvaluatorImpl::param_lo_; + + public: + /** + * @brief Default constructor for the system model + */ + PowerElectronicsModel() : ModelEvaluatorImpl(0, 0, 0) { - if (!component->hasJacobian()) - { + // Set system model tolerances as default + rtol_ = 1e-4; + atol_ = 1e-4; + this->max_steps_ = 2000; + // By default use jacobian + usejac_ = false; + } + + /** + * @brief Constructor for the system model + */ + PowerElectronicsModel(double rt = 1e-4, double at = 1e-4, bool ju = false, IdxT msa = 2000) : ModelEvaluatorImpl(0, 0, 0) + { + // Set system model tolerances from input + rtol_ = rt; + atol_ = at; + this->max_steps_ = msa; + // Can choose not to use jacobain + usejac_ = ju; + } + + /** + * @brief Destructor for the system model + */ + virtual ~PowerElectronicsModel() + { + for (auto comp : this->components_) + delete comp; + } + + /** + * @brief allocator default + * + * @todo this should throw an exception as no allocation without a graph is allowed. Or needs to be removed from the base class + * + * @return int + */ + int allocate() + { + + return 1; + } + + /** + * @brief Will check if each component has jacobian avalible. If one doesn't then jacobain is false. + * + * + * @return true + * @return false + */ + bool hasJacobian() + { + if (!this->usejac_) return false; + + for (const auto &component : components_) + { + if (!component->hasJacobian()) + { + return false; + } } - + return true; } - return true; - } - - /** - * @brief Allocate the vector data with size amount - * @todo Add capability to go through component model connection to get the size of the actual vector - * - * @param s - * @return int - */ - int allocate(IdxT s) - { - // Allocate all components - this->size_ = s; - for(const auto& component : components_) + /** + * @brief Allocate the vector data with size amount + * @todo Add capability to go through component model connection to get the size of the actual vector + * + * @param s + * @return int + */ + int allocate(IdxT s) { - component->allocate(); - } - // Allocate global vectors - y_.resize(size_); - yp_.resize(size_); - f_.resize(size_); + // Allocate all components + this->size_ = s; + for (const auto &component : components_) + { + component->allocate(); + } - return 0; - } + // Allocate global vectors + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); - /** - * @brief Set intial y and y' of each component - * - * @return int - */ - int initialize() - { + return 0; + } - // Initialize components - for(const auto& component : components_) + /** + * @brief Set intial y and y' of each component + * + * @return int + */ + int initialize() { - component->initialize(); + + // Initialize components + for (const auto &component : components_) + { + component->initialize(); + } + this->distributeVectors(); + + return 0; } - this->distributeVectors(); - - return 0; - } - - /** - * @brief Distribute y and y' to each component based of node connection graph - * - * @return int - */ - int distributeVectors() - { - for(const auto& component : components_) + + /** + * @brief Distribute y and y' to each component based of node connection graph + * + * @return int + */ + int distributeVectors() { - for(IdxT j=0; jsize(); ++j) + for (const auto &component : components_) { - if(component->getNodeConnection(j) != -1) + for (IdxT j = 0; j < component->size(); ++j) { - component->y()[j] = y_[component->getNodeConnection(j)]; - component->yp()[j] = yp_[component->getNodeConnection(j)]; - } - else - { - component->y()[j] = 0.0; - component->yp()[j] = 0.0; + if (component->getNodeConnection(j) != -1) + { + component->y()[j] = y_[component->getNodeConnection(j)]; + component->yp()[j] = yp_[component->getNodeConnection(j)]; + } + else + { + component->y()[j] = 0.0; + component->yp()[j] = 0.0; + } } } + return 0; } - return 0; - } - int tagDifferentiable() - { - return 0; - } - - /** - * @brief Evaluate Residuals at each component then collect them - * - * @return int - */ - int evaluateResidual() - { - for (IdxT i = 0; i < this->f_.size(); i++) + int tagDifferentiable() { - f_[i] = 0.0; + return 0; } - - this->distributeVectors(); - // Update system residual vector - - for(const auto& component : components_) + /** + * @brief Evaluate Residuals at each component then collect them + * + * @return int + */ + int evaluateResidual() { - //TODO:check return type - component->evaluateResidual(); - for(IdxT j=0; jsize(); ++j) + for (IdxT i = 0; i < this->f_.size(); i++) + { + f_[i] = 0.0; + } + + this->distributeVectors(); + + // Update system residual vector + + for (const auto &component : components_) { - //@todo should do a different grounding check - if (component->getNodeConnection(j) != -1) + // TODO:check return type + component->evaluateResidual(); + for (IdxT j = 0; j < component->size(); ++j) { - f_[component->getNodeConnection(j)] += component->getResidual()[j]; + //@todo should do a different grounding check + if (component->getNodeConnection(j) != -1) + { + f_[component->getNodeConnection(j)] += component->getResidual()[j]; + } } - } + + return 0; } - return 0; - } - - /** - * @brief Creates the Sparse COO Jacobian representing \alpha dF/dy' + dF/dy - * - * @return int - */ - int evaluateJacobian() - { - this->J_.zeroMatrix(); - this->distributeVectors(); - - //Evaluate component jacs - for(const auto& component : components_) + /** + * @brief Creates the Sparse COO Jacobian representing \alpha dF/dy' + dF/dy + * + * @return int + */ + int evaluateJacobian() { - component->evaluateJacobian(); - - //get references to local jacobain - std::tuple&, std::vector&, std::vector&> tpm = component->getJacobian().getEntries(); - const auto& [r, c, v] = tpm; + this->J_.zeroMatrix(); + this->distributeVectors(); - //Create copies of data to handle groundings - std::vector rgr; - std::vector cgr; - std::vector vgr; - for (IdxT i = 0; i < static_cast(r.size()); i++) + // Evaluate component jacs + for (const auto &component : components_) { - if (component->getNodeConnection(r[i]) != -1 && component->getNodeConnection(c[i]) != -1) + component->evaluateJacobian(); + + // get references to local jacobain + std::tuple &, std::vector &, std::vector &> tpm = component->getJacobian().getEntries(); + const auto &[r, c, v] = tpm; + + // Create copies of data to handle groundings + std::vector rgr; + std::vector cgr; + std::vector vgr; + for (IdxT i = 0; i < static_cast(r.size()); i++) { - rgr.push_back(component->getNodeConnection(r[i])); - cgr.push_back(component->getNodeConnection(c[i])); - vgr.push_back(v[i]); + if (component->getNodeConnection(r[i]) != -1 && component->getNodeConnection(c[i]) != -1) + { + rgr.push_back(component->getNodeConnection(r[i])); + cgr.push_back(component->getNodeConnection(c[i])); + vgr.push_back(v[i]); + } } + + // AXPY to Global Jacobian + this->J_.AXPY(1.0, rgr, cgr, vgr); } - - //AXPY to Global Jacobian - this->J_.AXPY(1.0, rgr, cgr, vgr); + + return 0; } - - return 0; - } - - /** - * @brief Evaluate integrands for the system quadratures. - */ - int evaluateIntegrand() - { - return 0; - } + /** + * @brief Evaluate integrands for the system quadratures. + */ + int evaluateIntegrand() + { - /** - * @brief Initialize system adjoint. - * - * Updates variables and optimization parameters, then initializes - * adjoints locally and copies them to the system adjoint vector. - */ - int initializeAdjoint() - { - return 0; - } - - /** - * @brief Compute adjoint residual for the system model. - * - * - */ - int evaluateAdjointResidual() - { - return 0; - } + return 0; + } + /** + * @brief Initialize system adjoint. + * + * Updates variables and optimization parameters, then initializes + * adjoints locally and copies them to the system adjoint vector. + */ + int initializeAdjoint() + { + return 0; + } - /** - * @brief Evaluate adjoint integrand for the system model. - * - * - */ - int evaluateAdjointIntegrand() - { - return 0; - } - - /** - * @brief Distribute time and time scaling for each component - * - * @param t - * @param a - */ - void updateTime(ScalarT t, ScalarT a) - { - for(const auto& component : components_) + /** + * @brief Compute adjoint residual for the system model. + * + * + */ + int evaluateAdjointResidual() { - component->updateTime(t, a); + return 0; } - this->time_ = t; - this->alpha_ = a; - } - void addComponent(component_type* component) - { - this->components_.push_back(component); - } + /** + * @brief Evaluate adjoint integrand for the system model. + * + * + */ + int evaluateAdjointIntegrand() + { + return 0; + } + + /** + * @brief Distribute time and time scaling for each component + * + * @param t + * @param a + */ + void updateTime(ScalarT t, ScalarT a) + { + for (const auto &component : components_) + { + component->updateTime(t, a); + } + this->time_ = t; + this->alpha_ = a; + } + + void addComponent(component_type *component) + { + this->components_.push_back(component); + } -private: - std::vector components_; - bool usejac_; + private: + std::vector components_; + bool usejac_; -}; // class PowerElectronicsModel + }; // class PowerElectronicsModel } // namespace ModelLib diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index 2be2913a9..e7b144610 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -57,718 +57,703 @@ * */ - #include #include -#include /* access to IDADls interface */ +#include /* access to IDADls interface */ #include -//Sundials Sparse KLU +// Sundials Sparse KLU #include -#include +#include #include "ModelEvaluator.hpp" #include "Ida.hpp" - namespace AnalysisManager { -namespace Sundials -{ - - template - Ida::Ida(ModelLib::ModelEvaluator* model) : DynamicSolver(model) + namespace Sundials { - int retval = 0; - // Create the SUNDIALS context that all SUNDIALS objects require - retval = SUNContext_Create(NULL, &context_); - checkOutput(retval, "SUNContext"); - solver_ = IDACreate(context_); - tag_ = NULL; - } + template + Ida::Ida(ModelLib::ModelEvaluator *model) : DynamicSolver(model) + { + int retval = 0; - template - Ida::~Ida() - { - } + // Create the SUNDIALS context that all SUNDIALS objects require + retval = SUNContext_Create(NULL, &context_); + checkOutput(retval, "SUNContext"); + solver_ = IDACreate(context_); + tag_ = NULL; + } - template - int Ida::configureSimulation() - { - int retval = 0; + template + Ida::~Ida() + { + } - // Allocate solution vectors - yy_ = N_VNew_Serial(model_->size(), context_); - checkAllocation((void*) yy_, "N_VNew_Serial"); - yp_ = N_VClone(yy_); - checkAllocation((void*) yp_, "N_VClone"); + template + int Ida::configureSimulation() + { + int retval = 0; - //get intial conditions - this->getDefaultInitialCondition(); + // Allocate solution vectors + yy_ = N_VNew_Serial(model_->size(), context_); + checkAllocation((void *)yy_, "N_VNew_Serial"); + yp_ = N_VClone(yy_); + checkAllocation((void *)yp_, "N_VClone"); - // Create vectors to store restart initial condition - yy0_ = N_VClone(yy_); - checkAllocation((void*) yy0_, "N_VClone"); - yp0_ = N_VClone(yy_); - checkAllocation((void*) yp0_, "N_VClone"); + // get intial conditions + this->getDefaultInitialCondition(); - // Dummy initial time; will be overridden. - const realtype t0 = RCONST(0.0); + // Create vectors to store restart initial condition + yy0_ = N_VClone(yy_); + checkAllocation((void *)yy0_, "N_VClone"); + yp0_ = N_VClone(yy_); + checkAllocation((void *)yp0_, "N_VClone"); - // Allocate and initialize IDA workspace - retval = IDAInit(solver_, this->Residual, t0, yy_, yp_); - checkOutput(retval, "IDAInit"); + // Dummy initial time; will be overridden. + const realtype t0 = RCONST(0.0); - // Set pointer to model data - retval = IDASetUserData(solver_, model_); - checkOutput(retval, "IDASetUserData"); + // Allocate and initialize IDA workspace + retval = IDAInit(solver_, this->Residual, t0, yy_, yp_); + checkOutput(retval, "IDAInit"); - // Set tolerances - realtype rtol; - realtype atol; + // Set pointer to model data + retval = IDASetUserData(solver_, model_); + checkOutput(retval, "IDASetUserData"); - model_->setTolerances(rtol, atol); ///< \todo Function name should be "getTolerances"! - retval = IDASStolerances(solver_, rtol, atol); - checkOutput(retval, "IDASStolerances"); - - IdxT msa; - model_->setMaxSteps(msa); + // Set tolerances + realtype rtol; + realtype atol; - /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumSteps(solver_, msa); - checkOutput(retval, "IDASetMaxNumSteps"); + model_->setTolerances(rtol, atol); ///< \todo Function name should be "getTolerances"! + retval = IDASStolerances(solver_, rtol, atol); + checkOutput(retval, "IDASStolerances"); - // Tag differential variables - std::vector& tag = model_->tag(); - if (static_cast(tag.size()) == model_->size()) - { - tag_ = N_VClone(yy_); - checkAllocation((void*) tag_, "N_VClone"); - model_->tagDifferentiable(); - copyVec(tag, tag_); + IdxT msa; + model_->setMaxSteps(msa); - retval = IDASetId(solver_, tag_); - checkOutput(retval, "IDASetId"); - retval = IDASetSuppressAlg(solver_, SUNTRUE); - checkOutput(retval, "IDASetSuppressAlg"); - } + /// \todo Need to set max number of steps based on user input! + retval = IDASetMaxNumSteps(solver_, msa); + checkOutput(retval, "IDASetMaxNumSteps"); - // Set up linear solver - this->configureLinearSolver(); + // Tag differential variables + std::vector &tag = model_->tag(); + if (static_cast(tag.size()) == model_->size()) + { + tag_ = N_VClone(yy_); + checkAllocation((void *)tag_, "N_VClone"); + model_->tagDifferentiable(); + copyVec(tag, tag_); + + retval = IDASetId(solver_, tag_); + checkOutput(retval, "IDASetId"); + retval = IDASetSuppressAlg(solver_, SUNTRUE); + checkOutput(retval, "IDASetSuppressAlg"); + } - return retval; - } + // Set up linear solver + this->configureLinearSolver(); - template - int Ida::configureLinearSolver() - { - int retval = 0; - if (model_->hasJacobian()) + return retval; + } + + template + int Ida::configureLinearSolver() { - JacobianMat_ = SUNSparseMatrix(model_->size(), model_->size(), model_->size() * model_->size(), CSR_MAT, context_); - checkAllocation((void*) JacobianMat_, "SUNSparseMatrix"); + int retval = 0; + //Setup KLU for when Jacobian is needed + if (model_->hasJacobian()) + { + JacobianMat_ = SUNSparseMatrix(model_->size(), model_->size(), model_->size() * model_->size(), CSR_MAT, context_); + checkAllocation((void *)JacobianMat_, "SUNSparseMatrix"); - linearSolver_ = SUNLinSol_KLU(yy_, JacobianMat_, context_); - checkAllocation((void*) linearSolver_, "SUNLinSol_KLU"); + linearSolver_ = SUNLinSol_KLU(yy_, JacobianMat_, context_); + checkAllocation((void *)linearSolver_, "SUNLinSol_KLU"); - retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "IDASetLinearSolver"); + retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "IDASetLinearSolver"); - retval = IDASetJacFn(solver_, this->Jac); - checkOutput(retval, "IDASetJacFn"); - } - else - { - JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); + retval = IDASetJacFn(solver_, this->Jac); + checkOutput(retval, "IDASetJacFn"); + } + else + { + JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void *)JacobianMat_, "SUNDenseMatrix"); - linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); - checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); + linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); + checkAllocation((void *)linearSolver_, "SUNLinSol_Dense"); - retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "IDASetLinearSolver"); + retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "IDASetLinearSolver"); + } + return retval; } - return retval; - } + template + int Ida::getDefaultInitialCondition() + { + model_->initialize(); - template - int Ida::getDefaultInitialCondition() - { - model_->initialize(); + copyVec(model_->y(), yy_); + copyVec(model_->yp(), yp_); - copyVec(model_->y(), yy_); - copyVec(model_->yp(), yp_); + return 0; + } - return 0; - } + template + int Ida::setIntegrationTime(real_type t_init, real_type t_final, int nout) + { + t_init_ = t_init; + t_final_ = t_final; + nout_ = nout; + return 0; + } - template - int Ida::setIntegrationTime(real_type t_init, real_type t_final, int nout) - { - t_init_ = t_init; - t_final_ = t_final; - nout_ = nout; - return 0; - } - - template - int Ida::initializeSimulation(real_type t0, bool findConsistent) - { - int retval = 0; + template + int Ida::initializeSimulation(real_type t0, bool findConsistent) + { + int retval = 0; - // Need to reinitialize IDA to set to get correct initial conditions - retval = IDAReInit(solver_, t0, yy_, yp_); - checkOutput(retval, "IDAReInit"); + // Need to reinitialize IDA to set to get correct initial conditions + retval = IDAReInit(solver_, t0, yy_, yp_); + checkOutput(retval, "IDAReInit"); - // Find a consistent set of initial conditions for DAE - if (findConsistent) - { - int initType = IDA_Y_INIT; + // Find a consistent set of initial conditions for DAE + if (findConsistent) + { + int initType = IDA_Y_INIT; - if (tag_) - initType = IDA_YA_YDP_INIT; + if (tag_) + initType = IDA_YA_YDP_INIT; - retval = IDACalcIC(solver_, initType, 0.1); - checkOutput(retval, "IDACalcIC"); - } + retval = IDACalcIC(solver_, initType, 0.1); + checkOutput(retval, "IDACalcIC"); + } - return retval; - } + return retval; + } - template - int Ida::runSimulation(real_type tf, int nout) - { - int retval = 0; - int iout = 0; - real_type tret; - real_type dt = tf/nout; - real_type tout = dt; - - /* In loop, call IDASolve, print results, and test for error. - * Break out of loop when NOUT preset output times have been reached. */ - //printOutput(0.0); - while(nout > iout) - { - retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); - checkOutput(retval, "IDASolve"); - //printOutput(tout); - - if (retval == IDA_SUCCESS) + template + int Ida::runSimulation(real_type tf, int nout) + { + int retval = 0; + int iout = 0; + real_type tret; + real_type dt = tf / nout; + real_type tout = dt; + + /* In loop, call IDASolve, print results, and test for error. + * Break out of loop when NOUT preset output times have been reached. */ + // printOutput(0.0); + while (nout > iout) { - ++iout; - tout += dt; + retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); + checkOutput(retval, "IDASolve"); + // printOutput(tout); + + if (retval == IDA_SUCCESS) + { + ++iout; + tout += dt; + } } + // std::cout << "\n"; + return retval; } - //std::cout << "\n"; - return retval; - } - - template - int Ida::deleteSimulation() - { - IDAFree(&solver_); - SUNLinSolFree(linearSolver_); - N_VDestroy(yy_); - N_VDestroy(yp_); - return 0; - } - - - template - int Ida::configureQuadrature() - { - int retval = 0; - // Create and initialize quadratures - q_ = N_VNew_Serial(model_->size_quad(), context_); - checkAllocation((void*) q_, "N_VNew_Serial"); + template + int Ida::deleteSimulation() + { + IDAFree(&solver_); + SUNLinSolFree(linearSolver_); + N_VDestroy(yy_); + N_VDestroy(yp_); + return 0; + } - // Set integrand function and allocate quadrature workspace - retval = IDAQuadInit(solver_, this->Integrand, q_); - checkOutput(retval, "IDAQuadInit"); + template + int Ida::configureQuadrature() + { + int retval = 0; - // Set tolerances and error control for quadratures - real_type rtol, atol; - model_->setTolerances(rtol, atol); + // Create and initialize quadratures + q_ = N_VNew_Serial(model_->size_quad(), context_); + checkAllocation((void *)q_, "N_VNew_Serial"); - // Set tolerances for quadrature stricter than for integration - retval = IDAQuadSStolerances(solver_, rtol*0.1, atol*0.1); - checkOutput(retval, "IDAQuadSStolerances"); + // Set integrand function and allocate quadrature workspace + retval = IDAQuadInit(solver_, this->Integrand, q_); + checkOutput(retval, "IDAQuadInit"); - // Include quadrature in eror checking - retval = IDASetQuadErrCon(solver_, SUNTRUE); - checkOutput(retval, "IDASetQuadErrCon"); + // Set tolerances and error control for quadratures + real_type rtol, atol; + model_->setTolerances(rtol, atol); - return retval; - } + // Set tolerances for quadrature stricter than for integration + retval = IDAQuadSStolerances(solver_, rtol * 0.1, atol * 0.1); + checkOutput(retval, "IDAQuadSStolerances"); + // Include quadrature in eror checking + retval = IDASetQuadErrCon(solver_, SUNTRUE); + checkOutput(retval, "IDASetQuadErrCon"); - template - int Ida::initializeQuadrature() - { - int retval = 0; - - // Set all quadratures to zero - N_VConst(RCONST(0.0), q_); + return retval; + } - // Initialize quadratures - retval = IDAQuadReInit(solver_, q_); - checkOutput(retval, "IDAQuadInit"); + template + int Ida::initializeQuadrature() + { + int retval = 0; - return retval; - } + // Set all quadratures to zero + N_VConst(RCONST(0.0), q_); + // Initialize quadratures + retval = IDAQuadReInit(solver_, q_); + checkOutput(retval, "IDAQuadInit"); - template - int Ida::runSimulationQuadrature(real_type tf, int nout) - { - int retval = 0; - real_type tret; - - //std::cout << "Forward integration for initial value problem ... \n"; + return retval; + } - real_type dt = tf/nout; - real_type tout = dt; - //printOutput(0.0); - //printSpecial(0.0, yy_); - for(int i = 0; i < nout; ++i) + template + int Ida::runSimulationQuadrature(real_type tf, int nout) { - retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); - checkOutput(retval, "IDASolve"); - //printSpecial(tout, yy_); - //printOutput(tout); + int retval = 0; + real_type tret; + + // std::cout << "Forward integration for initial value problem ... \n"; - if (retval == IDA_SUCCESS) + real_type dt = tf / nout; + real_type tout = dt; + // printOutput(0.0); + // printSpecial(0.0, yy_); + for (int i = 0; i < nout; ++i) { - tout += dt; + retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); + checkOutput(retval, "IDASolve"); + // printSpecial(tout, yy_); + // printOutput(tout); + + if (retval == IDA_SUCCESS) + { + tout += dt; + } + + retval = IDAGetQuad(solver_, &tret, q_); + checkOutput(retval, "IDAGetQuad"); } - retval = IDAGetQuad(solver_, &tret, q_); - checkOutput(retval, "IDAGetQuad"); + return retval; } - return retval; - } - - - template - int Ida::deleteQuadrature() - { - IDAQuadFree(solver_); - N_VDestroy(q_); - - return 0; - } - + template + int Ida::deleteQuadrature() + { + IDAQuadFree(solver_); + N_VDestroy(q_); - template - int Ida::configureAdjoint() - { - // Allocate adjoint vector, derivatives and quadrature - yyB_ = N_VNew_Serial(model_->size(), context_); - checkAllocation((void*) yyB_, "N_VNew_Serial"); + return 0; + } - ypB_ = N_VClone(yyB_); - checkAllocation((void*) ypB_, "N_VClone"); + template + int Ida::configureAdjoint() + { + // Allocate adjoint vector, derivatives and quadrature + yyB_ = N_VNew_Serial(model_->size(), context_); + checkAllocation((void *)yyB_, "N_VNew_Serial"); - qB_ = N_VNew_Serial(model_->size_opt(), context_); - checkAllocation((void*) qB_, "N_VNew_Serial"); + ypB_ = N_VClone(yyB_); + checkAllocation((void *)ypB_, "N_VClone"); - return 0; - } + qB_ = N_VNew_Serial(model_->size_opt(), context_); + checkAllocation((void *)qB_, "N_VNew_Serial"); - template - int Ida::initializeAdjoint(IdxT steps) - { - int retval = 0; + return 0; + } - // Create adjoint workspace - retval = IDAAdjInit(solver_, steps, IDA_HERMITE); - checkOutput(retval, "IDAAdjInit"); + template + int Ida::initializeAdjoint(IdxT steps) + { + int retval = 0; - return retval; - } + // Create adjoint workspace + retval = IDAAdjInit(solver_, steps, IDA_HERMITE); + checkOutput(retval, "IDAAdjInit"); - template - int Ida::initializeBackwardSimulation(real_type tf) - { - int retval = 0; - realtype rtol; - realtype atol; + return retval; + } - model_->initializeAdjoint(); + template + int Ida::initializeBackwardSimulation(real_type tf) + { + int retval = 0; + realtype rtol; + realtype atol; - copyVec(model_->yB(), yyB_); - copyVec(model_->ypB(), ypB_); - N_VConst(0.0, qB_); + model_->initializeAdjoint(); - retval = IDACreateB(solver_, &backwardID_); - checkOutput(retval, "IDACreateB"); + copyVec(model_->yB(), yyB_); + copyVec(model_->ypB(), ypB_); + N_VConst(0.0, qB_); - // IDAInitB must be called after forward simulation run. - retval = IDAInitB(solver_, backwardID_, this->adjointResidual, tf, yyB_, ypB_); - checkOutput(retval, "IDAInitB"); + retval = IDACreateB(solver_, &backwardID_); + checkOutput(retval, "IDACreateB"); - model_->setTolerances(rtol, atol); - retval = IDASStolerancesB(solver_, backwardID_, rtol, atol); - checkOutput(retval, "IDASStolerancesB"); + // IDAInitB must be called after forward simulation run. + retval = IDAInitB(solver_, backwardID_, this->adjointResidual, tf, yyB_, ypB_); + checkOutput(retval, "IDAInitB"); - retval = IDASetUserDataB(solver_, backwardID_, model_); - checkOutput(retval, "IDASetUserDataB"); + model_->setTolerances(rtol, atol); + retval = IDASStolerancesB(solver_, backwardID_, rtol, atol); + checkOutput(retval, "IDASStolerancesB"); - /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumStepsB(solver_, backwardID_, 200); - checkOutput(retval, "IDASetMaxNumSteps"); + retval = IDASetUserDataB(solver_, backwardID_, model_); + checkOutput(retval, "IDASetUserDataB"); - // Set up linear solver - JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMatB_, "SUNDenseMatrix"); + /// \todo Need to set max number of steps based on user input! + retval = IDASetMaxNumStepsB(solver_, backwardID_, 200); + checkOutput(retval, "IDASetMaxNumSteps"); - linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); - checkAllocation((void*) linearSolverB_, "SUNLinSol_Dense"); + // Set up linear solver + JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void *)JacobianMatB_, "SUNDenseMatrix"); - retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); - checkOutput(retval, "IDASetLinearSolverB"); + linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); + checkAllocation((void *)linearSolverB_, "SUNLinSol_Dense"); + retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); + checkOutput(retval, "IDASetLinearSolverB"); - // Also reinitialize quadratures. - retval = IDAQuadInitB(solver_, backwardID_, this->adjointIntegrand, qB_); - checkOutput(retval, "IDAQuadInitB"); + // Also reinitialize quadratures. + retval = IDAQuadInitB(solver_, backwardID_, this->adjointIntegrand, qB_); + checkOutput(retval, "IDAQuadInitB"); - //retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol*1.1, atol*1.1); - retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol*0.1, atol*0.1); - checkOutput(retval, "IDAQuadSStolerancesB"); + // retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol*1.1, atol*1.1); + retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol * 0.1, atol * 0.1); + checkOutput(retval, "IDAQuadSStolerancesB"); - // Include quadratures in error control - retval = IDASetQuadErrConB(solver_, backwardID_, SUNTRUE); - checkOutput(retval, "IDASetQuadErrConB"); + // Include quadratures in error control + retval = IDASetQuadErrConB(solver_, backwardID_, SUNTRUE); + checkOutput(retval, "IDASetQuadErrConB"); + return retval; + } - return retval; - } + template + int Ida::configureLinearSolverBackward() + { + int retval = 0; - template - int Ida::configureLinearSolverBackward() - { - int retval = 0; + // Create Jacobian matrix + JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void *)JacobianMatB_, "SUNDenseMatrix"); - // Create Jacobian matrix - JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void*) JacobianMatB_, "SUNDenseMatrix"); + // Create linear solver + linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); + checkAllocation((void *)linearSolverB_, "SUNLinSol_Dense"); - // Create linear solver - linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); - checkAllocation((void*) linearSolverB_, "SUNLinSol_Dense"); + // Attach linear solver to IDA + retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); + checkOutput(retval, "IDASetLinearSolverB"); - // Attach linear solver to IDA - retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); - checkOutput(retval, "IDASetLinearSolverB"); + return retval; + } - return retval; - } + template + int Ida::runForwardSimulation(real_type tf, int nout) + { + int retval = 0; + int ncheck; + real_type time; - template - int Ida::runForwardSimulation(real_type tf, int nout) - { - int retval = 0; - int ncheck; - real_type time; + // std::cout << "Forward integration for adjoint analysis ... \n"; - //std::cout << "Forward integration for adjoint analysis ... \n"; + real_type dt = tf / nout; + real_type tout = dt; + for (int i = 0; i < nout; ++i) + { + retval = IDASolveF(solver_, tout, &time, yy_, yp_, IDA_NORMAL, &ncheck); + checkOutput(retval, "IDASolveF"); - real_type dt = tf/nout; - real_type tout = dt; - for(int i = 0; i < nout; ++i) - { - retval = IDASolveF(solver_, tout, &time, yy_, yp_, IDA_NORMAL, &ncheck); - checkOutput(retval, "IDASolveF"); + if (retval == IDA_SUCCESS) + { + tout += dt; + } - if (retval == IDA_SUCCESS) - { - tout += dt; + retval = IDAGetQuad(solver_, &time, q_); + checkOutput(retval, "IDASolve"); } - retval = IDAGetQuad(solver_, &time, q_); - checkOutput(retval, "IDASolve"); + return retval; } - return retval; - } + template + int Ida::runBackwardSimulation(real_type t_init) + { + int retval = 0; + long int nstB; + real_type time; - template - int Ida::runBackwardSimulation(real_type t_init) - { - int retval = 0; - long int nstB; - real_type time; + // std::cout << "Backward integration for adjoint analysis ... "; - //std::cout << "Backward integration for adjoint analysis ... "; + retval = IDASolveB(solver_, t_init, IDA_NORMAL); + checkOutput(retval, "IDASolveB"); - retval = IDASolveB(solver_, t_init, IDA_NORMAL); - checkOutput(retval, "IDASolveB"); + IDAGetNumSteps(IDAGetAdjIDABmem(solver_, backwardID_), &nstB); + // std::cout << "done ( nst = " << nstB << " )\n"; - IDAGetNumSteps(IDAGetAdjIDABmem(solver_, backwardID_), &nstB); - //std::cout << "done ( nst = " << nstB << " )\n"; + retval = IDAGetB(solver_, backwardID_, &time, yyB_, ypB_); + checkOutput(retval, "IDAGetB"); - retval = IDAGetB(solver_, backwardID_, &time, yyB_, ypB_); - checkOutput(retval, "IDAGetB"); + retval = IDAGetQuadB(solver_, backwardID_, &time, qB_); + checkOutput(retval, "IDAGetQuadB"); - retval = IDAGetQuadB(solver_, backwardID_, &time, qB_); - checkOutput(retval, "IDAGetQuadB"); + return retval; + } - return retval; - } + template + int Ida::deleteAdjoint() + { + IDAAdjFree(solver_); + return 0; + } - template - int Ida::deleteAdjoint() - { - IDAAdjFree(solver_); - return 0; - } + template + int Ida::Residual(realtype tres, N_Vector yy, N_Vector yp, N_Vector rr, void *user_data) + { + ModelLib::ModelEvaluator *model = static_cast *>(user_data); - template - int Ida::Residual(realtype tres, N_Vector yy, N_Vector yp, N_Vector rr, void *user_data) - { - ModelLib::ModelEvaluator* model = static_cast*>(user_data); + model->updateTime(tres, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); - model->updateTime(tres, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); + model->evaluateResidual(); + const std::vector &f = model->getResidual(); + copyVec(f, rr); - model->evaluateResidual(); - const std::vector& f = model->getResidual(); - copyVec(f, rr); + return 0; + } - return 0; - } + template + int Ida::Jac(realtype t, realtype cj, N_Vector yy, N_Vector yp, N_Vector resvec, SUNMatrix J, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) + { - template - int Ida::Jac(realtype t, realtype cj, N_Vector yy, N_Vector yp, N_Vector resvec, SUNMatrix J, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) - { + ModelLib::ModelEvaluator *model = static_cast *>(user_data); - ModelLib::ModelEvaluator* model = static_cast*>(user_data); + model->updateTime(t, cj); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); + model->evaluateJacobian(); + COO_Matrix Jac = model->getJacobian(); - model->updateTime(t, cj); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); + // Get reference to the jacobian entries + std::tuple &, std::vector &, std::vector &> tpm = Jac.getEntries(); + const auto [r, c, val] = tpm; - model->evaluateJacobian(); - COO_Matrix Jac = model->getJacobian(); - - //Get reference to the jacobian entries - std::tuple&, std::vector&, std::vector&> tpm = Jac.getEntries(); - const auto [r, c, val] = tpm; + // get the CSR row pointers from COO matrix + std::vector csrrowdata = Jac.getCSRRowData(); - //get the CSR row pointers from COO matrix - std::vector csrrowdata = Jac.getCSRRowData(); + SUNMatZero(J); - SUNMatZero(J); + // Set row pointers + sunindextype *rowptrs = SUNSparseMatrix_IndexPointers(J); + for (unsigned int i = 0; i < csrrowdata.size(); i++) + { + rowptrs[i] = csrrowdata[i]; + } - //Set row pointers - sunindextype *rowptrs = SUNSparseMatrix_IndexPointers(J); - for (unsigned int i = 0; i < csrrowdata.size() ; i++) - { - rowptrs[i] = csrrowdata[i]; - } + sunindextype *colvals = SUNSparseMatrix_IndexValues(J); + realtype *data = SUNSparseMatrix_Data(J); + // Copy data from model jac to sundials + for (unsigned int i = 0; i < c.size(); i++) + { + colvals[i] = c[i]; + data[i] = val[i]; + } - sunindextype *colvals = SUNSparseMatrix_IndexValues(J); - realtype *data = SUNSparseMatrix_Data(J); - //Copy data from model jac to sundials - for (unsigned int i = 0; i < c.size(); i++ ) - { - colvals[i] = c[i]; - data[i] = val[i]; + return 0; } - return 0; - } - - template - int Ida::Integrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector rhsQ, void *user_data) - { - ModelLib::ModelEvaluator* model = static_cast*>(user_data); - - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); - - model->evaluateIntegrand(); - const std::vector& g = model->getIntegrand(); - copyVec(g, rhsQ); + template + int Ida::Integrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector rhsQ, void *user_data) + { + ModelLib::ModelEvaluator *model = static_cast *>(user_data); - return 0; - } + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); - template - int Ida::adjointResidual(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rrB, void *user_data) - { - ModelLib::ModelEvaluator* model = static_cast*>(user_data); + model->evaluateIntegrand(); + const std::vector &g = model->getIntegrand(); + copyVec(g, rhsQ); - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); - copyVec(yyB, model->yB()); - copyVec(ypB, model->ypB()); + return 0; + } - model->evaluateAdjointResidual(); - const std::vector& fB = model->getAdjointResidual(); - copyVec(fB, rrB); + template + int Ida::adjointResidual(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rrB, void *user_data) + { + ModelLib::ModelEvaluator *model = static_cast *>(user_data); - return 0; - } + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); + copyVec(yyB, model->yB()); + copyVec(ypB, model->ypB()); + model->evaluateAdjointResidual(); + const std::vector &fB = model->getAdjointResidual(); + copyVec(fB, rrB); - template - int Ida::adjointIntegrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rhsQB, void *user_data) - { - ModelLib::ModelEvaluator* model = static_cast*>(user_data); + return 0; + } - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); - copyVec(yyB, model->yB()); - copyVec(ypB, model->ypB()); + template + int Ida::adjointIntegrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rhsQB, void *user_data) + { + ModelLib::ModelEvaluator *model = static_cast *>(user_data); - model->evaluateAdjointIntegrand(); - const std::vector& gB = model->getAdjointIntegrand(); - copyVec(gB, rhsQB); + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); + copyVec(yyB, model->yB()); + copyVec(ypB, model->ypB()); - return 0; - } + model->evaluateAdjointIntegrand(); + const std::vector &gB = model->getAdjointIntegrand(); + copyVec(gB, rhsQB); + return 0; + } - template - void Ida::copyVec(const N_Vector x, std::vector< ScalarT >& y) - { - const ScalarT* xdata = NV_DATA_S(x); - for(unsigned int i = 0; i < y.size(); ++i) + template + void Ida::copyVec(const N_Vector x, std::vector &y) { - y[i] = xdata[i]; + const ScalarT *xdata = NV_DATA_S(x); + for (unsigned int i = 0; i < y.size(); ++i) + { + y[i] = xdata[i]; + } } - } - - template - void Ida::copyVec(const std::vector< ScalarT >& x, N_Vector y) - { - ScalarT* ydata = NV_DATA_S(y); - for(unsigned int i = 0; i < x.size(); ++i) + template + void Ida::copyVec(const std::vector &x, N_Vector y) { - ydata[i] = x[i]; + ScalarT *ydata = NV_DATA_S(y); + for (unsigned int i = 0; i < x.size(); ++i) + { + ydata[i] = x[i]; + } } - } - template - void Ida::copyVec(const std::vector< bool >& x, N_Vector y) - { - ScalarT* ydata = NV_DATA_S(y); - for(unsigned int i = 0; i < x.size(); ++i) + template + void Ida::copyVec(const std::vector &x, N_Vector y) { - if (x[i]) - ydata[i] = 1.0; - else - ydata[i] = 0.0; + ScalarT *ydata = NV_DATA_S(y); + for (unsigned int i = 0; i < x.size(); ++i) + { + if (x[i]) + ydata[i] = 1.0; + else + ydata[i] = 0.0; + } } - } - - - template - void Ida::printOutput(realtype t) - { - realtype *yval = N_VGetArrayPointer_Serial(yy_); - realtype *ypval = N_VGetArrayPointer_Serial(yp_); - std::cout << std::setprecision(5) << std::setw(7) << t << " "; - for (IdxT i = 0; i < model_->size(); ++i) + template + void Ida::printOutput(realtype t) { - std::cout << yval[i] << " "; + realtype *yval = N_VGetArrayPointer_Serial(yy_); + realtype *ypval = N_VGetArrayPointer_Serial(yp_); + + std::cout << std::setprecision(5) << std::setw(7) << t << " "; + for (IdxT i = 0; i < model_->size(); ++i) + { + std::cout << yval[i] << " "; + } + for (IdxT i = 0; i < model_->size(); ++i) + { + std::cout << ypval[i] << " "; + } + std::cout << "\n"; } - for (IdxT i = 0; i < model_->size(); ++i) + + template + void Ida::printSpecial(realtype t, N_Vector y) { - std::cout << ypval[i] << " "; + realtype *yval = N_VGetArrayPointer_Serial(y); + IdxT N = static_cast(N_VGetLength_Serial(y)); + std::cout << "{"; + std::cout << std::setprecision(5) << std::setw(7) << t; + for (IdxT i = 0; i < N; ++i) + { + std::cout << ", " << yval[i]; + } + std::cout << "},\n"; } - std::cout << "\n"; - } - template - void Ida::printSpecial(realtype t, N_Vector y) - { - realtype *yval = N_VGetArrayPointer_Serial(y); - IdxT N = static_cast(N_VGetLength_Serial(y)); - std::cout << "{"; - std::cout << std::setprecision(5) << std::setw(7) << t; - for (IdxT i = 0; i < N; ++i) + template + void Ida::printFinalStats() { - std::cout << ", " << yval[i]; + int retval = 0; + void *mem = solver_; + long int nst; + long int nre; + long int nje; + long int nni; + long int netf; + long int ncfn; + + retval = IDAGetNumSteps(mem, &nst); + checkOutput(retval, "IDAGetNumSteps"); + retval = IDAGetNumResEvals(mem, &nre); + checkOutput(retval, "IDAGetNumResEvals"); + retval = IDAGetNumJacEvals(mem, &nje); + checkOutput(retval, "IDAGetNumJacEvals"); + retval = IDAGetNumNonlinSolvIters(mem, &nni); + checkOutput(retval, "IDAGetNumNonlinSolvIters"); + retval = IDAGetNumErrTestFails(mem, &netf); + checkOutput(retval, "IDAGetNumErrTestFails"); + retval = IDAGetNumNonlinSolvConvFails(mem, &ncfn); + checkOutput(retval, "IDAGetNumNonlinSolvConvFails"); + + // std::cout << "\nFinal Run Statistics: \n\n"; + std::cout << "Number of steps = " << nst << "\n"; + std::cout << "Number of residual evaluations = " << nre << "\n"; + // std::cout << "Number of Jacobian evaluations = " << nje << "\n"; + std::cout << "Number of nonlinear iterations = " << nni << "\n"; + std::cout << "Number of error test failures = " << netf << "\n"; + std::cout << "Number of nonlinear conv. failures = " << ncfn << "\n"; } - std::cout << "},\n"; - } - template - void Ida::printFinalStats() - { - int retval = 0; - void* mem = solver_; - long int nst; - long int nre; - long int nje; - long int nni; - long int netf; - long int ncfn; - - retval = IDAGetNumSteps(mem, &nst); - checkOutput(retval, "IDAGetNumSteps"); - retval = IDAGetNumResEvals(mem, &nre); - checkOutput(retval, "IDAGetNumResEvals"); - retval = IDAGetNumJacEvals(mem, &nje); - checkOutput(retval, "IDAGetNumJacEvals"); - retval = IDAGetNumNonlinSolvIters(mem, &nni); - checkOutput(retval, "IDAGetNumNonlinSolvIters"); - retval = IDAGetNumErrTestFails(mem, &netf); - checkOutput(retval, "IDAGetNumErrTestFails"); - retval = IDAGetNumNonlinSolvConvFails(mem, &ncfn); - checkOutput(retval, "IDAGetNumNonlinSolvConvFails"); - - // std::cout << "\nFinal Run Statistics: \n\n"; - std::cout << "Number of steps = " << nst << "\n"; - std::cout << "Number of residual evaluations = " << nre << "\n"; - //std::cout << "Number of Jacobian evaluations = " << nje << "\n"; - std::cout << "Number of nonlinear iterations = " << nni << "\n"; - std::cout << "Number of error test failures = " << netf << "\n"; - std::cout << "Number of nonlinear conv. failures = " << ncfn << "\n"; - } - - - template - void Ida::checkAllocation(void* v, const char* functionName) - { - if (v == NULL) + template + void Ida::checkAllocation(void *v, const char *functionName) { - std::cerr << "\nERROR: Function " << functionName << " failed -- returned NULL pointer!\n\n"; - throw SundialsException(); + if (v == NULL) + { + std::cerr << "\nERROR: Function " << functionName << " failed -- returned NULL pointer!\n\n"; + throw SundialsException(); + } } - } - template - void Ida::checkOutput(int retval, const char* functionName) - { - if (retval < 0) + template + void Ida::checkOutput(int retval, const char *functionName) { - std::cerr << "\nERROR: Function " << functionName << " failed with flag " << retval << "!\n\n"; - throw SundialsException(); + if (retval < 0) + { + std::cerr << "\nERROR: Function " << functionName << " failed with flag " << retval << "!\n\n"; + throw SundialsException(); + } } - } - // Compiler will prevent building modules with data type incompatible with realtype - template class Ida; - template class Ida; - template class Ida; + // Compiler will prevent building modules with data type incompatible with realtype + template class Ida; + template class Ida; + template class Ida; -} // namespace Sundials + } // namespace Sundials } // namespace AnalysisManager From 226afcae0f0599edfd2aff84938d815288261f1f Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Tue, 12 Mar 2024 16:23:16 -0400 Subject: [PATCH 33/44] Fixed Some Bugs - Fixed SpMatTest - Updates on rebase --- Examples/Grid3Bus/Grid3BusSys.cpp | 43 ++++++++++++++++++++----------- SparseMatrix/COO_Matrix.hpp | 2 +- SystemSteadyStateModel.hpp | 39 +--------------------------- 3 files changed, 30 insertions(+), 54 deletions(-) diff --git a/Examples/Grid3Bus/Grid3BusSys.cpp b/Examples/Grid3Bus/Grid3BusSys.cpp index 02985ff1d..f673156a8 100644 --- a/Examples/Grid3Bus/Grid3BusSys.cpp +++ b/Examples/Grid3Bus/Grid3BusSys.cpp @@ -101,8 +101,8 @@ mpc.baseMVA = 100; %% bus data % bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin mpc.bus = [ - 1 3 2.0 0.0 0 0 0 1 0.0 0 0 0 0.0; - 2 1 2.5 -0.8 0 0 0 1 0.0 0 0 0 0.0; + 1 3 2.0 0.0 0 0 0 1.0 0.0 0 0 0 0.0; + 2 1 2.5 -0.8 0 0 0 1.0 0.0 0 0 0 0.0; 3 2 0 0 0 0 0 1.1 0.0 0 0 0 0.0; ]; @@ -216,6 +216,7 @@ int parser_case() // allocate model sysmodel->allocate(); + sysmodel->initialize(); std::cout << "Model size: " << sysmodel->size() << "\n\n"; // Create numerical solver and attach the model to it. @@ -274,51 +275,51 @@ int hardwired_case() // Next create and add buses ... // Create a slack bus, fix V=1, theta=0, bus ID = 1 - BusData bd1; + BusData bd1 = {}; bd1.bus_i = 1; bd1.type = 3; bd1.Vm = 1.0; bd1.Va = 0.0; auto* bus1 = BusFactory::create(bd1); sysmodel->addBus(bus1); //Create a PQ bus, initialize V=1, theta=0, bus ID = 2 - BusData bd2; + BusData bd2 = {}; bd2.bus_i = 2; bd2.type = 1; bd2.Vm = 1.0; bd2.Va = 0.0; auto* bus2 = BusFactory::create(bd2); sysmodel->addBus(bus2); // Create a PV bus, fix V=1.1, initialize theta=0, and set power injection Pg=2 - BusData bd3; + BusData bd3 = {}; bd3.bus_i = 3; bd3.type = 2; bd3.Vm = 1.1; bd3.Va = 0.0; auto* bus3 = BusFactory::create(bd3); sysmodel->addBus(bus3); // Create and add generators ... // Create and add slack generator connected to bus1 - GenData gd1; + GenData gd1 = {}; gd1.bus = 1; auto* gen1 = GeneratorFactory::create(sysmodel->getBus(gd1.bus), gd1); sysmodel->addComponent(gen1); // Create and add PV generator connected to bus3 - GenData gd3; + GenData gd3 = {}; gd3.Pg = 2.0; gd3.bus = 3; auto* gen3 = GeneratorFactory::create(sysmodel->getBus(gd3.bus), gd3); sysmodel->addComponent(gen3); // Create and add branches ... // Branch 1-2 - BranchData brd12; + BranchData brd12 = {}; brd12.fbus = 1; brd12.tbus = 2; brd12.x = 1.0/10.0; brd12.r = 0.0; brd12.b = 0.0; Branch* branch12 = new Branch(sysmodel->getBus(brd12.fbus), sysmodel->getBus(brd12.tbus), brd12); sysmodel->addComponent(branch12); // Branch 1-3 - BranchData brd13; + BranchData brd13 = {}; brd13.fbus = 1; brd13.tbus = 3; brd13.x = 1.0/15.0; brd13.r = 0.0; brd13.b = 0.0; Branch* branch13 = new Branch(sysmodel->getBus(brd13.fbus), sysmodel->getBus(brd13.tbus), brd13); sysmodel->addComponent(branch13); // Branch 2-3 - BranchData brd23; + BranchData brd23 = {}; brd23.fbus = 2; brd23.tbus = 3; brd23.x = 1.0/12.0; brd23.r = 0.0; brd23.b = 0.0; Branch* branch23 = new Branch(sysmodel->getBus(brd23.fbus), sysmodel->getBus(brd23.tbus), brd23); sysmodel->addComponent(branch23); @@ -326,19 +327,20 @@ int hardwired_case() // Create and add loads ... // Load on bus1 - LoadData ld1; + LoadData ld1 = {}; ld1.bus_i = 1; ld1.Pd = 2.0; ld1.Qd = 0.0; Load* load1 = new Load(sysmodel->getBus(ld1.bus_i), ld1); sysmodel->addComponent(load1); // Load on bus2 - LoadData ld2; + LoadData ld2 = {}; ld2.bus_i = 2; ld2.Pd = 2.5; ld2.Qd = -0.8; Load* load2 = new Load(sysmodel->getBus(ld2.bus_i), ld2); sysmodel->addComponent(load2); // allocate model sysmodel->allocate(); + sysmodel->initialize(); std::cout << "Model size: " << sysmodel->size() << "\n\n"; // Create numerical solver and attach the model to it. @@ -354,7 +356,7 @@ int hardwired_case() // Print solution double th2 = bus2->theta() * 180.0/M_PI; double V2 = bus2->V(); - double th3 = bus3->theta() * 180.0/M_PI; + double th3 = bus3->theta() * 180.0/M_PI; std::cout << "Solution:\n"; @@ -390,8 +392,19 @@ int main() std::cout << std::string(32,'-') << std::endl; resolve += monolithic_case(); std::cout << std::string(32,'-') << std::endl; - resolve += hardwired_case(); - std::cout << std::string(32,'-') << std::endl; resolve += parser_case(); + std::cout << std::string(32,'-') << std::endl; + resolve += hardwired_case(); + + if (resolve) + { + std::cout << "Failure!\n"; + } + else + { + std::cout << "Success!\n"; + } + + return resolve; } diff --git a/SparseMatrix/COO_Matrix.hpp b/SparseMatrix/COO_Matrix.hpp index 716748fa8..dc99d7b9e 100644 --- a/SparseMatrix/COO_Matrix.hpp +++ b/SparseMatrix/COO_Matrix.hpp @@ -294,9 +294,9 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrixrow_indexes.push_back(r[aiter]); this->column_indexes.push_back(c[aiter]); this->values.push_back(alpha * val[aiter]); - aiter++; this->checkIncreaseSize(r[aiter], c[aiter]); + aiter++; } if (aiter >= static_cast(r.size())) break; diff --git a/SystemSteadyStateModel.hpp b/SystemSteadyStateModel.hpp index de2dc000e..ca1af16f0 100644 --- a/SystemSteadyStateModel.hpp +++ b/SystemSteadyStateModel.hpp @@ -127,43 +127,6 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl atol_ = 1e-5; } - SystemSteadyStateModel(GridKit::PowerSystemData::SystemModelData mp) : ModelEvaluatorImpl(0,0,0) - { - rtol_ = 1e-5; - atol_ = 1e-5; - - //buses - for(auto busdata : mp.bus) - { - auto* bus = BusFactory::create(busdata); - this->addBus(bus); - } - - //generators - for (auto gendata : mp.gen) - { - auto* gen = GeneratorFactory::create(this->getBus(gendata.bus),gendata); - this->addComponent(gen); - } - - //branches - for (auto branchdata : mp.branch) - { - auto* branch = new Branch(this->getBus(branchdata.fbus),this->getBus(branchdata.tbus),branchdata); - this->addComponent(branch); - } - - //loads - for (auto loaddata : mp.load) - { - auto* loadm = new Load(this->getBus(loaddata.bus_i),loaddata); - this->addComponent(loadm); - } - - //There appears to not be a Generator Cost Object - //TODO: Implment for GenCost - } - /** * @brief Construct a new System Steady State Model object. Allows for simple allocation. * @@ -463,4 +426,4 @@ class SystemSteadyStateModel : public ModelEvaluatorImpl }; // class SystemSteadyStateModel -} // namespace ModelLib +} // namespace ModelLib \ No newline at end of file From 861b33c7aff1495c9f0a981b4118e1ba45a5ac97 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Fri, 15 Mar 2024 15:26:50 -0400 Subject: [PATCH 34/44] Fixed Memory Error with Grid3BusSys - Intalized Pg data --- ComponentLib/Bus/BusPV.cpp | 2 +- ComponentLib/Bus/BusSlack.cpp | 4 ++++ Examples/Grid3Bus/Grid3BusSys.cpp | 21 +++++++++++---------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/ComponentLib/Bus/BusPV.cpp b/ComponentLib/Bus/BusPV.cpp index d5a05dc98..50425d9dd 100644 --- a/ComponentLib/Bus/BusPV.cpp +++ b/ComponentLib/Bus/BusPV.cpp @@ -103,7 +103,7 @@ BusPV::BusPV(ScalarT V, ScalarT theta0) template BusPV::BusPV(BusData& data) - : BaseBus(data.bus_i), V_(data.Vm), theta0_(data.Va) + : BaseBus(data.bus_i), V_(data.Vm), theta0_(data.Va), Pg_(0.0) { //std::cout << "Create BusPV ..." << std::endl; //std::cout << "Number of equations is " << size_ << std::endl; diff --git a/ComponentLib/Bus/BusSlack.cpp b/ComponentLib/Bus/BusSlack.cpp index 80a5ae091..54318de74 100644 --- a/ComponentLib/Bus/BusSlack.cpp +++ b/ComponentLib/Bus/BusSlack.cpp @@ -97,6 +97,8 @@ BusSlack::BusSlack(ScalarT V, ScalarT theta) { //std::cout << "Create BusSlack..." << std::endl; //std::cout << "Number of equations is " << size_ << std::endl; + P() = 0.0; + Q() = 0.0; size_ = 0; } @@ -106,6 +108,8 @@ BusSlack::BusSlack(BusData& data) { //std::cout << "Create BusSlack..." << std::endl; //std::cout << "Number of equations is " << size_ << std::endl; + P() = 0.0; + Q() = 0.0; size_ = 0; } diff --git a/Examples/Grid3Bus/Grid3BusSys.cpp b/Examples/Grid3Bus/Grid3BusSys.cpp index f673156a8..d3bb29652 100644 --- a/Examples/Grid3Bus/Grid3BusSys.cpp +++ b/Examples/Grid3Bus/Grid3BusSys.cpp @@ -156,6 +156,7 @@ int monolithic_case() // allocate model model->allocate(); + model->initialize(); std::cout << "Model size: " << model->size() << "\n\n"; // Create numerical solver and attach the model to it. @@ -275,51 +276,51 @@ int hardwired_case() // Next create and add buses ... // Create a slack bus, fix V=1, theta=0, bus ID = 1 - BusData bd1 = {}; + BusData bd1; bd1.bus_i = 1; bd1.type = 3; bd1.Vm = 1.0; bd1.Va = 0.0; auto* bus1 = BusFactory::create(bd1); sysmodel->addBus(bus1); //Create a PQ bus, initialize V=1, theta=0, bus ID = 2 - BusData bd2 = {}; + BusData bd2; bd2.bus_i = 2; bd2.type = 1; bd2.Vm = 1.0; bd2.Va = 0.0; auto* bus2 = BusFactory::create(bd2); sysmodel->addBus(bus2); // Create a PV bus, fix V=1.1, initialize theta=0, and set power injection Pg=2 - BusData bd3 = {}; + BusData bd3; bd3.bus_i = 3; bd3.type = 2; bd3.Vm = 1.1; bd3.Va = 0.0; auto* bus3 = BusFactory::create(bd3); sysmodel->addBus(bus3); // Create and add generators ... // Create and add slack generator connected to bus1 - GenData gd1 = {}; + GenData gd1; gd1.bus = 1; auto* gen1 = GeneratorFactory::create(sysmodel->getBus(gd1.bus), gd1); sysmodel->addComponent(gen1); // Create and add PV generator connected to bus3 - GenData gd3 = {}; + GenData gd3; gd3.Pg = 2.0; gd3.bus = 3; auto* gen3 = GeneratorFactory::create(sysmodel->getBus(gd3.bus), gd3); sysmodel->addComponent(gen3); // Create and add branches ... // Branch 1-2 - BranchData brd12 = {}; + BranchData brd12; brd12.fbus = 1; brd12.tbus = 2; brd12.x = 1.0/10.0; brd12.r = 0.0; brd12.b = 0.0; Branch* branch12 = new Branch(sysmodel->getBus(brd12.fbus), sysmodel->getBus(brd12.tbus), brd12); sysmodel->addComponent(branch12); // Branch 1-3 - BranchData brd13 = {}; + BranchData brd13; brd13.fbus = 1; brd13.tbus = 3; brd13.x = 1.0/15.0; brd13.r = 0.0; brd13.b = 0.0; Branch* branch13 = new Branch(sysmodel->getBus(brd13.fbus), sysmodel->getBus(brd13.tbus), brd13); sysmodel->addComponent(branch13); // Branch 2-3 - BranchData brd23 = {}; + BranchData brd23; brd23.fbus = 2; brd23.tbus = 3; brd23.x = 1.0/12.0; brd23.r = 0.0; brd23.b = 0.0; Branch* branch23 = new Branch(sysmodel->getBus(brd23.fbus), sysmodel->getBus(brd23.tbus), brd23); sysmodel->addComponent(branch23); @@ -327,13 +328,13 @@ int hardwired_case() // Create and add loads ... // Load on bus1 - LoadData ld1 = {}; + LoadData ld1; ld1.bus_i = 1; ld1.Pd = 2.0; ld1.Qd = 0.0; Load* load1 = new Load(sysmodel->getBus(ld1.bus_i), ld1); sysmodel->addComponent(load1); // Load on bus2 - LoadData ld2 = {}; + LoadData ld2; ld2.bus_i = 2; ld2.Pd = 2.5; ld2.Qd = -0.8; Load* load2 = new Load(sysmodel->getBus(ld2.bus_i), ld2); sysmodel->addComponent(load2); From efddb287fecdfead8cbdc6eaabbee3f517850b20 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Fri, 22 Mar 2024 14:38:01 -0400 Subject: [PATCH 35/44] Fixed Unitalized Variable Stepsize --- Examples/GenInfiniteBus/GenInfiniteBus.cpp | 1 + SystemModel.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/Examples/GenInfiniteBus/GenInfiniteBus.cpp b/Examples/GenInfiniteBus/GenInfiniteBus.cpp index d4305ae05..f366a5a8a 100644 --- a/Examples/GenInfiniteBus/GenInfiniteBus.cpp +++ b/Examples/GenInfiniteBus/GenInfiniteBus.cpp @@ -93,6 +93,7 @@ int main() // allocate model components model->allocate(); + // Create numerical integrator and configure it for the generator model Ida* idas = new Ida(model); diff --git a/SystemModel.hpp b/SystemModel.hpp index 77bbdd20b..14b7e4e97 100644 --- a/SystemModel.hpp +++ b/SystemModel.hpp @@ -117,6 +117,7 @@ class SystemModel : public ModelEvaluatorImpl // Set system model tolerances rtol_ = 1e-7; atol_ = 1e-9; + this->max_steps_=2000; } /** From 3cb53a874db3b88b2b3fb31d9be0c27a1f7d8b59 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Tue, 9 Apr 2024 13:32:24 -0400 Subject: [PATCH 36/44] Fix max number of backward steps in IDA solver. --- Solver/Dynamic/Ida.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index e7b144610..3ae6854c4 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -415,7 +415,7 @@ namespace AnalysisManager checkOutput(retval, "IDASetUserDataB"); /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumStepsB(solver_, backwardID_, 200); + retval = IDASetMaxNumStepsB(solver_, backwardID_, 2000); checkOutput(retval, "IDASetMaxNumSteps"); // Set up linear solver From a2e71ab1973f6e733cd46a8114ef97bebc08ca3a Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Tue, 9 Apr 2024 15:29:01 -0400 Subject: [PATCH 37/44] Fixing indentation from tabs to spaces --- .../Capacitor/Capacitor.cpp | 2 +- .../CircuitComponent.hpp | 204 ++--- .../DistributedGenerator.cpp | 2 +- .../DistributedGenerator.hpp | 2 +- .../InductionMotor/InductionMotor.cpp | 34 +- .../InductionMotor/InductionMotor.hpp | 14 +- .../Inductor/Inductor.cpp | 2 +- .../LinearTransformer/LinearTransformer.cpp | 18 +- .../LinearTransformer/LinearTransformer.hpp | 10 +- .../MicrogridBusDQ/MicrogridBusDQ.cpp | 2 +- .../MicrogridLine/MicrogridLine.cpp | 4 +- .../MicrogridLoad/MicrogridLoad.cpp | 4 +- .../Resistor/Resistor.cpp | 4 +- .../Resistor/Resistor.hpp | 2 +- .../SynchronousMachine/SynchronousMachine.cpp | 64 +- .../SynchronousMachine/SynchronousMachine.hpp | 26 +- .../TransmissionLine/TransmissionLine.cpp | 4 +- .../TransmissionLine/TransmissionLine.hpp | 2 +- .../VoltageSource/VoltageSource.cpp | 8 +- .../VoltageSource/VoltageSource.hpp | 2 +- Examples/Grid3Bus/Grid3BusSys.cpp | 22 +- Examples/Microgrid/Microgrid.cpp | 676 +++++++------- Examples/RLCircuit/RLCircuit.cpp | 228 ++--- Examples/SparseTest/SparseTest.cpp | 142 +-- SparseMatrix/COO_Matrix.hpp | 834 +++++++++--------- 25 files changed, 1156 insertions(+), 1156 deletions(-) diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp index b6287b359..148c7c086 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -18,7 +18,7 @@ template Capacitor::Capacitor(IdxT id, ScalarT C) : C_(C) { - this->size_ = 3; + this->size_ = 3; this->n_intern = 1; this->n_extern = 2; this->extern_indices = {0,1}; diff --git a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp index fe2efdf96..2d43e06e0 100644 --- a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp +++ b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp @@ -27,113 +27,113 @@ namespace ModelLib this->time_ = t; this->alpha_ = a; } - + bool hasJacobian() { return true;} - size_t getExternSize() - { - return this->n_extern; - } - - size_t getInternalSize() - { - return this->n_intern; - } - - std::set getExternIndices() - { - return this->extern_indices; - } - - bool setExternalConnectionNodes(size_t index, IdxT id) - { - this->connection_nodes[index] = id; - return true; - } - - IdxT getNodeConnection(size_t index) - { - return this->connection_nodes.at(index); - } - - inline std::vector parkTransformMatrix(ScalarT angle) - { - std::vector result(9); - ScalarT anpim = angle - (2.0/3.0)*M_PI; - ScalarT anpip = angle + (2.0/3.0)*M_PI; - result[0] = (2.0/3.0)*cos(angle); - result[1] = (2.0/3.0)*cos(anpim); - result[2] = (2.0/3.0)*cos(anpip); - result[3] = (2.0/3.0)*sin(angle); - result[4] = (2.0/3.0)*sin(anpim); - result[5] = (2.0/3.0)*sin(anpip); - result[6] = 1.0/3.0; - result[7] = 1.0/3.0; - result[8] = 1.0/3.0; - return result; - } - - inline std::vector parkTransformMatrixDerivative(ScalarT angle) - { - std::vector result(9); - ScalarT anpim = angle - (2.0/3.0)*M_PI; - ScalarT anpip = angle + (2.0/3.0)*M_PI; - result[0] = (2.0/3.0)*sin(angle); - result[1] = (2.0/3.0)*sin(anpim); - result[2] = (2.0/3.0)*sin(anpip); - result[3] = (2.0/3.0)*-cos(angle); - result[4] = (2.0/3.0)*-cos(anpim); - result[5] = (2.0/3.0)*-cos(anpip); - result[6] = 0; - result[7] = 0; - result[8] = 0; - return result; - } - - inline std::vector inverseParkTransformMatrix(ScalarT angle) - { - std::vector result(9); - ScalarT anpim = angle - (2.0/3.0)*M_PI; - ScalarT anpip = angle + (2.0/3.0)*M_PI; - result[0] = cos(angle); - result[1] = sin(angle); - result[2] = 1.0; - result[3] = cos(anpim); - result[4] = sin(anpim); - result[5] = 1.0; - result[6] = cos(anpip); - result[7] = sin(anpip); - result[8] = 1.0; - return result; - } - - inline std::vector inverseParkTransformMatrixDerivative(ScalarT angle) - { - std::vector result(9); - ScalarT anpim = angle - (2.0/3.0)*M_PI; - ScalarT anpip = angle + (2.0/3.0)*M_PI; - result[0] = sin(angle); - result[1] = -cos(angle); - result[2] = 0.0; - result[3] = sin(anpim); - result[4] = -cos(anpim); - result[5] = 0.0; - result[6] = sin(anpip); - result[7] = -cos(anpip); - result[8] = 0.0; - return result; - } - - protected: - size_t n_extern; - size_t n_intern; - std::set extern_indices; - //@todo may want to replace the mapping of connection_nodes to Node objects instead of IdxT. Allows for container free setup - std::map connection_nodes; + size_t getExternSize() + { + return this->n_extern; + } + + size_t getInternalSize() + { + return this->n_intern; + } + + std::set getExternIndices() + { + return this->extern_indices; + } + + bool setExternalConnectionNodes(size_t index, IdxT id) + { + this->connection_nodes[index] = id; + return true; + } + + IdxT getNodeConnection(size_t index) + { + return this->connection_nodes.at(index); + } + + inline std::vector parkTransformMatrix(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = (2.0/3.0)*cos(angle); + result[1] = (2.0/3.0)*cos(anpim); + result[2] = (2.0/3.0)*cos(anpip); + result[3] = (2.0/3.0)*sin(angle); + result[4] = (2.0/3.0)*sin(anpim); + result[5] = (2.0/3.0)*sin(anpip); + result[6] = 1.0/3.0; + result[7] = 1.0/3.0; + result[8] = 1.0/3.0; + return result; + } + + inline std::vector parkTransformMatrixDerivative(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = (2.0/3.0)*sin(angle); + result[1] = (2.0/3.0)*sin(anpim); + result[2] = (2.0/3.0)*sin(anpip); + result[3] = (2.0/3.0)*-cos(angle); + result[4] = (2.0/3.0)*-cos(anpim); + result[5] = (2.0/3.0)*-cos(anpip); + result[6] = 0; + result[7] = 0; + result[8] = 0; + return result; + } + + inline std::vector inverseParkTransformMatrix(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = cos(angle); + result[1] = sin(angle); + result[2] = 1.0; + result[3] = cos(anpim); + result[4] = sin(anpim); + result[5] = 1.0; + result[6] = cos(anpip); + result[7] = sin(anpip); + result[8] = 1.0; + return result; + } + + inline std::vector inverseParkTransformMatrixDerivative(ScalarT angle) + { + std::vector result(9); + ScalarT anpim = angle - (2.0/3.0)*M_PI; + ScalarT anpip = angle + (2.0/3.0)*M_PI; + result[0] = sin(angle); + result[1] = -cos(angle); + result[2] = 0.0; + result[3] = sin(anpim); + result[4] = -cos(anpim); + result[5] = 0.0; + result[6] = sin(anpip); + result[7] = -cos(anpip); + result[8] = 0.0; + return result; + } + + protected: + size_t n_extern; + size_t n_intern; + std::set extern_indices; + //@todo may want to replace the mapping of connection_nodes to Node objects instead of IdxT. Allows for container free setup + std::map connection_nodes; }; - + } #endif diff --git a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp index d8d424b62..ee23eb7b7 100644 --- a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp @@ -22,7 +22,7 @@ DistributedGenerator::DistributedGenerator(IdxT id, DistributedGe { // internals [\delta_i, Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi] // externals [\omega_ref, vba_out, vbb_out] - this->size_ = 16; + this->size_ = 16; this->n_intern = 13; this->n_extern = 3; this->extern_indices = {0,1,2}; diff --git a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp index 94b297a55..65e71b2b9 100644 --- a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp @@ -69,7 +69,7 @@ namespace ModelLib int initialize(); int tagDifferentiable(); int evaluateResidual(); - int evaluateJacobian(); + int evaluateJacobian(); int evaluateIntegrand(); int initializeAdjoint(); int evaluateAdjointResidual(); diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp index 75782b435..c9b452f79 100644 --- a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp @@ -20,14 +20,14 @@ namespace ModelLib { template InductionMotor::InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, ScalarT Llr, ScalarT Rr, ScalarT Lms, ScalarT J, ScalarT P) : Lls_(Lls), - Rs_(Rs), - Llr_(Llr), - Rr_(Rr), - Lms_(Lms), - J_(J), - P_(P) + Rs_(Rs), + Llr_(Llr), + Rr_(Rr), + Lms_(Lms), + J_(J), + P_(P) { - this->size_ = 10; + this->size_ = 10; this->n_intern = 5; this->n_extern = 5; this->extern_indices = {0,1,2,3,4}; @@ -77,18 +77,18 @@ int InductionMotor::tagDifferentiable() template int InductionMotor::evaluateResidual() { - //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors - // for easier development + //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors + // for easier development this->f_[0] = y_[5] + y_[7]; this->f_[1] = (-1.0/2.0) * y_[5] - (sqrt(3.0)/2.0)*y_[6] + y_[7]; - this->f_[2] = (-1.0/2.0) * y_[5] + (sqrt(3.0)/2.0)*y_[6] + y_[7]; - this->f_[3] = J_ * yp_[3] - (3.0/4.0)*P_*Lms_ * (y_[5]*y_[9] - y_[6]*y_[8]); - this->f_[4] = yp_[4] - y_[3]; - this->f_[5] = (1.0/3.0)*(2.0* y_[0] - y_[1] - y_[2]) - Rs_*y_[5] - (Lls_ + Lms_) * yp_[5] - Lms_ * yp_[6]; - this->f_[6] = (1.0/sqrt(3.0))*(-y_[1] + y_[2]) - Rs_*y_[6] - (Lls_ + Lms_) * yp_[6] - Lms_ * yp_[5]; - this->f_[7] = (y_[0] + y_[1] + y_[2])/3.0 - Rs_*y_[7] - Lls_ * yp_[7]; - this->f_[8] = Rr_*y_[8] + (Llr_ + Lms_)*yp_[8] + Lms_ * yp_[5] - (P_/2)*y_[3]*((Llr_+Lms_)*y_[9] + Lms_*y_[6]); - this->f_[9] = Rr_*y_[9] + (Llr_ + Lms_)*yp_[9] + Lms_ * yp_[6] + (P_/2)*y_[3]*((Llr_+Lms_)*y_[8] + Lms_*y_[5]); + this->f_[2] = (-1.0/2.0) * y_[5] + (sqrt(3.0)/2.0)*y_[6] + y_[7]; + this->f_[3] = J_ * yp_[3] - (3.0/4.0)*P_*Lms_ * (y_[5]*y_[9] - y_[6]*y_[8]); + this->f_[4] = yp_[4] - y_[3]; + this->f_[5] = (1.0/3.0)*(2.0* y_[0] - y_[1] - y_[2]) - Rs_*y_[5] - (Lls_ + Lms_) * yp_[5] - Lms_ * yp_[6]; + this->f_[6] = (1.0/sqrt(3.0))*(-y_[1] + y_[2]) - Rs_*y_[6] - (Lls_ + Lms_) * yp_[6] - Lms_ * yp_[5]; + this->f_[7] = (y_[0] + y_[1] + y_[2])/3.0 - Rs_*y_[7] - Lls_ * yp_[7]; + this->f_[8] = Rr_*y_[8] + (Llr_ + Lms_)*yp_[8] + Lms_ * yp_[5] - (P_/2)*y_[3]*((Llr_+Lms_)*y_[9] + Lms_*y_[6]); + this->f_[9] = Rr_*y_[9] + (Llr_ + Lms_)*yp_[9] + Lms_ * yp_[6] + (P_/2)*y_[3]*((Llr_+Lms_)*y_[8] + Lms_*y_[5]); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp index 2547754e2..96ac6cc49 100644 --- a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp @@ -56,13 +56,13 @@ namespace ModelLib int evaluateAdjointIntegrand(); private: - ScalarT Lls_; - ScalarT Rs_; - ScalarT Llr_; - ScalarT Rr_; - ScalarT Lms_; - ScalarT J_; - ScalarT P_; + ScalarT Lls_; + ScalarT Rs_; + ScalarT Llr_; + ScalarT Rr_; + ScalarT Lms_; + ScalarT J_; + ScalarT P_; }; } diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index 885153d41..05cc66c51 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -18,7 +18,7 @@ template Inductor::Inductor(IdxT id, ScalarT L) : L_(L) { - this->size_ = 3; + this->size_ = 3; this->n_intern = 1; this->n_extern = 2; this->extern_indices = {0,1}; diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp index 4caaeae66..aa147493f 100644 --- a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp @@ -17,12 +17,12 @@ namespace ModelLib { template LinearTransformer::LinearTransformer(IdxT id, ScalarT L1, ScalarT L2, ScalarT R1, ScalarT R2, ScalarT M) : L1_(L1), - L2_(L2), - R1_(R1), - R2_(R2), - M_(M) + L2_(L2), + R1_(R1), + R2_(R2), + M_(M) { - this->size_ = 4; + this->size_ = 4; this->n_intern = 2; this->n_extern = 2; this->extern_indices = {0,1}; @@ -72,12 +72,12 @@ int LinearTransformer::tagDifferentiable() template int LinearTransformer::evaluateResidual() { - //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors - // for easier development + //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors + // for easier development this->f_[0] = this->y_[2]; this->f_[1] = this->y_[3]; - this->f_[2] = this->y_[0] - this->R1_ * this->y_[2] - this->L1_ * this->yp_[2] - this->M_ * this->yp_[3]; - this->f_[2] = this->y_[1] - this->R2_ * this->y_[3] - this->M_ * this->yp_[2] - this->L2_ * this->yp_[3]; + this->f_[2] = this->y_[0] - this->R1_ * this->y_[2] - this->L1_ * this->yp_[2] - this->M_ * this->yp_[3]; + this->f_[2] = this->y_[1] - this->R2_ * this->y_[3] - this->M_ * this->yp_[2] - this->L2_ * this->yp_[3]; return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp index cf56adfa2..0c0895383 100644 --- a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp @@ -56,11 +56,11 @@ namespace ModelLib int evaluateAdjointIntegrand(); private: - ScalarT L1_; - ScalarT L2_; - ScalarT R1_; - ScalarT R2_; - ScalarT M_; + ScalarT L1_; + ScalarT L2_; + ScalarT R1_; + ScalarT R2_; + ScalarT M_; }; } diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp index 206108221..a8327e341 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -19,7 +19,7 @@ MicrogridBusDQ::MicrogridBusDQ(IdxT id, ScalarT RN) : RN_(RN) { // externals [vbus_d, vbus_q] - this->size_ = 2; + this->size_ = 2; this->n_intern = 0; this->n_extern = 2; this->extern_indices = {0,1}; diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp index e040ceb70..05b1b5e66 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp @@ -20,7 +20,7 @@ MicrogridLine::MicrogridLine(IdxT id, ScalarT R,ScalarT L) { // internals [id, iq] // externals [\omegaref, vbd_in, vbq_in, vbd_out, vbq_out] - this->size_ = 7; + this->size_ = 7; this->n_intern = 2; this->n_extern = 5; this->extern_indices = {0,1,2,3,4}; @@ -74,7 +74,7 @@ int MicrogridLine::evaluateResidual() //ref motor this->f_[0] = 0.0; - //input + //input this->f_[1] = -y_[5] ; this->f_[2] = -y_[6] ; diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp index c39f53388..502170e3b 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp @@ -21,7 +21,7 @@ MicrogridLoad::MicrogridLoad(IdxT id, ScalarT R,ScalarT L) { // internals [id, iq] // externals [\omegaref, vbd_out, vbq_out] - this->size_ = 5; + this->size_ = 5; this->n_intern = 2; this->n_extern = 3; this->extern_indices = {0,1,2}; @@ -76,7 +76,7 @@ int MicrogridLoad::evaluateResidual() //only input for loads - //input + //input this->f_[1] = -y_[3] ; this->f_[2] = -y_[4] ; diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp index 45d9a34f3..d3acbb87f 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp @@ -18,7 +18,7 @@ template Resistor::Resistor(IdxT id, ScalarT R) : R_(R) { - this->size_ = 2; + this->size_ = 2; this->n_intern = 0; this->n_extern = 2; this->extern_indices = {0,1}; @@ -69,7 +69,7 @@ int Resistor::tagDifferentiable() template int Resistor::evaluateResidual() { - //input + //input this->f_[0] = (this->y_[0] - this->y_[1])/this->R_ ; //ouput this->f_[1] = (this->y_[1] - this->y_[0])/this->R_ ; diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp index 984d8304b..b9e01415d 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp @@ -59,7 +59,7 @@ namespace ModelLib private: - ScalarT R_; + ScalarT R_; }; } diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp index 05b1e59ac..8e9be323a 100644 --- a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp @@ -20,20 +20,20 @@ namespace ModelLib { template SynchronousMachine::SynchronousMachine(IdxT id, ScalarT Lls, std::tuple Llkq, ScalarT Llfd, ScalarT Llkd, ScalarT Lmq, ScalarT Lmd, ScalarT Rs, std::tuple Rkq, ScalarT Rfd, ScalarT Rkd, ScalarT J, ScalarT P, ScalarT mub) : Lls_(Lls), - Llkq_(Llkq), - Llfd_(Llfd), - Llkd_(Llkd), - Lmq_(Lmq), - Lmd_(Lmd), - Rs_(Rs), - Rkq_(Rkq), - Rfd_(Rfd), - Rkd_(Rkd), - J_(J), - P_(P), - mub_(mub) + Llkq_(Llkq), + Llfd_(Llfd), + Llkd_(Llkd), + Lmq_(Lmq), + Lmd_(Lmd), + Rs_(Rs), + Rkq_(Rkq), + Rfd_(Rfd), + Rkd_(Rkd), + J_(J), + P_(P), + mub_(mub) { - this->size_ = 13; + this->size_ = 13; this->n_intern = 6; this->n_extern = 7; this->extern_indices = {0,1,2,3,4}; @@ -83,28 +83,28 @@ int SynchronousMachine::tagDifferentiable() template int SynchronousMachine::evaluateResidual() { - ScalarT rkq1 = std::get<0>(Rkq_); - ScalarT rkq2 = std::get<1>(Rkq_); - ScalarT llkq1 = std::get<0>(Llkq_); - ScalarT llkq2 = std::get<1>(Llkq_); - - ScalarT cos1 = cos((P_/2.0)*y_[5]); - ScalarT sin1 = sin((P_/2.0)*y_[5]); - ScalarT cos23m = cos((P_/2.0)*y_[5] - (2.0/3.0)*M_PI); - ScalarT sin23m = sin((P_/2.0)*y_[5] - (2.0/3.0)*M_PI); - ScalarT cos23p = cos((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); - ScalarT sin23p = sin((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); + ScalarT rkq1 = std::get<0>(Rkq_); + ScalarT rkq2 = std::get<1>(Rkq_); + ScalarT llkq1 = std::get<0>(Llkq_); + ScalarT llkq2 = std::get<1>(Llkq_); + + ScalarT cos1 = cos((P_/2.0)*y_[5]); + ScalarT sin1 = sin((P_/2.0)*y_[5]); + ScalarT cos23m = cos((P_/2.0)*y_[5] - (2.0/3.0)*M_PI); + ScalarT sin23m = sin((P_/2.0)*y_[5] - (2.0/3.0)*M_PI); + ScalarT cos23p = cos((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); + ScalarT sin23p = sin((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); this->f_[0] = y_[6]*cos1 + y_[7]*sin1 + y_[8]; this->f_[1] = y_[6]*cos23m + y_[7]*sin23m + y_[8]; - this->f_[2] = y_[6]*cos23p + y_[7]*sin23p + y_[8]; - this->f_[3] = J_ * yp_[4] - (3.0/4.0)*P_*(Lmd_ *y_[6]* (y_[7] + y_[11] + y_[12]) - Lmq_*y_[7]*(y_[6] + y_[9] + y_[0])); - this->f_[4] = yp_[5] - y_[4]; - this->f_[5] = (-2.0/3.0)*(y_[0]*cos1 +y_[1]*cos23m + y_[2]*cos23p) + Rs_*y_[6] + (Lls_ + Lmq_)*yp_[6] + Lmq_*yp_[9] + Lmq_*yp_[10] + y_[4]*(P_/2.0)*((Lls_ + Lmd_)*y_[7] + Lmd_*y_[11] + Lmd_*y_[12]); - this->f_[6] = (-2.0/3.0)*(y_[0]*sin1 -y_[1]*sin23m - y_[2]*sin23p) + Rs_*y_[7] + (Lls_ + Lmd_)*yp_[7] + Lmd_*yp_[11] + Lmd_*yp_[12] - y_[4]*(P_/2.0)*((Lls_ + Lmq_)*y_[6] + Lmq_*y_[9] + Lmq_*y_[10]); - this->f_[7] = (-1.0/3.0)*(y_[0] + y_[1] + y_[2]) + Rs_*y_[8] + Lls_*yp_[8]; - this->f_[8] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; - this->f_[9] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; + this->f_[2] = y_[6]*cos23p + y_[7]*sin23p + y_[8]; + this->f_[3] = J_ * yp_[4] - (3.0/4.0)*P_*(Lmd_ *y_[6]* (y_[7] + y_[11] + y_[12]) - Lmq_*y_[7]*(y_[6] + y_[9] + y_[0])); + this->f_[4] = yp_[5] - y_[4]; + this->f_[5] = (-2.0/3.0)*(y_[0]*cos1 +y_[1]*cos23m + y_[2]*cos23p) + Rs_*y_[6] + (Lls_ + Lmq_)*yp_[6] + Lmq_*yp_[9] + Lmq_*yp_[10] + y_[4]*(P_/2.0)*((Lls_ + Lmd_)*y_[7] + Lmd_*y_[11] + Lmd_*y_[12]); + this->f_[6] = (-2.0/3.0)*(y_[0]*sin1 -y_[1]*sin23m - y_[2]*sin23p) + Rs_*y_[7] + (Lls_ + Lmd_)*yp_[7] + Lmd_*yp_[11] + Lmd_*yp_[12] - y_[4]*(P_/2.0)*((Lls_ + Lmq_)*y_[6] + Lmq_*y_[9] + Lmq_*y_[10]); + this->f_[7] = (-1.0/3.0)*(y_[0] + y_[1] + y_[2]) + Rs_*y_[8] + Lls_*yp_[8]; + this->f_[8] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; + this->f_[9] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp index a18eca9c9..b1ab24415 100644 --- a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp @@ -57,19 +57,19 @@ namespace ModelLib int evaluateAdjointIntegrand(); private: - ScalarT Lls_; - std::tuple Llkq_; - ScalarT Llfd_; - ScalarT Llkd_; - ScalarT Lmq_; - ScalarT Lmd_; - ScalarT Rs_; - std::tuple Rkq_; - ScalarT Rfd_; - ScalarT Rkd_; - ScalarT J_; - ScalarT P_; - ScalarT mub_; + ScalarT Lls_; + std::tuple Llkq_; + ScalarT Llfd_; + ScalarT Llkd_; + ScalarT Lmq_; + ScalarT Lmd_; + ScalarT Rs_; + std::tuple Rkq_; + ScalarT Rfd_; + ScalarT Rkd_; + ScalarT J_; + ScalarT P_; + ScalarT mub_; }; } diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp index 62965c68e..4158be388 100644 --- a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp @@ -21,7 +21,7 @@ TransmissionLine::TransmissionLine(IdxT id, ScalarT R,ScalarT X, { // internals [Iret1, Iimt1, Iret2, Iimt2] // externals [Vre11, Vim11, Vre12, Vim12, Vre21, Vim21, Vre22, Vim22] - this->size_ = 12; + this->size_ = 12; this->n_intern = 4; this->n_extern = 8; this->extern_indices = {0,1,2,3,4,5,6,7}; @@ -90,7 +90,7 @@ int TransmissionLine::tagDifferentiable() template int TransmissionLine::evaluateResidual() { - //input + //input this->f_[0] = y_[8] ; this->f_[1] = y_[9] ; diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp index 0f729d449..4acac0c58 100644 --- a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp @@ -59,7 +59,7 @@ namespace ModelLib private: - ScalarT R_; + ScalarT R_; ScalarT X_; ScalarT B_; ScalarT YReMat_; diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp index e58e50556..b8a659ba9 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -18,7 +18,7 @@ template VoltageSource::VoltageSource(IdxT id, ScalarT V) : V_(V) { - this->size_ = 3; + this->size_ = 3; this->n_intern = 1; this->n_extern = 2; this->extern_indices = {0,1}; @@ -69,14 +69,14 @@ int VoltageSource::tagDifferentiable() template int VoltageSource::evaluateResidual() { - //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors - // for easier development + //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors + // for easier development //input this->f_[0] = -this->y_[2]; //ouput this->f_[1] = this->y_[2]; //internal - this->f_[2] = this->y_[1] - this->y_[0] - this->V_; + this->f_[2] = this->y_[1] - this->y_[0] - this->V_; return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp index 3ac1c8699..17ba8f8c3 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp @@ -57,7 +57,7 @@ namespace ModelLib int evaluateAdjointIntegrand(); private: - ScalarT V_; + ScalarT V_; }; } diff --git a/Examples/Grid3Bus/Grid3BusSys.cpp b/Examples/Grid3Bus/Grid3BusSys.cpp index d3bb29652..454f7d456 100644 --- a/Examples/Grid3Bus/Grid3BusSys.cpp +++ b/Examples/Grid3Bus/Grid3BusSys.cpp @@ -101,24 +101,24 @@ mpc.baseMVA = 100; %% bus data % bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin mpc.bus = [ - 1 3 2.0 0.0 0 0 0 1.0 0.0 0 0 0 0.0; - 2 1 2.5 -0.8 0 0 0 1.0 0.0 0 0 0 0.0; - 3 2 0 0 0 0 0 1.1 0.0 0 0 0 0.0; + 1 3 2.0 0.0 0 0 0 1.0 0.0 0 0 0 0.0; + 2 1 2.5 -0.8 0 0 0 1.0 0.0 0 0 0 0.0; + 3 2 0 0 0 0 0 1.1 0.0 0 0 0 0.0; ]; %% generator data % bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf mpc.gen = [ - 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; - 3 2.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; + 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; + 3 2.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; ]; %% branch data % fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax mpc.branch = [ - 1 2 0 0.1 0 0 0 0 0 0 0 0 0; - 1 3 0 0.0666666 0 0 0 0 0 0 0 0 0; - 2 3 0 0.0833333 0 0 0 0 0 0 0 0 0; + 1 2 0 0.1 0 0 0 0 0 0 0 0 0; + 1 3 0 0.0666666 0 0 0 0 0 0 0 0 0; + 2 3 0 0.0833333 0 0 0 0 0 0 0 0 0; ]; %%----- OPF Data -----%% @@ -126,9 +126,9 @@ mpc.branch = [ % 1 startup shutdown n x1 y1 ... xn yn % 2 startup shutdown n c(n-1) ... c0 mpc.gencost = [ - 2 0 0 3 0 14 0; - 2 0 0 3 0 15 0; - 2 0 0 3 0 30 0; + 2 0 0 3 0 14 0; + 2 0 0 3 0 15 0; + 2 0 0 3 0 30 0; ]; )"; diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp index b263495ad..8107c3e66 100644 --- a/Examples/Microgrid/Microgrid.cpp +++ b/Examples/Microgrid/Microgrid.cpp @@ -19,328 +19,328 @@ int main(int argc, char const *argv[]) { - double abstol = 1.0e-8; - double reltol = 1.0e-8; - size_t max_step_amount = 3000; - bool usejac = true; - - //TODO:setup as named parameters - //Create circuit model - ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac, max_step_amount); - - //Modeled after the problem in the paper - double RN = 1.0e4; - - //DG Params - - ModelLib::DistributedGeneratorParameters parms1; - parms1.wb = 2.0*M_PI*50.0; - parms1.wc = 31.41; - parms1.mp = 9.4e-5; - parms1.Vn = 380.0; - parms1.nq = 1.3e-3; - parms1.F = 0.75; - parms1.Kiv = 420.0; - parms1.Kpv = 0.1; - parms1.Kic = 2.0e4; - parms1.Kpc = 15.0; - parms1.Cf = 5.0e-5; - parms1.rLf = 0.1; - parms1.Lf = 1.35e-3; - parms1.rLc = 0.03; - parms1.Lc = 0.35e-3; - - ModelLib::DistributedGeneratorParameters parms2; - //Parameters from MATLAB Microgrid code for first DG - parms2.wb = 2.0*M_PI*50.0; - parms2.wc = 31.41; - parms2.mp = 12.5e-5; - parms2.Vn = 380.0; - parms2.nq = 1.5e-3; - parms2.F = 0.75; - parms2.Kiv = 390.0; - parms2.Kpv = 0.05; - parms2.Kic = 16.0e3; - parms2.Kpc = 10.5; - parms2.Cf = 50.0e-6; - parms2.rLf = 0.1; - parms2.Lf = 1.35e-3; - parms2.rLc = 0.03; - parms2.Lc = 0.35e-3; - - //Line params - double rline1 = 0.23; - double Lline1 = 0.1 / (2.0 * M_PI * 50.0); - - double rline2 = 0.35; - double Lline2 = 0.58 / (2.0 * M_PI * 50.0); - - double rline3 = 0.23; - double Lline3 = 0.1 / (2.0 * M_PI * 50.0); - - //load parms - double rload1 = 3.0; - double Lload1 = 2.0 / (2.0 * M_PI * 50.0); - - double rload2 = 2.0; - double Lload2 = 1.0 / (2.0 * M_PI * 50.0); - - - //indexing sets - size_t Nsize = 2; - // DGs + - refframe Lines + Loads - size_t vec_size_internals = 13*(2*Nsize) - 1 + (2 + 4*(Nsize - 1)) + 2*Nsize; - // \omegaref + BusDQ - size_t vec_size_externals = 1 + 2*(2*Nsize); - size_t dqbus1 = vec_size_internals + 1; - size_t dqbus2 = vec_size_internals + 3; - size_t dqbus3 = vec_size_internals + 5; - size_t dqbus4 = vec_size_internals + 7; - - size_t vec_size_total = vec_size_internals + vec_size_externals; - - - size_t indexv = 0; - - //dg 1 - ModelLib::DistributedGenerator *dg1 = new ModelLib::DistributedGenerator(0, parms1, true); - //ref motor - dg1->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg1->setExternalConnectionNodes(1,dqbus1); - dg1->setExternalConnectionNodes(2,dqbus1 + 1); - //"grounding" of the difference - dg1->setExternalConnectionNodes(3,-1); - //internal connections - for (size_t i = 0; i < 12; i++) - { - - dg1->setExternalConnectionNodes(4 + i,indexv + i); - } - indexv += 12; - sysmodel->addComponent(dg1); - - //dg 2 - ModelLib::DistributedGenerator *dg2 = new ModelLib::DistributedGenerator(1, parms1, false); - //ref motor - dg2->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg2->setExternalConnectionNodes(1,dqbus2); - dg2->setExternalConnectionNodes(2,dqbus2 + 1); - //internal connections - for (size_t i = 0; i < 13; i++) - { - - dg2->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 13; - sysmodel->addComponent(dg2); - - - //dg 3 - ModelLib::DistributedGenerator *dg3 = new ModelLib::DistributedGenerator(2, parms2, false); - //ref motor - dg3->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg3->setExternalConnectionNodes(1,dqbus3); - dg3->setExternalConnectionNodes(2,dqbus3 + 1); - //internal connections - for (size_t i = 0; i < 13; i++) - { - - dg3->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 13; - sysmodel->addComponent(dg3); - - - //dg 4 - ModelLib::DistributedGenerator *dg4 = new ModelLib::DistributedGenerator(3, parms2, false); - //ref motor - dg4->setExternalConnectionNodes(0,vec_size_internals); - //outputs - dg4->setExternalConnectionNodes(1,dqbus4); - dg4->setExternalConnectionNodes(2,dqbus4 + 1); - - //internal connections - for (size_t i = 0; i < 13; i++) - { - - dg4->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 13; - sysmodel->addComponent(dg4); - - // Lines - - //line 1 - ModelLib::MicrogridLine *l1 = new ModelLib::MicrogridLine(4, rline1, Lline1); - //ref motor - l1->setExternalConnectionNodes(0,vec_size_internals); - //input connections - l1->setExternalConnectionNodes(1,dqbus1); - l1->setExternalConnectionNodes(2,dqbus1 + 1); - //output connections - l1->setExternalConnectionNodes(3,dqbus2); - l1->setExternalConnectionNodes(4,dqbus2 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - l1->setExternalConnectionNodes(5 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(l1); - - - //line 2 - ModelLib::MicrogridLine *l2 = new ModelLib::MicrogridLine(5, rline2, Lline2); - //ref motor - l2->setExternalConnectionNodes(0,vec_size_internals); - //input connections - l2->setExternalConnectionNodes(1,dqbus2); - l2->setExternalConnectionNodes(2,dqbus2 + 1); - //output connections - l2->setExternalConnectionNodes(3,dqbus3); - l2->setExternalConnectionNodes(4,dqbus3 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - l2->setExternalConnectionNodes(5 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(l2); - - //line 3 - ModelLib::MicrogridLine *l3 = new ModelLib::MicrogridLine(6, rline3, Lline3); - //ref motor - l3->setExternalConnectionNodes(0,vec_size_internals); - //input connections - l3->setExternalConnectionNodes(1,dqbus3); - l3->setExternalConnectionNodes(2,dqbus3 + 1); - //output connections - l3->setExternalConnectionNodes(3,dqbus4); - l3->setExternalConnectionNodes(4,dqbus4 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - l3->setExternalConnectionNodes(5 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(l3); - - // loads - - //load 1 - ModelLib::MicrogridLoad *load1 = new ModelLib::MicrogridLoad(7, rload1, Lload1); - //ref motor - load1->setExternalConnectionNodes(0,vec_size_internals); - //input connections - load1->setExternalConnectionNodes(1,dqbus1); - load1->setExternalConnectionNodes(2,dqbus1 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - load1->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(load1); - - //load 2 - ModelLib::MicrogridLoad *load2 = new ModelLib::MicrogridLoad(8, rload2, Lload2); - //ref motor - load2->setExternalConnectionNodes(0,vec_size_internals); - //input connections - load2->setExternalConnectionNodes(1,dqbus3); - load2->setExternalConnectionNodes(2,dqbus3 + 1); - //internal connections - for (size_t i = 0; i < 2; i++) - { - - load2->setExternalConnectionNodes(3 + i,indexv + i); - } - indexv += 2; - sysmodel->addComponent(load2); - - //Virtual PQ Buses - ModelLib::MicrogridBusDQ *bus1 = new ModelLib::MicrogridBusDQ(9, RN); - - bus1->setExternalConnectionNodes(0,dqbus1); - bus1->setExternalConnectionNodes(1,dqbus1 + 1); - sysmodel->addComponent(bus1); - - ModelLib::MicrogridBusDQ *bus2 = new ModelLib::MicrogridBusDQ(10, RN); - - bus2->setExternalConnectionNodes(0,dqbus2); - bus2->setExternalConnectionNodes(1,dqbus2 + 1); - sysmodel->addComponent(bus2); - - ModelLib::MicrogridBusDQ *bus3 = new ModelLib::MicrogridBusDQ(11, RN); - - bus3->setExternalConnectionNodes(0,dqbus3); - bus3->setExternalConnectionNodes(1,dqbus3 + 1); - sysmodel->addComponent(bus3); - - ModelLib::MicrogridBusDQ *bus4 = new ModelLib::MicrogridBusDQ(12, RN); - - bus4->setExternalConnectionNodes(0,dqbus4); - bus4->setExternalConnectionNodes(1,dqbus4 + 1); - sysmodel->addComponent(bus4); - - sysmodel->allocate(vec_size_total); - - std::cout << sysmodel->y().size() << std::endl; - std::cout << vec_size_internals << ", " << vec_size_externals << "\n"; - - //Create Intial points for states - for (size_t i = 0; i < vec_size_total; i++) - { - sysmodel->y()[i] = 0.0; - sysmodel->yp()[i] = 0.0; - } - - // Create Intial derivatives specifics generated in MATLAB - //DGs 1 - sysmodel->yp()[2] = parms1.Vn; - sysmodel->yp()[4] = parms1.Kpv * parms1.Vn; - sysmodel->yp()[6] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; - sysmodel->yp()[12 + 3] = parms1.Vn; - sysmodel->yp()[12 + 5] = parms1.Kpv * parms1.Vn; - sysmodel->yp()[12 + 7] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; - for (size_t i = 2; i < 4; i++) - { - sysmodel->yp()[13*i - 1 + 3] = parms2.Vn; - sysmodel->yp()[13*i - 1 + 5] = parms2.Kpv * parms2.Vn; - sysmodel->yp()[13*i - 1 + 7] = (parms2.Kpc * parms2.Kpv * parms2.Vn) / parms2.Lf; - } - - //since the intial P_com = 0 - sysmodel->y()[vec_size_internals] = parms1.wb; - - - - sysmodel->initialize(); - sysmodel->evaluateResidual(); - - std::vector& fres = sysmodel->getResidual(); - std::cout << "Verify Intial Resisdual is Zero: {\n"; - for (size_t i = 0; i < fres.size(); i++) - { - printf("%u : %e \n", i, fres[i]); - } - std::cout << "}\n"; - - sysmodel->updateTime(0.0, 1.0e-8); - sysmodel->evaluateJacobian(); - std::cout << "Intial Jacobian with alpha:\n"; - // std::cout << sysmodel->getJacobian().frobnorm() << "\n"; - - - //Create numerical integrator and configure it for the generator model - AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); + double abstol = 1.0e-8; + double reltol = 1.0e-8; + size_t max_step_amount = 3000; + bool usejac = true; + + //TODO:setup as named parameters + //Create circuit model + ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac, max_step_amount); + + //Modeled after the problem in the paper + double RN = 1.0e4; + + //DG Params + + ModelLib::DistributedGeneratorParameters parms1; + parms1.wb = 2.0*M_PI*50.0; + parms1.wc = 31.41; + parms1.mp = 9.4e-5; + parms1.Vn = 380.0; + parms1.nq = 1.3e-3; + parms1.F = 0.75; + parms1.Kiv = 420.0; + parms1.Kpv = 0.1; + parms1.Kic = 2.0e4; + parms1.Kpc = 15.0; + parms1.Cf = 5.0e-5; + parms1.rLf = 0.1; + parms1.Lf = 1.35e-3; + parms1.rLc = 0.03; + parms1.Lc = 0.35e-3; + + ModelLib::DistributedGeneratorParameters parms2; + //Parameters from MATLAB Microgrid code for first DG + parms2.wb = 2.0*M_PI*50.0; + parms2.wc = 31.41; + parms2.mp = 12.5e-5; + parms2.Vn = 380.0; + parms2.nq = 1.5e-3; + parms2.F = 0.75; + parms2.Kiv = 390.0; + parms2.Kpv = 0.05; + parms2.Kic = 16.0e3; + parms2.Kpc = 10.5; + parms2.Cf = 50.0e-6; + parms2.rLf = 0.1; + parms2.Lf = 1.35e-3; + parms2.rLc = 0.03; + parms2.Lc = 0.35e-3; + + //Line params + double rline1 = 0.23; + double Lline1 = 0.1 / (2.0 * M_PI * 50.0); + + double rline2 = 0.35; + double Lline2 = 0.58 / (2.0 * M_PI * 50.0); + + double rline3 = 0.23; + double Lline3 = 0.1 / (2.0 * M_PI * 50.0); + + //load parms + double rload1 = 3.0; + double Lload1 = 2.0 / (2.0 * M_PI * 50.0); + + double rload2 = 2.0; + double Lload2 = 1.0 / (2.0 * M_PI * 50.0); + + + //indexing sets + size_t Nsize = 2; + // DGs + - refframe Lines + Loads + size_t vec_size_internals = 13*(2*Nsize) - 1 + (2 + 4*(Nsize - 1)) + 2*Nsize; + // \omegaref + BusDQ + size_t vec_size_externals = 1 + 2*(2*Nsize); + size_t dqbus1 = vec_size_internals + 1; + size_t dqbus2 = vec_size_internals + 3; + size_t dqbus3 = vec_size_internals + 5; + size_t dqbus4 = vec_size_internals + 7; + + size_t vec_size_total = vec_size_internals + vec_size_externals; + + + size_t indexv = 0; + + //dg 1 + ModelLib::DistributedGenerator *dg1 = new ModelLib::DistributedGenerator(0, parms1, true); + //ref motor + dg1->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg1->setExternalConnectionNodes(1,dqbus1); + dg1->setExternalConnectionNodes(2,dqbus1 + 1); + //"grounding" of the difference + dg1->setExternalConnectionNodes(3,-1); + //internal connections + for (size_t i = 0; i < 12; i++) + { + + dg1->setExternalConnectionNodes(4 + i,indexv + i); + } + indexv += 12; + sysmodel->addComponent(dg1); + + //dg 2 + ModelLib::DistributedGenerator *dg2 = new ModelLib::DistributedGenerator(1, parms1, false); + //ref motor + dg2->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg2->setExternalConnectionNodes(1,dqbus2); + dg2->setExternalConnectionNodes(2,dqbus2 + 1); + //internal connections + for (size_t i = 0; i < 13; i++) + { + + dg2->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg2); + + + //dg 3 + ModelLib::DistributedGenerator *dg3 = new ModelLib::DistributedGenerator(2, parms2, false); + //ref motor + dg3->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg3->setExternalConnectionNodes(1,dqbus3); + dg3->setExternalConnectionNodes(2,dqbus3 + 1); + //internal connections + for (size_t i = 0; i < 13; i++) + { + + dg3->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg3); + + + //dg 4 + ModelLib::DistributedGenerator *dg4 = new ModelLib::DistributedGenerator(3, parms2, false); + //ref motor + dg4->setExternalConnectionNodes(0,vec_size_internals); + //outputs + dg4->setExternalConnectionNodes(1,dqbus4); + dg4->setExternalConnectionNodes(2,dqbus4 + 1); + + //internal connections + for (size_t i = 0; i < 13; i++) + { + + dg4->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 13; + sysmodel->addComponent(dg4); + + // Lines + + //line 1 + ModelLib::MicrogridLine *l1 = new ModelLib::MicrogridLine(4, rline1, Lline1); + //ref motor + l1->setExternalConnectionNodes(0,vec_size_internals); + //input connections + l1->setExternalConnectionNodes(1,dqbus1); + l1->setExternalConnectionNodes(2,dqbus1 + 1); + //output connections + l1->setExternalConnectionNodes(3,dqbus2); + l1->setExternalConnectionNodes(4,dqbus2 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + l1->setExternalConnectionNodes(5 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(l1); + + + //line 2 + ModelLib::MicrogridLine *l2 = new ModelLib::MicrogridLine(5, rline2, Lline2); + //ref motor + l2->setExternalConnectionNodes(0,vec_size_internals); + //input connections + l2->setExternalConnectionNodes(1,dqbus2); + l2->setExternalConnectionNodes(2,dqbus2 + 1); + //output connections + l2->setExternalConnectionNodes(3,dqbus3); + l2->setExternalConnectionNodes(4,dqbus3 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + l2->setExternalConnectionNodes(5 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(l2); + + //line 3 + ModelLib::MicrogridLine *l3 = new ModelLib::MicrogridLine(6, rline3, Lline3); + //ref motor + l3->setExternalConnectionNodes(0,vec_size_internals); + //input connections + l3->setExternalConnectionNodes(1,dqbus3); + l3->setExternalConnectionNodes(2,dqbus3 + 1); + //output connections + l3->setExternalConnectionNodes(3,dqbus4); + l3->setExternalConnectionNodes(4,dqbus4 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + l3->setExternalConnectionNodes(5 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(l3); + + // loads + + //load 1 + ModelLib::MicrogridLoad *load1 = new ModelLib::MicrogridLoad(7, rload1, Lload1); + //ref motor + load1->setExternalConnectionNodes(0,vec_size_internals); + //input connections + load1->setExternalConnectionNodes(1,dqbus1); + load1->setExternalConnectionNodes(2,dqbus1 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + load1->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(load1); + + //load 2 + ModelLib::MicrogridLoad *load2 = new ModelLib::MicrogridLoad(8, rload2, Lload2); + //ref motor + load2->setExternalConnectionNodes(0,vec_size_internals); + //input connections + load2->setExternalConnectionNodes(1,dqbus3); + load2->setExternalConnectionNodes(2,dqbus3 + 1); + //internal connections + for (size_t i = 0; i < 2; i++) + { + + load2->setExternalConnectionNodes(3 + i,indexv + i); + } + indexv += 2; + sysmodel->addComponent(load2); + + //Virtual PQ Buses + ModelLib::MicrogridBusDQ *bus1 = new ModelLib::MicrogridBusDQ(9, RN); + + bus1->setExternalConnectionNodes(0,dqbus1); + bus1->setExternalConnectionNodes(1,dqbus1 + 1); + sysmodel->addComponent(bus1); + + ModelLib::MicrogridBusDQ *bus2 = new ModelLib::MicrogridBusDQ(10, RN); + + bus2->setExternalConnectionNodes(0,dqbus2); + bus2->setExternalConnectionNodes(1,dqbus2 + 1); + sysmodel->addComponent(bus2); + + ModelLib::MicrogridBusDQ *bus3 = new ModelLib::MicrogridBusDQ(11, RN); + + bus3->setExternalConnectionNodes(0,dqbus3); + bus3->setExternalConnectionNodes(1,dqbus3 + 1); + sysmodel->addComponent(bus3); + + ModelLib::MicrogridBusDQ *bus4 = new ModelLib::MicrogridBusDQ(12, RN); + + bus4->setExternalConnectionNodes(0,dqbus4); + bus4->setExternalConnectionNodes(1,dqbus4 + 1); + sysmodel->addComponent(bus4); + + sysmodel->allocate(vec_size_total); + + std::cout << sysmodel->y().size() << std::endl; + std::cout << vec_size_internals << ", " << vec_size_externals << "\n"; + + //Create Intial points for states + for (size_t i = 0; i < vec_size_total; i++) + { + sysmodel->y()[i] = 0.0; + sysmodel->yp()[i] = 0.0; + } + + // Create Intial derivatives specifics generated in MATLAB + //DGs 1 + sysmodel->yp()[2] = parms1.Vn; + sysmodel->yp()[4] = parms1.Kpv * parms1.Vn; + sysmodel->yp()[6] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; + sysmodel->yp()[12 + 3] = parms1.Vn; + sysmodel->yp()[12 + 5] = parms1.Kpv * parms1.Vn; + sysmodel->yp()[12 + 7] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; + for (size_t i = 2; i < 4; i++) + { + sysmodel->yp()[13*i - 1 + 3] = parms2.Vn; + sysmodel->yp()[13*i - 1 + 5] = parms2.Kpv * parms2.Vn; + sysmodel->yp()[13*i - 1 + 7] = (parms2.Kpc * parms2.Kpv * parms2.Vn) / parms2.Lf; + } + + //since the intial P_com = 0 + sysmodel->y()[vec_size_internals] = parms1.wb; + + + + sysmodel->initialize(); + sysmodel->evaluateResidual(); + + std::vector& fres = sysmodel->getResidual(); + std::cout << "Verify Intial Resisdual is Zero: {\n"; + for (size_t i = 0; i < fres.size(); i++) + { + printf("%u : %e \n", i, fres[i]); + } + std::cout << "}\n"; + + sysmodel->updateTime(0.0, 1.0e-8); + sysmodel->evaluateJacobian(); + std::cout << "Intial Jacobian with alpha:\n"; + // std::cout << sysmodel->getJacobian().frobnorm() << "\n"; + + + //Create numerical integrator and configure it for the generator model + AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); double t_init = 0.0; double t_final = 1.0; @@ -352,17 +352,17 @@ int main(int argc, char const *argv[]) idas->runSimulation(t_final); - std::vector& yfinial = sysmodel->y(); + std::vector& yfinial = sysmodel->y(); - std::cout << "Final Vector y\n"; - for (size_t i = 0; i < yfinial.size(); i++) - { - std::cout << yfinial[i] << "\n"; - } + std::cout << "Final Vector y\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << yfinial[i] << "\n"; + } - //Generate from MATLAB code ODE form with tolerances of 1e-12 - std::vectortrue_vec{ - 2.297543153595780e+04, + //Generate from MATLAB code ODE form with tolerances of 1e-12 + std::vectortrue_vec{ + 2.297543153595780e+04, 1.275311524125022e+04, 3.763060183116022e-02, -2.098153459325261e-02, @@ -432,13 +432,13 @@ int main(int argc, char const *argv[]) -3.272400970143252e+01, 3.604108939430972e+02, -3.492842627398574e+01 - }; + }; - std::cout << "Test the Relative Error\n"; - for (size_t i = 0; i < true_vec.size(); i++) - { - printf("%u : %e ,\n", i, abs(true_vec[i] - yfinial[i]) / abs(true_vec[i])); - } + std::cout << "Test the Relative Error\n"; + for (size_t i = 0; i < true_vec.size(); i++) + { + printf("%u : %e ,\n", i, abs(true_vec[i] - yfinial[i]) / abs(true_vec[i])); + } - return 0; + return 0; } diff --git a/Examples/RLCircuit/RLCircuit.cpp b/Examples/RLCircuit/RLCircuit.cpp index 55fe476b9..770307d8c 100644 --- a/Examples/RLCircuit/RLCircuit.cpp +++ b/Examples/RLCircuit/RLCircuit.cpp @@ -18,97 +18,97 @@ int main(int argc, char const *argv[]) { - double abstol = 1.0e-8; - double reltol = 1.0e-8; - bool usejac = true; - - //TODO:setup as named parameters - //Create circuit model - ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac); - - size_t idoff = 0; - - //RL circuit parameters - double rinit = 1.0; - double linit = 1.0; - double vinit = 1.0; - - - //inductor - ModelLib::Inductor* induct = new ModelLib::Inductor(idoff,linit); - //Form index to node uid realations - // input - induct->setExternalConnectionNodes(0,1); - //output - induct->setExternalConnectionNodes(1,-1); - //internal - induct->setExternalConnectionNodes(2,2); - //add component - sysmodel->addComponent(induct); - - - //resistor - idoff++; - ModelLib::Resistor* resis = new ModelLib::Resistor(idoff, rinit); - //Form index to node uid realations - //input - resis->setExternalConnectionNodes(0,0); - //output - resis->setExternalConnectionNodes(1,1); - //add - sysmodel->addComponent(resis); - - //voltage source - idoff++; - ModelLib::VoltageSource* vsource = new ModelLib::VoltageSource(idoff, vinit); - //Form index to node uid realations - //input - vsource->setExternalConnectionNodes(0,-1); - //output - vsource->setExternalConnectionNodes(1,0); - //internal - vsource->setExternalConnectionNodes(2,3); - - - sysmodel->addComponent(vsource); - - sysmodel->allocate(4); - - std::cout << sysmodel->y().size() << std::endl; - - //Grounding for IDA. If no grounding then circuit is \mu > 1 - //v_0 (grounded) - //Create Intial points - sysmodel->y()[0] = vinit; //v_1 - sysmodel->y()[1] = vinit; // v_2 - sysmodel->y()[2] = 0.0; // i_L - sysmodel->y()[3] = 0.0; // i_s - - sysmodel->yp()[0] = 0.0; // v'_1 - sysmodel->yp()[1] = 0.0; // v'_2 - sysmodel->yp()[2] = -vinit / linit; // i'_s - sysmodel->yp()[3] = -vinit / linit; // i'_L - - - sysmodel->initialize(); - sysmodel->evaluateResidual(); - - std::cout << "Verify Intial Resisdual is Zero: {"; - for (double i : sysmodel->getResidual()) - { - std::cout << i << ", "; - } - std::cout << "}\n"; - - - sysmodel->updateTime(0.0, 1.0); - sysmodel->evaluateJacobian(); - std::cout << "Intial Jacobian with alpha = 1:\n"; - sysmodel->getJacobian().printMatrix(); - - - // Create numerical integrator and configure it for the generator model - AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); + double abstol = 1.0e-8; + double reltol = 1.0e-8; + bool usejac = true; + + //TODO:setup as named parameters + //Create circuit model + ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac); + + size_t idoff = 0; + + //RL circuit parameters + double rinit = 1.0; + double linit = 1.0; + double vinit = 1.0; + + + //inductor + ModelLib::Inductor* induct = new ModelLib::Inductor(idoff,linit); + //Form index to node uid realations + // input + induct->setExternalConnectionNodes(0,1); + //output + induct->setExternalConnectionNodes(1,-1); + //internal + induct->setExternalConnectionNodes(2,2); + //add component + sysmodel->addComponent(induct); + + + //resistor + idoff++; + ModelLib::Resistor* resis = new ModelLib::Resistor(idoff, rinit); + //Form index to node uid realations + //input + resis->setExternalConnectionNodes(0,0); + //output + resis->setExternalConnectionNodes(1,1); + //add + sysmodel->addComponent(resis); + + //voltage source + idoff++; + ModelLib::VoltageSource* vsource = new ModelLib::VoltageSource(idoff, vinit); + //Form index to node uid realations + //input + vsource->setExternalConnectionNodes(0,-1); + //output + vsource->setExternalConnectionNodes(1,0); + //internal + vsource->setExternalConnectionNodes(2,3); + + + sysmodel->addComponent(vsource); + + sysmodel->allocate(4); + + std::cout << sysmodel->y().size() << std::endl; + + //Grounding for IDA. If no grounding then circuit is \mu > 1 + //v_0 (grounded) + //Create Intial points + sysmodel->y()[0] = vinit; //v_1 + sysmodel->y()[1] = vinit; // v_2 + sysmodel->y()[2] = 0.0; // i_L + sysmodel->y()[3] = 0.0; // i_s + + sysmodel->yp()[0] = 0.0; // v'_1 + sysmodel->yp()[1] = 0.0; // v'_2 + sysmodel->yp()[2] = -vinit / linit; // i'_s + sysmodel->yp()[3] = -vinit / linit; // i'_L + + + sysmodel->initialize(); + sysmodel->evaluateResidual(); + + std::cout << "Verify Intial Resisdual is Zero: {"; + for (double i : sysmodel->getResidual()) + { + std::cout << i << ", "; + } + std::cout << "}\n"; + + + sysmodel->updateTime(0.0, 1.0); + sysmodel->evaluateJacobian(); + std::cout << "Intial Jacobian with alpha = 1:\n"; + sysmodel->getJacobian().printMatrix(); + + + // Create numerical integrator and configure it for the generator model + AnalysisManager::Sundials::Ida* idas = new AnalysisManager::Sundials::Ida(sysmodel); double t_init = 0.0; double t_final = 1.0; @@ -120,27 +120,27 @@ int main(int argc, char const *argv[]) idas->runSimulation(t_final); - std::vector& yfinial = sysmodel->y(); - - std::cout << "Final Vector y\n"; - for (size_t i = 0; i < yfinial.size(); i++) - { - std::cout << yfinial[i] << "\n"; - } - - std::vector yexact(4); - - //analytical solution to the circuit - yexact[0] = vinit; - yexact[2] = (vinit / rinit) * (exp(-(rinit / linit) * t_final) - 1.0); - yexact[3] = yexact[2]; - yexact[1] = vinit + rinit * yexact[2]; - - std::cout << "Element-wise Relative error at t=" << t_final << "\n"; - for (size_t i = 0; i < yfinial.size(); i++) - { - std::cout << abs((yfinial[i] - yexact[i]) / yexact[i]) << "\n"; - } - - return 0; + std::vector& yfinial = sysmodel->y(); + + std::cout << "Final Vector y\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << yfinial[i] << "\n"; + } + + std::vector yexact(4); + + //analytical solution to the circuit + yexact[0] = vinit; + yexact[2] = (vinit / rinit) * (exp(-(rinit / linit) * t_final) - 1.0); + yexact[3] = yexact[2]; + yexact[1] = vinit + rinit * yexact[2]; + + std::cout << "Element-wise Relative error at t=" << t_final << "\n"; + for (size_t i = 0; i < yfinial.size(); i++) + { + std::cout << abs((yfinial[i] - yexact[i]) / yexact[i]) << "\n"; + } + + return 0; } diff --git a/Examples/SparseTest/SparseTest.cpp b/Examples/SparseTest/SparseTest.cpp index 81e5ac7dd..399151434 100644 --- a/Examples/SparseTest/SparseTest.cpp +++ b/Examples/SparseTest/SparseTest.cpp @@ -12,75 +12,75 @@ int main(int argc, char const *argv[]) { - std::vector val{0.1, 0.2, 0.3, 0.4}; - std::vector x{2,1,3,1}; - std::vector y{1,3,2,2}; - size_t n = 4; - size_t m = 4; - - COO_Matrix A = COO_Matrix(x,y,val,m,n); - - std::vector valn(4); - std::vector xn(4); - std::vector yn(4); - - std::tie(xn, yn, valn) = A.getEntries(); - - for (size_t i = 0; i < valn.size(); i++) - { - std::cout << valn[i] << "\n"; - } - - std::cout << "A:\n"; - A.printMatrix(); - - std::vector val2{0.5, 0.6, 0.7, 0.8, 1.0}; - std::vector x2{0,2,0,2,1}; - std::vector y2{3,3,2,2,3}; - COO_Matrix B = COO_Matrix(x2,y2,val2,m,n); - - std::cout << "B:\n"; - B.printMatrix(); - - A.AXPY(2.0, B); - - std::cout << "A + 2B:\n"; - A.printMatrix(); - - std::vector r; - std::vector c; - std::vector v; - std::tie(r,c,v) = A.getDataToCSR(); - - for (size_t i = 0; i < r.size() - 1; i++) - { - std::cout << r[i] << std::endl; - size_t rdiff = r[i+1] - r[i]; - for (size_t j = 0; j < rdiff; j++) - { - std::cout << c[j + r[i]] << ", " << v[j + r[i]] << std::endl; - } - } - std::cout << r[r.size()-1] << std::endl; - - //Basic Verification test - std::vector rtest = {0, 2, 4, 7, 8}; - std::vector ctest = {2,3,2,3,1,2,3,2}; - std::vector valtest = {1.4, 1.0, 0.4, 2.2, 0.1, 1.6, 1.2, 0.3}; - - assert(rtest.size() == r.size()); - assert(ctest.size() == c.size()); - assert(valtest.size() == v.size()); - - int failval = 0; - for (size_t i = 0; i < rtest.size(); i++) if (r[i] != rtest[i]) failval--; - for (size_t i = 0; i < ctest.size(); i++) - { - double vdiff = v[i] - valtest[i]; - if (c[i] != ctest[i] || -1e-14 > vdiff || vdiff > 1e-14) failval--; - } - - std::cout << failval << std::endl; - - return failval; + std::vector val{0.1, 0.2, 0.3, 0.4}; + std::vector x{2,1,3,1}; + std::vector y{1,3,2,2}; + size_t n = 4; + size_t m = 4; + + COO_Matrix A = COO_Matrix(x,y,val,m,n); + + std::vector valn(4); + std::vector xn(4); + std::vector yn(4); + + std::tie(xn, yn, valn) = A.getEntries(); + + for (size_t i = 0; i < valn.size(); i++) + { + std::cout << valn[i] << "\n"; + } + + std::cout << "A:\n"; + A.printMatrix(); + + std::vector val2{0.5, 0.6, 0.7, 0.8, 1.0}; + std::vector x2{0,2,0,2,1}; + std::vector y2{3,3,2,2,3}; + COO_Matrix B = COO_Matrix(x2,y2,val2,m,n); + + std::cout << "B:\n"; + B.printMatrix(); + + A.AXPY(2.0, B); + + std::cout << "A + 2B:\n"; + A.printMatrix(); + + std::vector r; + std::vector c; + std::vector v; + std::tie(r,c,v) = A.getDataToCSR(); + + for (size_t i = 0; i < r.size() - 1; i++) + { + std::cout << r[i] << std::endl; + size_t rdiff = r[i+1] - r[i]; + for (size_t j = 0; j < rdiff; j++) + { + std::cout << c[j + r[i]] << ", " << v[j + r[i]] << std::endl; + } + } + std::cout << r[r.size()-1] << std::endl; + + //Basic Verification test + std::vector rtest = {0, 2, 4, 7, 8}; + std::vector ctest = {2,3,2,3,1,2,3,2}; + std::vector valtest = {1.4, 1.0, 0.4, 2.2, 0.1, 1.6, 1.2, 0.3}; + + assert(rtest.size() == r.size()); + assert(ctest.size() == c.size()); + assert(valtest.size() == v.size()); + + int failval = 0; + for (size_t i = 0; i < rtest.size(); i++) if (r[i] != rtest[i]) failval--; + for (size_t i = 0; i < ctest.size(); i++) + { + double vdiff = v[i] - valtest[i]; + if (c[i] != ctest[i] || -1e-14 > vdiff || vdiff > 1e-14) failval--; + } + + std::cout << failval << std::endl; + + return failval; } diff --git a/SparseMatrix/COO_Matrix.hpp b/SparseMatrix/COO_Matrix.hpp index dc99d7b9e..70da77a1e 100644 --- a/SparseMatrix/COO_Matrix.hpp +++ b/SparseMatrix/COO_Matrix.hpp @@ -20,63 +20,63 @@ template class COO_Matrix { private: - std::vector values; - std::vector row_indexes; - std::vector column_indexes; - Intdx rows_size; - Intdx columns_size; - bool sorted; + std::vector values; + std::vector row_indexes; + std::vector column_indexes; + Intdx rows_size; + Intdx columns_size; + bool sorted; public: - //Constructors - COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n); - COO_Matrix(Intdx m, Intdx n); - COO_Matrix(); - ~COO_Matrix(); + //Constructors + COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n); + COO_Matrix(Intdx m, Intdx n); + COO_Matrix(); + ~COO_Matrix(); - //Operations + //Operations - // --- Functions which call sort --- - std::tuple, std::vector> getRowCopy(Intdx r); - std::tuple&, std::vector&, std::vector&> getEntries(); - std::tuple, std::vector, std::vector> getEntrieCopies(); - std::tuple, std::vector, std::vector> getEntrieCopiesSubMatrix(std::vector submap); + // --- Functions which call sort --- + std::tuple, std::vector> getRowCopy(Intdx r); + std::tuple&, std::vector&, std::vector&> getEntries(); + std::tuple, std::vector, std::vector> getEntrieCopies(); + std::tuple, std::vector, std::vector> getEntrieCopiesSubMatrix(std::vector submap); - std::tuple, std::vector, std::vector> getDataToCSR(); - std::vector getCSRRowData(); + std::tuple, std::vector, std::vector> getDataToCSR(); + std::vector getCSRRowData(); - // BLAS. Will sort before running - void setValues(std::vector r, std::vector c, std::vector v); - void AXPY(ScalarT alpha, COO_Matrix& a); - void AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v); - void SCAL(ScalarT alpha); - ScalarT frobnorm(); + // BLAS. Will sort before running + void setValues(std::vector r, std::vector c, std::vector v); + void AXPY(ScalarT alpha, COO_Matrix& a); + void AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v); + void SCAL(ScalarT alpha); + ScalarT frobnorm(); - // --- Permutation Operations --- - //No sorting is actually done. Only done when nesscary - void permutation(std::vector row_perm, std::vector col_perm); - void permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n); + // --- Permutation Operations --- + //No sorting is actually done. Only done when nesscary + void permutation(std::vector row_perm, std::vector col_perm); + void permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n); - void zeroMatrix(); + void zeroMatrix(); - void identityMatrix(Intdx n); + void identityMatrix(Intdx n); - //Resort values - void sortSparse(); - bool isSorted(); - Intdx nnz(); + //Resort values + void sortSparse(); + bool isSorted(); + Intdx nnz(); - std::tuple getDimensions(); + std::tuple getDimensions(); - void printMatrix(); + void printMatrix(); - - static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values); + + static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values); private: - Intdx indexStartRow(const std::vector &rows, Intdx r); - Intdx sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci); - bool checkIncreaseSize(Intdx r, Intdx c); + Intdx indexStartRow(const std::vector &rows, Intdx r); + Intdx sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci); + bool checkIncreaseSize(Intdx r, Intdx c); }; @@ -91,25 +91,25 @@ class COO_Matrix template inline std::tuple, std::vector> COO_Matrix::getRowCopy(Intdx r) { - if (!this->sorted) - { - this->sortSparse(); - } - Intdx rowindex = this->indexStartRow(r); - - - if (rowindex == -1) - { - return {std::vector(),std::vector()}; - } - - Intdx rsize = rowindex; - do - { - rsize++; - } while (rsize < this->values.size() && this->row_indexes[rsize] == r); - - return {{this->column_indexes.begin() + rowindex, this->column_indexes.begin() + rsize},{this->values.begin() + rowindex, this->values.begin() + rsize}}; + if (!this->sorted) + { + this->sortSparse(); + } + Intdx rowindex = this->indexStartRow(r); + + + if (rowindex == -1) + { + return {std::vector(),std::vector()}; + } + + Intdx rsize = rowindex; + do + { + rsize++; + } while (rsize < this->values.size() && this->row_indexes[rsize] == r); + + return {{this->column_indexes.begin() + rowindex, this->column_indexes.begin() + rsize},{this->values.begin() + rowindex, this->values.begin() + rsize}}; } /** @@ -122,11 +122,11 @@ inline std::tuple, std::vector> COO_Matrix inline std::tuple&, std::vector&, std::vector&> COO_Matrix::getEntries() { - if (!this->sorted) - { - this->sortSparse(); - } - return {this->row_indexes, this->column_indexes, this->values}; + if (!this->sorted) + { + this->sortSparse(); + } + return {this->row_indexes, this->column_indexes, this->values}; } /** @@ -139,11 +139,11 @@ inline std::tuple&, std::vector&, std::vector template inline std::tuple, std::vector, std::vector> COO_Matrix::getEntrieCopies() { - if (!this->sorted) - { - this->sortSparse(); - } - return {this->row_indexes, this->column_indexes, this->values}; + if (!this->sorted) + { + this->sortSparse(); + } + return {this->row_indexes, this->column_indexes, this->values}; } /** @@ -156,19 +156,19 @@ inline std::tuple, std::vector, std::vector> template inline std::tuple, std::vector, std::vector> COO_Matrix::getDataToCSR() { - if (!this->isSorted()) this->sortSparse(); - std::vector rowsizevec(this->rows_size + 1, 0); - Intdx counter = 0; - for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) - { - rowsizevec[i + 1] = rowsizevec[i]; - while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) - { - rowsizevec[i+1]++; - counter++; - } - } - return {rowsizevec, this->column_indexes, this->values}; + if (!this->isSorted()) this->sortSparse(); + std::vector rowsizevec(this->rows_size + 1, 0); + Intdx counter = 0; + for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) + { + rowsizevec[i + 1] = rowsizevec[i]; + while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) + { + rowsizevec[i+1]++; + counter++; + } + } + return {rowsizevec, this->column_indexes, this->values}; } /** @@ -185,19 +185,19 @@ inline std::tuple, std::vector, std::vector> template inline std::vector COO_Matrix::getCSRRowData() { - if (!this->isSorted()) this->sortSparse(); - std::vector rowsizevec(this->rows_size + 1, 0); - Intdx counter = 0; - for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) - { - rowsizevec[i + 1] = rowsizevec[i]; - while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) - { - rowsizevec[i+1]++; - counter++; - } - } - return rowsizevec; + if (!this->isSorted()) this->sortSparse(); + std::vector rowsizevec(this->rows_size + 1, 0); + Intdx counter = 0; + for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) + { + rowsizevec[i + 1] = rowsizevec[i]; + while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) + { + rowsizevec[i+1]++; + counter++; + } + } + return rowsizevec; } /** @@ -212,44 +212,44 @@ inline std::vector COO_Matrix::getCSRRowData() template inline void COO_Matrix::setValues(std::vector r, std::vector c, std::vector v) { - //sort input - this->sortSparseCOO(r, c, v); - - - //Duplicated with AXPY. Could replace with function depdent on lambda expression - Intdx aiter = 0; - //iterate for all current values in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) - { - //pushback values when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) - { - this->row_indexes.push_back(r[aiter]); - this->column_indexes.push_back(c[aiter]); - this->values.push_back(v[aiter]); - this->checkIncreaseSize(r[aiter], c[aiter]); - aiter++; - } - if (aiter >= static_cast(r.size())) break; - - - if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) - { - this->values[i] = v[aiter]; - aiter++; - } - } - //push back rest that was not found sorted - for (Intdx i = aiter; i < static_cast(r.size()); i++) - { - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(v[i]); - - this->checkIncreaseSize(r[i], c[i]); - } - - this->sorted = false; + //sort input + this->sortSparseCOO(r, c, v); + + + //Duplicated with AXPY. Could replace with function depdent on lambda expression + Intdx aiter = 0; + //iterate for all current values in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + { + //pushback values when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + { + this->row_indexes.push_back(r[aiter]); + this->column_indexes.push_back(c[aiter]); + this->values.push_back(v[aiter]); + this->checkIncreaseSize(r[aiter], c[aiter]); + aiter++; + } + if (aiter >= static_cast(r.size())) break; + + + if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + { + this->values[i] = v[aiter]; + aiter++; + } + } + //push back rest that was not found sorted + for (Intdx i = aiter; i < static_cast(r.size()); i++) + { + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(v[i]); + + this->checkIncreaseSize(r[i], c[i]); + } + + this->sorted = false; } @@ -264,60 +264,60 @@ inline void COO_Matrix::setValues(std::vector r, std::vec template inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrix& a) { - if (alpha == 0) return; - - if (!this->sorted) - { - this->sortSparse(); - } - if (!a.isSorted()) - { - a.sortSparse(); - } - Intdx m = 0; - Intdx n = 0; - std::tuple&, std::vector&, std::vector&> tpm = a.getEntries(); - const auto& [r, c, val] = tpm; - std::tie(m,n) = a.getDimensions(); - - //Increase size as nesscary - this->rows_size = this->rows_size > m ? this->rows_size : m; - this->columns_size = this->columns_size > n ? this->columns_size : n; - - Intdx aiter = 0; - //iterate for all current values in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) - { - //pushback values when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) - { - this->row_indexes.push_back(r[aiter]); - this->column_indexes.push_back(c[aiter]); - this->values.push_back(alpha * val[aiter]); - - this->checkIncreaseSize(r[aiter], c[aiter]); - aiter++; - } - if (aiter >= static_cast(r.size())) break; - - - if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) - { - this->values[i] += alpha * val[aiter]; - aiter++; - } - } - //push back rest that was not found sorted - for (Intdx i = aiter; i < static_cast(r.size()); i++) - { - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(alpha * val[i]); - - this->checkIncreaseSize(r[i], c[i]); - } - - this->sorted = false; + if (alpha == 0) return; + + if (!this->sorted) + { + this->sortSparse(); + } + if (!a.isSorted()) + { + a.sortSparse(); + } + Intdx m = 0; + Intdx n = 0; + std::tuple&, std::vector&, std::vector&> tpm = a.getEntries(); + const auto& [r, c, val] = tpm; + std::tie(m,n) = a.getDimensions(); + + //Increase size as nesscary + this->rows_size = this->rows_size > m ? this->rows_size : m; + this->columns_size = this->columns_size > n ? this->columns_size : n; + + Intdx aiter = 0; + //iterate for all current values in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + { + //pushback values when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + { + this->row_indexes.push_back(r[aiter]); + this->column_indexes.push_back(c[aiter]); + this->values.push_back(alpha * val[aiter]); + + this->checkIncreaseSize(r[aiter], c[aiter]); + aiter++; + } + if (aiter >= static_cast(r.size())) break; + + + if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + { + this->values[i] += alpha * val[aiter]; + aiter++; + } + } + //push back rest that was not found sorted + for (Intdx i = aiter; i < static_cast(r.size()); i++) + { + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(alpha * val[i]); + + this->checkIncreaseSize(r[i], c[i]); + } + + this->sorted = false; } /** @@ -333,50 +333,50 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrix inline void COO_Matrix::AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v) { - if (alpha == 0) return; - - if (!this->sorted) - { - this->sortSparse(); - } - - //sort input - this->sortSparseCOO(r, c, v); - - Intdx aiter = 0; - //iterate for all current values in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) - { - //pushback values when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) - { - this->row_indexes.push_back(r[aiter]); - this->column_indexes.push_back(c[aiter]); - this->values.push_back(alpha * v[aiter]); - - this->checkIncreaseSize(r[aiter], c[aiter]); - aiter++; - } - if (aiter >= static_cast(r.size())) break; - - - if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) - { - this->values[i] += alpha * v[aiter]; - aiter++; - } - } - //push back rest that was not found sorted - for (Intdx i = aiter; i < static_cast(r.size()); i++) - { - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(alpha * v[i]); - - this->checkIncreaseSize(r[i], c[i]); - } - - this->sorted = false; + if (alpha == 0) return; + + if (!this->sorted) + { + this->sortSparse(); + } + + //sort input + this->sortSparseCOO(r, c, v); + + Intdx aiter = 0; + //iterate for all current values in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + { + //pushback values when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + { + this->row_indexes.push_back(r[aiter]); + this->column_indexes.push_back(c[aiter]); + this->values.push_back(alpha * v[aiter]); + + this->checkIncreaseSize(r[aiter], c[aiter]); + aiter++; + } + if (aiter >= static_cast(r.size())) break; + + + if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + { + this->values[i] += alpha * v[aiter]; + aiter++; + } + } + //push back rest that was not found sorted + for (Intdx i = aiter; i < static_cast(r.size()); i++) + { + this->row_indexes.push_back(r[i]); + this->column_indexes.push_back(c[i]); + this->values.push_back(alpha * v[i]); + + this->checkIncreaseSize(r[i], c[i]); + } + + this->sorted = false; } /** @@ -389,15 +389,15 @@ inline void COO_Matrix::AXPY(ScalarT alpha, std::vector r template inline void COO_Matrix::SCAL(ScalarT alpha) { - for (auto i = this->values.begin(); i < this->values.end(); i++) *i *= alpha; + for (auto i = this->values.begin(); i < this->values.end(); i++) *i *= alpha; } template inline ScalarT COO_Matrix::frobnorm() { - ScalarT totsum = 0.0; - for (auto i = this->values.begin(); i < this->values.end(); i++) totsum += abs(*i)^2; - return totsum; + ScalarT totsum = 0.0; + for (auto i = this->values.begin(); i < this->values.end(); i++) totsum += abs(*i)^2; + return totsum; } /** @@ -411,16 +411,16 @@ inline ScalarT COO_Matrix::frobnorm() template inline void COO_Matrix::permutation(std::vector row_perm, std::vector col_perm) { - assert(row_perm.size() = this->rows_size); - assert(col_perm.size() = this->columns_size); - - for (int i = 0; i < this->values.size(); i++) - { - this->row_indexes[i] = row_perm[this->row_indexes[i]]; - this->column_indexes[i] = col_perm[this->column_indexes[i]]; - } - this->sorted = false; - //cycle sorting maybe useful since permutations are already known + assert(row_perm.size() = this->rows_size); + assert(col_perm.size() = this->columns_size); + + for (int i = 0; i < this->values.size(); i++) + { + this->row_indexes[i] = row_perm[this->row_indexes[i]]; + this->column_indexes[i] = col_perm[this->column_indexes[i]]; + } + this->sorted = false; + //cycle sorting maybe useful since permutations are already known } /** @@ -437,25 +437,25 @@ inline void COO_Matrix::permutation(std::vector row_perm, template inline void COO_Matrix::permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n) { - assert(row_perm.size() == this->rows_size); - assert(col_perm.size() == this->columns_size); - - this->rows_size = m; - this->columns_size = n; - - for (int i = 0; i < this->values.size(); i++) - { - if (row_perm[this->row_indexes[i]] == -1 || col_perm[this->column_indexes[i]] == -1) - { - this->values[i] = 0; - } - else - { - this->row_indexes[i] = row_perm[this->row_indexes[i]]; - this->column_indexes[i] = col_perm[this->column_indexes[i]]; - } - } - this->sorted = false; + assert(row_perm.size() == this->rows_size); + assert(col_perm.size() == this->columns_size); + + this->rows_size = m; + this->columns_size = n; + + for (int i = 0; i < this->values.size(); i++) + { + if (row_perm[this->row_indexes[i]] == -1 || col_perm[this->column_indexes[i]] == -1) + { + this->values[i] = 0; + } + else + { + this->row_indexes[i] = row_perm[this->row_indexes[i]]; + this->column_indexes[i] = col_perm[this->column_indexes[i]]; + } + } + this->sorted = false; } /** @@ -467,25 +467,25 @@ inline void COO_Matrix::permutationSizeMap(std::vector ro template inline void COO_Matrix::zeroMatrix() { - //resize doesn't effect capacity if smaller - this->column_indexes.resize(0); - this->row_indexes.resize(0); - this->values.resize(0); - this->sorted = true; + //resize doesn't effect capacity if smaller + this->column_indexes.resize(0); + this->row_indexes.resize(0); + this->values.resize(0); + this->sorted = true; } template inline void COO_Matrix::identityMatrix(Intdx n) { - //Reset Matrix - this->zeroMatrix(); - for (Intdx i = 0; i < n; i++) - { - this->column_indexes[i] = i; - this->row_indexes[i] = i; - this->values[i] = 1.0; - } - this->sorted = true; + //Reset Matrix + this->zeroMatrix(); + for (Intdx i = 0; i < n; i++) + { + this->column_indexes[i] = i; + this->row_indexes[i] = i; + this->values[i] = 1.0; + } + this->sorted = true; } /** @@ -497,26 +497,26 @@ inline void COO_Matrix::identityMatrix(Intdx n) template inline void COO_Matrix::sortSparse() { - this->sortSparseCOO(this->row_indexes, this->column_indexes, this->values); - this->sorted = true; + this->sortSparseCOO(this->row_indexes, this->column_indexes, this->values); + this->sorted = true; } template inline bool COO_Matrix::isSorted() { - return this->sorted; + return this->sorted; } template inline Intdx COO_Matrix::nnz() { - return static_cast(this->values.size); + return static_cast(this->values.size); } template inline std::tuple COO_Matrix::getDimensions() { - return std::tuple(this->rows_size, this->columns_size); + return std::tuple(this->rows_size, this->columns_size); } /** @@ -528,19 +528,19 @@ inline std::tuple COO_Matrix::getDimensions() template inline void COO_Matrix::printMatrix() { - if (this->sorted == false) - { - this->sortSparse(); - } - - std::cout << "Sparse COO Matrix\n"; - std::cout << "(x , y, value)\n"; - for (size_t i = 0; i < this->values.size(); i++) - { - std::cout << "(" << this->row_indexes[i] - << ", " << this->column_indexes[i] - << ", " << this->values[i] << ")\n"; - } + if (this->sorted == false) + { + this->sortSparse(); + } + + std::cout << "Sparse COO Matrix\n"; + std::cout << "(x , y, value)\n"; + for (size_t i = 0; i < this->values.size(); i++) + { + std::cout << "(" << this->row_indexes[i] + << ", " << this->column_indexes[i] + << ", " << this->values[i] << ")\n"; + } } /** @@ -555,36 +555,36 @@ inline void COO_Matrix::printMatrix() template inline Intdx COO_Matrix::indexStartRow(const std::vector &rows, Intdx r) { - //Specialized Binary Search for Lowest Row - Intdx i1 = 0; - Intdx i2 = rows->size()-1; - Intdx m_smallest = -1; - Intdx m = -1; - while (i1 <= i2) - { - m = (i2 + i1) / 2; - //rows - if (rows[m] < r) - { - i1 = m + 1; - } - else if (r < rows[m]) - { - i2 = m - 1; - } - else - { - if (i1 == i2) - { - return m_smallest; - } - - //Keep track of smallest cordinate - m_smallest = m; - i2 = m - 1; - } - } - return m_smallest; + //Specialized Binary Search for Lowest Row + Intdx i1 = 0; + Intdx i2 = rows->size()-1; + Intdx m_smallest = -1; + Intdx m = -1; + while (i1 <= i2) + { + m = (i2 + i1) / 2; + //rows + if (rows[m] < r) + { + i1 = m + 1; + } + else if (r < rows[m]) + { + i2 = m - 1; + } + else + { + if (i1 == i2) + { + return m_smallest; + } + + //Keep track of smallest cordinate + m_smallest = m; + i2 = m - 1; + } + } + return m_smallest; } /** @@ -601,56 +601,56 @@ inline Intdx COO_Matrix::indexStartRow(const std::vector template inline Intdx COO_Matrix::sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci) { - assert(rows.size() == columns.size()); - //basic binary search - Intdx i1 = 0; - Intdx i2 = rows.size()-1; - Intdx m = 0; - while (i1 <= i2) - { - m = (i2 + i1) / 2; - //rows - if (rows[m] < ri) - { - i1 = m + 1; - } - else if (ri < rows[m]) - { - i2 = m - 1; - } - else - { - if (columns[m] < ci) - { - i1 = m + 1; - } - else if (ci < columns[m]) - { - i2 = m - 1; - } - break; - } - } - - return m; + assert(rows.size() == columns.size()); + //basic binary search + Intdx i1 = 0; + Intdx i2 = rows.size()-1; + Intdx m = 0; + while (i1 <= i2) + { + m = (i2 + i1) / 2; + //rows + if (rows[m] < ri) + { + i1 = m + 1; + } + else if (ri < rows[m]) + { + i2 = m - 1; + } + else + { + if (columns[m] < ci) + { + i1 = m + 1; + } + else if (ci < columns[m]) + { + i2 = m - 1; + } + break; + } + } + + return m; } template inline bool COO_Matrix::checkIncreaseSize(Intdx r, Intdx c) { - bool changed = false; - if (r + 1 > this->rows_size) - { - this->rows_size = r + 1; - changed = true; - } - if (c + 1 > this->columns_size) - { - this->columns_size = c + 1; - changed = true; - } - - return changed; + bool changed = false; + if (r + 1 > this->rows_size) + { + this->rows_size = r + 1; + changed = true; + } + if (c + 1 > this->columns_size) + { + this->columns_size = c + 1; + changed = true; + } + + return changed; } /** @@ -667,75 +667,75 @@ inline bool COO_Matrix::checkIncreaseSize(Intdx r, Intdx c) template inline void COO_Matrix::sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values) { - - //index based sort code - // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted-vector - //cannot call sort since two arrays are used instead + + //index based sort code + // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted-vector + //cannot call sort since two arrays are used instead std::vector ordervec(rows.size()); std::size_t n(0); std::generate(std::begin(ordervec), std::end(ordervec), [&]{ return n++; }); - //Sort by row first then column. + //Sort by row first then column. std::sort( std::begin(ordervec), std::end(ordervec), [&](int i1, int i2) { return (rows[i1] < rows[i2]) || - (rows[i1] == rows[i2] && columns[i1] < columns[i2]); } ); - - - //reorder based of index-sorting. Only swap cost no extra memory. - // @todo see if extra memory creation is fine - // https://stackoverflow.com/a/22183350 - for (size_t i = 0; i < ordervec.size(); i++) - { - //permutation swap - while (ordervec[i] != ordervec[ordervec[i]]) - { - std::swap(rows[ordervec[i]], rows[ordervec[ordervec[i]]]); - std::swap(columns[ordervec[i]], columns[ordervec[ordervec[i]]]); - std::swap(values[ordervec[i]], values[ordervec[ordervec[i]]]); - - //swap orderings - std::swap(ordervec[i], ordervec[ordervec[i]]); - } - - } + (rows[i1] == rows[i2] && columns[i1] < columns[i2]); } ); + + + //reorder based of index-sorting. Only swap cost no extra memory. + // @todo see if extra memory creation is fine + // https://stackoverflow.com/a/22183350 + for (size_t i = 0; i < ordervec.size(); i++) + { + //permutation swap + while (ordervec[i] != ordervec[ordervec[i]]) + { + std::swap(rows[ordervec[i]], rows[ordervec[ordervec[i]]]); + std::swap(columns[ordervec[i]], columns[ordervec[ordervec[i]]]); + std::swap(values[ordervec[i]], values[ordervec[ordervec[i]]]); + + //swap orderings + std::swap(ordervec[i], ordervec[ordervec[i]]); + } + + } } template inline COO_Matrix::COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n) { - this->values = v; - this->row_indexes = r; - this->column_indexes = c; - this->rows_size = m; - this->columns_size = n; - this->sorted = false; + this->values = v; + this->row_indexes = r; + this->column_indexes = c; + this->rows_size = m; + this->columns_size = n; + this->sorted = false; } template inline COO_Matrix::COO_Matrix(Intdx m, Intdx n) { - this->rows_size = m; - this->columns_size = n; - this->values = std::vector(); - this->row_indexes = std::vector(); - this->column_indexes = std::vector(); - this->sorted = false; + this->rows_size = m; + this->columns_size = n; + this->values = std::vector(); + this->row_indexes = std::vector(); + this->column_indexes = std::vector(); + this->sorted = false; } template inline COO_Matrix::COO_Matrix() { - this->rows_size = 0; - this->columns_size = 0; - this->values = std::vector(); - this->row_indexes = std::vector(); - this->column_indexes = std::vector(); - this->sorted = false; + this->rows_size = 0; + this->columns_size = 0; + this->values = std::vector(); + this->row_indexes = std::vector(); + this->column_indexes = std::vector(); + this->sorted = false; } template COO_Matrix::~COO_Matrix() { - + } From 17a0cb7e2370d322173e49621d2932102e1a44c1 Mon Sep 17 00:00:00 2001 From: Reid Date: Tue, 9 Apr 2024 21:57:45 -0400 Subject: [PATCH 38/44] Formatting Fix Composer-Dev (#6) * Merge Ida Fix * Fixed Whitespace Editor Changes * Tabs to Spaces Ida.cpp --- ModelEvaluatorImpl.hpp | 99 ++-- Solver/Dynamic/Ida.cpp | 1069 ++++++++++++++++++++-------------------- 2 files changed, 593 insertions(+), 575 deletions(-) diff --git a/ModelEvaluatorImpl.hpp b/ModelEvaluatorImpl.hpp index 3e9a4cef6..0f8969f0b 100644 --- a/ModelEvaluatorImpl.hpp +++ b/ModelEvaluatorImpl.hpp @@ -77,28 +77,27 @@ namespace ModelLib typedef typename ModelEvaluator::real_type real_type; ModelEvaluatorImpl() - : size_(0), - size_quad_(0), - size_opt_(0) - { - } + : size_(0), + size_quad_(0), + size_opt_(0) + {} ModelEvaluatorImpl(IdxT size, IdxT size_quad, IdxT size_opt) - : size_(size), - size_quad_(size_quad), - size_opt_(size_opt), - y_(size_), - yp_(size_), - f_(size_), - g_(size_quad_), - yB_(size_), - ypB_(size_), - fB_(size_), - gB_(size_opt_), - J_(COO_Matrix()), - param_(size_opt_), - param_up_(size_opt_), - param_lo_(size_opt_) + : size_(size), + size_quad_(size_quad), + size_opt_(size_opt), + y_(size_), + yp_(size_), + f_(size_), + g_(size_quad_), + yB_(size_), + ypB_(size_), + fB_(size_), + gB_(size_opt_), + J_(COO_Matrix()), + param_(size_opt_), + param_up_(size_opt_), + param_lo_(size_opt_) { } @@ -134,143 +133,143 @@ namespace ModelLib // std::cout << "updateTime: t = " << time_ << "\n"; // } - virtual void setTolerances(real_type &rtol, real_type &atol) const + virtual void setTolerances(real_type& rtol, real_type& atol) const { rtol = rtol_; atol = atol_; } - virtual void setMaxSteps(IdxT &msa) const + virtual void setMaxSteps(IdxT& msa) const { msa = max_steps_; } - std::vector &y() + std::vector& y() { return y_; } - const std::vector &y() const + const std::vector& y() const { return y_; } - std::vector &yp() + std::vector& yp() { return yp_; } - const std::vector &yp() const + const std::vector& yp() const { return yp_; } - std::vector &tag() + std::vector& tag() { return tag_; } - const std::vector &tag() const + const std::vector& tag() const { return tag_; } - std::vector &yB() + std::vector& yB() { return yB_; } - const std::vector &yB() const + const std::vector& yB() const { return yB_; } - std::vector &ypB() + std::vector& ypB() { return ypB_; } - const std::vector &ypB() const + const std::vector& ypB() const { return ypB_; } - std::vector ¶m() + std::vector& param() { return param_; } - const std::vector ¶m() const + const std::vector& param() const { return param_; } - std::vector ¶m_up() + std::vector& param_up() { return param_up_; } - const std::vector ¶m_up() const + const std::vector& param_up() const { return param_up_; } - std::vector ¶m_lo() + std::vector& param_lo() { return param_lo_; } - const std::vector ¶m_lo() const + const std::vector& param_lo() const { return param_lo_; } - std::vector &getResidual() + std::vector& getResidual() { return f_; } - const std::vector &getResidual() const + const std::vector& getResidual() const { return f_; } - COO_Matrix &getJacobian() + COO_Matrix& getJacobian() { return J_; } - const COO_Matrix &getJacobian() const + const COO_Matrix& getJacobian() const { return J_; } - std::vector &getIntegrand() + std::vector& getIntegrand() { return g_; } - const std::vector &getIntegrand() const + const std::vector& getIntegrand() const { return g_; } - std::vector &getAdjointResidual() + std::vector& getAdjointResidual() { return fB_; } - const std::vector &getAdjointResidual() const + const std::vector& getAdjointResidual() const { return fB_; } - std::vector &getAdjointIntegrand() + std::vector& getAdjointIntegrand() { return gB_; } - const std::vector &getAdjointIntegrand() const + const std::vector& getAdjointIntegrand() const { return gB_; } @@ -281,6 +280,8 @@ namespace ModelLib return idc_; } + + protected: IdxT size_; IdxT nnz_; @@ -313,8 +314,10 @@ namespace ModelLib IdxT max_steps_; IdxT idc_; + }; + } // namespace ModelLib #endif // _MODEL_EVALUATOR_IMPL_HPP_ \ No newline at end of file diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index 3ae6854c4..fbe7c8973 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -57,703 +57,718 @@ * */ + #include #include -#include /* access to IDADls interface */ +#include /* access to IDADls interface */ #include -// Sundials Sparse KLU +//Sundials Sparse KLU #include -#include +#include #include "ModelEvaluator.hpp" #include "Ida.hpp" + namespace AnalysisManager { - namespace Sundials - { +namespace Sundials +{ - template - Ida::Ida(ModelLib::ModelEvaluator *model) : DynamicSolver(model) - { - int retval = 0; + template + Ida::Ida(ModelLib::ModelEvaluator* model) : DynamicSolver(model) + { + int retval = 0; - // Create the SUNDIALS context that all SUNDIALS objects require - retval = SUNContext_Create(NULL, &context_); - checkOutput(retval, "SUNContext"); - solver_ = IDACreate(context_); - tag_ = NULL; - } + // Create the SUNDIALS context that all SUNDIALS objects require + retval = SUNContext_Create(NULL, &context_); + checkOutput(retval, "SUNContext"); + solver_ = IDACreate(context_); + tag_ = NULL; + } - template - Ida::~Ida() - { - } + template + Ida::~Ida() + { + } - template - int Ida::configureSimulation() - { - int retval = 0; + template + int Ida::configureSimulation() + { + int retval = 0; - // Allocate solution vectors - yy_ = N_VNew_Serial(model_->size(), context_); - checkAllocation((void *)yy_, "N_VNew_Serial"); - yp_ = N_VClone(yy_); - checkAllocation((void *)yp_, "N_VClone"); + // Allocate solution vectors + yy_ = N_VNew_Serial(model_->size(), context_); + checkAllocation((void*) yy_, "N_VNew_Serial"); + yp_ = N_VClone(yy_); + checkAllocation((void*) yp_, "N_VClone"); - // get intial conditions - this->getDefaultInitialCondition(); + //get intial conditions + this->getDefaultInitialCondition(); - // Create vectors to store restart initial condition - yy0_ = N_VClone(yy_); - checkAllocation((void *)yy0_, "N_VClone"); - yp0_ = N_VClone(yy_); - checkAllocation((void *)yp0_, "N_VClone"); + // Create vectors to store restart initial condition + yy0_ = N_VClone(yy_); + checkAllocation((void*) yy0_, "N_VClone"); + yp0_ = N_VClone(yy_); + checkAllocation((void*) yp0_, "N_VClone"); - // Dummy initial time; will be overridden. - const realtype t0 = RCONST(0.0); + // Dummy initial time; will be overridden. + const realtype t0 = RCONST(0.0); - // Allocate and initialize IDA workspace - retval = IDAInit(solver_, this->Residual, t0, yy_, yp_); - checkOutput(retval, "IDAInit"); + // Allocate and initialize IDA workspace + retval = IDAInit(solver_, this->Residual, t0, yy_, yp_); + checkOutput(retval, "IDAInit"); - // Set pointer to model data - retval = IDASetUserData(solver_, model_); - checkOutput(retval, "IDASetUserData"); + // Set pointer to model data + retval = IDASetUserData(solver_, model_); + checkOutput(retval, "IDASetUserData"); - // Set tolerances - realtype rtol; - realtype atol; + // Set tolerances + realtype rtol; + realtype atol; - model_->setTolerances(rtol, atol); ///< \todo Function name should be "getTolerances"! - retval = IDASStolerances(solver_, rtol, atol); - checkOutput(retval, "IDASStolerances"); + model_->setTolerances(rtol, atol); ///< \todo Function name should be "getTolerances"! + retval = IDASStolerances(solver_, rtol, atol); + checkOutput(retval, "IDASStolerances"); + + IdxT msa; + model_->setMaxSteps(msa); - IdxT msa; - model_->setMaxSteps(msa); + /// \todo Need to set max number of steps based on user input! + retval = IDASetMaxNumSteps(solver_, msa); + checkOutput(retval, "IDASetMaxNumSteps"); - /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumSteps(solver_, msa); - checkOutput(retval, "IDASetMaxNumSteps"); + // Tag differential variables + std::vector& tag = model_->tag(); + if (static_cast(tag.size()) == model_->size()) + { + tag_ = N_VClone(yy_); + checkAllocation((void*) tag_, "N_VClone"); + model_->tagDifferentiable(); + copyVec(tag, tag_); - // Tag differential variables - std::vector &tag = model_->tag(); - if (static_cast(tag.size()) == model_->size()) - { - tag_ = N_VClone(yy_); - checkAllocation((void *)tag_, "N_VClone"); - model_->tagDifferentiable(); - copyVec(tag, tag_); - - retval = IDASetId(solver_, tag_); - checkOutput(retval, "IDASetId"); - retval = IDASetSuppressAlg(solver_, SUNTRUE); - checkOutput(retval, "IDASetSuppressAlg"); - } + retval = IDASetId(solver_, tag_); + checkOutput(retval, "IDASetId"); + retval = IDASetSuppressAlg(solver_, SUNTRUE); + checkOutput(retval, "IDASetSuppressAlg"); + } - // Set up linear solver - this->configureLinearSolver(); + // Set up linear solver + this->configureLinearSolver(); - return retval; - } + return retval; + } - template - int Ida::configureLinearSolver() + template + int Ida::configureLinearSolver() + { + int retval = 0; + if (model_->hasJacobian()) { - int retval = 0; - //Setup KLU for when Jacobian is needed - if (model_->hasJacobian()) - { - JacobianMat_ = SUNSparseMatrix(model_->size(), model_->size(), model_->size() * model_->size(), CSR_MAT, context_); - checkAllocation((void *)JacobianMat_, "SUNSparseMatrix"); + JacobianMat_ = SUNSparseMatrix(model_->size(), model_->size(), model_->size() * model_->size(), CSR_MAT, context_); + checkAllocation((void*) JacobianMat_, "SUNSparseMatrix"); - linearSolver_ = SUNLinSol_KLU(yy_, JacobianMat_, context_); - checkAllocation((void *)linearSolver_, "SUNLinSol_KLU"); + linearSolver_ = SUNLinSol_KLU(yy_, JacobianMat_, context_); + checkAllocation((void*) linearSolver_, "SUNLinSol_KLU"); - retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "IDASetLinearSolver"); + retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "IDASetLinearSolver"); - retval = IDASetJacFn(solver_, this->Jac); - checkOutput(retval, "IDASetJacFn"); - } - else - { - JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void *)JacobianMat_, "SUNDenseMatrix"); + retval = IDASetJacFn(solver_, this->Jac); + checkOutput(retval, "IDASetJacFn"); + } + else + { + JacobianMat_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void*) JacobianMat_, "SUNDenseMatrix"); - linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); - checkAllocation((void *)linearSolver_, "SUNLinSol_Dense"); + linearSolver_ = SUNLinSol_Dense(yy_, JacobianMat_, context_); + checkAllocation((void*) linearSolver_, "SUNLinSol_Dense"); - retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); - checkOutput(retval, "IDASetLinearSolver"); - } + retval = IDASetLinearSolver(solver_, linearSolver_, JacobianMat_); + checkOutput(retval, "IDASetLinearSolver"); - return retval; } - template - int Ida::getDefaultInitialCondition() - { - model_->initialize(); + return retval; + } - copyVec(model_->y(), yy_); - copyVec(model_->yp(), yp_); + template + int Ida::getDefaultInitialCondition() + { + model_->initialize(); - return 0; - } + copyVec(model_->y(), yy_); + copyVec(model_->yp(), yp_); - template - int Ida::setIntegrationTime(real_type t_init, real_type t_final, int nout) - { - t_init_ = t_init; - t_final_ = t_final; - nout_ = nout; - return 0; - } + return 0; + } - template - int Ida::initializeSimulation(real_type t0, bool findConsistent) - { - int retval = 0; + template + int Ida::setIntegrationTime(real_type t_init, real_type t_final, int nout) + { + t_init_ = t_init; + t_final_ = t_final; + nout_ = nout; + return 0; + } + + template + int Ida::initializeSimulation(real_type t0, bool findConsistent) + { + int retval = 0; - // Need to reinitialize IDA to set to get correct initial conditions - retval = IDAReInit(solver_, t0, yy_, yp_); - checkOutput(retval, "IDAReInit"); + // Need to reinitialize IDA to set to get correct initial conditions + retval = IDAReInit(solver_, t0, yy_, yp_); + checkOutput(retval, "IDAReInit"); - // Find a consistent set of initial conditions for DAE - if (findConsistent) - { - int initType = IDA_Y_INIT; - - if (tag_) - initType = IDA_YA_YDP_INIT; + // Find a consistent set of initial conditions for DAE + if (findConsistent) + { + int initType = IDA_Y_INIT; - retval = IDACalcIC(solver_, initType, 0.1); - checkOutput(retval, "IDACalcIC"); - } + if (tag_) + initType = IDA_YA_YDP_INIT; - return retval; + retval = IDACalcIC(solver_, initType, 0.1); + checkOutput(retval, "IDACalcIC"); } - template - int Ida::runSimulation(real_type tf, int nout) - { - int retval = 0; - int iout = 0; - real_type tret; - real_type dt = tf / nout; - real_type tout = dt; - - /* In loop, call IDASolve, print results, and test for error. - * Break out of loop when NOUT preset output times have been reached. */ - // printOutput(0.0); - while (nout > iout) + return retval; + } + + template + int Ida::runSimulation(real_type tf, int nout) + { + int retval = 0; + int iout = 0; + real_type tret; + real_type dt = tf/nout; + real_type tout = dt; + + /* In loop, call IDASolve, print results, and test for error. + * Break out of loop when NOUT preset output times have been reached. */ + //printOutput(0.0); + while(nout > iout) + { + retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); + checkOutput(retval, "IDASolve"); + //printOutput(tout); + + if (retval == IDA_SUCCESS) { - retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); - checkOutput(retval, "IDASolve"); - // printOutput(tout); - - if (retval == IDA_SUCCESS) - { - ++iout; - tout += dt; - } + ++iout; + tout += dt; } - // std::cout << "\n"; - return retval; } + //std::cout << "\n"; + return retval; + } - template - int Ida::deleteSimulation() - { - IDAFree(&solver_); - SUNLinSolFree(linearSolver_); - N_VDestroy(yy_); - N_VDestroy(yp_); - return 0; - } + template + int Ida::deleteSimulation() + { + IDAFree(&solver_); + SUNLinSolFree(linearSolver_); + N_VDestroy(yy_); + N_VDestroy(yp_); + return 0; + } - template - int Ida::configureQuadrature() - { - int retval = 0; - // Create and initialize quadratures - q_ = N_VNew_Serial(model_->size_quad(), context_); - checkAllocation((void *)q_, "N_VNew_Serial"); + template + int Ida::configureQuadrature() + { + int retval = 0; - // Set integrand function and allocate quadrature workspace - retval = IDAQuadInit(solver_, this->Integrand, q_); - checkOutput(retval, "IDAQuadInit"); + // Create and initialize quadratures + q_ = N_VNew_Serial(model_->size_quad(), context_); + checkAllocation((void*) q_, "N_VNew_Serial"); - // Set tolerances and error control for quadratures - real_type rtol, atol; - model_->setTolerances(rtol, atol); + // Set integrand function and allocate quadrature workspace + retval = IDAQuadInit(solver_, this->Integrand, q_); + checkOutput(retval, "IDAQuadInit"); - // Set tolerances for quadrature stricter than for integration - retval = IDAQuadSStolerances(solver_, rtol * 0.1, atol * 0.1); - checkOutput(retval, "IDAQuadSStolerances"); + // Set tolerances and error control for quadratures + real_type rtol, atol; + model_->setTolerances(rtol, atol); - // Include quadrature in eror checking - retval = IDASetQuadErrCon(solver_, SUNTRUE); - checkOutput(retval, "IDASetQuadErrCon"); + // Set tolerances for quadrature stricter than for integration + retval = IDAQuadSStolerances(solver_, rtol*0.1, atol*0.1); + checkOutput(retval, "IDAQuadSStolerances"); - return retval; - } + // Include quadrature in eror checking + retval = IDASetQuadErrCon(solver_, SUNTRUE); + checkOutput(retval, "IDASetQuadErrCon"); - template - int Ida::initializeQuadrature() - { - int retval = 0; + return retval; + } - // Set all quadratures to zero - N_VConst(RCONST(0.0), q_); - // Initialize quadratures - retval = IDAQuadReInit(solver_, q_); - checkOutput(retval, "IDAQuadInit"); + template + int Ida::initializeQuadrature() + { + int retval = 0; - return retval; - } + // Set all quadratures to zero + N_VConst(RCONST(0.0), q_); - template - int Ida::runSimulationQuadrature(real_type tf, int nout) - { - int retval = 0; - real_type tret; + // Initialize quadratures + retval = IDAQuadReInit(solver_, q_); + checkOutput(retval, "IDAQuadInit"); - // std::cout << "Forward integration for initial value problem ... \n"; + return retval; + } - real_type dt = tf / nout; - real_type tout = dt; - // printOutput(0.0); - // printSpecial(0.0, yy_); - for (int i = 0; i < nout; ++i) + + template + int Ida::runSimulationQuadrature(real_type tf, int nout) + { + int retval = 0; + real_type tret; + + //std::cout << "Forward integration for initial value problem ... \n"; + + real_type dt = tf/nout; + real_type tout = dt; + //printOutput(0.0); + //printSpecial(0.0, yy_); + for(int i = 0; i < nout; ++i) + { + retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); + checkOutput(retval, "IDASolve"); + //printSpecial(tout, yy_); + //printOutput(tout); + + if (retval == IDA_SUCCESS) { - retval = IDASolve(solver_, tout, &tret, yy_, yp_, IDA_NORMAL); - checkOutput(retval, "IDASolve"); - // printSpecial(tout, yy_); - // printOutput(tout); - - if (retval == IDA_SUCCESS) - { - tout += dt; - } - - retval = IDAGetQuad(solver_, &tret, q_); - checkOutput(retval, "IDAGetQuad"); + tout += dt; } - return retval; + retval = IDAGetQuad(solver_, &tret, q_); + checkOutput(retval, "IDAGetQuad"); } - template - int Ida::deleteQuadrature() - { - IDAQuadFree(solver_); - N_VDestroy(q_); + return retval; + } - return 0; - } - template - int Ida::configureAdjoint() - { - // Allocate adjoint vector, derivatives and quadrature - yyB_ = N_VNew_Serial(model_->size(), context_); - checkAllocation((void *)yyB_, "N_VNew_Serial"); + template + int Ida::deleteQuadrature() + { + IDAQuadFree(solver_); + N_VDestroy(q_); - ypB_ = N_VClone(yyB_); - checkAllocation((void *)ypB_, "N_VClone"); + return 0; + } - qB_ = N_VNew_Serial(model_->size_opt(), context_); - checkAllocation((void *)qB_, "N_VNew_Serial"); - return 0; - } + template + int Ida::configureAdjoint() + { + // Allocate adjoint vector, derivatives and quadrature + yyB_ = N_VNew_Serial(model_->size(), context_); + checkAllocation((void*) yyB_, "N_VNew_Serial"); - template - int Ida::initializeAdjoint(IdxT steps) - { - int retval = 0; + ypB_ = N_VClone(yyB_); + checkAllocation((void*) ypB_, "N_VClone"); - // Create adjoint workspace - retval = IDAAdjInit(solver_, steps, IDA_HERMITE); - checkOutput(retval, "IDAAdjInit"); + qB_ = N_VNew_Serial(model_->size_opt(), context_); + checkAllocation((void*) qB_, "N_VNew_Serial"); - return retval; - } + return 0; + } - template - int Ida::initializeBackwardSimulation(real_type tf) - { - int retval = 0; - realtype rtol; - realtype atol; + template + int Ida::initializeAdjoint(IdxT steps) + { + int retval = 0; + + // Create adjoint workspace + retval = IDAAdjInit(solver_, steps, IDA_HERMITE); + checkOutput(retval, "IDAAdjInit"); + + return retval; + } + + template + int Ida::initializeBackwardSimulation(real_type tf) + { + int retval = 0; + realtype rtol; + realtype atol; - model_->initializeAdjoint(); + model_->initializeAdjoint(); - copyVec(model_->yB(), yyB_); - copyVec(model_->ypB(), ypB_); - N_VConst(0.0, qB_); + copyVec(model_->yB(), yyB_); + copyVec(model_->ypB(), ypB_); + N_VConst(0.0, qB_); - retval = IDACreateB(solver_, &backwardID_); - checkOutput(retval, "IDACreateB"); + retval = IDACreateB(solver_, &backwardID_); + checkOutput(retval, "IDACreateB"); - // IDAInitB must be called after forward simulation run. - retval = IDAInitB(solver_, backwardID_, this->adjointResidual, tf, yyB_, ypB_); - checkOutput(retval, "IDAInitB"); + // IDAInitB must be called after forward simulation run. + retval = IDAInitB(solver_, backwardID_, this->adjointResidual, tf, yyB_, ypB_); + checkOutput(retval, "IDAInitB"); - model_->setTolerances(rtol, atol); - retval = IDASStolerancesB(solver_, backwardID_, rtol, atol); - checkOutput(retval, "IDASStolerancesB"); + model_->setTolerances(rtol, atol); + retval = IDASStolerancesB(solver_, backwardID_, rtol, atol); + checkOutput(retval, "IDASStolerancesB"); - retval = IDASetUserDataB(solver_, backwardID_, model_); - checkOutput(retval, "IDASetUserDataB"); + retval = IDASetUserDataB(solver_, backwardID_, model_); + checkOutput(retval, "IDASetUserDataB"); /// \todo Need to set max number of steps based on user input! retval = IDASetMaxNumStepsB(solver_, backwardID_, 2000); checkOutput(retval, "IDASetMaxNumSteps"); - // Set up linear solver - JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void *)JacobianMatB_, "SUNDenseMatrix"); + // Set up linear solver + JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void*) JacobianMatB_, "SUNDenseMatrix"); - linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); - checkAllocation((void *)linearSolverB_, "SUNLinSol_Dense"); + linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); + checkAllocation((void*) linearSolverB_, "SUNLinSol_Dense"); - retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); - checkOutput(retval, "IDASetLinearSolverB"); + retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); + checkOutput(retval, "IDASetLinearSolverB"); - // Also reinitialize quadratures. - retval = IDAQuadInitB(solver_, backwardID_, this->adjointIntegrand, qB_); - checkOutput(retval, "IDAQuadInitB"); - // retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol*1.1, atol*1.1); - retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol * 0.1, atol * 0.1); - checkOutput(retval, "IDAQuadSStolerancesB"); + // Also reinitialize quadratures. + retval = IDAQuadInitB(solver_, backwardID_, this->adjointIntegrand, qB_); + checkOutput(retval, "IDAQuadInitB"); - // Include quadratures in error control - retval = IDASetQuadErrConB(solver_, backwardID_, SUNTRUE); - checkOutput(retval, "IDASetQuadErrConB"); + //retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol*1.1, atol*1.1); + retval = IDAQuadSStolerancesB(solver_, backwardID_, rtol*0.1, atol*0.1); + checkOutput(retval, "IDAQuadSStolerancesB"); - return retval; - } + // Include quadratures in error control + retval = IDASetQuadErrConB(solver_, backwardID_, SUNTRUE); + checkOutput(retval, "IDASetQuadErrConB"); - template - int Ida::configureLinearSolverBackward() - { - int retval = 0; - // Create Jacobian matrix - JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); - checkAllocation((void *)JacobianMatB_, "SUNDenseMatrix"); + return retval; + } - // Create linear solver - linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); - checkAllocation((void *)linearSolverB_, "SUNLinSol_Dense"); + template + int Ida::configureLinearSolverBackward() + { + int retval = 0; - // Attach linear solver to IDA - retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); - checkOutput(retval, "IDASetLinearSolverB"); + // Create Jacobian matrix + JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); + checkAllocation((void*) JacobianMatB_, "SUNDenseMatrix"); - return retval; - } + // Create linear solver + linearSolverB_ = SUNLinSol_Dense(yyB_, JacobianMatB_, context_); + checkAllocation((void*) linearSolverB_, "SUNLinSol_Dense"); - template - int Ida::runForwardSimulation(real_type tf, int nout) - { - int retval = 0; - int ncheck; - real_type time; + // Attach linear solver to IDA + retval = IDASetLinearSolverB(solver_, backwardID_, linearSolverB_, JacobianMatB_); + checkOutput(retval, "IDASetLinearSolverB"); - // std::cout << "Forward integration for adjoint analysis ... \n"; + return retval; + } - real_type dt = tf / nout; - real_type tout = dt; - for (int i = 0; i < nout; ++i) - { - retval = IDASolveF(solver_, tout, &time, yy_, yp_, IDA_NORMAL, &ncheck); - checkOutput(retval, "IDASolveF"); + template + int Ida::runForwardSimulation(real_type tf, int nout) + { + int retval = 0; + int ncheck; + real_type time; + + //std::cout << "Forward integration for adjoint analysis ... \n"; - if (retval == IDA_SUCCESS) - { - tout += dt; - } + real_type dt = tf/nout; + real_type tout = dt; + for(int i = 0; i < nout; ++i) + { + retval = IDASolveF(solver_, tout, &time, yy_, yp_, IDA_NORMAL, &ncheck); + checkOutput(retval, "IDASolveF"); - retval = IDAGetQuad(solver_, &time, q_); - checkOutput(retval, "IDASolve"); + if (retval == IDA_SUCCESS) + { + tout += dt; } - return retval; + retval = IDAGetQuad(solver_, &time, q_); + checkOutput(retval, "IDASolve"); } - template - int Ida::runBackwardSimulation(real_type t_init) - { - int retval = 0; - long int nstB; - real_type time; + return retval; + } - // std::cout << "Backward integration for adjoint analysis ... "; + template + int Ida::runBackwardSimulation(real_type t_init) + { + int retval = 0; + long int nstB; + real_type time; - retval = IDASolveB(solver_, t_init, IDA_NORMAL); - checkOutput(retval, "IDASolveB"); + //std::cout << "Backward integration for adjoint analysis ... "; - IDAGetNumSteps(IDAGetAdjIDABmem(solver_, backwardID_), &nstB); - // std::cout << "done ( nst = " << nstB << " )\n"; + retval = IDASolveB(solver_, t_init, IDA_NORMAL); + checkOutput(retval, "IDASolveB"); - retval = IDAGetB(solver_, backwardID_, &time, yyB_, ypB_); - checkOutput(retval, "IDAGetB"); + IDAGetNumSteps(IDAGetAdjIDABmem(solver_, backwardID_), &nstB); + //std::cout << "done ( nst = " << nstB << " )\n"; - retval = IDAGetQuadB(solver_, backwardID_, &time, qB_); - checkOutput(retval, "IDAGetQuadB"); + retval = IDAGetB(solver_, backwardID_, &time, yyB_, ypB_); + checkOutput(retval, "IDAGetB"); - return retval; - } + retval = IDAGetQuadB(solver_, backwardID_, &time, qB_); + checkOutput(retval, "IDAGetQuadB"); - template - int Ida::deleteAdjoint() - { - IDAAdjFree(solver_); - return 0; - } - - template - int Ida::Residual(realtype tres, N_Vector yy, N_Vector yp, N_Vector rr, void *user_data) - { - ModelLib::ModelEvaluator *model = static_cast *>(user_data); + return retval; + } - model->updateTime(tres, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); + template + int Ida::deleteAdjoint() + { + IDAAdjFree(solver_); + return 0; + } - model->evaluateResidual(); - const std::vector &f = model->getResidual(); - copyVec(f, rr); + template + int Ida::Residual(realtype tres, N_Vector yy, N_Vector yp, N_Vector rr, void *user_data) + { + ModelLib::ModelEvaluator* model = static_cast*>(user_data); - return 0; - } + model->updateTime(tres, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); - template - int Ida::Jac(realtype t, realtype cj, N_Vector yy, N_Vector yp, N_Vector resvec, SUNMatrix J, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) - { + model->evaluateResidual(); + const std::vector& f = model->getResidual(); + copyVec(f, rr); - ModelLib::ModelEvaluator *model = static_cast *>(user_data); + return 0; + } - model->updateTime(t, cj); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); + template + int Ida::Jac(realtype t, realtype cj, N_Vector yy, N_Vector yp, N_Vector resvec, SUNMatrix J, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) + { - model->evaluateJacobian(); - COO_Matrix Jac = model->getJacobian(); + ModelLib::ModelEvaluator* model = static_cast*>(user_data); - // Get reference to the jacobian entries - std::tuple &, std::vector &, std::vector &> tpm = Jac.getEntries(); - const auto [r, c, val] = tpm; - // get the CSR row pointers from COO matrix - std::vector csrrowdata = Jac.getCSRRowData(); + model->updateTime(t, cj); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); - SUNMatZero(J); + model->evaluateJacobian(); + COO_Matrix Jac = model->getJacobian(); + + //Get reference to the jacobian entries + std::tuple&, std::vector&, std::vector&> tpm = Jac.getEntries(); + const auto [r, c, val] = tpm; - // Set row pointers - sunindextype *rowptrs = SUNSparseMatrix_IndexPointers(J); - for (unsigned int i = 0; i < csrrowdata.size(); i++) - { - rowptrs[i] = csrrowdata[i]; - } + //get the CSR row pointers from COO matrix + std::vector csrrowdata = Jac.getCSRRowData(); - sunindextype *colvals = SUNSparseMatrix_IndexValues(J); - realtype *data = SUNSparseMatrix_Data(J); - // Copy data from model jac to sundials - for (unsigned int i = 0; i < c.size(); i++) - { - colvals[i] = c[i]; - data[i] = val[i]; - } + SUNMatZero(J); - return 0; + //Set row pointers + sunindextype *rowptrs = SUNSparseMatrix_IndexPointers(J); + for (unsigned int i = 0; i < csrrowdata.size() ; i++) + { + rowptrs[i] = csrrowdata[i]; } - template - int Ida::Integrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector rhsQ, void *user_data) + sunindextype *colvals = SUNSparseMatrix_IndexValues(J); + realtype *data = SUNSparseMatrix_Data(J); + //Copy data from model jac to sundials + for (unsigned int i = 0; i < c.size(); i++ ) { - ModelLib::ModelEvaluator *model = static_cast *>(user_data); + colvals[i] = c[i]; + data[i] = val[i]; + } - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); + return 0; + } - model->evaluateIntegrand(); - const std::vector &g = model->getIntegrand(); - copyVec(g, rhsQ); + template + int Ida::Integrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector rhsQ, void *user_data) + { + ModelLib::ModelEvaluator* model = static_cast*>(user_data); - return 0; - } + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); - template - int Ida::adjointResidual(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rrB, void *user_data) - { - ModelLib::ModelEvaluator *model = static_cast *>(user_data); + model->evaluateIntegrand(); + const std::vector& g = model->getIntegrand(); + copyVec(g, rhsQ); - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); - copyVec(yyB, model->yB()); - copyVec(ypB, model->ypB()); + return 0; + } - model->evaluateAdjointResidual(); - const std::vector &fB = model->getAdjointResidual(); - copyVec(fB, rrB); + template + int Ida::adjointResidual(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rrB, void *user_data) + { + ModelLib::ModelEvaluator* model = static_cast*>(user_data); - return 0; - } + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); + copyVec(yyB, model->yB()); + copyVec(ypB, model->ypB()); - template - int Ida::adjointIntegrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rhsQB, void *user_data) - { - ModelLib::ModelEvaluator *model = static_cast *>(user_data); + model->evaluateAdjointResidual(); + const std::vector& fB = model->getAdjointResidual(); + copyVec(fB, rrB); - model->updateTime(tt, 0.0); - copyVec(yy, model->y()); - copyVec(yp, model->yp()); - copyVec(yyB, model->yB()); - copyVec(ypB, model->ypB()); + return 0; + } - model->evaluateAdjointIntegrand(); - const std::vector &gB = model->getAdjointIntegrand(); - copyVec(gB, rhsQB); - return 0; - } + template + int Ida::adjointIntegrand(realtype tt, N_Vector yy, N_Vector yp, N_Vector yyB, N_Vector ypB, N_Vector rhsQB, void *user_data) + { + ModelLib::ModelEvaluator* model = static_cast*>(user_data); + + model->updateTime(tt, 0.0); + copyVec(yy, model->y()); + copyVec(yp, model->yp()); + copyVec(yyB, model->yB()); + copyVec(ypB, model->ypB()); + + model->evaluateAdjointIntegrand(); + const std::vector& gB = model->getAdjointIntegrand(); + copyVec(gB, rhsQB); + + return 0; + } + - template - void Ida::copyVec(const N_Vector x, std::vector &y) + template + void Ida::copyVec(const N_Vector x, std::vector< ScalarT >& y) + { + const ScalarT* xdata = NV_DATA_S(x); + for(unsigned int i = 0; i < y.size(); ++i) { - const ScalarT *xdata = NV_DATA_S(x); - for (unsigned int i = 0; i < y.size(); ++i) - { - y[i] = xdata[i]; - } + y[i] = xdata[i]; } + } + - template - void Ida::copyVec(const std::vector &x, N_Vector y) + template + void Ida::copyVec(const std::vector< ScalarT >& x, N_Vector y) + { + ScalarT* ydata = NV_DATA_S(y); + for(unsigned int i = 0; i < x.size(); ++i) { - ScalarT *ydata = NV_DATA_S(y); - for (unsigned int i = 0; i < x.size(); ++i) - { - ydata[i] = x[i]; - } + ydata[i] = x[i]; } + } - template - void Ida::copyVec(const std::vector &x, N_Vector y) + template + void Ida::copyVec(const std::vector< bool >& x, N_Vector y) + { + ScalarT* ydata = NV_DATA_S(y); + for(unsigned int i = 0; i < x.size(); ++i) { - ScalarT *ydata = NV_DATA_S(y); - for (unsigned int i = 0; i < x.size(); ++i) - { - if (x[i]) - ydata[i] = 1.0; - else - ydata[i] = 0.0; - } + if (x[i]) + ydata[i] = 1.0; + else + ydata[i] = 0.0; } + } - template - void Ida::printOutput(realtype t) - { - realtype *yval = N_VGetArrayPointer_Serial(yy_); - realtype *ypval = N_VGetArrayPointer_Serial(yp_); - std::cout << std::setprecision(5) << std::setw(7) << t << " "; - for (IdxT i = 0; i < model_->size(); ++i) - { - std::cout << yval[i] << " "; - } - for (IdxT i = 0; i < model_->size(); ++i) - { - std::cout << ypval[i] << " "; - } - std::cout << "\n"; - } + template + void Ida::printOutput(realtype t) + { + realtype *yval = N_VGetArrayPointer_Serial(yy_); + realtype *ypval = N_VGetArrayPointer_Serial(yp_); - template - void Ida::printSpecial(realtype t, N_Vector y) + std::cout << std::setprecision(5) << std::setw(7) << t << " "; + for (IdxT i = 0; i < model_->size(); ++i) { - realtype *yval = N_VGetArrayPointer_Serial(y); - IdxT N = static_cast(N_VGetLength_Serial(y)); - std::cout << "{"; - std::cout << std::setprecision(5) << std::setw(7) << t; - for (IdxT i = 0; i < N; ++i) - { - std::cout << ", " << yval[i]; - } - std::cout << "},\n"; + std::cout << yval[i] << " "; + } + for (IdxT i = 0; i < model_->size(); ++i) + { + std::cout << ypval[i] << " "; } + std::cout << "\n"; + } - template - void Ida::printFinalStats() + template + void Ida::printSpecial(realtype t, N_Vector y) + { + realtype *yval = N_VGetArrayPointer_Serial(y); + IdxT N = static_cast(N_VGetLength_Serial(y)); + std::cout << "{"; + std::cout << std::setprecision(5) << std::setw(7) << t; + for (IdxT i = 0; i < N; ++i) { - int retval = 0; - void *mem = solver_; - long int nst; - long int nre; - long int nje; - long int nni; - long int netf; - long int ncfn; - - retval = IDAGetNumSteps(mem, &nst); - checkOutput(retval, "IDAGetNumSteps"); - retval = IDAGetNumResEvals(mem, &nre); - checkOutput(retval, "IDAGetNumResEvals"); - retval = IDAGetNumJacEvals(mem, &nje); - checkOutput(retval, "IDAGetNumJacEvals"); - retval = IDAGetNumNonlinSolvIters(mem, &nni); - checkOutput(retval, "IDAGetNumNonlinSolvIters"); - retval = IDAGetNumErrTestFails(mem, &netf); - checkOutput(retval, "IDAGetNumErrTestFails"); - retval = IDAGetNumNonlinSolvConvFails(mem, &ncfn); - checkOutput(retval, "IDAGetNumNonlinSolvConvFails"); - - // std::cout << "\nFinal Run Statistics: \n\n"; - std::cout << "Number of steps = " << nst << "\n"; - std::cout << "Number of residual evaluations = " << nre << "\n"; - // std::cout << "Number of Jacobian evaluations = " << nje << "\n"; - std::cout << "Number of nonlinear iterations = " << nni << "\n"; - std::cout << "Number of error test failures = " << netf << "\n"; - std::cout << "Number of nonlinear conv. failures = " << ncfn << "\n"; + std::cout << ", " << yval[i]; } + std::cout << "},\n"; + } - template - void Ida::checkAllocation(void *v, const char *functionName) + template + void Ida::printFinalStats() + { + int retval = 0; + void* mem = solver_; + long int nst; + long int nre; + long int nje; + long int nni; + long int netf; + long int ncfn; + + retval = IDAGetNumSteps(mem, &nst); + checkOutput(retval, "IDAGetNumSteps"); + retval = IDAGetNumResEvals(mem, &nre); + checkOutput(retval, "IDAGetNumResEvals"); + retval = IDAGetNumJacEvals(mem, &nje); + checkOutput(retval, "IDAGetNumJacEvals"); + retval = IDAGetNumNonlinSolvIters(mem, &nni); + checkOutput(retval, "IDAGetNumNonlinSolvIters"); + retval = IDAGetNumErrTestFails(mem, &netf); + checkOutput(retval, "IDAGetNumErrTestFails"); + retval = IDAGetNumNonlinSolvConvFails(mem, &ncfn); + checkOutput(retval, "IDAGetNumNonlinSolvConvFails"); + + // std::cout << "\nFinal Run Statistics: \n\n"; + std::cout << "Number of steps = " << nst << "\n"; + std::cout << "Number of residual evaluations = " << nre << "\n"; + //std::cout << "Number of Jacobian evaluations = " << nje << "\n"; + std::cout << "Number of nonlinear iterations = " << nni << "\n"; + std::cout << "Number of error test failures = " << netf << "\n"; + std::cout << "Number of nonlinear conv. failures = " << ncfn << "\n"; + } + + + template + void Ida::checkAllocation(void* v, const char* functionName) + { + if (v == NULL) { - if (v == NULL) - { - std::cerr << "\nERROR: Function " << functionName << " failed -- returned NULL pointer!\n\n"; - throw SundialsException(); - } + std::cerr << "\nERROR: Function " << functionName << " failed -- returned NULL pointer!\n\n"; + throw SundialsException(); } + } - template - void Ida::checkOutput(int retval, const char *functionName) + template + void Ida::checkOutput(int retval, const char* functionName) + { + if (retval < 0) { - if (retval < 0) - { - std::cerr << "\nERROR: Function " << functionName << " failed with flag " << retval << "!\n\n"; - throw SundialsException(); - } + std::cerr << "\nERROR: Function " << functionName << " failed with flag " << retval << "!\n\n"; + throw SundialsException(); } + } - // Compiler will prevent building modules with data type incompatible with realtype - template class Ida; - template class Ida; - template class Ida; + // Compiler will prevent building modules with data type incompatible with realtype + template class Ida; + template class Ida; + template class Ida; - } // namespace Sundials +} // namespace Sundials } // namespace AnalysisManager From d2ac21a51cb8bd47b7d15d117912fd04f346cd49 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Wed, 10 Apr 2024 15:27:28 -0400 Subject: [PATCH 39/44] Formatting updates + Fixed Warnings - Update format - Fixed casting warnings --- .../Capacitor/Capacitor.cpp | 8 +- .../CircuitComponent.hpp | 18 +- .../DistributedGenerator.cpp | 11 +- .../DistributedGenerator.hpp | 30 +- .../InductionMotor/InductionMotor.cpp | 6 +- .../Inductor/Inductor.cpp | 8 +- .../LinearTransformer/LinearTransformer.cpp | 6 +- .../MicrogridBusDQ/MicrogridBusDQ.cpp | 6 +- .../MicrogridLine/MicrogridLine.cpp | 8 +- .../MicrogridLoad/MicrogridLoad.cpp | 8 +- .../Resistor/Resistor.cpp | 6 +- .../SynchronousMachine/SynchronousMachine.cpp | 6 +- .../TransmissionLine/TransmissionLine.cpp | 6 +- .../VoltageSource/VoltageSource.cpp | 6 +- Examples/DistributedGeneratorTest/DGTest.cpp | 30 +- Examples/Grid3Bus/Grid3BusSys.cpp | 12 +- Examples/Microgrid/Microgrid.cpp | 91 ++--- Examples/SparseTest/SparseTest.cpp | 24 +- PowerElectronicsModel.hpp | 11 +- Solver/Dynamic/Ida.cpp | 6 +- SparseMatrix/COO_Matrix.hpp | 325 ++++++++++-------- 21 files changed, 339 insertions(+), 293 deletions(-) diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp index 148c7c086..f8f26f6da 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -19,9 +19,9 @@ Capacitor::Capacitor(IdxT id, ScalarT C) : C_(C) { this->size_ = 3; - this->n_intern = 1; - this->n_extern = 2; - this->extern_indices = {0,1}; + this->n_intern_ = 1; + this->n_extern_ = 2; + this->extern_indices_ = {0,1}; this->idc_ = id; } @@ -96,7 +96,7 @@ int Capacitor::evaluateJacobian() COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(this->alpha_, Jacder); + this->J_.axpy(this->alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp index 2d43e06e0..5a1a2702e 100644 --- a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp +++ b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp @@ -32,28 +32,28 @@ namespace ModelLib size_t getExternSize() { - return this->n_extern; + return this->n_extern_; } size_t getInternalSize() { - return this->n_intern; + return this->n_intern_; } std::set getExternIndices() { - return this->extern_indices; + return this->extern_indices_; } bool setExternalConnectionNodes(size_t index, IdxT id) { - this->connection_nodes[index] = id; + this->connection_nodes_[index] = id; return true; } IdxT getNodeConnection(size_t index) { - return this->connection_nodes.at(index); + return this->connection_nodes_.at(index); } inline std::vector parkTransformMatrix(ScalarT angle) @@ -125,11 +125,11 @@ namespace ModelLib } protected: - size_t n_extern; - size_t n_intern; - std::set extern_indices; + size_t n_extern_; + size_t n_intern_; + std::set extern_indices_; //@todo may want to replace the mapping of connection_nodes to Node objects instead of IdxT. Allows for container free setup - std::map connection_nodes; + std::map connection_nodes_; }; diff --git a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp index ee23eb7b7..f0b6864a0 100644 --- a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp @@ -18,14 +18,14 @@ namespace ModelLib { template DistributedGenerator::DistributedGenerator(IdxT id, DistributedGeneratorParameters parm, bool reference_frame) - : wb_(parm.wb), wc_(parm.wc), mp_(parm.mp), Vn_(parm.Vn), nq_(parm.nq), F_(parm.F), Kiv_(parm.Kiv), Kpv_(parm.Kpv), Kic_(parm.Kic), Kpc_(parm.Kpc), Cf_(parm.Cf), rLf_(parm.rLf), Lf_(parm.Lf), rLc_(parm.rLc), Lc_(parm.Lc), refframe_(reference_frame) + : wb_(parm.wb_), wc_(parm.wc_), mp_(parm.mp_), Vn_(parm.Vn_), nq_(parm.nq_), F_(parm.F_), Kiv_(parm.Kiv_), Kpv_(parm.Kpv_), Kic_(parm.Kic_), Kpc_(parm.Kpc_), Cf_(parm.Cf_), rLf_(parm.rLf_), Lf_(parm.Lf_), rLc_(parm.rLc_), Lc_(parm.Lc_), refframe_(reference_frame) { // internals [\delta_i, Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi] // externals [\omega_ref, vba_out, vbb_out] this->size_ = 16; - this->n_intern = 13; - this->n_extern = 3; - this->extern_indices = {0,1,2}; + this->n_intern_ = 13; + this->n_extern_ = 3; + this->extern_indices_ = {0,1,2}; this->idc_ = id; } @@ -77,6 +77,7 @@ int DistributedGenerator::evaluateResidual() ScalarT omega = wb_ - mp_ * y_[4]; //ref common ref motor angle + /// @todo fix boolian conditional, unclear result if (refframe_) { f_[0] = omega - y_[0]; @@ -307,7 +308,7 @@ int DistributedGenerator::evaluateJacobian() //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(this->alpha_, Jacder); + this->J_.axpy(this->alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp index 65e71b2b9..6dd297d7a 100644 --- a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp @@ -15,21 +15,21 @@ namespace ModelLib template struct DistributedGeneratorParameters { - ScalarT wb; - ScalarT wc; - ScalarT mp; - ScalarT Vn; - ScalarT nq; - ScalarT F; - ScalarT Kiv; - ScalarT Kpv; - ScalarT Kic; - ScalarT Kpc; - ScalarT Cf; - ScalarT rLf; - ScalarT Lf; - ScalarT rLc; - ScalarT Lc; + ScalarT wb_; + ScalarT wc_; + ScalarT mp_; + ScalarT Vn_; + ScalarT nq_; + ScalarT F_; + ScalarT Kiv_; + ScalarT Kpv_; + ScalarT Kic_; + ScalarT Kpc_; + ScalarT Cf_; + ScalarT rLf_; + ScalarT Lf_; + ScalarT rLc_; + ScalarT Lc_; }; } diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp index c9b452f79..af64888cb 100644 --- a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp @@ -28,9 +28,9 @@ InductionMotor::InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, P_(P) { this->size_ = 10; - this->n_intern = 5; - this->n_extern = 5; - this->extern_indices = {0,1,2,3,4}; + this->n_intern_ = 5; + this->n_extern_ = 5; + this->extern_indices_ = {0,1,2,3,4}; this->idc_ = id; } diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index 05cc66c51..7048efb6e 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -19,9 +19,9 @@ Inductor::Inductor(IdxT id, ScalarT L) : L_(L) { this->size_ = 3; - this->n_intern = 1; - this->n_extern = 2; - this->extern_indices = {0,1}; + this->n_intern_ = 1; + this->n_extern_ = 2; + this->extern_indices_ = {0,1}; this->idc_ = id; } @@ -97,7 +97,7 @@ int Inductor::evaluateJacobian() COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(this->alpha_, Jacder); + this->J_.axpy(this->alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp index aa147493f..fc2a65661 100644 --- a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp @@ -23,9 +23,9 @@ LinearTransformer::LinearTransformer(IdxT id, ScalarT L1, ScalarT M_(M) { this->size_ = 4; - this->n_intern = 2; - this->n_extern = 2; - this->extern_indices = {0,1}; + this->n_intern_ = 2; + this->n_extern_ = 2; + this->extern_indices_ = {0,1}; this->idc_ = id; } diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp index a8327e341..442d5814f 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -20,9 +20,9 @@ MicrogridBusDQ::MicrogridBusDQ(IdxT id, ScalarT RN) { // externals [vbus_d, vbus_q] this->size_ = 2; - this->n_intern = 0; - this->n_extern = 2; - this->extern_indices = {0,1}; + this->n_intern_ = 0; + this->n_extern_ = 2; + this->extern_indices_ = {0,1}; this->idc_ = id; } diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp index 05b1b5e66..4661e4fba 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp @@ -21,9 +21,9 @@ MicrogridLine::MicrogridLine(IdxT id, ScalarT R,ScalarT L) // internals [id, iq] // externals [\omegaref, vbd_in, vbq_in, vbd_out, vbq_out] this->size_ = 7; - this->n_intern = 2; - this->n_extern = 5; - this->extern_indices = {0,1,2,3,4}; + this->n_intern_ = 2; + this->n_extern_ = 5; + this->extern_indices_ = {0,1,2,3,4}; this->idc_ = id; } @@ -129,7 +129,7 @@ int MicrogridLine::evaluateJacobian() COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,7,7); //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(this->alpha_, Jacder); + this->J_.axpy(this->alpha_, Jacder); return 0; diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp index 502170e3b..337390965 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp @@ -22,9 +22,9 @@ MicrogridLoad::MicrogridLoad(IdxT id, ScalarT R,ScalarT L) // internals [id, iq] // externals [\omegaref, vbd_out, vbq_out] this->size_ = 5; - this->n_intern = 2; - this->n_extern = 3; - this->extern_indices = {0,1,2}; + this->n_intern_ = 2; + this->n_extern_ = 3; + this->extern_indices_ = {0,1,2}; this->idc_ = id; } @@ -127,7 +127,7 @@ int MicrogridLoad::evaluateJacobian() COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,5,5); //Perform dF/dy + \alpha dF/dy' - this->J_.AXPY(this->alpha_, Jacder); + this->J_.axpy(this->alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp index d3acbb87f..fcdb9227c 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp @@ -19,9 +19,9 @@ Resistor::Resistor(IdxT id, ScalarT R) : R_(R) { this->size_ = 2; - this->n_intern = 0; - this->n_extern = 2; - this->extern_indices = {0,1}; + this->n_intern_ = 0; + this->n_extern_ = 2; + this->extern_indices_ = {0,1}; this->idc_ = id; } diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp index 8e9be323a..5e1c44076 100644 --- a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp @@ -34,9 +34,9 @@ SynchronousMachine::SynchronousMachine(IdxT id, ScalarT Lls, std: mub_(mub) { this->size_ = 13; - this->n_intern = 6; - this->n_extern = 7; - this->extern_indices = {0,1,2,3,4}; + this->n_intern_ = 6; + this->n_extern_ = 7; + this->extern_indices_ = {0,1,2,3,4}; this->idc_ = id; } diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp index 4158be388..f7fad07aa 100644 --- a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp @@ -22,9 +22,9 @@ TransmissionLine::TransmissionLine(IdxT id, ScalarT R,ScalarT X, // internals [Iret1, Iimt1, Iret2, Iimt2] // externals [Vre11, Vim11, Vre12, Vim12, Vre21, Vim21, Vre22, Vim22] this->size_ = 12; - this->n_intern = 4; - this->n_extern = 8; - this->extern_indices = {0,1,2,3,4,5,6,7}; + this->n_intern_ = 4; + this->n_extern_ = 8; + this->extern_indices_ = {0,1,2,3,4,5,6,7}; this->idc_ = id; ScalarT magImpendence = 1 / (R_*R_ + X_*X_); diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp index b8a659ba9..f77381dcc 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -19,9 +19,9 @@ VoltageSource::VoltageSource(IdxT id, ScalarT V) : V_(V) { this->size_ = 3; - this->n_intern = 1; - this->n_extern = 2; - this->extern_indices = {0,1}; + this->n_intern_ = 1; + this->n_extern_ = 2; + this->extern_indices_ = {0,1}; this->idc_ = id; } diff --git a/Examples/DistributedGeneratorTest/DGTest.cpp b/Examples/DistributedGeneratorTest/DGTest.cpp index 8d682e88c..b65d7c57c 100644 --- a/Examples/DistributedGeneratorTest/DGTest.cpp +++ b/Examples/DistributedGeneratorTest/DGTest.cpp @@ -15,21 +15,21 @@ int main(int argc, char const *argv[]) ModelLib::DistributedGeneratorParameters parms; //Parameters from MATLAB Microgrid code for first DG - parms.wb = 2.0*M_PI*50.0; - parms.wc = 31.41; - parms.mp = 9.4e-5; - parms.Vn = 380; - parms.nq = 1.3e-3; - parms.F = 0.75; - parms.Kiv = 420.0; - parms.Kpv = 0.1; - parms.Kic = 20.0 * 1.0e3; - parms.Kpc = 15.0; - parms.Cf = 50.0e-6; - parms.rLf = 0.1; - parms.Lf = 1.35e-3; - parms.rLc = 0.03; - parms.Lc = 0.35e-3; + parms.wb_ = 2.0*M_PI*50.0; + parms.wc_ = 31.41; + parms.mp_ = 9.4e-5; + parms.Vn_ = 380; + parms.nq_ = 1.3e-3; + parms.F_ = 0.75; + parms.Kiv_ = 420.0; + parms.Kpv_ = 0.1; + parms.Kic_ = 20.0 * 1.0e3; + parms.Kpc_ = 15.0; + parms.Cf_ = 50.0e-6; + parms.rLf_ = 0.1; + parms.Lf_ = 1.35e-3; + parms.rLc_ = 0.03; + parms.Lc_ = 0.35e-3; ModelLib::DistributedGenerator *dg = new ModelLib::DistributedGenerator(0, parms, true); diff --git a/Examples/Grid3Bus/Grid3BusSys.cpp b/Examples/Grid3Bus/Grid3BusSys.cpp index 454f7d456..1248f6aa8 100644 --- a/Examples/Grid3Bus/Grid3BusSys.cpp +++ b/Examples/Grid3Bus/Grid3BusSys.cpp @@ -148,7 +148,7 @@ constexpr double theta3_ref = 1.46241; // [deg] * Testing the monlithic case via the class MiniGrid * @return returns 0 if pass o.w. fails */ -int monolithic_case() +int monolithicCase() { std::cout << "\nSolving power flow for a 3-bus monolithic model ...\n\n"; // Create a 3-bus model @@ -201,7 +201,7 @@ int monolithic_case() * Run the Testing case for parser setup * @return returns 0 if pass o.w. fail */ -int parser_case() +int parserCase() { std::cout << "Solving same problem, but assembled from components via a parser ...\n\n"; @@ -267,7 +267,7 @@ int parser_case() * Hardwired Test Case * @return 0 if pass otherwise fails */ -int hardwired_case() +int hardwiredCase() { std::cout << "Solving same problem, but assembled from components manually ...\n\n"; @@ -391,11 +391,11 @@ int main() //return the results of each case int resolve = 0; std::cout << std::string(32,'-') << std::endl; - resolve += monolithic_case(); + resolve |= monolithicCase(); std::cout << std::string(32,'-') << std::endl; - resolve += parser_case(); + resolve |= parserCase(); std::cout << std::string(32,'-') << std::endl; - resolve += hardwired_case(); + resolve |= hardwiredCase(); if (resolve) { diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp index 8107c3e66..4cbf765f0 100644 --- a/Examples/Microgrid/Microgrid.cpp +++ b/Examples/Microgrid/Microgrid.cpp @@ -1,5 +1,6 @@ + #include #include #include @@ -34,39 +35,39 @@ int main(int argc, char const *argv[]) //DG Params ModelLib::DistributedGeneratorParameters parms1; - parms1.wb = 2.0*M_PI*50.0; - parms1.wc = 31.41; - parms1.mp = 9.4e-5; - parms1.Vn = 380.0; - parms1.nq = 1.3e-3; - parms1.F = 0.75; - parms1.Kiv = 420.0; - parms1.Kpv = 0.1; - parms1.Kic = 2.0e4; - parms1.Kpc = 15.0; - parms1.Cf = 5.0e-5; - parms1.rLf = 0.1; - parms1.Lf = 1.35e-3; - parms1.rLc = 0.03; - parms1.Lc = 0.35e-3; + parms1.wb_ = 2.0*M_PI*50.0; + parms1.wc_ = 31.41; + parms1.mp_ = 9.4e-5; + parms1.Vn_ = 380.0; + parms1.nq_ = 1.3e-3; + parms1.F_ = 0.75; + parms1.Kiv_ = 420.0; + parms1.Kpv_ = 0.1; + parms1.Kic_ = 2.0e4; + parms1.Kpc_ = 15.0; + parms1.Cf_ = 5.0e-5; + parms1.rLf_ = 0.1; + parms1.Lf_ = 1.35e-3; + parms1.rLc_ = 0.03; + parms1.Lc_ = 0.35e-3; ModelLib::DistributedGeneratorParameters parms2; //Parameters from MATLAB Microgrid code for first DG - parms2.wb = 2.0*M_PI*50.0; - parms2.wc = 31.41; - parms2.mp = 12.5e-5; - parms2.Vn = 380.0; - parms2.nq = 1.5e-3; - parms2.F = 0.75; - parms2.Kiv = 390.0; - parms2.Kpv = 0.05; - parms2.Kic = 16.0e3; - parms2.Kpc = 10.5; - parms2.Cf = 50.0e-6; - parms2.rLf = 0.1; - parms2.Lf = 1.35e-3; - parms2.rLc = 0.03; - parms2.Lc = 0.35e-3; + parms2.wb_ = 2.0*M_PI*50.0; + parms2.wc_ = 31.41; + parms2.mp_ = 12.5e-5; + parms2.Vn_ = 380.0; + parms2.nq_ = 1.5e-3; + parms2.F_ = 0.75; + parms2.Kiv_ = 390.0; + parms2.Kpv_ = 0.05; + parms2.Kic_ = 16.0e3; + parms2.Kpc_ = 10.5; + parms2.Cf_ = 50.0e-6; + parms2.rLf_ = 0.1; + parms2.Lf_ = 1.35e-3; + parms2.rLc_ = 0.03; + parms2.Lc_ = 0.35e-3; //Line params double rline1 = 0.23; @@ -304,21 +305,21 @@ int main(int argc, char const *argv[]) // Create Intial derivatives specifics generated in MATLAB //DGs 1 - sysmodel->yp()[2] = parms1.Vn; - sysmodel->yp()[4] = parms1.Kpv * parms1.Vn; - sysmodel->yp()[6] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; - sysmodel->yp()[12 + 3] = parms1.Vn; - sysmodel->yp()[12 + 5] = parms1.Kpv * parms1.Vn; - sysmodel->yp()[12 + 7] = (parms1.Kpc * parms1.Kpv * parms1.Vn) / parms1.Lf; + sysmodel->yp()[2] = parms1.Vn_; + sysmodel->yp()[4] = parms1.Kpv_ * parms1.Vn_; + sysmodel->yp()[6] = (parms1.Kpc_ * parms1.Kpv_ * parms1.Vn_) / parms1.Lf_; + sysmodel->yp()[12 + 3] = parms1.Vn_; + sysmodel->yp()[12 + 5] = parms1.Kpv_ * parms1.Vn_; + sysmodel->yp()[12 + 7] = (parms1.Kpc_ * parms1.Kpv_ * parms1.Vn_) / parms1.Lf_; for (size_t i = 2; i < 4; i++) { - sysmodel->yp()[13*i - 1 + 3] = parms2.Vn; - sysmodel->yp()[13*i - 1 + 5] = parms2.Kpv * parms2.Vn; - sysmodel->yp()[13*i - 1 + 7] = (parms2.Kpc * parms2.Kpv * parms2.Vn) / parms2.Lf; + sysmodel->yp()[13*i - 1 + 3] = parms2.Vn_; + sysmodel->yp()[13*i - 1 + 5] = parms2.Kpv_ * parms2.Vn_; + sysmodel->yp()[13*i - 1 + 7] = (parms2.Kpc_ * parms2.Kpv_ * parms2.Vn_) / parms2.Lf_; } //since the intial P_com = 0 - sysmodel->y()[vec_size_internals] = parms1.wb; + sysmodel->y()[vec_size_internals] = parms1.wb_; @@ -329,7 +330,7 @@ int main(int argc, char const *argv[]) std::cout << "Verify Intial Resisdual is Zero: {\n"; for (size_t i = 0; i < fres.size(); i++) { - printf("%u : %e \n", i, fres[i]); + printf("%lu : %e \n", i, fres[i]); } std::cout << "}\n"; @@ -435,10 +436,10 @@ int main(int argc, char const *argv[]) }; std::cout << "Test the Relative Error\n"; - for (size_t i = 0; i < true_vec.size(); i++) - { - printf("%u : %e ,\n", i, abs(true_vec[i] - yfinial[i]) / abs(true_vec[i])); - } + for (size_t i = 0; i < true_vec.size(); i++) + { + printf("%lu : %e ,\n", i, abs(true_vec[i] - yfinial[i]) / abs(true_vec[i])); + } return 0; } diff --git a/Examples/SparseTest/SparseTest.cpp b/Examples/SparseTest/SparseTest.cpp index 399151434..c563dbd49 100644 --- a/Examples/SparseTest/SparseTest.cpp +++ b/Examples/SparseTest/SparseTest.cpp @@ -42,7 +42,7 @@ int main(int argc, char const *argv[]) std::cout << "B:\n"; B.printMatrix(); - A.AXPY(2.0, B); + A.axpy(2.0, B); std::cout << "A + 2B:\n"; A.printMatrix(); @@ -73,14 +73,30 @@ int main(int argc, char const *argv[]) assert(valtest.size() == v.size()); int failval = 0; - for (size_t i = 0; i < rtest.size(); i++) if (r[i] != rtest[i]) failval--; + for (size_t i = 0; i < rtest.size(); i++) + { + if (r[i] != rtest[i]) + { + failval--; + } + } for (size_t i = 0; i < ctest.size(); i++) { double vdiff = v[i] - valtest[i]; - if (c[i] != ctest[i] || -1e-14 > vdiff || vdiff > 1e-14) failval--; + if (c[i] != ctest[i] || -1e-14 > vdiff || vdiff > 1e-14) + { + failval--; + } } - std::cout << failval << std::endl; + if (failval == 0) + { + std::cout << "Success!" << std::endl; + } + else + { + std::cout << "Failed!" << std::endl; + } return failval; } diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index d74b92cf0..ca7e4dbdf 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -166,7 +166,7 @@ namespace ModelLib { for (IdxT j = 0; j < component->size(); ++j) { - if (component->getNodeConnection(j) != -1) + if (component->getNodeConnection(j) != neg1_) { component->y()[j] = y_[component->getNodeConnection(j)]; component->yp()[j] = yp_[component->getNodeConnection(j)]; @@ -209,7 +209,7 @@ namespace ModelLib for (IdxT j = 0; j < component->size(); ++j) { //@todo should do a different grounding check - if (component->getNodeConnection(j) != -1) + if (component->getNodeConnection(j) != neg1_) { f_[component->getNodeConnection(j)] += component->getResidual()[j]; } @@ -244,7 +244,7 @@ namespace ModelLib std::vector vgr; for (IdxT i = 0; i < static_cast(r.size()); i++) { - if (component->getNodeConnection(r[i]) != -1 && component->getNodeConnection(c[i]) != -1) + if (component->getNodeConnection(r[i]) != neg1_ && component->getNodeConnection(c[i]) != neg1_) { rgr.push_back(component->getNodeConnection(r[i])); cgr.push_back(component->getNodeConnection(c[i])); @@ -253,7 +253,7 @@ namespace ModelLib } // AXPY to Global Jacobian - this->J_.AXPY(1.0, rgr, cgr, vgr); + this->J_.axpy(1.0, rgr, cgr, vgr); } return 0; @@ -321,6 +321,9 @@ namespace ModelLib } private: + + static constexpr IdxT neg1_ = static_cast(-1); + std::vector components_; bool usejac_; diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index fbe7c8973..c97c60cb8 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -421,9 +421,9 @@ namespace Sundials retval = IDASetUserDataB(solver_, backwardID_, model_); checkOutput(retval, "IDASetUserDataB"); - /// \todo Need to set max number of steps based on user input! - retval = IDASetMaxNumStepsB(solver_, backwardID_, 2000); - checkOutput(retval, "IDASetMaxNumSteps"); + /// \todo Need to set max number of steps based on user input! + retval = IDASetMaxNumStepsB(solver_, backwardID_, 2000); + checkOutput(retval, "IDASetMaxNumSteps"); // Set up linear solver JacobianMatB_ = SUNDenseMatrix(model_->size(), model_->size(), context_); diff --git a/SparseMatrix/COO_Matrix.hpp b/SparseMatrix/COO_Matrix.hpp index 70da77a1e..9036085a5 100644 --- a/SparseMatrix/COO_Matrix.hpp +++ b/SparseMatrix/COO_Matrix.hpp @@ -12,7 +12,7 @@ /** * @brief Quick class to provide sparse matrices of COO type. Simplifies data movement * - * @todo add functionality to keep track of multiple sorted list. Faster adding of new entries and will have a threshold to sort completely. + * @todo add functionality to keep track of multiple sorted_ list. Faster adding of new entries and will have a threshold to sort completely. * * m x n sparse matrix */ @@ -20,12 +20,12 @@ template class COO_Matrix { private: - std::vector values; - std::vector row_indexes; - std::vector column_indexes; - Intdx rows_size; - Intdx columns_size; - bool sorted; + std::vector values_; + std::vector row_indexes_; + std::vector column_indexes_; + Intdx rows_size_; + Intdx columns_size_; + bool sorted_; public: //Constructors COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n); @@ -47,9 +47,9 @@ class COO_Matrix // BLAS. Will sort before running void setValues(std::vector r, std::vector c, std::vector v); - void AXPY(ScalarT alpha, COO_Matrix& a); - void AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v); - void SCAL(ScalarT alpha); + void axpy(ScalarT alpha, COO_Matrix& a); + void axpy(ScalarT alpha, std::vector r, std::vector c, std::vector v); + void scal(ScalarT alpha); ScalarT frobnorm(); // --- Permutation Operations --- @@ -61,7 +61,7 @@ class COO_Matrix void identityMatrix(Intdx n); - //Resort values + //Resort values_ void sortSparse(); bool isSorted(); Intdx nnz(); @@ -71,7 +71,7 @@ class COO_Matrix void printMatrix(); - static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values); + static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &vals); private: Intdx indexStartRow(const std::vector &rows, Intdx r); @@ -81,7 +81,7 @@ class COO_Matrix }; /** - * @brief Get copy of row values + * @brief Get copy of row values_ * * @tparam ScalarT * @tparam Intdx @@ -91,7 +91,7 @@ class COO_Matrix template inline std::tuple, std::vector> COO_Matrix::getRowCopy(Intdx r) { - if (!this->sorted) + if (!this->sorted_) { this->sortSparse(); } @@ -107,9 +107,9 @@ inline std::tuple, std::vector> COO_Matrixvalues.size() && this->row_indexes[rsize] == r); + } while (rsize < this->values_.size() && this->row_indexes_[rsize] == r); - return {{this->column_indexes.begin() + rowindex, this->column_indexes.begin() + rsize},{this->values.begin() + rowindex, this->values.begin() + rsize}}; + return {{this->column_indexes_.begin() + rowindex, this->column_indexes_.begin() + rsize},{this->values_.begin() + rowindex, this->values_.begin() + rsize}}; } /** @@ -122,15 +122,15 @@ inline std::tuple, std::vector> COO_Matrix inline std::tuple&, std::vector&, std::vector&> COO_Matrix::getEntries() { - if (!this->sorted) + if (!this->sorted_) { this->sortSparse(); } - return {this->row_indexes, this->column_indexes, this->values}; + return {this->row_indexes_, this->column_indexes_, this->values_}; } /** - * @brief Get copies of the data. Sorted before returning + * @brief Get copies of the data. Sorted_ before returning * * @tparam ScalarT * @tparam Intdx @@ -139,11 +139,11 @@ inline std::tuple&, std::vector&, std::vector template inline std::tuple, std::vector, std::vector> COO_Matrix::getEntrieCopies() { - if (!this->sorted) + if (!this->sorted_) { this->sortSparse(); } - return {this->row_indexes, this->column_indexes, this->values}; + return {this->row_indexes_, this->column_indexes_, this->values_}; } /** @@ -157,18 +157,18 @@ template inline std::tuple, std::vector, std::vector> COO_Matrix::getDataToCSR() { if (!this->isSorted()) this->sortSparse(); - std::vector rowsizevec(this->rows_size + 1, 0); + std::vector rowsizevec(this->rows_size_ + 1, 0); Intdx counter = 0; for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) { rowsizevec[i + 1] = rowsizevec[i]; - while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) + while (counter < static_cast(this->row_indexes_.size()) && i == this->row_indexes_[counter]) { rowsizevec[i+1]++; counter++; } } - return {rowsizevec, this->column_indexes, this->values}; + return {rowsizevec, this->column_indexes_, this->values_}; } /** @@ -176,7 +176,6 @@ inline std::tuple, std::vector, std::vector> * * @todo swap this with having the matrix store the data and updates. This can then be passed by reference * - * @todo fails, fix * * @tparam ScalarT * @tparam Intdx @@ -186,12 +185,12 @@ template inline std::vector COO_Matrix::getCSRRowData() { if (!this->isSorted()) this->sortSparse(); - std::vector rowsizevec(this->rows_size + 1, 0); + std::vector rowsizevec(this->rows_size_ + 1, 0); Intdx counter = 0; for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) { rowsizevec[i + 1] = rowsizevec[i]; - while (counter < static_cast(this->row_indexes.size()) && i == this->row_indexes[counter]) + while (counter < static_cast(this->row_indexes_.size()) && i == this->row_indexes_[counter]) { rowsizevec[i+1]++; counter++; @@ -201,7 +200,7 @@ inline std::vector COO_Matrix::getCSRRowData() } /** - * @brief Given set of vector data it will set the values into the matrix + * @brief Given set of vector data it will set the values_ into the matrix * * @tparam ScalarT * @tparam Intdx @@ -216,45 +215,48 @@ inline void COO_Matrix::setValues(std::vector r, std::vec this->sortSparseCOO(r, c, v); - //Duplicated with AXPY. Could replace with function depdent on lambda expression + //Duplicated with axpy. Could replace with function depdent on lambda expression Intdx aiter = 0; - //iterate for all current values in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + //iterate for all current values_ in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes_.size()); i++) { - //pushback values when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + //pushback values_ when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) { - this->row_indexes.push_back(r[aiter]); - this->column_indexes.push_back(c[aiter]); - this->values.push_back(v[aiter]); + this->row_indexes_.push_back(r[aiter]); + this->column_indexes_.push_back(c[aiter]); + this->values_.push_back(v[aiter]); this->checkIncreaseSize(r[aiter], c[aiter]); aiter++; } - if (aiter >= static_cast(r.size())) break; + if (aiter >= static_cast(r.size())) + { + break; + } - if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + if (r[aiter] == this->row_indexes_[i] && c[aiter] == this->column_indexes_[i]) { - this->values[i] = v[aiter]; + this->values_[i] = v[aiter]; aiter++; } } //push back rest that was not found sorted for (Intdx i = aiter; i < static_cast(r.size()); i++) { - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(v[i]); + this->row_indexes_.push_back(r[i]); + this->column_indexes_.push_back(c[i]); + this->values_.push_back(v[i]); this->checkIncreaseSize(r[i], c[i]); } - this->sorted = false; + this->sorted_ = false; } /** - * @brief BLAS AXPY operation on another COO matrix. Will sort both matrices before acting + * @brief BLAS axpy operation on another COO matrix. Will sort both matrices before acting * * @tparam ScalarT * @tparam Intdx @@ -262,11 +264,14 @@ inline void COO_Matrix::setValues(std::vector r, std::vec * @param a */ template -inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrix& a) +inline void COO_Matrix::axpy(ScalarT alpha, COO_Matrix& a) { - if (alpha == 0) return; + if (alpha == 0) + { + return; + } - if (!this->sorted) + if (!this->sorted_) { this->sortSparse(); } @@ -281,47 +286,50 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrixrows_size = this->rows_size > m ? this->rows_size : m; - this->columns_size = this->columns_size > n ? this->columns_size : n; + this->rows_size_ = this->rows_size_ > m ? this->rows_size_ : m; + this->columns_size_ = this->columns_size_ > n ? this->columns_size_ : n; Intdx aiter = 0; - //iterate for all current values in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + //iterate for all current values_ in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes_.size()); i++) { - //pushback values when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + //pushback values_ when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) { - this->row_indexes.push_back(r[aiter]); - this->column_indexes.push_back(c[aiter]); - this->values.push_back(alpha * val[aiter]); + this->row_indexes_.push_back(r[aiter]); + this->column_indexes_.push_back(c[aiter]); + this->values_.push_back(alpha * val[aiter]); this->checkIncreaseSize(r[aiter], c[aiter]); aiter++; } - if (aiter >= static_cast(r.size())) break; + if (aiter >= static_cast(r.size())) + { + break; + } - if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + if (r[aiter] == this->row_indexes_[i] && c[aiter] == this->column_indexes_[i]) { - this->values[i] += alpha * val[aiter]; + this->values_[i] += alpha * val[aiter]; aiter++; } } - //push back rest that was not found sorted + //push back rest that was not found sorted_ for (Intdx i = aiter; i < static_cast(r.size()); i++) { - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(alpha * val[i]); + this->row_indexes_.push_back(r[i]); + this->column_indexes_.push_back(c[i]); + this->values_.push_back(alpha * val[i]); this->checkIncreaseSize(r[i], c[i]); } - this->sorted = false; + this->sorted_ = false; } /** - * @brief AXPY on 3list. + * @brief axpy on 3list. * * @tparam ScalarT * @tparam Intdx @@ -331,11 +339,11 @@ inline void COO_Matrix::AXPY(ScalarT alpha, COO_Matrix -inline void COO_Matrix::AXPY(ScalarT alpha, std::vector r, std::vector c, std::vector v) +inline void COO_Matrix::axpy(ScalarT alpha, std::vector r, std::vector c, std::vector v) { if (alpha == 0) return; - if (!this->sorted) + if (!this->sorted_) { this->sortSparse(); } @@ -344,59 +352,75 @@ inline void COO_Matrix::AXPY(ScalarT alpha, std::vector r this->sortSparseCOO(r, c, v); Intdx aiter = 0; - //iterate for all current values in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes.size()); i++) + //iterate for all current values_ in matrix + for (Intdx i = 0; i < static_cast(this->row_indexes_.size()); i++) { - //pushback values when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes[i] || (r[aiter] == this->row_indexes[i] && c[aiter] < this->column_indexes[i]))) + //pushback values_ when they are not in current matrix + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) { - this->row_indexes.push_back(r[aiter]); - this->column_indexes.push_back(c[aiter]); - this->values.push_back(alpha * v[aiter]); + this->row_indexes_.push_back(r[aiter]); + this->column_indexes_.push_back(c[aiter]); + this->values_.push_back(alpha * v[aiter]); this->checkIncreaseSize(r[aiter], c[aiter]); aiter++; } - if (aiter >= static_cast(r.size())) break; + if (aiter >= static_cast(r.size())) + { + break; + } - if (r[aiter] == this->row_indexes[i] && c[aiter] == this->column_indexes[i]) + if (r[aiter] == this->row_indexes_[i] && c[aiter] == this->column_indexes_[i]) { - this->values[i] += alpha * v[aiter]; + this->values_[i] += alpha * v[aiter]; aiter++; } } - //push back rest that was not found sorted + //push back rest that was not found sorted_ for (Intdx i = aiter; i < static_cast(r.size()); i++) { - this->row_indexes.push_back(r[i]); - this->column_indexes.push_back(c[i]); - this->values.push_back(alpha * v[i]); + this->row_indexes_.push_back(r[i]); + this->column_indexes_.push_back(c[i]); + this->values_.push_back(alpha * v[i]); this->checkIncreaseSize(r[i], c[i]); } - this->sorted = false; + this->sorted_ = false; } /** - * @brief Scale all values + * @brief Scale all values_ * * @tparam ScalarT * @tparam Intdx * @param alpha */ template -inline void COO_Matrix::SCAL(ScalarT alpha) +inline void COO_Matrix::scal(ScalarT alpha) { - for (auto i = this->values.begin(); i < this->values.end(); i++) *i *= alpha; + for (auto i = this->values_.begin(); i < this->values_.end(); i++) + { + *i *= alpha; + } } +/** + * @brief Frobenius Norm of the Matrix + * + * @tparam ScalarT + * @tparam Intdx + * @return ScalarT + */ template inline ScalarT COO_Matrix::frobnorm() { ScalarT totsum = 0.0; - for (auto i = this->values.begin(); i < this->values.end(); i++) totsum += abs(*i)^2; + for (auto i = this->values_.begin(); i < this->values_.end(); i++) + { + totsum += abs(*i)^2; + } return totsum; } @@ -411,15 +435,15 @@ inline ScalarT COO_Matrix::frobnorm() template inline void COO_Matrix::permutation(std::vector row_perm, std::vector col_perm) { - assert(row_perm.size() = this->rows_size); - assert(col_perm.size() = this->columns_size); + assert(row_perm.size() = this->rows_size_); + assert(col_perm.size() = this->columns_size_); - for (int i = 0; i < this->values.size(); i++) + for (int i = 0; i < this->values_.size(); i++) { - this->row_indexes[i] = row_perm[this->row_indexes[i]]; - this->column_indexes[i] = col_perm[this->column_indexes[i]]; + this->row_indexes_[i] = row_perm[this->row_indexes_[i]]; + this->column_indexes_[i] = col_perm[this->column_indexes_[i]]; } - this->sorted = false; + this->sorted_ = false; //cycle sorting maybe useful since permutations are already known } @@ -437,25 +461,25 @@ inline void COO_Matrix::permutation(std::vector row_perm, template inline void COO_Matrix::permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n) { - assert(row_perm.size() == this->rows_size); - assert(col_perm.size() == this->columns_size); + assert(row_perm.size() == this->rows_size_); + assert(col_perm.size() == this->columns_size_); - this->rows_size = m; - this->columns_size = n; + this->rows_size_ = m; + this->columns_size_ = n; - for (int i = 0; i < this->values.size(); i++) + for (int i = 0; i < this->values_.size(); i++) { - if (row_perm[this->row_indexes[i]] == -1 || col_perm[this->column_indexes[i]] == -1) + if (row_perm[this->row_indexes_[i]] == -1 || col_perm[this->column_indexes_[i]] == -1) { - this->values[i] = 0; + this->values_[i] = 0; } else { - this->row_indexes[i] = row_perm[this->row_indexes[i]]; - this->column_indexes[i] = col_perm[this->column_indexes[i]]; + this->row_indexes_[i] = row_perm[this->row_indexes_[i]]; + this->column_indexes_[i] = col_perm[this->column_indexes_[i]]; } } - this->sorted = false; + this->sorted_ = false; } /** @@ -468,10 +492,10 @@ template inline void COO_Matrix::zeroMatrix() { //resize doesn't effect capacity if smaller - this->column_indexes.resize(0); - this->row_indexes.resize(0); - this->values.resize(0); - this->sorted = true; + this->column_indexes_.resize(0); + this->row_indexes_.resize(0); + this->values_.resize(0); + this->sorted_ = true; } template @@ -481,11 +505,11 @@ inline void COO_Matrix::identityMatrix(Intdx n) this->zeroMatrix(); for (Intdx i = 0; i < n; i++) { - this->column_indexes[i] = i; - this->row_indexes[i] = i; - this->values[i] = 1.0; + this->column_indexes_[i] = i; + this->row_indexes_[i] = i; + this->values_[i] = 1.0; } - this->sorted = true; + this->sorted_ = true; } /** @@ -497,30 +521,30 @@ inline void COO_Matrix::identityMatrix(Intdx n) template inline void COO_Matrix::sortSparse() { - this->sortSparseCOO(this->row_indexes, this->column_indexes, this->values); - this->sorted = true; + this->sortSparseCOO(this->row_indexes_, this->column_indexes_, this->values_); + this->sorted_ = true; } template inline bool COO_Matrix::isSorted() { - return this->sorted; + return this->sorted_; } template inline Intdx COO_Matrix::nnz() { - return static_cast(this->values.size); + return static_cast(this->values_.size); } template inline std::tuple COO_Matrix::getDimensions() { - return std::tuple(this->rows_size, this->columns_size); + return std::tuple(this->rows_size_, this->columns_size_); } /** - * @brief Print matrix that is sorted + * @brief Print matrix that is sorted_ * * @tparam ScalarT * @tparam Intdx @@ -528,25 +552,26 @@ inline std::tuple COO_Matrix::getDimensions() template inline void COO_Matrix::printMatrix() { - if (this->sorted == false) + if (this->sorted_ == false) { this->sortSparse(); } std::cout << "Sparse COO Matrix\n"; std::cout << "(x , y, value)\n"; - for (size_t i = 0; i < this->values.size(); i++) + for (size_t i = 0; i < this->values_.size(); i++) { - std::cout << "(" << this->row_indexes[i] - << ", " << this->column_indexes[i] - << ", " << this->values[i] << ")\n"; + std::cout << "(" << this->row_indexes_[i] + << ", " << this->column_indexes_[i] + << ", " << this->values_[i] << ")\n"; } + std::cout << std::flush; } /** * @brief Find the lowest row cordinate from set of provided cordinates * - * Assumes rows and columns are sorted + * Assumes rows and columns are sorted_ * @tparam ScalarT * @tparam Intdx * @param r @@ -639,14 +664,14 @@ template inline bool COO_Matrix::checkIncreaseSize(Intdx r, Intdx c) { bool changed = false; - if (r + 1 > this->rows_size) + if (r + 1 > this->rows_size_) { - this->rows_size = r + 1; + this->rows_size_ = r + 1; changed = true; } - if (c + 1 > this->columns_size) + if (c + 1 > this->columns_size_) { - this->columns_size = c + 1; + this->columns_size_ = c + 1; changed = true; } @@ -654,22 +679,22 @@ inline bool COO_Matrix::checkIncreaseSize(Intdx r, Intdx c) } /** - * @brief Sort a disoreded set of values. Assume nothing on order. + * @brief Sort a disoreded set of values_. Assume nothing on order. * - * @todo simple setup. Should add stable sorting since list are pre-sorted + * @todo simple setup. Should add stable sorting since list are pre-sorted_ * * @tparam ScalarT * @tparam Intdx * @param rows * @param columns - * @param values + * @param values_ */ template -inline void COO_Matrix::sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &values) +inline void COO_Matrix::sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &vals) { //index based sort code - // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted-vector + // https://stackoverflow.com/questions/25921706/creating-a-vector-of-indices-of-a-sorted_-vector //cannot call sort since two arrays are used instead std::vector ordervec(rows.size()); std::size_t n(0); @@ -692,7 +717,7 @@ inline void COO_Matrix::sortSparseCOO(std::vector &rows, { std::swap(rows[ordervec[i]], rows[ordervec[ordervec[i]]]); std::swap(columns[ordervec[i]], columns[ordervec[ordervec[i]]]); - std::swap(values[ordervec[i]], values[ordervec[ordervec[i]]]); + std::swap(vals[ordervec[i]], vals[ordervec[ordervec[i]]]); //swap orderings std::swap(ordervec[i], ordervec[ordervec[i]]); @@ -704,34 +729,34 @@ inline void COO_Matrix::sortSparseCOO(std::vector &rows, template inline COO_Matrix::COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n) { - this->values = v; - this->row_indexes = r; - this->column_indexes = c; - this->rows_size = m; - this->columns_size = n; - this->sorted = false; + this->values_ = v; + this->row_indexes_ = r; + this->column_indexes_ = c; + this->rows_size_ = m; + this->columns_size_ = n; + this->sorted_ = false; } template inline COO_Matrix::COO_Matrix(Intdx m, Intdx n) { - this->rows_size = m; - this->columns_size = n; - this->values = std::vector(); - this->row_indexes = std::vector(); - this->column_indexes = std::vector(); - this->sorted = false; + this->rows_size_ = m; + this->columns_size_ = n; + this->values_ = std::vector(); + this->row_indexes_ = std::vector(); + this->column_indexes_ = std::vector(); + this->sorted_ = false; } template inline COO_Matrix::COO_Matrix() { - this->rows_size = 0; - this->columns_size = 0; - this->values = std::vector(); - this->row_indexes = std::vector(); - this->column_indexes = std::vector(); - this->sorted = false; + this->rows_size_ = 0; + this->columns_size_ = 0; + this->values_ = std::vector(); + this->row_indexes_ = std::vector(); + this->column_indexes_ = std::vector(); + this->sorted_ = false; } template From a192d474ac01a815690a0a2e25a37379072432f8 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Wed, 10 Apr 2024 15:53:49 -0400 Subject: [PATCH 40/44] Rebasing with BusPV Fixes --- ComponentLib/Bus/BusPV.cpp | 2 +- .../SynchronousMachine/SynchronousMachine.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ComponentLib/Bus/BusPV.cpp b/ComponentLib/Bus/BusPV.cpp index 50425d9dd..d5a05dc98 100644 --- a/ComponentLib/Bus/BusPV.cpp +++ b/ComponentLib/Bus/BusPV.cpp @@ -103,7 +103,7 @@ BusPV::BusPV(ScalarT V, ScalarT theta0) template BusPV::BusPV(BusData& data) - : BaseBus(data.bus_i), V_(data.Vm), theta0_(data.Va), Pg_(0.0) + : BaseBus(data.bus_i), V_(data.Vm), theta0_(data.Va) { //std::cout << "Create BusPV ..." << std::endl; //std::cout << "Number of equations is " << size_ << std::endl; diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp index 5e1c44076..83428e5fc 100644 --- a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp @@ -79,6 +79,7 @@ int SynchronousMachine::tagDifferentiable() * @brief Contributes to the bus residual. * * Must be connected to a PQ bus. + * @todo fix up */ template int SynchronousMachine::evaluateResidual() From ad7f4af9bccb13dce8a1c0f126739fde6bde04cf Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Fri, 12 Apr 2024 20:40:15 -0400 Subject: [PATCH 41/44] Minor comments and style corrections. Co-authored-by: Reid --- CircuitGraph.hpp | 12 +++++-- .../CircuitComponent.hpp | 31 ++++++++++++++----- .../Inductor/Inductor.cpp | 4 +-- .../MicrogridBusDQ/MicrogridBusDQ.cpp | 4 +++ .../MicrogridLine/MicrogridLine.cpp | 6 ++++ .../TransmissionLine/TransmissionLine.hpp | 4 +++ PowerElectronicsModel.hpp | 24 +++++++------- 7 files changed, 60 insertions(+), 25 deletions(-) diff --git a/CircuitGraph.hpp b/CircuitGraph.hpp index e54f5a150..d24a83566 100644 --- a/CircuitGraph.hpp +++ b/CircuitGraph.hpp @@ -7,11 +7,17 @@ #include /** - * @brief A very basic hypergraph setup for circuit representation. This forms the hypergraph as a bipartite graph. Doesn't allow removing. Can only grab sets of connections to nodes + * @brief A very basic hypergraph setup for circuit representation. + * This forms the hypergraph as a bipartite graph. Doesn't allow + * removing. Can only grab sets of connections to nodes * - * @todo should replace with something better and more efficent. Should replace with a libraries setup instead. This would allow fast and easy partitioning of circuits + * @todo should replace with something better and more efficent. + * Should replace with a libraries setup instead. This would allow + * fast and easy partitioning of circuits * - * @todo should replace N and E with Node and Component classes respectively + * @todo should replace N and E with Node and Component classes respectively. + * + * @note Tested but currently not used in the rest of the code. * * @tparam IdxT * @tparam Label diff --git a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp index 5a1a2702e..0b6aa2f9f 100644 --- a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp +++ b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp @@ -32,7 +32,7 @@ namespace ModelLib size_t getExternSize() { - return this->n_extern_; + return n_extern_; } size_t getInternalSize() @@ -45,15 +45,30 @@ namespace ModelLib return this->extern_indices_; } - bool setExternalConnectionNodes(size_t index, IdxT id) + /** + * @brief Create the mappings from local to global indexes + * + * @param local_index + * @param global_index + * @return int + */ + int setExternalConnectionNodes(IdxT local_index, IdxT global_index) { - this->connection_nodes_[index] = id; - return true; + connection_nodes_[local_index] = global_index; + return 0; } - IdxT getNodeConnection(size_t index) + /** + * @brief Given the location of value in the local vector map to global index + * + * f(local_index) = global_index + * + * @param local_index index of local value in vector + * @return IdxT Index of the same value in the global vector + */ + IdxT getNodeConnection(IdxT local_index) { - return this->connection_nodes_.at(index); + return connection_nodes_.at(local_index); } inline std::vector parkTransformMatrix(ScalarT angle) @@ -127,9 +142,9 @@ namespace ModelLib protected: size_t n_extern_; size_t n_intern_; - std::set extern_indices_; + std::set extern_indices_; //@todo may want to replace the mapping of connection_nodes to Node objects instead of IdxT. Allows for container free setup - std::map connection_nodes_; + std::map connection_nodes_; }; diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index 7048efb6e..42b8c5330 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -18,11 +18,11 @@ template Inductor::Inductor(IdxT id, ScalarT L) : L_(L) { - this->size_ = 3; + size_ = 3; this->n_intern_ = 1; this->n_extern_ = 2; this->extern_indices_ = {0,1}; - this->idc_ = id; + idc_ = id; } template diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp index 442d5814f..bf070f507 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -11,7 +11,11 @@ namespace ModelLib { * * Calls default ModelEvaluatorImpl constructor. * + * In DQ space * Each microgrid line has a virtual resistance RN + * Model is from paper: " + "Modeling, Analysis and Testing of Autonomous Operation of an Inverter-Based Microgrid" Nagaraju Pogaku, Milan Prodanovic, and Timothy C. Green" + * Section E */ template diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp index 4661e4fba..d1aea251d 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp @@ -11,7 +11,13 @@ namespace ModelLib { * * Calls default ModelEvaluatorImpl constructor. * + * * Each microgrid line has a virtual resistance RN + * Model is from paper: " + "Modeling, Analysis and Testing of Autonomous Operation of an Inverter-Based Microgrid" Nagaraju Pogaku, Milan Prodanovic, and Timothy C. Green" + * Section C + * + * @todo Consider having \omegaref as a global constant, not a node variable. */ template diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp index 4acac0c58..336515733 100644 --- a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp @@ -19,6 +19,10 @@ namespace ModelLib /*! * @brief Declaration of a passive TransmissionLine class. * + * Model from Adam Birchfield paper (medium distances < 2km). + * See also textbooks "Power System Analysis" by Grainger and "Power System Dynamics and Stability" by Sauer & Pai + * + * @note Not used in the Microgrid model. */ template class TransmissionLine : public CircuitComponent diff --git a/PowerElectronicsModel.hpp b/PowerElectronicsModel.hpp index ca7e4dbdf..ef109b926 100644 --- a/PowerElectronicsModel.hpp +++ b/PowerElectronicsModel.hpp @@ -51,7 +51,7 @@ namespace ModelLib rtol_ = 1e-4; atol_ = 1e-4; this->max_steps_ = 2000; - // By default use jacobian + // By default not use jacobian usejac_ = false; } @@ -64,7 +64,7 @@ namespace ModelLib rtol_ = rt; atol_ = at; this->max_steps_ = msa; - // Can choose not to use jacobain + // Can choose if to use jacobain usejac_ = ju; } @@ -123,7 +123,7 @@ namespace ModelLib { // Allocate all components - this->size_ = s; + size_ = s; for (const auto &component : components_) { component->allocate(); @@ -226,8 +226,8 @@ namespace ModelLib */ int evaluateJacobian() { - this->J_.zeroMatrix(); - this->distributeVectors(); + J_.zeroMatrix(); + distributeVectors(); // Evaluate component jacs for (const auto &component : components_) @@ -235,8 +235,8 @@ namespace ModelLib component->evaluateJacobian(); // get references to local jacobain - std::tuple &, std::vector &, std::vector &> tpm = component->getJacobian().getEntries(); - const auto &[r, c, v] = tpm; + std::tuple&, std::vector&, std::vector&> tpm = component->getJacobian().getEntries(); + const auto& [r, c, v] = tpm; // Create copies of data to handle groundings std::vector rgr; @@ -253,7 +253,7 @@ namespace ModelLib } // AXPY to Global Jacobian - this->J_.axpy(1.0, rgr, cgr, vgr); + J_.axpy(1.0, rgr, cgr, vgr); } return 0; @@ -311,20 +311,20 @@ namespace ModelLib { component->updateTime(t, a); } - this->time_ = t; - this->alpha_ = a; + time_ = t; + alpha_ = a; } void addComponent(component_type *component) { - this->components_.push_back(component); + components_.push_back(component); } private: static constexpr IdxT neg1_ = static_cast(-1); - std::vector components_; + std::vector components_; bool usejac_; }; // class PowerElectronicsModel From 7e685c5c848d09ccf650808db2abdee467040b43 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Tue, 16 Apr 2024 16:17:14 -0400 Subject: [PATCH 42/44] Multiple Format & Comment Updates + Valgrind Error Fixes - Updated Comments to respect current models - Fixed valgrind errors in ida.cpp. Note: there is still more but seg faults are happening from frees --- CircuitGraph.hpp | 49 ++++++------- .../Capacitor/Capacitor.cpp | 18 +++-- .../Capacitor/Capacitor.hpp | 2 +- .../CircuitComponent.hpp | 72 +------------------ .../DistributedGenerator.cpp | 3 +- .../DistributedGenerator.hpp | 2 +- .../InductionMotor/InductionMotor.cpp | 8 +-- .../InductionMotor/InductionMotor.hpp | 2 +- .../Inductor/Inductor.cpp | 12 +++- .../Inductor/Inductor.hpp | 2 +- .../LinearTransformer/LinearTransformer.cpp | 11 ++- .../LinearTransformer/LinearTransformer.hpp | 2 +- .../MicrogridBusDQ/MicrogridBusDQ.cpp | 4 +- .../MicrogridBusDQ/MicrogridBusDQ.hpp | 2 +- .../MicrogridLine/MicrogridLine.cpp | 6 +- .../MicrogridLine/MicrogridLine.hpp | 2 +- .../MicrogridLoad/MicrogridLoad.cpp | 6 +- .../Resistor/Resistor.cpp | 5 +- .../Resistor/Resistor.hpp | 2 +- .../SynchronousMachine/SynchronousMachine.cpp | 7 +- .../SynchronousMachine/SynchronousMachine.hpp | 2 +- .../TransmissionLine/TransmissionLine.cpp | 4 +- .../TransmissionLine/TransmissionLine.hpp | 2 +- .../VoltageSource/VoltageSource.cpp | 9 +-- .../VoltageSource/VoltageSource.hpp | 2 +- .../DistributedGeneratorTest/CMakeLists.txt | 8 +-- Examples/DistributedGeneratorTest/DGTest.cpp | 7 ++ Examples/Microgrid/CMakeLists.txt | 10 +-- Examples/Microgrid/Microgrid.cpp | 8 ++- Examples/RLCircuit/CMakeLists.txt | 10 +-- Examples/SparseTest/CMakeLists.txt | 2 +- Solver/Dynamic/Ida.cpp | 26 +++++++ 32 files changed, 139 insertions(+), 168 deletions(-) diff --git a/CircuitGraph.hpp b/CircuitGraph.hpp index d24a83566..070d838f1 100644 --- a/CircuitGraph.hpp +++ b/CircuitGraph.hpp @@ -10,17 +10,19 @@ * @brief A very basic hypergraph setup for circuit representation. * This forms the hypergraph as a bipartite graph. Doesn't allow * removing. Can only grab sets of connections to nodes - * + * * @todo should replace with something better and more efficent. * Should replace with a libraries setup instead. This would allow * fast and easy partitioning of circuits * + * @todo This is to replace inserting vector size for allocating PowerElectronicsModel + * * @todo should replace N and E with Node and Component classes respectively. - * + * * @note Tested but currently not used in the rest of the code. - * - * @tparam IdxT - * @tparam Label + * + * @tparam IdxT + * @tparam Label */ template class CircuitGraph @@ -29,6 +31,7 @@ class CircuitGraph std::set hypernodes; std::set hyperedges; std::map> edgestonodes; + public: CircuitGraph(); ~CircuitGraph(); @@ -52,74 +55,68 @@ CircuitGraph::~CircuitGraph() } template -bool CircuitGraph::addHyperNode(N hn) +bool CircuitGraph::addHyperNode(N hn) { return this->hypernodes.insert(hn).second; } template -bool CircuitGraph::addHyperEdge(E he) +bool CircuitGraph::addHyperEdge(E he) { return this->hyperedges.insert(he).second; } - template -bool CircuitGraph::addConnection(N hn, E he) +bool CircuitGraph::addConnection(N hn, E he) { - if(this->hyperedges.count(he) == 0 || this->hypernodes.count(hn) == 0) + if (this->hyperedges.count(he) == 0 || this->hypernodes.count(hn) == 0) { return false; - } + } return this->edgestonodes[he].insert(hn).second; } - template -std::set CircuitGraph::getHyperEdgeConnections(E he) +std::set CircuitGraph::getHyperEdgeConnections(E he) { return this->edgestonodes[he]; } - template -size_t CircuitGraph::amountHyperNodes() +size_t CircuitGraph::amountHyperNodes() { return this->hypernodes.size(); } - template -size_t CircuitGraph::amountHyperEdges() +size_t CircuitGraph::amountHyperEdges() { return this->hyperedges.size(); } /** * @brief Printing - * + * * @todo need to add verbose printing for connections display - * - * @tparam IdxT - * @param verbose + * + * @tparam IdxT + * @param verbose */ template void CircuitGraph::printBiPartiteGraph(bool verbose) { - + std::cout << "Amount of HyperNodes: " << this->amountHyperNodes() << std::endl; std::cout << "Amount of HyperEdges: " << this->amountHyperEdges() << std::endl; std::cout << "Connections per Edge:" << std::endl; for (auto i : this->edgestonodes) { std::cout << i.first << " : {"; - for (auto j : i.second){ + for (auto j : i.second) + { std::cout << j << ", "; } std::cout << "}\n"; - } - - } diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp index f8f26f6da..4174a88e0 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -9,7 +9,9 @@ namespace ModelLib { /*! - * @brief Constructor for a constant load model + * @brief Constructor for Capacitor + * + * @todo this needs to be tested on some circuit * * Calls default ModelEvaluatorImpl constructor. */ @@ -31,7 +33,7 @@ Capacitor::~Capacitor() } /*! - * @brief allocate method computes sparsity pattern of the Jacobian. + * @brief allocate method creates memory for vectors */ template int Capacitor::allocate() @@ -62,9 +64,8 @@ int Capacitor::tagDifferentiable() } /** - * @brief Contributes to the bus residual. + * @brief Evaluate the resisdual of the Capcitor * - * Must be connected to a PQ bus. */ template int Capacitor::evaluateResidual() @@ -79,6 +80,13 @@ int Capacitor::evaluateResidual() return 0; } +/** + * @brief Compute the Jacobian dF/dy - a dF/dy' + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ template int Capacitor::evaluateJacobian() { @@ -89,7 +97,7 @@ int Capacitor::evaluateJacobian() std::vector vals{1.0, -1.0, -1.0}; this->J_.setValues(rcord, ccord, vals); - //Create -dF/dy' + //Create dF/dy' std::vector rcordder{0,1,2}; std::vector ccordder{2,2,2}; std::vector valsder{C_, -C_, -this->C_}; diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp index e1a9974c3..0e445c29c 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp @@ -17,7 +17,7 @@ namespace ModelLib namespace ModelLib { /*! - * @brief Declaration of a passive Capacitor class. + * @brief Declaration of a Capacitor class. * */ template diff --git a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp index 0b6aa2f9f..8186c7272 100644 --- a/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp +++ b/ComponentLib/PowerElectronicsComponents/CircuitComponent.hpp @@ -12,7 +12,7 @@ namespace ModelLib { /*! - * @brief Declaration of a passive CircuitComponent class. + * @brief Declaration of a CircuitComponent class. * */ template @@ -71,79 +71,11 @@ namespace ModelLib return connection_nodes_.at(local_index); } - inline std::vector parkTransformMatrix(ScalarT angle) - { - std::vector result(9); - ScalarT anpim = angle - (2.0/3.0)*M_PI; - ScalarT anpip = angle + (2.0/3.0)*M_PI; - result[0] = (2.0/3.0)*cos(angle); - result[1] = (2.0/3.0)*cos(anpim); - result[2] = (2.0/3.0)*cos(anpip); - result[3] = (2.0/3.0)*sin(angle); - result[4] = (2.0/3.0)*sin(anpim); - result[5] = (2.0/3.0)*sin(anpip); - result[6] = 1.0/3.0; - result[7] = 1.0/3.0; - result[8] = 1.0/3.0; - return result; - } - - inline std::vector parkTransformMatrixDerivative(ScalarT angle) - { - std::vector result(9); - ScalarT anpim = angle - (2.0/3.0)*M_PI; - ScalarT anpip = angle + (2.0/3.0)*M_PI; - result[0] = (2.0/3.0)*sin(angle); - result[1] = (2.0/3.0)*sin(anpim); - result[2] = (2.0/3.0)*sin(anpip); - result[3] = (2.0/3.0)*-cos(angle); - result[4] = (2.0/3.0)*-cos(anpim); - result[5] = (2.0/3.0)*-cos(anpip); - result[6] = 0; - result[7] = 0; - result[8] = 0; - return result; - } - - inline std::vector inverseParkTransformMatrix(ScalarT angle) - { - std::vector result(9); - ScalarT anpim = angle - (2.0/3.0)*M_PI; - ScalarT anpip = angle + (2.0/3.0)*M_PI; - result[0] = cos(angle); - result[1] = sin(angle); - result[2] = 1.0; - result[3] = cos(anpim); - result[4] = sin(anpim); - result[5] = 1.0; - result[6] = cos(anpip); - result[7] = sin(anpip); - result[8] = 1.0; - return result; - } - - inline std::vector inverseParkTransformMatrixDerivative(ScalarT angle) - { - std::vector result(9); - ScalarT anpim = angle - (2.0/3.0)*M_PI; - ScalarT anpip = angle + (2.0/3.0)*M_PI; - result[0] = sin(angle); - result[1] = -cos(angle); - result[2] = 0.0; - result[3] = sin(anpim); - result[4] = -cos(anpim); - result[5] = 0.0; - result[6] = sin(anpip); - result[7] = -cos(anpip); - result[8] = 0.0; - return result; - } - protected: size_t n_extern_; size_t n_intern_; std::set extern_indices_; - //@todo may want to replace the mapping of connection_nodes to Node objects instead of IdxT. Allows for container free setup + ///@todo may want to replace the mapping of connection_nodes to Node objects instead of IdxT. Allows for container free setup std::map connection_nodes_; }; diff --git a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp index f0b6864a0..34148c297 100644 --- a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp @@ -66,9 +66,8 @@ int DistributedGenerator::tagDifferentiable() } /** - * @brief Contributes to the bus residual. + * @brief Contributes to the resisdual of the Distributed Generator * - * Must be connected to a PQ bus. */ template int DistributedGenerator::evaluateResidual() diff --git a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp index 6dd297d7a..4a8746492 100644 --- a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp @@ -37,7 +37,7 @@ namespace ModelLib namespace ModelLib { /*! - * @brief Declaration of a passive DistributedGenerator class. + * @brief Declaration of a DistributedGenerator class. * */ template diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp index af64888cb..06d94da12 100644 --- a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp @@ -15,6 +15,8 @@ namespace ModelLib { * @brief Constructor for a constant InductionMotor model * * Calls default ModelEvaluatorImpl constructor. + * @todo create a test case utilizing the component. + * @todo create a unit test to check correctness of component */ template @@ -70,15 +72,13 @@ int InductionMotor::tagDifferentiable() } /** - * @brief Contributes to the bus residual. + * @brief Contributes to the resisdual * - * Must be connected to a PQ bus. */ template int InductionMotor::evaluateResidual() { - //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors - // for easier development + this->f_[0] = y_[5] + y_[7]; this->f_[1] = (-1.0/2.0) * y_[5] - (sqrt(3.0)/2.0)*y_[6] + y_[7]; this->f_[2] = (-1.0/2.0) * y_[5] + (sqrt(3.0)/2.0)*y_[6] + y_[7]; diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp index 96ac6cc49..58247eea0 100644 --- a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp @@ -17,7 +17,7 @@ namespace ModelLib namespace ModelLib { /*! - * @brief Declaration of a passive InductionMotor class. + * @brief Declaration of a InductionMotor class. * */ template diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index 42b8c5330..cbc6dd4c3 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -9,7 +9,7 @@ namespace ModelLib { /*! - * @brief Constructor for a constant load model + * @brief Constructor for a inductor * * Calls default ModelEvaluatorImpl constructor. */ @@ -63,9 +63,8 @@ int Inductor::tagDifferentiable() } /** - * @brief Contributes to the bus residual. + * @brief Compute the resisdual of the component * - * Must be connected to a PQ bus. */ template int Inductor::evaluateResidual() @@ -79,6 +78,13 @@ int Inductor::evaluateResidual() return 0; } +/** + * @brief Evaluate the jacobian of the component + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ template int Inductor::evaluateJacobian() { diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp index 2f2c1085b..20aa89733 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp @@ -17,7 +17,7 @@ namespace ModelLib namespace ModelLib { /*! - * @brief Declaration of a passive Inductor class. + * @brief Declaration of a Inductor class. * */ template diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp index fc2a65661..cfcb5ee7b 100644 --- a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp @@ -9,9 +9,11 @@ namespace ModelLib { /*! - * @brief Constructor for a constant LinearTransformer model + * @brief Constructor for a LinearTransformer model * * Calls default ModelEvaluatorImpl constructor. + * @todo Not tested in any model yet. Should be + * @todo Has not been tested for correctness */ template @@ -65,15 +67,12 @@ int LinearTransformer::tagDifferentiable() } /** - * @brief Contributes to the bus residual. - * - * Must be connected to a PQ bus. + * @brief Computes the component resisdual + * */ template int LinearTransformer::evaluateResidual() { - //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors - // for easier development this->f_[0] = this->y_[2]; this->f_[1] = this->y_[3]; this->f_[2] = this->y_[0] - this->R1_ * this->y_[2] - this->L1_ * this->yp_[2] - this->M_ * this->yp_[3]; diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp index 0c0895383..390b47508 100644 --- a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp @@ -17,7 +17,7 @@ namespace ModelLib namespace ModelLib { /*! - * @brief Declaration of a passive LinearTransformer class. + * @brief Declaration of a LinearTransformer class. * */ template diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp index bf070f507..225a90047 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -68,7 +68,7 @@ int MicrogridBusDQ::tagDifferentiable() /** * @brief Evaluate residual of microgrid line - * This model has "Virtual resistors" on both ends with parameters RN1 and RN2 + * This model has "Virtual resistors". This component represent sum of inductions on the bus * */ template @@ -82,7 +82,7 @@ int MicrogridBusDQ::evaluateResidual() } /** - * @brief Generate Jacobian for Transmission Line + * @brief Generate Jacobian * * @tparam ScalarT * @tparam IdxT diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp index 44154da38..55946c7d4 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp @@ -17,7 +17,7 @@ namespace ModelLib namespace ModelLib { /*! - * @brief Declaration of a passive MicrogridBusDQ class. + * @brief Declaration of a MicrogridBusDQ class. * */ template diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp index d1aea251d..7c53f6f5a 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp @@ -12,7 +12,6 @@ namespace ModelLib { * Calls default ModelEvaluatorImpl constructor. * * - * Each microgrid line has a virtual resistance RN * Model is from paper: " "Modeling, Analysis and Testing of Autonomous Operation of an Inverter-Based Microgrid" Nagaraju Pogaku, Milan Prodanovic, and Timothy C. Green" * Section C @@ -71,8 +70,7 @@ int MicrogridLine::tagDifferentiable() /** * @brief Evaluate residual of microgrid line - * This model has "Virtual resistors" on both ends with parameters RN1 and RN2 - * + * */ template int MicrogridLine::evaluateResidual() @@ -97,7 +95,7 @@ int MicrogridLine::evaluateResidual() } /** - * @brief Generate Jacobian for Transmission Line + * @brief Generate Jacobian for Microgrid Line * * @tparam ScalarT * @tparam IdxT diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp index bc683045a..7eefec034 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp @@ -16,7 +16,7 @@ namespace ModelLib namespace ModelLib { /*! - * @brief Declaration of a passive MicrogridLine class. + * @brief Declaration of a MicrogridLine class. * */ template diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp index 337390965..86efe2369 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp @@ -11,8 +11,10 @@ namespace ModelLib { * * Calls default ModelEvaluatorImpl constructor. * - * This is the Medium distance form with the use of the admittance matrix. - * Since the line is of medium length then there is no real part for shunt admittance + * + * Model is from paper: " + "Modeling, Analysis and Testing of Autonomous Operation of an Inverter-Based Microgrid" Nagaraju Pogaku, Milan Prodanovic, and Timothy C. Green" + * Section D */ template diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp index fcdb9227c..bfc42eacf 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp @@ -9,7 +9,7 @@ namespace ModelLib { /*! - * @brief Constructor for a constant resistor model + * @brief Constructor for a resistor model * * Calls default ModelEvaluatorImpl constructor. */ @@ -62,9 +62,8 @@ int Resistor::tagDifferentiable() } /** - * @brief Contributes to the bus residual. + * @brief Computes the resistors resisdual * - * Must be connected to a PQ bus. */ template int Resistor::evaluateResidual() diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp index b9e01415d..12244d752 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp @@ -17,7 +17,7 @@ namespace ModelLib namespace ModelLib { /*! - * @brief Declaration of a passive Resistor class. + * @brief Declaration of a Resistor class. * */ template diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp index 83428e5fc..457194252 100644 --- a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp @@ -15,6 +15,8 @@ namespace ModelLib { * @brief Constructor for a constant SynchronousMachine model * * Calls default ModelEvaluatorImpl constructor. + * @todo This models equations are not finish + * @todo needs to be tested for correctness */ template @@ -76,10 +78,9 @@ int SynchronousMachine::tagDifferentiable() } /** - * @brief Contributes to the bus residual. + * @brief Compute the resisdual of the component. * - * Must be connected to a PQ bus. - * @todo fix up + * @todo not finished */ template int SynchronousMachine::evaluateResidual() diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp index b1ab24415..445bc38dd 100644 --- a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp @@ -18,7 +18,7 @@ namespace ModelLib namespace ModelLib { /*! - * @brief Declaration of a passive SynchronousMachine class. + * @brief Declaration of a SynchronousMachine class. * */ template diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp index f7fad07aa..a54491763 100644 --- a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp @@ -7,12 +7,14 @@ namespace ModelLib { /*! - * @brief Constructor for a constant TransmissionLine model + * @brief Constructor for a TransmissionLine model * * Calls default ModelEvaluatorImpl constructor. * * This is the Medium distance form with the use of the admittance matrix. * Since the line is of medium length then there is no real part for shunt admittance + * @todo needs to used in a model + * @todo test for correctness */ template diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp index 336515733..7959720a9 100644 --- a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp @@ -17,7 +17,7 @@ namespace ModelLib namespace ModelLib { /*! - * @brief Declaration of a passive TransmissionLine class. + * @brief Declaration of a TransmissionLine class. * * Model from Adam Birchfield paper (medium distances < 2km). * See also textbooks "Power System Analysis" by Grainger and "Power System Dynamics and Stability" by Sauer & Pai diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp index f77381dcc..6a4c9667a 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -62,15 +62,11 @@ int VoltageSource::tagDifferentiable() } /** - * @brief Contributes to the bus residual. - * - * Must be connected to a PQ bus. + * @brief Evaluate resisdual of component */ template int VoltageSource::evaluateResidual() { - //Note this leaves induction lumped into y. Perhaps would be better to seperate volatge and induction into seperate vectors - // for easier development //input this->f_[0] = -this->y_[2]; //ouput @@ -117,9 +113,6 @@ int VoltageSource::evaluateAdjointIntegrand() } - - - // Available template instantiations template class VoltageSource; template class VoltageSource; diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp index 17ba8f8c3..fef2890c0 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp @@ -17,7 +17,7 @@ namespace ModelLib namespace ModelLib { /*! - * @brief Declaration of a passive VoltageSource class. + * @brief Declaration of a VoltageSource class. * */ template diff --git a/Examples/DistributedGeneratorTest/CMakeLists.txt b/Examples/DistributedGeneratorTest/CMakeLists.txt index d158e4c58..41b124cb8 100644 --- a/Examples/DistributedGeneratorTest/CMakeLists.txt +++ b/Examples/DistributedGeneratorTest/CMakeLists.txt @@ -4,9 +4,9 @@ add_executable(dgtest DGTest.cpp) target_link_libraries(dgtest GRIDKIT::powerelec_disgen - GRIDKIT::powerelec_mircoline - GRIDKIT::powerelec_microload - GRIDKIT::solvers_dyn) - + GRIDKIT::powerelec_mircoline + GRIDKIT::powerelec_microload + GRIDKIT::solvers_dyn) + add_test(NAME DistributedGeneratorTest COMMAND $) install(TARGETS dgtest RUNTIME DESTINATION bin) diff --git a/Examples/DistributedGeneratorTest/DGTest.cpp b/Examples/DistributedGeneratorTest/DGTest.cpp index b65d7c57c..d1f58c5c8 100644 --- a/Examples/DistributedGeneratorTest/DGTest.cpp +++ b/Examples/DistributedGeneratorTest/DGTest.cpp @@ -10,6 +10,13 @@ #include +/** + * @brief Testing for the Distributed Generators outputs + * + * @param argc + * @param argv + * @return int + */ int main(int argc, char const *argv[]) { diff --git a/Examples/Microgrid/CMakeLists.txt b/Examples/Microgrid/CMakeLists.txt index 0958144c4..77c59d753 100644 --- a/Examples/Microgrid/CMakeLists.txt +++ b/Examples/Microgrid/CMakeLists.txt @@ -4,10 +4,10 @@ add_executable(microgrid Microgrid.cpp) target_link_libraries(microgrid GRIDKIT::powerelec_disgen - GRIDKIT::powerelec_mircoline - GRIDKIT::powerelec_microload - GRIDKIT::solvers_dyn - GRIDKIT::powerelec_mircobusdq) - + GRIDKIT::powerelec_mircoline + GRIDKIT::powerelec_microload + GRIDKIT::solvers_dyn + GRIDKIT::powerelec_mircobusdq) + add_test(NAME Microgrid COMMAND $) install(TARGETS microgrid RUNTIME DESTINATION bin) diff --git a/Examples/Microgrid/Microgrid.cpp b/Examples/Microgrid/Microgrid.cpp index 4cbf765f0..306394378 100644 --- a/Examples/Microgrid/Microgrid.cpp +++ b/Examples/Microgrid/Microgrid.cpp @@ -20,20 +20,19 @@ int main(int argc, char const *argv[]) { + ///@todo Needs to be modified. Some components are small relative to others thus there error is high (or could be matlab vector issue) double abstol = 1.0e-8; double reltol = 1.0e-8; size_t max_step_amount = 3000; bool usejac = true; - //TODO:setup as named parameters - //Create circuit model + //Create model ModelLib::PowerElectronicsModel* sysmodel = new ModelLib::PowerElectronicsModel(reltol, abstol, usejac, max_step_amount); //Modeled after the problem in the paper double RN = 1.0e4; //DG Params - ModelLib::DistributedGeneratorParameters parms1; parms1.wb_ = 2.0*M_PI*50.0; parms1.wc_ = 31.41; @@ -441,5 +440,8 @@ int main(int argc, char const *argv[]) printf("%lu : %e ,\n", i, abs(true_vec[i] - yfinial[i]) / abs(true_vec[i])); } + delete idas; + delete sysmodel; + return 0; } diff --git a/Examples/RLCircuit/CMakeLists.txt b/Examples/RLCircuit/CMakeLists.txt index 476eb5e95..e7e052603 100644 --- a/Examples/RLCircuit/CMakeLists.txt +++ b/Examples/RLCircuit/CMakeLists.txt @@ -4,10 +4,10 @@ add_executable(rlcircuit RLCircuit.cpp) target_link_libraries(rlcircuit GRIDKIT::powerelec_capacitor - GRIDKIT::powerelec_inductor - GRIDKIT::powerelec_resistor - GRIDKIT::powerelec_voltagesource - GRIDKIT::solvers_dyn) - + GRIDKIT::powerelec_inductor + GRIDKIT::powerelec_resistor + GRIDKIT::powerelec_voltagesource + GRIDKIT::solvers_dyn) + add_test(NAME RLCircuit COMMAND $) install(TARGETS rlcircuit RUNTIME DESTINATION bin) diff --git a/Examples/SparseTest/CMakeLists.txt b/Examples/SparseTest/CMakeLists.txt index d0b6f5e05..ef5c8ae0c 100644 --- a/Examples/SparseTest/CMakeLists.txt +++ b/Examples/SparseTest/CMakeLists.txt @@ -2,6 +2,6 @@ add_executable(spmattest SparseTest.cpp) target_link_libraries(spmattest GRIDKIT::SparseMatrix) - + add_test(NAME SparseMatrixTest COMMAND $) install(TARGETS spmattest RUNTIME DESTINATION bin) diff --git a/Solver/Dynamic/Ida.cpp b/Solver/Dynamic/Ida.cpp index c97c60cb8..637d11060 100644 --- a/Solver/Dynamic/Ida.cpp +++ b/Solver/Dynamic/Ida.cpp @@ -90,9 +90,35 @@ namespace Sundials tag_ = NULL; } + /** + * @brief Destroy the Ida< Scalar T, Idx T>:: Ida object + * + * @note if sysmodel is freed before this will fail. May want something agnostic to this + * + * @tparam ScalarT + * @tparam IdxT + */ template Ida::~Ida() { + N_VDestroy(yy_); + N_VDestroy(yp_); + N_VDestroy(yy0_); + N_VDestroy(yp0_); + if (model_->hasJacobian()) + { + SUNLinSolFree_KLU(linearSolver_); + SUNMatDestroy_Sparse(JacobianMat_); + } + else + { + SUNLinSolFree_Dense(linearSolver_); + SUNMatDestroy_Dense(JacobianMat_); + } + ///@todo this free is needed but on geninfbus this seg faults + // IDAFree(&solver_); + SUNContext_Free(&context_); + } template From a43404fa248747540850b71cdd15449231f01424 Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Wed, 17 Apr 2024 11:39:53 -0400 Subject: [PATCH 43/44] Formatting Updates with "this" and using + Minor Fixes - Removed this-> with usings for formatting - Added using for Jac to components which did not have --- .../Capacitor/Capacitor.cpp | 30 ++++---- .../Capacitor/Capacitor.hpp | 3 + .../DistributedGenerator.cpp | 71 +++++++++++-------- .../DistributedGenerator.hpp | 4 ++ .../InductionMotor/InductionMotor.cpp | 50 +++++++------ .../InductionMotor/InductionMotor.hpp | 9 ++- .../Inductor/Inductor.cpp | 26 +++---- .../Inductor/Inductor.hpp | 5 ++ .../LinearTransformer/LinearTransformer.cpp | 24 +++---- .../LinearTransformer/LinearTransformer.hpp | 5 ++ .../MicrogridBusDQ/MicrogridBusDQ.cpp | 20 +++--- .../MicrogridBusDQ/MicrogridBusDQ.hpp | 4 ++ .../MicrogridLine/MicrogridLine.cpp | 43 +++++------ .../MicrogridLine/MicrogridLine.hpp | 4 ++ .../MicrogridLoad/MicrogridLoad.cpp | 39 +++++----- .../MicrogridLoad/MicrogridLoad.hpp | 4 ++ .../Resistor/Resistor.cpp | 24 +++---- .../Resistor/Resistor.hpp | 5 ++ .../SynchronousMachine/SynchronousMachine.cpp | 40 +++++------ .../SynchronousMachine/SynchronousMachine.hpp | 9 ++- .../TransmissionLine/TransmissionLine.cpp | 54 +++++++------- .../TransmissionLine/TransmissionLine.hpp | 3 + .../VoltageSource/VoltageSource.cpp | 24 +++---- .../VoltageSource/VoltageSource.hpp | 4 ++ 24 files changed, 292 insertions(+), 212 deletions(-) diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp index 4174a88e0..779b8a627 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.cpp @@ -20,11 +20,11 @@ template Capacitor::Capacitor(IdxT id, ScalarT C) : C_(C) { - this->size_ = 3; - this->n_intern_ = 1; - this->n_extern_ = 2; - this->extern_indices_ = {0,1}; - this->idc_ = id; + size_ = 3; + n_intern_ = 1; + n_extern_ = 2; + extern_indices_ = {0,1}; + idc_ = id; } template @@ -38,9 +38,9 @@ Capacitor::~Capacitor() template int Capacitor::allocate() { - this->y_.resize(this->size_); - this->yp_.resize(this->size_); - this->f_.resize(this->size_); + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); return 0; } @@ -71,12 +71,12 @@ template int Capacitor::evaluateResidual() { //input - this->f_[0] = C_ * this->yp_[2]; + f_[0] = C_ * yp_[2]; //output - this->f_[1] = -C_ * this->yp_[2]; + f_[1] = -C_ * yp_[2]; //internal - this->f_[2] = -C_ * this->yp_[2] + this->y_[0] - this->y_[1] - this->y_[2]; + f_[2] = -C_ * yp_[2] + y_[0] - y_[1] - y_[2]; return 0; } @@ -90,21 +90,21 @@ int Capacitor::evaluateResidual() template int Capacitor::evaluateJacobian() { - this->J_.zeroMatrix(); + J_.zeroMatrix(); //Create dF/dy std::vector rcord{2,2,2}; std::vector ccord{0,1,2}; std::vector vals{1.0, -1.0, -1.0}; - this->J_.setValues(rcord, ccord, vals); + J_.setValues(rcord, ccord, vals); //Create dF/dy' std::vector rcordder{0,1,2}; std::vector ccordder{2,2,2}; - std::vector valsder{C_, -C_, -this->C_}; + std::vector valsder{C_, -C_, -C_}; COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' - this->J_.axpy(this->alpha_, Jacder); + J_.axpy(alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp index 0e445c29c..5b5fb7132 100644 --- a/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp +++ b/ComponentLib/PowerElectronicsComponents/Capacitor/Capacitor.hpp @@ -40,6 +40,9 @@ namespace ModelLib using CircuitComponent::param_; using CircuitComponent::idc_; + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; public: Capacitor(IdxT id, ScalarT C); diff --git a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp index 34148c297..21b91d751 100644 --- a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.cpp @@ -18,15 +18,30 @@ namespace ModelLib { template DistributedGenerator::DistributedGenerator(IdxT id, DistributedGeneratorParameters parm, bool reference_frame) - : wb_(parm.wb_), wc_(parm.wc_), mp_(parm.mp_), Vn_(parm.Vn_), nq_(parm.nq_), F_(parm.F_), Kiv_(parm.Kiv_), Kpv_(parm.Kpv_), Kic_(parm.Kic_), Kpc_(parm.Kpc_), Cf_(parm.Cf_), rLf_(parm.rLf_), Lf_(parm.Lf_), rLc_(parm.rLc_), Lc_(parm.Lc_), refframe_(reference_frame) + : wb_(parm.wb_), + wc_(parm.wc_), + mp_(parm.mp_), + Vn_(parm.Vn_), + nq_(parm.nq_), + F_(parm.F_), + Kiv_(parm.Kiv_), + Kpv_(parm.Kpv_), + Kic_(parm.Kic_), + Kpc_(parm.Kpc_), + Cf_(parm.Cf_), + rLf_(parm.rLf_), + Lf_(parm.Lf_), + rLc_(parm.rLc_), + Lc_(parm.Lc_), + refframe_(reference_frame) { // internals [\delta_i, Pi, Qi, phi_di, phi_qi, gamma_di, gamma_qi, il_di, il_qi, vo_di, vo_qi, io_di, io_qi] // externals [\omega_ref, vba_out, vbb_out] - this->size_ = 16; - this->n_intern_ = 13; - this->n_extern_ = 3; - this->extern_indices_ = {0,1,2}; - this->idc_ = id; + size_ = 16; + n_intern_ = 13; + n_extern_ = 3; + extern_indices_ = {0,1,2}; + idc_ = id; } template @@ -40,9 +55,9 @@ DistributedGenerator::~DistributedGenerator() template int DistributedGenerator::allocate() { - this->y_.resize(this->size_); - this->yp_.resize(this->size_); - this->f_.resize(this->size_); + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); return 0; } @@ -97,7 +112,7 @@ int DistributedGenerator::evaluateResidual() ScalarT vbq_in = -sin(y_[3]) * y_[1] + cos(y_[3]) * y_[2]; // ### Internal Componenets ## - // Rotator difference angle + // Rotor difference angle f_[3] = -yp_[3] + omega - y_[0]; // P and Q equations @@ -165,7 +180,7 @@ int DistributedGenerator::evaluateResidual() template int DistributedGenerator::evaluateJacobian() { - this->J_.zeroMatrix(); + J_.zeroMatrix(); //Create dF/dy' std::vector rcordder(13); std::vector valsder(13, -1.0); @@ -188,7 +203,7 @@ int DistributedGenerator::evaluateJacobian() rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(1); valtemp = { - sin(y_[3]) * y_[14] - cos(y_[3]) * y_[15], cos(y_[3]),-sin(y_[3])}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //r = 2 @@ -196,7 +211,7 @@ int DistributedGenerator::evaluateJacobian() rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(2); valtemp = { cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15], sin(y_[3]),cos(y_[3])}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //r = 3 @@ -204,7 +219,7 @@ int DistributedGenerator::evaluateJacobian() rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(3); valtemp = {-1.0, -mp_}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //r = 0 if (refframe_) @@ -213,7 +228,7 @@ int DistributedGenerator::evaluateJacobian() rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(0); valtemp = {-1.0, -mp_}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); } @@ -222,63 +237,63 @@ int DistributedGenerator::evaluateJacobian() rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(4); valtemp = {-wc_, wc_*y_[14], wc_*y_[15], wc_*y_[12], wc_*y_[13]}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //r = 5 ctemp = {5, 12, 13, 14, 15}; rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(5); valtemp = {-wc_, -wc_*y_[15], wc_*y_[14], wc_*y_[13], -wc_*y_[12]}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //r = 6 ctemp = {5, 12}; rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(6); valtemp = {-nq_, -1.0}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //r = 7 ctemp = {13}; rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(7); valtemp = {-1.0}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //r = 8 ctemp = {5,6,10,12,13,14}; rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(8); valtemp = {-Kpv_*nq_, Kiv_, -1.0, -Kpv_, -Cf_*wb_, F_}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //r = 9 ctemp = {7, 11, 12, 13, 15}; rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(9); valtemp = {Kiv_, -1.0, Cf_*wb_,-Kpv_,F_}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //r = 10 ctemp = {4, 5, 6, 8, 10, 11, 12, 13, 14}; rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(10); valtemp = {-mp_ * y_[11], -(Kpc_ * Kpv_ * nq_) / Lf_, (Kpc_ * Kiv_) / Lf_, Kic_ / Lf_, -(Kpc_ + rLf_) / Lf_, -mp_ * y_[4], -(Kpc_ * Kpv_ + 1.0) / Lf_, -(Cf_ * Kpc_ * wb_) / Lf_, (F_ * Kpc_) / Lf_}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //r = 11 ctemp = {4, 7, 9, 10, 11, 12, 13, 15}; rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(11); valtemp = {mp_ * y_[10], (Kiv_ * Kpc_) / Lf_, Kic_ / Lf_, mp_ * y_[4], -(Kpc_ + rLf_) / Lf_, (Cf_ * Kpc_ * wb_) / Lf_, -(Kpc_ * Kpv_ + 1.0) / Lf_, (F_ * Kpc_) / Lf_}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //r = 12 ctemp = {4, 10, 13, 14}; rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(12); valtemp = {-mp_ * y_[13], 1.0 / Cf_, wb_ - mp_ * y_[4], -1.0 / Cf_}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //r = 13 @@ -286,7 +301,7 @@ int DistributedGenerator::evaluateJacobian() rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(13); valtemp = {mp_ * y_[12], 1.0 / Cf_, -wb_ + mp_ * y_[4], -1.0 / Cf_}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //r = 14 @@ -294,7 +309,7 @@ int DistributedGenerator::evaluateJacobian() rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(14); valtemp = {(1.0/Lc_) * -cos(y_[3]) , (1.0/Lc_) * -sin(y_[3]) , (1.0/Lc_) * (sin(y_[3]) * y_[1] - cos(y_[3]) * y_[2]), -mp_ * y_[15], 1.0 / Lc_, -rLc_ / Lc_, wb_ - mp_ * y_[4]}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //r = 15 @@ -302,12 +317,12 @@ int DistributedGenerator::evaluateJacobian() rtemp.clear(); for (size_t i = 0; i < ctemp.size(); i++) rtemp.push_back(15); valtemp = {(1.0/Lc_) * sin(y_[3]) , (1.0/Lc_) * -cos(y_[3]), (1.0/Lc_) * (cos(y_[3]) * y_[1] + sin(y_[3]) * y_[2]), mp_ * y_[14], 1.0 / Lc_, -wb_ + mp_ * y_[4], -rLc_ / Lc_}; - this->J_.setValues(rtemp, ctemp, valtemp); + J_.setValues(rtemp, ctemp, valtemp); //Perform dF/dy + \alpha dF/dy' - this->J_.axpy(this->alpha_, Jacder); + J_.axpy(alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp index 4a8746492..9946f9a26 100644 --- a/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp +++ b/ComponentLib/PowerElectronicsComponents/DistributedGenerator/DistributedGenerator.hpp @@ -59,6 +59,10 @@ namespace ModelLib using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; + + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; public: diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp index 06d94da12..fa0da7fbc 100644 --- a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.cpp @@ -20,20 +20,20 @@ namespace ModelLib { */ template -InductionMotor::InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, ScalarT Llr, ScalarT Rr, ScalarT Lms, ScalarT J, ScalarT P) +InductionMotor::InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, ScalarT Llr, ScalarT Rr, ScalarT Lms, ScalarT RJ, ScalarT P) : Lls_(Lls), Rs_(Rs), Llr_(Llr), Rr_(Rr), Lms_(Lms), - J_(J), + RJ_(RJ), P_(P) { - this->size_ = 10; - this->n_intern_ = 5; - this->n_extern_ = 5; - this->extern_indices_ = {0,1,2,3,4}; - this->idc_ = id; + size_ = 10; + n_intern_ = 5; + n_extern_ = 5; + extern_indices_ = {0,1,2,3,4}; + idc_ = id; } template @@ -47,9 +47,9 @@ InductionMotor::~InductionMotor() template int InductionMotor::allocate() { - this->y_.resize(this->size_); - this->yp_.resize(this->size_); - this->f_.resize(this->size_); + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); return 0; } @@ -79,22 +79,32 @@ template int InductionMotor::evaluateResidual() { - this->f_[0] = y_[5] + y_[7]; - this->f_[1] = (-1.0/2.0) * y_[5] - (sqrt(3.0)/2.0)*y_[6] + y_[7]; - this->f_[2] = (-1.0/2.0) * y_[5] + (sqrt(3.0)/2.0)*y_[6] + y_[7]; - this->f_[3] = J_ * yp_[3] - (3.0/4.0)*P_*Lms_ * (y_[5]*y_[9] - y_[6]*y_[8]); - this->f_[4] = yp_[4] - y_[3]; - this->f_[5] = (1.0/3.0)*(2.0* y_[0] - y_[1] - y_[2]) - Rs_*y_[5] - (Lls_ + Lms_) * yp_[5] - Lms_ * yp_[6]; - this->f_[6] = (1.0/sqrt(3.0))*(-y_[1] + y_[2]) - Rs_*y_[6] - (Lls_ + Lms_) * yp_[6] - Lms_ * yp_[5]; - this->f_[7] = (y_[0] + y_[1] + y_[2])/3.0 - Rs_*y_[7] - Lls_ * yp_[7]; - this->f_[8] = Rr_*y_[8] + (Llr_ + Lms_)*yp_[8] + Lms_ * yp_[5] - (P_/2)*y_[3]*((Llr_+Lms_)*y_[9] + Lms_*y_[6]); - this->f_[9] = Rr_*y_[9] + (Llr_ + Lms_)*yp_[9] + Lms_ * yp_[6] + (P_/2)*y_[3]*((Llr_+Lms_)*y_[8] + Lms_*y_[5]); + f_[0] = y_[5] + y_[7]; + f_[1] = (-1.0/2.0) * y_[5] - (sqrt(3.0)/2.0)*y_[6] + y_[7]; + f_[2] = (-1.0/2.0) * y_[5] + (sqrt(3.0)/2.0)*y_[6] + y_[7]; + f_[3] = RJ_ * yp_[3] - (3.0/4.0)*P_*Lms_ * (y_[5]*y_[9] - y_[6]*y_[8]); + f_[4] = yp_[4] - y_[3]; + f_[5] = (1.0/3.0)*(2.0* y_[0] - y_[1] - y_[2]) - Rs_*y_[5] - (Lls_ + Lms_) * yp_[5] - Lms_ * yp_[6]; + f_[6] = (1.0/sqrt(3.0))*(-y_[1] + y_[2]) - Rs_*y_[6] - (Lls_ + Lms_) * yp_[6] - Lms_ * yp_[5]; + f_[7] = (y_[0] + y_[1] + y_[2])/3.0 - Rs_*y_[7] - Lls_ * yp_[7]; + f_[8] = Rr_*y_[8] + (Llr_ + Lms_)*yp_[8] + Lms_ * yp_[5] - (P_/2)*y_[3]*((Llr_+Lms_)*y_[9] + Lms_*y_[6]); + f_[9] = Rr_*y_[9] + (Llr_ + Lms_)*yp_[9] + Lms_ * yp_[6] + (P_/2)*y_[3]*((Llr_+Lms_)*y_[8] + Lms_*y_[5]); return 0; } +/** + * @brief Compute component Jacobian + * + * @todo need to implement + * + * @tparam ScalarT + * @tparam IdxT + * @return int + */ template int InductionMotor::evaluateJacobian() { + return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp index 58247eea0..cb49f761f 100644 --- a/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp +++ b/ComponentLib/PowerElectronicsComponents/InductionMotor/InductionMotor.hpp @@ -36,11 +36,16 @@ namespace ModelLib using CircuitComponent::ypB_; using CircuitComponent::fB_; using CircuitComponent::gB_; + using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; + + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; public: - InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, ScalarT Llr, ScalarT Rr, ScalarT Lms, ScalarT J, ScalarT P); + InductionMotor(IdxT id, ScalarT Lls, ScalarT Rs, ScalarT Llr, ScalarT Rr, ScalarT Lms, ScalarT RJ, ScalarT P); virtual ~InductionMotor(); int allocate(); @@ -61,7 +66,7 @@ namespace ModelLib ScalarT Llr_; ScalarT Rr_; ScalarT Lms_; - ScalarT J_; + ScalarT RJ_; ScalarT P_; }; } diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp index cbc6dd4c3..2bb4dd1d9 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.cpp @@ -19,9 +19,9 @@ Inductor::Inductor(IdxT id, ScalarT L) : L_(L) { size_ = 3; - this->n_intern_ = 1; - this->n_extern_ = 2; - this->extern_indices_ = {0,1}; + n_intern_ = 1; + n_extern_ = 2; + extern_indices_ = {0,1}; idc_ = id; } @@ -37,9 +37,9 @@ template int Inductor::allocate() { - this->y_.resize(this->size_); - this->yp_.resize(this->size_); - this->f_.resize(this->size_); + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); return 0; } @@ -70,11 +70,11 @@ template int Inductor::evaluateResidual() { //input - this->f_[0] = -this->y_[2]; + f_[0] = -y_[2]; //output - this->f_[1] = this->y_[2]; + f_[1] = y_[2]; //internal - this->f_[2] = -this->L_ * this->yp_[2] + this->y_[1] - this->y_[0] ; + f_[2] = -L_ * yp_[2] + y_[1] - y_[0] ; return 0; } @@ -88,22 +88,22 @@ int Inductor::evaluateResidual() template int Inductor::evaluateJacobian() { - this->J_.zeroMatrix(); + J_.zeroMatrix(); //Create dF/dy std::vector rcord{0,1,2,2}; std::vector ccord{2,2,0,1}; std::vector vals{-1.0, 1.0, -1.0, 1.0}; - this->J_.setValues(rcord, ccord, vals); + J_.setValues(rcord, ccord, vals); //Create dF/dy' std::vector rcordder{2}; std::vector ccordder{2}; - std::vector valsder{-this->L_}; + std::vector valsder{-L_}; COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,3,3); //Perform dF/dy + \alpha dF/dy' - this->J_.axpy(this->alpha_, Jacder); + J_.axpy(alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp index 20aa89733..2b0f8ec69 100644 --- a/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp +++ b/ComponentLib/PowerElectronicsComponents/Inductor/Inductor.hpp @@ -40,6 +40,11 @@ namespace ModelLib using CircuitComponent::param_; using CircuitComponent::idc_; + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; + + public: diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp index cfcb5ee7b..b53fbd278 100644 --- a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.cpp @@ -24,11 +24,11 @@ LinearTransformer::LinearTransformer(IdxT id, ScalarT L1, ScalarT R2_(R2), M_(M) { - this->size_ = 4; - this->n_intern_ = 2; - this->n_extern_ = 2; - this->extern_indices_ = {0,1}; - this->idc_ = id; + size_ = 4; + n_intern_ = 2; + n_extern_ = 2; + extern_indices_ = {0,1}; + idc_ = id; } template @@ -42,9 +42,9 @@ LinearTransformer::~LinearTransformer() template int LinearTransformer::allocate() { - this->y_.resize(this->size_); - this->yp_.resize(this->size_); - this->f_.resize(this->size_); + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); return 0; } @@ -73,10 +73,10 @@ int LinearTransformer::tagDifferentiable() template int LinearTransformer::evaluateResidual() { - this->f_[0] = this->y_[2]; - this->f_[1] = this->y_[3]; - this->f_[2] = this->y_[0] - this->R1_ * this->y_[2] - this->L1_ * this->yp_[2] - this->M_ * this->yp_[3]; - this->f_[2] = this->y_[1] - this->R2_ * this->y_[3] - this->M_ * this->yp_[2] - this->L2_ * this->yp_[3]; + f_[0] = y_[2]; + f_[1] = y_[3]; + f_[2] = y_[0] - R1_ * y_[2] - L1_ * yp_[2] - M_ * yp_[3]; + f_[2] = y_[1] - R2_ * y_[3] - M_ * yp_[2] - L2_ * yp_[3]; return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp index 390b47508..6d9a920c5 100644 --- a/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp +++ b/ComponentLib/PowerElectronicsComponents/LinearTransformer/LinearTransformer.hpp @@ -36,9 +36,14 @@ namespace ModelLib using CircuitComponent::ypB_; using CircuitComponent::fB_; using CircuitComponent::gB_; + using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; + public: LinearTransformer(IdxT id, ScalarT L1, ScalarT L2, ScalarT R1, ScalarT R2, ScalarT M); virtual ~LinearTransformer(); diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp index 225a90047..ed375cfa9 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -23,11 +23,11 @@ MicrogridBusDQ::MicrogridBusDQ(IdxT id, ScalarT RN) : RN_(RN) { // externals [vbus_d, vbus_q] - this->size_ = 2; - this->n_intern_ = 0; - this->n_extern_ = 2; - this->extern_indices_ = {0,1}; - this->idc_ = id; + size_ = 2; + n_intern_ = 0; + n_extern_ = 2; + extern_indices_ = {0,1}; + idc_ = id; } template @@ -41,9 +41,9 @@ MicrogridBusDQ::~MicrogridBusDQ() template int MicrogridBusDQ::allocate() { - this->y_.resize(this->size_); - this->yp_.resize(this->size_); - this->f_.resize(this->size_); + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); return 0; } @@ -91,13 +91,13 @@ int MicrogridBusDQ::evaluateResidual() template int MicrogridBusDQ::evaluateJacobian() { - this->J_.zeroMatrix(); + J_.zeroMatrix(); //Create dF/dy std::vector rtemp{0,1}; std::vector ctemp{0,1}; std::vector vals{-1.0 / RN_,-1.0 / RN_}; - this->J_.setValues(rtemp, ctemp, vals); + J_.setValues(rtemp, ctemp, vals); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp index 55946c7d4..cc5280fa7 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.hpp @@ -39,6 +39,10 @@ namespace ModelLib using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; + + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; public: diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp index 7c53f6f5a..46c97fa29 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.cpp @@ -21,15 +21,16 @@ namespace ModelLib { template MicrogridLine::MicrogridLine(IdxT id, ScalarT R,ScalarT L) - : R_(R), L_(L) + : R_(R), + L_(L) { // internals [id, iq] // externals [\omegaref, vbd_in, vbq_in, vbd_out, vbq_out] - this->size_ = 7; - this->n_intern_ = 2; - this->n_extern_ = 5; - this->extern_indices_ = {0,1,2,3,4}; - this->idc_ = id; + size_ = 7; + n_intern_ = 2; + n_extern_ = 5; + extern_indices_ = {0,1,2,3,4}; + idc_ = id; } template @@ -43,9 +44,9 @@ MicrogridLine::~MicrogridLine() template int MicrogridLine::allocate() { - this->y_.resize(this->size_); - this->yp_.resize(this->size_); - this->f_.resize(this->size_); + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); return 0; } @@ -76,19 +77,19 @@ template int MicrogridLine::evaluateResidual() { //ref motor - this->f_[0] = 0.0; + f_[0] = 0.0; //input - this->f_[1] = -y_[5] ; - this->f_[2] = -y_[6] ; + f_[1] = -y_[5] ; + f_[2] = -y_[6] ; //output - this->f_[3] = y_[5] ; - this->f_[4] = y_[6] ; + f_[3] = y_[5] ; + f_[4] = y_[6] ; //Internal variables - this->f_[5] = -yp_[5] - (R_ / L_) * y_[5] + y_[0]*y_[6] + (y_[1] - y_[3])/L_; - this->f_[6] = -yp_[6] - (R_ / L_) * y_[6] - y_[0]*y_[5] + (y_[2] - y_[4])/L_; + f_[5] = -yp_[5] - (R_ / L_) * y_[5] + y_[0]*y_[6] + (y_[1] - y_[3])/L_; + f_[6] = -yp_[6] - (R_ / L_) * y_[6] - y_[0]*y_[5] + (y_[2] - y_[4])/L_; return 0; @@ -104,26 +105,26 @@ int MicrogridLine::evaluateResidual() template int MicrogridLine::evaluateJacobian() { - this->J_.zeroMatrix(); + J_.zeroMatrix(); //Create dF/dy std::vector rtemp{1,2,3,4}; std::vector ctemp{5,6,5,6}; std::vector vals{-1.0,-1.0,1.0,1.0}; - this->J_.setValues(rtemp, ctemp, vals); + J_.setValues(rtemp, ctemp, vals); std::vector ccord{0, 1, 3, 5, 6}; std::vector rcord(ccord.size(),5); vals = {y_[6], (1.0 / L_) , -(1.0 / L_), - (R_ / L_) , y_[0]}; - this->J_.setValues(rcord, ccord, vals); + J_.setValues(rcord, ccord, vals); std::vector ccor2{0, 2, 4, 5, 6}; std::fill(rcord.begin(), rcord.end(), 6); vals = {-y_[5], (1.0 / L_) , -(1.0 / L_), -y_[0], - (R_ / L_)}; - this->J_.setValues(rcord, ccor2, vals); + J_.setValues(rcord, ccor2, vals); //Create -dF/dy' @@ -133,7 +134,7 @@ int MicrogridLine::evaluateJacobian() COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,7,7); //Perform dF/dy + \alpha dF/dy' - this->J_.axpy(this->alpha_, Jacder); + J_.axpy(alpha_, Jacder); return 0; diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp index 7eefec034..362cb4b63 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLine/MicrogridLine.hpp @@ -38,6 +38,10 @@ namespace ModelLib using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; + + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; public: MicrogridLine(IdxT id, ScalarT R, ScalarT L); diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp index 86efe2369..ddfa9ab94 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.cpp @@ -19,15 +19,16 @@ namespace ModelLib { template MicrogridLoad::MicrogridLoad(IdxT id, ScalarT R,ScalarT L) - : R_(R), L_(L) + : R_(R), + L_(L) { // internals [id, iq] // externals [\omegaref, vbd_out, vbq_out] - this->size_ = 5; - this->n_intern_ = 2; - this->n_extern_ = 3; - this->extern_indices_ = {0,1,2}; - this->idc_ = id; + size_ = 5; + n_intern_ = 2; + n_extern_ = 3; + extern_indices_ = {0,1,2}; + idc_ = id; } @@ -42,9 +43,9 @@ MicrogridLoad::~MicrogridLoad() template int MicrogridLoad::allocate() { - this->y_.resize(this->size_); - this->yp_.resize(this->size_); - this->f_.resize(this->size_); + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); return 0; } @@ -74,17 +75,17 @@ template int MicrogridLoad::evaluateResidual() { //ref motor - this->f_[0] = 0.0; + f_[0] = 0.0; //only input for loads //input - this->f_[1] = -y_[3] ; - this->f_[2] = -y_[4] ; + f_[1] = -y_[3] ; + f_[2] = -y_[4] ; //Internal variables - this->f_[3] = -yp_[3] - (R_ / L_) * y_[3] + y_[0]*y_[4] + y_[1] / L_; - this->f_[4] = -yp_[4] - (R_ / L_) * y_[4] - y_[0]*y_[3] + y_[2] / L_; + f_[3] = -yp_[3] - (R_ / L_) * y_[3] + y_[0]*y_[4] + y_[1] / L_; + f_[4] = -yp_[4] - (R_ / L_) * y_[4] - y_[0]*y_[3] + y_[2] / L_; return 0; @@ -100,26 +101,26 @@ int MicrogridLoad::evaluateResidual() template int MicrogridLoad::evaluateJacobian() { - this->J_.zeroMatrix(); + J_.zeroMatrix(); //Create dF/dy std::vector rtemp{1,2}; std::vector ctemp{3,4}; std::vector vals{-1.0,-1.0}; - this->J_.setValues(rtemp, ctemp, vals); + J_.setValues(rtemp, ctemp, vals); std::vector ccord{0, 1, 3, 4}; std::vector rcord(ccord.size(),3); vals = {y_[4], (1.0 / L_) , - (R_ / L_) , y_[0]}; - this->J_.setValues(rcord, ccord, vals); + J_.setValues(rcord, ccord, vals); std::vector ccor2{0, 2, 3, 4}; std::fill(rcord.begin(), rcord.end(), 4); vals = {-y_[3], (1.0 / L_) , -y_[0], - (R_ / L_)}; - this->J_.setValues(rcord, ccor2, vals); + J_.setValues(rcord, ccor2, vals); //Create -dF/dy' @@ -129,7 +130,7 @@ int MicrogridLoad::evaluateJacobian() COO_Matrix Jacder = COO_Matrix(rcordder, ccordder, valsder,5,5); //Perform dF/dy + \alpha dF/dy' - this->J_.axpy(this->alpha_, Jacder); + J_.axpy(alpha_, Jacder); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.hpp b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.hpp index 22694f614..69ad822a7 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.hpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridLoad/MicrogridLoad.hpp @@ -39,6 +39,10 @@ namespace ModelLib using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; + + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; public: diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp index bfc42eacf..caf0335f1 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.cpp @@ -18,11 +18,11 @@ template Resistor::Resistor(IdxT id, ScalarT R) : R_(R) { - this->size_ = 2; - this->n_intern_ = 0; - this->n_extern_ = 2; - this->extern_indices_ = {0,1}; - this->idc_ = id; + size_ = 2; + n_intern_ = 0; + n_extern_ = 2; + extern_indices_ = {0,1}; + idc_ = id; } template @@ -36,9 +36,9 @@ Resistor::~Resistor() template int Resistor::allocate() { - this->y_.resize(this->size_); - this->yp_.resize(this->size_); - this->f_.resize(this->size_); + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); return 0; } @@ -69,9 +69,9 @@ template int Resistor::evaluateResidual() { //input - this->f_[0] = (this->y_[0] - this->y_[1])/this->R_ ; + f_[0] = (y_[0] - y_[1])/R_ ; //ouput - this->f_[1] = (this->y_[1] - this->y_[0])/this->R_ ; + f_[1] = (y_[1] - y_[0])/R_ ; return 0; } @@ -83,8 +83,8 @@ int Resistor::evaluateJacobian() //does compiler make constant??? std::vector rcord{0,0,1,1}; std::vector ccord{0,1,0,1}; - std::vector vals{1.0 / this->R_, -1.0 / this->R_, -1.0 / this->R_, 1.0 / this->R_}; - this->J_.setValues(rcord, ccord, vals); + std::vector vals{1.0 / R_, -1.0 / R_, -1.0 / R_, 1.0 / R_}; + J_.setValues(rcord, ccord, vals); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp index 12244d752..5ec5587b7 100644 --- a/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp +++ b/ComponentLib/PowerElectronicsComponents/Resistor/Resistor.hpp @@ -40,6 +40,11 @@ namespace ModelLib using CircuitComponent::param_; using CircuitComponent::idc_; + + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; + public: Resistor(IdxT id, ScalarT R); diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp index 457194252..e3f65bed5 100644 --- a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.cpp @@ -20,7 +20,7 @@ namespace ModelLib { */ template -SynchronousMachine::SynchronousMachine(IdxT id, ScalarT Lls, std::tuple Llkq, ScalarT Llfd, ScalarT Llkd, ScalarT Lmq, ScalarT Lmd, ScalarT Rs, std::tuple Rkq, ScalarT Rfd, ScalarT Rkd, ScalarT J, ScalarT P, ScalarT mub) +SynchronousMachine::SynchronousMachine(IdxT id, ScalarT Lls, std::tuple Llkq, ScalarT Llfd, ScalarT Llkd, ScalarT Lmq, ScalarT Lmd, ScalarT Rs, std::tuple Rkq, ScalarT Rfd, ScalarT Rkd, ScalarT RJ, ScalarT P, ScalarT mub) : Lls_(Lls), Llkq_(Llkq), Llfd_(Llfd), @@ -31,15 +31,15 @@ SynchronousMachine::SynchronousMachine(IdxT id, ScalarT Lls, std: Rkq_(Rkq), Rfd_(Rfd), Rkd_(Rkd), - J_(J), + RJ_(RJ), P_(P), mub_(mub) { - this->size_ = 13; - this->n_intern_ = 6; - this->n_extern_ = 7; - this->extern_indices_ = {0,1,2,3,4}; - this->idc_ = id; + size_ = 13; + n_intern_ = 6; + n_extern_ = 7; + extern_indices_ = {0,1,2,3,4}; + idc_ = id; } template @@ -53,9 +53,9 @@ SynchronousMachine::~SynchronousMachine() template int SynchronousMachine::allocate() { - this->y_.resize(this->size_); - this->yp_.resize(this->size_); - this->f_.resize(this->size_); + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); return 0; } @@ -97,16 +97,16 @@ int SynchronousMachine::evaluateResidual() ScalarT cos23p = cos((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); ScalarT sin23p = sin((P_/2.0)*y_[5] + (2.0/3.0)*M_PI); - this->f_[0] = y_[6]*cos1 + y_[7]*sin1 + y_[8]; - this->f_[1] = y_[6]*cos23m + y_[7]*sin23m + y_[8]; - this->f_[2] = y_[6]*cos23p + y_[7]*sin23p + y_[8]; - this->f_[3] = J_ * yp_[4] - (3.0/4.0)*P_*(Lmd_ *y_[6]* (y_[7] + y_[11] + y_[12]) - Lmq_*y_[7]*(y_[6] + y_[9] + y_[0])); - this->f_[4] = yp_[5] - y_[4]; - this->f_[5] = (-2.0/3.0)*(y_[0]*cos1 +y_[1]*cos23m + y_[2]*cos23p) + Rs_*y_[6] + (Lls_ + Lmq_)*yp_[6] + Lmq_*yp_[9] + Lmq_*yp_[10] + y_[4]*(P_/2.0)*((Lls_ + Lmd_)*y_[7] + Lmd_*y_[11] + Lmd_*y_[12]); - this->f_[6] = (-2.0/3.0)*(y_[0]*sin1 -y_[1]*sin23m - y_[2]*sin23p) + Rs_*y_[7] + (Lls_ + Lmd_)*yp_[7] + Lmd_*yp_[11] + Lmd_*yp_[12] - y_[4]*(P_/2.0)*((Lls_ + Lmq_)*y_[6] + Lmq_*y_[9] + Lmq_*y_[10]); - this->f_[7] = (-1.0/3.0)*(y_[0] + y_[1] + y_[2]) + Rs_*y_[8] + Lls_*yp_[8]; - this->f_[8] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; - this->f_[9] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; + f_[0] = y_[6]*cos1 + y_[7]*sin1 + y_[8]; + f_[1] = y_[6]*cos23m + y_[7]*sin23m + y_[8]; + f_[2] = y_[6]*cos23p + y_[7]*sin23p + y_[8]; + f_[3] = RJ_ * yp_[4] - (3.0/4.0)*P_*(Lmd_ *y_[6]* (y_[7] + y_[11] + y_[12]) - Lmq_*y_[7]*(y_[6] + y_[9] + y_[0])); + f_[4] = yp_[5] - y_[4]; + f_[5] = (-2.0/3.0)*(y_[0]*cos1 +y_[1]*cos23m + y_[2]*cos23p) + Rs_*y_[6] + (Lls_ + Lmq_)*yp_[6] + Lmq_*yp_[9] + Lmq_*yp_[10] + y_[4]*(P_/2.0)*((Lls_ + Lmd_)*y_[7] + Lmd_*y_[11] + Lmd_*y_[12]); + f_[6] = (-2.0/3.0)*(y_[0]*sin1 -y_[1]*sin23m - y_[2]*sin23p) + Rs_*y_[7] + (Lls_ + Lmd_)*yp_[7] + Lmd_*yp_[11] + Lmd_*yp_[12] - y_[4]*(P_/2.0)*((Lls_ + Lmq_)*y_[6] + Lmq_*y_[9] + Lmq_*y_[10]); + f_[7] = (-1.0/3.0)*(y_[0] + y_[1] + y_[2]) + Rs_*y_[8] + Lls_*yp_[8]; + f_[8] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; + f_[9] = rkq1*y_[9] + (llkq1 + Lmq_)*yp_[9] + Lmq_*yp_[6] + Lmq_*yp_[10]; return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp index 445bc38dd..4681cb6fa 100644 --- a/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp +++ b/ComponentLib/PowerElectronicsComponents/SynchronousMachine/SynchronousMachine.hpp @@ -37,11 +37,16 @@ namespace ModelLib using CircuitComponent::ypB_; using CircuitComponent::fB_; using CircuitComponent::gB_; + using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; + public: - SynchronousMachine(IdxT id, ScalarT Lls, std::tuple Llkq, ScalarT Llfd, ScalarT Llkd, ScalarT Lmq, ScalarT Lmd, ScalarT Rs, std::tuple Rkq, ScalarT Rfd, ScalarT Rkd, ScalarT J, ScalarT P, ScalarT mub); + SynchronousMachine(IdxT id, ScalarT Lls, std::tuple Llkq, ScalarT Llfd, ScalarT Llkd, ScalarT Lmq, ScalarT Lmd, ScalarT Rs, std::tuple Rkq, ScalarT Rfd, ScalarT Rkd, ScalarT RJ, ScalarT P, ScalarT mub); virtual ~SynchronousMachine(); int allocate(); @@ -67,7 +72,7 @@ namespace ModelLib std::tuple Rkq_; ScalarT Rfd_; ScalarT Rkd_; - ScalarT J_; + ScalarT RJ_; ScalarT P_; ScalarT mub_; }; diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp index a54491763..010f38e1f 100644 --- a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.cpp @@ -19,15 +19,17 @@ namespace ModelLib { template TransmissionLine::TransmissionLine(IdxT id, ScalarT R,ScalarT X, ScalarT B) - : R_(R), X_(X), B_(B) + : R_(R), + X_(X), + B_(B) { // internals [Iret1, Iimt1, Iret2, Iimt2] // externals [Vre11, Vim11, Vre12, Vim12, Vre21, Vim21, Vre22, Vim22] - this->size_ = 12; - this->n_intern_ = 4; - this->n_extern_ = 8; - this->extern_indices_ = {0,1,2,3,4,5,6,7}; - this->idc_ = id; + size_ = 12; + n_intern_ = 4; + n_extern_ = 8; + extern_indices_ = {0,1,2,3,4,5,6,7}; + idc_ = id; ScalarT magImpendence = 1 / (R_*R_ + X_*X_); YReMat_ = magImpendence * R_; @@ -46,9 +48,9 @@ TransmissionLine::~TransmissionLine() template int TransmissionLine::allocate() { - this->y_.resize(this->size_); - this->yp_.resize(this->size_); - this->f_.resize(this->size_); + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); return 0; } @@ -93,17 +95,17 @@ template int TransmissionLine::evaluateResidual() { //input - this->f_[0] = y_[8] ; - this->f_[1] = y_[9] ; + f_[0] = y_[8] ; + f_[1] = y_[9] ; - this->f_[2] = y_[10] ; - this->f_[3] = y_[11] ; + f_[2] = y_[10] ; + f_[3] = y_[11] ; //ouput - this->f_[4] = -y_[8] ; - this->f_[5] = -y_[9] ; + f_[4] = -y_[8] ; + f_[5] = -y_[9] ; - this->f_[6] = -y_[10] ; - this->f_[7] = -y_[11] ; + f_[6] = -y_[10] ; + f_[7] = -y_[11] ; //Voltage drop accross terminals ScalarT V1re = y_[0] - y_[4]; @@ -113,12 +115,12 @@ int TransmissionLine::evaluateResidual() //Internal variables //row 1 - this->f_[8] = YReMat_ * (V1re - V2re) - (YImMatDi_ * V1im + YImMatOff_ * V2im) - y_[8] ; - this->f_[9] = YReMat_ * (V1im - V2im) + (YImMatDi_ * V1re + YImMatOff_ * V2re) - y_[9] ; + f_[8] = YReMat_ * (V1re - V2re) - (YImMatDi_ * V1im + YImMatOff_ * V2im) - y_[8] ; + f_[9] = YReMat_ * (V1im - V2im) + (YImMatDi_ * V1re + YImMatOff_ * V2re) - y_[9] ; //row2 - this->f_[10] = YReMat_ * (V2re - V1re) - (YImMatOff_ * V1im + YImMatDi_ * V2im) - y_[10]; - this->f_[11] = YReMat_ * (V2im - V1im) + (YImMatOff_ * V1re + YImMatDi_ * V2re) - y_[11]; + f_[10] = YReMat_ * (V2re - V1re) - (YImMatOff_ * V1im + YImMatDi_ * V2im) - y_[10]; + f_[11] = YReMat_ * (V2im - V1im) + (YImMatOff_ * V1re + YImMatDi_ * V2re) - y_[11]; return 0; @@ -139,29 +141,29 @@ int TransmissionLine::evaluateJacobian() std::vector rtemp{0,1,2,3,4,5,6,7,8,9,10,11}; std::vector ctemp{8,9,10,11,8,9,10,11,8,9,10,11}; std::vector vals{1.0,1.0,1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0}; - this->J_.setValues(rtemp, ctemp, vals); + J_.setValues(rtemp, ctemp, vals); std::vector ccord{0,1,2,3,4,5,6,7}; std::vector rcord(ccord.size(),8); vals = {YReMat_, -YImMatDi_ ,-YReMat_, -YImMatOff_,-YReMat_, YImMatDi_ ,YReMat_, YImMatOff_}; - this->J_.setValues(rtemp, ctemp, vals); + J_.setValues(rtemp, ctemp, vals); std::fill(rcord.begin(), rcord.end(), 9); vals = {YImMatDi_ ,YReMat_, YImMatOff_, -YReMat_,-YImMatDi_ ,-YReMat_, -YImMatOff_, YReMat_}; - this->J_.setValues(rtemp, ctemp, vals); + J_.setValues(rtemp, ctemp, vals); std::fill(rcord.begin(), rcord.end(), 10); vals = {-YReMat_, -YImMatDi_ ,YReMat_, -YImMatOff_,YReMat_, YImMatDi_ ,-YReMat_, YImMatOff_}; - this->J_.setValues(rtemp, ctemp, vals); + J_.setValues(rtemp, ctemp, vals); std::fill(rcord.begin(), rcord.end(), 11); vals = {YImMatDi_ ,-YReMat_, YImMatOff_, YReMat_,-YImMatDi_ ,YReMat_, -YImMatOff_, -YReMat_}; - this->J_.setValues(rtemp, ctemp, vals); + J_.setValues(rtemp, ctemp, vals); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp index 7959720a9..63cd1e88d 100644 --- a/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp +++ b/ComponentLib/PowerElectronicsComponents/TransmissionLine/TransmissionLine.hpp @@ -44,6 +44,9 @@ namespace ModelLib using CircuitComponent::param_; using CircuitComponent::idc_; + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; public: TransmissionLine(IdxT id, ScalarT R, ScalarT X, ScalarT B); diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp index 6a4c9667a..2e4041519 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.cpp @@ -18,11 +18,11 @@ template VoltageSource::VoltageSource(IdxT id, ScalarT V) : V_(V) { - this->size_ = 3; - this->n_intern_ = 1; - this->n_extern_ = 2; - this->extern_indices_ = {0,1}; - this->idc_ = id; + size_ = 3; + n_intern_ = 1; + n_extern_ = 2; + extern_indices_ = {0,1}; + idc_ = id; } template @@ -36,9 +36,9 @@ VoltageSource::~VoltageSource() template int VoltageSource::allocate() { - this->y_.resize(this->size_); - this->yp_.resize(this->size_); - this->f_.resize(this->size_); + y_.resize(size_); + yp_.resize(size_); + f_.resize(size_); return 0; } @@ -68,11 +68,11 @@ template int VoltageSource::evaluateResidual() { //input - this->f_[0] = -this->y_[2]; + f_[0] = -y_[2]; //ouput - this->f_[1] = this->y_[2]; + f_[1] = y_[2]; //internal - this->f_[2] = this->y_[1] - this->y_[0] - this->V_; + f_[2] = y_[1] - y_[0] - V_; return 0; } @@ -83,7 +83,7 @@ int VoltageSource::evaluateJacobian() std::vector rcord{0,1,2,2}; std::vector ccord{2,2,0,1}; std::vector vals{-1.0, 1.0, -1.0, 1.0}; - this->J_.setValues(rcord, ccord, vals); + J_.setValues(rcord, ccord, vals); return 0; } diff --git a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp index fef2890c0..89c13d3f0 100644 --- a/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp +++ b/ComponentLib/PowerElectronicsComponents/VoltageSource/VoltageSource.hpp @@ -39,6 +39,10 @@ namespace ModelLib using CircuitComponent::J_; using CircuitComponent::param_; using CircuitComponent::idc_; + + using CircuitComponent::extern_indices_; + using CircuitComponent::n_extern_; + using CircuitComponent::n_intern_; public: VoltageSource(IdxT id, ScalarT V); From 92504112718f8d9ec1d169a9a35ef173e1998b6e Mon Sep 17 00:00:00 2001 From: Reid Gomillion Date: Fri, 3 May 2024 12:22:58 -0400 Subject: [PATCH 44/44] Added Better Description to the MicrogridBus --- .../MicrogridBusDQ/MicrogridBusDQ.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp index ed375cfa9..0355e44d0 100644 --- a/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp +++ b/ComponentLib/PowerElectronicsComponents/MicrogridBusDQ/MicrogridBusDQ.cpp @@ -68,8 +68,11 @@ int MicrogridBusDQ::tagDifferentiable() /** * @brief Evaluate residual of microgrid line - * This model has "Virtual resistors". This component represent sum of inductions on the bus + * This model has "Virtual resistors". The voltage of the bus divided by its virtual resistance. + * The components are external to allow for outside components to add inductances to the terms. * + * refernce to equations in class header + * */ template int MicrogridBusDQ::evaluateResidual()