DPsim
EMT_Ph3_SSN_Inductor.cpp
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 #include <dpsim-models/EMT/EMT_Ph3_SSN_Inductor.h>
10 
11 using namespace CPS;
12 
13 EMT::Ph3::SSN::Inductor::Inductor(String uid, String name,
14  Logger::Level logLevel)
15  : MNASimPowerComp<Real>(uid, name, true, true, logLevel),
16  Base::Ph3::Inductor(mAttributes) {
17  mPhaseType = PhaseType::ABC;
18  setTerminalNumber(2);
19  **mIntfVoltage = Matrix::Zero(3, 1);
20  **mIntfCurrent = Matrix::Zero(3, 1);
21  mHistoricCurrent = Matrix::Zero(3, 1);
22 }
23 
25  auto copy = Inductor::make(name, mLogLevel);
26  copy->setParameters(**mInductance);
27  return copy;
28 }
29 
31 
32  Real omega = 2 * PI * frequency;
33  MatrixComp impedance = MatrixComp::Zero(3, 3);
34  impedance << Complex(0, omega * (**mInductance)(0, 0)),
35  Complex(0, omega * (**mInductance)(0, 1)),
36  Complex(0, omega * (**mInductance)(0, 2)),
37  Complex(0, omega * (**mInductance)(1, 0)),
38  Complex(0, omega * (**mInductance)(1, 1)),
39  Complex(0, omega * (**mInductance)(1, 2)),
40  Complex(0, omega * (**mInductance)(2, 0)),
41  Complex(0, omega * (**mInductance)(2, 1)),
42  Complex(0, omega * (**mInductance)(2, 2));
43 
44  MatrixComp vInitABC = Matrix::Zero(3, 1);
45  vInitABC(0, 0) = RMS3PH_TO_PEAK1PH * initialSingleVoltage(1) -
46  RMS3PH_TO_PEAK1PH * initialSingleVoltage(0);
47  vInitABC(1, 0) = vInitABC(0, 0) * SHIFT_TO_PHASE_B;
48  vInitABC(2, 0) = vInitABC(0, 0) * SHIFT_TO_PHASE_C;
49  **mIntfVoltage = vInitABC.real();
50  MatrixComp admittance = impedance.inverse();
51  **mIntfCurrent = (admittance * vInitABC).real();
52 
53  SPDLOG_LOGGER_INFO(mSLog,
54  "\nInductance [H]: {:s}"
55  "\nImpedance [Ohm]: {:s}",
56  Logger::matrixToString(**mInductance),
57  Logger::matrixCompToString(impedance));
58  SPDLOG_LOGGER_INFO(
59  mSLog,
60  "\n--- Initialization from powerflow ---"
61  "\nVoltage across: {:s}"
62  "\nCurrent: {:s}"
63  "\nTerminal 0 voltage: {:s}"
64  "\nTerminal 1 voltage: {:s}"
65  "\n--- Initialization from powerflow finished ---",
66  Logger::matrixToString(**mIntfVoltage),
67  Logger::matrixToString(**mIntfCurrent),
68  Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(0)),
69  Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(1)));
70 }
71 
73  Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) {
74 
75  updateMatrixNodeIndices();
76  //update history term
77  mDufourBKHat = (timeStep / 2. * (**mInductance).inverse());
78  mDufourWKN = mDufourBKHat;
79  mHistoricCurrent = mDufourBKHat * **mIntfVoltage + **mIntfCurrent;
80 
81  **mRightVector = Matrix::Zero(leftVector->get().rows(), 1);
82 
83  SPDLOG_LOGGER_INFO(mSLog,
84  "\n--- MNA initialization ---"
85  "\nInitial voltage {:s}"
86  "\nInitial current {:s}"
87  "\nhistoric current {:s}"
88  "\n--- MNA initialization finished ---",
89  Logger::matrixToString(**mIntfVoltage),
90  Logger::matrixToString(**mIntfCurrent),
91  Logger::matrixToString(mHistoricCurrent));
92  mSLog->flush();
93 }
94 
96  SparseMatrixRow &systemMatrix) {
97 
98  MNAStampUtils::stampConductanceMatrix(
99  mDufourWKN, systemMatrix, matrixNodeIndex(0), matrixNodeIndex(1),
100  terminalNotGrounded(0), terminalNotGrounded(1), mSLog);
101 
102  SPDLOG_LOGGER_INFO(mSLog, "\nConductance matrix: {:s}",
103  Logger::matrixToString(mDufourWKN));
104 }
105 
107  Matrix &rightVector) {
108  // Update internal state
109  mHistoricCurrent = mDufourBKHat * **mIntfVoltage + **mIntfCurrent;
110  if (terminalNotGrounded(0)) {
111  Math::setVectorElement(rightVector, matrixNodeIndex(0, 0),
112  mHistoricCurrent(0, 0));
113  Math::setVectorElement(rightVector, matrixNodeIndex(0, 1),
114  mHistoricCurrent(1, 0));
115  Math::setVectorElement(rightVector, matrixNodeIndex(0, 2),
116  mHistoricCurrent(2, 0));
117  }
118  if (terminalNotGrounded(1)) {
119  Math::setVectorElement(rightVector, matrixNodeIndex(1, 0),
120  -mHistoricCurrent(0, 0));
121  Math::setVectorElement(rightVector, matrixNodeIndex(1, 1),
122  -mHistoricCurrent(1, 0));
123  Math::setVectorElement(rightVector, matrixNodeIndex(1, 2),
124  -mHistoricCurrent(2, 0));
125  }
126  SPDLOG_LOGGER_DEBUG(
127  mSLog, "\nHistory current term (mnaCompApplyRightSideVectorStamp): {:s}",
128  Logger::matrixToString(mHistoricCurrent));
129  mSLog->flush();
130 }
131 
133  AttributeBase::List &prevStepDependencies,
134  AttributeBase::List &attributeDependencies,
135  AttributeBase::List &modifiedAttributes) {
136  // actually depends on L, but then we'd have to modify the system matrix anyway
137  prevStepDependencies.push_back(mIntfVoltage);
138  prevStepDependencies.push_back(mIntfCurrent);
139  modifiedAttributes.push_back(mRightVector);
140 }
141 
142 void EMT::Ph3::SSN::Inductor::mnaCompPreStep(Real time, Int timeStepCount) {
143  mnaCompApplyRightSideVectorStamp(**mRightVector);
144 }
145 
147  AttributeBase::List &prevStepDependencies,
148  AttributeBase::List &attributeDependencies,
149  AttributeBase::List &modifiedAttributes,
150  Attribute<Matrix>::Ptr &leftVector) {
151  attributeDependencies.push_back(leftVector);
152  modifiedAttributes.push_back(mIntfVoltage);
153  modifiedAttributes.push_back(mIntfCurrent);
154 }
155 
157  Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
158  mnaCompUpdateVoltage(**leftVector);
159  mnaCompUpdateCurrent(**leftVector);
160 }
161 
162 void EMT::Ph3::SSN::Inductor::mnaCompUpdateVoltage(const Matrix &leftVector) {
163  // v1 - v0
164  **mIntfVoltage = Matrix::Zero(3, 1);
165  if (terminalNotGrounded(1)) {
166  (**mIntfVoltage)(0, 0) =
167  Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 0));
168  (**mIntfVoltage)(1, 0) =
169  Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 1));
170  (**mIntfVoltage)(2, 0) =
171  Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 2));
172  }
173  if (terminalNotGrounded(0)) {
174  (**mIntfVoltage)(0, 0) =
175  (**mIntfVoltage)(0, 0) -
176  Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 0));
177  (**mIntfVoltage)(1, 0) =
178  (**mIntfVoltage)(1, 0) -
179  Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 1));
180  (**mIntfVoltage)(2, 0) =
181  (**mIntfVoltage)(2, 0) -
182  Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 2));
183  }
184  SPDLOG_LOGGER_DEBUG(mSLog, "\nUpdate Voltage: {:s}",
185  Logger::matrixToString(**mIntfVoltage));
186 }
187 
188 void EMT::Ph3::SSN::Inductor::mnaCompUpdateCurrent(const Matrix &leftVector) {
189  **mIntfCurrent = mHistoricCurrent + mDufourWKN * **mIntfVoltage;
190  SPDLOG_LOGGER_DEBUG(mSLog, "\nUpdate Current: {:s}",
191  Logger::matrixToString(**mIntfCurrent));
192  mSLog->flush();
193 }
virtual T & get()=0
void mnaCompUpdateCurrent(const Matrix &leftVector) override
Update interface current from MNA system result.
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override
Stamps right side (source) vector.
void mnaCompUpdateVoltage(const Matrix &leftVector) override
Update interface voltage from MNA system result.
void initializeFromNodesAndTerminals(Real frequency) override
Initializes component from power flow data.
void mnaCompAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
Add MNA pre step dependencies.
SimPowerComp< Real >::Ptr clone(String name) override
Returns a modified copy of the component with the given suffix added to the name and without.
void mnaCompInitialize(Real omega, Real timeStep, Attribute< Matrix >::Ptr leftVector) override
Initializes internal variables of the component.
void mnaCompPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
MNA post step operations.
void mnaCompPreStep(Real time, Int timeStepCount) override
MNA pre step operations.
Inductor(String uid, String name, Logger::Level logLevel=Logger::Level::off)
Defines UID, name, component parameters and logging level.
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) override
Stamps system matrix.
void mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
Add MNA post step dependencies.
Base class for all MNA components that are transmitting power.
Base class for all components that are transmitting power.
Definition: SimPowerComp.h:17
const Attribute< MatrixVar< Real > >::Ptr mIntfCurrent
Current through component.
Definition: SimPowerComp.h:47
const Attribute< MatrixVar< Real > >::Ptr mIntfVoltage
Voltage between terminals.
Definition: SimPowerComp.h:45