9 #include <dpsim-models/Base/Base_SynchronGenerator.h>
13 void Base::SynchronGenerator::setBaseParameters(Real nomPower, Real nomVolt,
35 void Base::SynchronGenerator::setBaseParameters(Real nomPower, Real nomVolt,
38 mNomFieldCur = nomFieldCur;
39 Base::SynchronGenerator::setBaseParameters(nomPower, nomVolt, nomFreq);
43 Real nomPower, Real nomVolt, Real nomFreq, Real nomFieldCur, Int poleNumber,
44 Real Rs, Real Ll, Real Lmd, Real Lmq, Real Rfd, Real Llfd, Real Rkd,
45 Real Llkd, Real Rkq1, Real Llkq1, Real Rkq2, Real Llkq2, Real inertia) {
46 mParameterType = ParameterType::perUnit;
47 mNumericalMethod = NumericalMethod::Trapezoidal;
49 setBaseParameters(nomPower, nomVolt, nomFreq, nomFieldCur);
50 setAndApplyFundamentalPerUnitParameters(poleNumber, Rs, Ll, Lmd, Lmq, Rfd,
51 Llfd, Rkd, Llkd, Rkq1, Llkq1, Rkq2,
56 Real nomPower, Real nomVolt, Real nomFreq, Int poleNumber, Real nomFieldCur,
57 Real Rs, Real Ld, Real Lq, Real Ld_t, Real Lq_t, Real Ld_s, Real Lq_s,
58 Real Ll, Real Td0_t, Real Tq0_t, Real Td0_s, Real Tq0_s, Real inertia) {
59 mParameterType = ParameterType::perUnit;
60 mNumericalMethod = NumericalMethod::Trapezoidal;
62 setBaseParameters(nomPower, nomVolt, nomFreq, nomFieldCur);
63 setOperationalPerUnitParameters(poleNumber, inertia, Rs, Ld, Lq, Ll, Ld_t,
64 Lq_t, Ld_s, Lq_s, Td0_t, Tq0_t, Td0_s, Tq0_s);
65 calculateFundamentalFromOperationalParameters();
68 void Base::SynchronGenerator::setOperationalPerUnitParameters(
69 Int poleNumber, Real inertia, Real Rs, Real Ld, Real Lq, Real Ll, Real Ld_t,
70 Real Lq_t, Real Ld_s, Real Lq_s, Real Td0_t, Real Tq0_t, Real Td0_s,
72 mPoleNumber = poleNumber;
90 void Base::SynchronGenerator::setAndApplyFundamentalPerUnitParameters(
91 Int poleNumber, Real Rs, Real Ll, Real Lmd, Real Lmq, Real Rfd, Real Llfd,
92 Real Rkd, Real Llkd, Real Rkq1, Real Llkq1, Real Rkq2, Real Llkq2,
94 Base::SynchronGenerator::setFundamentalPerUnitParameters(
95 poleNumber, Rs, Ll, Lmd, Lmq, Rfd, Llfd, Rkd, Llkd, Rkq1, Llkq1, Rkq2,
98 Base::SynchronGenerator::applyFundamentalPerUnitParameters();
101 void Base::SynchronGenerator::setFundamentalPerUnitParameters(
102 Int poleNumber, Real Rs, Real Ll, Real Lmd, Real Lmq, Real Rfd, Real Llfd,
103 Real Rkd, Real Llkd, Real Rkq1, Real Llkq1, Real Rkq2, Real Llkq2,
106 mPoleNumber = poleNumber;
107 **mInertia = inertia;
124 void Base::SynchronGenerator::applyFundamentalPerUnitParameters() {
126 **mLd = **mLl + mLmd;
127 **mLq = **mLl + mLmq;
130 mLkq1 = mLlkq1 + mLmq;
131 mLkq2 = mLlkq2 + mLmq;
134 mBase_ifd = mLmd * mNomFieldCur;
135 mBase_vfd = mNomPower / mBase_ifd;
136 mBase_Zfd = mBase_vfd / mBase_ifd;
137 mBase_Lfd = mBase_Zfd / mBase_OmElec;
140 if (mRkq2 == 0 && mLlkq2 == 0)
141 mNumDampingWindings = 1;
143 mNumDampingWindings = 2;
145 if (mNumDampingWindings == 1) {
146 mVsr = Matrix::Zero(6, 1);
147 mIsr = Matrix::Zero(6, 1);
148 mPsisr = Matrix::Zero(6, 1);
149 mInductanceMat = Matrix::Zero(6, 6);
150 mResistanceMat = Matrix::Zero(6, 6);
158 mInductanceMat << **mLd, mLmd, mLmd, 0, 0, 0, mLmd, mLfd, mLmd, 0, 0, 0,
159 mLmd, mLmd, mLkd, 0, 0, 0, 0, 0, 0, **mLq, mLmq, 0, 0, 0, 0, mLmq,
160 mLkq1, 0, 0, 0, 0, 0, 0, **mLl;
162 mResistanceMat << **mRs, 0, 0, 0, 0, 0, 0, mRfd, 0, 0, 0, 0, 0, 0, mRkd, 0,
163 0, 0, 0, 0, 0, **mRs, 0, 0, 0, 0, 0, 0, mRkq1, 0, 0, 0, 0, 0, 0, **mRs;
166 mInvInductanceMat = mInductanceMat.inverse();
168 mVsr = Matrix::Zero(7, 1);
169 mIsr = Matrix::Zero(7, 1);
170 mPsisr = Matrix::Zero(7, 1);
171 mInductanceMat = Matrix::Zero(7, 7);
172 mResistanceMat = Matrix::Zero(7, 7);
180 mInductanceMat << **mLd, mLmd, mLmd, 0, 0, 0, 0, mLmd, mLfd, mLmd, 0, 0, 0,
181 0, mLmd, mLmd, mLkd, 0, 0, 0, 0, 0, 0, 0, **mLq, mLmq, mLmq, 0, 0, 0, 0,
182 mLmq, mLkq1, mLmq, 0, 0, 0, 0, mLmq, mLmq, mLkq2, 0, 0, 0, 0, 0, 0, 0,
185 mResistanceMat << **mRs, 0, 0, 0, 0, 0, 0, 0, mRfd, 0, 0, 0, 0, 0, 0, 0,
186 mRkd, 0, 0, 0, 0, 0, 0, 0, **mRs, 0, 0, 0, 0, 0, 0, 0, mRkq1, 0, 0, 0,
187 0, 0, 0, 0, mRkq2, 0, 0, 0, 0, 0, 0, 0, **mRs;
190 mInvInductanceMat = mInductanceMat.inverse();
194 void Base::SynchronGenerator::calculateFundamentalFromOperationalParameters() {
195 mLmd = **mLd - **mLl;
196 mLmq = **mLq - **mLl;
198 mLlfd = mLmd * (**mLd_t - **mLl) / (mLmd - **mLd_t + **mLl);
199 mLlkq1 = mLmq * (**mLq_t - **mLl) / (mLmq - **mLq_t + **mLl);
201 mLlkd = mLmd * mLlfd * (**mLd_s - **mLl) /
202 (mLlfd * mLmd - (mLmd + mLlfd) * (**mLd_s - **mLl));
203 mLlkq2 = mLmq * mLlkq1 * (**mLq_s - **mLl) /
204 (mLlkq1 * mLmq - (mLmq + mLlkq1) * (**mLq_s - **mLl));
206 mRfd = (mLmd + mLlfd) / (**mTd0_t * mNomOmega);
207 mRkd = (1 / (**mTd0_s * mNomOmega)) * (mLlkd + mLmd * mLlfd / (mLmd + mLlfd));
208 mRkq1 = (mLmq + mLlkq1) / (**mTq0_t * mNomOmega);
210 (1 / (**mTq0_s * mNomOmega)) * (mLlkq2 + mLmq * mLlkq1 / (mLmq + mLlkq1));
212 Base::SynchronGenerator::applyFundamentalPerUnitParameters();
215 void Base::SynchronGenerator::setInitialValues(Real initActivePower,
216 Real initReactivePower,
217 Real initTerminalVolt,
219 Real initMechPower) {
220 mInitElecPower = Complex(initActivePower, initReactivePower);
221 mInitTerminalVoltage = initTerminalVolt;
222 mInitVoltAngle = initVoltAngle;
223 mInitMechPower = initMechPower;
224 mInitialValuesSet =
true;
229 Real init_P = mInitElecPower.real() / mNomPower;
230 Real init_Q = mInitElecPower.imag() / mNomPower;
231 Real init_S_abs = sqrt(pow(init_P, 2.) + pow(init_Q, 2.));
234 Real init_vt_abs = mInitTerminalVoltage / mBase_V;
237 Real init_it_abs = init_S_abs / init_vt_abs;
240 Real init_pf = acos(init_P / init_S_abs);
242 Real init_delta = atan(((mLmq + **mLl) * init_it_abs * cos(init_pf) -
243 **mRs * init_it_abs * sin(init_pf)) /
244 (init_vt_abs + **mRs * init_it_abs * cos(init_pf) +
245 (mLmq + **mLl) * init_it_abs * sin(init_pf)));
252 Real init_vd = init_vt_abs * sin(init_delta);
253 Real init_vq = init_vt_abs * cos(init_delta);
254 Real init_id = init_it_abs * sin(init_delta + init_pf);
255 Real init_iq = init_it_abs * cos(init_delta + init_pf);
258 Real init_ifd = (init_vq + **mRs * init_iq + (mLmd + **mLl) * init_id) / mLmd;
259 Real init_vfd = mRfd * init_ifd;
262 Real init_psid = init_vq + **mRs * init_iq;
263 Real init_psiq = -init_vd - **mRs * init_id;
264 Real init_psifd = mLfd * init_ifd - mLmd * init_id;
265 Real init_psikd = mLmd * (init_ifd - init_id);
266 Real init_psiq1 = -mLmq * init_iq;
267 Real init_psiq2 = -mLmq * init_iq;
271 **mMechPower = mInitMechPower / mNomPower;
272 **mMechTorque = **mMechPower / 1;
273 mThetaMech = mInitVoltAngle + init_delta - PI / 2.;
274 **mDelta = init_delta;
276 if (mNumDampingWindings == 2) {
277 mVsr << init_vd, init_vfd, 0, init_vq, 0, 0, 0;
278 mIsr << -init_id, init_ifd, 0, -init_iq, 0, 0, 0;
279 mPsisr << init_psid, init_psifd, init_psikd, init_psiq, init_psiq1,
282 mVsr << init_vd, init_vfd, 0, init_vq, 0, 0;
283 mIsr << -init_id, init_ifd, 0, -init_iq, 0, 0;
284 mPsisr << init_psid, init_psifd, init_psikd, init_psiq, init_psiq1, 0;
287 if (mNumDampingWindings == 2) {
288 mVsr << init_vd, init_vfd, 0, init_vq, 0, 0, 0;
289 mIsr << -init_id, init_ifd, 0, -init_iq, 0, 0, 0;
290 mPsisr << init_psid, init_psifd, init_psikd, init_psiq, init_psiq1,
293 mVsr << init_vd, init_vfd, 0, init_vq, 0, 0;
294 mIsr << -init_id, init_ifd, 0, -init_iq, 0, 0;
295 mPsisr << init_psid, init_psifd, init_psikd, init_psiq, init_psiq1, 0;
298 **mElecTorque = (mPsisr(3, 0) * mIsr(0, 0) - mPsisr(0, 0) * mIsr(3, 0));
304 mExciter->initialize(init_vt_abs, (mLmd / mRfd) * init_vfd);
308 void Base::SynchronGenerator::calcStateSpaceMatrixDQ() {
309 if (mNumDampingWindings == 2) {
310 mLad = 1. / (1. / mLmd + 1. / **mLl + 1. / mLlfd + 1. / mLlkd);
311 mLaq = 1. / (1. / mLmq + 1. / **mLl + 1. / mLlkq1 + 1. / mLlkq2);
313 mPsisr = Matrix::Zero(7, 1);
315 mOmegaFluxMat = Matrix::Zero(7, 7);
316 mOmegaFluxMat << 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
317 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
322 mFluxStateSpaceMat << **mRs / **mLl * mLad / **mLl - **mRs / **mLl,
323 **mRs / **mLl * mLad / mLlfd, **mRs / **mLl * mLad / mLlkd, 0, 0, 0, 0,
324 mRfd / mLlfd * mLad / **mLl, mRfd / mLlfd * mLad / mLlfd - mRfd / mLlfd,
325 mRfd / mLlfd * mLad / mLlkd, 0, 0, 0, 0, mRkd / mLlkd * mLad / **mLl,
326 mRkd / mLlkd * mLad / mLlfd, mRkd / mLlkd * mLad / mLlkd - mRkd / mLlkd,
327 0, 0, 0, 0, 0, 0, 0, **mRs / **mLl * mLaq / **mLl - **mRs / **mLl,
328 **mRs / **mLl * mLaq / mLlkq1, **mRs / **mLl * mLaq / mLlkq2, 0, 0, 0,
329 0, mRkq1 / mLlkq1 * mLaq / **mLl,
330 mRkq1 / mLlkq1 * mLaq / mLlkq1 - mRkq1 / mLlkq1,
331 mRkq1 / mLlkq1 * mLaq / mLlkq2, 0, 0, 0, 0,
332 mRkq2 / mLlkq2 * mLaq / **mLl, mRkq2 / mLlkq2 * mLaq / mLlkq1,
333 mRkq2 / mLlkq2 * mLaq / mLlkq2 - mRkq2 / mLlkq2, 0, 0, 0, 0, 0, 0, 0,
338 mFluxToCurrentMat << 1. / **mLl - mLad / **mLl / **mLl,
339 -mLad / mLlfd / **mLl, -mLad / mLlkd / **mLl, 0, 0, 0, 0,
340 -mLad / **mLl / mLlfd, 1. / mLlfd - mLad / mLlfd / mLlfd,
341 -mLad / mLlkd / mLlfd, 0, 0, 0, 0, -mLad / **mLl / mLlkd,
342 -mLad / mLlfd / mLlkd, 1. / mLlkd - mLad / mLlkd / mLlkd, 0, 0, 0, 0, 0,
343 0, 0, 1. / **mLl - mLaq / **mLl / **mLl, -mLaq / mLlkq1 / **mLl,
344 -mLaq / mLlkq2 / **mLl, 0, 0, 0, 0, -mLaq / **mLl / mLlkq1,
345 1. / mLlkq1 - mLaq / mLlkq1 / mLlkq1, -mLaq / mLlkq2 / mLlkq1, 0, 0, 0,
346 0, -mLaq / **mLl / mLlkq2, -mLaq / mLlkq1 / mLlkq2,
347 1. / mLlkq2 - mLaq / mLlkq2 / mLlkq2, 0, 0, 0, 0, 0, 0, 0, 1. / **mLl;
349 mLad = 1. / (1. / mLmd + 1. / **mLl + 1. / mLlfd + 1. / mLlkd);
350 mLaq = 1. / (1. / mLmq + 1. / **mLl + 1. / mLlkq1);
352 mPsisr = Matrix::Zero(6, 1);
354 mOmegaFluxMat = Matrix::Zero(6, 6);
355 mOmegaFluxMat << 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1,
356 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
358 mFluxStateSpaceMat = Matrix::Zero(6, 6);
359 mFluxStateSpaceMat <<
360 **mRs / **mLl * mLad / **mLl - **mRs / **mLl,
361 **mRs / **mLl * mLad / mLlfd, **mRs / **mLl * mLad / mLlkd, 0, 0, 0,
362 mRfd / mLlfd * mLad / **mLl, mRfd / mLlfd * mLad / mLlfd - mRfd / mLlfd,
363 mRfd / mLlfd * mLad / mLlkd, 0, 0, 0, mRkd / mLlkd * mLad / **mLl,
364 mRkd / mLlkd * mLad / mLlfd, mRkd / mLlkd * mLad / mLlkd - mRkd / mLlkd,
365 0, 0, 0, 0, 0, 0, **mRs / **mLl * mLaq / **mLl - **mRs / **mLl,
366 **mRs / **mLl * mLaq / mLlkq1, 0, 0, 0, 0,
367 mRkq1 / mLlkq1 * mLaq / **mLl,
368 mRkq1 / mLlkq1 * mLaq / mLlkq1 - mRkq1 / mLlkq1, 0, 0, 0, 0, 0, 0,
371 mFluxToCurrentMat = Matrix::Zero(6, 6);
372 mFluxToCurrentMat << 1. / **mLl - mLad / **mLl / **mLl,
373 -mLad / mLlfd / **mLl, -mLad / mLlkd / **mLl, 0, 0, 0,
374 -mLad / **mLl / mLlfd, 1. / mLlfd - mLad / mLlfd / mLlfd,
375 -mLad / mLlkd / mLlfd, 0, 0, 0, -mLad / **mLl / mLlkd,
376 -mLad / mLlfd / mLlkd, 1. / mLlkd - mLad / mLlkd / mLlkd, 0, 0, 0, 0, 0,
377 0, 1. / **mLl - mLaq / **mLl / **mLl, -mLaq / mLlkq1 / **mLl, 0, 0, 0,
378 0, -mLaq / **mLl / mLlkq1, 1. / mLlkq1 - mLaq / mLlkq1 / mLlkq1, 0, 0,
379 0, 0, 0, 0, 1. / **mLl;
383 Real Base::SynchronGenerator::calcHfromJ(Real J, Real omegaNominal,
384 Int polePairNumber) {
385 return J * 0.5 * omegaNominal * omegaNominal / polePairNumber;
389 Real Tf, Real Kf, Real Tr) {
390 mExciter = Signal::Exciter::make(
"Exciter", CPS::Logger::Level::info);
391 mExciter->setParameters(Ta, Ka, Te, Ke, Tf, Kf, Tr);
396 Real Fb, Real Fc, Real K, Real Tsr,
397 Real Tsm, Real Tm_init, Real PmRef) {
398 mTurbineGovernor = Signal::TurbineGovernor::make(
"TurbineGovernor",
399 CPS::Logger::Level::info);
400 mTurbineGovernor->setParameters(Ta, Tb, Tc, Fa, Fb, Fc, K, Tsr, Tsm);
401 mTurbineGovernor->initialize(PmRef, Tm_init);
402 mHasTurbineGovernor =
true;
Real mNomFreq
nominal frequency fn [Hz]
Real mBase_I
base stator current peak
Real mBase_I_RMS
base stator current RMS
Real mNomVolt
nominal voltage Vn [V] (phase-to-phase RMS)
Real mBase_L
base stator inductance
Real mBase_Z
base stator impedance
void addExciter(Real Ta, Real Ka, Real Te, Real Ke, Real Tf, Real Kf, Real Tr)
Add voltage regulator and exciter.
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)
Add governor and turbine.
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 mNomOmega
nominal angular frequency wn [Hz]
Real mBase_OmElec
base electrical angular frequency
Real mBase_OmMech
base mechanical angular frequency
Real mBase_V
base stator voltage (phase-to-ground peak)
Real mBase_Psi
base flux linkage
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_V_RMS
base stator voltage (phase-to-ground RMS)