DPsim
Loading...
Searching...
No Matches
MNASolverPlugin.cpp
Go to the documentation of this file.
1/* Copyright 2017-2021 Institute for Automation of Complex Power Systems,
2 * EONERC, RWTH Aachen University
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 *********************************************************************************/
8
9#include <Eigen/Eigen>
10#include <dlfcn.h>
13
14using namespace DPsim;
15using namespace CPS;
16
17namespace DPsim {
18
19template <typename VarType>
21 CPS::Domain domain,
22 CPS::Logger::Level logLevel)
23 : MnaSolverDirect<VarType>(name, domain, logLevel), mPluginName(pluginName),
24 mPlugin(nullptr), mDlHandle(nullptr) {}
25
26template <typename VarType> MnaSolverPlugin<VarType>::~MnaSolverPlugin() {
27 if (mPlugin != nullptr) {
28 mPlugin->cleanup();
29 }
30 if (mDlHandle != nullptr) {
31 dlclose(mDlHandle);
32 }
33}
34
35extern "C" void pluginLogger(const char *str) {
36 CPS::Logger::Log log = CPS::Logger::get("Plugin", CPS::Logger::Level::debug,
37 CPS::Logger::Level::debug);
38 SPDLOG_LOGGER_INFO(log, str);
39}
40
41template <typename VarType>
43 // Start from base matrix
45
46 // Now stamp switches into matrix
47 for (auto sw : this->mMNAIntfSwitches)
48 sw->mnaApplySystemMatrixStamp(this->mVariableSystemMatrix);
49
50 // Now stamp variable elements into matrix
51 for (auto comp : this->mMNAIntfVariableComps)
52 comp->mnaApplySystemMatrixStamp(this->mVariableSystemMatrix);
53
54 int size = this->mRightSideVector.rows();
55 int nnz = this->mVariableSystemMatrix.nonZeros();
56 struct dpsim_csr_matrix matrix = {
57 .values = this->mVariableSystemMatrix.valuePtr(),
58 .rowIndex = this->mVariableSystemMatrix.outerIndexPtr(),
59 .colIndex = this->mVariableSystemMatrix.innerIndexPtr(),
60 .row_number = size,
61 .nnz = nnz,
62 };
63 // Refactorization of matrix assuming that structure remained
64 // constant by omitting analyzePattern
65 if (mPlugin->lu_decomp(&matrix) != 0) {
66 SPDLOG_LOGGER_ERROR(this->mSLog, "error recomputing decomposition");
67 return;
68 }
69 ++this->mNumRecomputations;
70}
71
72template <typename VarType> void MnaSolverPlugin<VarType>::initialize() {
74 int size = this->mRightSideVector.rows();
75 std::vector<SparseMatrix> hMat;
76 int nnz = 0;
78 throw CPS::SystemError(
79 "System-matrix recomputation is not supported by MNA solver plugins.");
80 } else {
81 hMat = this->mSwitchedMatrices[std::bitset<SWITCH_NUM>(0)];
82 nnz = hMat[0].nonZeros();
83 }
84
85 struct dpsim_mna_plugin *(*get_mna_plugin)(const char *);
86
87 String pluginFileName = mPluginName + ".so";
88
89 if ((mDlHandle = dlopen(pluginFileName.c_str(), RTLD_NOW)) == nullptr) {
90 SPDLOG_LOGGER_ERROR(this->mSLog, "error opening dynamic library {}: {}",
91 mPluginName, dlerror());
92 throw CPS::SystemError("error opening dynamic library.");
93 }
94
95 get_mna_plugin = (struct dpsim_mna_plugin * (*)(const char *))
96 dlsym(mDlHandle, "get_mna_plugin");
97 if (get_mna_plugin == NULL) {
98 SPDLOG_LOGGER_ERROR(this->mSLog, "error reading symbol from library {}: {}",
99 mPluginName, dlerror());
100 throw CPS::SystemError("error reading symbol from library.");
101 }
102
103 if ((mPlugin = get_mna_plugin(mPluginName.c_str())) == nullptr) {
104 SPDLOG_LOGGER_ERROR(this->mSLog, "error getting plugin class");
105 throw CPS::SystemError("error getting plugin class.");
106 }
107
108 mPlugin->log = pluginLogger;
109
110 struct dpsim_csr_matrix matrix = {
111 .values = hMat[0].valuePtr(),
112 .rowIndex = hMat[0].outerIndexPtr(),
113 .colIndex = hMat[0].innerIndexPtr(),
114 .row_number = size,
115 .nnz = nnz,
116 };
117
118 if (mPlugin->init(&matrix) != 0) {
119 SPDLOG_LOGGER_ERROR(this->mSLog, "error initializing plugin");
120 return;
121 }
122}
123
124template <typename VarType> Task::List MnaSolverPlugin<VarType>::getTasks() {
125 Task::List l;
126
127 for (auto comp : this->mMNAComponents) {
128 for (auto task : comp->mnaTasks()) {
129 l.push_back(task);
130 }
131 }
132 for (auto node : this->mNodes) {
133 for (auto task : node->mnaTasks())
134 l.push_back(task);
135 }
136 // TODO signal components should be moved out of MNA solver
137 for (auto comp : this->mSimSignalComps) {
138 for (auto task : comp->getTasks()) {
139 l.push_back(task);
140 }
141 }
142 l.push_back(std::make_shared<MnaSolverPlugin<VarType>::SolveTask>(*this));
143 l.push_back(std::make_shared<MnaSolverPlugin<VarType>::LogTask>(*this));
144 return l;
145}
146
147template <typename VarType>
148void MnaSolverPlugin<VarType>::solve(Real time, Int timeStepCount) {
149 // Reset source vector
150 this->mRightSideVector.setZero();
151
152 // Add together the right side vector (computed by the components'
153 // pre-step tasks)
154 for (const auto &stamp : this->mRightVectorStamps)
155 this->mRightSideVector += *stamp;
156
157 if (!this->mIsInInitialization)
158 this->updateSwitchStatus();
159
160 mPlugin->solve((double *)this->mRightSideVector.data(),
161 (double *)this->leftSideVector().data());
162
163 // TODO split into separate task? (dependent on x, updating all v attributes)
164 for (UInt nodeIdx = 0; nodeIdx < this->mNumNetNodes; ++nodeIdx)
165 this->mNodes[nodeIdx]->mnaUpdateVoltage(**(this->mLeftSideVector));
166
167 // Components' states will be updated by the post-step tasks
168}
169
170} // namespace DPsim
171template class DPsim::MnaSolverPlugin<Real>;
spdlog::level::level_enum Level
Definition Logger.h:33
std::shared_ptr< spdlog::logger > Log
Definition Logger.h:34
static Log get(const std::string &name, Level filelevel=Level::info, Level clilevel=Level::off)
Definition Logger.cpp:139
std::vector< Ptr > List
Definition Task.h:28
SparseMatrix mVariableSystemMatrix
System matrix including stamp of static and variable elements.
SparseMatrix mBaseSystemMatrix
System matrix including all static elements.
std::unordered_map< std::bitset< SWITCH_NUM >, std::vector< SparseMatrix > > mSwitchedMatrices
Map of system matrices where the key is the bitset describing the switch states.
MnaSolverDirect(String name, CPS::Domain domain=CPS::Domain::DP, CPS::Logger::Level logLevel=CPS::Logger::Level::info)
Matrix mRightSideVector
Source vector of known quantities.
Definition MNASolver.h:84
virtual void initialize() override
Calls subroutines to set up everything that is required before simulation.
Definition MNASolver.cpp:54
CPS::MNAInterface::List mMNAIntfVariableComps
List of variable components if they must be accessed as MNAInterface objects.
Definition MNASolver.h:99
UInt mNumNetNodes
Number of network nodes, single line equivalent.
Definition MNASolver.h:47
CPS::MNAInterface::List mMNAIntfSwitches
List of switches if they must be accessed as MNAInterface objects.
Definition MNASolver.h:75
std::vector< const Matrix * > mRightVectorStamps
List of all right side vector contributions.
Definition MNASolver.h:86
void updateSwitchStatus()
Collects the status of switches to select correct system matrix.
Int mNumRecomputations
Number of system matrix recomputations.
Definition MNASolver.h:94
CPS::MNAInterface::List mMNAComponents
List of MNA components with static stamp into system matrix.
Definition MNASolver.h:70
CPS::Attribute< Matrix >::Ptr mLeftSideVector
Solution vector of unknown quantities.
Definition MNASolver.h:210
CPS::SimSignalComp::List mSimSignalComps
List of signal type components that do not directly interact with the MNA solver.
Definition MNASolver.h:77
CPS::SimNode< VarType >::List mNodes
List of simulation nodes.
Definition MNASolver.h:66
CPS::Task::List getTasks() override
Get tasks for scheduler.
CPS::Logger::Log mSLog
Logger.
Definition Solver.h:55
struct dpsim_mna_plugin * mPlugin
void solve(Real time, Int timeStepCount) override
Solves system for single frequency.
MnaSolverPlugin(String pluginName, String name, CPS::Domain domain=CPS::Domain::DP, CPS::Logger::Level logLevel=CPS::Logger::Level::info)
void recomputeSystemMatrix(Real time) override
Recomputes systems matrix.
void initialize() override
Initialize cuSparse-library.
Bool mSystemMatrixRecomputationEnabled
Effective system-matrix recomputation setting used by the solver.
Definition Solver.h:77
Bool mIsInInitialization
Determines if solver is in initialization phase, which requires different behavior.
Definition Solver.h:69
struct dpsim_mna_plugin * get_mna_plugin(const char *name)
Definition example.c:22
CPS::Real Real
Definition Definitions.h:18
CPS::String String
Definition Definitions.h:20
CPS::Int Int
Definition Definitions.h:22
void pluginLogger(const char *str)
CPS::UInt UInt
Definition Definitions.h:23