DPsim
Loading...
Searching...
No Matches
EMT_Ph3_RXLoad.cpp
Go to the documentation of this file.
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
10
11using namespace CPS;
12
14 : CompositePowerComp<Real>(uid, name, true, true, logLevel),
15 mActivePower(mAttributes->create<Matrix>("P")),
16 mReactivePower(mAttributes->create<Matrix>("Q")),
17 mNomVoltage(mAttributes->create<Real>("V_nom")),
18 mReactanceInSeries(false) {
21
22 SPDLOG_LOGGER_INFO(mSLog, "Create {} {}", this->type(), name);
23 **mIntfVoltage = Matrix::Zero(3, 1);
24 **mIntfCurrent = Matrix::Zero(3, 1);
25 mSLog->flush();
26}
27
30
31EMT::Ph3::RXLoad::RXLoad(String name, Matrix activePower, Matrix reactivePower,
32 Real volt, Logger::Level logLevel)
33 : RXLoad(name, logLevel) {
34 **mActivePower = activePower;
35 **mReactivePower = reactivePower;
36 mPower = MatrixComp::Zero(3, 3);
37 mPower << Complex((**mActivePower)(0, 0), (**mReactivePower)(0, 0)),
38 Complex((**mActivePower)(0, 1), (**mReactivePower)(0, 1)),
39 Complex((**mActivePower)(0, 2), (**mReactivePower)(0, 2)),
40 Complex((**mActivePower)(1, 0), (**mReactivePower)(1, 0)),
41 Complex((**mActivePower)(1, 1), (**mReactivePower)(1, 1)),
42 Complex((**mActivePower)(1, 2), (**mReactivePower)(1, 2)),
43 Complex((**mActivePower)(2, 0), (**mReactivePower)(2, 0)),
44 Complex((**mActivePower)(2, 1), (**mReactivePower)(2, 1)),
45 Complex((**mActivePower)(2, 2), (**mReactivePower)(2, 2));
46
47 **mNomVoltage = volt;
49}
50
58
59void EMT::Ph3::RXLoad::setParameters(Matrix activePower, Matrix reactivePower,
60 Real volt, bool reactanceInSeries) {
61 **mActivePower = activePower;
62 **mReactivePower = reactivePower;
63 mReactanceInSeries = reactanceInSeries;
64
67 }
68 // complex power
69 mPower = MatrixComp::Zero(3, 3);
70 mPower(0, 0) = {(**mActivePower)(0, 0), (**mReactivePower)(0, 0)};
71 mPower(1, 1) = {(**mActivePower)(1, 1), (**mReactivePower)(1, 1)};
72 mPower(2, 2) = {(**mActivePower)(2, 2), (**mReactivePower)(2, 2)};
73
74 **mNomVoltage = volt;
75
76 SPDLOG_LOGGER_INFO(mSLog,
77 "\nActive Power [W]: {}"
78 "\nReactive Power [VAr]: {}",
81 SPDLOG_LOGGER_INFO(mSLog, "Nominal Voltage={} [V]", **mNomVoltage);
82
84}
85
88 return;
89 mSubCompCreated = true;
90
91 // Intentionally empty: which of R/L/C exist depends on the load power sign, known only in
92 // initializeParentFromNodesAndTerminals(), where the sub-components are created. Safe: any
93 // series-mode virtual node is already declared in setParameters().
94}
95
97 Real omega = 2. * PI * frequency;
98
100 **mActivePower = Matrix::Zero(3, 3);
101 (**mActivePower)(0, 0) = mTerminals[0]->singleActivePower() / 3.;
102 (**mActivePower)(1, 1) = mTerminals[0]->singleActivePower() / 3.;
103 (**mActivePower)(2, 2) = mTerminals[0]->singleActivePower() / 3.;
104
105 **mReactivePower = Matrix::Zero(3, 3);
106 (**mReactivePower)(0, 0) = mTerminals[0]->singleReactivePower() / 3.;
107 (**mReactivePower)(1, 1) = mTerminals[0]->singleReactivePower() / 3.;
108 (**mReactivePower)(2, 2) = mTerminals[0]->singleReactivePower() / 3.;
109
110 // complex power
111 mPower = MatrixComp::Zero(3, 3);
112 mPower(0, 0) = {(**mActivePower)(0, 0), (**mReactivePower)(0, 0)};
113 mPower(1, 1) = {(**mActivePower)(1, 1), (**mReactivePower)(1, 1)};
114 mPower(2, 2) = {(**mActivePower)(2, 2), (**mReactivePower)(2, 2)};
115
116 **mNomVoltage = std::abs(mTerminals[0]->initialSingleVoltage());
117
118 SPDLOG_LOGGER_INFO(mSLog,
119 "\nActive Power [W]: {}"
120 "\nReactive Power [VAr]: {}",
123 SPDLOG_LOGGER_INFO(mSLog, "Nominal Voltage={} [V]", **mNomVoltage);
124 }
125
126 // Compute derived impedance values and create+parametrize sub-components
127 // now that power and voltage are guaranteed to be known.
128 if ((**mActivePower)(0, 0) != 0)
130 std::pow(**mNomVoltage / sqrt(3), 2) * (**mActivePower).inverse();
131 else
132 mResistance = Matrix::Zero(3, 3);
133
134 if ((**mReactivePower)(0, 0) != 0)
135 mReactance =
136 std::pow(**mNomVoltage / sqrt(3), 2) * (**mReactivePower).inverse();
137 else
138 mReactance = Matrix::Zero(3, 3);
139
140 if ((**mActivePower)(0, 0) != 0) {
142 std::make_shared<EMT::Ph3::Resistor>(**mName + "_res", mLogLevel);
143 mSubResistor->setParameters(mResistance);
144 if (mReactanceInSeries) {
145 mSubResistor->connect({mTerminals[0]->node(), mVirtualNodes[0]});
146 } else {
147 mSubResistor->connect({SimNode::GND, mTerminals[0]->node()});
148 }
151 }
152
153 if (mReactance(0, 0) > 0) {
154 mInductance = mReactance / omega;
155
157 std::make_shared<EMT::Ph3::Inductor>(**mName + "_ind", mLogLevel);
158 mSubInductor->setParameters(mInductance);
159 if (mReactanceInSeries) {
161 } else {
162 mSubInductor->connect({SimNode::GND, mTerminals[0]->node()});
163 }
166 } else if (mReactance(0, 0) < 0) {
167 mCapacitance = -1. / omega * mReactance.inverse();
168
170 std::make_shared<EMT::Ph3::Capacitor>(**mName + "_cap", mLogLevel);
171 mSubCapacitor->setParameters(mCapacitance);
172 if (mReactanceInSeries) {
174 } else {
175 mSubCapacitor->connect({SimNode::GND, mTerminals[0]->node()});
176 }
180 }
181
182 MatrixComp vInitABC = MatrixComp::Zero(3, 1);
183 vInitABC(0, 0) = RMS3PH_TO_PEAK1PH * mTerminals[0]->initialSingleVoltage();
184 vInitABC(1, 0) = vInitABC(0, 0) * SHIFT_TO_PHASE_B;
185 vInitABC(2, 0) = vInitABC(0, 0) * SHIFT_TO_PHASE_C;
186 **mIntfVoltage = vInitABC.real();
187
188 if (mReactanceInSeries) {
189 MatrixComp impedance = MatrixComp::Zero(3, 3);
190 impedance << Complex(mResistance(0, 0), mReactance(0, 0)),
191 Complex(mResistance(0, 1), mReactance(0, 1)),
192 Complex(mResistance(0, 2), mReactance(0, 2)),
193 Complex(mResistance(1, 0), mReactance(1, 0)),
194 Complex(mResistance(1, 1), mReactance(1, 1)),
195 Complex(mResistance(1, 2), mReactance(1, 2)),
196 Complex(mResistance(2, 0), mReactance(2, 0)),
197 Complex(mResistance(2, 1), mReactance(2, 1)),
198 Complex(mResistance(2, 2), mReactance(2, 2));
199 MatrixComp iInit = impedance.inverse() * vInitABC;
200 **mIntfCurrent = iInit.real();
201
202 // Initialization of virtual node
203 // Initial voltage of phase B,C is set after A
204 MatrixComp vInitTerm0 = MatrixComp::Zero(3, 1);
205 vInitTerm0(0, 0) = RMS3PH_TO_PEAK1PH * initialSingleVoltage(0);
206 vInitTerm0(1, 0) = vInitTerm0(0, 0) * SHIFT_TO_PHASE_B;
207 vInitTerm0(2, 0) = vInitTerm0(0, 0) * SHIFT_TO_PHASE_C;
208 mVirtualNodes[0]->setInitialVoltage(PEAK1PH_TO_RMS3PH *
209 (vInitTerm0 - mResistance * iInit));
210 }
211
212 if ((**mActivePower)(0, 0) != 0) {
213 mSubResistor->initializeFromNodesAndTerminals(frequency);
214 if (!mReactanceInSeries) {
215 **mIntfCurrent += mSubResistor->intfCurrent();
216 }
217 }
218
219 if (mReactance(0, 0) > 0) {
220 mSubInductor->initializeFromNodesAndTerminals(frequency);
221 if (!mReactanceInSeries) {
222 **mIntfCurrent += mSubInductor->intfCurrent();
223 }
224 } else if (mReactance(0, 0) < 0) {
225 mSubCapacitor->initializeFromNodesAndTerminals(frequency);
226 if (!mReactanceInSeries) {
227 **mIntfCurrent += mSubCapacitor->intfCurrent();
228 }
229 }
230
231 SPDLOG_LOGGER_INFO(
232 mSLog,
233 "\n--- Initialization from powerflow ---"
234 "\nVoltage across: {:s}"
235 "\nCurrent: {:s}"
236 "\nTerminal 0 voltage: {:s}"
237 "\nActive Power: {:s}"
238 "\nReactive Power: {:s}"
239 "\nResistance: {:s}"
240 "\nReactance: {:s}"
241 "\n--- Initialization from powerflow finished ---",
248 mSLog->flush();
249}
250
252 AttributeBase::List &prevStepDependencies,
253 AttributeBase::List &attributeDependencies,
254 AttributeBase::List &modifiedAttributes) {
255 modifiedAttributes.push_back(mRightVector);
256};
257
259 AttributeBase::List &prevStepDependencies,
260 AttributeBase::List &attributeDependencies,
261 AttributeBase::List &modifiedAttributes,
262 Attribute<Matrix>::Ptr &leftVector) {
263 attributeDependencies.push_back(leftVector);
264 modifiedAttributes.push_back(mIntfCurrent);
265 modifiedAttributes.push_back(mIntfVoltage);
266};
267
271
273 Attribute<Matrix>::Ptr &leftVector) {
274 mnaCompUpdateVoltage(**leftVector);
275 mnaCompUpdateCurrent(**leftVector);
276}
277
279 **mIntfVoltage = Matrix::Zero(3, 1);
280 (**mIntfVoltage)(0, 0) =
282 (**mIntfVoltage)(1, 0) =
284 (**mIntfVoltage)(2, 0) =
286}
287
289 if (mReactanceInSeries) {
290 **mIntfCurrent = mSubInductor->intfCurrent();
291 } else {
292 **mIntfCurrent = Matrix::Zero(3, 1);
293 for (auto &subc : mSubComponents) {
294 **mIntfCurrent += subc->intfCurrent();
295 }
296 }
297}
std::vector< Ptr > List
Definition Attribute.h:123
AttributePointer< Attribute< T > > Ptr
Definition Attribute.h:249
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)
const Attribute< Matrix >::Ptr mActivePower
Active power [Watt].
Bool mReactanceInSeries
If set to true, the reactance is in series with the resistor. Otherwise it is parallel to the resisto...
void setParameters(Matrix activePower, Matrix reactivePower, Real volt, bool reactanceInSeries=false)
RXLoad(String uid, String name, Logger::Level logLevel=Logger::Level::off)
Defines UID, name and logging level.
std::shared_ptr< EMT::Ph3::Resistor > mSubResistor
Internal resistance.
std::shared_ptr< EMT::Ph3::Inductor > mSubInductor
Internal inductor.
void createSubComponents() override
Constructs and registers MNA subcomponents; idempotent.
std::shared_ptr< EMT::Ph3::Capacitor > mSubCapacitor
Internal capacitor.
Matrix mResistance
Resistance [Ohm].
void initializeParentFromNodesAndTerminals(Real frequency) override
Derives values from power flow data and pushes them to subcomponents.
void mnaParentAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
Matrix mReactance
Reactance [Ohm].
const Attribute< Real >::Ptr mNomVoltage
Nominal voltage [V].
void mnaCompUpdateVoltage(const Matrix &leftVector) override
SimPowerComp< Real >::Ptr clone(String name) override
Returns a modified copy of the component with the given suffix added to the name and without.
void mnaParentPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
void mnaParentPreStep(Real time, Int timeStepCount) override
MNA pre and post step operations.
void mnaCompUpdateCurrent(const Matrix &leftVector) override
Matrix mCapacitance
Capacitance [F].
const Attribute< Matrix >::Ptr mReactivePower
Reactive power [VAr].
void mnaParentAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
Matrix mInductance
Inductance [H].
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.
spdlog::level::level_enum Level
Definition Logger.h:33
static String matrixToString(const Matrix &mat)
Definition Logger.cpp:31
static String phasorToString(const Complex &num)
Definition Logger.cpp:57
Attribute< Matrix >::Ptr mRightVector
static Real realFromVectorElement(const Matrix &mat, Matrix::Index row)
static Ptr GND
Definition SimNode.h:35
UInt matrixNodeIndex(UInt nodeIndex)
const Attribute< MatrixVar< Real > >::Ptr mIntfCurrent
SimTerminal< Real >::List mTerminals
void setVirtualNodeNumber(UInt num)
const Attribute< MatrixVar< Real > >::Ptr mIntfVoltage
std::shared_ptr< SimPowerComp< VarType > > Ptr
SimNode< Real >::List mVirtualNodes
std::vector< std::shared_ptr< SimPowerComp< Real > > > mSubComponents
Complex initialSingleVoltage(UInt index)
void setTerminalNumber(UInt num)
Logger::Level mLogLevel
Component logger control for internal variables.
Logger::Log mSLog
Component logger.
static std::shared_ptr< RXLoad > make(Args &&...args)
Definition PtrFactory.h:19
#define PI
Definition Definitions.h:43
#define RMS3PH_TO_PEAK1PH
Definition Definitions.h:50
#define SHIFT_TO_PHASE_C
Definition Definitions.h:47
#define PEAK1PH_TO_RMS3PH
Definition Definitions.h:51
#define SHIFT_TO_PHASE_B
Definition Definitions.h:46
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > Matrix
Dense matrix for real numbers.
Definition Definitions.h:79
std::string String
Definition Definitions.h:63
double Real
Definition Definitions.h:60
int Int
Definition Definitions.h:59
std::complex< Real > Complex
Definition Definitions.h:61
Eigen::Matrix< Complex, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > MatrixComp
Dense matrix for complex numbers.
Definition Definitions.h:82