DPsim
Loading...
Searching...
No Matches
Base_SynchronGenerator.cpp
Go to the documentation of this file.
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
11
12using namespace CPS;
13
15 Real nomFreq) {
16 mNomPower = nomPower;
17 mNomVolt = nomVolt;
18 mNomFreq = nomFreq;
19 mNomOmega = nomFreq * 2 * PI;
20
21 // Set base stator values
22 mBase_V_RMS = mNomVolt / sqrt(3);
23 mBase_V = mBase_V_RMS * sqrt(2);
25 mBase_I = mBase_I_RMS * sqrt(2);
27
31
34}
35
37 Real nomFreq,
38 Real nomFieldCur) {
39 mNomFieldCur = nomFieldCur;
40 Base::SynchronGenerator::setBaseParameters(nomPower, nomVolt, nomFreq);
41}
42
44 Real nomPower, Real nomVolt, Real nomFreq, Real nomFieldCur, Int poleNumber,
45 Real Rs, Real Ll, Real Lmd, Real Lmq, Real Rfd, Real Llfd, Real Rkd,
46 Real Llkd, Real Rkq1, Real Llkq1, Real Rkq2, Real Llkq2, Real inertia) {
49
50 setBaseParameters(nomPower, nomVolt, nomFreq, nomFieldCur);
51 setAndApplyFundamentalPerUnitParameters(poleNumber, Rs, Ll, Lmd, Lmq, Rfd,
52 Llfd, Rkd, Llkd, Rkq1, Llkq1, Rkq2,
53 Llkq2, inertia);
54}
55
57 Real nomPower, Real nomVolt, Real nomFreq, Int poleNumber, Real nomFieldCur,
58 Real Rs, Real Ld, Real Lq, Real Ld_t, Real Lq_t, Real Ld_s, Real Lq_s,
59 Real Ll, Real Td0_t, Real Tq0_t, Real Td0_s, Real Tq0_s, Real inertia) {
62
63 setBaseParameters(nomPower, nomVolt, nomFreq, nomFieldCur);
64 setOperationalPerUnitParameters(poleNumber, inertia, Rs, Ld, Lq, Ll, Ld_t,
65 Lq_t, Ld_s, Lq_s, Td0_t, Tq0_t, Td0_s, Tq0_s);
67}
68
70 Int poleNumber, Real inertia, Real Rs, Real Ld, Real Lq, Real Ll, Real Ld_t,
71 Real Lq_t, Real Ld_s, Real Lq_s, Real Td0_t, Real Tq0_t, Real Td0_s,
72 Real Tq0_s) {
73 mPoleNumber = poleNumber;
74 **mInertia = inertia;
75
76 **mRs = Rs;
77 **mLl = Ll;
78 **mLd = Ld;
79 **mLq = Lq;
80
81 **mLd_t = Ld_t;
82 **mLq_t = Lq_t;
83 **mLd_s = Ld_s;
84 **mLq_s = Lq_s;
85 **mTd0_t = Td0_t;
86 **mTq0_t = Tq0_t;
87 **mTd0_s = Td0_s;
88 **mTq0_s = Tq0_s;
89}
90
92 Int poleNumber, Real Rs, Real Ll, Real Lmd, Real Lmq, Real Rfd, Real Llfd,
93 Real Rkd, Real Llkd, Real Rkq1, Real Llkq1, Real Rkq2, Real Llkq2,
94 Real inertia) {
96 poleNumber, Rs, Ll, Lmd, Lmq, Rfd, Llfd, Rkd, Llkd, Rkq1, Llkq1, Rkq2,
97 Llkq2, inertia);
98
100}
101
103 Int poleNumber, Real Rs, Real Ll, Real Lmd, Real Lmq, Real Rfd, Real Llfd,
104 Real Rkd, Real Llkd, Real Rkq1, Real Llkq1, Real Rkq2, Real Llkq2,
105 Real inertia) {
106 // PoleNumber otherwise not set but currently not used in SynchronGeneratorDQ
107 mPoleNumber = poleNumber;
108 **mInertia = inertia;
109
110 **mRs = Rs;
111 **mLl = Ll;
112 mLmd = Lmd;
113 mLmq = Lmq;
114
115 mRfd = Rfd;
116 mLlfd = Llfd;
117 mRkd = Rkd;
118 mLlkd = Llkd;
119 mRkq1 = Rkq1;
120 mLlkq1 = Llkq1;
121 mRkq2 = Rkq2;
122 mLlkq2 = Llkq2;
123}
124
126 // derive further parameters
127 **mLd = **mLl + mLmd;
128 **mLq = **mLl + mLmq;
129 mLfd = mLlfd + mLmd;
130 mLkd = mLlkd + mLmd;
131 mLkq1 = mLlkq1 + mLmq;
132 mLkq2 = mLlkq2 + mLmq;
133
134 // base rotor values
139
140 // derive number of damping windings
141 if (mRkq2 == 0 && mLlkq2 == 0)
143 else
145
146 if (mNumDampingWindings == 1) {
147 mVsr = Matrix::Zero(6, 1);
148 mIsr = Matrix::Zero(6, 1);
149 mPsisr = Matrix::Zero(6, 1);
150 mInductanceMat = Matrix::Zero(6, 6);
151 mResistanceMat = Matrix::Zero(6, 6);
152
153 // Determinant of Lq(inductance matrix of q axis)
154 // Real detLq = -(mLl + mLmq)*(mLlkq1 + mLmq) + mLmq*mLmq;
155 // Determinant of Ld (inductance matrix of d axis)
156 // Real detLd = (mLmd + mLl)*(-mLlfd*mLlkd - mLlfd*mLmd - mLmd*mLlkd) +
157 // mLmd*mLmd*(mLlfd + mLlkd);
158
159 mInductanceMat << **mLd, mLmd, mLmd, 0, 0, 0, mLmd, mLfd, mLmd, 0, 0, 0,
160 mLmd, mLmd, mLkd, 0, 0, 0, 0, 0, 0, **mLq, mLmq, 0, 0, 0, 0, mLmq,
161 mLkq1, 0, 0, 0, 0, 0, 0, **mLl;
162
163 mResistanceMat << **mRs, 0, 0, 0, 0, 0, 0, mRfd, 0, 0, 0, 0, 0, 0, mRkd, 0,
164 0, 0, 0, 0, 0, **mRs, 0, 0, 0, 0, 0, 0, mRkq1, 0, 0, 0, 0, 0, 0, **mRs;
165
166 // Compute inverse Inductance Matrix:
168 } else {
169 mVsr = Matrix::Zero(7, 1);
170 mIsr = Matrix::Zero(7, 1);
171 mPsisr = Matrix::Zero(7, 1);
172 mInductanceMat = Matrix::Zero(7, 7);
173 mResistanceMat = Matrix::Zero(7, 7);
174
175 // Determinant of Lq(inductance matrix of q axis)
176 // Real detLq = -mLmq*mLlkq2*(mLlkq1 + mLl) - mLl*mLlkq1*(mLlkq2 + mLmq);
177 // Determinant of Ld (inductance matrix of d axis)
178 // Real detLd = (mLmd + mLl)*(-mLlfd*mLlkd - mLlfd*mLmd - mLmd*mLlkd) +
179 // mLmd*mLmd*(mLlfd + mLlkd);
180
181 mInductanceMat << **mLd, mLmd, mLmd, 0, 0, 0, 0, mLmd, mLfd, mLmd, 0, 0, 0,
182 0, mLmd, mLmd, mLkd, 0, 0, 0, 0, 0, 0, 0, **mLq, mLmq, mLmq, 0, 0, 0, 0,
183 mLmq, mLkq1, mLmq, 0, 0, 0, 0, mLmq, mLmq, mLkq2, 0, 0, 0, 0, 0, 0, 0,
184 **mLl;
185
186 mResistanceMat << **mRs, 0, 0, 0, 0, 0, 0, 0, mRfd, 0, 0, 0, 0, 0, 0, 0,
187 mRkd, 0, 0, 0, 0, 0, 0, 0, **mRs, 0, 0, 0, 0, 0, 0, 0, mRkq1, 0, 0, 0,
188 0, 0, 0, 0, mRkq2, 0, 0, 0, 0, 0, 0, 0, **mRs;
189
190 // Compute inverse Inductance Matrix:
192 }
193}
194
196 mLmd = **mLd - **mLl;
197 mLmq = **mLq - **mLl;
198
199 mLlfd = mLmd * (**mLd_t - **mLl) / (mLmd - **mLd_t + **mLl);
200 mLlkq1 = mLmq * (**mLq_t - **mLl) / (mLmq - **mLq_t + **mLl);
201
202 mLlkd = mLmd * mLlfd * (**mLd_s - **mLl) /
203 (mLlfd * mLmd - (mLmd + mLlfd) * (**mLd_s - **mLl));
204 mLlkq2 = mLmq * mLlkq1 * (**mLq_s - **mLl) /
205 (mLlkq1 * mLmq - (mLmq + mLlkq1) * (**mLq_s - **mLl));
206
207 mRfd = (mLmd + mLlfd) / (**mTd0_t * mNomOmega);
208 mRkd = (1 / (**mTd0_s * mNomOmega)) * (mLlkd + mLmd * mLlfd / (mLmd + mLlfd));
209 mRkq1 = (mLmq + mLlkq1) / (**mTq0_t * mNomOmega);
210 mRkq2 =
211 (1 / (**mTq0_s * mNomOmega)) * (mLlkq2 + mLmq * mLlkq1 / (mLmq + mLlkq1));
212
214}
215
217 Real initReactivePower,
218 Real initTerminalVolt,
219 Real initVoltAngle,
220 Real initMechPower) {
221 mInitElecPower = Complex(initActivePower, initReactivePower);
222 mInitTerminalVoltage = initTerminalVolt;
223 mInitVoltAngle = initVoltAngle;
224 mInitMechPower = initMechPower;
225 mInitialValuesSet = true;
226}
227
229 // Power in per unit
230 Real init_P = mInitElecPower.real() / mNomPower;
231 Real init_Q = mInitElecPower.imag() / mNomPower;
232 Real init_S_abs = sqrt(pow(init_P, 2.) + pow(init_Q, 2.));
233 // Complex init_S = mInitElecPower;
234 // Terminal voltage in pu
235 Real init_vt_abs = mInitTerminalVoltage / mBase_V;
236 // Complex init_vt = Complex(mInitTerminalVoltage*cos(mInitVoltAngle),
237 // mInitTerminalVoltage*sin(mInitVoltAngle));
238 Real init_it_abs = init_S_abs / init_vt_abs;
239 // Complex init_it = std::conj( init_S / init_vt );
240 // Power factor
241 Real init_pf = acos(init_P / init_S_abs);
242 // Load angle
243 Real init_delta = atan(((mLmq + **mLl) * init_it_abs * cos(init_pf) -
244 **mRs * init_it_abs * sin(init_pf)) /
245 (init_vt_abs + **mRs * init_it_abs * cos(init_pf) +
246 (mLmq + **mLl) * init_it_abs * sin(init_pf)));
247 // Real init_delta_deg = init_delta / PI * 180;
248
249 // Electrical torque
250 // Real init_Te = init_P + **mRs * pow(init_it, 2.);
251
252 // dq stator voltages and currents
253 Real init_vd = init_vt_abs * sin(init_delta);
254 Real init_vq = init_vt_abs * cos(init_delta);
255 Real init_id = init_it_abs * sin(init_delta + init_pf);
256 Real init_iq = init_it_abs * cos(init_delta + init_pf);
257
258 // Rotor voltage and current
259 Real init_ifd = (init_vq + **mRs * init_iq + (mLmd + **mLl) * init_id) / mLmd;
260 Real init_vfd = mRfd * init_ifd;
261
262 // Flux linkages
263 Real init_psid = init_vq + **mRs * init_iq;
264 Real init_psiq = -init_vd - **mRs * init_id;
265 Real init_psifd = mLfd * init_ifd - mLmd * init_id;
266 Real init_psikd = mLmd * (init_ifd - init_id);
267 Real init_psiq1 = -mLmq * init_iq;
268 Real init_psiq2 = -mLmq * init_iq;
269
270 // Initialize mechanical variables
271 **mOmMech = 1;
273 **mMechTorque = **mMechPower / 1;
274 mThetaMech = mInitVoltAngle + init_delta - PI / 2.;
275 **mDelta = init_delta;
276
277 if (mNumDampingWindings == 2) {
278 mVsr << init_vd, init_vfd, 0, init_vq, 0, 0, 0;
279 mIsr << -init_id, init_ifd, 0, -init_iq, 0, 0, 0;
280 mPsisr << init_psid, init_psifd, init_psikd, init_psiq, init_psiq1,
281 init_psiq2, 0;
282 } else {
283 mVsr << init_vd, init_vfd, 0, init_vq, 0, 0;
284 mIsr << -init_id, init_ifd, 0, -init_iq, 0, 0;
285 mPsisr << init_psid, init_psifd, init_psikd, init_psiq, init_psiq1, 0;
286 }
287
288 if (mNumDampingWindings == 2) {
289 mVsr << init_vd, init_vfd, 0, init_vq, 0, 0, 0;
290 mIsr << -init_id, init_ifd, 0, -init_iq, 0, 0, 0;
291 mPsisr << init_psid, init_psifd, init_psikd, init_psiq, init_psiq1,
292 init_psiq2, 0;
293 } else {
294 mVsr << init_vd, init_vfd, 0, init_vq, 0, 0;
295 mIsr << -init_id, init_ifd, 0, -init_iq, 0, 0;
296 mPsisr << init_psid, init_psifd, init_psikd, init_psiq, init_psiq1, 0;
297 }
298
299 **mElecTorque = (mPsisr(3, 0) * mIsr(0, 0) - mPsisr(0, 0) * mIsr(3, 0));
300
301 // Initialize controllers
302 if (mHasExciter) {
303 // Note: field voltage scaled by Lmd/Rfd to transform from synchronous generator pu system
304 // to the exciter pu system
305 mExciter->initializeStates(init_vt_abs, (mLmd / mRfd) * init_vfd);
306 }
308 mGovernor->initializeStates(**mMechTorque);
309 mTurbine->initializeStates(**mMechTorque);
310 }
311}
312
314 if (mNumDampingWindings == 2) {
315 mLad = 1. / (1. / mLmd + 1. / **mLl + 1. / mLlfd + 1. / mLlkd);
316 mLaq = 1. / (1. / mLmq + 1. / **mLl + 1. / mLlkq1 + 1. / mLlkq2);
317
318 mPsisr = Matrix::Zero(7, 1);
319
320 mOmegaFluxMat = Matrix::Zero(7, 7);
321 mOmegaFluxMat << 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
322 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
323 0, 0, 0, 0, 0;
324
326 Matrix::Zero(7, 7); // order of lambdas: ds; fd; kd; qs; kq1; kq2; 0s
327 mFluxStateSpaceMat << **mRs / **mLl * mLad / **mLl - **mRs / **mLl,
328 **mRs / **mLl * mLad / mLlfd, **mRs / **mLl * mLad / mLlkd, 0, 0, 0, 0,
329 mRfd / mLlfd * mLad / **mLl, mRfd / mLlfd * mLad / mLlfd - mRfd / mLlfd,
330 mRfd / mLlfd * mLad / mLlkd, 0, 0, 0, 0, mRkd / mLlkd * mLad / **mLl,
331 mRkd / mLlkd * mLad / mLlfd, mRkd / mLlkd * mLad / mLlkd - mRkd / mLlkd,
332 0, 0, 0, 0, 0, 0, 0, **mRs / **mLl * mLaq / **mLl - **mRs / **mLl,
333 **mRs / **mLl * mLaq / mLlkq1, **mRs / **mLl * mLaq / mLlkq2, 0, 0, 0,
334 0, mRkq1 / mLlkq1 * mLaq / **mLl,
336 mRkq1 / mLlkq1 * mLaq / mLlkq2, 0, 0, 0, 0,
337 mRkq2 / mLlkq2 * mLaq / **mLl, mRkq2 / mLlkq2 * mLaq / mLlkq1,
338 mRkq2 / mLlkq2 * mLaq / mLlkq2 - mRkq2 / mLlkq2, 0, 0, 0, 0, 0, 0, 0,
339 -**mRs / **mLl;
340
342 Matrix::Zero(7, 7); // need for electric torque id, iq ->1st and 4th row
343 mFluxToCurrentMat << 1. / **mLl - mLad / **mLl / **mLl,
344 -mLad / mLlfd / **mLl, -mLad / mLlkd / **mLl, 0, 0, 0, 0,
345 -mLad / **mLl / mLlfd, 1. / mLlfd - mLad / mLlfd / mLlfd,
346 -mLad / mLlkd / mLlfd, 0, 0, 0, 0, -mLad / **mLl / mLlkd,
347 -mLad / mLlfd / mLlkd, 1. / mLlkd - mLad / mLlkd / mLlkd, 0, 0, 0, 0, 0,
348 0, 0, 1. / **mLl - mLaq / **mLl / **mLl, -mLaq / mLlkq1 / **mLl,
349 -mLaq / mLlkq2 / **mLl, 0, 0, 0, 0, -mLaq / **mLl / mLlkq1,
350 1. / mLlkq1 - mLaq / mLlkq1 / mLlkq1, -mLaq / mLlkq2 / mLlkq1, 0, 0, 0,
351 0, -mLaq / **mLl / mLlkq2, -mLaq / mLlkq1 / mLlkq2,
352 1. / mLlkq2 - mLaq / mLlkq2 / mLlkq2, 0, 0, 0, 0, 0, 0, 0, 1. / **mLl;
353 } else {
354 mLad = 1. / (1. / mLmd + 1. / **mLl + 1. / mLlfd + 1. / mLlkd);
355 mLaq = 1. / (1. / mLmq + 1. / **mLl + 1. / mLlkq1);
356
357 mPsisr = Matrix::Zero(6, 1);
358
359 mOmegaFluxMat = Matrix::Zero(6, 6);
360 mOmegaFluxMat << 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1,
361 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
362
363 mFluxStateSpaceMat = Matrix::Zero(6, 6);
364 mFluxStateSpaceMat << // same order as above; only without kq2
365 **mRs / **mLl * mLad / **mLl - **mRs / **mLl,
366 **mRs / **mLl * mLad / mLlfd, **mRs / **mLl * mLad / mLlkd, 0, 0, 0,
367 mRfd / mLlfd * mLad / **mLl, mRfd / mLlfd * mLad / mLlfd - mRfd / mLlfd,
368 mRfd / mLlfd * mLad / mLlkd, 0, 0, 0, mRkd / mLlkd * mLad / **mLl,
369 mRkd / mLlkd * mLad / mLlfd, mRkd / mLlkd * mLad / mLlkd - mRkd / mLlkd,
370 0, 0, 0, 0, 0, 0, **mRs / **mLl * mLaq / **mLl - **mRs / **mLl,
371 **mRs / **mLl * mLaq / mLlkq1, 0, 0, 0, 0,
372 mRkq1 / mLlkq1 * mLaq / **mLl,
373 mRkq1 / mLlkq1 * mLaq / mLlkq1 - mRkq1 / mLlkq1, 0, 0, 0, 0, 0, 0,
374 -**mRs / **mLl;
375
376 mFluxToCurrentMat = Matrix::Zero(6, 6);
377 mFluxToCurrentMat << 1. / **mLl - mLad / **mLl / **mLl,
378 -mLad / mLlfd / **mLl, -mLad / mLlkd / **mLl, 0, 0, 0,
379 -mLad / **mLl / mLlfd, 1. / mLlfd - mLad / mLlfd / mLlfd,
380 -mLad / mLlkd / mLlfd, 0, 0, 0, -mLad / **mLl / mLlkd,
381 -mLad / mLlfd / mLlkd, 1. / mLlkd - mLad / mLlkd / mLlkd, 0, 0, 0, 0, 0,
382 0, 1. / **mLl - mLaq / **mLl / **mLl, -mLaq / mLlkq1 / **mLl, 0, 0, 0,
383 0, -mLaq / **mLl / mLlkq1, 1. / mLlkq1 - mLaq / mLlkq1 / mLlkq1, 0, 0,
384 0, 0, 0, 0, 1. / **mLl;
385 }
386}
387
389 Int polePairNumber) {
390 return J * 0.5 * omegaNominal * omegaNominal / polePairNumber;
391}
392
394 Real Ke, Real Tf, Real Kf,
395 Real Tr) {
396 // CLI-only logger
397 auto log = CPS::Logger::get("SynchronGenerator",
398 CPS::Logger::Level::off, // file level
399 CPS::Logger::Level::info); // CLI level
400
401 SPDLOG_LOGGER_WARN(
402 log, "Deprecated API addExciter(Ta,Ka,Te,Ke,Tf,Kf,Tr) called. "
403 "This overload will be removed in the future. "
404 "Please create an ExciterDC1Simp and parameters explicitly.");
405
406 auto params = std::make_shared<CPS::Signal::ExciterDC1SimpParameters>();
407 params->Ta = Ta;
408 params->Ka = Ka;
409 params->Tef = Te;
410 params->Kef = Ke;
411 params->Tf = Tf;
412 params->Kf = Kf;
413 params->Tr = Tr;
414
415 // Apply legacy amplifier limits for the deprecated path
416 params->MaxVa = 1.0;
417 params->MinVa = -0.9;
418
419 // No saturation by default
420 params->Aef = 0.0;
421 params->Bef = 0.0;
422
423 mExciter = std::make_shared<CPS::Signal::ExciterDC1Simp>(
424 "Exciter", CPS::Logger::Level::info);
425 mExciter->setParameters(params);
426 mHasExciter = true;
427
428 SPDLOG_LOGGER_INFO(
429 log,
430 "Attached ExciterDC1Simp (Ka={:.3g}, Ta={:.3g}, Kef={:.3g}, Tef={:.3g}, "
431 "Kf={:.3g}, Tf={:.3g}, Tr={:.3g}, MaxVa={:.3g}, MinVa={:.3g})",
432 params->Ka, params->Ta, params->Kef, params->Tef, params->Kf, params->Tf,
433 params->Tr, params->MaxVa, params->MinVa);
434}
435
437 Real Fb, Real Fc, Real K, Real Tsr,
438 Real Tsm, Real Tm_init, Real PmRef) {
439 auto log = CPS::Logger::get("SynchronGenerator", CPS::Logger::Level::off,
440 CPS::Logger::Level::info);
441 SPDLOG_LOGGER_WARN(
442 log, "addGovernor(Ta, Tb, ...) uses the legacy TurbineGovernor "
443 "model; prefer addGovernor(shared_ptr<TurbineGovernorType1>)");
445 CPS::Logger::Level::info);
446 mTurbineGovernor->setParameters(Ta, Tb, Tc, Fa, Fb, Fc, K, Tsr, Tsm);
447 mTurbineGovernor->initialize(PmRef, Tm_init);
448 mHasTurbineGovernor = true;
449}
450
452 std::shared_ptr<Signal::TurbineGovernorType1> turbineGovernor) {
453 auto log = CPS::Logger::get("SynchronGenerator", CPS::Logger::Level::off,
454 CPS::Logger::Level::info);
455 if (!turbineGovernor) {
456 SPDLOG_LOGGER_ERROR(log,
457 "addGovernor called with null TurbineGovernorType1");
458 return;
459 }
460 mTurbineGovernorType1 = turbineGovernor;
462}
463
465 Real Ts, Real R, Real Tmin, Real Tmax,
466 Real OmRef, Real TmRef) {
467 auto log = CPS::Logger::get("SynchronGenerator", CPS::Logger::Level::off,
468 CPS::Logger::Level::info);
469 SPDLOG_LOGGER_WARN(log,
470 "Scalar addGovernor(T3, T4, ...) is deprecated; create a "
471 "TurbineGovernorType1 and use "
472 "addGovernor(shared_ptr<TurbineGovernorType1>) instead");
473 auto gov = Signal::TurbineGovernorType1::make("TurbineGovernorType1",
474 CPS::Logger::Level::info);
475 gov->setParameters(T3, T4, T5, Tc, Ts, R, Tmin, Tmax, OmRef);
476 gov->initializeStates(TmRef);
477 addGovernor(gov);
478}
479
481 std::shared_ptr<Base::Governor> governor,
482 std::shared_ptr<Base::GovernorParameters> govParams,
483 std::shared_ptr<Base::Turbine> turbine,
484 std::shared_ptr<Base::TurbineParameters> turbineParams) {
485 auto log = CPS::Logger::get("SynchronGenerator", CPS::Logger::Level::off,
486 CPS::Logger::Level::info);
487 if (!governor) {
488 SPDLOG_LOGGER_ERROR(log, "addGovernorAndTurbine called with null governor");
489 return;
490 }
491 if (!turbine) {
492 SPDLOG_LOGGER_ERROR(log, "addGovernorAndTurbine called with null turbine");
493 return;
494 }
495 governor->setParameters(govParams);
496 turbine->setParameters(turbineParams);
497 mGovernor = governor;
498 mTurbine = turbine;
500}
501
503 std::shared_ptr<Base::Governor> governor,
504 std::shared_ptr<Base::Turbine> turbine) {
505 auto log = CPS::Logger::get("SynchronGenerator", CPS::Logger::Level::off,
506 CPS::Logger::Level::info);
507 if (!governor) {
508 SPDLOG_LOGGER_ERROR(log, "addGovernorAndTurbine called with null governor");
509 return;
510 }
511 if (!turbine) {
512 SPDLOG_LOGGER_ERROR(log, "addGovernorAndTurbine called with null turbine");
513 return;
514 }
515 mGovernor = governor;
516 mTurbine = turbine;
518}
519
521 std::shared_ptr<Base::PSS> pss,
522 std::shared_ptr<Base::PSSParameters> parameters) {
523 auto log = CPS::Logger::get("SynchronGenerator", CPS::Logger::Level::off,
524 CPS::Logger::Level::info);
525 if (!mHasExciter) {
526 SPDLOG_LOGGER_ERROR(
527 log, "Cannot attach PSS: no exciter present. Attach an exciter first.");
529 }
530 if (!pss) {
531 SPDLOG_LOGGER_ERROR(log,
532 "addPSS called with null PSS on SynchronGenerator");
533 return;
534 }
535 mPSS = pss;
536 mPSS->setParameters(parameters);
537 mHasPSS = true;
538}
539
540void Base::SynchronGenerator::addPSS(std::shared_ptr<Base::PSS> pss) {
541 auto log = CPS::Logger::get("SynchronGenerator", CPS::Logger::Level::off,
542 CPS::Logger::Level::info);
543 if (!mHasExciter) {
544 SPDLOG_LOGGER_ERROR(
545 log, "Cannot attach PSS: no exciter present. Attach an exciter first.");
547 }
548 if (!pss) {
549 SPDLOG_LOGGER_ERROR(log,
550 "addPSS called with null PSS on SynchronGenerator");
551 return;
552 }
553 mPSS = pss;
554 mHasPSS = true;
555}
Matrix mIsr
Vector of stator and rotor currents.
Real mNomFreq
nominal frequency fn [Hz]
Bool mHasTurbineGovernorType1
Determines if TurbineGovernorType1 is activated.
const Attribute< Real >::Ptr mLq_t
Transient q-axis inductance [H].
Real mRkq1
q-axis damper resistance 1 Rkq1 [Ohm]
Real mLmd
d-axis mutual inductance Lmd [H]
Real mBase_I
base stator current peak
Bool mHasExciter
Determines if Exciter is activated.
Real mLad
Inductance to calculate magnetizing flux linkage from winding flux linkages.
const Attribute< Real >::Ptr mMechTorque
mechanical torque
void setInitialValues(Real initActivePower, Real initReactivePower, Real initTerminalVolt, Real initVoltAngle, Real initMechPower)
const Attribute< Real >::Ptr mTq0_s
Subtransient time constant of q-axis [s].
Matrix mFluxToCurrentMat
Calculates currents from fluxes.
Real mLmq
q-axis mutual inductance Lmq [H]
void setOperationalPerUnitParameters(Int poleNumber, Real inertia, Real Rs, Real Ld, Real Lq, Real Ll, Real Ld_t, Real Lq_t, Real Ld_s, Real Lq_s, Real Td0_t, Real Tq0_t, Real Td0_s, Real Tq0_s)
std::shared_ptr< Base::Exciter > mExciter
Signal component modelling voltage regulator and exciter.
Real mLkq1
q-axis damper inductance 1 Lkq1 [H]
void addGovernorAndTurbine(std::shared_ptr< Base::Governor > governor, std::shared_ptr< Base::GovernorParameters > govParams, std::shared_ptr< Base::Turbine > turbine, std::shared_ptr< Base::TurbineParameters > turbineParams)
Add a modular governor + turbine pair (new API for SteamTurbineGovernor / SteamTurbine)
Real mBase_I_RMS
base stator current RMS
Real mLkd
d-axis damper inductance Lkd [H]
std::shared_ptr< Base::Turbine > mTurbine
Modular turbine (SteamTurbine / HydroTurbine)
Real mLlfd
field leakage inductance Llfd [H]
Bool mInitialValuesSet
Flag to remember when initial values are set.
Matrix mFluxStateSpaceMat
Flux state space matrix excluding omega term.
void addPSS(std::shared_ptr< Base::PSS > pss, std::shared_ptr< Base::PSSParameters > parameters)
Attach a PSS (initialised separately) to this generator.
const Attribute< Real >::Ptr mTq0_t
Transient time constant of q-axis [s].
Real mLlkd
d-axis damper leakage inductance Llkd [H]
const Attribute< Real >::Ptr mMechPower
mechanical Power Pm [W]
Real mNomVolt
nominal voltage Vn [V] (phase-to-phase RMS)
Matrix mVsr
Vector of stator and rotor voltages.
Matrix mPsisr
Vector of stator and rotor fluxes.
Real mBase_L
base stator inductance
const Attribute< Real >::Ptr mLq
q-axis inductance Lq [H]
Real mBase_Z
base stator impedance
const Attribute< Real >::Ptr mRs
stator resistance Rs [Ohm]
Matrix mResistanceMat
resistance matrix
Bool mHasGovernorAndTurbine
Determines if modular Governor + Turbine pair is activated.
Real mLkq2
q-axis damper inductance 2 Lkq2 [H]
std::shared_ptr< Base::PSS > mPSS
Power system stabilizer.
void addGovernor(Real Ta, Real Tb, Real Tc, Real Fa, Real Fb, Real Fc, Real K, Real Tsr, Real Tsm, Real Tm_init, Real PmRef)
std::shared_ptr< Signal::TurbineGovernor > mTurbineGovernor
Signal component modelling governor control and steam turbine (legacy)
Matrix mOmegaFluxMat
Omega-flux matrix for state space system.
Real mLlkq1
q-axis damper leakage inductance 1 Llkq1 [H]
void addExciter(std::shared_ptr< Base::Exciter > exciter, std::shared_ptr< Base::ExciterParameters > params)
Add voltage regulator and exciter.
const Attribute< Real >::Ptr mLq_s
Subtransient q-axis inductance [H].
std::shared_ptr< Base::Governor > mGovernor
Modular governor (SteamTurbineGovernor / HydroTurbineGovernor)
void setBaseAndFundamentalPerUnitParameters(Real nomPower, Real nomVolt, Real nomFreq, Real nomFieldCur, Int poleNumber, Real Rs, Real Ll, Real Lmd, Real Lmq, Real Rfd, Real Llfd, Real Rkd, Real Llkd, Real Rkq1, Real Llkq1, Real Rkq2, Real Llkq2, Real inertia)
Initializes the base and fundamental machine parameters in per unit.
Real mRkd
d-axis damper resistance Rkd [Ohm]
Real mNomFieldCur
nominal field current Ifn [A]
Real mRfd
field resistance Rfd [Ohm]
Real mNomOmega
nominal angular frequency wn [Hz]
Real mLaq
Inductance to calculate magnetizing flux linkage from winding flux linkages.
Real mBase_OmElec
base electrical angular frequency
const Attribute< Real >::Ptr mLl
leakage inductance Ll [H]
const Attribute< Real >::Ptr mTd0_s
Subtransient time constant of d-axis [s].
void setBaseParameters(Real nomPower, Real nomVolt, Real nomFreq)
Real mBase_OmMech
base mechanical angular frequency
Real mBase_Zfd
base field impedance
const Attribute< Real >::Ptr mDelta
rotor angle delta
Real mRkq2
q-axis damper resistance 2 Rkq2 [Ohm]
Real mLfd
field inductance Lfd [H]
const Attribute< Real >::Ptr mTd0_t
Transient time constant of d-axis [s].
Bool mHasPSS
Determines if PSS is activated.
void setAndApplyFundamentalPerUnitParameters(Int poleNumber, Real Rs, Real Ll, Real Lmd, Real Lmq, Real Rfd, Real Llfd, Real Rkd, Real Llkd, Real Rkq1, Real Llkq1, Real Rkq2, Real Llkq2, Real inertia)
Int mNumDampingWindings
Number of damping windings in q.
Real mBase_V
base stator voltage (phase-to-ground peak)
const Attribute< Real >::Ptr mLd
d-axis inductance Ld [H]
Matrix mInvInductanceMat
Inverse of the inductance matrix.
Real mNomPower
nominal power Pn [VA]
void setBaseAndOperationalPerUnitParameters(Real nomPower, Real nomVolt, Real nomFreq, Int poleNumber, Real nomFieldCur, Real Rs, Real Ld, Real Lq, Real Ld_t, Real Lq_t, Real Ld_s, Real Lq_s, Real Ll, Real Td0_t, Real Tq0_t, Real Td0_s, Real Tq0_s, Real inertia)
Real mBase_Lfd
base field inductance
const Attribute< Real >::Ptr mOmMech
rotor speed omega_r
Bool mHasTurbineGovernor
Determines if legacy TurbineGovernor is activated.
const Attribute< Real >::Ptr mLd_t
Transient d-axis inductance [H].
Real mLlkq2
q-axis damper leakage inductance 2 Llkq2 [H]
Real calcHfromJ(Real J, Real omegaNominal, Int polePairNumber)
const Attribute< Real >::Ptr mLd_s
Subtransient d-axis inductance [H].
std::shared_ptr< Signal::TurbineGovernorType1 > mTurbineGovernorType1
Signal component modelling governor control and steam turbine (TurbineGovernorType1)
Matrix mInductanceMat
Inductance matrix which is numerically equal to the reactance matrix in per unit.
const Attribute< Real >::Ptr mInertia
inertia constant H [s] for per unit or moment of inertia J [kg*m^2]
const Attribute< Real >::Ptr mElecTorque
electrical torque
Real mBase_V_RMS
base stator voltage (phase-to-ground RMS)
void setFundamentalPerUnitParameters(Int poleNumber, Real Rs, Real Ll, Real Lmd, Real Lmq, Real Rfd, Real Llfd, Real Rkd, Real Llkd, Real Rkq1, Real Llkq1, Real Rkq2, Real Llkq2, Real inertia)
static Log get(const std::string &name, Level filelevel=Level::info, Level clilevel=Level::off)
Definition Logger.cpp:139
static std::shared_ptr< TurbineGovernor > make(Args &&...args)
Definition PtrFactory.h:19
#define PI
Definition Definitions.h:43
double Real
Definition Definitions.h:62
int Int
Definition Definitions.h:61
std::complex< Real > Complex
Definition Definitions.h:63