DPsim
EMT_Ph3_CurrentSource.cpp
1 /* Copyright 2017-2020 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_CurrentSource.h>
10 
11 using namespace CPS;
12 
14  Logger::Level logLevel)
15  : MNASimPowerComp<Real>(uid, name, true, true, logLevel),
16  mCurrentRef(mAttributes->create<MatrixComp>("I_ref")), // rms-value
17  mSrcFreq(mAttributes->createDynamic<Real>("f_src")),
18  mSigOut(mAttributes->createDynamic<Complex>("sigOut")) {
19  mPhaseType = PhaseType::ABC;
20  setVirtualNodeNumber(0);
21  setTerminalNumber(2);
22  **mIntfVoltage = Matrix::Zero(3, 1);
23  **mIntfCurrent = Matrix::Zero(3, 1);
24 }
26  auto copy = CurrentSource::make(name, mLogLevel);
27  copy->setParameters(attributeTyped<MatrixComp>("I_ref")->get(),
28  attributeTyped<Real>("f_src")->get());
29  return copy;
30 }
31 
32 void EMT::Ph3::CurrentSource::setParameters(MatrixComp currentRef,
33  Real srcFreq) {
34  auto srcSigSine = Signal::SineWaveGenerator::make(**mName + "_sw");
35  // Complex(1,0) is used as initialPhasor for signal generator as only phase is used
36  srcSigSine->setParameters(Complex(1, 0), srcFreq);
37  mSrcSig = srcSigSine;
38 
39  **mCurrentRef = currentRef;
40  mSrcFreq->setReference(mSrcSig->mFreq);
41 
42  mSLog->info("\nCurrent reference phasor [I]: {:s}"
43  "\nFrequency [Hz]: {:s}",
44  Logger::matrixCompToString(currentRef),
45  Logger::realToString(srcFreq));
46 
47  mParametersSet = true;
48 }
49 
51  SPDLOG_LOGGER_INFO(
52  mSLog, "\n--- Initialization from node voltages and terminal ---");
53  if (!mParametersSet) {
54  auto srcSigSine =
55  Signal::SineWaveGenerator::make(**mName + "_sw", Logger::Level::off);
56  // Complex(1,0) is used as initialPhasor for signal generator as only phase is used
57  srcSigSine->setParameters(Complex(1, 0), frequency);
58  mSrcSig = srcSigSine;
59 
60  Complex v_ref = initialSingleVoltage(1) - initialSingleVoltage(0);
61  Complex s_ref = terminal(1)->singlePower() - terminal(0)->singlePower();
62 
63  // Current flowing from T1 to T0 (rms value)
64  Complex i_ref = std::conj(s_ref / v_ref / sqrt(3.));
65 
66  **mCurrentRef = CPS::Math::singlePhaseVariableToThreePhase(i_ref);
67  mSrcFreq->setReference(mSrcSig->attributeTyped<Real>("freq"));
68 
69  SPDLOG_LOGGER_INFO(mSLog,
70  "\nReference current: {:s}"
71  "\nReference voltage: {:s}"
72  "\nReference power: {:s}"
73  "\nTerminal 0 voltage: {:s}"
74  "\nTerminal 1 voltage: {:s}"
75  "\nTerminal 0 power: {:s}"
76  "\nTerminal 1 power: {:s}",
77  Logger::phasorToString(i_ref),
78  Logger::phasorToString(v_ref),
79  Logger::complexToString(s_ref),
80  Logger::phasorToString(initialSingleVoltage(0)),
81  Logger::phasorToString(initialSingleVoltage(1)),
82  Logger::complexToString(terminal(0)->singlePower()),
83  Logger::complexToString(terminal(1)->singlePower()));
84  } else {
85  SPDLOG_LOGGER_INFO(
86  mSLog,
87  "\nInitialization from node voltages and terminal omitted (parameter "
88  "already set)."
89  "\nReference voltage: {:s}",
90  Logger::matrixCompToString(attributeTyped<MatrixComp>("I_ref")->get()));
91  }
92  SPDLOG_LOGGER_INFO(
93  mSLog, "\n--- Initialization from node voltages and terminal ---");
94  mSLog->flush();
95 }
96 
98  Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) {
99  updateMatrixNodeIndices();
100 }
101 
103  Matrix &rightVector) {
104  if (terminalNotGrounded(1)) {
105  Math::setVectorElement(rightVector, matrixNodeIndex(1, 0),
106  -(**mIntfCurrent)(0, 0));
107  Math::setVectorElement(rightVector, matrixNodeIndex(1, 1),
108  -(**mIntfCurrent)(1, 0));
109  Math::setVectorElement(rightVector, matrixNodeIndex(1, 2),
110  -(**mIntfCurrent)(2, 0));
111  }
112  if (terminalNotGrounded(0)) {
113  Math::setVectorElement(rightVector, matrixNodeIndex(0, 0),
114  (**mIntfCurrent)(0, 0));
115  Math::setVectorElement(rightVector, matrixNodeIndex(0, 1),
116  (**mIntfCurrent)(1, 0));
117  Math::setVectorElement(rightVector, matrixNodeIndex(0, 2),
118  (**mIntfCurrent)(2, 0));
119  }
120 }
121 
122 void EMT::Ph3::CurrentSource::updateCurrent(Real time) {
123  if (mSrcSig != nullptr) {
124  mSrcSig->step(time);
125  for (int i = 0; i < 3; i++) {
126  (**mIntfCurrent)(i, 0) = RMS_TO_PEAK * Math::abs((**mCurrentRef)(i, 0)) *
127  cos(Math::phase(mSrcSig->getSignal()) +
128  Math::phase((**mCurrentRef)(i, 0)));
129  }
130  } else {
131  **mIntfCurrent = RMS_TO_PEAK * (**mCurrentRef).real();
132  }
133  SPDLOG_LOGGER_DEBUG(mSLog, "\nUpdate current: {:s}",
134  Logger::matrixToString(**mIntfCurrent));
135 }
136 
138  AttributeBase::List &prevStepDependencies,
139  AttributeBase::List &attributeDependencies,
140  AttributeBase::List &modifiedAttributes) {
141  attributeDependencies.push_back(mCurrentRef);
142  modifiedAttributes.push_back(mRightVector);
143  modifiedAttributes.push_back(mIntfVoltage);
144 }
145 
146 void EMT::Ph3::CurrentSource::mnaCompPreStep(Real time, Int timeStepCount) {
147  updateCurrent(time);
148  mnaCompApplyRightSideVectorStamp(**mRightVector);
149 }
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 };
159 
161  Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
162  mnaCompUpdateVoltage(**leftVector);
163 }
164 
165 void EMT::Ph3::CurrentSource::mnaCompUpdateVoltage(const Matrix &leftVector) {
166  // v1 - v0
167  **mIntfVoltage = Matrix::Zero(3, 1);
168  if (terminalNotGrounded(1)) {
169  (**mIntfVoltage)(0, 0) =
170  Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 0));
171  (**mIntfVoltage)(1, 0) =
172  Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 1));
173  (**mIntfVoltage)(2, 0) =
174  Math::realFromVectorElement(leftVector, matrixNodeIndex(1, 2));
175  }
176  if (terminalNotGrounded(0)) {
177  (**mIntfVoltage)(0, 0) =
178  (**mIntfVoltage)(0, 0) -
179  Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 0));
180  (**mIntfVoltage)(1, 0) =
181  (**mIntfVoltage)(1, 0) -
182  Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 1));
183  (**mIntfVoltage)(2, 0) =
184  (**mIntfVoltage)(2, 0) -
185  Math::realFromVectorElement(leftVector, matrixNodeIndex(0, 2));
186  }
187 }
void mnaCompUpdateVoltage(const Matrix &leftVector) override
Returns voltage through the component.
CurrentSource(String uid, String name, Logger::Level logLevel=Logger::Level::off)
Defines UID, name and logging level.
void setParameters(MatrixComp currentRef, Real srcFreq=50.0)
Setter for reference current.
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override
Stamps right side (source) vector.
void initializeFromNodesAndTerminals(Real frequency) override
Initializes component from power flow data.
void mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
Add MNA post step dependencies.
void mnaCompAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
Add MNA pre step dependencies.
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 mnaCompInitialize(Real omega, Real timeStep, Attribute< Matrix >::Ptr leftVector) override
Initializes internal variables of the component.
void mnaCompPreStep(Real time, Int timeStepCount) override
MNA pre step operations.
void mnaCompPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
MNA post step operations.
Base class for all MNA components that are transmitting power.
static MatrixComp singlePhaseVariableToThreePhase(Complex var_1ph)
To convert single phase complex variables (voltages, currents) to symmetrical three phase ones.
Definition: MathUtils.cpp:205
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