DPsim
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 
11 using namespace CPS;
12 
13 template <>
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 
38 template <>
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");
62 }
63 
64 template <typename VarType>
66  Bool modelAsCurrentSource) {
67  mModelAsNortonSource = modelAsCurrentSource;
68 
69  if (mModelAsNortonSource) {
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  }
76 }
77 
78 template <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
91  mBase_V_RMS = mNomVolt;
92  mBase_V = mNomVolt / sqrt(3) * sqrt(2);
93  mBase_I_RMS = mNomPower / mBase_V_RMS;
94  mBase_I = mNomPower / ((3. / 2.) * mBase_V);
95  mBase_Z = mBase_V_RMS / mBase_I_RMS;
96  mBase_OmElec = mNomOmega;
97  mBase_OmMech = mBase_OmElec;
98  mBase_L = mBase_Z / mBase_OmElec;
99 }
100 
101 template <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 
130 template <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",
160  mH, mLd, mLq, mL0, mLd_t, mLq_t, mTd0_t, mTq0_t);
161 }
162 
163 template <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",
202  mH, mLd, mLq, mL0, mLd_t, mLq_t, mTd0_t, mTq0_t, mLd_s,
203  mLq_s, mTd0_s, mTq0_s, mTaa);
204 }
205 
206 template <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 
216 template <typename VarType>
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 
262 template <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 
280 template <typename VarType>
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 
317 template <>
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 
397 template <>
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 
473 template <typename VarType>
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 
485 template <>
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 
516 template <>
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 
547 template <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 
556 template <typename VarType>
558  Real time, Int timeStepCount) {
559  mSimTime = time;
560  stepInPerUnit();
561  (**mRightVector).setZero();
562  mnaCompApplyRightSideVectorStamp(**mRightVector);
563 }
564 
565 template <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 
575 template <typename VarType>
577  Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
578  mnaCompPostStep(**leftVector);
579 }
580 
581 template <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 
591 template <typename VarType>
593  std::shared_ptr<Signal::Exciter> exciter) {
594  mExciter = exciter;
595  mHasExciter = true;
596 }
597 
598 template <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 
609 template <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
Base class for all MNA components that are transmitting power.