9 #include <dpsim-models/EMT/EMT_Ph3_Transformer.h>
14 Logger::Level logLevel,
15 Bool withResistiveLosses)
18 mPhaseType = PhaseType::ABC;
19 if (withResistiveLosses)
20 setVirtualNodeNumber(3);
22 setVirtualNodeNumber(2);
26 SPDLOG_LOGGER_INFO(
mSLog,
"Create {} {}", this->
type(), name);
33 auto copy = Transformer::make(name, mLogLevel);
34 copy->setParameters(mNominalVoltageEnd1, mNominalVoltageEnd2, mRatedPower,
35 std::abs(**mRatio), std::arg(**mRatio), mResistance,
41 Real nomVoltageEnd2, Real ratedPower,
42 Real ratioAbs, Real ratioPhase,
46 Base::Ph3::Transformer::setParameters(nomVoltageEnd1, nomVoltageEnd2,
47 ratedPower, ratioAbs, ratioPhase,
48 resistance, inductance);
51 mSLog,
"Nominal Voltage End 1 = {} [V] Nominal Voltage End 2 = {} [V]",
52 mNominalVoltageEnd1, mNominalVoltageEnd2);
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));
57 mParametersSet =
true;
65 if (Math::abs(**mRatio) < 1.) {
66 **mRatio = 1. / **mRatio;
67 std::shared_ptr<SimTerminal<Real>> tmp = mTerminals[0];
68 mTerminals[0] = mTerminals[1];
70 Real tmpVolt = mNominalVoltageEnd1;
71 mNominalVoltageEnd1 = mNominalVoltageEnd2;
72 mNominalVoltageEnd2 = tmpVolt;
73 SPDLOG_LOGGER_INFO(mSLog,
"Switching terminals to have first terminal at "
74 "higher voltage side. Updated parameters: ");
76 mSLog,
"Nominal Voltage End 1 = {} [V] Nominal Voltage End 2 = {} [V]",
77 mNominalVoltageEnd1, mNominalVoltageEnd2);
78 SPDLOG_LOGGER_INFO(mSLog,
"Tap Ratio = {} [ ] Phase Shift = {} [deg]",
79 std::abs(**mRatio), std::arg(**mRatio));
83 mVirtualNodes[0]->setInitialVoltage(initialSingleVoltage(1) * **mRatio);
86 Real omega = 2. * PI * frequency;
87 MatrixComp impedance = MatrixComp::Zero(3, 3);
88 impedance << Complex(mResistance(0, 0), omega * mInductance(0, 0)),
89 Complex(mResistance(0, 1), omega * mInductance(0, 1)),
90 Complex(mResistance(0, 2), omega * mInductance(0, 2)),
91 Complex(mResistance(1, 0), omega * mInductance(1, 0)),
92 Complex(mResistance(1, 1), omega * mInductance(1, 1)),
93 Complex(mResistance(1, 2), omega * mInductance(1, 2)),
94 Complex(mResistance(2, 0), omega * mInductance(2, 0)),
95 Complex(mResistance(2, 1), omega * mInductance(2, 1)),
96 Complex(mResistance(2, 2), omega * mInductance(2, 2));
98 SPDLOG_LOGGER_INFO(mSLog,
99 "Resistance (referred to higher voltage side) = {} [Ohm]",
100 Logger::matrixToString(mResistance));
101 SPDLOG_LOGGER_INFO(mSLog,
102 "Inductance (referred to higher voltage side) = {} [H]",
103 Logger::matrixToString(mInductance));
104 SPDLOG_LOGGER_INFO(mSLog,
105 "Reactance (referred to higher voltage side) = {} [Ohm]",
106 Logger::matrixToString(omega * mInductance));
108 MatrixComp vInitABC = MatrixComp::Zero(3, 1);
111 (mVirtualNodes[0]->initialSingleVoltage() - initialSingleVoltage(0));
112 vInitABC(1, 0) = vInitABC(0, 0) * SHIFT_TO_PHASE_B;
113 vInitABC(2, 0) = vInitABC(0, 0) * SHIFT_TO_PHASE_C;
115 MatrixComp iInit = impedance.inverse() * vInitABC;
116 **mIntfCurrent = iInit.real();
117 **mIntfVoltage = vInitABC.real();
121 std::make_shared<EMT::Ph3::Inductor>(**mName +
"_ind", mLogLevel);
122 mSubInductor->setParameters(mInductance);
123 addMNASubComponent(mSubInductor, MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
124 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
126 if (mNumVirtualNodes == 3) {
127 mVirtualNodes[2]->setInitialVoltage(initialSingleVoltage(0));
129 std::make_shared<EMT::Ph3::Resistor>(**mName +
"_res", mLogLevel);
130 addMNASubComponent(mSubResistor, MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
131 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
132 mSubResistor->setParameters(mResistance);
133 mSubResistor->connect({node(0), mVirtualNodes[2]});
134 mSubInductor->connect({mVirtualNodes[2], mVirtualNodes[0]});
136 mSubInductor->connect({node(0), mVirtualNodes[0]});
140 Real pSnub = P_SNUB_TRANSFORMER * mRatedPower;
141 Real qSnub = Q_SNUB_TRANSFORMER * mRatedPower;
144 Real snubberResistance1 = std::pow(std::abs(mNominalVoltageEnd1), 2) / pSnub;
145 mSnubberResistance1 =
148 std::make_shared<EMT::Ph3::Resistor>(**mName +
"_snub_res1", mLogLevel);
149 mSubSnubResistor1->setParameters(mSnubberResistance1);
150 mSubSnubResistor1->connect({node(0), EMT::SimNode::GND});
153 "Snubber Resistance 1 (connected to higher voltage side {}) = {} [Ohm]",
154 node(0)->name(), Logger::matrixToString(mSnubberResistance1));
155 addMNASubComponent(mSubSnubResistor1,
156 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
157 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
160 Real snubberResistance2 = std::pow(std::abs(mNominalVoltageEnd2), 2) / pSnub;
161 mSnubberResistance2 =
164 std::make_shared<EMT::Ph3::Resistor>(**mName +
"_snub_res2", mLogLevel);
165 mSubSnubResistor2->setParameters(mSnubberResistance2);
166 mSubSnubResistor2->connect({node(1), EMT::SimNode::GND});
169 "Snubber Resistance 2 (connected to lower voltage side {}) = {} [Ohm]",
170 node(1)->name(), Logger::matrixToString(mSnubberResistance2));
171 addMNASubComponent(mSubSnubResistor2,
172 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
173 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
185 Real snubberCapacitance2 =
186 qSnub / std::pow(std::abs(mNominalVoltageEnd2), 2) / omega;
187 mSnubberCapacitance2 =
190 std::make_shared<EMT::Ph3::Capacitor>(**mName +
"_snub_cap2", mLogLevel);
191 mSubSnubCapacitor2->setParameters(mSnubberCapacitance2);
192 mSubSnubCapacitor2->connect({node(1), EMT::SimNode::GND});
195 "Snubber Capacitance 2 (connected to lower voltage side {}) = {} [F]",
196 node(1)->name(), Logger::matrixToString(mSnubberCapacitance2));
197 addMNASubComponent(mSubSnubCapacitor2,
198 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
199 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
202 SPDLOG_LOGGER_INFO(mSLog,
"Electrical subcomponents: ");
203 for (
auto subcomp : mSubComponents) {
204 SPDLOG_LOGGER_INFO(mSLog,
"- {}", subcomp->name());
205 subcomp->initialize(mFrequencies);
206 subcomp->initializeFromNodesAndTerminals(frequency);
211 "\n--- Initialization from powerflow ---"
212 "\nVoltage across: {:s}"
214 "\nTerminal 0 voltage: {:s}"
215 "\nTerminal 1 voltage: {:s}"
216 "\nVirtual Node 1 voltage: {:s}"
217 "\n--- Initialization from powerflow finished ---",
218 Logger::matrixToString(**mIntfVoltage),
219 Logger::matrixToString(**mIntfCurrent),
220 Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(0)),
221 Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(1)),
222 Logger::phasorToString(RMS3PH_TO_PEAK1PH *
223 mVirtualNodes[0]->initialSingleVoltage()));
230 "\nTerminal 0 connected to {:s} = sim node {:d}"
231 "\nTerminal 1 connected to {:s} = sim node {:d}",
232 mTerminals[0]->node()->name(), mTerminals[0]->node()->matrixNodeIndex(),
233 mTerminals[1]->node()->name(), mTerminals[1]->node()->matrixNodeIndex());
237 SparseMatrixRow &systemMatrix) {
239 if (terminalNotGrounded(0)) {
240 Math::setMatrixElement(
241 systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
242 mVirtualNodes[1]->matrixNodeIndex(PhaseType::A), -1.);
243 Math::setMatrixElement(
244 systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
245 mVirtualNodes[1]->matrixNodeIndex(PhaseType::B), -1.);
246 Math::setMatrixElement(
247 systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
248 mVirtualNodes[1]->matrixNodeIndex(PhaseType::C), -1.);
250 Math::setMatrixElement(systemMatrix,
251 mVirtualNodes[1]->matrixNodeIndex(PhaseType::A),
252 mVirtualNodes[0]->matrixNodeIndex(PhaseType::A), 1.);
253 Math::setMatrixElement(systemMatrix,
254 mVirtualNodes[1]->matrixNodeIndex(PhaseType::B),
255 mVirtualNodes[0]->matrixNodeIndex(PhaseType::B), 1.);
256 Math::setMatrixElement(systemMatrix,
257 mVirtualNodes[1]->matrixNodeIndex(PhaseType::C),
258 mVirtualNodes[0]->matrixNodeIndex(PhaseType::C), 1.);
260 if (terminalNotGrounded(1)) {
261 Math::setMatrixElement(systemMatrix, matrixNodeIndex(1, 0),
262 mVirtualNodes[1]->matrixNodeIndex(PhaseType::A),
264 Math::setMatrixElement(systemMatrix, matrixNodeIndex(1, 1),
265 mVirtualNodes[1]->matrixNodeIndex(PhaseType::B),
267 Math::setMatrixElement(systemMatrix, matrixNodeIndex(1, 2),
268 mVirtualNodes[1]->matrixNodeIndex(PhaseType::C),
270 Math::setMatrixElement(systemMatrix,
271 mVirtualNodes[1]->matrixNodeIndex(PhaseType::A),
272 matrixNodeIndex(1, 0), -(**mRatio).real());
273 Math::setMatrixElement(systemMatrix,
274 mVirtualNodes[1]->matrixNodeIndex(PhaseType::B),
275 matrixNodeIndex(1, 1), -(**mRatio).real());
276 Math::setMatrixElement(systemMatrix,
277 mVirtualNodes[1]->matrixNodeIndex(PhaseType::C),
278 matrixNodeIndex(1, 2), -(**mRatio).real());
282 for (
auto subcomp : mSubComponents)
283 if (
auto mnasubcomp = std::dynamic_pointer_cast<MNAInterface>(subcomp))
284 mnasubcomp->mnaApplySystemMatrixStamp(systemMatrix);
286 if (terminalNotGrounded(0)) {
287 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
288 Logger::complexToString(Complex(-1.0, 0)),
289 mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
290 mVirtualNodes[1]->matrixNodeIndex(PhaseType::A));
291 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
292 Logger::complexToString(Complex(-1.0, 0)),
293 mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
294 mVirtualNodes[1]->matrixNodeIndex(PhaseType::B));
295 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
296 Logger::complexToString(Complex(-1.0, 0)),
297 mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
298 mVirtualNodes[1]->matrixNodeIndex(PhaseType::C));
300 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
301 Logger::complexToString(Complex(1.0, 0)),
302 mVirtualNodes[1]->matrixNodeIndex(PhaseType::A),
303 mVirtualNodes[0]->matrixNodeIndex(PhaseType::A));
304 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
305 Logger::complexToString(Complex(1.0, 0)),
306 mVirtualNodes[1]->matrixNodeIndex(PhaseType::B),
307 mVirtualNodes[0]->matrixNodeIndex(PhaseType::B));
308 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
309 Logger::complexToString(Complex(1.0, 0)),
310 mVirtualNodes[1]->matrixNodeIndex(PhaseType::C),
311 mVirtualNodes[0]->matrixNodeIndex(PhaseType::C));
313 if (terminalNotGrounded(1)) {
314 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
315 Logger::complexToString(**mRatio), matrixNodeIndex(1, 0),
316 mVirtualNodes[1]->matrixNodeIndex(PhaseType::A));
317 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
318 Logger::complexToString(**mRatio), matrixNodeIndex(1, 1),
319 mVirtualNodes[1]->matrixNodeIndex(PhaseType::B));
320 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
321 Logger::complexToString(**mRatio), matrixNodeIndex(1, 2),
322 mVirtualNodes[1]->matrixNodeIndex(PhaseType::C));
324 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
325 Logger::complexToString(-**mRatio),
326 mVirtualNodes[1]->matrixNodeIndex(PhaseType::A),
327 matrixNodeIndex(1, 0));
328 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
329 Logger::complexToString(-**mRatio),
330 mVirtualNodes[1]->matrixNodeIndex(PhaseType::B),
331 matrixNodeIndex(1, 1));
332 SPDLOG_LOGGER_INFO(mSLog,
"Add {:s} to system at ({:d},{:d})",
333 Logger::complexToString(-**mRatio),
334 mVirtualNodes[1]->matrixNodeIndex(PhaseType::C),
335 matrixNodeIndex(1, 2));
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);
349 mnaCompApplyRightSideVectorStamp(**mRightVector);
353 AttributeBase::List &prevStepDependencies,
354 AttributeBase::List &attributeDependencies,
355 AttributeBase::List &modifiedAttributes,
357 attributeDependencies.push_back(leftVector);
358 modifiedAttributes.push_back(mIntfVoltage);
359 modifiedAttributes.push_back(mIntfCurrent);
364 mnaCompUpdateVoltage(**leftVector);
365 mnaCompUpdateCurrent(**leftVector);
369 **mIntfCurrent = mSubInductor->intfCurrent();
374 **mIntfVoltage = Matrix::Zero(3, 1);
375 if (terminalNotGrounded(1)) {
376 (**mIntfVoltage)(0, 0) =
377 Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 0));
378 (**mIntfVoltage)(1, 0) =
379 Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 1));
380 (**mIntfVoltage)(2, 0) =
381 Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 2));
383 if (terminalNotGrounded(0)) {
384 (**mIntfVoltage)(0, 0) =
385 (**mIntfVoltage)(0, 0) -
386 Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 0));
387 (**mIntfVoltage)(1, 0) =
388 (**mIntfVoltage)(1, 0) -
389 Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 1));
390 (**mIntfVoltage)(2, 0) =
391 (**mIntfVoltage)(2, 0) -
392 Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 2));
Base class for composite power components.
String type()
Get component type (cross-platform)
static Matrix singlePhaseParameterToThreePhase(Real parameter)
To convert single phase parameters to symmetrical three phase ones.
Base class for all components that are transmitting power.
const Attribute< MatrixVar< Real > >::Ptr mIntfCurrent
Current through component.
const Attribute< MatrixVar< Real > >::Ptr mIntfVoltage
Voltage between terminals.
Logger::Log mSLog
Component logger.