9 #include <dpsim-models/DP/DP_Ph1_SynchronGeneratorTrStab.h>
12 DP::Ph1::SynchronGeneratorTrStab::SynchronGeneratorTrStab(
13 String uid, String name, Logger::Level logLevel)
14 : Base::SynchronGenerator(mAttributes),
16 mEp(mAttributes->create<Complex>(
"Ep")),
17 mEp_abs(mAttributes->create<Real>(
"Ep_mag")),
18 mEp_phase(mAttributes->create<Real>(
"Ep_phase")),
19 mDelta_p(mAttributes->create<Real>(
"delta_r")),
20 mRefOmega(mAttributes->createDynamic<Real>(
"w_ref")),
21 mRefDelta(mAttributes->createDynamic<Real>(
"delta_ref")) {
22 setVirtualNodeNumber(2);
24 **mIntfVoltage = MatrixComp::Zero(1, 1);
25 **mIntfCurrent = MatrixComp::Zero(1, 1);
27 mStates = Matrix::Zero(10, 1);
31 DP::Ph1::SynchronGeneratorTrStab::clone(String name) {
32 auto copy = SynchronGeneratorTrStab::make(name,
mLogLevel);
39 Real nomPower, Real nomVolt, Real nomFreq, Real Ll, Real Lmd, Real Llfd,
40 Real inertia, Real D) {
41 setBaseParameters(nomPower, nomVolt, nomFreq);
42 SPDLOG_LOGGER_INFO(mSLog,
43 "\n--- Base Parameters ---"
47 mNomPower, mNomVolt, mNomFreq);
50 mParameterType = ParameterType::statorReferred;
51 mStateType = StateType::statorReferred;
61 mXpd = mNomOmega * (**mLd - mLmd * mLmd / mLfd) * mBase_L;
62 mLpd = (**mLd - mLmd * mLmd / mLfd) * mBase_L;
66 mKd = D * mNomPower / mNomOmega;
68 SPDLOG_LOGGER_INFO(mSLog,
69 "\n--- Parameters ---"
74 mXpd, mLpd, **mInertia, mKd);
78 Real nomPower, Real nomVolt, Real nomFreq, Int polePairNumber, Real Rs,
79 Real Lpd, Real inertiaJ, Real Kd) {
80 setBaseParameters(nomPower, nomVolt, nomFreq);
81 SPDLOG_LOGGER_INFO(mSLog,
82 "\n--- Base Parameters ---"
86 mNomPower, mNomVolt, mNomFreq);
88 mParameterType = ParameterType::statorReferred;
89 mStateType = StateType::statorReferred;
93 **mInertia = calcHfromJ(inertiaJ, 2 * PI * nomFreq, polePairNumber);
95 mXpd = mNomOmega * Lpd;
98 SPDLOG_LOGGER_INFO(mSLog,
99 "\n--- Parameters ---"
104 mXpd, mLpd, **mInertia, mKd);
108 Real nomPower, Real nomVolt, Real nomFreq, Real Xpd, Real inertia, Real Rs,
110 setBaseParameters(nomPower, nomVolt, nomFreq);
111 SPDLOG_LOGGER_INFO(mSLog,
112 "\n--- Base Parameters ---"
116 mNomPower, mNomVolt, mNomFreq);
119 mParameterType = ParameterType::statorReferred;
120 mStateType = StateType::statorReferred;
123 **mInertia = inertia;
125 mXpd = Xpd * mBase_Z;
126 mLpd = Xpd * mBase_L;
131 mKd = D * mNomPower / mNomOmega;
133 SPDLOG_LOGGER_INFO(mSLog,
134 "\n--- Parameters ---"
139 mXpd, mLpd, **mInertia, mKd);
143 Bool convertWithOmegaMech) {
144 mConvertWithOmegaMech = convertWithOmegaMech;
146 SPDLOG_LOGGER_INFO(mSLog,
147 "\n--- Model flags ---"
148 "\nconvertWithOmegaMech: {:s}",
149 std::to_string(mConvertWithOmegaMech));
152 void DP::Ph1::SynchronGeneratorTrStab::setInitialValues(Complex elecPower,
154 mInitElecPower = elecPower;
155 mInitMechPower = mechPower;
162 **mOmMech = mNomOmega;
165 (**mIntfVoltage)(0, 0) = initialSingleVoltage(0);
166 mInitElecPower = (mInitElecPower == Complex(0, 0))
167 ? -terminal(0)->singlePower()
169 mInitMechPower = (mInitElecPower == Complex(0, 0)) ? mInitElecPower.real()
173 (**mIntfCurrent)(0, 0) = std::conj(-mInitElecPower / (**mIntfVoltage)(0, 0));
175 mImpedance = Complex(**mRs, mXpd);
178 **mEp = (**mIntfVoltage)(0, 0) - mImpedance * (**mIntfCurrent)(0, 0);
181 **mEp_abs = Math::abs(**mEp);
183 **mDelta_p = Math::phase(**mEp);
187 ((**mIntfVoltage)(0, 0) * std::conj(-(**mIntfCurrent)(0, 0))).real();
191 **mMechPower = **mElecActivePower;
194 mVirtualNodes[0]->setInitialVoltage(**mEp);
197 mSubVoltageSource = DP::Ph1::VoltageSource::make(**mName +
"_src", mLogLevel);
198 mSubVoltageSource->setParameters(**mEp);
199 mSubVoltageSource->connect({SimNode::GND, mVirtualNodes[0]});
200 mSubVoltageSource->setVirtualNodeAt(mVirtualNodes[1], 0);
201 mSubVoltageSource->initialize(mFrequencies);
202 mSubVoltageSource->initializeFromNodesAndTerminals(frequency);
203 addMNASubComponent(mSubVoltageSource,
204 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
205 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
208 mSubInductor = DP::Ph1::Inductor::make(**mName +
"_ind", mLogLevel);
209 mSubInductor->setParameters(mLpd);
210 mSubInductor->connect({mVirtualNodes[0], terminal(0)->node()});
211 mSubInductor->initialize(mFrequencies);
212 mSubInductor->initializeFromNodesAndTerminals(frequency);
213 addMNASubComponent(mSubInductor, MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
214 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
216 SPDLOG_LOGGER_INFO(mSLog,
217 "\n--- Initialize according to powerflow ---"
218 "\nTerminal 0 voltage: {:e}<{:e}"
219 "\nVoltage behind reactance: {:e}<{:e}"
220 "\ninitial electrical power: {:e}+j{:e}"
221 "\nactive electrical power: {:e}"
222 "\nmechanical power: {:e}"
223 "\n--- End of powerflow initialization ---",
224 Math::abs((**mIntfVoltage)(0, 0)),
225 Math::phaseDeg((**mIntfVoltage)(0, 0)), Math::abs(**mEp),
226 Math::phaseDeg(**mEp), mInitElecPower.real(),
227 mInitElecPower.imag(), **mElecActivePower, **mMechPower);
230 void DP::Ph1::SynchronGeneratorTrStab::step(Real time) {
235 ((**mIntfVoltage)(0, 0) * std::conj(-(**mIntfCurrent)(0, 0))).real();
240 if (mConvertWithOmegaMech)
242 mNomOmega * mNomOmega / (2. * **mInertia * mNomPower * **mOmMech) *
243 (**mMechPower - **mElecActivePower - mKd * (**mOmMech - mNomOmega));
246 mNomOmega / (2. * **mInertia * mNomPower) *
247 (**mMechPower - **mElecActivePower - mKd * (**mOmMech - mNomOmega));
251 if (mBehaviour == Behaviour::MNASimulation)
252 **mOmMech = **mOmMech + mTimeStep * dOmMech;
256 Real dDelta_p = **mOmMech - (mUseOmegaRef ? **mRefOmega : mNomOmega);
260 if (mBehaviour == Behaviour::MNASimulation) {
261 **mDelta_p = **mDelta_p + mTimeStep * dDelta_p;
262 **mEp = Complex(**mEp_abs * cos(**mDelta_p), **mEp_abs * sin(**mDelta_p));
265 mStates << Math::abs(**mEp), Math::phaseDeg(**mEp), **mElecActivePower,
266 **mMechPower, **mDelta_p, **mOmMech, dOmMech, dDelta_p,
267 (**mIntfVoltage)(0, 0).real(), (**mIntfVoltage)(0, 0).imag();
268 SPDLOG_LOGGER_DEBUG(mSLog,
"\nStates, time {:f}: \n{:s}", time,
269 Logger::matrixToString(mStates));
274 mTimeStep = timeStep;
275 mMnaTasks.push_back(std::make_shared<AddBStep>(*
this));
279 AttributeBase::List &prevStepDependencies,
280 AttributeBase::List &attributeDependencies,
281 AttributeBase::List &modifiedAttributes) {
285 prevStepDependencies.push_back(mIntfVoltage);
288 void DP::Ph1::SynchronGeneratorTrStab::mnaParentAddPostStepDependencies(
289 AttributeBase::List &prevStepDependencies,
290 AttributeBase::List &attributeDependencies,
291 AttributeBase::List &modifiedAttributes,
293 attributeDependencies.push_back(leftVector);
294 modifiedAttributes.push_back(mIntfVoltage);
301 mSubVoltageSource->mVoltageRef->set(**mEp);
304 void DP::Ph1::SynchronGeneratorTrStab::AddBStep::execute(Real time,
306 **mGenerator.mRightVector = mGenerator.mSubInductor->mRightVector->get() +
307 mGenerator.mSubVoltageSource->mRightVector->get();
312 mnaCompUpdateVoltage(**leftVector);
313 mnaCompUpdateCurrent(**leftVector);
316 void DP::Ph1::SynchronGeneratorTrStab::mnaCompUpdateVoltage(
317 const Matrix &leftVector) {
318 SPDLOG_LOGGER_DEBUG(mSLog,
"Read voltage from {:d}", matrixNodeIndex(0));
319 (**mIntfVoltage)(0, 0) =
320 Math::complexFromVectorElement(leftVector, matrixNodeIndex(0));
323 void DP::Ph1::SynchronGeneratorTrStab::mnaCompUpdateCurrent(
324 const Matrix &leftVector) {
325 SPDLOG_LOGGER_DEBUG(mSLog,
"Read current from {:d}", matrixNodeIndex(0));
327 **mIntfCurrent = mSubInductor->mIntfCurrent->get();
330 void DP::Ph1::SynchronGeneratorTrStab::setReferenceOmega(
332 mRefOmega->setReference(refOmegaPtr);
333 mRefDelta->setReference(refDeltaPtr);
336 SPDLOG_LOGGER_INFO(mSLog,
"Use of reference omega.");
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 mnaParentPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
Retrieves calculated voltage from simulation for next step.
void setStandardParametersSI(Real nomPower, Real nomVolt, Real nomFreq, Int polePairNumber, Real Rs, Real Lpd, Real inertiaJ, Real Kd=0)
Initializes the machine parameters.
void initializeFromNodesAndTerminals(Real frequency) override
Initializes Component variables according to power flow data stored in Nodes.
void mnaParentAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
Real mKd
Absolute damping coefficient.
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 setModelFlags(Bool convertWithOmegaMech)
Flags to modify model behavior.
Real mXpd
Absolute d-axis transient reactance X'd.
void setFundamentalParametersPU(Real nomPower, Real nomVolt, Real nomFreq, Real Ll, Real Lmd, Real Llfd, Real inertia, Real D=0)
Initializes the machine parameters.
void mnaParentPreStep(Real time, Int timeStepCount) override
Base class for all components that are transmitting power.
Logger::Level mLogLevel
Component logger control for internal variables.