DPsim
Loading...
Searching...
No Matches
Base_ReducedOrderSynchronGenerator.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/Base/Base_ReducedOrderSynchronGenerator.h>
10
11using namespace CPS;
12
13template <>
14Base::ReducedOrderSynchronGenerator<Real>::ReducedOrderSynchronGenerator(
15 String uid, String name, Logger::Level logLevel)
16 : MNASimPowerComp<Real>(uid, name, true, true, logLevel),
17 mVdq0(mAttributes->create<Matrix>("Vdq0")),
18 mIdq0(mAttributes->create<Matrix>("Idq0")),
19 mElecTorque(mAttributes->create<Real>("Te")),
20 mMechTorque(mAttributes->create<Real>("Tm")),
21 mOmMech(mAttributes->create<Real>("w_r")),
22 mThetaMech(mAttributes->create<Real>("Theta")),
23 mDelta(mAttributes->create<Real>("delta")),
24 mEf(mAttributes->create<Real>("Ef")) {
25
26 mSimTime = 0.0;
27
28 // declare state variables
29 **mVdq0 = Matrix::Zero(3, 1);
30 **mIdq0 = Matrix::Zero(3, 1);
31
32 // default model is Norton equivalent
33 mModelAsNortonSource = true;
34 SPDLOG_LOGGER_DEBUG(this->mSLog,
35 "SG per default modelled as Norton equivalent");
36}
37
38template <>
39Base::ReducedOrderSynchronGenerator<Complex>::ReducedOrderSynchronGenerator(
40 String uid, String name, Logger::Level logLevel)
41 : MNASimPowerComp<Complex>(uid, name, true, true, logLevel),
42 mVdq(mAttributes->create<Matrix>("Vdq0")),
43 mIdq(mAttributes->create<Matrix>("Idq0")),
44 mElecTorque(mAttributes->create<Real>("Te")),
45 mMechTorque(mAttributes->create<Real>("Tm")),
46 mOmMech(mAttributes->create<Real>("w_r")),
47 mThetaMech(mAttributes->create<Real>("Theta")),
48 mDelta(mAttributes->create<Real>("delta")),
49 mEf(mAttributes->create<Real>("Ef")) {
50
51 mSimTime = 0.0;
52
53 // declare state variables
55 **mVdq = Matrix::Zero(2, 1);
56 **mIdq = Matrix::Zero(2, 1);
57
58 // default model is Norton equivalent
59 mModelAsNortonSource = true;
60 SPDLOG_LOGGER_DEBUG(this->mSLog,
61 "SG per default modelled as Norton equivalent");
63
64template <typename VarType>
66 Bool modelAsCurrentSource) {
67 mModelAsNortonSource = modelAsCurrentSource;
68
70 this->setVirtualNodeNumber(0);
71 SPDLOG_LOGGER_DEBUG(this->mSLog, "Setting SG model to Norton equivalent");
72 } else {
73 this->setVirtualNodeNumber(2);
74 SPDLOG_LOGGER_DEBUG(this->mSLog, "Setting SG model to Thevenin equivalent");
75 }
77
78template <typename VarType>
80 Real nomPower, Real nomVolt, Real nomFreq) {
81
83
84 // set base nominal values
85 mNomPower = nomPower;
86 mNomVolt = nomVolt;
87 mNomFreq = nomFreq;
88 mNomOmega = nomFreq * 2 * PI;
89
90 // Set base stator values
92 mBase_V = mNomVolt / sqrt(3) * sqrt(2);
94 mBase_I = mNomPower / ((3. / 2.) * mBase_V);
99}
100
101template <typename VarType>
103 VarType>::setOperationalParametersPerUnit(Real nomPower, Real nomVolt,
104 Real nomFreq, Real H, Real Ld,
105 Real Lq, Real L0, Real Ld_t,
106 Real Td0_t) {
107
108 setBaseParameters(nomPower, nomVolt, nomFreq);
109
110 mLd = Ld;
111 mLq = Lq;
112 mL0 = L0;
113 mLd_t = Ld_t;
114 mTd0_t = Td0_t;
115 mH = H;
116
117 SPDLOG_LOGGER_INFO(this->mSLog,
118 "Set base parameters: \n"
119 "nomPower: {:e}\nnomVolt: {:e}\nnomFreq: {:e}\n",
120 mNomPower, mNomVolt, mNomFreq);
121
122 SPDLOG_LOGGER_INFO(this->mSLog,
123 "Set operational parameters in per unit: \n"
124 "inertia: {:e}\n"
125 "Ld: {:e}\nLq: {:e}\nL0: {:e}\n"
126 "Ld_t: {:e}\nTd0_t: {:e}\n",
127 mH, mLd, mLq, mL0, mLd_t, mTd0_t);
128}
129
130template <typename VarType>
132 VarType>::setOperationalParametersPerUnit(Real nomPower, Real nomVolt,
133 Real nomFreq, Real H, Real Ld,
134 Real Lq, Real L0, Real Ld_t,
135 Real Lq_t, Real Td0_t,
136 Real Tq0_t) {
137
138 setBaseParameters(nomPower, nomVolt, nomFreq);
139
140 mLd = Ld;
141 mLq = Lq;
142 mL0 = L0;
143 mLd_t = Ld_t;
144 mLq_t = Lq_t;
145 mTd0_t = Td0_t;
146 mTq0_t = Tq0_t;
147 mH = H;
148
149 SPDLOG_LOGGER_INFO(this->mSLog,
150 "Set base parameters: \n"
151 "nomPower: {:e}\nnomVolt: {:e}\nnomFreq: {:e}\n",
152 mNomPower, mNomVolt, mNomFreq);
153
154 SPDLOG_LOGGER_INFO(this->mSLog,
155 "Set operational parameters in per unit: \n"
156 "inertia: {:e}\n"
157 "Ld: {:e}\nLq: {:e}\nL0: {:e}\n"
158 "Ld_t: {:e}\nLq_t: {:e}\n"
159 "Td0_t: {:e}\nTq0_t: {:e}\n",
161}
162
163template <typename VarType>
165 VarType>::setOperationalParametersPerUnit(Real nomPower, Real nomVolt,
166 Real nomFreq, Real H, Real Ld,
167 Real Lq, Real L0, Real Ld_t,
168 Real Lq_t, Real Td0_t, Real Tq0_t,
169 Real Ld_s, Real Lq_s, Real Td0_s,
170 Real Tq0_s, Real Taa) {
171
172 setBaseParameters(nomPower, nomVolt, nomFreq);
173
174 mLd = Ld;
175 mLq = Lq;
176 mL0 = L0;
177 mLd_t = Ld_t;
178 mLq_t = Lq_t;
179 mLd_s = Ld_s;
180 mLq_s = Lq_s;
181 mTd0_t = Td0_t;
182 mTq0_t = Tq0_t;
183 mTd0_s = Td0_s;
184 mTq0_s = Tq0_s;
185 mTaa = Taa;
186 mH = H;
187
188 SPDLOG_LOGGER_INFO(this->mSLog,
189 "Set base parameters: \n"
190 "nomPower: {:e}\nnomVolt: {:e}\nnomFreq: {:e}\n",
191 mNomPower, mNomVolt, mNomFreq);
192
193 SPDLOG_LOGGER_INFO(this->mSLog,
194 "Set operational parameters in per unit: \n"
195 "inertia: {:e}\n"
196 "Ld: {:e}\nLq: {:e}\nL0: {:e}\n"
197 "Ld_t: {:e}\nLq_t: {:e}\n"
198 "Td0_t: {:e}\nTq0_t: {:e}\n"
199 "Ld_s: {:e}\nLq_s: {:e}\n"
200 "Td0_s: {:e}\nTq0_s: {:e}\n"
201 "Taa: {:e}\n",
204}
205
206template <typename VarType>
208 Real scalingFactor) {
209 mH = mH * scalingFactor;
210 SPDLOG_LOGGER_INFO(
211 this->mSLog,
212 "Scaling inertia with factor {:e}:\n resulting inertia: {:e}\n",
213 scalingFactor, mH);
214}
215
216template <typename VarType>
217void Base::ReducedOrderSynchronGenerator<VarType>::calculateVBRconstants() {
218
219 Real Tf = 0;
220 if (mSGOrder == SGOrder::SG5Order) {
221 mYd = (mTd0_s / mTd0_t) * (mLd_s / mLd_t) * (mLd - mLd_t);
222 mYq = 0.0;
223 Tf = mTaa / mTd0_t;
224 } else if (mSGOrder == SGOrder::SG6aOrder) {
225 mYd = (mTd0_s / mTd0_t) * (mLd_s / mLd_t) * (mLd - mLd_t);
226 mYq = (mTq0_s / mTq0_t) * (mLq_s / mLq_t) * (mLq - mLq_t);
227 Tf = mTaa / mTd0_t;
228 } else {
229 mYd = 0;
230 mYq = 0;
231 }
232
233 Real Zq_t = mLd - mLd_t - mYd;
234 Real Zd_t = mLq - mLq_t - mYq;
235 Real Zq_s = mLd_t - mLd_s + mYd;
236 Real Zd_s = mLq_t - mLq_s + mYq;
237
238 mAd_t = mTimeStep * Zd_t / (2 * mTq0_t + mTimeStep);
239 mBd_t = (2 * mTq0_t - mTimeStep) / (2 * mTq0_t + mTimeStep);
240 mAq_t = -mTimeStep * Zq_t / (2 * mTd0_t + mTimeStep);
241 mBq_t = (2 * mTd0_t - mTimeStep) / (2 * mTd0_t + mTimeStep);
242 mDq_t = mTimeStep * (1 - Tf) / (2 * mTd0_t + mTimeStep);
243
244 if (mSGOrder == SGOrder::SG5Order) {
245 mAd_s = (mTimeStep * (mLq - mLq_s)) / (2 * mTq0_s + mTimeStep);
246 mCd_s = (2 * mTq0_s - mTimeStep) / (2 * mTq0_s + mTimeStep);
247 mAq_s = (-mTimeStep * Zq_s + mTimeStep * mAq_t) / (2 * mTd0_s + mTimeStep);
248 mBq_s = (mTimeStep * mBq_t + mTimeStep) / (2 * mTd0_s + mTimeStep);
249 mCq_s = (2 * mTd0_s - mTimeStep) / (2 * mTd0_s + mTimeStep);
250 mDq_s = (mTimeStep * mDq_t + Tf * mTimeStep) / (2 * mTd0_s + mTimeStep);
251 } else if (mSGOrder == SGOrder::SG6aOrder || mSGOrder == SGOrder::SG6bOrder) {
252 mAd_s = (mTimeStep * Zd_s + mTimeStep * mAd_t) / (2 * mTq0_s + mTimeStep);
253 mBd_s = (mTimeStep * mBd_t + mTimeStep) / (2 * mTq0_s + mTimeStep);
254 mCd_s = (2 * mTq0_s - mTimeStep) / (2 * mTq0_s + mTimeStep);
255 mAq_s = (-mTimeStep * Zq_s + mTimeStep * mAq_t) / (2 * mTd0_s + mTimeStep);
256 mBq_s = (mTimeStep * mBq_t + mTimeStep) / (2 * mTd0_s + mTimeStep);
257 mCq_s = (2 * mTd0_s - mTimeStep) / (2 * mTd0_s + mTimeStep);
258 mDq_s = (mTimeStep * mDq_t + Tf * mTimeStep) / (2 * mTd0_s + mTimeStep);
259 }
260}
261
262template <typename VarType>
264 VarType>::calculateResistanceMatrixConstants() {
265 if (mSGOrder == SGOrder::SG3Order) {
266 mA = -mLq;
267 mB = mLd_t - mAq_t;
268 }
269 if (mSGOrder == SGOrder::SG4Order) {
270 mA = -mAd_t - mLq_t;
271 mB = mLd_t - mAq_t;
272 }
273 if (mSGOrder == SGOrder::SG5Order || mSGOrder == SGOrder::SG6aOrder ||
274 mSGOrder == SGOrder::SG6bOrder) {
275 mA = -mLq_s - mAd_s;
276 mB = mLd_s - mAq_s;
277 }
278}
279
280template <typename VarType>
281void Base::ReducedOrderSynchronGenerator<VarType>::setInitialValues(
282 Complex initComplexElectricalPower, Real initMechanicalPower,
283 Complex initTerminalVoltage) {
284
285 mInitElecPower = initComplexElectricalPower;
286 mInitMechPower = initMechanicalPower;
287
288 mInitVoltage = initTerminalVoltage;
289 mInitVoltageAngle = Math::phase(mInitVoltage);
290
291 mInitCurrent = std::conj(mInitElecPower / mInitVoltage);
292 mInitCurrentAngle = Math::phase(mInitCurrent);
293
294 mInitVoltage = mInitVoltage / mBase_V_RMS;
295 mInitCurrent = mInitCurrent / mBase_I_RMS;
296
297 mInitialValuesSet = true;
298
299 SPDLOG_LOGGER_DEBUG(this->mSLog,
300 "\n--- Set initial values ---"
301 "\nInitial active power: {:}W = {:} p.u."
302 "\nInitial reactive power W: {:}W = {:} p.u."
303 "\nInitial terminal voltage magnitude: {:} p.u."
304 "\nInitial terminal voltage phase: {:} rad = ({:}°)"
305 "\nInitial current magnitude: {:} p.u."
306 "\nInitial current phase: {:} rad = ({:}°)"
307 "\n--- Set initial values finished ---\n",
308
309 mInitElecPower.real(), mInitElecPower.real() / mNomPower,
310 mInitElecPower.imag(), mInitElecPower.imag() / mNomPower,
311 Math::abs(mInitVoltage), Math::phase(mInitVoltage),
312 Math::phaseDeg(mInitVoltage), Math::abs(mInitCurrent),
313 Math::phase(mInitCurrent), Math::phaseDeg(mInitCurrent));
314 this->mSLog->flush();
315}
316
317template <>
319 Real frequency) {
320
321 this->updateMatrixNodeIndices();
322
323 if (!mInitialValuesSet)
324 this->setInitialValues(-this->terminal(0)->singlePower(),
325 -this->terminal(0)->singlePower().real(),
326 this->initialSingleVoltage(0));
327
328 // Initialize mechanical torque
329 **mMechTorque = mInitMechPower / mNomPower;
330 mMechTorque_prev = **mMechTorque;
331
332 // calculate steady state machine emf (i.e. voltage behind synchronous reactance)
333 Complex Eq0 = mInitVoltage + Complex(0, mLq) * mInitCurrent;
334
335 // Load angle
336 **mDelta = Math::phase(Eq0);
337
338 // convert currrents to dq reference frame
339 (**mIdq0)(0, 0) = Math::abs(mInitCurrent) * sin(**mDelta - mInitCurrentAngle);
340 (**mIdq0)(1, 0) = Math::abs(mInitCurrent) * cos(**mDelta - mInitCurrentAngle);
341
342 // convert voltages to dq reference frame
343 (**mVdq0)(0, 0) = Math::abs(mInitVoltage) * sin(**mDelta - mInitVoltageAngle);
344 (**mVdq0)(1, 0) = Math::abs(mInitVoltage) * cos(**mDelta - mInitVoltageAngle);
345
346 // calculate Ef
347 **mEf = Math::abs(Eq0) + (mLd - mLq) * (**mIdq0)(0, 0);
348 mEf_prev = **mEf;
349
350 // Initialize controllers
351 if (mHasExciter) {
352 mExciter->initialize(Math::abs(mInitVoltage), **mEf);
353 }
354 if (mHasTurbineGovernor) {
355 mTurbineGovernor->initialize(**mMechTorque);
356 }
357
358 // initial electrical torque
359 **mElecTorque =
360 (**mVdq0)(0, 0) * (**mIdq0)(0, 0) + (**mVdq0)(1, 0) * (**mIdq0)(1, 0);
361
362 // Initialize omega mech with nominal system frequency
363 **mOmMech = mNomOmega / mBase_OmMech;
364
365 // initialize theta and calculate transform matrix
366 **mThetaMech = **mDelta - PI / 2.;
367
368 // set initial interface current
369 (**mIntfCurrent)(0, 0) = (mInitCurrent * mBase_I).real();
370 (**mIntfCurrent)(1, 0) = (mInitCurrent * mBase_I * SHIFT_TO_PHASE_B).real();
371 (**mIntfCurrent)(2, 0) = (mInitCurrent * mBase_I * SHIFT_TO_PHASE_C).real();
372
373 // set initial interface voltage
374 (**mIntfVoltage)(0, 0) = (mInitVoltage * mBase_V).real();
375 (**mIntfVoltage)(1, 0) = (mInitVoltage * mBase_V * SHIFT_TO_PHASE_B).real();
376 (**mIntfVoltage)(2, 0) = (mInitVoltage * mBase_V * SHIFT_TO_PHASE_C).real();
377
378 SPDLOG_LOGGER_DEBUG(this->mSLog,
379 "\n--- Initialization from power flow ---"
380 "\nInitial Vd (per unit): {:f}"
381 "\nInitial Vq (per unit): {:f}"
382 "\nInitial Id (per unit): {:f}"
383 "\nInitial Iq (per unit): {:f}"
384 "\nInitial Ef (per unit): {:f}"
385 "\nInitial mechanical torque (per unit): {:f}"
386 "\nInitial electrical torque (per unit): {:f}"
387 "\nInitial initial mechanical theta (per unit): {:f}"
388 "\nInitial delta (per unit): {:f} (= {:f}°)"
389 "\n--- Initialization from power flow finished ---",
390
391 (**mVdq0)(0, 0), (**mVdq0)(1, 0), (**mIdq0)(0, 0),
392 (**mIdq0)(1, 0), **mEf, **mMechTorque, **mElecTorque,
393 **mThetaMech, **mDelta, **mDelta * 180 / PI);
394 this->mSLog->flush();
395}
396
397template <>
399 Complex>::initializeFromNodesAndTerminals(Real frequency) {
400
401 this->updateMatrixNodeIndices();
402
403 if (!mInitialValuesSet)
404 this->setInitialValues(-this->terminal(0)->singlePower(),
405 -this->terminal(0)->singlePower().real(),
406 this->initialSingleVoltage(0));
407
408 // Initialize mechanical torque
409 **mMechTorque = mInitMechPower / mNomPower;
410 mMechTorque_prev = **mMechTorque;
411
412 // calculate steady state machine emf (i.e. voltage behind synchronous reactance)
413 Complex Eq0 = mInitVoltage + Complex(0, mLq) * mInitCurrent;
414
415 // Load angle
416 **mDelta = Math::phase(Eq0);
417
418 // convert currrents to dq reference frame
419 (**mIdq)(0, 0) = Math::abs(mInitCurrent) * sin(**mDelta - mInitCurrentAngle);
420 (**mIdq)(1, 0) = Math::abs(mInitCurrent) * cos(**mDelta - mInitCurrentAngle);
421
422 // convert voltages to dq reference frame
423 (**mVdq)(0, 0) = Math::abs(mInitVoltage) * sin(**mDelta - mInitVoltageAngle);
424 (**mVdq)(1, 0) = Math::abs(mInitVoltage) * cos(**mDelta - mInitVoltageAngle);
425
426 // calculate Ef
427 **mEf = Math::abs(Eq0) + (mLd - mLq) * (**mIdq)(0, 0);
428 mEf_prev = **mEf;
429
430 // Initialize controllers
431 if (mHasExciter) {
432 mExciter->initialize(Math::abs(mInitVoltage), **mEf);
433 }
434 if (mHasTurbineGovernor) {
435 mTurbineGovernor->initialize(**mMechTorque);
436 }
437
438 // initial electrical torque
439 **mElecTorque =
440 (**mVdq)(0, 0) * (**mIdq)(0, 0) + (**mVdq)(1, 0) * (**mIdq)(1, 0);
441
442 // Initialize omega mech with nominal system frequency
443 **mOmMech = mNomOmega / mBase_OmMech;
444
445 // initialize theta and calculate transform matrix
446 **mThetaMech = **mDelta - PI / 2.;
447
448 // set initial value of current
449 (**mIntfCurrent)(0, 0) = mInitCurrent * mBase_I_RMS;
450
451 // set initial interface voltage
452 (**mIntfVoltage)(0, 0) = mInitVoltage * mBase_V_RMS;
453
454 SPDLOG_LOGGER_DEBUG(this->mSLog,
455 "\n--- Initialization from power flow ---"
456 "\nInitial Vd (per unit): {:f}"
457 "\nInitial Vq (per unit): {:f}"
458 "\nInitial Id (per unit): {:f}"
459 "\nInitial Iq (per unit): {:f}"
460 "\nInitial Ef (per unit): {:f}"
461 "\nInitial mechanical torque (per unit): {:f}"
462 "\nInitial electrical torque (per unit): {:f}"
463 "\nInitial initial mechanical theta (per unit): {:f}"
464 "\nInitial delta (per unit): {:f} (= {:f}°)"
465 "\n--- Initialization from power flow finished ---",
466
467 (**mVdq)(0, 0), (**mVdq)(1, 0), (**mIdq)(0, 0),
468 (**mIdq)(1, 0), **mEf, **mMechTorque, **mElecTorque,
469 **mThetaMech, **mDelta, **mDelta * 180 / PI);
470 this->mSLog->flush();
471}
472
473template <typename VarType>
474void Base::ReducedOrderSynchronGenerator<VarType>::mnaCompInitialize(
475 Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) {
476
477 this->updateMatrixNodeIndices();
478 mTimeStep = timeStep;
479 calculateVBRconstants();
480 calculateResistanceMatrixConstants();
481 initializeResistanceMatrix();
482 specificInitialization();
483}
484
485template <>
486void Base::ReducedOrderSynchronGenerator<Complex>::mnaCompPreStep(
487 Real time, Int timeStepCount) {
488 mSimTime = time;
489
490 // update controller variables
491 if (mHasExciter) {
492 mEf_prev = **mEf;
493 **mEf = mExciter->step((**mVdq)(0, 0), (**mVdq)(1, 0), mTimeStep);
494 }
495 if (mHasTurbineGovernor) {
496 mMechTorque_prev = **mMechTorque;
497 **mMechTorque = mTurbineGovernor->step(**mOmMech, mTimeStep);
498 }
499
500 // calculate mechanical variables at t=k+1 with forward euler
501 **mElecTorque =
502 (**mVdq)(0, 0) * (**mIdq)(0, 0) + (**mVdq)(1, 0) * (**mIdq)(1, 0);
503 **mOmMech = **mOmMech +
504 mTimeStep * (1. / (2. * mH) * (mMechTorque_prev - **mElecTorque));
505 **mThetaMech = **mThetaMech + mTimeStep * (**mOmMech * mBase_OmMech);
506 **mDelta = **mDelta + mTimeStep * (**mOmMech - 1.) * mBase_OmMech;
507
508 // model specific calculation of electrical vars
509 stepInPerUnit();
510
511 // stamp model specific right side vector after calculation of electrical vars
512 (**mRightVector).setZero();
513 mnaCompApplyRightSideVectorStamp(**mRightVector);
514}
515
516template <>
517void Base::ReducedOrderSynchronGenerator<Real>::mnaCompPreStep(
518 Real time, Int timeStepCount) {
519 mSimTime = time;
520
521 // update controller variables
522 if (mHasExciter) {
523 mEf_prev = **mEf;
524 **mEf = mExciter->step((**mVdq0)(0, 0), (**mVdq0)(1, 0), mTimeStep);
525 }
526 if (mHasTurbineGovernor) {
527 mMechTorque_prev = **mMechTorque;
528 **mMechTorque = mTurbineGovernor->step(**mOmMech, mTimeStep);
529 }
530
531 // calculate mechanical variables at t=k+1 with forward euler
532 **mElecTorque =
533 ((**mVdq0)(0, 0) * (**mIdq0)(0, 0) + (**mVdq0)(1, 0) * (**mIdq0)(1, 0));
534 **mOmMech = **mOmMech +
535 mTimeStep * (1. / (2. * mH) * (mMechTorque_prev - **mElecTorque));
536 **mThetaMech = **mThetaMech + mTimeStep * (**mOmMech * mBase_OmMech);
537 **mDelta = **mDelta + mTimeStep * (**mOmMech - 1.) * mBase_OmMech;
538
539 // model specific calculation of electrical vars
540 stepInPerUnit();
541
542 // stamp model specific right side vector after calculation of electrical vars
543 (**mRightVector).setZero();
544 mnaCompApplyRightSideVectorStamp(**mRightVector);
545}
546
547template <typename VarType>
549 mnaCompAddPreStepDependencies(AttributeBase::List &prevStepDependencies,
550 AttributeBase::List &attributeDependencies,
551 AttributeBase::List &modifiedAttributes) {
552 modifiedAttributes.push_back(mRightVector);
553 prevStepDependencies.push_back(mIntfVoltage);
554}
555
556template <typename VarType>
557void Base::ReducedOrderSynchronGenerator<VarType>::mnaCompPreStep(
558 Real time, Int timeStepCount) {
559 mSimTime = time;
560 stepInPerUnit();
561 (**mRightVector).setZero();
562 mnaCompApplyRightSideVectorStamp(**mRightVector);
563}
564
565template <typename VarType>
567 mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies,
568 AttributeBase::List &attributeDependencies,
569 AttributeBase::List &modifiedAttributes,
570 Attribute<Matrix>::Ptr &leftVector) {
571 attributeDependencies.push_back(leftVector);
572 modifiedAttributes.push_back(mIntfVoltage);
573}
574
575template <typename VarType>
576void Base::ReducedOrderSynchronGenerator<VarType>::mnaCompPostStep(
577 Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
578 mnaCompPostStep(**leftVector);
579}
580
581template <typename VarType>
583 Real Te, Real Ke,
584 Real Tf, Real Kf,
585 Real Tr) {
586 mExciter = Signal::Exciter::make(**this->mName + "_Exciter", this->mLogLevel);
587 mExciter->setParameters(Ta, Ka, Te, Ke, Tf, Kf, Tr);
588 mHasExciter = true;
589}
590
591template <typename VarType>
593 std::shared_ptr<Signal::Exciter> exciter) {
594 mExciter = exciter;
595 mHasExciter = true;
596}
597
598template <typename VarType>
600 Real T3, Real T4, Real T5, Real Tc, Real Ts, Real R, Real Pmin, Real Pmax,
601 Real OmRef, Real TmRef) {
602 mTurbineGovernor = Signal::TurbineGovernorType1::make(
603 **this->mName + "_TurbineGovernor", this->mLogLevel);
604 mTurbineGovernor->setParameters(T3, T4, T5, Tc, Ts, R, Pmin, Pmax, OmRef);
605 mTurbineGovernor->initialize(TmRef);
606 mHasTurbineGovernor = true;
607}
608
609template <typename VarType>
611 std::shared_ptr<Signal::TurbineGovernorType1> turbineGovernor) {
612 mTurbineGovernor = turbineGovernor;
613 mHasTurbineGovernor = true;
614}
615
616// Declare specializations to move definitions to .cpp
void addExciter(Real Ta, Real Ka, Real Te, Real Ke, Real Tf, Real Kf, Real Tr)
Add voltage regulator and exciter.
Real mTd0_s
Subtransient time constant of d-axis.
void setBaseParameters(Real nomPower, Real nomVolt, Real nomFreq)
Bool mHasTurbineGovernor
Determines if Turbine and Governor are activated.
void setOperationalParametersPerUnit(Real nomPower, Real nomVolt, Real nomFreq, Real H, Real Ld, Real Lq, Real L0, Real Ld_t, Real Td0_t)
Initialization for 3 Order SynGen.
std::shared_ptr< Signal::Exciter > mExciter
Signal component modelling voltage regulator and exciter.
void mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
Add MNA post step dependencies.
virtual void setModelAsNortonSource(Bool modelAsCurrentSource)
Real mTaa
d-axis additional leakage time constant
void initializeFromNodesAndTerminals(Real frequency) override
Initializes Component variables according to power flow data stored in Nodes.
Real mTq0_s
Subtransient time constant of q-axis.
void mnaCompAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
Add MNA pre step dependencies.
void addGovernor(Real T3, Real T4, Real T5, Real Tc, Real Ts, Real R, Real Pmin, Real Pmax, Real OmRef, Real TmRef)
Add governor and turbine.
Bool mHasExciter
Determines if Exciter is activated.
std::shared_ptr< Signal::TurbineGovernorType1 > mTurbineGovernor
Signal component modelling governor control and steam turbine.
const Attribute< String >::Ptr mName
Human readable name.
Base class for all MNA components that are transmitting power.
Attribute< Matrix >::Ptr mRightVector
const Attribute< MatrixVar< VarType > >::Ptr mIntfVoltage
Voltage between terminals.
Logger::Level mLogLevel
Component logger control for internal variables.
Logger::Log mSLog
Component logger.