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]});
48 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
49 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, false);
50
52 std::make_shared<EMT::Ph1::Inductor>(**mName + "_ind", mLogLevel);
53 mSubSeriesInductor->setParameters(**mSeriesInd);
54 mSubSeriesInductor->connect({mVirtualNodes[0], mTerminals[1]->node()});
56 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
57 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
58
59 // Create parallel sub components
61 std::make_shared<EMT::Ph1::Resistor>(**mName + "_con0", mLogLevel);
62 mSubParallelResistor0->setParameters(2. / (**mParallelCond));
63 mSubParallelResistor0->connect(
64 SimNode::List{SimNode::GND, mTerminals[0]->node()});
66 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
67 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, false);
68
70 std::make_shared<EMT::Ph1::Resistor>(**mName + "_con1", mLogLevel);
71 mSubParallelResistor1->setParameters(2. / (**mParallelCond));
72 mSubParallelResistor1->connect(
73 SimNode::List{SimNode::GND, mTerminals[1]->node()});
75 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
76 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, false);
77
78 if ((**mParallelCap) > 0) {
79 mSubParallelCapacitor0 =
80 std::make_shared<EMT::Ph1::Capacitor>(**mName + "_cap0", mLogLevel);
81 mSubParallelCapacitor0->setParameters(**mParallelCap / 2.);
82 mSubParallelCapacitor0->connect(
83 SimNode::List{SimNode::GND, mTerminals[0]->node()});
84 addMNASubComponent(mSubParallelCapacitor0,
85 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
86 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
87
88 mSubParallelCapacitor1 =
89 std::make_shared<EMT::Ph1::Capacitor>(**mName + "_cap1", mLogLevel);
90 mSubParallelCapacitor1->setParameters(**mParallelCap / 2.);
91 mSubParallelCapacitor1->connect(
92 SimNode::List{SimNode::GND, mTerminals[1]->node()});
93 addMNASubComponent(mSubParallelCapacitor1,
94 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
95 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
96 }
97}
98
100 // Static calculation
101 Real omega = 2. * PI * frequency;
102 Complex impedance = {**mSeriesRes, omega * **mSeriesInd};
103 Complex voltage =
104 RMS3PH_TO_PEAK1PH * (initialSingleVoltage(1) - initialSingleVoltage(0));
105 (**mIntfVoltage)(0, 0) = voltage.real();
106 (**mIntfCurrent)(0, 0) = (voltage / impedance).real();
107
108 // Initialization of virtual node
109 mVirtualNodes[0]->setInitialVoltage(initialSingleVoltage(0) +
110 (**mIntfCurrent)(0, 0) * **mSeriesRes);
111
112 SPDLOG_LOGGER_DEBUG(mSLog,
113 "\n--debug--"
114 "\n seriesRes: {:s}"
115 "\n seriesInd: {:s}"
116 "\n Impedance: {:s}",
117 Logger::matrixToString(**mSeriesRes),
118 Logger::matrixToString(**mSeriesInd),
119 Logger::complexToString(impedance));
120
121 SPDLOG_LOGGER_INFO(
122 mSLog,
123 "\n--- Initialization from powerflow ---"
124 "\nVoltage across: {:s}"
125 "\nCurrent: {:s}"
126 "\nTerminal 0 voltage: {:s}"
127 "\nTerminal 1 voltage: {:s}"
128 "\nVirtual Node 1 voltage: {:s}"
129 "\n--- Initialization from powerflow finished ---",
130 Logger::matrixToString(**mIntfVoltage),
131 Logger::matrixToString(**mIntfCurrent),
132 Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(0)),
133 Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(1)),
134 Logger::phasorToString(mVirtualNodes[0]->initialSingleVoltage()));
135 mSLog->flush();
136}
137
139 AttributeBase::List &prevStepDependencies,
140 AttributeBase::List &attributeDependencies,
141 AttributeBase::List &modifiedAttributes) {
142 prevStepDependencies.push_back(mIntfCurrent);
143 prevStepDependencies.push_back(mIntfVoltage);
144 modifiedAttributes.push_back(mRightVector);
145}
146
150
152 AttributeBase::List &prevStepDependencies,
153 AttributeBase::List &attributeDependencies,
154 AttributeBase::List &modifiedAttributes,
155 Attribute<Matrix>::Ptr &leftVector) {
156 attributeDependencies.push_back(leftVector);
157 modifiedAttributes.push_back(mIntfVoltage);
158 modifiedAttributes.push_back(mIntfCurrent);
159}
160
161void EMT::Ph1::PiLine::mnaParentPostStep(Real time, Int timeStepCount,
162 Attribute<Matrix>::Ptr &leftVector) {
163 mnaCompUpdateVoltage(**leftVector);
164 mnaCompUpdateCurrent(**leftVector);
165}
166
167void EMT::Ph1::PiLine::mnaCompUpdateVoltage(const Matrix &leftVector) {
168 (**mIntfVoltage)(0, 0) = 0;
169 if (terminalNotGrounded(1))
170 (**mIntfVoltage)(0, 0) =
171 Math::realFromVectorElement(leftVector, matrixNodeIndex(1));
172 if (terminalNotGrounded(0))
173 (**mIntfVoltage)(0, 0) =
174 (**mIntfVoltage)(0, 0) -
175 Math::realFromVectorElement(leftVector, matrixNodeIndex(0));
176}
177
178void EMT::Ph1::PiLine::mnaCompUpdateCurrent(const Matrix &leftVector) {
179 **mIntfCurrent = mSubSeriesInductor->intfCurrent();
180}
181
182// #### Tear Methods ####
183MNAInterface::List EMT::Ph1::PiLine::mnaTearGroundComponents() {
184 MNAInterface::List gndComponents;
185
186 gndComponents.push_back(mSubParallelResistor0);
187 gndComponents.push_back(mSubParallelResistor1);
188
189 if ((**mParallelCap) > 0) {
190 gndComponents.push_back(mSubParallelCapacitor0);
191 gndComponents.push_back(mSubParallelCapacitor1);
192 }
193
194 return gndComponents;
195}
196
197void EMT::Ph1::PiLine::mnaTearInitialize(Real omega, Real timeStep) {
198 mSubSeriesResistor->mnaTearSetIdx(mTearIdx);
199 mSubSeriesResistor->mnaTearInitialize(omega, timeStep);
200 mSubSeriesInductor->mnaTearSetIdx(mTearIdx);
201 mSubSeriesInductor->mnaTearInitialize(omega, timeStep);
202}
203
204void EMT::Ph1::PiLine::mnaTearApplyMatrixStamp(SparseMatrixRow &tearMatrix) {
205 mSubSeriesResistor->mnaTearApplyMatrixStamp(tearMatrix);
206 mSubSeriesInductor->mnaTearApplyMatrixStamp(tearMatrix);
207}
208
209void EMT::Ph1::PiLine::mnaTearApplyVoltageStamp(Matrix &voltageVector) {
210 mSubSeriesInductor->mnaTearApplyVoltageStamp(voltageVector);
211}
212
213void EMT::Ph1::PiLine::mnaTearPostStep(Complex voltage, Complex current) {
214 mSubSeriesInductor->mnaTearPostStep(voltage - current * **mSeriesRes,
215 current);
216 (**mIntfCurrent) = mSubSeriesInductor->intfCurrent();
217}
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.