9 #include <dpsim-models/SP/SP_Ph1_SynchronGeneratorTrStab.h>
12 SP::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);
32 SP::Ph1::SynchronGeneratorTrStab::clone(String name) {
33 auto copy = SynchronGeneratorTrStab::make(name,
mLogLevel);
40 Real nomPower, Real nomVolt, Real nomFreq, Real Ll, Real Lmd, Real Llfd,
41 Real inertia, Real D) {
42 setBaseParameters(nomPower, nomVolt, nomFreq);
43 SPDLOG_LOGGER_INFO(mSLog,
44 "\n--- Base Parameters ---"
48 mNomPower, mNomVolt, mNomFreq);
51 mParameterType = ParameterType::statorReferred;
52 mStateType = StateType::statorReferred;
62 mXpd = mNomOmega * (**mLd - mLmd * mLmd / mLfd) * mBase_L;
63 mLpd = (**mLd - mLmd * mLmd / mLfd) * mBase_L;
67 mKd = D * mNomPower / mNomOmega;
69 SPDLOG_LOGGER_INFO(mSLog,
70 "\n--- Parameters ---"
75 mXpd, mLpd, **mInertia, mKd);
79 Real nomPower, Real nomVolt, Real nomFreq, Int polePairNumber, Real Rs,
80 Real Lpd, Real inertiaJ, Real Kd) {
81 setBaseParameters(nomPower, nomVolt, nomFreq);
82 SPDLOG_LOGGER_INFO(mSLog,
83 "\n--- Base Parameters ---"
87 mNomPower, mNomVolt, mNomFreq);
89 mParameterType = ParameterType::statorReferred;
90 mStateType = StateType::statorReferred;
94 **mInertia = calcHfromJ(inertiaJ, 2 * PI * nomFreq, polePairNumber);
96 mXpd = mNomOmega * Lpd;
99 SPDLOG_LOGGER_INFO(mSLog,
100 "\n--- Parameters ---"
105 mXpd, mLpd, **mInertia, mKd);
109 Real nomPower, Real nomVolt, Real nomFreq, Real Xpd, Real inertia, Real Rs,
111 setBaseParameters(nomPower, nomVolt, nomFreq);
112 SPDLOG_LOGGER_INFO(mSLog,
113 "\n--- Base Parameters ---"
117 mNomPower, mNomVolt, mNomFreq);
119 SPDLOG_LOGGER_INFO(mSLog,
120 "\n--- Parameters Per-Unit ---"
121 "\n Xpd: {:f} [p.u.]",
125 mParameterType = ParameterType::statorReferred;
126 mStateType = StateType::statorReferred;
129 **mInertia = inertia;
131 mXpd = Xpd * mBase_Z;
132 mLpd = Xpd * mBase_L;
137 mKd = D * mNomPower / mNomOmega;
139 SPDLOG_LOGGER_INFO(mSLog,
140 "\n--- Parameters ---"
143 "\nInertia: {:f} [s]"
145 mXpd, mLpd, **mInertia, mKd);
149 Bool convertWithOmegaMech) {
150 mConvertWithOmegaMech = convertWithOmegaMech;
152 SPDLOG_LOGGER_INFO(mSLog,
153 "\n--- Model flags ---"
154 "\nconvertWithOmegaMech: {:s}",
155 std::to_string(mConvertWithOmegaMech));
158 void SP::Ph1::SynchronGeneratorTrStab::setInitialValues(Complex elecPower,
160 mInitElecPower = elecPower;
161 mInitMechPower = mechPower;
168 **mOmMech = mNomOmega;
171 (**mIntfVoltage)(0, 0) = initialSingleVoltage(0);
172 mInitElecPower = (mInitElecPower == Complex(0, 0))
173 ? -terminal(0)->singlePower()
175 mInitMechPower = (mInitElecPower == Complex(0, 0)) ? mInitElecPower.real()
179 (**mIntfCurrent)(0, 0) = std::conj(-mInitElecPower / (**mIntfVoltage)(0, 0));
181 mImpedance = Complex(**mRs, mXpd);
184 **mEp = (**mIntfVoltage)(0, 0) - mImpedance * (**mIntfCurrent)(0, 0);
187 **mEp_abs = Math::abs(**mEp);
189 **mDelta_p = Math::phase(**mEp);
194 ((**mIntfVoltage)(0, 0) * std::conj(-(**mIntfCurrent)(0, 0))).real();
195 **mElecReactivePower =
196 ((**mIntfVoltage)(0, 0) * std::conj(-(**mIntfCurrent)(0, 0))).imag();
201 **mMechPower = **mElecActivePower;
204 mVirtualNodes[0]->setInitialVoltage(**mEp);
207 mSubVoltageSource = SP::Ph1::VoltageSource::make(**mName +
"_src", mLogLevel);
208 mSubVoltageSource->setParameters(**mEp);
209 mSubVoltageSource->connect({SimNode::GND, mVirtualNodes[0]});
210 mSubVoltageSource->setVirtualNodeAt(mVirtualNodes[1], 0);
211 mSubVoltageSource->initialize(mFrequencies);
212 mSubVoltageSource->initializeFromNodesAndTerminals(frequency);
213 addMNASubComponent(mSubVoltageSource,
214 MNA_SUBCOMP_TASK_ORDER::TASK_AFTER_PARENT,
215 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
false);
218 mSubInductor = SP::Ph1::Inductor::make(**mName +
"_ind", mLogLevel);
219 mSubInductor->setParameters(mLpd);
220 mSubInductor->connect({mVirtualNodes[0], terminal(0)->node()});
221 mSubInductor->initialize(mFrequencies);
222 mSubInductor->initializeFromNodesAndTerminals(frequency);
223 addMNASubComponent(mSubInductor, MNA_SUBCOMP_TASK_ORDER::TASK_AFTER_PARENT,
224 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
false);
226 SPDLOG_LOGGER_INFO(mSLog,
227 "\n--- Initialize according to powerflow ---"
228 "\nTerminal 0 voltage: {:e}<{:e}"
229 "\nVoltage behind reactance: {:e}<{:e}"
230 "\ninitial electrical power: {:e}+j{:e}"
231 "\nactive electrical power: {:e}"
232 "\nreactive electrical power: {:e}"
233 "\nmechanical power: {:e}"
234 "\n--- End of powerflow initialization ---",
235 Math::abs((**mIntfVoltage)(0, 0)),
236 Math::phaseDeg((**mIntfVoltage)(0, 0)), Math::abs(**mEp),
237 Math::phaseDeg(**mEp), mInitElecPower.real(),
238 mInitElecPower.imag(), **mElecActivePower,
239 **mElecReactivePower, **mMechPower);
242 void SP::Ph1::SynchronGeneratorTrStab::step(Real time) {
248 ((**mIntfVoltage)(0, 0) * std::conj(-(**mIntfCurrent)(0, 0))).real();
249 **mElecReactivePower =
250 ((**mIntfVoltage)(0, 0) * std::conj(-(**mIntfCurrent)(0, 0))).imag();
255 if (mConvertWithOmegaMech)
257 mNomOmega * mNomOmega / (2. * **mInertia * mNomPower * **mOmMech) *
258 (**mMechPower - **mElecActivePower - mKd * (**mOmMech - mNomOmega));
261 mNomOmega / (2. * **mInertia * mNomPower) *
262 (**mMechPower - **mElecActivePower - mKd * (**mOmMech - mNomOmega));
266 if (mBehaviour == Behaviour::MNASimulation)
267 **mOmMech = **mOmMech + mTimeStep * dOmMech;
271 Real dDelta_p = **mOmMech - (mUseOmegaRef ? **mRefOmega : mNomOmega);
275 if (mBehaviour == Behaviour::MNASimulation) {
276 **mDelta_p = **mDelta_p + mTimeStep * dDelta_p;
277 **mEp = Complex(**mEp_abs * cos(**mDelta_p), **mEp_abs * sin(**mDelta_p));
280 mStates << Math::abs(**mEp), Math::phaseDeg(**mEp), **mElecActivePower,
281 **mMechPower, **mDelta_p, **mOmMech, dOmMech, dDelta_p,
282 (**mIntfVoltage)(0, 0).real(), (**mIntfVoltage)(0, 0).imag();
283 SPDLOG_LOGGER_DEBUG(mSLog,
"\nStates, time {:f}: \n{:s}", time,
284 Logger::matrixToString(mStates));
289 mTimeStep = timeStep;
291 mMnaTasks.push_back(std::make_shared<AddBStep>(*
this));
295 AttributeBase::List &prevStepDependencies,
296 AttributeBase::List &attributeDependencies,
297 AttributeBase::List &modifiedAttributes) {
301 prevStepDependencies.push_back(mIntfVoltage);
304 void SP::Ph1::SynchronGeneratorTrStab::mnaParentAddPostStepDependencies(
305 AttributeBase::List &prevStepDependencies,
306 AttributeBase::List &attributeDependencies,
307 AttributeBase::List &modifiedAttributes,
309 attributeDependencies.push_back(leftVector);
310 modifiedAttributes.push_back(mIntfVoltage);
317 mSubVoltageSource->mVoltageRef->set(**mEp);
320 void SP::Ph1::SynchronGeneratorTrStab::AddBStep::execute(Real time,
322 **mGenerator.mRightVector = mGenerator.mSubInductor->mRightVector->get() +
323 mGenerator.mSubVoltageSource->mRightVector->get();
326 void SP::Ph1::SynchronGeneratorTrStab::mnaParentPostStep(
328 mnaCompUpdateVoltage(**leftVector);
329 mnaCompUpdateCurrent(**leftVector);
332 void SP::Ph1::SynchronGeneratorTrStab::mnaCompUpdateVoltage(
333 const Matrix &leftVector) {
334 SPDLOG_LOGGER_DEBUG(mSLog,
"Read voltage from {:d}", matrixNodeIndex(0));
335 (**mIntfVoltage)(0, 0) =
336 Math::complexFromVectorElement(leftVector, matrixNodeIndex(0));
339 void SP::Ph1::SynchronGeneratorTrStab::mnaCompUpdateCurrent(
340 const Matrix &leftVector) {
341 SPDLOG_LOGGER_DEBUG(mSLog,
"Read current from {:d}", matrixNodeIndex(0));
343 **mIntfCurrent = mSubInductor->mIntfCurrent->get();
346 void SP::Ph1::SynchronGeneratorTrStab::setReferenceOmega(
348 mRefOmega->setReference(refOmegaPtr);
349 mRefDelta->setReference(refDeltaPtr);
352 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 mnaParentPreStep(Real time, Int timeStepCount) override
MNA pre and post step operations.
Real mKd
Absolute damping coefficient.
void setModelFlags(Bool convertWithOmegaMech)
Flags to modify model behavior.
void initializeFromNodesAndTerminals(Real frequency) override
Initializes Component variables according to power flow data stored in Nodes.
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 mXpd
Absolute d-axis transient reactance X'd.
void mnaParentAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
void setFundamentalParametersPU(Real nomPower, Real nomVolt, Real nomFreq, Real Ll, Real Lmd, Real Llfd, Real inertia, Real D=0)
Initializes the machine parameters.
Base class for all components that are transmitting power.
Logger::Level mLogLevel
Component logger control for internal variables.