9 #include <dpsim-models/DP/DP_Ph1_ResIndSeries.h>
14 Logger::Level logLevel)
16 mInductance(mAttributes->create<Real>(
"L")),
18 mResistance(mAttributes->create<Real>(
"R")) {
27 auto copy = ResIndSeries::make(name, mLogLevel);
28 copy->setParameters(**mResistance, **mInductance);
33 **mResistance = resistance;
34 **mInductance = inductance;
40 mEquivCurrent = MatrixComp::Zero(mNumFreqs, 1);
41 mEquivCond = MatrixComp::Zero(mNumFreqs, 1);
42 mPrevCurrFac = MatrixComp::Zero(mNumFreqs, 1);
47 Real omega = 2. * PI * frequency;
48 Complex impedance = {0, omega * **mInductance};
49 (**mIntfVoltage)(0, 0) = initialSingleVoltage(1) - initialSingleVoltage(0);
50 (**mIntfCurrent)(0, 0) = (**mIntfVoltage)(0, 0) / impedance;
52 SPDLOG_LOGGER_INFO(mSLog,
53 "\n--- Initialization from powerflow ---"
54 "\nVoltage across: {:s}"
56 "\nTerminal 0 voltage: {:s}"
57 "\nTerminal 1 voltage: {:s}"
58 "\n--- Initialization from powerflow finished ---",
59 Logger::phasorToString((**mIntfVoltage)(0, 0)),
60 Logger::phasorToString((**mIntfCurrent)(0, 0)),
61 Logger::phasorToString(initialSingleVoltage(0)),
62 Logger::phasorToString(initialSingleVoltage(1)));
67 void DP::Ph1::ResIndSeries::initVars(Real timeStep) {
68 for (Int freq = 0; freq < mNumFreqs; freq++) {
69 Real a = timeStep / (2. * **mInductance);
70 Real b = timeStep * 2. * PI * mFrequencies(freq, 0) / 2.;
72 Real equivCondReal = a / (1. + b * b);
73 Real equivCondImag = -a * b / (1. + b * b);
74 mEquivCond(freq, 0) = {equivCondReal, equivCondImag};
75 Real preCurrFracReal = (1. - b * b) / (1. + b * b);
76 Real preCurrFracImag = (-2. * b) / (1. + b * b);
77 mPrevCurrFac(freq, 0) = {preCurrFracReal, preCurrFracImag};
80 mEquivCurrent(freq, 0) = mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
81 mPrevCurrFac(freq, 0) * (**mIntfCurrent)(0, freq);
82 (**mIntfCurrent)(0, freq) =
83 mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
84 mEquivCurrent(freq, 0);
90 updateMatrixNodeIndices();
93 SPDLOG_LOGGER_INFO(mSLog,
94 "\n--- MNA initialization ---"
95 "\nInitial voltage {:s}"
96 "\nInitial current {:s}"
97 "\nEquiv. current {:s}"
98 "\n--- MNA initialization finished ---",
99 Logger::phasorToString((**mIntfVoltage)(0, 0)),
100 Logger::phasorToString((**mIntfCurrent)(0, 0)),
101 Logger::complexToString(mEquivCurrent(0, 0)));
104 void DP::Ph1::ResIndSeries::mnaCompInitializeHarm(
105 Real omega, Real timeStep,
107 updateMatrixNodeIndices();
111 mMnaTasks.push_back(std::make_shared<MnaPreStepHarm>(*
this));
112 mMnaTasks.push_back(std::make_shared<MnaPostStepHarm>(*
this, leftVectors));
113 **mRightVector = Matrix::Zero(leftVectors[0]->get().rows(), mNumFreqs);
117 SparseMatrixRow &systemMatrix) {
118 for (Int freq = 0; freq < mNumFreqs; freq++) {
119 if (terminalNotGrounded(0))
120 Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0),
121 matrixNodeIndex(0), mEquivCond(freq, 0),
123 if (terminalNotGrounded(1))
124 Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1),
125 matrixNodeIndex(1), mEquivCond(freq, 0),
127 if (terminalNotGrounded(0) && terminalNotGrounded(1)) {
128 Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0),
129 matrixNodeIndex(1), -mEquivCond(freq, 0),
131 Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1),
132 matrixNodeIndex(0), -mEquivCond(freq, 0),
136 SPDLOG_LOGGER_INFO(mSLog,
"-- Stamp frequency {:d} ---", freq);
137 if (terminalNotGrounded(0))
138 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
139 Logger::complexToString(mEquivCond(freq, 0)),
140 matrixNodeIndex(0), matrixNodeIndex(0));
141 if (terminalNotGrounded(1))
142 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
143 Logger::complexToString(mEquivCond(freq, 0)),
144 matrixNodeIndex(1), matrixNodeIndex(1));
145 if (terminalNotGrounded(0) && terminalNotGrounded(1)) {
146 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
147 Logger::complexToString(-mEquivCond(freq, 0)),
148 matrixNodeIndex(0), matrixNodeIndex(1));
149 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
150 Logger::complexToString(-mEquivCond(freq, 0)),
151 matrixNodeIndex(1), matrixNodeIndex(0));
156 void DP::Ph1::ResIndSeries::mnaCompApplySystemMatrixStampHarm(
157 SparseMatrixRow &systemMatrix, Int freqIdx) {
158 if (terminalNotGrounded(0))
159 Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0),
160 matrixNodeIndex(0), mEquivCond(freqIdx, 0));
161 if (terminalNotGrounded(1))
162 Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1),
163 matrixNodeIndex(1), mEquivCond(freqIdx, 0));
164 if (terminalNotGrounded(0) && terminalNotGrounded(1)) {
165 Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0),
166 matrixNodeIndex(1), -mEquivCond(freqIdx, 0));
167 Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1),
168 matrixNodeIndex(0), -mEquivCond(freqIdx, 0));
171 SPDLOG_LOGGER_INFO(mSLog,
"-- Stamp frequency {:d} ---", freqIdx);
172 if (terminalNotGrounded(0))
173 SPDLOG_LOGGER_INFO(mSLog,
"Add {:f}+j{:f} to system at ({:d},{:d})",
174 mEquivCond(freqIdx, 0).real(),
175 mEquivCond(freqIdx, 0).imag(), matrixNodeIndex(0),
177 if (terminalNotGrounded(1))
178 SPDLOG_LOGGER_INFO(mSLog,
"Add {:f}+j{:f} to system at ({:d},{:d})",
179 mEquivCond(freqIdx, 0).real(),
180 mEquivCond(freqIdx, 0).imag(), matrixNodeIndex(1),
182 if (terminalNotGrounded(0) && terminalNotGrounded(1)) {
183 SPDLOG_LOGGER_INFO(mSLog,
"Add {:f}+j{:f} to system at ({:d},{:d})",
184 -mEquivCond(freqIdx, 0).real(),
185 -mEquivCond(freqIdx, 0).imag(), matrixNodeIndex(0),
187 SPDLOG_LOGGER_INFO(mSLog,
"Add {:f}+j{:f} to system at ({:d},{:d})",
188 -mEquivCond(freqIdx, 0).real(),
189 -mEquivCond(freqIdx, 0).imag(), matrixNodeIndex(1),
195 Matrix &rightVector) {
196 for (Int freq = 0; freq < mNumFreqs; freq++) {
198 mEquivCurrent(freq, 0) = mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
199 mPrevCurrFac(freq, 0) * (**mIntfCurrent)(0, freq);
201 if (terminalNotGrounded(0))
202 Math::setVectorElement(rightVector, matrixNodeIndex(0),
203 mEquivCurrent(freq, 0), mNumFreqs, freq);
204 if (terminalNotGrounded(1))
205 Math::setVectorElement(rightVector, matrixNodeIndex(1),
206 -mEquivCurrent(freq, 0), mNumFreqs, freq);
208 SPDLOG_LOGGER_DEBUG(mSLog,
"MNA EquivCurrent {:s}",
209 Logger::complexToString(mEquivCurrent(freq, 0)));
210 if (terminalNotGrounded(0))
211 SPDLOG_LOGGER_DEBUG(mSLog,
"Add {:s} to source vector at {:d}",
212 Logger::complexToString(mEquivCurrent(freq, 0)),
214 if (terminalNotGrounded(1))
215 SPDLOG_LOGGER_DEBUG(mSLog,
"Add {:s} to source vector at {:d}",
216 Logger::complexToString(-mEquivCurrent(freq, 0)),
221 void DP::Ph1::ResIndSeries::mnaCompApplyRightSideVectorStampHarm(
222 Matrix &rightVector) {
223 for (Int freq = 0; freq < mNumFreqs; freq++) {
225 mEquivCurrent(freq, 0) = mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
226 mPrevCurrFac(freq, 0) * (**mIntfCurrent)(0, freq);
228 if (terminalNotGrounded(0))
229 Math::setVectorElement(rightVector, matrixNodeIndex(0),
230 mEquivCurrent(freq, 0), 1, 0, freq);
231 if (terminalNotGrounded(1))
232 Math::setVectorElement(rightVector, matrixNodeIndex(1),
233 -mEquivCurrent(freq, 0), 1, 0, freq);
237 void mnaCompAddPreStepDependencies(AttributeBase::List &prevStepDependencies,
238 AttributeBase::List &attributeDependencies,
239 AttributeBase::List &modifiedAttributes) {
241 modifiedAttributes.push_back(mRightVector);
242 prevStepDependencies.push_back(mIntfVoltage);
243 prevStepDependencies.push_back(mIntfCurrent);
246 void DP::Ph1::ResIndSeries::mnaCompPreStep(Real time, Int timeStepCount) {
247 mResIndSeries.mnaCompApplyRightSideVectorStamp(**mRightVector);
250 void DP::Ph1::ResIndSeries::MnaPreStepHarm::execute(Real time,
252 mResIndSeries.mnaCompApplyRightSideVectorStampHarm(
253 **mResIndSeries.mRightVector);
256 void mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies,
257 AttributeBase::List &attributeDependencies,
258 AttributeBase::List &modifiedAttributes,
260 attributeDependencies.push_back(leftVector);
261 modifiedAttributes.push_back(mIntfVoltage);
262 modifiedAttributes.push_back(mIntfCurrent);
265 void DP::Ph1::ResIndSeries::mnaCompPostStep(
267 mnaCompUpdateVoltage(**leftVector);
268 mnaCompUpdateCurrent(**leftVector);
271 void DP::Ph1::ResIndSeries::MnaPostStepHarm::execute(Real time,
273 for (Int freq = 0; freq < mResIndSeries.mNumFreqs; freq++)
274 mResIndSeries.mnaCompUpdateVoltageHarm(**mLeftVectors[freq], freq);
275 mResIndSeries.mnaCompUpdateCurrentHarm();
280 for (Int freq = 0; freq < mNumFreqs; freq++) {
281 (**mIntfVoltage)(0, freq) = 0;
282 if (terminalNotGrounded(1))
283 (**mIntfVoltage)(0, freq) = Math::complexFromVectorElement(
284 leftVector, matrixNodeIndex(1), mNumFreqs, freq);
285 if (terminalNotGrounded(0))
286 (**mIntfVoltage)(0, freq) =
287 (**mIntfVoltage)(0, freq) -
288 Math::complexFromVectorElement(leftVector, matrixNodeIndex(0),
291 SPDLOG_LOGGER_DEBUG(mSLog,
"Voltage {:s}",
292 Logger::phasorToString((**mIntfVoltage)(0, freq)));
296 void DP::Ph1::ResIndSeries::mnaCompUpdateVoltageHarm(
const Matrix &leftVector,
299 (**mIntfVoltage)(0, freqIdx) = 0;
300 if (terminalNotGrounded(1))
301 (**mIntfVoltage)(0, freqIdx) =
302 Math::complexFromVectorElement(leftVector, matrixNodeIndex(1));
303 if (terminalNotGrounded(0))
304 (**mIntfVoltage)(0, freqIdx) =
305 (**mIntfVoltage)(0, freqIdx) -
306 Math::complexFromVectorElement(leftVector, matrixNodeIndex(0));
308 SPDLOG_LOGGER_DEBUG(mSLog,
"Voltage {:s}",
309 Logger::phasorToString((**mIntfVoltage)(0, freqIdx)));
313 for (Int freq = 0; freq < mNumFreqs; freq++) {
314 (**mIntfCurrent)(0, freq) =
315 mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
316 mEquivCurrent(freq, 0);
317 SPDLOG_LOGGER_DEBUG(mSLog,
"Current {:s}",
318 Logger::phasorToString((**mIntfCurrent)(0, freq)));
322 void DP::Ph1::ResIndSeries::mnaCompUpdateCurrentHarm() {
323 for (Int freq = 0; freq < mNumFreqs; freq++) {
324 (**mIntfCurrent)(0, freq) =
325 mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
326 mEquivCurrent(freq, 0);
327 SPDLOG_LOGGER_DEBUG(mSLog,
"Current {:s}",
328 Logger::phasorToString((**mIntfCurrent)(0, freq)));
333 void DP::Ph1::ResIndSeries::mnaTearInitialize(Real omega, Real timeStep) {
337 void DP::Ph1::ResIndSeries::mnaTearApplyMatrixStamp(
338 SparseMatrixRow &tearMatrix) {
339 Math::addToMatrixElement(tearMatrix, mTearIdx, mTearIdx,
340 1. / mEquivCond(0, 0));
343 void DP::Ph1::ResIndSeries::mnaTearApplyVoltageStamp(Matrix &voltageVector) {
344 mEquivCurrent(0, 0) = mEquivCond(0, 0) * (**mIntfVoltage)(0, 0) +
345 mPrevCurrFac(0, 0) * (**mIntfCurrent)(0, 0);
346 Math::addToVectorElement(voltageVector, mTearIdx,
347 mEquivCurrent(0, 0) / mEquivCond(0, 0));
350 void DP::Ph1::ResIndSeries::mnaTearPostStep(Complex voltage, Complex current) {
351 (**mIntfVoltage)(0, 0) = voltage;
352 (**mIntfCurrent)(0, 0) = mEquivCond(0, 0) * voltage + mEquivCurrent(0, 0);
void initialize(Matrix frequencies)
Initializes state variables considering the number of frequencies.
void mnaCompInitialize(Real omega, Real timeStep, Attribute< Matrix >::Ptr leftVector)
Initializes MNA specific variables.
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector)
Stamps right side (source) vector.
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix)
Stamps system matrix.
void initializeFromNodesAndTerminals(Real frequency)
Initializes states from power flow data.
MatrixComp mEquivCurrent
DC equivalent current source for harmonics [A].
void mnaCompUpdateVoltage(const Matrix &leftVector)
Update interface voltage from MNA system results.
void setParameters(Real resistance, Real inductance)
Sets model specific parameters.
ResIndSeries(String uid, String name, Logger::Level logLevel=Logger::Level::off)
Defines UID, name and log level.
SimPowerComp< Complex >::Ptr clone(String name)
Return new instance with the same parameters.
void mnaCompUpdateCurrent()
Update interface current from MNA system results.
Base class for all MNA components that are transmitting power.
Base class for all components that are transmitting power.
virtual void initialize(Matrix frequencies)
Initialize components with correct network frequencies.
const Attribute< MatrixVar< Complex > >::Ptr mIntfCurrent
Current through component.
const Attribute< MatrixVar< Complex > >::Ptr mIntfVoltage
Voltage between terminals.