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
75
76 // Component parameters are referred to higher voltage side.
77 // Switch terminals to have terminal 0 at higher voltage side
78 // if transformer is connected the other way around.
79 if (Math::abs(**mRatio) < 1.) {
80 **mRatio = 1. / **mRatio;
81 std::shared_ptr<SimTerminal<Complex>> tmp = mTerminals[0];
82 mTerminals[0] = mTerminals[1];
83 mTerminals[1] = tmp;
84 Real tmpVolt = mNominalVoltageEnd1;
86 mNominalVoltageEnd2 = tmpVolt;
87 SPDLOG_LOGGER_INFO(mSLog, "Switching terminals to have first terminal at "
88 "higher voltage side. Updated parameters: ");
89 SPDLOG_LOGGER_INFO(
90 mSLog, "Nominal Voltage End 1 = {} [V] Nominal Voltage End 2 = {} [V]",
92 SPDLOG_LOGGER_INFO(mSLog, "Tap Ratio = {} [ ] Phase Shift = {} [deg]",
93 std::abs(**mRatio), std::arg(**mRatio));
94 }
95
96 // Set initial voltage of virtual node in between
97 mVirtualNodes[0]->setInitialVoltage(initialSingleVoltage(1) * **mRatio);
98
99 // Static calculations from load flow data
100 Real omega = 2. * PI * frequency;
101 Complex impedance = {**mResistance, omega * **mInductance};
102 SPDLOG_LOGGER_INFO(mSLog, "Reactance={} [Ohm] (referred to primary side)",
103 omega * **mInductance);
104 (**mIntfVoltage)(0, 0) =
105 mVirtualNodes[0]->initialSingleVoltage() - initialSingleVoltage(0);
106 (**mIntfCurrent)(0, 0) = (**mIntfVoltage)(0, 0) / impedance;
107
108 // Create series sub components
109 mSubInductor =
110 std::make_shared<DP::Ph1::Inductor>(**mName + "_ind", mLogLevel);
111 mSubInductor->setParameters(**mInductance);
112 addMNASubComponent(mSubInductor, MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
113 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
114
115 if (mNumVirtualNodes == 3) {
116 mVirtualNodes[2]->setInitialVoltage(initialSingleVoltage(0));
117 mSubResistor =
118 std::make_shared<DP::Ph1::Resistor>(**mName + "_res", mLogLevel);
119 mSubResistor->setParameters(**mResistance);
120 mSubResistor->connect({node(0), mVirtualNodes[2]});
121 mSubInductor->connect({mVirtualNodes[2], mVirtualNodes[0]});
122 addMNASubComponent(mSubResistor, MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
123 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
124 } else {
125 mSubInductor->connect({node(0), mVirtualNodes[0]});
126 }
127
128 // Create parallel sub components
129 Real pSnub = P_SNUB_TRANSFORMER * **mRatedPower;
130 Real qSnub = Q_SNUB_TRANSFORMER * **mRatedPower;
131
132 // A snubber conductance is added on the higher voltage side
133 mSnubberResistance1 = std::pow(std::abs(mNominalVoltageEnd1), 2) / pSnub;
134 mSubSnubResistor1 =
135 std::make_shared<DP::Ph1::Resistor>(**mName + "_snub_res1", mLogLevel);
136 mSubSnubResistor1->setParameters(mSnubberResistance1);
137 mSubSnubResistor1->connect({node(0), DP::SimNode::GND});
138 SPDLOG_LOGGER_INFO(
139 mSLog,
140 "Snubber Resistance 1 (connected to higher voltage side {}) = {} [Ohm]",
141 node(0)->name(), Logger::realToString(mSnubberResistance1));
142 addMNASubComponent(mSubSnubResistor1,
143 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
144 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
145
146 // A snubber conductance is added on the lower voltage side
147 mSnubberResistance2 = std::pow(std::abs(mNominalVoltageEnd2), 2) / pSnub;
148 mSubSnubResistor2 =
149 std::make_shared<DP::Ph1::Resistor>(**mName + "_snub_res2", mLogLevel);
150 mSubSnubResistor2->setParameters(mSnubberResistance2);
151 mSubSnubResistor2->connect({node(1), DP::SimNode::GND});
152 SPDLOG_LOGGER_INFO(
153 mSLog,
154 "Snubber Resistance 2 (connected to lower voltage side {}) = {} [Ohm]",
155 node(1)->name(), Logger::realToString(mSnubberResistance2));
156 addMNASubComponent(mSubSnubResistor2,
157 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
158 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
159
160 // // A snubber capacitance is added to higher voltage side (not used as capacitor at high voltage side made it worse)
161 // mSnubberCapacitance1 = qSnub / std::pow(std::abs(mNominalVoltageEnd1),2) / omega;
162 // mSubSnubCapacitor1 = std::make_shared<DP::Ph1::Capacitor>(**mName + "_snub_cap1", mLogLevel);
163 // mSubSnubCapacitor1->setParameters(mSnubberCapacitance1);
164 // mSubSnubCapacitor1->connect({ node(0), DP::SimNode::GND });
165 // SPDLOG_LOGGER_INFO(mSLog, "Snubber Capacitance 1 (connected to higher voltage side {}) = \n{} [F] \n ", node(0)->name(), Logger::realToString(mSnubberCapacitance1));
166 // mSubComponents.push_back(mSubSnubCapacitor1);
167
168 // A snubber capacitance is added to lower voltage side
169 mSnubberCapacitance2 =
170 qSnub / std::pow(std::abs(mNominalVoltageEnd2), 2) / omega;
171 mSubSnubCapacitor2 =
172 std::make_shared<DP::Ph1::Capacitor>(**mName + "_snub_cap2", mLogLevel);
173 mSubSnubCapacitor2->setParameters(mSnubberCapacitance2);
174 mSubSnubCapacitor2->connect({node(1), DP::SimNode::GND});
175 SPDLOG_LOGGER_INFO(
176 mSLog,
177 "Snubber Capacitance 2 (connected to lower voltage side {}) = {} [F]",
178 node(1)->name(), Logger::realToString(mSnubberCapacitance2));
179 addMNASubComponent(mSubSnubCapacitor2,
180 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
181 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
182
183 // Initialize electrical subcomponents
184 SPDLOG_LOGGER_INFO(mSLog, "Electrical subcomponents: ");
185 for (auto subcomp : mSubComponents) {
186 SPDLOG_LOGGER_INFO(mSLog, "- {}", subcomp->name());
187 subcomp->initialize(mFrequencies);
188 subcomp->initializeFromNodesAndTerminals(frequency);
189 }
190
191 SPDLOG_LOGGER_INFO(
192 mSLog,
193 "\n--- Initialization from powerflow ---"
194 "\nVoltage across: {:s}"
195 "\nCurrent: {:s}"
196 "\nTerminal 0 voltage: {:s}"
197 "\nTerminal 1 voltage: {:s}"
198 "\nVirtual Node 1 voltage: {:s}"
199 "\n--- Initialization from powerflow finished ---",
200 Logger::phasorToString((**mIntfVoltage)(0, 0)),
201 Logger::phasorToString((**mIntfCurrent)(0, 0)),
202 Logger::phasorToString(initialSingleVoltage(0)),
203 Logger::phasorToString(initialSingleVoltage(1)),
204 Logger::phasorToString(mVirtualNodes[0]->initialSingleVoltage()));
205}
206
208 Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) {
209 SPDLOG_LOGGER_INFO(
210 mSLog,
211 "\nTerminal 0 connected to {:s} = sim node {:d}"
212 "\nTerminal 1 connected to {:s} = sim node {:d}",
213 mTerminals[0]->node()->name(), mTerminals[0]->node()->matrixNodeIndex(),
214 mTerminals[1]->node()->name(), mTerminals[1]->node()->matrixNodeIndex());
215}
216
218 SparseMatrixRow &systemMatrix) {
219 // Ideal transformer equations
220 if (terminalNotGrounded(0)) {
221 Math::setMatrixElement(systemMatrix, mVirtualNodes[0]->matrixNodeIndex(),
222 mVirtualNodes[1]->matrixNodeIndex(),
223 Complex(-1.0, 0));
224 Math::setMatrixElement(systemMatrix, mVirtualNodes[1]->matrixNodeIndex(),
225 mVirtualNodes[0]->matrixNodeIndex(),
226 Complex(1.0, 0));
227 }
228 if (terminalNotGrounded(1)) {
229 Math::setMatrixElement(systemMatrix, matrixNodeIndex(1),
230 mVirtualNodes[1]->matrixNodeIndex(), **mRatio);
231 Math::setMatrixElement(systemMatrix, mVirtualNodes[1]->matrixNodeIndex(),
232 matrixNodeIndex(1), -**mRatio);
233 }
234
235 // Add subcomps to system matrix
236 for (auto subcomp : mSubComponents)
237 if (auto mnasubcomp = std::dynamic_pointer_cast<MNAInterface>(subcomp))
238 mnasubcomp->mnaApplySystemMatrixStamp(systemMatrix);
239
240 if (terminalNotGrounded(0)) {
241 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
242 Logger::complexToString(Complex(-1.0, 0)),
243 mVirtualNodes[0]->matrixNodeIndex(),
244 mVirtualNodes[1]->matrixNodeIndex());
245 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
246 Logger::complexToString(Complex(1.0, 0)),
247 mVirtualNodes[1]->matrixNodeIndex(),
248 mVirtualNodes[0]->matrixNodeIndex());
249 }
250 if (terminalNotGrounded(1)) {
251 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
252 Logger::complexToString(**mRatio), matrixNodeIndex(1),
253 mVirtualNodes[1]->matrixNodeIndex());
254 SPDLOG_LOGGER_INFO(mSLog, "Add {:s} to system at ({:d},{:d})",
255 Logger::complexToString(-**mRatio),
256 mVirtualNodes[1]->matrixNodeIndex(), matrixNodeIndex(1));
257 }
258}
259
261 AttributeBase::List &prevStepDependencies,
262 AttributeBase::List &attributeDependencies,
263 AttributeBase::List &modifiedAttributes) {
264 prevStepDependencies.push_back(mIntfCurrent);
265 prevStepDependencies.push_back(mIntfVoltage);
266 modifiedAttributes.push_back(mRightVector);
267}
268
269void DP::Ph1::Transformer::mnaParentPreStep(Real time, Int timeStepCount) {
271}
272
274 AttributeBase::List &prevStepDependencies,
275 AttributeBase::List &attributeDependencies,
276 AttributeBase::List &modifiedAttributes,
277 Attribute<Matrix>::Ptr &leftVector) {
278 attributeDependencies.push_back(leftVector);
279 modifiedAttributes.push_back(mIntfVoltage);
280 modifiedAttributes.push_back(mIntfCurrent);
281}
282
284 Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
285 this->mnaUpdateVoltage(**leftVector);
286 this->mnaUpdateCurrent(**leftVector);
287}
288
289void DP::Ph1::Transformer::mnaCompUpdateCurrent(const Matrix &leftVector) {
290 (**mIntfCurrent)(0, 0) = mSubInductor->intfCurrent()(0, 0);
291}
292
293void DP::Ph1::Transformer::mnaCompUpdateVoltage(const Matrix &leftVector) {
294 // v1 - v0
295 (**mIntfVoltage)(0, 0) = 0;
296 (**mIntfVoltage)(0, 0) =
297 Math::complexFromVectorElement(leftVector, matrixNodeIndex(1));
298 (**mIntfVoltage)(0, 0) = (**mIntfVoltage)(0, 0) -
299 Math::complexFromVectorElement(
300 leftVector, mVirtualNodes[0]->matrixNodeIndex());
301 SPDLOG_LOGGER_DEBUG(mSLog, "Voltage {:s}",
302 Logger::phasorToString((**mIntfVoltage)(0, 0)));
303}
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 initializeFromNodesAndTerminals(Real frequency) override
Initializes component from power flow data.
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)
Defines UID, name and logging level.
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 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.