DPsim
Loading...
Searching...
No Matches
DP_Ph1_Transformer.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_Ph1_Transformer.h>
10
11using namespace CPS;
12
14 Logger::Level logLevel,
15 Bool withResistiveLosses)
16 : Base::Ph1::Transformer(mAttributes),
17 CompositePowerComp<Complex>(uid, name, true, true, logLevel) {
18 if (withResistiveLosses)
19 setVirtualNodeNumber(3);
20 else
21 setVirtualNodeNumber(2);
22
23 setTerminalNumber(2);
24
25 SPDLOG_LOGGER_INFO(mSLog, "Create {} {}", this->type(), name);
26 **mIntfVoltage = MatrixComp::Zero(1, 1);
27 **mIntfCurrent = MatrixComp::Zero(1, 1);
28}
29
31SimPowerComp<Complex>::Ptr DP::Ph1::Transformer::clone(String name) {
32 auto copy = Transformer::make(name, mLogLevel);
33 copy->setParameters(mNominalVoltageEnd1, mNominalVoltageEnd2,
34 std::abs(**mRatio), std::arg(**mRatio), **mResistance,
35 **mInductance);
36 return copy;
37}
38
39void DP::Ph1::Transformer::setParameters(Real nomVoltageEnd1,
40 Real nomVoltageEnd2, Real ratioAbs,
41 Real ratioPhase, Real resistance,
42 Real inductance) {
43
44 Base::Ph1::Transformer::setParameters(nomVoltageEnd1, nomVoltageEnd2,
45 ratioAbs, ratioPhase, resistance,
46 inductance);
47
48 SPDLOG_LOGGER_INFO(
49 mSLog, "Nominal Voltage End 1={} [V] Nominal Voltage End 2={} [V]",
51 SPDLOG_LOGGER_INFO(
52 mSLog,
53 "Resistance={} [Ohm] Inductance={} [Ohm] (referred to primary side)",
55 SPDLOG_LOGGER_INFO(mSLog, "Tap Ratio={} [ ] Phase Shift={} [deg]",
56 std::abs(**mRatio), std::arg(**mRatio));
57 SPDLOG_LOGGER_INFO(mSLog, "Rated Power ={} [W]", **mRatedPower);
58
59 mParametersSet = true;
60}
61
62void DP::Ph1::Transformer::setParameters(Real nomVoltageEnd1,
63 Real nomVoltageEnd2, Real ratedPower,
64 Real ratioAbs, Real ratioPhase,
65 Real resistance, Real inductance) {
66
67 **mRatedPower = ratedPower;
68 SPDLOG_LOGGER_INFO(mSLog, "Rated Power ={} [W]", **mRatedPower);
69
70 DP::Ph1::Transformer::setParameters(nomVoltageEnd1, nomVoltageEnd2, ratioAbs,
71 ratioPhase, resistance, inductance);
72}
73
76 return;
77 mSubCompCreated = true;
78
79 // Component parameters are referred to higher voltage side.
80 // Switch terminals so that terminal 0 is always the higher-voltage side.
81 if (Math::abs(**mRatio) < 1.) {
82 **mRatio = 1. / **mRatio;
83 std::shared_ptr<SimTerminal<Complex>> tmp = mTerminals[0];
84 mTerminals[0] = mTerminals[1];
85 mTerminals[1] = tmp;
86 Real tmpVolt = mNominalVoltageEnd1;
88 mNominalVoltageEnd2 = tmpVolt;
89 SPDLOG_LOGGER_INFO(mSLog, "Switching terminals to have first terminal at "
90 "higher voltage side. Updated parameters: ");
91 SPDLOG_LOGGER_INFO(
92 mSLog, "Nominal Voltage End 1 = {} [V] Nominal Voltage End 2 = {} [V]",
94 SPDLOG_LOGGER_INFO(mSLog, "Tap Ratio = {} [ ] Phase Shift = {} [deg]",
95 std::abs(**mRatio), std::arg(**mRatio));
96 }
97
98 mSubInductor =
99 std::make_shared<DP::Ph1::Inductor>(**mName + "_ind", mLogLevel);
100 mSubInductor->setParameters(**mInductance);
101 addMNASubComponent(mSubInductor, MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
102 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
103
104 if (mNumVirtualNodes == 3) {
105 mSubResistor =
106 std::make_shared<DP::Ph1::Resistor>(**mName + "_res", mLogLevel);
107 mSubResistor->setParameters(**mResistance);
108 mSubResistor->connect({node(0), mVirtualNodes[2]});
109 mSubInductor->connect({mVirtualNodes[2], mVirtualNodes[0]});
110 addMNASubComponent(mSubResistor, MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
111 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
112 } else {
113 mSubInductor->connect({node(0), mVirtualNodes[0]});
114 }
115
116 Real pSnub = P_SNUB_TRANSFORMER * **mRatedPower;
117 Real qSnub = Q_SNUB_TRANSFORMER * **mRatedPower;
118
119 mSnubberResistance1 = std::pow(std::abs(mNominalVoltageEnd1), 2) / pSnub;
120 mSubSnubResistor1 =
121 std::make_shared<DP::Ph1::Resistor>(**mName + "_snub_res1", mLogLevel);
122 mSubSnubResistor1->setParameters(mSnubberResistance1);
123 mSubSnubResistor1->connect({node(0), DP::SimNode::GND});
124 SPDLOG_LOGGER_INFO(
125 mSLog,
126 "Snubber Resistance 1 (connected to higher voltage side {}) = {} [Ohm]",
127 node(0)->name(), Logger::realToString(mSnubberResistance1));
128 addMNASubComponent(mSubSnubResistor1,
129 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
130 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
131
132 mSnubberResistance2 = std::pow(std::abs(mNominalVoltageEnd2), 2) / pSnub;
133 mSubSnubResistor2 =
134 std::make_shared<DP::Ph1::Resistor>(**mName + "_snub_res2", mLogLevel);
135 mSubSnubResistor2->setParameters(mSnubberResistance2);
136 mSubSnubResistor2->connect({node(1), DP::SimNode::GND});
137 SPDLOG_LOGGER_INFO(
138 mSLog,
139 "Snubber Resistance 2 (connected to lower voltage side {}) = {} [Ohm]",
140 node(1)->name(), Logger::realToString(mSnubberResistance2));
141 addMNASubComponent(mSubSnubResistor2,
142 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
143 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
144
145 // Capacitor created here; its omega-dependent value is set in initializeParentFromNodesAndTerminals().
146 mSubSnubCapacitor2 =
147 std::make_shared<DP::Ph1::Capacitor>(**mName + "_snub_cap2", mLogLevel);
148 mSubSnubCapacitor2->connect({node(1), DP::SimNode::GND});
149 addMNASubComponent(mSubSnubCapacitor2,
150 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
151 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
152}
153
155 Real frequency) {
156 Real omega = 2. * PI * frequency;
157 Real qSnub = Q_SNUB_TRANSFORMER * **mRatedPower;
158 mSnubberCapacitance2 =
159 qSnub / std::pow(std::abs(mNominalVoltageEnd2), 2) / omega;
160 mSubSnubCapacitor2->setParameters(mSnubberCapacitance2);
161 SPDLOG_LOGGER_INFO(
162 mSLog,
163 "Snubber Capacitance 2 (connected to lower voltage side {}) = {} [F]",
164 node(1)->name(), Logger::realToString(mSnubberCapacitance2));
165
166 // Set initial voltage of virtual node in between
167 mVirtualNodes[0]->setInitialVoltage(initialSingleVoltage(1) * **mRatio);
168
169 if (mNumVirtualNodes == 3)
170 mVirtualNodes[2]->setInitialVoltage(initialSingleVoltage(0));
171
172 // Static calculations from load flow data
173 Complex impedance = {**mResistance, omega * **mInductance};
174 SPDLOG_LOGGER_INFO(mSLog, "Reactance={} [Ohm] (referred to primary side)",
175 omega * **mInductance);
176 (**mIntfVoltage)(0, 0) =
177 mVirtualNodes[0]->initialSingleVoltage() - initialSingleVoltage(0);
178 (**mIntfCurrent)(0, 0) = (**mIntfVoltage)(0, 0) / impedance;
179
180 SPDLOG_LOGGER_INFO(
181 mSLog,
182 "\n--- Initialization from powerflow ---"
183 "\nVoltage across: {:s}"
184 "\nCurrent: {:s}"
185 "\nTerminal 0 voltage: {:s}"
186 "\nTerminal 1 voltage: {:s}"
187 "\nVirtual Node 1 voltage: {:s}"
188 "\n--- Initialization from powerflow finished ---",
189 Logger::phasorToString((**mIntfVoltage)(0, 0)),
190 Logger::phasorToString((**mIntfCurrent)(0, 0)),
191 Logger::phasorToString(initialSingleVoltage(0)),
192 Logger::phasorToString(initialSingleVoltage(1)),
193 Logger::phasorToString(mVirtualNodes[0]->initialSingleVoltage()));
194}
195
197 Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) {
198 SPDLOG_LOGGER_INFO(
199 mSLog,
200 "\nTerminal 0 connected to {:s} = sim node {:d}"
201 "\nTerminal 1 connected to {:s} = sim node {:d}",
202 mTerminals[0]->node()->name(), mTerminals[0]->node()->matrixNodeIndex(),
203 mTerminals[1]->node()->name(), mTerminals[1]->node()->matrixNodeIndex());
204}
205
207 SparseMatrixRow &systemMatrix) {
208 // Ideal transformer equations
209 if (terminalNotGrounded(0)) {
210 Math::setMatrixElement(systemMatrix, mVirtualNodes[0]->matrixNodeIndex(),
211 mVirtualNodes[1]->matrixNodeIndex(),
212 Complex(-1.0, 0));
213 Math::setMatrixElement(systemMatrix, mVirtualNodes[1]->matrixNodeIndex(),
214 mVirtualNodes[0]->matrixNodeIndex(),
215 Complex(1.0, 0));
216 }
217 if (terminalNotGrounded(1)) {
218 Math::setMatrixElement(systemMatrix, matrixNodeIndex(1),
219 mVirtualNodes[1]->matrixNodeIndex(), **mRatio);
220 Math::setMatrixElement(systemMatrix, mVirtualNodes[1]->matrixNodeIndex(),
221 matrixNodeIndex(1), -**mRatio);
222 }
223
224 // Add subcomps to system matrix
225 for (auto subcomp : mSubComponents)
226 if (auto mnasubcomp = std::dynamic_pointer_cast<MNAInterface>(subcomp))
227 mnasubcomp->mnaApplySystemMatrixStamp(systemMatrix);
228
229 if (terminalNotGrounded(0)) {
230 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
231 Logger::complexToString(Complex(-1.0, 0)),
232 mVirtualNodes[0]->matrixNodeIndex(),
233 mVirtualNodes[1]->matrixNodeIndex());
234 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
235 Logger::complexToString(Complex(1.0, 0)),
236 mVirtualNodes[1]->matrixNodeIndex(),
237 mVirtualNodes[0]->matrixNodeIndex());
238 }
239 if (terminalNotGrounded(1)) {
240 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
241 Logger::complexToString(**mRatio), matrixNodeIndex(1),
242 mVirtualNodes[1]->matrixNodeIndex());
243 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
244 Logger::complexToString(-**mRatio),
245 mVirtualNodes[1]->matrixNodeIndex(), matrixNodeIndex(1));
246 }
247}
248
250 AttributeBase::List &prevStepDependencies,
251 AttributeBase::List &attributeDependencies,
252 AttributeBase::List &modifiedAttributes) {
253 prevStepDependencies.push_back(mIntfCurrent);
254 prevStepDependencies.push_back(mIntfVoltage);
255 modifiedAttributes.push_back(mRightVector);
256}
257
258void DP::Ph1::Transformer::mnaParentPreStep(Real time, Int timeStepCount) {
260}
261
263 AttributeBase::List &prevStepDependencies,
264 AttributeBase::List &attributeDependencies,
265 AttributeBase::List &modifiedAttributes,
266 Attribute<Matrix>::Ptr &leftVector) {
267 attributeDependencies.push_back(leftVector);
268 modifiedAttributes.push_back(mIntfVoltage);
269 modifiedAttributes.push_back(mIntfCurrent);
270}
271
273 Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
274 this->mnaUpdateVoltage(**leftVector);
275 this->mnaUpdateCurrent(**leftVector);
276}
277
278void DP::Ph1::Transformer::mnaCompUpdateCurrent(const Matrix &leftVector) {
279 (**mIntfCurrent)(0, 0) = mSubInductor->intfCurrent()(0, 0);
280}
281
282void DP::Ph1::Transformer::mnaCompUpdateVoltage(const Matrix &leftVector) {
283 // v1 - v0
284 (**mIntfVoltage)(0, 0) = 0;
285 (**mIntfVoltage)(0, 0) =
286 Math::complexFromVectorElement(leftVector, matrixNodeIndex(1));
287 (**mIntfVoltage)(0, 0) = (**mIntfVoltage)(0, 0) -
288 Math::complexFromVectorElement(
289 leftVector, mVirtualNodes[0]->matrixNodeIndex());
290 SPDLOG_LOGGER_DEBUG(mSLog, "Voltage {:s}",
291 Logger::phasorToString((**mIntfVoltage)(0, 0)));
292}
const Attribute< Real >::Ptr mRatedPower
Rated Apparent Power [VA].
Real mNominalVoltageEnd2
Nominal voltage of secondary side.
Real mNominalVoltageEnd1
Nominal voltage of primary side.
const Attribute< Real >::Ptr mInductance
Inductance [H].
const Attribute< Real >::Ptr mResistance
Resistance [Ohm].
const Attribute< Complex >::Ptr mRatio
Complex transformer ratio.
void addMNASubComponent(typename SimPowerComp< Complex >::Ptr subc, MNA_SUBCOMP_TASK_ORDER preStepOrder, MNA_SUBCOMP_TASK_ORDER postStepOrder, Bool contributeToRightVector)
CompositePowerComp(String uid, String name, Bool hasPreStep, Bool hasPostStep, Logger::Level logLevel)
void setParameters(Real nomVoltageEnd1, Real nomVoltageEnd2, Real ratioAbs, Real ratioPhase, Real resistance, Real inductance)
Defines component parameters.
Transformer(String uid, String name, Logger::Level logLevel=Logger::Level::off, Bool withResistiveLosses=false)
True after createSubComponents() runs; prevents double-construction.
void createSubComponents() override
Constructs and registers MNA subcomponents (incl. terminal swap); idempotent.
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) override
Stamps system matrix.
void mnaParentPreStep(Real time, Int timeStepCount) override
MNA pre step operations.
void mnaParentInitialize(Real omega, Real timeStep, Attribute< Matrix >::Ptr leftVector) override
Initializes internal variables of the component.
void initializeParentFromNodesAndTerminals(Real frequency) override
Initializes component from power flow data.
void mnaParentAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
Add MNA post step dependencies.
void mnaCompUpdateVoltage(const Matrix &leftVector) override
Updates internal voltage variable of the component.
SimPowerComp< Complex >::Ptr clone(String name) override
DEPRECATED: Delete method.
void mnaCompUpdateCurrent(const Matrix &leftVector) override
Updates internal current variable of the component.
void mnaParentAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
Add MNA pre step dependencies.
void mnaParentPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
MNA post step operations.
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.
void mnaUpdateCurrent(const Matrix &leftVector) final
void mnaUpdateVoltage(const Matrix &leftVector) final
Attribute< Matrix >::Ptr mRightVector
void mnaApplyRightSideVectorStamp(Matrix &rightVector) final
const Attribute< MatrixVar< Complex > >::Ptr mIntfCurrent
SimTerminal< Complex >::List mTerminals
SimNode< Complex >::Ptr node(UInt index)
const Attribute< MatrixVar< Complex > >::Ptr mIntfVoltage
SimNode< Complex >::List mVirtualNodes
std::vector< std::shared_ptr< SimPowerComp< Complex > > > mSubComponents
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.