DPsim
DP_Ph1_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/DP/DP_Ph1_Capacitor.h>
10 
11 using namespace CPS;
12 using namespace CPS::DP::Ph1;
13 
14 DP::Ph1::Capacitor::Capacitor(String uid, String name, Logger::Level logLevel)
15  : MNASimPowerComp<Complex>(uid, name, true, true, logLevel),
16  Base::Ph1::Capacitor(mAttributes) {
17  mEquivCurrent = {0, 0};
18  **mIntfVoltage = MatrixComp::Zero(1, 1);
19  **mIntfCurrent = MatrixComp::Zero(1, 1);
20  setTerminalNumber(2);
21 }
22 
24  auto copy = Capacitor::make(name, mLogLevel);
25  copy->setParameters(**mCapacitance);
26  return copy;
27 }
28 
29 void DP::Ph1::Capacitor::initialize(Matrix frequencies) {
31 
32  mEquivCurrent = MatrixComp::Zero(mNumFreqs, 1);
33  mEquivCond = MatrixComp::Zero(mNumFreqs, 1);
34  mPrevVoltCoeff = MatrixComp::Zero(mNumFreqs, 1);
35 }
36 
38 
39  Real omega = 2 * PI * frequency;
40  Complex impedance = {0, -1. / (omega * **mCapacitance)};
41  (**mIntfVoltage)(0, 0) = initialSingleVoltage(1) - initialSingleVoltage(0);
42  (**mIntfCurrent)(0, 0) = (**mIntfVoltage)(0, 0) / impedance;
43 
44  SPDLOG_LOGGER_INFO(mSLog,
45  "\nCapacitance [F]: {:s}"
46  "\nImpedance [Ohm]: {:s}",
47  Logger::realToString(**mCapacitance),
48  Logger::complexToString(impedance));
49  SPDLOG_LOGGER_INFO(mSLog,
50  "\n--- Initialization from powerflow ---"
51  "\nVoltage across: {:s}"
52  "\nCurrent: {:s}"
53  "\nTerminal 0 voltage: {:s}"
54  "\nTerminal 1 voltage: {:s}"
55  "\n--- Initialization from powerflow finished ---",
56  Logger::phasorToString((**mIntfVoltage)(0, 0)),
57  Logger::phasorToString((**mIntfCurrent)(0, 0)),
58  Logger::phasorToString(initialSingleVoltage(0)),
59  Logger::phasorToString(initialSingleVoltage(1)));
60  mSLog->flush();
61 }
62 
63 void DP::Ph1::Capacitor::mnaCompInitialize(Real omega, Real timeStep,
64  Attribute<Matrix>::Ptr leftVector) {
65  updateMatrixNodeIndices();
66 
67  Real equivCondReal = 2.0 * **mCapacitance / timeStep;
68  Real prevVoltCoeffReal = 2.0 * **mCapacitance / timeStep;
69 
70  for (UInt freq = 0; freq < mNumFreqs; freq++) {
71  Real equivCondImag = 2. * PI * mFrequencies(freq, 0) * **mCapacitance;
72  mEquivCond(freq, 0) = {equivCondReal, equivCondImag};
73  Real prevVoltCoeffImag = -2. * PI * mFrequencies(freq, 0) * **mCapacitance;
74  mPrevVoltCoeff(freq, 0) = {prevVoltCoeffReal, prevVoltCoeffImag};
75 
76  mEquivCurrent(freq, 0) =
77  -(**mIntfCurrent)(0, freq) +
78  -mPrevVoltCoeff(freq, 0) * (**mIntfVoltage)(0, freq);
79  (**mIntfCurrent)(0, freq) =
80  mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
81  mEquivCurrent(freq, 0);
82  }
83 
84  SPDLOG_LOGGER_INFO(mSLog,
85  "\n--- MNA initialization ---"
86  "\nInitial voltage {:s}"
87  "\nInitial current {:s}"
88  "\nEquiv. current {:s}"
89  "\n--- MNA initialization finished ---",
90  Logger::phasorToString((**mIntfVoltage)(0, 0)),
91  Logger::phasorToString((**mIntfCurrent)(0, 0)),
92  Logger::complexToString(mEquivCurrent(0, 0)));
93  mSLog->flush();
94 }
95 
96 void DP::Ph1::Capacitor::mnaCompInitializeHarm(
97  Real omega, Real timeStep,
98  std::vector<Attribute<Matrix>::Ptr> leftVectors) {
99  updateMatrixNodeIndices();
100 
101  Real equivCondReal = 2.0 * **mCapacitance / timeStep;
102  Real prevVoltCoeffReal = 2.0 * **mCapacitance / timeStep;
103 
104  for (UInt freq = 0; freq < mNumFreqs; freq++) {
105  Real equivCondImag = 2. * PI * mFrequencies(freq, 0) * **mCapacitance;
106  mEquivCond(freq, 0) = {equivCondReal, equivCondImag};
107  Real prevVoltCoeffImag = -2. * PI * mFrequencies(freq, 0) * **mCapacitance;
108  mPrevVoltCoeff(freq, 0) = {prevVoltCoeffReal, prevVoltCoeffImag};
109 
110  mEquivCurrent(freq, 0) =
111  -(**mIntfCurrent)(0, freq) +
112  -mPrevVoltCoeff(freq, 0) * (**mIntfVoltage)(0, freq);
113  (**mIntfCurrent)(0, freq) =
114  mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
115  mEquivCurrent(freq, 0);
116  }
117 
118  mMnaTasks.push_back(std::make_shared<MnaPreStepHarm>(*this));
119  mMnaTasks.push_back(std::make_shared<MnaPostStepHarm>(*this, leftVectors));
120  **mRightVector = Matrix::Zero(leftVectors[0]->get().rows(), mNumFreqs);
121 }
122 
124  SparseMatrixRow &systemMatrix) {
125  for (UInt freq = 0; freq < mNumFreqs; freq++) {
126  MNAStampUtils::stampAdmittance(
127  mEquivCond(freq, 0), systemMatrix, matrixNodeIndex(0),
128  matrixNodeIndex(1), terminalNotGrounded(0), terminalNotGrounded(1),
129  mSLog, mNumFreqs, freq);
130  }
131 }
132 
133 void DP::Ph1::Capacitor::mnaCompApplySystemMatrixStampHarm(
134  SparseMatrixRow &systemMatrix, Int freqIdx) {
135  MNAStampUtils::stampAdmittance(mEquivCond(freqIdx, 0), systemMatrix,
136  matrixNodeIndex(0), matrixNodeIndex(1),
137  terminalNotGrounded(0), terminalNotGrounded(1),
138  mSLog);
139 }
140 
142  for (UInt freq = 0; freq < mNumFreqs; freq++) {
143  //mCureqr = mCurrr + mGcr * mDeltavr + mGci * mDeltavi;
144  //mCureqi = mCurri + mGcr * mDeltavi - mGci * mDeltavr;
145  mEquivCurrent(freq, 0) =
146  -(**mIntfCurrent)(0, freq) +
147  -mPrevVoltCoeff(freq, 0) * (**mIntfVoltage)(0, freq);
148 
149  if (terminalNotGrounded(0))
150  Math::setVectorElement(rightVector, matrixNodeIndex(0),
151  mEquivCurrent(freq, 0), mNumFreqs, freq);
152  if (terminalNotGrounded(1))
153  Math::setVectorElement(rightVector, matrixNodeIndex(1),
154  -mEquivCurrent(freq, 0), mNumFreqs, freq);
155 
156  SPDLOG_LOGGER_DEBUG(mSLog, "MNA EquivCurrent {:f}+j{:f}",
157  mEquivCurrent(freq, 0).real(),
158  mEquivCurrent(freq, 0).imag());
159  if (terminalNotGrounded(0))
160  SPDLOG_LOGGER_DEBUG(mSLog, "Add {:f}+j{:f} to source vector at {:d}",
161  mEquivCurrent(freq, 0).real(),
162  mEquivCurrent(freq, 0).imag(), matrixNodeIndex(0));
163  if (terminalNotGrounded(1))
164  SPDLOG_LOGGER_DEBUG(mSLog, "Add {:f}+j{:f} to source vector at {:d}",
165  -mEquivCurrent(freq, 0).real(),
166  -mEquivCurrent(freq, 0).imag(), matrixNodeIndex(1));
167  }
168 }
169 
170 void DP::Ph1::Capacitor::mnaCompApplyRightSideVectorStampHarm(
171  Matrix &rightVector) {
172  for (UInt freq = 0; freq < mNumFreqs; freq++) {
173  //mCureqr = mCurrr + mGcr * mDeltavr + mGci * mDeltavi;
174  //mCureqi = mCurri + mGcr * mDeltavi - mGci * mDeltavr;
175  mEquivCurrent(freq, 0) =
176  -(**mIntfCurrent)(0, freq) +
177  -mPrevVoltCoeff(freq, 0) * (**mIntfVoltage)(0, freq);
178 
179  if (terminalNotGrounded(0))
180  Math::setVectorElement(rightVector, matrixNodeIndex(0),
181  mEquivCurrent(freq, 0), 1, 0, freq);
182  if (terminalNotGrounded(1))
183  Math::setVectorElement(rightVector, matrixNodeIndex(1),
184  -mEquivCurrent(freq, 0), 1, 0, freq);
185  }
186 }
187 
188 void DP::Ph1::Capacitor::mnaCompApplyRightSideVectorStampHarm(
189  Matrix &rightVector, Int freq) {
190  //mCureqr = mCurrr + mGcr * mDeltavr + mGci * mDeltavi;
191  //mCureqi = mCurri + mGcr * mDeltavi - mGci * mDeltavr;
192  mEquivCurrent(freq, 0) = -(**mIntfCurrent)(0, freq) +
193  -mPrevVoltCoeff(freq, 0) * (**mIntfVoltage)(0, freq);
194 
195  if (terminalNotGrounded(0))
196  Math::setVectorElement(rightVector, matrixNodeIndex(0),
197  mEquivCurrent(freq, 0));
198  if (terminalNotGrounded(1))
199  Math::setVectorElement(rightVector, matrixNodeIndex(1),
200  -mEquivCurrent(freq, 0));
201 }
202 
204  AttributeBase::List &prevStepDependencies,
205  AttributeBase::List &attributeDependencies,
206  AttributeBase::List &modifiedAttributes) {
207  // actually depends on C, but then we'd have to modify the system matrix anyway
208  prevStepDependencies.push_back(mIntfCurrent);
209  prevStepDependencies.push_back(mIntfVoltage);
210  modifiedAttributes.push_back(mRightVector);
211 }
212 
213 void DP::Ph1::Capacitor::mnaCompPreStep(Real time, Int timeStepCount) {
214  this->mnaApplyRightSideVectorStamp(**this->mRightVector);
215 }
216 
218  AttributeBase::List &prevStepDependencies,
219  AttributeBase::List &attributeDependencies,
220  AttributeBase::List &modifiedAttributes,
221  Attribute<Matrix>::Ptr &leftVector) {
222  attributeDependencies.push_back(leftVector);
223  modifiedAttributes.push_back(mIntfVoltage);
224  modifiedAttributes.push_back(mIntfCurrent);
225 }
226 
227 void DP::Ph1::Capacitor::mnaCompPostStep(Real time, Int timeStepCount,
228  Attribute<Matrix>::Ptr &leftVector) {
229  this->mnaUpdateVoltage(**leftVector);
230  this->mnaUpdateCurrent(**leftVector);
231 }
232 
233 void DP::Ph1::Capacitor::MnaPreStepHarm::execute(Real time, Int timeStepCount) {
234  mCapacitor.mnaCompApplyRightSideVectorStampHarm(**mCapacitor.mRightVector);
235 }
236 
237 void DP::Ph1::Capacitor::MnaPostStepHarm::execute(Real time,
238  Int timeStepCount) {
239  for (UInt freq = 0; freq < mCapacitor.mNumFreqs; freq++)
240  mCapacitor.mnaCompUpdateVoltageHarm(**mLeftVectors[freq], freq);
241  mCapacitor.mnaCompUpdateCurrentHarm();
242 }
243 
244 void DP::Ph1::Capacitor::mnaCompUpdateVoltage(const Matrix &leftVector) {
245  // v1 - v0
246  for (UInt freq = 0; freq < mNumFreqs; freq++) {
247  (**mIntfVoltage)(0, freq) = 0;
248  if (terminalNotGrounded(1))
249  (**mIntfVoltage)(0, freq) = Math::complexFromVectorElement(
250  leftVector, matrixNodeIndex(1), mNumFreqs, freq);
251  if (terminalNotGrounded(0))
252  (**mIntfVoltage)(0, freq) =
253  (**mIntfVoltage)(0, freq) -
254  Math::complexFromVectorElement(leftVector, matrixNodeIndex(0),
255  mNumFreqs, freq);
256 
257  SPDLOG_LOGGER_DEBUG(mSLog, "Voltage {:e}<{:e}",
258  std::abs((**mIntfVoltage)(0, freq)),
259  std::arg((**mIntfVoltage)(0, freq)));
260  }
261 }
262 
263 void DP::Ph1::Capacitor::mnaCompUpdateVoltageHarm(const Matrix &leftVector,
264  Int freqIdx) {
265  // v1 - v0
266  (**mIntfVoltage)(0, freqIdx) = 0;
267  if (terminalNotGrounded(1))
268  (**mIntfVoltage)(0, freqIdx) =
269  Math::complexFromVectorElement(leftVector, matrixNodeIndex(1));
270  if (terminalNotGrounded(0))
271  (**mIntfVoltage)(0, freqIdx) =
272  (**mIntfVoltage)(0, freqIdx) -
273  Math::complexFromVectorElement(leftVector, matrixNodeIndex(0));
274 
275  SPDLOG_LOGGER_DEBUG(mSLog, "Voltage {:s}",
276  Logger::phasorToString((**mIntfVoltage)(0, freqIdx)));
277 }
278 
279 void DP::Ph1::Capacitor::mnaCompUpdateCurrent(const Matrix &leftVector) {
280  for (UInt freq = 0; freq < mNumFreqs; freq++) {
281  (**mIntfCurrent)(0, freq) =
282  mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
283  mEquivCurrent(freq, 0);
284  SPDLOG_LOGGER_DEBUG(mSLog, "Current {:s}",
285  Logger::phasorToString((**mIntfCurrent)(0, freq)));
286  }
287 }
288 
289 void DP::Ph1::Capacitor::mnaCompUpdateCurrentHarm() {
290  for (UInt freq = 0; freq < mNumFreqs; freq++) {
291  (**mIntfCurrent)(0, freq) =
292  mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
293  mEquivCurrent(freq, 0);
294  SPDLOG_LOGGER_DEBUG(mSLog, "Current {:s}",
295  Logger::phasorToString((**mIntfCurrent)(0, freq)));
296  }
297 }
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) override
Stamps system matrix.
Capacitor(String uid, String name, Logger::Level logLevel=Logger::Level::off)
Defines UID, name and logging level.
void mnaCompPreStep(Real time, Int timeStepCount) override
MNA pre step operations.
void mnaCompAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
Add MNA pre step dependencies.
void initializeFromNodesAndTerminals(Real frequency) override
Initializes component from power flow data.
void mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
Add MNA post step dependencies.
void initialize(Matrix frequencies) override
Initialize components with correct network frequencies.
MatrixComp mEquivCurrent
DC equivalent current source for harmonics [A].
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.
void mnaCompUpdateCurrent(const Matrix &leftVector) override
Update interface current from MNA system result.
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override
Stamps right side (source) vector.
SimPowerComp< Complex >::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.
Base class for all MNA components that are transmitting power.
Base class for all components that are transmitting power.
Definition: SimPowerComp.h:17
virtual void initialize(Matrix frequencies)
Initialize components with correct network frequencies.
const Attribute< MatrixVar< Complex > >::Ptr mIntfCurrent
Current through component.
Definition: SimPowerComp.h:47
const Attribute< MatrixVar< Complex > >::Ptr mIntfVoltage
Voltage between terminals.
Definition: SimPowerComp.h:45