DPsim
Loading...
Searching...
No Matches
DP_Ph3_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/DP/DP_Ph3_PiLine.h>
7
8using namespace CPS;
9
10DP::Ph3::PiLine::PiLine(String uid, String name, Logger::Level logLevel)
11 : Base::Ph3::PiLine(mAttributes),
12 CompositePowerComp<Complex>(uid, name, true, true, logLevel) {
13 mPhaseType = PhaseType::ABC;
14 setVirtualNodeNumber(1);
15 setTerminalNumber(2);
16
17 SPDLOG_LOGGER_INFO(mSLog, "Create {} {}", this->type(), name);
18 **mIntfVoltage = MatrixComp::Zero(3, 1);
19 **mIntfCurrent = MatrixComp::Zero(3, 1);
20}
21
23SimPowerComp<Complex>::Ptr DP::Ph3::PiLine::clone(String name) {
24 auto copy = PiLine::make(name, mLogLevel);
25 copy->setParameters(**mSeriesRes, **mSeriesInd, **mParallelCap,
27 return copy;
28}
29
32 return;
33 mSubCompCreated = true;
34
35 // By default there is always a small conductance to ground to
36 // avoid problems with floating nodes.
37 Matrix defaultParallelCond = Matrix::Zero(3, 3);
38 defaultParallelCond << 1e-6, 0, 0, 0, 1e-6, 0, 0, 0, 1e-6;
40 ((**mParallelCond)(0, 0) > 0) ? **mParallelCond : defaultParallelCond;
41
42 // Create series sub components
44 std::make_shared<DP::Ph3::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<DP::Ph3::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<DP::Ph3::Resistor>(**mName + "_con0", mLogLevel);
64 mSubParallelResistor0->setParameters(2. * (**mParallelCond).inverse());
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<DP::Ph3::Resistor>(**mName + "_con1", mLogLevel);
74 mSubParallelResistor1->setParameters(2. * (**mParallelCond).inverse());
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, 0) > 0) {
83 mSubParallelCapacitor0 =
84 std::make_shared<DP::Ph3::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
94 std::make_shared<DP::Ph3::Capacitor>(**mName + "_cap1", mLogLevel);
95 mSubParallelCapacitor1->setParameters(**mParallelCap / 2.);
97 SimNode::List{SimNode::GND, mTerminals[1]->node()});
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 MatrixComp impedance = MatrixComp::Zero(3, 3);
109 impedance << Complex((**mSeriesRes)(0, 0), omega * (**mSeriesInd)(0, 0)),
110 Complex((**mSeriesRes)(0, 1), omega * (**mSeriesInd)(0, 1)),
111 Complex((**mSeriesRes)(0, 2), omega * (**mSeriesInd)(0, 2)),
112 Complex((**mSeriesRes)(1, 0), omega * (**mSeriesInd)(1, 0)),
113 Complex((**mSeriesRes)(1, 1), omega * (**mSeriesInd)(1, 1)),
114 Complex((**mSeriesRes)(1, 2), omega * (**mSeriesInd)(1, 2)),
115 Complex((**mSeriesRes)(2, 0), omega * (**mSeriesInd)(2, 0)),
116 Complex((**mSeriesRes)(2, 1), omega * (**mSeriesInd)(2, 1)),
117 Complex((**mSeriesRes)(2, 2), omega * (**mSeriesInd)(2, 2));
118 MatrixComp vInitABC = MatrixComp::Zero(3, 1);
119 vInitABC(0, 0) = RMS3PH_TO_PEAK1PH * initialSingleVoltage(1) -
120 RMS3PH_TO_PEAK1PH * initialSingleVoltage(0);
121 vInitABC(1, 0) = vInitABC(0, 0) * SHIFT_TO_PHASE_B;
122 vInitABC(2, 0) = vInitABC(0, 0) * SHIFT_TO_PHASE_C;
123 MatrixComp iInit = impedance.inverse() * vInitABC;
124 **mIntfCurrent = iInit;
125 **mIntfVoltage = vInitABC;
126
127 // Initialization of virtual node
128 // Initial voltage of phase B,C is set after A
129 MatrixComp vInitTerm0 = MatrixComp::Zero(3, 1);
130 vInitTerm0(0, 0) = RMS3PH_TO_PEAK1PH * initialSingleVoltage(0);
131 vInitTerm0(1, 0) = vInitTerm0(0, 0) * SHIFT_TO_PHASE_B;
132 vInitTerm0(2, 0) = vInitTerm0(0, 0) * SHIFT_TO_PHASE_C;
133
134 mVirtualNodes[0]->setInitialVoltage(PEAK1PH_TO_RMS3PH *
135 (vInitTerm0 + **mSeriesRes * iInit));
136
137 SPDLOG_LOGGER_INFO(
138 mSLog,
139 "\n--- Initialization from powerflow ---"
140 "\nVoltage across: {:s}"
141 "\nCurrent: {:s}"
142 "\nTerminal 0 voltage: {:s}"
143 "\nTerminal 1 voltage: {:s}"
144 "\nVirtual Node 1 voltage: {:s}"
145 "\n--- Initialization from powerflow finished ---",
146 Logger::matrixCompToString(**mIntfVoltage),
147 Logger::matrixCompToString(**mIntfCurrent),
148 Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(0)),
149 Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(1)),
150 Logger::phasorToString(mVirtualNodes[0]->initialSingleVoltage()));
151}
152
154 AttributeBase::List &prevStepDependencies,
155 AttributeBase::List &attributeDependencies,
156 AttributeBase::List &modifiedAttributes) {
157 // add pre-step dependencies of component itself
158 prevStepDependencies.push_back(mIntfCurrent);
159 prevStepDependencies.push_back(mIntfVoltage);
160 modifiedAttributes.push_back(mRightVector);
161}
162
163void DP::Ph3::PiLine::mnaParentPreStep(Real time, Int timeStepCount) {
164 // pre-step of component itself
166}
167
168void DP::Ph3::PiLine::mnaParentAddPostStepDependencies(
169 AttributeBase::List &prevStepDependencies,
170 AttributeBase::List &attributeDependencies,
171 AttributeBase::List &modifiedAttributes,
172 Attribute<Matrix>::Ptr &leftVector) {
173 // add post-step dependencies of component itself
174 attributeDependencies.push_back(leftVector);
175 modifiedAttributes.push_back(mIntfVoltage);
176 modifiedAttributes.push_back(mIntfCurrent);
177}
178
179void DP::Ph3::PiLine::mnaParentPostStep(Real time, Int timeStepCount,
180 Attribute<Matrix>::Ptr &leftVector) {
181 // post-step of component itself
182 this->mnaUpdateVoltage(**leftVector);
183 this->mnaUpdateCurrent(**leftVector);
184}
185
186void DP::Ph3::PiLine::mnaCompUpdateVoltage(const Matrix &leftVector) {
187 // v1 - v0
188 **mIntfVoltage = MatrixComp::Zero(3, 1);
189 if (terminalNotGrounded(1)) {
190 (**mIntfVoltage)(0, 0) =
191 Math::complexFromVectorElement(leftVector, matrixNodeIndex(1, 0));
192 (**mIntfVoltage)(1, 0) =
193 Math::complexFromVectorElement(leftVector, matrixNodeIndex(1, 1));
194 (**mIntfVoltage)(2, 0) =
195 Math::complexFromVectorElement(leftVector, matrixNodeIndex(1, 2));
196 }
197 if (terminalNotGrounded(0)) {
198 (**mIntfVoltage)(0, 0) =
199 (**mIntfVoltage)(0, 0) -
200 Math::complexFromVectorElement(leftVector, matrixNodeIndex(0, 0));
201 (**mIntfVoltage)(1, 0) =
202 (**mIntfVoltage)(1, 0) -
203 Math::complexFromVectorElement(leftVector, matrixNodeIndex(0, 1));
204 (**mIntfVoltage)(2, 0) =
205 (**mIntfVoltage)(2, 0) -
206 Math::complexFromVectorElement(leftVector, matrixNodeIndex(0, 2));
207 }
208}
209
210void DP::Ph3::PiLine::mnaCompUpdateCurrent(const Matrix &leftVector) {
211 **mIntfCurrent = mSubSeriesInductor->intfCurrent();
212}
213
214// #### Tear Methods ####
215MNAInterface::List DP::Ph3::PiLine::mnaTearGroundComponents() {
216 MNAInterface::List gndComponents;
217
218 gndComponents.push_back(mSubParallelResistor0);
219 gndComponents.push_back(mSubParallelResistor1);
220
221 if ((**mParallelCap)(0, 0) > 0) {
222 gndComponents.push_back(mSubParallelCapacitor0);
223 gndComponents.push_back(mSubParallelCapacitor1);
224 }
225
226 return gndComponents;
227}
228
229void DP::Ph3::PiLine::mnaTearInitialize(Real omega, Real timeStep) {
230 mSubSeriesResistor->mnaTearSetIdx(mTearIdx);
231 mSubSeriesResistor->mnaTearInitialize(omega, timeStep);
232 mSubSeriesInductor->mnaTearSetIdx(mTearIdx);
233 mSubSeriesInductor->mnaTearInitialize(omega, timeStep);
234}
235
236void DP::Ph3::PiLine::mnaTearApplyMatrixStamp(SparseMatrixRow &tearMatrix) {
237 mSubSeriesResistor->mnaTearApplyMatrixStamp(tearMatrix);
238 mSubSeriesInductor->mnaTearApplyMatrixStamp(tearMatrix);
239}
240
241void DP::Ph3::PiLine::mnaTearApplyVoltageStamp(Matrix &voltageVector) {
242 mSubSeriesInductor->mnaTearApplyVoltageStamp(voltageVector);
243}
244
245void DP::Ph3::PiLine::mnaTearPostStep(MatrixComp voltage, MatrixComp current) {
246 mSubSeriesInductor->mnaTearPostStep(voltage - (**mSeriesRes * current),
247 current);
248 (**mIntfCurrent) = mSubSeriesInductor->intfCurrent();
249}
const Attribute< Matrix >::Ptr mParallelCond
Conductance in parallel to the line [S].
const Attribute< Matrix >::Ptr mSeriesRes
Resistance along the line [ohms].
const Attribute< Matrix >::Ptr mSeriesInd
Inductance along the line [H].
const Attribute< Matrix >::Ptr mParallelCap
Capacitance in parallel to the line [F].
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 mnaParentPreStep(Real time, Int timeStepCount) override
MNA pre and post step operations.
std::shared_ptr< Resistor > mSubSeriesResistor
Series Resistor submodel.
void mnaCompUpdateCurrent(const Matrix &leftVector) override
Updates internal current variable of the component.
PiLine(String uid, String name, Logger::Level logLevel=Logger::Level::off)
Defines UID, name and logging level.
std::shared_ptr< Capacitor > mSubParallelCapacitor1
Parallel capacitor submodel at Terminal 1.
void mnaCompUpdateVoltage(const Matrix &leftVector) override
Updates internal voltage variable of the component.
SimPowerComp< Complex >::Ptr clone(String copySuffix) override
DEPRECATED: Remove method.
std::shared_ptr< Inductor > mSubSeriesInductor
std::shared_ptr< Resistor > mSubParallelResistor0
Parallel Resistor submodel at Terminal 0.
void mnaParentAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
add MNA pre and post step dependencies
void initializeParentFromNodesAndTerminals(Real frequency) override
Derives values from power flow data and pushes them to subcomponents.
void createSubComponents() override
Constructs and registers MNA subcomponents; idempotent.
std::shared_ptr< Resistor > mSubParallelResistor1
Parallel resistor submodel at Terminal 1.
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
void mnaApplyRightSideVectorStamp(Matrix &rightVector) final
const Attribute< MatrixVar< Complex > >::Ptr mIntfCurrent
SimTerminal< Complex >::List mTerminals
const Attribute< MatrixVar< Complex > >::Ptr mIntfVoltage
SimNode< Complex >::List mVirtualNodes
Logger::Level mLogLevel
Component logger control for internal variables.
Logger::Log mSLog
Component logger.