9#include <dpsim/MNASolverDirect.h>
10#include <dpsim/SequentialScheduler.h>
17template <
typename VarType>
19 CPS::Logger::Level logLevel)
20 :
MnaSolver<VarType>(name, domain, logLevel) {
23#elif defined(WITH_SPARSE)
30template <
typename VarType>
35template <
typename VarType>
41template <
typename VarType>
43 std::size_t index, std::vector<std::shared_ptr<CPS::MNAInterface>> &comp) {
44 auto bit = std::bitset<SWITCH_NUM>(index);
46 for (
auto component : comp) {
47 component->mnaApplySystemMatrixStamp(sys);
49 for (UInt i = 0; i <
mSwitches.size(); ++i)
50 mSwitches[i]->mnaApplySwitchSystemMatrixStamp(bit[i], sys, 0);
55 auto start = std::chrono::steady_clock::now();
57 auto end = std::chrono::steady_clock::now();
58 std::chrono::duration<Real> diff = end - start;
62template <
typename VarType>
71 SPDLOG_LOGGER_INFO(
mSLog,
72 "Number of variable Elements: {}"
73 "\nNumber of MNA components: {}",
80 SPDLOG_LOGGER_INFO(
mSLog,
"Base matrix with only static elements: {}",
88 SPDLOG_LOGGER_INFO(
mSLog,
"Stamping variable elements");
92 SPDLOG_LOGGER_INFO(
mSLog,
"Initial system matrix with variable elements {}",
101 auto start = std::chrono::steady_clock::now();
103 auto end = std::chrono::steady_clock::now();
104 std::chrono::duration<Real> diff = end - start;
108template <
typename VarType>
110 Real time, Int timeStepCount) {
125 auto start = std::chrono::steady_clock::now();
128 auto end = std::chrono::steady_clock::now();
129 std::chrono::duration<Real> diff = end - start;
133 for (UInt nodeIdx = 0; nodeIdx <
mNumNetNodes; ++nodeIdx)
139template <
typename VarType>
150 auto start = std::chrono::steady_clock::now();
153 auto end = std::chrono::steady_clock::now();
154 std::chrono::duration<Real> diff = end - start;
159template <
typename VarType>
185 for (std::size_t i = 0; i < (1ULL <<
mSwitches.size()); i++) {
186 auto bit = std::bitset<SWITCH_NUM>(i);
200 for (UInt i = 0; i < std::pow(2,
mSwitches.size()); ++i) {
201 for (Int freq = 0; freq <
mSystem.mFrequencies.size(); ++freq) {
202 auto bit = std::bitset<SWITCH_NUM>(i);
215 for (std::size_t i = 0; i < (1ULL <<
mSwitches.size()); i++) {
216 auto bit = std::bitset<SWITCH_NUM>(i);
225template <
typename VarType>
227 return std::make_shared<MnaSolverDirect<VarType>::SolveTask>(*this);
230template <
typename VarType>
232 return std::make_shared<MnaSolverDirect<VarType>::SolveTaskRecomp>(*this);
235template <
typename VarType>
236std::shared_ptr<CPS::Task>
238 return std::make_shared<MnaSolverDirect<VarType>::SolveTaskHarm>(*
this,
242template <
typename VarType>
243std::shared_ptr<CPS::Task>
245 return std::make_shared<
249template <
typename VarType>
251 return std::make_shared<MnaSolverDirect<VarType>::LogTask>(*this);
254template <
typename VarType>
268 std::chrono::steady_clock::time_point start;
270 start = std::chrono::steady_clock::now();
276 auto end = std::chrono::steady_clock::now();
277 std::chrono::duration<Real> diff = end - start;
292 UInt numCompsRequireIter;
295 numCompsRequireIter = 0;
297 if (syncGen->requiresIteration())
298 numCompsRequireIter++;
301 if (numCompsRequireIter > 0) {
311 syncGen->correctorStep();
318 auto start = std::chrono::steady_clock::now();
322 auto end = std::chrono::steady_clock::now();
323 std::chrono::duration<Real> diff = end - start;
332 }
while (numCompsRequireIter > 0);
338 for (UInt nodeIdx = 0; nodeIdx <
mNumNetNodes; ++nodeIdx)
344template <
typename VarType>
360 for (UInt i = 0; i < mSwitchedMatrices[std::bitset<SWITCH_NUM>(0)].size();
362 SPDLOG_LOGGER_INFO(
mSLog,
"System matrix for frequency: {:d} \n{:s}", i,
363 Logger::matrixToString(
368 SPDLOG_LOGGER_INFO(
mSLog,
"Right side vector for frequency: {:d} \n{:s}",
373 SPDLOG_LOGGER_INFO(
mSLog,
"Summarizing matrices: ");
374 SPDLOG_LOGGER_INFO(
mSLog,
"Base matrix with only static elements: {}",
376 SPDLOG_LOGGER_INFO(
mSLog,
"Initial system matrix with variable elements {}",
378 SPDLOG_LOGGER_INFO(
mSLog,
"Right side vector: {}",
382 SPDLOG_LOGGER_INFO(
mSLog,
"System matrix: \n{}",
385 SPDLOG_LOGGER_INFO(
mSLog,
"Initial switch status: {:s}",
389 SPDLOG_LOGGER_INFO(
mSLog,
"Switching System matrix {:s} \n{:s}",
390 sys.first.to_string(),
391 Logger::matrixToString(sys.second[0]));
412 SPDLOG_LOGGER_INFO(
mSLog,
"Cumulative solve times: {:.12f}", solveSum);
413 SPDLOG_LOGGER_INFO(
mSLog,
"Average solve time: {:.12f}",
414 solveSum /
static_cast<double>(
mSolveTimes.size()));
415 SPDLOG_LOGGER_INFO(
mSLog,
"Maximum solve time: {:.12f}", solveMax);
419template <
typename VarType>
422 SPDLOG_LOGGER_INFO(
mSLog,
"LU factorization time: {:.12f}", meas);
426template <
typename VarType>
428 Real recompSum = 0.0;
429 Real recompMax = 0.0;
432 if (meas > recompMax)
437 SPDLOG_LOGGER_INFO(
mSLog,
"Cumulative refactorization times: {:.12f}",
439 SPDLOG_LOGGER_INFO(
mSLog,
"Average refactorization time: {:.12f}",
441 SPDLOG_LOGGER_INFO(
mSLog,
"Maximum refactorization time: {:.12f}",
443 SPDLOG_LOGGER_INFO(
mSLog,
"Number of refactorizations: {:d}",
448template <
typename VarType>
449std::shared_ptr<DirectLinearSolver>
451 CPS::Logger::Log
mSLog) {
453 case DirectLinearSolverImpl::DenseLU:
454 return std::make_shared<DenseLUAdapter>(
mSLog);
456 case DirectLinearSolverImpl::SparseLU:
457 return std::make_shared<SparseLUAdapter>(
mSLog);
460 case DirectLinearSolverImpl::KLU:
461 return std::make_shared<KLUAdapter>(
mSLog);
464 case DirectLinearSolverImpl::CUDADense:
465 return std::make_shared<GpuDenseAdapter>(
mSLog);
466#ifdef WITH_CUDA_SPARSE
467 case DirectLinearSolverImpl::CUDASparse:
468 return std::make_shared<GpuSparseAdapter>(
mSLog);
471 case DirectLinearSolverImpl::CUDAMagma:
472 return std::make_shared<GpuMagmaAdapter>(
mSLog);
480template <
typename VarType>
482 DirectLinearSolverImpl implementation) {
486template <
typename VarType>
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.
void logFactorizationTime()
Logging of the LU factorization time.
void extractStateSpace(Real time)
Runs state-space extraction using the active linear solver.
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.
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.
Bool mSystemMatrixChanged
Tracks active MNA system-matrix changes from the last solve step.
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.
Bool mVariableComponentChanged
Tracks variable-component changes from the last solve step.
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::shared_ptr< CPS::Task > createStateSpaceExtractionTask() override
Create state-space extraction task for this solver implementation.
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::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.
std::bitset< SWITCH_NUM > mCurrentSwitchStatus
Current status of all switches encoded as bitset.
std::vector< Matrix > mRightSideVectorHarm
Source vector of known quantities.
Matrix mRightSideVector
Source vector of known quantities.
CPS::SystemTopology mSystem
System topology.
std::vector< Real > mRecomputationTimes
LU refactorization measurements.
std::vector< Real > mFactorizeTimes
LU factorization measurements.
std::vector< CPS::Attribute< Matrix >::Ptr > mLeftSideVectorHarm
Solution vector of unknown quantities (parallel frequencies)
Bool hasVariableComponentChanged()
Checks whether the status of variable MNA elements have changed.
CPS::MNAInterface::List mMNAIntfVariableComps
List of variable components if they must be accessed as MNAInterface objects.
UInt mNumNetNodes
Number of network nodes, single line equivalent.
MNAStateSpaceExtractor::Ptr mStateSpaceExtractor
Extractor for the MNA-coupled state-space model.
UInt mNumTotalMatrixNodeIndices
Total number of network and virtual nodes, considering individual phases and additional frequencies.
CPS::MNASyncGenInterface::List mSyncGen
List of synchronous generators that need iterate to solve the differential equations.
std::vector< const Matrix * > mRightVectorStamps
List of all right side vector contributions.
void updateSwitchStatus()
Collects the status of switches to select correct system matrix.
std::vector< Real > mSolveTimes
Right-hand side solution measurements.
std::vector< std::pair< UInt, UInt > > mListVariableSystemMatrixEntries
List of index pairs of varying matrix entries.
CPS::MNAVariableCompInterface::List mVariableComps
Int mNumRecomputations
Number of system matrix recomputations.
CPS::MNAInterface::List mMNAComponents
List of MNA components with static stamp into system matrix.
UInt mNumMatrixNodeIndices
Number of network and virtual nodes, considering individual phases.
MnaSolver(String name, CPS::Domain domain=CPS::Domain::DP, CPS::Logger::Level logLevel=CPS::Logger::Level::info)
Constructor should not be called by users but by Simulation.
CPS::Attribute< Matrix >::Ptr mLeftSideVector
Solution vector of unknown quantities.
CPS::MNASwitchInterface::List mSwitches
CPS::SimNode< VarType >::List mNodes
List of simulation nodes.
Bool mSystemMatrixRecomputation
Enable recomputation of system matrix during simulation.
CPS::Logger::Log mSLog
Logger.
Bool mIsInInitialization
Determines if solver is in initialization phase, which requires different behavior.
Bool mLogSolveTimes
Collect step time for logging.
Bool mFrequencyParallel
Activates parallelized computation of frequencies.