DPsim
DP_Ph1_Resistor.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/DP/DP_Ph1_Resistor.h>
10 
11 using namespace CPS;
12 
13 DP::Ph1::Resistor::Resistor(String uid, String name, Logger::Level logLevel)
14  : MNASimPowerComp<Complex>(uid, name, false, true, logLevel),
15  Base::Ph1::Resistor(mAttributes) {
16  **mIntfVoltage = MatrixComp::Zero(1, 1);
17  **mIntfCurrent = MatrixComp::Zero(1, 1);
18  setTerminalNumber(2);
19 }
20 
22  auto copy = Resistor::make(name, mLogLevel);
23  copy->setParameters(**mResistance);
24  return copy;
25 }
26 
28 
29  Complex impedance = {**mResistance, 0};
30  (**mIntfVoltage)(0, 0) = initialSingleVoltage(1) - initialSingleVoltage(0);
31  (**mIntfCurrent)(0, 0) = (**mIntfVoltage)(0, 0) / impedance;
32 
33  SPDLOG_LOGGER_INFO(mSLog,
34  "\nResistance [Ohm]: {:s}"
35  "\nImpedance [Ohm]: {:s}",
36  Logger::realToString(**mResistance),
37  Logger::complexToString(impedance));
38  SPDLOG_LOGGER_INFO(mSLog,
39  "\n--- Initialization from powerflow ---"
40  "\nVoltage across: {:s}"
41  "\nCurrent: {:s}"
42  "\nTerminal 0 voltage: {:s}"
43  "\nTerminal 1 voltage: {:s}"
44  "\n--- Initialization from powerflow finished ---",
45  Logger::phasorToString((**mIntfVoltage)(0, 0)),
46  Logger::phasorToString((**mIntfCurrent)(0, 0)),
47  Logger::phasorToString(initialSingleVoltage(0)),
48  Logger::phasorToString(initialSingleVoltage(1)));
49 }
50 
51 // #### MNA functions ####
52 void DP::Ph1::Resistor::mnaCompInitialize(Real omega, Real timeStep,
53  Attribute<Matrix>::Ptr leftVector) {
54  updateMatrixNodeIndices();
55 
56  **mRightVector = Matrix::Zero(0, 0);
57 
58  SPDLOG_LOGGER_INFO(mSLog,
59  "\n--- MNA initialization ---"
60  "\nInitial voltage {:s}"
61  "\nInitial current {:s}"
62  "\n--- MNA initialization finished ---",
63  Logger::phasorToString((**mIntfVoltage)(0, 0)),
64  Logger::phasorToString((**mIntfCurrent)(0, 0)));
65 }
66 
67 void DP::Ph1::Resistor::mnaCompInitializeHarm(
68  Real omega, Real timeStep,
69  std::vector<Attribute<Matrix>::Ptr> leftVectors) {
70  updateMatrixNodeIndices();
71 
72  mMnaTasks.push_back(std::make_shared<MnaPostStepHarm>(*this, leftVectors));
73 }
74 
76  SparseMatrixRow &systemMatrix) {
77  Complex conductance = Complex(1. / **mResistance, 0);
78 
79  for (UInt freq = 0; freq < mNumFreqs; freq++) {
80  MNAStampUtils::stampAdmittance(
81  conductance, systemMatrix, matrixNodeIndex(0), matrixNodeIndex(1),
82  terminalNotGrounded(0), terminalNotGrounded(1), mSLog, mNumFreqs, freq);
83  }
84 }
85 
87  SparseMatrixRow &systemMatrix, Int freqIdx) {
88  Complex conductance = Complex(1. / **mResistance, 0);
89 
90  MNAStampUtils::stampAdmittance(conductance, systemMatrix, matrixNodeIndex(0),
91  matrixNodeIndex(1), terminalNotGrounded(0),
92  terminalNotGrounded(1), mSLog);
93 }
94 
96  AttributeBase::List &prevStepDependencies,
97  AttributeBase::List &attributeDependencies,
98  AttributeBase::List &modifiedAttributes,
99  Attribute<Matrix>::Ptr &leftVector) {
100  attributeDependencies.push_back(leftVector);
101  modifiedAttributes.push_back(this->mIntfVoltage);
102  modifiedAttributes.push_back(this->mIntfCurrent);
103 }
104 
105 void DP::Ph1::Resistor::mnaCompPostStep(Real time, Int timeStepCount,
106  Attribute<Matrix>::Ptr &leftVector) {
107  this->mnaUpdateVoltage(**leftVector);
108  this->mnaUpdateCurrent(**leftVector);
109 }
110 
111 void DP::Ph1::Resistor::MnaPostStepHarm::execute(Real time, Int timeStepCount) {
112  for (UInt freq = 0; freq < mResistor.mNumFreqs; freq++)
113  mResistor.mnaCompUpdateVoltageHarm(**mLeftVectors[freq], freq);
114  mResistor.mnaCompUpdateCurrentHarm();
115 }
116 
117 void DP::Ph1::Resistor::mnaCompUpdateVoltage(const Matrix &leftVector) {
118  // v1 - v0
119  for (UInt freq = 0; freq < mNumFreqs; freq++) {
120  (**mIntfVoltage)(0, freq) = 0;
121  if (terminalNotGrounded(1))
122  (**mIntfVoltage)(0, freq) = Math::complexFromVectorElement(
123  leftVector, matrixNodeIndex(1), mNumFreqs, freq);
124  if (terminalNotGrounded(0))
125  (**mIntfVoltage)(0, freq) =
126  (**mIntfVoltage)(0, freq) -
127  Math::complexFromVectorElement(leftVector, matrixNodeIndex(0),
128  mNumFreqs, freq);
129 
130  SPDLOG_LOGGER_DEBUG(mSLog, "Voltage {:s}",
131  Logger::phasorToString((**mIntfVoltage)(0, freq)));
132  }
133 }
134 
135 void DP::Ph1::Resistor::mnaCompUpdateCurrent(const Matrix &leftVector) {
136  for (UInt freq = 0; freq < mNumFreqs; freq++) {
137  (**mIntfCurrent)(0, freq) = (**mIntfVoltage)(0, freq) / **mResistance;
138  SPDLOG_LOGGER_DEBUG(mSLog, "Current {:s}",
139  Logger::phasorToString((**mIntfCurrent)(0, freq)));
140  }
141 }
142 
143 void DP::Ph1::Resistor::mnaCompUpdateVoltageHarm(const Matrix &leftVector,
144  Int freqIdx) {
145  // v1 - v0
146  (**mIntfVoltage)(0, freqIdx) = 0;
147  if (terminalNotGrounded(1))
148  (**mIntfVoltage)(0, freqIdx) =
149  Math::complexFromVectorElement(leftVector, matrixNodeIndex(1));
150  if (terminalNotGrounded(0))
151  (**mIntfVoltage)(0, freqIdx) =
152  (**mIntfVoltage)(0, freqIdx) -
153  Math::complexFromVectorElement(leftVector, matrixNodeIndex(0));
154 
155  SPDLOG_LOGGER_DEBUG(mSLog, "Voltage {:s}",
156  Logger::phasorToString((**mIntfVoltage)(0, freqIdx)));
157 }
158 
159 void DP::Ph1::Resistor::mnaCompUpdateCurrentHarm() {
160  for (UInt freq = 0; freq < mNumFreqs; freq++) {
161  (**mIntfCurrent)(0, freq) = (**mIntfVoltage)(0, freq) / **mResistance;
162  SPDLOG_LOGGER_DEBUG(mSLog, "Current {:s}",
163  Logger::phasorToString((**mIntfCurrent)(0, freq)));
164  }
165 }
166 
167 void DP::Ph1::Resistor::mnaTearApplyMatrixStamp(SparseMatrixRow &tearMatrix) {
168  Math::addToMatrixElement(tearMatrix, mTearIdx, mTearIdx,
169  Complex(**mResistance, 0));
170 }
171 
172 // #### DAE functions ####
173 
174 void DP::Ph1::Resistor::daeResidual(double ttime, const double state[],
175  const double dstate_dt[], double resid[],
176  std::vector<int> &off) {
177  // new state vector definintion:
178  // state[0]=node0_voltage
179  // state[1]=node1_voltage
180  // ....
181  // state[n]=noden_voltage
182  // state[n+1]=component0_voltage
183  // state[n+2]=component0_inductance (not yet implemented)
184  // ...
185  // state[m-1]=componentm_voltage
186  // state[m]=componentm_inductance
187  // ...
188  // state[x] = nodal_equation_1
189  // state[x+1] = nodal_equation_2
190  // ...
191 
192  int Pos1 = matrixNodeIndex(0);
193  int Pos2 = matrixNodeIndex(1);
194  int c_offset = off[0] + off[1]; //current offset for component
195  int n_offset_1 =
196  c_offset + Pos1 + 1; // current offset for first nodal equation
197  int n_offset_2 =
198  c_offset + Pos2 + 1; // current offset for second nodal equation
199  resid[c_offset] = (state[Pos2] - state[Pos1]) -
200  state[c_offset]; // Voltage equation for Resistor
201  //resid[c_offset+1] = ; //TODO : add inductance equation
202  resid[n_offset_1] += 1.0 / **mResistance * state[c_offset];
203  resid[n_offset_2] += 1.0 / **mResistance * state[c_offset];
204  off[1] += 1;
205 }
206 
207 Complex DP::Ph1::Resistor::daeInitialize() { return (**mIntfVoltage)(0, 0); }
Dynamic phasor resistor model.
Complex daeInitialize()
Voltage Getter.
void mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector)
add MNA pre and post step dependencies
void mnaCompApplySystemMatrixStampHarm(SparseMatrixRow &systemMatrix, Int freqIdx)
Stamps system matrix considering the frequency index.
Resistor(String uid, String name, Logger::Level loglevel=Logger::Level::off)
Defines UID, name and logging level.
void mnaCompPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector)
MNA pre and post step operations.
void daeResidual(double ttime, const double state[], const double dstate_dt[], double resid[], std::vector< int > &off)
Residual Function for DAE Solver.
void mnaCompUpdateCurrent(const Matrix &leftVector)
Update interface current from MNA system result.
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix)
Stamps system matrix.
SimPowerComp< Complex >::Ptr clone(String name)
Returns a modified copy of the component with the given suffix added to the name and without.
void mnaCompUpdateVoltage(const Matrix &leftVector)
Update interface voltage from MNA system result.
void initializeFromNodesAndTerminals(Real frequency)
Initializes component from power flow data.
Base class for all MNA components that are transmitting power.
Base class for all components that are transmitting power.
Definition: SimPowerComp.h:17
const Attribute< MatrixVar< Complex > >::Ptr mIntfCurrent
Current through component.
Definition: SimPowerComp.h:47
const Attribute< MatrixVar< Complex > >::Ptr mIntfVoltage
Voltage between terminals.
Definition: SimPowerComp.h:45