DPsim
Loading...
Searching...
No Matches
EMT_Ph3_Transformer.cpp
Go to the documentation of this file.
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
10
11using namespace CPS;
12
14 Logger::Level logLevel,
15 Bool withResistiveLosses)
17 CompositePowerComp<Real>(uid, name, true, true, logLevel) {
19 if (withResistiveLosses)
21 else
23
25
26 SPDLOG_LOGGER_INFO(mSLog, "Create {} {}", this->type(), name);
27 **mIntfVoltage = Matrix::Zero(3, 1);
28 **mIntfCurrent = Matrix::Zero(1, 1);
29}
30
39
41 Real nomVoltageEnd2, Real ratedPower,
42 Real ratioAbs, Real ratioPhase,
43 Matrix resistance,
44 Matrix inductance) {
45
46 Base::Ph3::Transformer::setParameters(nomVoltageEnd1, nomVoltageEnd2,
47 ratedPower, ratioAbs, ratioPhase,
48 resistance, inductance);
49
50 SPDLOG_LOGGER_INFO(
51 mSLog, "Nominal Voltage End 1 = {} [V] Nominal Voltage End 2 = {} [V]",
53 SPDLOG_LOGGER_INFO(mSLog, "Rated Apparent Power = {} [VA]", mRatedPower);
54 SPDLOG_LOGGER_INFO(mSLog, "Tap Ratio = {} [ ] Phase Shift = {} [deg]",
55 std::abs(**mRatio), std::arg(**mRatio));
56
57 mParametersSet = true;
58}
59
62 return;
63 mSubCompCreated = true;
64
65 // Switch terminals so terminal 0 is always the higher-voltage side.
66 if (Math::abs(**mRatio) < 1.) {
67 **mRatio = 1. / **mRatio;
68 std::shared_ptr<SimTerminal<Real>> tmp = mTerminals[0];
69 mTerminals[0] = mTerminals[1];
70 mTerminals[1] = tmp;
71 Real tmpVolt = mNominalVoltageEnd1;
73 mNominalVoltageEnd2 = tmpVolt;
74 SPDLOG_LOGGER_INFO(mSLog, "Switching terminals to have first terminal at "
75 "higher voltage side. Updated parameters: ");
76 SPDLOG_LOGGER_INFO(
77 mSLog, "Nominal Voltage End 1 = {} [V] Nominal Voltage End 2 = {} [V]",
79 SPDLOG_LOGGER_INFO(mSLog, "Tap Ratio = {} [ ] Phase Shift = {} [deg]",
80 std::abs(**mRatio), std::arg(**mRatio));
81 }
82
83 // Create series sub components
84 mSubInductor =
85 std::make_shared<EMT::Ph3::Inductor>(**mName + "_ind", mLogLevel);
86 mSubInductor->setParameters(mInductance);
89
90 if (mNumVirtualNodes == 3) {
91 mSubResistor =
92 std::make_shared<EMT::Ph3::Resistor>(**mName + "_res", mLogLevel);
95 mSubResistor->setParameters(mResistance);
96 mSubResistor->connect({node(0), mVirtualNodes[2]});
97 mSubInductor->connect({mVirtualNodes[2], mVirtualNodes[0]});
98 } else {
99 mSubInductor->connect({node(0), mVirtualNodes[0]});
100 }
101
102 // Create parallel sub components (three-phase power)
104
105 // A snubber conductance is added on the higher voltage side
106 Real snubberResistance1 = std::pow(std::abs(mNominalVoltageEnd1), 2) / pSnub;
107 mSnubberResistance1 =
108 Math::singlePhaseParameterToThreePhase(snubberResistance1);
109 mSubSnubResistor1 =
110 std::make_shared<EMT::Ph3::Resistor>(**mName + "_snub_res1", mLogLevel);
111 mSubSnubResistor1->setParameters(mSnubberResistance1);
112 mSubSnubResistor1->connect({node(0), EMT::SimNode::GND});
113 SPDLOG_LOGGER_INFO(
114 mSLog,
115 "Snubber Resistance 1 (connected to higher voltage side {}) = {} [Ohm]",
116 node(0)->name(), Logger::matrixToString(mSnubberResistance1));
117 addMNASubComponent(mSubSnubResistor1,
120
121 // A snubber conductance is added on the lower voltage side
122 Real snubberResistance2 = std::pow(std::abs(mNominalVoltageEnd2), 2) / pSnub;
123 mSnubberResistance2 =
124 Math::singlePhaseParameterToThreePhase(snubberResistance2);
125 mSubSnubResistor2 =
126 std::make_shared<EMT::Ph3::Resistor>(**mName + "_snub_res2", mLogLevel);
127 mSubSnubResistor2->setParameters(mSnubberResistance2);
128 mSubSnubResistor2->connect({node(1), EMT::SimNode::GND});
129 SPDLOG_LOGGER_INFO(
130 mSLog,
131 "Snubber Resistance 2 (connected to lower voltage side {}) = {} [Ohm]",
132 node(1)->name(), Logger::matrixToString(mSnubberResistance2));
133 addMNASubComponent(mSubSnubResistor2,
136
137 // LV-side snubber capacitor created here; its omega-dependent value is set in initializeParentFromNodesAndTerminals().
138 mSubSnubCapacitor2 =
139 std::make_shared<EMT::Ph3::Capacitor>(**mName + "_snub_cap2", mLogLevel);
140 mSubSnubCapacitor2->connect({node(1), EMT::SimNode::GND});
141 addMNASubComponent(mSubSnubCapacitor2,
144}
145
147 Real frequency) {
148 // Set initial voltage of virtual node in between
149 mVirtualNodes[0]->setInitialVoltage(initialSingleVoltage(1) * **mRatio);
150
151 // Static calculations from load flow data
152 Real omega = 2. * PI * frequency;
153
155
156 // // A snubber capacitance is added to higher voltage side (not used as capacitor at high voltage side made it worse)
157 // Real snubberCapacitance1 = qSnub / std::pow(std::abs(mNominalVoltageEnd1),2) / omega;
158 // mSnubberCapacitance1 = Math::singlePhaseParameterToThreePhase*(snubberCapacitance1);
159 // mSubSnubCapacitor1 = std::make_shared<EMT::Ph3::Capacitor>(**mName + "_snub_cap1", mLogLevel);
160 // mSubSnubCapacitor1->setParameters(mSnubberCapacitance1);
161 // mSubSnubCapacitor1->connect({ node(0), EMT::SimNode::GND });
162 // SPDLOG_LOGGER_INFO(mSLog, "Snubber Capacitance 1 (connected to higher voltage side {}) = \n{} [F] \n ", node(0)->name(), Logger::matrixToString(mSnubberCapacitance1));
163 // mSubComponents.push_back(mSubSnubCapacitor1);
164
165 Real snubberCapacitance2 =
166 qSnub / std::pow(std::abs(mNominalVoltageEnd2), 2) / omega;
167 mSnubberCapacitance2 =
168 Math::singlePhaseParameterToThreePhase(snubberCapacitance2);
169 mSubSnubCapacitor2->setParameters(mSnubberCapacitance2);
170 SPDLOG_LOGGER_INFO(
171 mSLog,
172 "Snubber Capacitance 2 (connected to lower voltage side {}) = {} [F]",
173 node(1)->name(), Logger::matrixToString(mSnubberCapacitance2));
174 MatrixComp impedance = MatrixComp::Zero(3, 3);
175 impedance << Complex(mResistance(0, 0), omega * mInductance(0, 0)),
176 Complex(mResistance(0, 1), omega * mInductance(0, 1)),
177 Complex(mResistance(0, 2), omega * mInductance(0, 2)),
178 Complex(mResistance(1, 0), omega * mInductance(1, 0)),
179 Complex(mResistance(1, 1), omega * mInductance(1, 1)),
180 Complex(mResistance(1, 2), omega * mInductance(1, 2)),
181 Complex(mResistance(2, 0), omega * mInductance(2, 0)),
182 Complex(mResistance(2, 1), omega * mInductance(2, 1)),
183 Complex(mResistance(2, 2), omega * mInductance(2, 2));
184
185 SPDLOG_LOGGER_INFO(mSLog,
186 "Resistance (referred to higher voltage side) = {} [Ohm]",
188 SPDLOG_LOGGER_INFO(mSLog,
189 "Inductance (referred to higher voltage side) = {} [H]",
191 SPDLOG_LOGGER_INFO(mSLog,
192 "Reactance (referred to higher voltage side) = {} [Ohm]",
194
195 MatrixComp vInitABC = MatrixComp::Zero(3, 1);
196 vInitABC(0, 0) =
198 (mVirtualNodes[0]->initialSingleVoltage() - initialSingleVoltage(0));
199 vInitABC(1, 0) = vInitABC(0, 0) * SHIFT_TO_PHASE_B;
200 vInitABC(2, 0) = vInitABC(0, 0) * SHIFT_TO_PHASE_C;
201
202 MatrixComp iInit = impedance.inverse() * vInitABC;
203 **mIntfCurrent = iInit.real();
204 **mIntfVoltage = vInitABC.real();
205
206 if (mNumVirtualNodes == 3)
207 mVirtualNodes[2]->setInitialVoltage(initialSingleVoltage(0));
208
209 SPDLOG_LOGGER_INFO(
210 mSLog,
211 "\n--- Initialization from powerflow ---"
212 "\nVoltage across: {:s}"
213 "\nCurrent: {:s}"
214 "\nTerminal 0 voltage: {:s}"
215 "\nTerminal 1 voltage: {:s}"
216 "\nVirtual Node 1 voltage: {:s}"
217 "\n--- Initialization from powerflow finished ---",
224}
225
227 Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) {
228 SPDLOG_LOGGER_INFO(
229 mSLog,
230 "\nTerminal 0 connected to {:s} = sim node {:d}"
231 "\nTerminal 1 connected to {:s} = sim node {:d}",
234}
235
237 SparseMatrixRow &systemMatrix) {
238 // Ideal transformer equations
239 if (terminalNotGrounded(0)) {
241 systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
244 systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
247 systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
249
250 Math::setMatrixElement(systemMatrix,
253 Math::setMatrixElement(systemMatrix,
256 Math::setMatrixElement(systemMatrix,
259 }
260 if (terminalNotGrounded(1)) {
261 Math::setMatrixElement(systemMatrix, matrixNodeIndex(1, 0),
263 (**mRatio).real());
264 Math::setMatrixElement(systemMatrix, matrixNodeIndex(1, 1),
266 (**mRatio).real());
267 Math::setMatrixElement(systemMatrix, matrixNodeIndex(1, 2),
269 (**mRatio).real());
270 Math::setMatrixElement(systemMatrix,
272 matrixNodeIndex(1, 0), -(**mRatio).real());
273 Math::setMatrixElement(systemMatrix,
275 matrixNodeIndex(1, 1), -(**mRatio).real());
276 Math::setMatrixElement(systemMatrix,
278 matrixNodeIndex(1, 2), -(**mRatio).real());
279 }
280
281 // Add subcomps to system matrix
282 for (auto subcomp : mSubComponents)
283 if (auto mnasubcomp = std::dynamic_pointer_cast<MNAInterface>(subcomp))
284 mnasubcomp->mnaApplySystemMatrixStamp(systemMatrix);
285
286 if (terminalNotGrounded(0)) {
287 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
291 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
295 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
299
300 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
304 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
308 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
312 }
313 if (terminalNotGrounded(1)) {
314 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
317 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
320 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
323
324 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
327 matrixNodeIndex(1, 0));
328 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
331 matrixNodeIndex(1, 1));
332 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
335 matrixNodeIndex(1, 2));
336 }
337}
338
340 AttributeBase::List &prevStepDependencies,
341 AttributeBase::List &attributeDependencies,
342 AttributeBase::List &modifiedAttributes) {
343 prevStepDependencies.push_back(mIntfCurrent);
344 prevStepDependencies.push_back(mIntfVoltage);
345 modifiedAttributes.push_back(mRightVector);
346}
347
351
353 AttributeBase::List &prevStepDependencies,
354 AttributeBase::List &attributeDependencies,
355 AttributeBase::List &modifiedAttributes,
356 Attribute<Matrix>::Ptr &leftVector) {
357 attributeDependencies.push_back(leftVector);
358 modifiedAttributes.push_back(mIntfVoltage);
359 modifiedAttributes.push_back(mIntfCurrent);
360}
361
363 Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
364 mnaCompUpdateVoltage(**leftVector);
365 mnaCompUpdateCurrent(**leftVector);
366}
367
369 **mIntfCurrent = mSubInductor->intfCurrent();
370}
371
373 // v1 - v0
374 **mIntfVoltage = Matrix::Zero(3, 1);
375 if (terminalNotGrounded(1)) {
376 (**mIntfVoltage)(0, 0) =
378 (**mIntfVoltage)(1, 0) =
380 (**mIntfVoltage)(2, 0) =
382 }
383 if (terminalNotGrounded(0)) {
384 (**mIntfVoltage)(0, 0) =
385 (**mIntfVoltage)(0, 0) -
387 (**mIntfVoltage)(1, 0) =
388 (**mIntfVoltage)(1, 0) -
390 (**mIntfVoltage)(2, 0) =
391 (**mIntfVoltage)(2, 0) -
393 }
394}
std::vector< Ptr > List
Definition Attribute.h:123
AttributePointer< Attribute< T > > Ptr
Definition Attribute.h:250
Real mNominalVoltageEnd1
Nominal voltage of primary side.
Real mNominalVoltageEnd2
Nominal voltage of secondary side.
void setParameters(Real nomVoltageEnd1, Real nomVoltageEnd2, Real ratedPower, Real ratioAbs, Real ratioPhase, Matrix resistance, Matrix inductance)
const Attribute< Complex >::Ptr mRatio
Transformer ratio.
Matrix mResistance
Resistance [Ohm].
Matrix mInductance
Inductance [H].
Real mRatedPower
Rated Apparent Power [VA].
void addMNASubComponent(typename SimPowerComp< Real >::Ptr subc, MNA_SUBCOMP_TASK_ORDER preStepOrder, MNA_SUBCOMP_TASK_ORDER postStepOrder, Bool contributeToRightVector)
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override
CompositePowerComp(String uid, String name, Bool hasPreStep, Bool hasPostStep, Logger::Level logLevel)
void mnaParentAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
Add MNA pre step dependencies.
Transformer(String uid, String name, Logger::Level logLevel=Logger::Level::off, Bool withResistiveLosses=false)
Defines UID, name and logging level.
void mnaParentPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
MNA post step operations.
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) override
Stamps system matrix.
void mnaCompUpdateVoltage(const Matrix &leftVector) override
Updates internal voltage variable of the component.
SimPowerComp< Real >::Ptr clone(String name) override
DEPRECATED: Delete method.
void initializeParentFromNodesAndTerminals(Real frequency) override
Initializes component from power flow data.
void createSubComponents() override
Constructs and registers MNA subcomponents; idempotent.
void mnaParentPreStep(Real time, Int timeStepCount) override
MNA pre step operations.
void mnaCompUpdateCurrent(const Matrix &leftVector) override
Updates internal current variable of the component.
void mnaParentAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
Add MNA post step dependencies.
void setParameters(Real nomVoltageEnd1, Real nomVoltageEnd2, Real ratedPower, Real ratioAbs, Real ratioPhase, Matrix resistance, Matrix inductance)
Defines component parameters.
void mnaParentInitialize(Real omega, Real timeStep, Attribute< Matrix >::Ptr leftVector) override
Initializes internal variables of the component.
const Attribute< String >::Ptr mName
Human readable name.
String uid()
Returns unique id.
String type()
Get component type (cross-platform)
AttributeList::Ptr mAttributes
Attribute List.
spdlog::level::level_enum Level
Definition Logger.h:33
static String complexToString(const Complex &num)
Definition Logger.cpp:63
static String matrixToString(const Matrix &mat)
Definition Logger.cpp:31
static String phasorToString(const Complex &num)
Definition Logger.cpp:57
Attribute< Matrix >::Ptr mRightVector
static Real realFromVectorElement(const Matrix &mat, Matrix::Index row)
static void setMatrixElement(SparseMatrixRow &mat, Matrix::Index row, Matrix::Index column, Complex value, Int maxFreq=1, Int freqIdx=0)
static Matrix singlePhaseParameterToThreePhase(Real parameter)
To convert single phase parameters to symmetrical three phase ones.
static Real abs(Complex value)
Definition MathUtils.cpp:27
static Ptr GND
Definition SimNode.h:35
UInt matrixNodeIndex(UInt nodeIndex)
const Attribute< MatrixVar< Real > >::Ptr mIntfCurrent
SimTerminal< Real >::List mTerminals
SimNode< Real >::Ptr node(UInt index)
void setVirtualNodeNumber(UInt num)
const Attribute< MatrixVar< Real > >::Ptr mIntfVoltage
std::shared_ptr< SimPowerComp< VarType > > Ptr
SimNode< Real >::List mVirtualNodes
std::vector< std::shared_ptr< SimPowerComp< Real > > > mSubComponents
Bool terminalNotGrounded(UInt index)
Complex initialSingleVoltage(UInt index)
void setTerminalNumber(UInt num)
Logger::Level mLogLevel
Component logger control for internal variables.
UInt mNumVirtualNodes
Determines the number of virtual or internal Nodes.
bool mParametersSet
Flag indicating that parameters are set via setParameters() function.
Logger::Log mSLog
Component logger.
static std::shared_ptr< Transformer > make(Args &&...args)
Definition PtrFactory.h:19
#define Q_SNUB_TRANSFORMER
Definition Definitions.h:54
#define PI
Definition Definitions.h:43
#define RMS3PH_TO_PEAK1PH
Definition Definitions.h:50
#define P_SNUB_TRANSFORMER
Definition Definitions.h:53
#define SHIFT_TO_PHASE_C
Definition Definitions.h:47
#define SHIFT_TO_PHASE_B
Definition Definitions.h:46
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > Matrix
Dense matrix for real numbers.
Definition Definitions.h:81
std::string String
Definition Definitions.h:65
double Real
Definition Definitions.h:62
int Int
Definition Definitions.h:61
std::complex< Real > Complex
Definition Definitions.h:63
Eigen::Matrix< Complex, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > MatrixComp
Dense matrix for complex numbers.
Definition Definitions.h:84
bool Bool
Definition Definitions.h:64
Eigen::SparseMatrix< Real, Eigen::RowMajor > SparseMatrixRow
Sparse matrix for real numbers (row major).
Definition Definitions.h:74