9 #include <dpsim-models/EMT/EMT_Ph3_SynchronGeneratorTrStab.h>
12 Matrix EMT::Ph3::SynchronGeneratorTrStab::parkTransformPowerInvariant(
13 Real theta,
const Matrix &fabc) {
16 Matrix Tdq = getParkTransformMatrixPowerInvariant(theta);
17 Matrix dqvector = Tdq * fabc;
21 Matrix EMT::Ph3::SynchronGeneratorTrStab::getParkTransformMatrixPowerInvariant(
25 Matrix Tdq = Matrix::Zero(2, 3);
26 Real k = sqrt(2. / 3.);
27 Tdq << k * cos(theta), k * cos(theta - 2. * M_PI / 3.),
28 k * cos(theta + 2. * M_PI / 3.), -k * sin(theta),
29 -k * sin(theta - 2. * M_PI / 3.), -k * sin(theta + 2. * M_PI / 3.);
33 EMT::Ph3::SynchronGeneratorTrStab::SynchronGeneratorTrStab(
34 String uid, String name, Logger::Level logLevel)
35 : Base::SynchronGenerator(mAttributes),
37 mEp(mAttributes->create<Complex>(
"Ep")),
38 mEp_abs(mAttributes->create<Real>(
"Ep_mag")),
39 mEp_phase(mAttributes->create<Real>(
"Ep_phase")),
40 mDelta_p(mAttributes->create<Real>(
"delta_r")),
41 mRefOmega(mAttributes->createDynamic<Real>(
"w_ref")),
42 mRefDelta(mAttributes->createDynamic<Real>(
"delta_ref")) {
43 setVirtualNodeNumber(2);
45 **mIntfVoltage = Matrix::Zero(3, 1);
46 **mIntfCurrent = Matrix::Zero(3, 1);
48 mStates = Matrix::Zero(10, 1);
52 auto copy = SynchronGeneratorTrStab::make(name,
mLogLevel);
59 Real nomPower, Real nomVolt, Real nomFreq, Real Ll, Real Lmd, Real Llfd,
60 Real inertia, Real D) {
61 setBaseParameters(nomPower, nomVolt, nomFreq);
64 mParameterType = ParameterType::statorReferred;
65 mStateType = StateType::statorReferred;
75 mXpd = mNomOmega * (**mLd - mLmd * mLmd / mLfd) * mBase_L;
76 mLpd = (**mLd - mLmd * mLmd / mLfd) * mBase_L;
78 SPDLOG_LOGGER_INFO(mSLog,
79 "\n--- Parameters ---"
86 Real nomPower, Real nomVolt, Real nomFreq, Int polePairNumber, Real Rs,
87 Real Lpd, Real inertiaJ, Real Kd) {
88 setBaseParameters(nomPower, nomVolt, nomFreq);
90 mParameterType = ParameterType::statorReferred;
91 mStateType = StateType::statorReferred;
95 **mInertia = calcHfromJ(inertiaJ, 2 * PI * nomFreq, polePairNumber);
97 mXpd = mNomOmega * Lpd;
100 SPDLOG_LOGGER_INFO(mSLog,
101 "\n--- Parameters ---"
103 "\ninductance: {:f}",
108 Real nomPower, Real nomVolt, Real nomFreq, Real Xpd, Real inertia, Real Rs,
110 setBaseParameters(nomPower, nomVolt, nomFreq);
113 mParameterType = ParameterType::statorReferred;
114 mStateType = StateType::statorReferred;
117 **mInertia = inertia;
119 mXpd = Xpd * mBase_Z;
120 mLpd = Xpd * mBase_L;
125 mKd = D * mNomPower / mNomOmega;
127 SPDLOG_LOGGER_INFO(mSLog,
128 "\n--- Parameters ---"
130 "\ninductance: {:f}",
134 void EMT::Ph3::SynchronGeneratorTrStab::setInitialValues(Complex elecPower,
136 mInitElecPower = elecPower;
137 mInitMechPower = mechPower;
144 **mOmMech = mNomOmega;
146 mInitElecPower = (mInitElecPower == Complex(0, 0))
147 ? -terminal(0)->singlePower()
149 mInitMechPower = (mInitElecPower == Complex(0, 0)) ? mInitElecPower.real()
153 MatrixComp intfVoltageComplex = MatrixComp::Zero(3, 1);
154 MatrixComp intfCurrentComplex = MatrixComp::Zero(3, 1);
157 intfVoltageComplex(0, 0) = initialSingleVoltage(0);
158 intfVoltageComplex(1, 0) = intfVoltageComplex(0, 0) * SHIFT_TO_PHASE_B;
159 intfVoltageComplex(2, 0) = intfVoltageComplex(0, 0) * SHIFT_TO_PHASE_C;
160 intfCurrentComplex(0, 0) =
161 std::conj(-2. / 3. * mInitElecPower / intfVoltageComplex(0, 0));
162 intfCurrentComplex(1, 0) = intfCurrentComplex(0, 0) * SHIFT_TO_PHASE_B;
163 intfCurrentComplex(2, 0) = intfCurrentComplex(0, 0) * SHIFT_TO_PHASE_C;
166 **mIntfVoltage = intfVoltageComplex.real();
167 **mIntfCurrent = intfCurrentComplex.real();
169 mImpedance = Complex(**mRs, mXpd);
172 **mEp = intfVoltageComplex(0, 0) - mImpedance * intfCurrentComplex(0, 0);
175 **mEp_abs = Math::abs(**mEp);
177 **mDelta_p = Math::phase(**mEp);
180 **mElecActivePower = (3. / 2. * intfVoltageComplex(0, 0) *
181 std::conj(-intfCurrentComplex(0, 0)))
189 **mMechPower = **mElecActivePower - mKd * (**mOmMech - mNomOmega);
192 mVirtualNodes[0]->setInitialVoltage(PEAK1PH_TO_RMS3PH * **mEp);
194 MatrixComp vref = MatrixComp::Zero(3, 1);
199 EMT::Ph3::VoltageSource::make(**mName +
"_src", mLogLevel);
200 mSubVoltageSource->setParameters(vref, frequency);
201 mSubVoltageSource->connect({SimNode::GND, mVirtualNodes[0]});
202 mSubVoltageSource->setVirtualNodeAt(mVirtualNodes[1], 0);
203 mSubVoltageSource->initialize(mFrequencies);
204 mSubVoltageSource->initializeFromNodesAndTerminals(frequency);
205 addMNASubComponent(mSubVoltageSource,
206 MNA_SUBCOMP_TASK_ORDER::TASK_AFTER_PARENT,
207 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
210 mSubInductor = EMT::Ph3::Inductor::make(**mName +
"_ind", mLogLevel);
211 mSubInductor->setParameters(
213 mSubInductor->connect({mVirtualNodes[0], terminal(0)->node()});
214 mSubInductor->initialize(mFrequencies);
215 mSubInductor->initializeFromNodesAndTerminals(frequency);
216 addMNASubComponent(mSubInductor, MNA_SUBCOMP_TASK_ORDER::TASK_AFTER_PARENT,
217 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
219 SPDLOG_LOGGER_INFO(mSLog,
220 "\n--- Initialize according to powerflow ---"
221 "\nTerminal 0 voltage: {:e}<{:e}"
222 "\nVoltage behind reactance: {:e}<{:e}"
223 "\ninitial electrical power: {:e}+j{:e}"
224 "\nactive electrical power: {:e}"
225 "\nmechanical power: {:e}"
226 "\n--- End of powerflow initialization ---",
227 Math::abs((**mIntfVoltage)(0, 0)),
228 Math::phaseDeg((**mIntfVoltage)(0, 0)), Math::abs(**mEp),
229 Math::phaseDeg(**mEp), mInitElecPower.real(),
230 mInitElecPower.imag(), **mElecActivePower, **mMechPower);
233 void EMT::Ph3::SynchronGeneratorTrStab::step(Real time) {
236 Matrix intfVoltageDQ = parkTransformPowerInvariant(mThetaN, **mIntfVoltage);
237 Matrix intfCurrentDQ = parkTransformPowerInvariant(mThetaN, **mIntfCurrent);
239 **mElecActivePower = -1. * (intfVoltageDQ(0, 0) * intfCurrentDQ(0, 0) +
240 intfVoltageDQ(1, 0) * intfCurrentDQ(1, 0));
250 mNomOmega / (2. * **mInertia * mNomPower) *
251 (**mMechPower - **mElecActivePower - mKd * (**mOmMech - mNomOmega));
252 if (mBehaviour == Behaviour::MNASimulation)
253 **mOmMech = **mOmMech + mTimeStep * dOmMech;
254 Real dDelta_p = **mOmMech - mNomOmega;
255 if (mBehaviour == Behaviour::MNASimulation)
256 **mDelta_p = **mDelta_p + mTimeStep * dDelta_p;
258 if (mBehaviour == Behaviour::MNASimulation)
259 **mEp = Complex(**mEp_abs * cos(**mDelta_p), **mEp_abs * sin(**mDelta_p));
262 mThetaN = mThetaN + mTimeStep * mNomOmega;
271 mTimeStep = timeStep;
272 mMnaTasks.push_back(std::make_shared<AddBStep>(*
this));
275 void EMT::Ph3::SynchronGeneratorTrStab::mnaParentAddPreStepDependencies(
276 AttributeBase::List &prevStepDependencies,
277 AttributeBase::List &attributeDependencies,
278 AttributeBase::List &modifiedAttributes) {
279 prevStepDependencies.push_back(mIntfVoltage);
282 void EMT::Ph3::SynchronGeneratorTrStab::mnaParentAddPostStepDependencies(
283 AttributeBase::List &prevStepDependencies,
284 AttributeBase::List &attributeDependencies,
285 AttributeBase::List &modifiedAttributes,
287 attributeDependencies.push_back(leftVector);
288 modifiedAttributes.push_back(mIntfVoltage);
295 MatrixComp vref = MatrixComp::Zero(3, 1);
297 mSubVoltageSource->mVoltageRef->set(vref);
300 void EMT::Ph3::SynchronGeneratorTrStab::AddBStep::execute(Real time,
302 **mGenerator.mRightVector = **mGenerator.mSubInductor->mRightVector +
303 **mGenerator.mSubVoltageSource->mRightVector;
308 mnaCompUpdateVoltage(**leftVector);
309 mnaCompUpdateCurrent(**leftVector);
312 void EMT::Ph3::SynchronGeneratorTrStab::mnaCompUpdateVoltage(
313 const Matrix &leftVector) {
314 SPDLOG_LOGGER_DEBUG(mSLog,
"Read voltage from {:d}", matrixNodeIndex(0));
315 (**mIntfVoltage)(0, 0) =
316 Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 0));
317 (**mIntfVoltage)(1, 0) =
318 Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 1));
319 (**mIntfVoltage)(2, 0) =
320 Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 2));
323 void EMT::Ph3::SynchronGeneratorTrStab::mnaCompUpdateCurrent(
324 const Matrix &leftVector) {
325 SPDLOG_LOGGER_DEBUG(mSLog,
"Read current from {:d}", matrixNodeIndex(0));
327 **mIntfCurrent = **mSubInductor->mIntfCurrent;
Real mNomFreq
nominal frequency fn [Hz]
Real mNomVolt
nominal voltage Vn [V] (phase-to-phase RMS)
Real mBase_Z
base stator impedance
const Attribute< Real >::Ptr mRs
stator resistance Rs [Ohm]
Real mNomPower
nominal power Pn [VA]
const Attribute< Real >::Ptr mInertia
inertia constant H [s] for per unit or moment of inertia J [kg*m^2]
Base class for composite power components.
void setStandardParametersPU(Real nomPower, Real nomVolt, Real nomFreq, Real Xpd, Real inertia, Real Rs=0, Real D=0)
Initializes the machine parameters.
void mnaParentInitialize(Real omega, Real timeStep, Attribute< Matrix >::Ptr leftVector) override
Initializes variables of component.
void setStandardParametersSI(Real nomPower, Real nomVolt, Real nomFreq, Int polePairNumber, Real Rs, Real Lpd, Real inertiaJ, Real Kd=0)
Initializes the machine parameters.
Real mKd
Absolute damping coefficient.
void mnaParentPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
Retrieves calculated voltage from simulation for next step.
void mnaParentPreStep(Real time, Int timeStepCount) override
void initializeFromNodesAndTerminals(Real frequency) override
Initializes Component variables according to power flow data stored in Nodes.
void setFundamentalParametersPU(Real nomPower, Real nomVolt, Real nomFreq, Real Ll, Real Lmd, Real Llfd, Real inertia, Real D=0)
Initializes the machine parameters.
Real mXpd
Absolute d-axis transient reactance X'd.
static Matrix singlePhaseParameterToThreePhase(Real parameter)
To convert single phase parameters to symmetrical three phase ones.
static MatrixComp singlePhaseVariableToThreePhase(Complex var_1ph)
To convert single phase complex variables (voltages, currents) to symmetrical three phase ones.
Base class for all components that are transmitting power.
Logger::Level mLogLevel
Component logger control for internal variables.