DPsim
SimNode.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/SimNode.h>
10 
11 using namespace CPS;
12 
13 template <typename VarType>
14 SimNode<VarType>::SimNode(String uid, String name,
15  std::vector<UInt> matrixNodeIndex,
16  PhaseType phaseType,
17  const std::vector<Complex> &initialVoltage)
18  : TopologicalNode(uid, name, phaseType, initialVoltage),
19  mVoltage(mAttributes->create<MatrixVar<VarType>>("v")),
20  mApparentPower(mAttributes->create<MatrixVar<VarType>>("s")) {
21 
22  if (phaseType == PhaseType::ABC) {
23  mMatrixNodeIndex = matrixNodeIndex;
24  **mVoltage = MatrixVar<VarType>::Zero(3, 1);
25  **mApparentPower = MatrixVar<VarType>::Zero(3, 1);
26  } else {
27  mMatrixNodeIndex[0] = matrixNodeIndex[0];
28  **mVoltage = MatrixVar<VarType>::Zero(1, 1);
29  **mApparentPower = MatrixVar<VarType>::Zero(1, 1);
30  }
31 }
32 
33 template <typename VarType>
34 SimNode<VarType>::SimNode(PhaseType phaseType)
35  : SimNode("gnd", "gnd", {0, 0, 0}, phaseType, {0, 0, 0}) {
36  mIsGround = true;
37  **mInitialVoltage = MatrixComp::Zero(3, 1);
38  **mVoltage = MatrixVar<VarType>::Zero(3, 1);
39 }
40 
41 template <> void SimNode<Real>::initialize() {
42  if (phaseType() == PhaseType::Single)
43  (**mVoltage)(0, 0) = (RMS3PH_TO_PEAK1PH * (**mInitialVoltage)(0, 0)).real();
44  else
45  **mVoltage = (RMS3PH_TO_PEAK1PH * **mInitialVoltage).real();
46 }
47 
48 template <> void SimNode<Complex>::initialize() {
49  (**mVoltage)(0, 0) = (**mInitialVoltage)(0, 0);
50  if (phaseType() == PhaseType::ABC) {
51  (**mVoltage)(1, 0) = (**mInitialVoltage)(1, 0);
52  (**mVoltage)(2, 0) = (**mInitialVoltage)(2, 0);
53  }
54 }
55 
56 template <typename VarType>
57 void SimNode<VarType>::initialize(Matrix frequencies) {
58  mFrequencies = frequencies;
59  mNumFreqs = static_cast<UInt>(mFrequencies.size());
60  Matrix::Index rowNum = phaseType() == PhaseType::ABC ? 3 : 1;
61  **mVoltage = MatrixVar<VarType>::Zero(rowNum, mNumFreqs);
62 }
63 
64 template <typename VarType>
65 VarType SimNode<VarType>::singleVoltage(PhaseType phaseType) {
66  if (phaseType == PhaseType::B)
67  return (**mVoltage)(1, 0);
68  else if (phaseType == PhaseType::C)
69  return (**mVoltage)(2, 0);
70  else // phaseType == PhaseType::Single || mPhaseType == PhaseType::A
71  return (**mVoltage)(0, 0);
72 }
73 
74 template <typename VarType>
75 UInt SimNode<VarType>::matrixNodeIndex(PhaseType phaseType) {
76  if ((phaseType == PhaseType::A || phaseType == PhaseType::Single) &&
77  (mPhaseType == PhaseType::Single || mPhaseType == PhaseType::A ||
78  mPhaseType == PhaseType::ABC))
79  return mMatrixNodeIndex[0];
80  else if (phaseType == PhaseType::B &&
81  (mPhaseType == PhaseType::B || mPhaseType == PhaseType::ABC))
82  return mMatrixNodeIndex[1];
83  else if (phaseType == PhaseType::C &&
84  (mPhaseType == PhaseType::C || mPhaseType == PhaseType::ABC))
85  return mMatrixNodeIndex[2];
86  else
87  return 0;
88 }
89 
90 template <typename VarType>
92  if (mPhaseType == PhaseType::B)
93  return {mMatrixNodeIndex[1]};
94  else if (mPhaseType == PhaseType::C)
95  return {mMatrixNodeIndex[2]};
96  else if (mPhaseType == PhaseType::ABC)
97  return mMatrixNodeIndex;
98  else // phaseType == PhaseType::Single || mPhaseType == PhaseType::A
99  return {mMatrixNodeIndex[0]};
100 }
101 
102 template <typename VarType> MatrixVar<VarType> SimNode<VarType>::voltage() {
103  return **mVoltage;
104 }
105 
106 template <typename VarType>
107 void SimNode<VarType>::setMatrixNodeIndex(UInt phase, UInt matrixNodeIndex) {
108  mMatrixNodeIndex[phase] = matrixNodeIndex;
109 }
110 
111 template <typename VarType> const Task::List &SimNode<VarType>::mnaTasks() {
112  return mMnaTasks;
113 }
114 
115 template <> void SimNode<Complex>::setVoltage(Complex newVoltage) {
116  (**mVoltage)(0, 0) = newVoltage;
117 }
118 
119 template <> void SimNode<Complex>::setPower(Complex newPower) {
120  (**mApparentPower)(0, 0) = newPower;
121 }
122 
123 template <> void SimNode<Real>::mnaUpdateVoltage(const Matrix &leftVector) {
124  if (mMatrixNodeIndex[0] >= 0)
125  (**mVoltage)(0, 0) =
126  Math::realFromVectorElement(leftVector, mMatrixNodeIndex[0]);
127  if (mPhaseType == PhaseType::ABC) {
128  if (mMatrixNodeIndex[1] >= 0)
129  (**mVoltage)(1, 0) =
130  Math::realFromVectorElement(leftVector, mMatrixNodeIndex[1]);
131  if (mMatrixNodeIndex[2] >= 0)
132  (**mVoltage)(2, 0) =
133  Math::realFromVectorElement(leftVector, mMatrixNodeIndex[2]);
134  }
135 }
136 
137 template <> void SimNode<Complex>::mnaUpdateVoltage(const Matrix &leftVector) {
138  for (UInt freq = 0; freq < mNumFreqs; freq++) {
139  if (mMatrixNodeIndex[0] >= 0)
140  (**mVoltage)(0, freq) = Math::complexFromVectorElement(
141  leftVector, mMatrixNodeIndex[0], mNumFreqs, freq);
142  if (mPhaseType == PhaseType::ABC) {
143  if (mMatrixNodeIndex[1] >= 0)
144  (**mVoltage)(1, freq) = Math::complexFromVectorElement(
145  leftVector, mMatrixNodeIndex[1], mNumFreqs, freq);
146  if (mMatrixNodeIndex[2] >= 0)
147  (**mVoltage)(2, freq) = Math::complexFromVectorElement(
148  leftVector, mMatrixNodeIndex[2], mNumFreqs, freq);
149  }
150  }
151 }
152 
153 template <>
154 void SimNode<Real>::mnaUpdateVoltageHarm(const Matrix &leftVector,
155  Int freqIdx) {}
156 
157 template <>
158 void SimNode<Complex>::mnaUpdateVoltageHarm(const Matrix &leftVector,
159  Int freqIdx) {
160  if (mMatrixNodeIndex[0] >= 0)
161  (**mVoltage)(0, freqIdx) =
162  Math::complexFromVectorElement(leftVector, mMatrixNodeIndex[0]);
163  if (mPhaseType == PhaseType::ABC) {
164  if (mMatrixNodeIndex[1] >= 0)
165  (**mVoltage)(1, freqIdx) =
166  Math::complexFromVectorElement(leftVector, mMatrixNodeIndex[1]);
167  if (mMatrixNodeIndex[2] >= 0)
168  (**mVoltage)(2, freqIdx) =
169  Math::complexFromVectorElement(leftVector, mMatrixNodeIndex[2]);
170  }
171 }
172 
173 template <>
175  std::vector<Attribute<Matrix>::Ptr> leftVectors) {}
176 
177 template <>
179  std::vector<Attribute<Matrix>::Ptr> leftVectors) {
180  mMnaTasks = {std::make_shared<MnaPostStepHarm>(*this, leftVectors)};
181 }
182 
183 template <>
184 void SimNode<Complex>::MnaPostStepHarm::execute(Real time, Int timeStepCount) {
185  for (UInt freq = 0; freq < mNode.mNumFreqs; freq++)
186  mNode.mnaUpdateVoltageHarm(**mLeftVectors[freq], freq);
187 }
188 
189 template <>
190 void SimNode<Real>::MnaPostStepHarm::execute(Real time, Int timeStepCount) {}
191 
192 template class CPS::SimNode<Real>;
193 template class CPS::SimNode<Complex>;
SimNode(String uid, String name, std::vector< UInt > matrixNodeIndex, PhaseType phaseType, const std::vector< Complex > &initialVoltage)
This very general constructor is used by other constructors.
Definition: SimNode.cpp:14
const Attribute< MatrixVar< VarType > >::Ptr mApparentPower
Power injected at node.
Definition: SimNode.h:40
void initialize()
Initialize mVoltage according to mInitialVoltage.
UInt matrixNodeIndex(PhaseType phaseType=PhaseType::Single) override
Returns matrix index for specified phase.
Definition: SimNode.cpp:75