4#include <dpsim/DirectLinearSolver.h>
5#include <dpsim/MNAStateSpaceExtractor.h>
11void MNAStateSpaceExtractor::initialize(
12 const CPS::MNAInterface::List &components, UInt mnaVectorSize,
17 throw std::invalid_argument(
18 "MNAStateSpaceExtractor requires a positive time step.");
20 mMnaVectorSize = mnaVectorSize;
23 const auto contributors =
24 MNAStateSpaceContributorFactory::createList(components);
26 UInt nextStateOffset = 0;
28 for (
const auto &contributor : contributors) {
29 const UInt localStateCount = contributor->getStateCount();
31 ContributorEntry entry;
32 entry.contributor = contributor;
33 entry.stateOffset = nextStateOffset;
34 mContributorEntries.push_back(entry);
36 nextStateOffset += localStateCount;
38 if (contributor->isVariable())
39 mHasVariableContributors =
true;
42 mStateCount = nextStateOffset;
46 stampStaticMatrices();
47 restampVariableMatrices();
48 rebuildCombinedMatrices();
50 mStateMatrixValid =
false;
54void MNAStateSpaceExtractor::reset() {
61 mHasVariableContributors =
false;
62 mStateMatrixValid =
false;
64 mContributorEntries.clear();
66 mAdLocalStatic.resize(0, 0);
67 mBdMnaStatic.resize(0, 0);
68 mCdMnaStatic.resize(0, 0);
70 mAdLocalVariable.resize(0, 0);
71 mBdMnaVariable.resize(0, 0);
72 mCdMnaVariable.resize(0, 0);
74 mAdLocal.resize(0, 0);
82 Bool variableModelChanged,
83 Bool systemMatrixChanged) {
85 throw std::logic_error(
86 "MNAStateSpaceExtractor::extract() called before initialize().");
88 if (mStateCount == 0) {
89 mStateMatrixValid =
true;
93 if (variableModelChanged && mHasVariableContributors) {
94 restampVariableMatrices();
95 rebuildCombinedMatrices();
96 mStateMatrixValid =
false;
99 if (systemMatrixChanged)
100 mStateMatrixValid =
false;
102 if (!mStateMatrixValid)
103 computeStateMatrix(linearSolver);
106void MNAStateSpaceExtractor::allocateMatrices() {
107 mAdLocalStatic = Matrix::Zero(mStateCount, mStateCount);
108 mBdMnaStatic = Matrix::Zero(mStateCount, mMnaVectorSize);
109 mCdMnaStatic = Matrix::Zero(mMnaVectorSize, mStateCount);
111 mAdLocalVariable = Matrix::Zero(mStateCount, mStateCount);
112 mBdMnaVariable = Matrix::Zero(mStateCount, mMnaVectorSize);
113 mCdMnaVariable = Matrix::Zero(mMnaVectorSize, mStateCount);
115 mAdLocal = Matrix::Zero(mStateCount, mStateCount);
116 mBdMna = Matrix::Zero(mStateCount, mMnaVectorSize);
117 mCdMna = Matrix::Zero(mMnaVectorSize, mStateCount);
119 mAd = Matrix::Zero(mStateCount, mStateCount);
122void MNAStateSpaceExtractor::stampStaticMatrices() {
123 mAdLocalStatic.setZero();
124 mBdMnaStatic.setZero();
125 mCdMnaStatic.setZero();
127 for (
const auto &entry : mContributorEntries) {
128 if (!entry.contributor->isVariable()) {
129 entry.contributor->stamp(mAdLocalStatic, mBdMnaStatic, mCdMnaStatic,
130 entry.stateOffset, mMnaVectorSize);
135void MNAStateSpaceExtractor::restampVariableMatrices() {
136 mAdLocalVariable.setZero();
137 mBdMnaVariable.setZero();
138 mCdMnaVariable.setZero();
140 for (
const auto &entry : mContributorEntries) {
141 if (entry.contributor->isVariable()) {
142 entry.contributor->stamp(mAdLocalVariable, mBdMnaVariable, mCdMnaVariable,
143 entry.stateOffset, mMnaVectorSize);
148void MNAStateSpaceExtractor::rebuildCombinedMatrices() {
149 mAdLocal = mAdLocalStatic + mAdLocalVariable;
150 mBdMna = mBdMnaStatic + mBdMnaVariable;
151 mCdMna = mCdMnaStatic + mCdMnaVariable;
154void MNAStateSpaceExtractor::computeStateMatrix(
158 const Matrix mnaToStateSolution = linearSolver.solve(rhs);
160 if (mnaToStateSolution.rows() != mMnaVectorSize ||
161 mnaToStateSolution.cols() != mStateCount) {
162 throw std::runtime_error(
163 "MNAStateSpaceExtractor: linear solver returned unexpected "
167 mAd = mAdLocal + mBdMna * mnaToStateSolution;
169 mStateMatrixValid =
true;