DPsim
Loading...
Searching...
No Matches
DP_Ph3_SynchronGeneratorDQ.cpp
1/* Copyright 2017-2021 Institute for Automation of Complex Power Systems,
2 * EONERC, RWTH Aachen University
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 *********************************************************************************/
8
9#include <dpsim-models/DP/DP_Ph3_SynchronGeneratorDQ.h>
10
11//Added for testing/printing purposes:
12#include <fstream>
13#include <iostream>
14
15using namespace CPS;
16using namespace std;
17
19 Logger::Level logLevel)
20 : MNASimPowerComp<Complex>(uid, name, true, true, logLevel),
22 mPhaseType = PhaseType::ABC;
23 setTerminalNumber(1);
24 **mIntfVoltage = MatrixComp::Zero(3, 1);
25 **mIntfCurrent = MatrixComp::Zero(3, 1);
26}
27
29 Logger::Level logLevel)
30 : SynchronGeneratorDQ(name, name, logLevel) {}
31
32DP::Ph3::SynchronGeneratorDQ::~SynchronGeneratorDQ() {}
33
35 Real nomPower, Real nomVolt, Real nomFreq, Int poleNumber, Real nomFieldCur,
36 Real Rs, Real Ll, Real Lmd, Real Lmq, Real Rfd, Real Llfd, Real Rkd,
37 Real Llkd, Real Rkq1, Real Llkq1, Real Rkq2, Real Llkq2, Real inertia,
38 Real initActivePower, Real initReactivePower, Real initTerminalVolt,
39 Real initVoltAngle, Real initMechPower) {
40
42 nomPower, nomVolt, nomFreq, nomFieldCur, poleNumber, Rs, Ll, Lmd, Lmq,
43 Rfd, Llfd, Rkd, Llkd, Rkq1, Llkq1, Rkq2, Llkq2, inertia);
44 Base::SynchronGenerator::setInitialValues(initActivePower, initReactivePower,
45 initTerminalVolt, initVoltAngle,
46 initMechPower);
47}
48
51 mSystemOmega = frequencies(0, 0);
52
53 // #### Compensation ####
54 mCompensationOn = false;
55 mCompensationCurrent = MatrixComp::Zero(3, 1);
56 // Calculate real compensation resistance from per unit
58
59 // #### General setup ####
60 // Create matrices for state space representation
61 calcStateSpaceMatrixDQ();
62
63 // steady state per unit initial value
65
66 mVdq0 = Matrix::Zero(3, 1);
67 mIdq0 = Matrix::Zero(3, 1);
68 if (mNumDampingWindings == 2) {
69 mVdq0 << mVsr(0, 0), mVsr(3, 0), mVsr(6, 0);
70 mIdq0 << mIsr(0, 0), mIsr(3, 0), mIsr(6, 0);
71 } else {
72 mVdq0 << mVsr(0, 0), mVsr(3, 0), mVsr(5, 0);
73 mIdq0 << mIsr(0, 0), mIsr(3, 0), mIsr(5, 0);
74 }
75
78}
79
80void DP::Ph3::SynchronGeneratorDQ::mnaCompApplySystemMatrixStamp(
81 SparseMatrixRow &systemMatrix) {
82 if (!mCompensationOn)
83 return;
84
85 Real conductance = 1. / mRcomp;
86
87 if (terminalNotGrounded(0)) {
88 Math::addToMatrixElement(systemMatrix, matrixNodeIndices(0)[0],
89 matrixNodeIndices(0)[0], Complex(conductance, 0));
90 Math::addToMatrixElement(systemMatrix, matrixNodeIndices(0)[1],
91 matrixNodeIndices(0)[1], Complex(conductance, 0));
92 Math::addToMatrixElement(systemMatrix, matrixNodeIndices(0)[2],
93 matrixNodeIndices(0)[2], Complex(conductance, 0));
94 SPDLOG_LOGGER_INFO(mSLog, "Add {} to {}, {}", conductance,
95 matrixNodeIndices(0)[0], matrixNodeIndices(0)[0]);
96 SPDLOG_LOGGER_INFO(mSLog, "Add {} to {}, {}", conductance,
97 matrixNodeIndices(0)[1], matrixNodeIndices(0)[1]);
98 SPDLOG_LOGGER_INFO(mSLog, "Add {} to {}, {}", conductance,
99 matrixNodeIndices(0)[2], matrixNodeIndices(0)[2]);
100 }
101}
102
103void DP::Ph3::SynchronGeneratorDQ::mnaCompApplyRightSideVectorStamp(
104 Matrix &rightVector) {
105 if (mCompensationOn)
106 mCompensationCurrent = **mIntfVoltage / mRcomp;
107
108 // If the interface current is positive, it is flowing out of the connected node and into ground.
109 // Therefore, the generator is interfaced as a consumer but since the currents are reversed the equations
110 // are in generator mode.
111 if (terminalNotGrounded(0)) {
112 Math::setVectorElement(rightVector, matrixNodeIndex(0, 0),
113 -(**mIntfCurrent)(0, 0) +
114 mCompensationCurrent(0, 0));
115 Math::setVectorElement(rightVector, matrixNodeIndex(0, 1),
116 -(**mIntfCurrent)(1, 0) +
117 mCompensationCurrent(1, 0));
118 Math::setVectorElement(rightVector, matrixNodeIndex(0, 2),
119 -(**mIntfCurrent)(2, 0) +
120 mCompensationCurrent(2, 0));
121 }
122}
123
125 const Matrix &leftVector) {
126 (**mIntfVoltage)(0, 0) =
127 Math::complexFromVectorElement(leftVector, matrixNodeIndex(0, 0));
128 (**mIntfVoltage)(1, 0) =
129 Math::complexFromVectorElement(leftVector, matrixNodeIndex(0, 1));
130 (**mIntfVoltage)(2, 0) =
131 Math::complexFromVectorElement(leftVector, matrixNodeIndex(0, 2));
132}
133
135 AttributeBase::List &prevStepDependencies,
136 AttributeBase::List &attributeDependencies,
137 AttributeBase::List &modifiedAttributes,
138 Attribute<Matrix>::Ptr &leftVector) {
139 attributeDependencies.push_back(leftVector);
140 modifiedAttributes.push_back(mIntfVoltage);
141}
142
143void DP::Ph3::SynchronGeneratorDQ::mnaCompPostStep(
144 Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
145 mnaCompUpdateVoltage(**leftVector);
146}
147
148Real DP::Ph3::SynchronGeneratorDQ::electricalTorque() const {
149 return **mElecTorque * mBase_T;
150}
151
152Real DP::Ph3::SynchronGeneratorDQ::rotationalSpeed() const {
153 return **mOmMech * mBase_OmMech;
154}
155
156Real DP::Ph3::SynchronGeneratorDQ::rotorPosition() const { return mThetaMech; }
157
159 MatrixComp &abcVector) {
160 // Balanced case because we do not return the zero sequence component
161 Complex alpha(cos(2. / 3. * PI), sin(2. / 3. * PI));
162 Complex thetaCompInv(cos(-theta), sin(-theta));
163
164 MatrixComp abcToPnz(3, 3);
165 abcToPnz << 1, 1, 1, 1, alpha, pow(alpha, 2), 1, pow(alpha, 2), alpha;
166 abcToPnz = (1. / 3.) * abcToPnz;
167
168 MatrixComp pnzVector(3, 1);
169 pnzVector = abcToPnz * abcVector * thetaCompInv;
170
171 Matrix dq0Vector(3, 1);
172 dq0Vector << pnzVector(1, 0).real(), pnzVector(1, 0).imag(), 0;
173
174 return dq0Vector;
175}
176
178 Matrix &dq0) {
179 // Balanced case because we do not consider the zero sequence component
180 Complex alpha(cos(2. / 3. * PI), sin(2. / 3. * PI));
181 Complex thetaComp(cos(theta), sin(theta));
182 // Matrix to transform from symmetrical components to ABC
183 MatrixComp pnzToAbc(3, 3);
184 pnzToAbc << 1, 1, 1, 1, pow(alpha, 2), alpha, 1, alpha, pow(alpha, 2);
185 // Symmetrical components vector
186 MatrixComp pnzVector(3, 1);
187 // Picking only d and q for positive sequence component
188 pnzVector << 0, Complex(dq0(0, 0), dq0(1, 0)), 0;
189 // ABC vector
190 MatrixComp abcCompVector(3, 1);
191 abcCompVector = pnzToAbc * pnzVector * thetaComp;
192
193 return abcCompVector;
194}
195
197
198void DP::Ph3::SynchronGeneratorDQ::trapezoidalCurrentStates() {}
Matrix mIsr
Vector of stator and rotor currents.
Real mSystemOmega
Simulation angular system speed.
Real mRcomp
Compensation Resistance.
Real mBase_I
base stator current peak
Bool mCompensationOn
Determines if compensation elements are used.
SynchronGenerator(CPS::AttributeList::Ptr attributeList)
Constructor.
Matrix mVsr
Vector of stator and rotor voltages.
Real mBase_Z
base stator impedance
Matrix mIdq0
dq0 current calculated from terminal current
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.
Matrix mVdq0
dq0 voltage calculated from terminal voltage
Int mNumDampingWindings
Number of damping windings in q.
Real mBase_V
base stator voltage (phase-to-ground peak)
void initialize(Real omega, Real timeStep)
SynchronGeneratorDQ(String name, String uid, Logger::Level logLevel=Logger::Level::off)
Defines UID, name and logging level.
void trapezoidalFluxStates()
calculate flux states using trapezoidal rule - depcrecated
virtual void mnaCompUpdateVoltage(const Matrix &leftVector) override
Retrieves calculated voltage from simulation for next step.
void mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
Add MNA post step dependencies.
Matrix abcToDq0Transform(Real theta, MatrixComp &abc)
Park transform as described in Krause.
MatrixComp mCompensationCurrent
Compensation current source set point.
void setParametersFundamentalPerUnit(Real nomPower, Real nomVolt, Real nomFreq, Int poleNumber, Real nomFieldCur, 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, Real initActivePower, Real initReactivePower, Real initTerminalVolt, Real initVoltAngle, Real initMechPower)
MatrixComp dq0ToAbcTransform(Real theta, Matrix &dq0)
Inverse Park transform as described in Krause.
String uid()
Returns unique id.
AttributeList::Ptr mAttributes
Attribute List.
MNASimPowerComp(String uid, String name, Bool hasPreStep, Bool hasPostStep, Logger::Level logLevel)
const Attribute< MatrixVar< Complex > >::Ptr mIntfCurrent
virtual void initialize(Matrix frequencies)
Initialize components with correct network frequencies.
const Attribute< MatrixVar< Complex > >::Ptr mIntfVoltage