9#include <dpsim-models/EMT/EMT_Ph3_SynchronGeneratorTrStab.h>
12Matrix EMT::Ph3::SynchronGeneratorTrStab::parkTransformPowerInvariant(
13 Real theta,
const Matrix &fabc) {
16 Matrix Tdq = getParkTransformMatrixPowerInvariant(theta);
17 Matrix dqvector = Tdq * fabc;
21Matrix 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.);
33EMT::Ph3::SynchronGeneratorTrStab::SynchronGeneratorTrStab(
34 String uid, String name, Logger::Level logLevel)
35 : Base::SynchronGenerator(mAttributes),
36 CompositePowerComp<Real>(uid, name, true, true, logLevel),
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;
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;
95 **
mInertia = calcHfromJ(inertiaJ, 2 * PI * nomFreq, polePairNumber);
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;
127 SPDLOG_LOGGER_INFO(
mSLog,
128 "\n--- Parameters ---"
130 "\ninductance: {:f}",
134void EMT::Ph3::SynchronGeneratorTrStab::setInitialValues(Complex elecPower,
136 mInitElecPower = elecPower;
137 mInitMechPower = mechPower;
146 mInitElecPower = (mInitElecPower == Complex(0, 0))
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;
172 **
mEp = intfVoltageComplex(0, 0) -
mImpedance * intfCurrentComplex(0, 0);
181 std::conj(-intfCurrentComplex(0, 0)))
194 MatrixComp vref = MatrixComp::Zero(3, 1);
206 MNA_SUBCOMP_TASK_ORDER::TASK_AFTER_PARENT,
207 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
215 mSubInductor->initializeFromNodesAndTerminals(frequency);
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 ---",
229 Math::phaseDeg(**
mEp), mInitElecPower.real(),
233void 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;
270 Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) {
272 mMnaTasks.push_back(std::make_shared<AddBStep>(*
this));
275void EMT::Ph3::SynchronGeneratorTrStab::mnaParentAddPreStepDependencies(
276 AttributeBase::List &prevStepDependencies,
277 AttributeBase::List &attributeDependencies,
278 AttributeBase::List &modifiedAttributes) {
279 prevStepDependencies.push_back(mIntfVoltage);
282void EMT::Ph3::SynchronGeneratorTrStab::mnaParentAddPostStepDependencies(
283 AttributeBase::List &prevStepDependencies,
284 AttributeBase::List &attributeDependencies,
285 AttributeBase::List &modifiedAttributes,
286 Attribute<Matrix>::Ptr &leftVector) {
287 attributeDependencies.push_back(leftVector);
288 modifiedAttributes.push_back(mIntfVoltage);
295 MatrixComp vref = MatrixComp::Zero(3, 1);
300void EMT::Ph3::SynchronGeneratorTrStab::AddBStep::execute(Real time,
302 **mGenerator.mRightVector = **mGenerator.mSubInductor->mRightVector +
303 **mGenerator.mSubVoltageSource->mRightVector;
307 Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
308 mnaCompUpdateVoltage(**leftVector);
309 mnaCompUpdateCurrent(**leftVector);
312void 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));
323void 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 mTimeStep
Simulation time step.
Real mLmd
d-axis mutual inductance Lmd [H]
Real mLlfd
field leakage inductance Llfd [H]
const Attribute< Real >::Ptr mMechPower
mechanical Power Pm [W]
Real mNomVolt
nominal voltage Vn [V] (phase-to-phase RMS)
Real mBase_L
base stator inductance
Real mBase_Z
base stator impedance
const Attribute< Real >::Ptr mRs
stator resistance Rs [Ohm]
const Attribute< Real >::Ptr mElecActivePower
Active part of the electrical power.
StateType mStateType
specifies if the machine parameters are transformed to per unit
Real mNomOmega
nominal angular frequency wn [Hz]
const Attribute< Real >::Ptr mLl
leakage inductance Ll [H]
Real mLfd
field inductance Lfd [H]
const Attribute< Real >::Ptr mLd
d-axis inductance Ld [H]
Real mNomPower
nominal power Pn [VA]
const Attribute< Real >::Ptr mOmMech
rotor speed omega_r
const Attribute< Real >::Ptr mInertia
inertia constant H [s] for per unit or moment of inertia J [kg*m^2]
void addMNASubComponent(typename SimPowerComp< Real >::Ptr subc, MNA_SUBCOMP_TASK_ORDER preStepOrder, MNA_SUBCOMP_TASK_ORDER postStepOrder, Bool contributeToRightVector)
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.
std::shared_ptr< VoltageSource > mSubVoltageSource
Inner voltage source that represents the generator.
SimPowerComp< Real >::Ptr clone(String name) override
Returns a modified copy of the component with the given suffix added to the name and without.
void mnaParentPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
Retrieves calculated voltage from simulation for next step.
const Attribute< Complex >::Ptr mEp
emf behind transient reactance
void mnaParentPreStep(Real time, Int timeStepCount) override
Complex mImpedance
Equivalent impedance for loadflow calculation.
std::shared_ptr< Inductor > mSubInductor
Inner inductor that represents the generator impedance.
void initializeFromNodesAndTerminals(Real frequency) override
Initializes Component variables according to power flow data stored in Nodes.
const Attribute< Real >::Ptr mEp_abs
const Attribute< Real >::Ptr mDelta_p
Angle by which the emf Ep is leading the terminal voltage.
void setFundamentalParametersPU(Real nomPower, Real nomVolt, Real nomFreq, Real Ll, Real Lmd, Real Llfd, Real inertia, Real D=0)
Initializes the machine parameters.
Real mLpd
Absolute d-axis transient inductance.
Real mXpd
Absolute d-axis transient reactance X'd.
const Attribute< String >::Ptr mName
Human readable name.
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.
const Attribute< MatrixVar< Real > >::Ptr mIntfCurrent
SimTerminal< Real >::Ptr terminal(UInt index)
const Attribute< MatrixVar< Real > >::Ptr mIntfVoltage
SimNode< Real >::List mVirtualNodes
Logger::Level mLogLevel
Component logger control for internal variables.
Logger::Log mSLog
Component logger.