DPsim
EMT_Ph3_PiLine.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/EMT/EMT_Ph3_PiLine.h>
10 
11 using namespace CPS;
12 
13 EMT::Ph3::PiLine::PiLine(String uid, String name, Logger::Level logLevel)
14  : Base::Ph3::PiLine(mAttributes),
15  CompositePowerComp<Real>(uid, name, true, true, logLevel) {
16  mPhaseType = PhaseType::ABC;
17  setVirtualNodeNumber(1);
18  setTerminalNumber(2);
19 
20  SPDLOG_LOGGER_INFO(mSLog, "Create {} {}", this->type(), name);
21  **mIntfVoltage = Matrix::Zero(3, 1);
22  **mIntfCurrent = Matrix::Zero(3, 1);
23 
24  mSLog->flush();
25 }
26 
29  auto copy = PiLine::make(name, mLogLevel);
30  copy->setParameters(**mSeriesRes, **mSeriesInd, **mParallelCap,
31  **mParallelCond);
32  return copy;
33 }
34 
36 
37  // By default there is always a small conductance to ground to
38  // avoid problems with floating nodes.
39  Matrix defaultParallelCond = Matrix::Zero(3, 3);
40  defaultParallelCond << 1e-6, 0, 0, 0, 1e-6, 0, 0, 0, 1e-6;
41  **mParallelCond =
42  ((**mParallelCond)(0, 0) > 0) ? **mParallelCond : defaultParallelCond;
43 
44  // Static calculation
45  Real omega = 2. * PI * frequency;
46  MatrixComp impedance = MatrixComp::Zero(3, 3);
47  impedance << Complex((**mSeriesRes)(0, 0), omega * (**mSeriesInd)(0, 0)),
48  Complex((**mSeriesRes)(0, 1), omega * (**mSeriesInd)(0, 1)),
49  Complex((**mSeriesRes)(0, 2), omega * (**mSeriesInd)(0, 2)),
50  Complex((**mSeriesRes)(1, 0), omega * (**mSeriesInd)(1, 0)),
51  Complex((**mSeriesRes)(1, 1), omega * (**mSeriesInd)(1, 1)),
52  Complex((**mSeriesRes)(1, 2), omega * (**mSeriesInd)(1, 2)),
53  Complex((**mSeriesRes)(2, 0), omega * (**mSeriesInd)(2, 0)),
54  Complex((**mSeriesRes)(2, 1), omega * (**mSeriesInd)(2, 1)),
55  Complex((**mSeriesRes)(2, 2), omega * (**mSeriesInd)(2, 2));
56 
57  MatrixComp vInitABC = MatrixComp::Zero(3, 1);
58  vInitABC(0, 0) = RMS3PH_TO_PEAK1PH * initialSingleVoltage(1) -
59  RMS3PH_TO_PEAK1PH * initialSingleVoltage(0);
60  vInitABC(1, 0) = vInitABC(0, 0) * SHIFT_TO_PHASE_B;
61  vInitABC(2, 0) = vInitABC(0, 0) * SHIFT_TO_PHASE_C;
62  MatrixComp iInit = impedance.inverse() * vInitABC;
63  **mIntfCurrent = iInit.real();
64  **mIntfVoltage = vInitABC.real();
65 
66  // Initialization of virtual node
67  // Initial voltage of phase B,C is set after A
68  MatrixComp vInitTerm0 = MatrixComp::Zero(3, 1);
69  vInitTerm0(0, 0) = RMS3PH_TO_PEAK1PH * initialSingleVoltage(0);
70  vInitTerm0(1, 0) = vInitTerm0(0, 0) * SHIFT_TO_PHASE_B;
71  vInitTerm0(2, 0) = vInitTerm0(0, 0) * SHIFT_TO_PHASE_C;
72 
73  mVirtualNodes[0]->setInitialVoltage(PEAK1PH_TO_RMS3PH *
74  (vInitTerm0 + **mSeriesRes * iInit));
75 
76  // Create series sub components
77  mSubSeriesResistor =
78  std::make_shared<EMT::Ph3::Resistor>(**mName + "_res", mLogLevel);
79  mSubSeriesResistor->setParameters(**mSeriesRes);
80  mSubSeriesResistor->connect({mTerminals[0]->node(), mVirtualNodes[0]});
81  mSubSeriesResistor->initialize(mFrequencies);
82  mSubSeriesResistor->initializeFromNodesAndTerminals(frequency);
83  addMNASubComponent(mSubSeriesResistor,
84  MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
85  MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, false);
86 
87  mSubSeriesInductor =
88  std::make_shared<EMT::Ph3::Inductor>(**mName + "_ind", mLogLevel);
89  mSubSeriesInductor->setParameters(**mSeriesInd);
90  mSubSeriesInductor->connect({mVirtualNodes[0], mTerminals[1]->node()});
91  mSubSeriesInductor->initialize(mFrequencies);
92  mSubSeriesInductor->initializeFromNodesAndTerminals(frequency);
93  addMNASubComponent(mSubSeriesInductor,
94  MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
95  MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
96 
97  // Create parallel sub components
98  mSubParallelResistor0 =
99  std::make_shared<EMT::Ph3::Resistor>(**mName + "_con0", mLogLevel);
100  mSubParallelResistor0->setParameters(2. * (**mParallelCond).inverse());
101  mSubParallelResistor0->connect(
102  SimNode::List{SimNode::GND, mTerminals[0]->node()});
103  mSubParallelResistor0->initialize(mFrequencies);
104  mSubParallelResistor0->initializeFromNodesAndTerminals(frequency);
105  addMNASubComponent(mSubParallelResistor0,
106  MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
107  MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, false);
108 
109  mSubParallelResistor1 =
110  std::make_shared<EMT::Ph3::Resistor>(**mName + "_con1", mLogLevel);
111  mSubParallelResistor1->setParameters(2. * (**mParallelCond).inverse());
112  mSubParallelResistor1->connect(
113  SimNode::List{SimNode::GND, mTerminals[1]->node()});
114  mSubParallelResistor1->initialize(mFrequencies);
115  mSubParallelResistor1->initializeFromNodesAndTerminals(frequency);
116  addMNASubComponent(mSubParallelResistor1,
117  MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
118  MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, false);
119 
120  if ((**mParallelCap)(0, 0) > 0) {
121  mSubParallelCapacitor0 =
122  std::make_shared<EMT::Ph3::Capacitor>(**mName + "_cap0", mLogLevel);
123  mSubParallelCapacitor0->setParameters(**mParallelCap / 2.);
124  mSubParallelCapacitor0->connect(
125  SimNode::List{SimNode::GND, mTerminals[0]->node()});
126  mSubParallelCapacitor0->initialize(mFrequencies);
127  mSubParallelCapacitor0->initializeFromNodesAndTerminals(frequency);
128  addMNASubComponent(mSubParallelCapacitor0,
129  MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
130  MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
131 
132  mSubParallelCapacitor1 =
133  std::make_shared<EMT::Ph3::Capacitor>(**mName + "_cap1", mLogLevel);
134  mSubParallelCapacitor1->setParameters(**mParallelCap / 2.);
135  mSubParallelCapacitor1->connect(
136  SimNode::List{SimNode::GND, mTerminals[1]->node()});
137  mSubParallelCapacitor1->initialize(mFrequencies);
138  mSubParallelCapacitor1->initializeFromNodesAndTerminals(frequency);
139  addMNASubComponent(mSubParallelCapacitor1,
140  MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
141  MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT, true);
142  }
143 
144  SPDLOG_LOGGER_DEBUG(mSLog,
145  "\n--debug--"
146  "\n seriesRes: {:s}"
147  "\n seriesInd: {:s}"
148  "\n Impedance: {:s}"
149  "\n vInit: {:s}"
150  "\n iInit: {:s}",
151  Logger::matrixToString(**mSeriesRes),
152  Logger::matrixToString(**mSeriesInd),
153  Logger::matrixCompToString(impedance),
154  Logger::matrixCompToString(vInitABC),
155  Logger::matrixCompToString(iInit));
156 
157  SPDLOG_LOGGER_INFO(
158  mSLog,
159  "\n--- Initialization from powerflow ---"
160  "\nVoltage across: {:s}"
161  "\nCurrent: {:s}"
162  "\nTerminal 0 voltage: {:s}"
163  "\nTerminal 1 voltage: {:s}"
164  "\nVirtual Node 1 voltage: {:s}"
165  "\n--- Initialization from powerflow finished ---",
166  Logger::matrixToString(**mIntfVoltage),
167  Logger::matrixToString(**mIntfCurrent),
168  Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(0)),
169  Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(1)),
170  Logger::phasorToString(mVirtualNodes[0]->initialSingleVoltage()));
171  mSLog->flush();
172 }
173 
175  AttributeBase::List &prevStepDependencies,
176  AttributeBase::List &attributeDependencies,
177  AttributeBase::List &modifiedAttributes) {
178  prevStepDependencies.push_back(mIntfCurrent);
179  prevStepDependencies.push_back(mIntfVoltage);
180  modifiedAttributes.push_back(mRightVector);
181 }
182 
183 void EMT::Ph3::PiLine::mnaParentPreStep(Real time, Int timeStepCount) {
184  mnaCompApplyRightSideVectorStamp(**mRightVector);
185 }
186 
188  AttributeBase::List &prevStepDependencies,
189  AttributeBase::List &attributeDependencies,
190  AttributeBase::List &modifiedAttributes,
191  Attribute<Matrix>::Ptr &leftVector) {
192  attributeDependencies.push_back(leftVector);
193  modifiedAttributes.push_back(mIntfVoltage);
194  modifiedAttributes.push_back(mIntfCurrent);
195 }
196 
197 void EMT::Ph3::PiLine::mnaParentPostStep(Real time, Int timeStepCount,
198  Attribute<Matrix>::Ptr &leftVector) {
199  mnaCompUpdateVoltage(**leftVector);
200  mnaCompUpdateCurrent(**leftVector);
201 }
202 
203 void EMT::Ph3::PiLine::mnaCompUpdateVoltage(const Matrix &leftVector) {
204  // v1 - v0
205  **mIntfVoltage = Matrix::Zero(3, 1);
206  if (terminalNotGrounded(1)) {
207  (**mIntfVoltage)(0, 0) =
208  Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 0));
209  (**mIntfVoltage)(1, 0) =
210  Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 1));
211  (**mIntfVoltage)(2, 0) =
212  Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 2));
213  }
214  if (terminalNotGrounded(0)) {
215  (**mIntfVoltage)(0, 0) =
216  (**mIntfVoltage)(0, 0) -
217  Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 0));
218  (**mIntfVoltage)(1, 0) =
219  (**mIntfVoltage)(1, 0) -
220  Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 1));
221  (**mIntfVoltage)(2, 0) =
222  (**mIntfVoltage)(2, 0) -
223  Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 2));
224  }
225 }
226 
227 void EMT::Ph3::PiLine::mnaCompUpdateCurrent(const Matrix &leftVector) {
228  **mIntfCurrent = mSubSeriesInductor->intfCurrent();
229 }
Base class for composite power components.
PI-line dynamic phasor model.
PiLine(String uid, String name, Logger::Level logLevel=Logger::Level::off)
Defines UID, name and logging level.
SimPowerComp< Real >::Ptr clone(String copySuffix) override
DEPRECATED: Delete method.
void mnaParentPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
MNA post step operations.
void mnaCompUpdateVoltage(const Matrix &leftVector) override
Updates internal voltage variable 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 initializeFromNodesAndTerminals(Real frequency) override
Initializes component from power flow data.
void mnaCompUpdateCurrent(const Matrix &leftVector) override
Updates internal current variable of the component.
void mnaParentPreStep(Real time, Int timeStepCount) override
MNA pre step operations.
void mnaParentAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
Add MNA pre step dependencies.
String type()
Get component type (cross-platform)
Base class for all components that are transmitting power.
Definition: SimPowerComp.h:17
const Attribute< MatrixVar< Real > >::Ptr mIntfCurrent
Current through component.
Definition: SimPowerComp.h:47
const Attribute< MatrixVar< Real > >::Ptr mIntfVoltage
Voltage between terminals.
Definition: SimPowerComp.h:45
Logger::Log mSLog
Component logger.