DPsim
Loading...
Searching...
No Matches
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
11using namespace CPS;
12
13template <typename VarType>
14SimNode<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
33template <typename VarType>
34SimNode<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
41template <> 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();
47
48template <> 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
56template <typename VarType>
57void 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
64template <typename VarType>
65std::shared_ptr<TopologicalNode> SimNode<VarType>::clone(String name) {
66 auto nodeCpy = SimNode<VarType>::make(name, phaseType());
67 nodeCpy->setInitialVoltage(initialVoltage());
68 return nodeCpy;
69}
70
71template <typename VarType>
72VarType SimNode<VarType>::singleVoltage(PhaseType phaseType) {
73 if (phaseType == PhaseType::B)
74 return (**mVoltage)(1, 0);
75 else if (phaseType == PhaseType::C)
76 return (**mVoltage)(2, 0);
77 else // phaseType == PhaseType::Single || mPhaseType == PhaseType::A
78 return (**mVoltage)(0, 0);
79}
80
81template <typename VarType>
82UInt SimNode<VarType>::matrixNodeIndex(PhaseType phaseType) {
83 if ((phaseType == PhaseType::A || phaseType == PhaseType::Single) &&
84 (mPhaseType == PhaseType::Single || mPhaseType == PhaseType::A ||
85 mPhaseType == PhaseType::ABC))
86 return mMatrixNodeIndex[0];
87 else if (phaseType == PhaseType::B &&
88 (mPhaseType == PhaseType::B || mPhaseType == PhaseType::ABC))
89 return mMatrixNodeIndex[1];
90 else if (phaseType == PhaseType::C &&
91 (mPhaseType == PhaseType::C || mPhaseType == PhaseType::ABC))
92 return mMatrixNodeIndex[2];
93 else
94 return 0;
95}
97template <typename VarType>
99 if (mPhaseType == PhaseType::B)
100 return {mMatrixNodeIndex[1]};
101 else if (mPhaseType == PhaseType::C)
102 return {mMatrixNodeIndex[2]};
103 else if (mPhaseType == PhaseType::ABC)
104 return mMatrixNodeIndex;
105 else // phaseType == PhaseType::Single || mPhaseType == PhaseType::A
106 return {mMatrixNodeIndex[0]};
107}
108
109template <typename VarType> MatrixVar<VarType> SimNode<VarType>::voltage() {
110 return **mVoltage;
111}
112
113template <typename VarType>
114void SimNode<VarType>::setMatrixNodeIndex(UInt phase, UInt matrixNodeIndex) {
115 mMatrixNodeIndex[phase] = matrixNodeIndex;
116}
117
118template <typename VarType> const Task::List &SimNode<VarType>::mnaTasks() {
119 return mMnaTasks;
120}
121
122template <> void SimNode<Complex>::setVoltage(Complex newVoltage) {
123 (**mVoltage)(0, 0) = newVoltage;
124}
125
126template <> void SimNode<Complex>::setPower(Complex newPower) {
127 (**mApparentPower)(0, 0) = newPower;
128}
129
130template <> void SimNode<Real>::mnaUpdateVoltage(const Matrix &leftVector) {
131 if (mMatrixNodeIndex[0] >= 0)
132 (**mVoltage)(0, 0) =
133 Math::realFromVectorElement(leftVector, mMatrixNodeIndex[0]);
134 if (mPhaseType == PhaseType::ABC) {
135 if (mMatrixNodeIndex[1] >= 0)
136 (**mVoltage)(1, 0) =
137 Math::realFromVectorElement(leftVector, mMatrixNodeIndex[1]);
138 if (mMatrixNodeIndex[2] >= 0)
139 (**mVoltage)(2, 0) =
140 Math::realFromVectorElement(leftVector, mMatrixNodeIndex[2]);
141 }
142}
143
144template <> void SimNode<Complex>::mnaUpdateVoltage(const Matrix &leftVector) {
145 for (UInt freq = 0; freq < mNumFreqs; freq++) {
146 if (mMatrixNodeIndex[0] >= 0)
147 (**mVoltage)(0, freq) = Math::complexFromVectorElement(
148 leftVector, mMatrixNodeIndex[0], mNumFreqs, freq);
149 if (mPhaseType == PhaseType::ABC) {
150 if (mMatrixNodeIndex[1] >= 0)
151 (**mVoltage)(1, freq) = Math::complexFromVectorElement(
152 leftVector, mMatrixNodeIndex[1], mNumFreqs, freq);
153 if (mMatrixNodeIndex[2] >= 0)
154 (**mVoltage)(2, freq) = Math::complexFromVectorElement(
155 leftVector, mMatrixNodeIndex[2], mNumFreqs, freq);
156 }
157 }
158}
159
160template <>
161void SimNode<Real>::mnaUpdateVoltageHarm(const Matrix &leftVector,
162 Int freqIdx) {}
163
164template <>
165void SimNode<Complex>::mnaUpdateVoltageHarm(const Matrix &leftVector,
166 Int freqIdx) {
167 if (mMatrixNodeIndex[0] >= 0)
168 (**mVoltage)(0, freqIdx) =
169 Math::complexFromVectorElement(leftVector, mMatrixNodeIndex[0]);
170 if (mPhaseType == PhaseType::ABC) {
171 if (mMatrixNodeIndex[1] >= 0)
172 (**mVoltage)(1, freqIdx) =
173 Math::complexFromVectorElement(leftVector, mMatrixNodeIndex[1]);
174 if (mMatrixNodeIndex[2] >= 0)
175 (**mVoltage)(2, freqIdx) =
176 Math::complexFromVectorElement(leftVector, mMatrixNodeIndex[2]);
177 }
178}
179
180template <>
181void SimNode<Real>::mnaInitializeHarm(
182 std::vector<Attribute<Matrix>::Ptr> leftVectors) {}
183
184template <>
185void SimNode<Complex>::mnaInitializeHarm(
186 std::vector<Attribute<Matrix>::Ptr> leftVectors) {
187 mMnaTasks = {std::make_shared<MnaPostStepHarm>(*this, leftVectors)};
188}
189
190template <>
191void SimNode<Complex>::MnaPostStepHarm::execute(Real time, Int timeStepCount) {
192 for (UInt freq = 0; freq < mNode.mNumFreqs; freq++)
193 mNode.mnaUpdateVoltageHarm(**mLeftVectors[freq], freq);
194}
195
196template <>
197void SimNode<Real>::MnaPostStepHarm::execute(Real time, Int timeStepCount) {}
198
199template class CPS::SimNode<Real>;
200template class CPS::SimNode<Complex>;
String uid()
Returns unique id.
AttributeList::Ptr mAttributes
Attribute List.
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
void initialize()
Initialize mVoltage according to mInitialVoltage.
const Task::List & mnaTasks()
Return list of MNA tasks.
Definition SimNode.cpp:118
UInt matrixNodeIndex(PhaseType phaseType=PhaseType::Single) override
Returns matrix index for specified phase.
Definition SimNode.cpp:82
UInt mNumFreqs
Number of harmonics.
Definition SimNode.h:26
std::vector< UInt > matrixNodeIndices() override
Returns all matrix indices.
Definition SimNode.cpp:98
const Attribute< MatrixVar< VarType > >::Ptr mApparentPower
Power injected at node.
Definition SimNode.h:40
Matrix mFrequencies
List of considered network harmonics.
Definition SimNode.h:24