DPsim
Loading...
Searching...
No Matches
EMT_Ph1_PiLine.cpp
1/* Author: Christoph Wirtz <christoph.wirtz@fgh-ma.de>
2 * SPDX-FileCopyrightText: 2025 FGH e.V.
3 * SPDX-License-Identifier: MPL-2.0
4 */
5
6#include <dpsim-models/EMT/EMT_Ph1_PiLine.h>
7
8using namespace CPS;
9
10EMT::Ph1::PiLine::PiLine(String uid, String name, Logger::Level logLevel)
11 : Base::Ph1::PiLine(mAttributes),
12 CompositePowerComp<Real>(uid, name, true, true, logLevel) {
13 setVirtualNodeNumber(1);
14 setTerminalNumber(2);
15
16 SPDLOG_LOGGER_INFO(mSLog, "Create {} {}", this->type(), name);
17 **mIntfVoltage = Matrix::Zero(1, 1);
18 **mIntfCurrent = Matrix::Zero(1, 1);
19
20 mSLog->flush();
21}
22
24SimPowerComp<Real>::Ptr EMT::Ph1::PiLine::clone(String name) {
25 auto copy = PiLine::make(name, mLogLevel);
26 copy->setParameters(**mSeriesRes, **mSeriesInd, **mParallelCap,
28 return copy;
29}
30
33 return;
34 mSubCompCreated = true;
35
36 // By default there is always a small conductance to ground to
37 // avoid problems with floating nodes.
38 Real defaultParallelCond = 1e-6;
40 (**mParallelCond > 0) ? **mParallelCond : defaultParallelCond;
41
42 // Create series sub components
44 std::make_shared<EMT::Ph1::Resistor>(**mName + "_res", mLogLevel);
45 mSubSeriesResistor->setParameters(**mSeriesRes);
46 mSubSeriesResistor->connect({mTerminals[0]->node(), mVirtualNodes[0]});
49 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
50 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, false);
51
53 std::make_shared<EMT::Ph1::Inductor>(**mName + "_ind", mLogLevel);
54 mSubSeriesInductor->setParameters(**mSeriesInd);
55 mSubSeriesInductor->connect({mVirtualNodes[0], mTerminals[1]->node()});
58 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
59 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
60
61 // Create parallel sub components
63 std::make_shared<EMT::Ph1::Resistor>(**mName + "_con0", mLogLevel);
64 mSubParallelResistor0->setParameters(2. / (**mParallelCond));
65 mSubParallelResistor0->connect(
66 SimNode::List{SimNode::GND, mTerminals[0]->node()});
69 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
70 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, false);
71
73 std::make_shared<EMT::Ph1::Resistor>(**mName + "_con1", mLogLevel);
74 mSubParallelResistor1->setParameters(2. / (**mParallelCond));
75 mSubParallelResistor1->connect(
76 SimNode::List{SimNode::GND, mTerminals[1]->node()});
79 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
80 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, false);
81
82 if ((**mParallelCap) > 0) {
83 mSubParallelCapacitor0 =
84 std::make_shared<EMT::Ph1::Capacitor>(**mName + "_cap0", mLogLevel);
85 mSubParallelCapacitor0->setParameters(**mParallelCap / 2.);
86 mSubParallelCapacitor0->connect(
87 SimNode::List{SimNode::GND, mTerminals[0]->node()});
88 mSubParallelCapacitor0->initialize(mFrequencies);
89 addMNASubComponent(mSubParallelCapacitor0,
90 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
91 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
92
93 mSubParallelCapacitor1 =
94 std::make_shared<EMT::Ph1::Capacitor>(**mName + "_cap1", mLogLevel);
95 mSubParallelCapacitor1->setParameters(**mParallelCap / 2.);
96 mSubParallelCapacitor1->connect(
97 SimNode::List{SimNode::GND, mTerminals[1]->node()});
98 mSubParallelCapacitor1->initialize(mFrequencies);
99 addMNASubComponent(mSubParallelCapacitor1,
100 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
101 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
102 }
103}
104
106 // Static calculation
107 Real omega = 2. * PI * frequency;
108 Complex impedance = {**mSeriesRes, omega * **mSeriesInd};
109 Complex voltage =
110 RMS3PH_TO_PEAK1PH * (initialSingleVoltage(1) - initialSingleVoltage(0));
111 (**mIntfVoltage)(0, 0) = voltage.real();
112 (**mIntfCurrent)(0, 0) = (voltage / impedance).real();
113
114 // Initialization of virtual node
115 mVirtualNodes[0]->setInitialVoltage(initialSingleVoltage(0) +
116 (**mIntfCurrent)(0, 0) * **mSeriesRes);
117
118 SPDLOG_LOGGER_DEBUG(mSLog,
119 "\n--debug--"
120 "\n seriesRes: {:s}"
121 "\n seriesInd: {:s}"
122 "\n Impedance: {:s}",
123 Logger::matrixToString(**mSeriesRes),
124 Logger::matrixToString(**mSeriesInd),
125 Logger::complexToString(impedance));
126
127 SPDLOG_LOGGER_INFO(
128 mSLog,
129 "\n--- Initialization from powerflow ---"
130 "\nVoltage across: {:s}"
131 "\nCurrent: {:s}"
132 "\nTerminal 0 voltage: {:s}"
133 "\nTerminal 1 voltage: {:s}"
134 "\nVirtual Node 1 voltage: {:s}"
135 "\n--- Initialization from powerflow finished ---",
136 Logger::matrixToString(**mIntfVoltage),
137 Logger::matrixToString(**mIntfCurrent),
138 Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(0)),
139 Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(1)),
140 Logger::phasorToString(mVirtualNodes[0]->initialSingleVoltage()));
141 mSLog->flush();
142}
143
145 AttributeBase::List &prevStepDependencies,
146 AttributeBase::List &attributeDependencies,
147 AttributeBase::List &modifiedAttributes) {
148 prevStepDependencies.push_back(mIntfCurrent);
149 prevStepDependencies.push_back(mIntfVoltage);
150 modifiedAttributes.push_back(mRightVector);
151}
152
156
158 AttributeBase::List &prevStepDependencies,
159 AttributeBase::List &attributeDependencies,
160 AttributeBase::List &modifiedAttributes,
161 Attribute<Matrix>::Ptr &leftVector) {
162 attributeDependencies.push_back(leftVector);
163 modifiedAttributes.push_back(mIntfVoltage);
164 modifiedAttributes.push_back(mIntfCurrent);
165}
166
167void EMT::Ph1::PiLine::mnaParentPostStep(Real time, Int timeStepCount,
168 Attribute<Matrix>::Ptr &leftVector) {
169 mnaCompUpdateVoltage(**leftVector);
170 mnaCompUpdateCurrent(**leftVector);
171}
172
173void EMT::Ph1::PiLine::mnaCompUpdateVoltage(const Matrix &leftVector) {
174 (**mIntfVoltage)(0, 0) = 0;
175 if (terminalNotGrounded(1))
176 (**mIntfVoltage)(0, 0) =
177 Math::realFromVectorElement(leftVector, matrixNodeIndex(1));
178 if (terminalNotGrounded(0))
179 (**mIntfVoltage)(0, 0) =
180 (**mIntfVoltage)(0, 0) -
181 Math::realFromVectorElement(leftVector, matrixNodeIndex(0));
182}
183
184void EMT::Ph1::PiLine::mnaCompUpdateCurrent(const Matrix &leftVector) {
185 **mIntfCurrent = mSubSeriesInductor->intfCurrent();
186}
187
188// #### Tear Methods ####
189MNAInterface::List EMT::Ph1::PiLine::mnaTearGroundComponents() {
190 MNAInterface::List gndComponents;
191
192 gndComponents.push_back(mSubParallelResistor0);
193 gndComponents.push_back(mSubParallelResistor1);
194
195 if ((**mParallelCap) > 0) {
196 gndComponents.push_back(mSubParallelCapacitor0);
197 gndComponents.push_back(mSubParallelCapacitor1);
198 }
199
200 return gndComponents;
201}
202
203void EMT::Ph1::PiLine::mnaTearInitialize(Real omega, Real timeStep) {
204 mSubSeriesResistor->mnaTearSetIdx(mTearIdx);
205 mSubSeriesResistor->mnaTearInitialize(omega, timeStep);
206 mSubSeriesInductor->mnaTearSetIdx(mTearIdx);
207 mSubSeriesInductor->mnaTearInitialize(omega, timeStep);
208}
209
210void EMT::Ph1::PiLine::mnaTearApplyMatrixStamp(SparseMatrixRow &tearMatrix) {
211 mSubSeriesResistor->mnaTearApplyMatrixStamp(tearMatrix);
212 mSubSeriesInductor->mnaTearApplyMatrixStamp(tearMatrix);
213}
214
215void EMT::Ph1::PiLine::mnaTearApplyVoltageStamp(Matrix &voltageVector) {
216 mSubSeriesInductor->mnaTearApplyVoltageStamp(voltageVector);
217}
218
219void EMT::Ph1::PiLine::mnaTearPostStep(Complex voltage, Complex current) {
220 mSubSeriesInductor->mnaTearPostStep(voltage - current * **mSeriesRes,
221 current);
222 (**mIntfCurrent) = mSubSeriesInductor->intfCurrent();
223}
const Attribute< Real >::Ptr mParallelCap
Capacitance in parallel to the line [F].
const Attribute< Real >::Ptr mParallelCond
Conductance in parallel to the line [S].
const Attribute< Real >::Ptr mSeriesInd
Inductance along the line [H].
const Attribute< Real >::Ptr mSeriesRes
Resistance along the line [ohms].
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 mnaParentPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
MNA post step operations.
std::shared_ptr< Inductor > mSubSeriesInductor
void mnaCompUpdateVoltage(const Matrix &leftVector) override
Updates internal voltage variable of the component.
std::shared_ptr< Resistor > mSubParallelResistor1
Parallel resistor submodel at Terminal 1.
void mnaParentAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
Add MNA post step dependencies.
void createSubComponents() override
Constructs and registers MNA subcomponents; idempotent.
void mnaCompUpdateCurrent(const Matrix &leftVector) override
Updates internal current variable of the component.
std::shared_ptr< Resistor > mSubSeriesResistor
Series Resistor submodel.
void mnaParentAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
Add MNA pre step dependencies.
SimPowerComp< Real >::Ptr clone(String copySuffix) override
DEPRECATED: Delete method.
std::shared_ptr< Resistor > mSubParallelResistor0
Parallel Resistor submodel at Terminal 0.
PiLine(String uid, String name, Logger::Level logLevel=Logger::Level::off)
Defines UID, name and logging level.
void initializeParentFromNodesAndTerminals(Real frequency) override
Derives values from power flow data and pushes them to subcomponents.
void mnaParentPreStep(Real time, Int timeStepCount) override
MNA pre 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.
Attribute< Matrix >::Ptr mRightVector
const Attribute< MatrixVar< Real > >::Ptr mIntfCurrent
SimTerminal< Real >::List mTerminals
const Attribute< MatrixVar< Real > >::Ptr mIntfVoltage
SimNode< Real >::List mVirtualNodes
Logger::Level mLogLevel
Component logger control for internal variables.
Logger::Log mSLog
Component logger.