DPsim
MNASolverFactory.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 <dpsim/DataLogger.h>
12 #include <dpsim/DenseLUAdapter.h>
13 #include <dpsim/DirectLinearSolverConfiguration.h>
14 #include <dpsim/MNASolver.h>
15 #include <dpsim/MNASolverDirect.h>
16 #include <dpsim/SparseLUAdapter.h>
17 #ifdef WITH_KLU
18 #include <dpsim/KLUAdapter.h>
19 #endif
20 #ifdef WITH_CUDA
21 #include <dpsim/GpuDenseAdapter.h>
22 #ifdef WITH_CUDA_SPARSE
23 #include <dpsim/GpuSparseAdapter.h>
24 #endif
25 #ifdef WITH_MAGMA
26 #include <dpsim/GpuMagmaAdapter.h>
27 #endif
28 #endif
29 #ifdef WITH_MNASOLVERPLUGIN
30 #include <dpsim/MNASolverPlugin.h>
31 #endif
32 
33 namespace DPsim {
34 
36 public:
38  static const std::vector<DirectLinearSolverImpl> mSupportedSolverImpls(void) {
39  static std::vector<DirectLinearSolverImpl> ret = {
40 #ifdef WITH_MNASOLVERPLUGIN
41  DirectLinearSolverImpl::Plugin,
42 #endif //WITH_MNASOLVERPLUGIN
43 #ifdef WITH_CUDA
44  DirectLinearSolverImpl::CUDADense,
45 #ifdef WITH_CUDA_SPARSE
46 #endif // WITH_CUDA_SPARSE
47  DirectLinearSolverImpl::CUDASparse,
48 #ifdef WITH_MAGMA
49  DirectLinearSolverImpl::CUDAMagma,
50 #endif // WITH_MAGMA
51 #endif // WITH_CUDA
52  DirectLinearSolverImpl::DenseLU, DirectLinearSolverImpl::SparseLU,
53 #ifdef WITH_KLU
54  DirectLinearSolverImpl::KLU
55 #endif //WITH_KLU
56  };
57  return ret;
58  }
59 
61  template <typename VarType>
62  static std::shared_ptr<MnaSolver<VarType>> factory(
63  String name, CPS::Domain domain = CPS::Domain::DP,
64  CPS::Logger::Level logLevel = CPS::Logger::Level::info,
65  DirectLinearSolverImpl implementation = mSupportedSolverImpls().back(),
66  String pluginName = "plugin.so") {
67  //To avoid regression we use KLU in case of undefined implementation
68  if (implementation == DirectLinearSolverImpl::Undef) {
69 #ifdef WITH_KLU
70  implementation = DirectLinearSolverImpl::KLU;
71 #else
72  implementation = mSupportedSolverImpls().back();
73 #endif
74  }
75  CPS::Logger::Log log = CPS::Logger::get(
76  "MnaSolverFactory", CPS::Logger::Level::info, CPS::Logger::Level::info);
77 
78  switch (implementation) {
79  /* TODO: have only one "solver" object of type MnaSolverDirect and only use setDirectLinearSolverImplementation in the switch-case.
80  * This is not done now, since MnaSolverDirect and MnaSolver are distinct classes - and someone might add another subclass of MnaSolver
81  * to the project (MnaSolverIterative?). It is planned to merge MnaSolverDirect and MnaSolver anyway, so this won't happen. */
82  case DirectLinearSolverImpl::SparseLU: {
83  log->info("creating SparseLUAdapter solver implementation");
84  std::shared_ptr<MnaSolverDirect<VarType>> sparseSolver =
85  std::make_shared<MnaSolverDirect<VarType>>(name, domain, logLevel);
86  sparseSolver->setDirectLinearSolverImplementation(
87  DirectLinearSolverImpl::SparseLU);
88  return sparseSolver;
89  }
90  case DirectLinearSolverImpl::DenseLU: {
91  log->info("creating DenseLUAdapter solver implementation");
92  std::shared_ptr<MnaSolverDirect<VarType>> denseSolver =
93  std::make_shared<MnaSolverDirect<VarType>>(name, domain, logLevel);
94  denseSolver->setDirectLinearSolverImplementation(
95  DirectLinearSolverImpl::DenseLU);
96  return denseSolver;
97  }
98 #ifdef WITH_KLU
99  case DirectLinearSolverImpl::KLU: {
100  log->info("creating KLUAdapter solver implementation");
101  std::shared_ptr<MnaSolverDirect<VarType>> kluSolver =
102  std::make_shared<MnaSolverDirect<VarType>>(name, domain, logLevel);
103  kluSolver->setDirectLinearSolverImplementation(
104  DirectLinearSolverImpl::KLU);
105  return kluSolver;
106  }
107 #endif
108 #ifdef WITH_CUDA
109  case DirectLinearSolverImpl::CUDADense: {
110  log->info("creating GpuDenseAdapter solver implementation");
111  std::shared_ptr<MnaSolverDirect<VarType>> gpuDenseSolver =
112  std::make_shared<MnaSolverDirect<VarType>>(name, domain, logLevel);
113  gpuDenseSolver->setDirectLinearSolverImplementation(
114  DirectLinearSolverImpl::CUDADense);
115  return gpuDenseSolver;
116  }
117 #ifdef WITH_CUDA_SPARSE
118  case DirectLinearSolverImpl::CUDASparse: {
119  log->info("creating GpuSparseAdapter solver implementation");
120  std::shared_ptr<MnaSolverDirect<VarType>> gpuSparseSolver =
121  std::make_shared<MnaSolverDirect<VarType>>(name, domain, logLevel);
122  gpuSparseSolver->setDirectLinearSolverImplementation(
123  DirectLinearSolverImpl::CUDASparse);
124  return gpuSparseSolver;
125  }
126 #endif
127 #ifdef WITH_MAGMA
128  case DirectLinearSolverImpl::CUDAMagma: {
129  log->info("creating GpuMagmaAdapter solver implementation");
130  std::shared_ptr<MnaSolverDirect<VarType>> gpuMagmaSolver =
131  std::make_shared<MnaSolverDirect<VarType>>(name, domain, logLevel);
132  gpuMagmaSolver->setDirectLinearSolverImplementation(
133  DirectLinearSolverImpl::CUDAMagma);
134  return gpuMagmaSolver;
135  }
136 #endif
137 #endif
138 #ifdef WITH_MNASOLVERPLUGIN
139  case DirectLinearSolverImpl::Plugin:
140  log->info("creating Plugin solver implementation");
141  return std::make_shared<MnaSolverPlugin<VarType>>(pluginName, name,
142  domain, logLevel);
143 #endif
144  default:
145  throw CPS::SystemError("unsupported MNA implementation.");
146  }
147  }
148 };
149 } // namespace DPsim
static const std::vector< DirectLinearSolverImpl > mSupportedSolverImpls(void)
MNA implementations supported by this compilation.
static std::shared_ptr< MnaSolver< VarType > > factory(String name, CPS::Domain domain=CPS::Domain::DP, CPS::Logger::Level logLevel=CPS::Logger::Level::info, DirectLinearSolverImpl implementation=mSupportedSolverImpls().back(), String pluginName="plugin.so")
sovlerImpl: choose the most advanced solver implementation available by default