DPsim
EMT_Ph3_SSN_Capacitor.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_Capacitor.h>
10 
11 using namespace CPS;
12 
13 EMT::Ph3::SSN::Capacitor::Capacitor(String uid, String name,
14  Logger::Level logLevel)
15  : MNASimPowerComp<Real>(uid, name, true, true, logLevel),
16  Base::Ph3::Capacitor(mAttributes) {
17  mPhaseType = PhaseType::ABC;
18  setVirtualNodeNumber(1);
19  setTerminalNumber(2);
20  mHistoricVoltage = Matrix::Zero(3, 1);
21  **mIntfVoltage = Matrix::Zero(3, 1);
22  **mIntfCurrent = Matrix::Zero(3, 1);
23 }
24 
26  auto copy = Capacitor::make(name, mLogLevel);
27  copy->setParameters(**mCapacitance);
28  return copy;
29 }
31 
32  Real omega = 2 * PI * frequency;
33  MatrixComp admittance = MatrixComp::Zero(3, 3);
34  admittance << Complex(0, omega * (**mCapacitance)(0, 0)),
35  Complex(0, omega * (**mCapacitance)(0, 1)),
36  Complex(0, omega * (**mCapacitance)(0, 2)),
37  Complex(0, omega * (**mCapacitance)(1, 0)),
38  Complex(0, omega * (**mCapacitance)(1, 1)),
39  Complex(0, omega * (**mCapacitance)(1, 2)),
40  Complex(0, omega * (**mCapacitance)(2, 0)),
41  Complex(0, omega * (**mCapacitance)(2, 1)),
42  Complex(0, omega * (**mCapacitance)(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  **mIntfCurrent = (admittance * vInitABC).real();
51 
52  SPDLOG_LOGGER_INFO(mSLog,
53  "\nCapacitance [F]: {:s}"
54  "\nAdmittance [S]: {:s}",
55  Logger::matrixToString(**mCapacitance),
56  Logger::matrixCompToString(admittance));
57  SPDLOG_LOGGER_INFO(
58  mSLog,
59  "\n--- Initialization from powerflow ---"
60  "\nVoltage across: {:s}"
61  "\nCurrent: {:s}"
62  "\nTerminal 0 voltage: {:s}"
63  "\nTerminal 1 voltage: {:s}"
64  "\n--- Initialization from powerflow finished ---",
65  Logger::matrixToString(**mIntfVoltage),
66  Logger::matrixToString(**mIntfCurrent),
67  Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(0)),
68  Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(1)));
69 }
70 
72  Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) {
73  updateMatrixNodeIndices();
74 
75  mHistoricVoltage = mDufourBKHat * **mIntfCurrent + **mIntfVoltage;
76  mDufourBKHat = timeStep * (2.0 * **mCapacitance).inverse();
77  mDufourWKN = mDufourBKHat;
78 
79  **mRightVector = Matrix::Zero(leftVector->get().rows(), 1);
80 }
81 
83  SparseMatrixRow &systemMatrix) {
84  if (terminalNotGrounded(0)) {
85  Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0),
86  mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
87  -1);
88  Math::addToMatrixElement(systemMatrix,
89  mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
90  matrixNodeIndex(0, 0), -1);
91 
92  Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1),
93  mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
94  -1);
95  Math::addToMatrixElement(systemMatrix,
96  mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
97  matrixNodeIndex(0, 1), -1);
98 
99  Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2),
100  mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
101  -1);
102  Math::addToMatrixElement(systemMatrix,
103  mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
104  matrixNodeIndex(0, 2), -1);
105  }
106  if (terminalNotGrounded(1)) {
107  Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 0),
108  mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
109  1);
110  Math::addToMatrixElement(systemMatrix,
111  mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
112  matrixNodeIndex(1, 0), 1);
113 
114  Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 1),
115  mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
116  1);
117  Math::addToMatrixElement(systemMatrix,
118  mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
119  matrixNodeIndex(1, 1), 1);
120 
121  Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 2),
122  mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
123  1);
124  Math::addToMatrixElement(systemMatrix,
125  mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
126  matrixNodeIndex(1, 2), 1);
127  }
128  //mesh equations are independent from grounded terminals
129  Math::addToMatrixElement(
130  systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
131  mVirtualNodes[0]->matrixNodeIndex(PhaseType::A), -mDufourWKN(0, 0));
132  Math::addToMatrixElement(
133  systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
134  mVirtualNodes[0]->matrixNodeIndex(PhaseType::B), -mDufourWKN(0, 1));
135  Math::addToMatrixElement(
136  systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
137  mVirtualNodes[0]->matrixNodeIndex(PhaseType::C), -mDufourWKN(0, 2));
138 
139  Math::addToMatrixElement(
140  systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
141  mVirtualNodes[0]->matrixNodeIndex(PhaseType::A), -mDufourWKN(1, 0));
142  Math::addToMatrixElement(
143  systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
144  mVirtualNodes[0]->matrixNodeIndex(PhaseType::B), -mDufourWKN(1, 1));
145  Math::addToMatrixElement(
146  systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
147  mVirtualNodes[0]->matrixNodeIndex(PhaseType::C), -mDufourWKN(1, 2));
148 
149  Math::addToMatrixElement(
150  systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
151  mVirtualNodes[0]->matrixNodeIndex(PhaseType::A), -mDufourWKN(2, 0));
152  Math::addToMatrixElement(
153  systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
154  mVirtualNodes[0]->matrixNodeIndex(PhaseType::B), -mDufourWKN(2, 1));
155  Math::addToMatrixElement(
156  systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
157  mVirtualNodes[0]->matrixNodeIndex(PhaseType::C), -mDufourWKN(2, 2));
158 }
159 
161  Matrix &rightVector) {
162  mHistoricVoltage = mDufourBKHat * **mIntfCurrent + **mIntfVoltage;
163  Math::setVectorElement(rightVector,
164  mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
165  mHistoricVoltage(0, 0));
166  Math::setVectorElement(rightVector,
167  mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
168  mHistoricVoltage(1, 0));
169  Math::setVectorElement(rightVector,
170  mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
171  mHistoricVoltage(2, 0));
172 }
173 
175  AttributeBase::List &prevStepDependencies,
176  AttributeBase::List &attributeDependencies,
177  AttributeBase::List &modifiedAttributes) {
178  // actually depends on C, but then we'd have to modify the system matrix anyway
179  prevStepDependencies.push_back(mIntfCurrent);
180  prevStepDependencies.push_back(mIntfVoltage);
181  modifiedAttributes.push_back(mRightVector);
182 }
183 
184 void EMT::Ph3::SSN::Capacitor::mnaCompPreStep(Real time, Int timeStepCount) {
185  mnaCompApplyRightSideVectorStamp(**mRightVector);
186 }
187 
189  AttributeBase::List &prevStepDependencies,
190  AttributeBase::List &attributeDependencies,
191  AttributeBase::List &modifiedAttributes,
192  Attribute<Matrix>::Ptr &leftVector) {
193  attributeDependencies.push_back(leftVector);
194  modifiedAttributes.push_back(mIntfVoltage);
195  modifiedAttributes.push_back(mIntfCurrent);
196 }
197 
199  Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
200  mnaCompUpdateVoltage(**leftVector);
201  mnaCompUpdateCurrent(**leftVector);
202 }
203 
204 void EMT::Ph3::SSN::Capacitor::mnaCompUpdateVoltage(const Matrix &leftVector) {
205  // v1 - v0
206  **mIntfVoltage = Matrix::Zero(3, 1);
207  if (terminalNotGrounded(1)) {
208  (**mIntfVoltage)(0, 0) =
209  Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 0));
210  (**mIntfVoltage)(1, 0) =
211  Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 1));
212  (**mIntfVoltage)(2, 0) =
213  Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 2));
214  }
215  if (terminalNotGrounded(0)) {
216  (**mIntfVoltage)(0, 0) =
217  (**mIntfVoltage)(0, 0) -
218  Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 0));
219  (**mIntfVoltage)(1, 0) =
220  (**mIntfVoltage)(1, 0) -
221  Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 1));
222  (**mIntfVoltage)(2, 0) =
223  (**mIntfVoltage)(2, 0) -
224  Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 2));
225  }
226 }
227 
228 void EMT::Ph3::SSN::Capacitor::mnaCompUpdateCurrent(const Matrix &leftVector) {
229  (**mIntfCurrent)(0, 0) = Math::realFromVectorElement(
230  leftVector, mVirtualNodes[0]->matrixNodeIndex(PhaseType::A));
231  (**mIntfCurrent)(1, 0) = Math::realFromVectorElement(
232  leftVector, mVirtualNodes[0]->matrixNodeIndex(PhaseType::B));
233  (**mIntfCurrent)(2, 0) = Math::realFromVectorElement(
234  leftVector, mVirtualNodes[0]->matrixNodeIndex(PhaseType::C));
235 
236  SPDLOG_LOGGER_DEBUG(mSLog, "\nCurrent: {:s}",
237  Logger::matrixToString(**mIntfCurrent));
238 }
virtual T & get()=0
void mnaCompInitialize(Real omega, Real timeStep, Attribute< Matrix >::Ptr leftVector) override
Initializes internal variables of the component.
void mnaCompUpdateVoltage(const Matrix &leftVector) override
Update interface voltage from MNA system result.
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 mnaCompPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
MNA post step operations.
void mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
Add MNA post step dependencies.
Capacitor(String uid, String name, Logger::Level logLevel=Logger::Level::off)
Defines UID, name and logging level.
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override
Stamps right side (source) vector.
void initializeFromNodesAndTerminals(Real frequency) override
Initializes component from power flow data.
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) override
Stamps system matrix.
void mnaCompAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
Add MNA pre step dependencies.
void mnaCompPreStep(Real time, Int timeStepCount) override
MNA pre step operations.
void mnaCompUpdateCurrent(const Matrix &leftVector) override
Update interface current from MNA system result.
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