DPsim
MNASolverDirect.h
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 #pragma once
10 
11 #include <bitset>
12 #include <iostream>
13 #include <list>
14 #include <memory>
15 #include <unordered_map>
16 #include <vector>
17 
18 #include <dpsim/Config.h>
19 #include <dpsim/DataLogger.h>
20 #include <dpsim/DenseLUAdapter.h>
21 #include <dpsim/DirectLinearSolver.h>
22 #include <dpsim/DirectLinearSolverConfiguration.h>
23 #include <dpsim/Solver.h>
24 #ifdef WITH_KLU
25 #include <dpsim/KLUAdapter.h>
26 #endif
27 #include <dpsim/SparseLUAdapter.h>
28 #ifdef WITH_CUDA
29 #include <dpsim/GpuDenseAdapter.h>
30 #ifdef WITH_CUDA_SPARSE
31 #include <dpsim/GpuSparseAdapter.h>
32 #endif
33 #ifdef WITH_MAGMA
34 #include <dpsim/GpuMagmaAdapter.h>
35 #endif
36 #endif
37 #include <dpsim-models/AttributeList.h>
38 #include <dpsim-models/SimPowerComp.h>
39 #include <dpsim-models/SimSignalComp.h>
40 #include <dpsim-models/Solver/MNASwitchInterface.h>
41 #include <dpsim-models/Solver/MNAVariableCompInterface.h>
42 #include <dpsim/MNASolver.h>
43 
44 namespace DPsim {
45 
46 enum DirectLinearSolverImpl {
47  Undef = 0,
48  KLU,
49  SparseLU,
50  DenseLU,
51  CUDADense,
52  CUDASparse,
53  CUDAMagma,
54  Plugin
55 };
56 
58 template <typename VarType> class MnaSolverDirect : public MnaSolver<VarType> {
59 
60 protected:
61  // #### Data structures for precomputed switch matrices (optionally with parallel frequencies) ####
63  std::unordered_map<std::bitset<SWITCH_NUM>, std::vector<SparseMatrix>>
66  std::unordered_map<std::bitset<SWITCH_NUM>,
67  std::vector<std::shared_ptr<DirectLinearSolver>>>
69 
70  // #### Data structures for system recomputation over time ####
72  SparseMatrix mBaseSystemMatrix;
74  SparseMatrix mVariableSystemMatrix;
76  std::shared_ptr<DirectLinearSolver> mDirectLinearSolverVariableSystemMatrix;
78  DirectLinearSolverImpl mImplementationInUse;
81 
106 
107  // #### General
109  void createEmptySystemMatrix() override;
110 
111  // #### Methods for precomputed switch matrices (optionally with parallel frequencies) ####
113  void switchedMatrixEmpty(std::size_t index) override;
115  void switchedMatrixEmpty(std::size_t swIdx, Int freqIdx) override;
117  void switchedMatrixStamp(
118  std::size_t index,
119  std::vector<std::shared_ptr<CPS::MNAInterface>> &comp) override;
120 
121  // #### Methods for system recomputation over time ####
123  void stampVariableSystemMatrix() override;
125  void solveWithSystemMatrixRecomputation(Real time,
126  Int timeStepCount) override;
128  std::shared_ptr<CPS::Task> createSolveTaskRecomp() override;
130  virtual void recomputeSystemMatrix(Real time);
131 
132  // #### Scheduler Task Methods ####
134  std::shared_ptr<CPS::Task> createSolveTask() override;
136  std::shared_ptr<CPS::Task> createLogTask() override;
138  std::shared_ptr<CPS::Task> createSolveTaskHarm(UInt freqIdx) override;
140  void logSystemMatrices() override;
142  void solve(Real time, Int timeStepCount) override;
144  void solveWithHarmonics(Real time, Int timeStepCount, Int freqIdx) override;
145 
147  void logSolveTime();
149  void logFactorizationTime();
151  void logRecomputationTime();
152 
154  std::shared_ptr<DirectLinearSolver>
155  createDirectSolverImplementation(CPS::Logger::Log mSLog);
156 
157 public:
160  MnaSolverDirect(String name, CPS::Domain domain = CPS::Domain::DP,
161  CPS::Logger::Level logLevel = CPS::Logger::Level::info);
162 
164  virtual ~MnaSolverDirect() = default;
165 
167  void
168  setDirectLinearSolverImplementation(DirectLinearSolverImpl implementation);
169 
172  DirectLinearSolverConfiguration &configuration) override;
173 
175  void logLUTimes() override;
176 
178  int mIter = 0;
179 
180  // #### MNA Solver Tasks ####
182  class SolveTask : public CPS::Task {
183  public:
185  : Task(solver.mName + ".Solve"), mSolver(solver) {
186 
187  for (auto it : solver.mMNAComponents) {
188  if (it->getRightVector()->get().size() != 0)
189  mAttributeDependencies.push_back(it->getRightVector());
190  }
191  for (auto node : solver.mNodes) {
192  mModifiedAttributes.push_back(node->mVoltage);
193  }
194  mModifiedAttributes.push_back(solver.mLeftSideVector);
195  }
196 
197  void execute(Real time, Int timeStepCount) {
198  mSolver.solve(time, timeStepCount);
199  }
200 
201  private:
202  MnaSolverDirect<VarType> &mSolver;
203  };
204 
206  class SolveTaskHarm : public CPS::Task {
207  public:
208  SolveTaskHarm(MnaSolverDirect<VarType> &solver, UInt freqIdx)
209  : Task(solver.mName + ".Solve"), mSolver(solver), mFreqIdx(freqIdx) {
210 
211  for (auto it : solver.mMNAComponents) {
212  if (it->getRightVector()->get().size() != 0)
213  mAttributeDependencies.push_back(it->getRightVector());
214  }
215  for (auto node : solver.mNodes) {
216  mModifiedAttributes.push_back(node->mVoltage);
217  }
218  for (auto leftVec : solver.mLeftSideVectorHarm) {
219  mModifiedAttributes.push_back(leftVec);
220  }
221  }
222 
223  void execute(Real time, Int timeStepCount) {
224  mSolver.solveWithHarmonics(time, timeStepCount, mFreqIdx);
225  }
226 
227  private:
228  MnaSolverDirect<VarType> &mSolver;
229  UInt mFreqIdx;
230  };
231 
233  class SolveTaskRecomp : public CPS::Task {
234  public:
236  : Task(solver.mName + ".Solve"), mSolver(solver) {
237 
238  for (auto it : solver.mMNAComponents) {
239  if (it->getRightVector()->get().size() != 0)
240  mAttributeDependencies.push_back(it->getRightVector());
241  }
242  for (auto it : solver.mMNAIntfVariableComps) {
243  if (it->getRightVector()->get().size() != 0)
244  mAttributeDependencies.push_back(it->getRightVector());
245  }
246  for (auto node : solver.mNodes) {
247  mModifiedAttributes.push_back(node->mVoltage);
248  }
249  mModifiedAttributes.push_back(solver.mLeftSideVector);
250  }
251 
252  void execute(Real time, Int timeStepCount) {
253  mSolver.solveWithSystemMatrixRecomputation(time, timeStepCount);
254  mSolver.log(time, timeStepCount);
255  }
256 
257  private:
258  MnaSolverDirect<VarType> &mSolver;
259  };
260 
262  class LogTask : public CPS::Task {
263  public:
265  : Task(solver.mName + ".Log"), mSolver(solver) {
266  mAttributeDependencies.push_back(solver.mLeftSideVector);
267  mModifiedAttributes.push_back(Scheduler::external);
268  }
269 
270  void execute(Real time, Int timeStepCount) {
271  mSolver.log(time, timeStepCount);
272  }
273 
274  private:
275  MnaSolverDirect<VarType> &mSolver;
276  };
277 };
278 } // namespace DPsim
Tasks to be defined by every component.
Definition: Task.h:25
Solver class using Modified Nodal Analysis (MNA).
std::shared_ptr< CPS::Task > createSolveTask() override
Create a solve task for this solver implementation.
void stampVariableSystemMatrix() override
Stamps components into the variable system matrix.
void logSolveTime()
Logging of the right-hand-side solution time.
virtual ~MnaSolverDirect()=default
Destructor.
void logFactorizationTime()
Logging of the LU factorization time.
void solve(Real time, Int timeStepCount) override
Solves system for single frequency.
void logRecomputationTime()
Logging of the LU refactorization time.
virtual void recomputeSystemMatrix(Real time)
Recomputes systems matrix.
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.
void switchedMatrixStamp(std::size_t index, std::vector< std::shared_ptr< CPS::MNAInterface >> &comp) override
Applies a component stamp to the matrix with the given switch index.
std::shared_ptr< DirectLinearSolver > createDirectSolverImplementation(CPS::Logger::Log mSLog)
Returns a pointer to an object of type DirectLinearSolver.
void setDirectLinearSolverConfiguration(DirectLinearSolverConfiguration &configuration) override
Sets the linear solver configuration.
DirectLinearSolverImpl mImplementationInUse
LU factorization indicator.
std::shared_ptr< DirectLinearSolver > mDirectLinearSolverVariableSystemMatrix
LU factorization of variable system matrix.
void setDirectLinearSolverImplementation(DirectLinearSolverImpl implementation)
Sets the linear solver to "implementation" and creates an object.
std::shared_ptr< CPS::Task > createSolveTaskHarm(UInt freqIdx) override
Create a solve task for this solver implementation.
std::shared_ptr< CPS::Task > createSolveTaskRecomp() override
Create a solve task for recomputation solver.
void logSystemMatrices() override
Logging of system matrices and source vector.
void createEmptySystemMatrix() override
Create system matrix.
std::shared_ptr< CPS::Task > createLogTask() override
Create a solve task for this solver implementation.
void logLUTimes() override
log LU decomposition times
void switchedMatrixEmpty(std::size_t index) override
Sets all entries in the matrix with the given switch index to zero.
void solveWithSystemMatrixRecomputation(Real time, Int timeStepCount) override
Solves the system with variable system matrix.
std::unordered_map< std::bitset< SWITCH_NUM >, std::vector< std::shared_ptr< DirectLinearSolver > > > mDirectLinearSolvers
Map of direct linear solvers related to the system matrices.
MnaSolverDirect(String name, CPS::Domain domain=CPS::Domain::DP, CPS::Logger::Level logLevel=CPS::Logger::Level::info)
DirectLinearSolverConfiguration mConfigurationInUse
LU factorization configuration.
void solveWithHarmonics(Real time, Int timeStepCount, Int freqIdx) override
Solves system for multiple frequencies.
Solver class using Modified Nodal Analysis (MNA).
Definition: MNASolver.h:38
std::vector< CPS::Attribute< Matrix >::Ptr > mLeftSideVectorHarm
Solution vector of unknown quantities (parallel frequencies)
Definition: MNASolver.h:199
CPS::MNAInterface::List mMNAIntfVariableComps
List of variable components if they must be accessed as MNAInterface objects.
Definition: MNASolver.h:98
CPS::MNAInterface::List mMNAComponents
List of MNA components with static stamp into system matrix.
Definition: MNASolver.h:69
CPS::Attribute< Matrix >::Ptr mLeftSideVector
Solution vector of unknown quantities.
Definition: MNASolver.h:196
CPS::SimNode< VarType >::List mNodes
List of simulation nodes.
Definition: MNASolver.h:65
String mName
Name for logging.
Definition: Solver.h:39
CPS::Logger::Log mSLog
Logger.
Definition: Solver.h:43