4#include <dpsim-models/DP/DP_SSNComp.h>
5#include <dpsim-models/MathUtils.h>
9DP::SSNComp::SSNComp(String uid, String name, Int inputSize, Int outputSize,
10 Logger::Level logLevel)
11 :
MNASimPowerComp<Complex>(uid, name, true, true, logLevel), mTimeStep(0.0),
12 mW(MatrixComp::Zero(outputSize, inputSize)),
13 mYHist(MatrixComp::Zero(outputSize, 1)), mInputSize(inputSize),
14 mOutputSize(outputSize), mX(mAttributes->create<MatrixComp>(
"x")) {
15 mParametersSet =
false;
26void DP::SSNComp::setParameters(
const Matrix &A,
const Matrix &B,
27 const Matrix &C,
const Matrix &D) {
28 mParametersSet =
false;
30 if (A.rows() != A.cols())
31 throw std::invalid_argument(
"A must be square.");
33 if (B.rows() != A.rows() || B.cols() != mInputSize)
34 throw std::invalid_argument(
"B has invalid dimensions.");
36 if (C.rows() != mOutputSize || C.cols() != A.rows())
37 throw std::invalid_argument(
"C has invalid dimensions.");
39 if (D.rows() != mOutputSize || D.cols() != mInputSize)
40 throw std::invalid_argument(
"D has invalid dimensions.");
47 **mX = MatrixComp::Zero(mA.rows(), 1);
49 mDiscreteA = MatrixComp::Zero(mA.rows(), mA.cols());
50 mDiscreteB = MatrixComp::Zero(mB.rows(), mB.cols());
52 mW = MatrixComp::Zero(mOutputSize, mInputSize);
53 mYHist = MatrixComp::Zero(mOutputSize, 1);
55 mParametersSet =
true;
59 const Matrix::Index n =
mA.rows();
60 const Matrix wI = omega * Matrix::Identity(n, n);
62 Matrix aAug = Matrix::Zero(2 * n, 2 * n);
63 aAug.topLeftCorner(n, n) =
mA;
64 aAug.topRightCorner(n, n) = wI;
65 aAug.bottomLeftCorner(n, n) = -wI;
66 aAug.bottomRightCorner(n, n) =
mA;
71 const Matrix::Index n =
mA.rows();
73 Matrix bAug = Matrix::Zero(2 * n, 2 * mInputSize);
74 bAug.topLeftCorner(n, mInputSize) = mB;
75 bAug.bottomRightCorner(n, mInputSize) = mB;
80 const Matrix::Index n =
mA.rows();
85 Matrix dAaug = Matrix::Zero(2 * n, 2 * n);
86 Matrix dBaug = Matrix::Zero(2 * n, 2 * mInputSize);
91 mDiscreteA = dAaug.topLeftCorner(n, n).cast<Complex>() +
92 Complex(0., 1.) * dAaug.bottomLeftCorner(n, n).cast<Complex>();
94 dBaug.block(0, 0, n, mInputSize).cast<Complex>() +
95 Complex(0., 1.) * dBaug.block(n, 0, n, mInputSize).cast<Complex>();
97 mW = mC.cast<Complex>() * mDiscreteB + mD.cast<Complex>();
100MatrixComp DP::SSNComp::calculateHistoryVector()
const {
101 return mC.cast<Complex>() *
102 (mDiscreteA * (**mX) + mDiscreteB * (**inputAttribute()));
108 Complex(0., omega) * MatrixComp::Identity(
mA.rows(),
mA.cols()) -
111 return h.inverse() * mB.cast<Complex>() * u;
115DP::SSNComp::calculateSteadyStateOutputFromInput(
const MatrixComp &x,
116 const MatrixComp &u)
const {
117 return mC.cast<Complex>() * x + mD.cast<Complex>() * u;
120void DP::SSNComp::updateState(
const MatrixComp &uOld,
const MatrixComp &uNew) {
121 **mX = mDiscreteA * (**mX) + mDiscreteB * (uNew + uOld);
128void DP::SSNComp::mnaCompInitialize(Real omega, Real timeStep,
129 Attribute<Matrix>::Ptr) {
131 throw std::logic_error(
132 "setParameters() must be called before initialization.");
135 throw std::logic_error(
136 "DP SSN components currently support a single carrier frequency.");
138 mTimeStep = timeStep;
139 updateMatrixNodeIndices();
141 recomputeDiscreteModel(omega);
142 mYHist = calculateHistoryVector();
145void DP::SSNComp::mnaCompAddPreStepDependencies(
146 AttributeBase::List &prevStepDependencies,
147 AttributeBase::List &attributeDependencies,
148 AttributeBase::List &modifiedAttributes) {
149 modifiedAttributes.push_back(mRightVector);
150 prevStepDependencies.push_back(mX);
151 prevStepDependencies.push_back(inputAttribute());
154void DP::SSNComp::mnaCompPreStep(Real time, Int timeStepCount) {
155 updateStateSpaceModel();
156 mYHist = calculateHistoryVector();
157 mnaCompApplyRightSideVectorStamp(**mRightVector);
160void DP::SSNComp::mnaCompAddPostStepDependencies(
161 AttributeBase::List &prevStepDependencies,
162 AttributeBase::List &attributeDependencies,
163 AttributeBase::List &modifiedAttributes,
164 Attribute<Matrix>::Ptr &leftVector) {
165 attributeDependencies.push_back(leftVector);
166 modifiedAttributes.push_back(inputAttribute());
167 modifiedAttributes.push_back(outputAttribute());
168 modifiedAttributes.push_back(mX);
virtual void updateStateSpaceModel()
Hook for variable/time-varying SSN components.
Matrix mA
Continuous-time real physical model (user-provided).
const MatrixComp & getDiscreteA() const
Get the complex discrete state-transition operator of the envelope model.
UInt getStateCount() const
Get number of internal state variables of the SSN model.
Matrix buildAugmentedA(Real omega) const
Build A_aug = [[A, w I], [-w I, A]].
virtual MatrixComp calculateSteadyStateStateFromInput(const MatrixComp &u, Real omega) const
Steady-state envelope state X_ss = (j w I - A)^-1 B u.
virtual void recomputeDiscreteModel(Real omega)
Discretize the augmented model and fold it into complex dA, dB, W.
MatrixComp mW
Complex Norton matrix W = C dB + D.
const Matrix & getC() const
Get the continuous-time output matrix of the SSN model.
MatrixComp mDiscreteA
Complex envelope discrete operators (folded from the augmented model).
Matrix buildAugmentedB() const
Build B_aug = blkdiag(B, B).
const MatrixComp & getDiscreteB() const
Get the complex discrete input operator of the envelope model.
Base class for all MNA components that are transmitting power.
static void calculateStateSpaceTrapezoidalMatrices(const Matrix &A, const Matrix &B, const Matrix &C, const Real &dt, Matrix &Ad, Matrix &Bd, Matrix &Cd)
Calculate the discretized state space matrices Ad, Bd, Cd using trapezoidal rule.