DPsim
SimPowerComp.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/SimPowerComp.h>
10 
11 using namespace CPS;
12 
13 template <typename VarType>
14 SimPowerComp<VarType>::SimPowerComp(String uid, String name,
15  Logger::Level logLevel)
16  : TopologicalPowerComp(uid, name, logLevel),
17  mIntfVoltage(mAttributes->create<MatrixVar<VarType>>("v_intf")),
18  mIntfCurrent(mAttributes->create<MatrixVar<VarType>>("i_intf")) {
19  mTerminals.clear();
20 }
21 
22 template <typename VarType>
23 typename SimPowerComp<VarType>::Ptr SimPowerComp<VarType>::clone(String name) {
24  return nullptr;
25 }
26 
27 template <typename VarType> UInt SimPowerComp<VarType>::terminalNumber() {
28  return mNumTerminals;
29 }
30 
31 template <typename VarType>
32 typename SimTerminal<VarType>::List SimPowerComp<VarType>::terminals() {
33  return mTerminals;
34 }
35 
36 template <typename VarType>
37 typename SimNode<VarType>::Ptr SimPowerComp<VarType>::node(UInt index) {
38  if (index >= mTerminals.size()) {
39  throw SystemError("Node not available for " + **mUID);
40  }
41  return mTerminals[index]->node();
42 };
43 
44 template <typename VarType>
45 UInt SimPowerComp<VarType>::matrixNodeIndex(UInt nodeIndex) {
46  return mMatrixNodeIndices[nodeIndex * 3];
47 }
48 
49 template <typename VarType>
50 UInt SimPowerComp<VarType>::matrixNodeIndex(UInt nodeIndex, UInt phaseIndex) {
51  return mMatrixNodeIndices[nodeIndex * 3 + phaseIndex];
52 }
53 
54 template <typename VarType>
55 std::vector<UInt> SimPowerComp<VarType>::matrixNodeIndices(UInt index) {
56  return node(index)->matrixNodeIndices();
57 }
58 
59 template <typename VarType> UInt SimPowerComp<VarType>::virtualNodesNumber() {
60  return mNumVirtualNodes;
61 }
62 
63 template <typename VarType> Bool SimPowerComp<VarType>::hasVirtualNodes() {
64  return mNumVirtualNodes > 0;
65 }
66 
67 template <typename VarType> Bool SimPowerComp<VarType>::hasSubComponents() {
68  return mSubComponents.size() > 0;
69 }
70 
71 template <typename VarType>
72 typename SimPowerComp<VarType>::List SimPowerComp<VarType>::subComponents() {
73  return mSubComponents;
74 }
75 
76 template <typename VarType>
77 typename SimNode<VarType>::List &SimPowerComp<VarType>::virtualNodes() {
78  return mVirtualNodes;
79 }
80 
81 template <typename VarType>
82 std::vector<UInt> SimPowerComp<VarType>::virtualMatrixNodeIndices(UInt index) {
83  return virtualNode(index)->matrixNodeIndices();
84 }
85 
86 template <typename VarType>
87 UInt SimPowerComp<VarType>::virtualSimNode(UInt nodeIndex, UInt phaseIndex) {
88  return virtualMatrixNodeIndices(nodeIndex)[phaseIndex];
89 }
90 
91 template <typename VarType>
92 const MatrixVar<VarType> &SimPowerComp<VarType>::intfCurrent() {
93  return **mIntfCurrent;
94 }
95 
96 template <typename VarType>
97 const MatrixVar<VarType> &SimPowerComp<VarType>::intfVoltage() {
98  return **mIntfVoltage;
99 }
100 
101 template <typename VarType>
102 MatrixComp SimPowerComp<VarType>::initialVoltage(UInt index) {
103  return mTerminals[index]->initialVoltage();
104 }
105 
106 template <typename VarType>
108  return mTerminals[index]->initialSingleVoltage();
109 }
110 
111 template <typename VarType>
113  return !mMatrixNodeIndexIsGround[index];
114 }
115 
116 template <typename VarType>
117 void SimPowerComp<VarType>::setIntfCurrent(MatrixVar<VarType> current) {
118  **mIntfCurrent = current;
119 }
120 
121 template <typename VarType>
122 void SimPowerComp<VarType>::setIntfVoltage(MatrixVar<VarType> voltage) {
123  **mIntfVoltage = voltage;
124 }
125 
126 // #### Terminals ####
127 template <typename VarType>
129  return (UInt)(mNumTerminals -
130  std::count(mTerminals.begin(), mTerminals.end(), nullptr));
131 }
132 
133 template <typename VarType>
135  return (std::count(mTerminals.begin(), mTerminals.end(), nullptr) > 0);
136 }
137 
138 template <typename VarType>
140  if (hasUnconnectedTerminals()) {
141  throw SystemError("Found unconnected Terminals for " + **mUID);
142  }
143 }
144 
145 template <typename VarType>
146 typename SimTerminal<VarType>::Ptr SimPowerComp<VarType>::terminal(UInt index) {
147  if (index >= mTerminals.size()) {
148  throw SystemError("Terminal not available for " + **mUID);
149  }
150  return mTerminals[index];
151 }
152 
153 template <typename VarType>
154 TopologicalTerminal::List SimPowerComp<VarType>::topologicalTerminals() {
155  TopologicalTerminal::List terminals;
156  for (typename SimTerminal<VarType>::Ptr term : mTerminals) {
157  terminals.push_back(term);
158  }
159  return terminals;
160 }
161 
162 template <typename VarType>
164  mNumTerminals = num;
165  mTerminals.resize(mNumTerminals, nullptr);
166  mMatrixNodeIndices.resize(3 * num);
167  mMatrixNodeIndexIsGround.resize(num);
168 }
169 
170 template <typename VarType>
172  typename SimTerminal<VarType>::List terminals) {
173  if (mNumTerminals < terminals.size()) {
174  SPDLOG_LOGGER_ERROR(
175  mSLog, "Number of Terminals is too large for Component {} - Ignoring",
176  **mName);
177  return;
178  }
179  mTerminals = terminals;
180 }
181 
182 template <typename VarType>
184  typename SimTerminal<VarType>::Ptr terminal, UInt terminalPosition) {
185  if (mNumTerminals <= terminalPosition) {
186  SPDLOG_LOGGER_ERROR(
187  mSLog, "Terminal position number too large for Component {} - Ignoring",
188  **mName);
189  return;
190  }
191  mTerminals[terminalPosition] = terminal;
192  SPDLOG_LOGGER_INFO(
193  mSLog, "Set Terminal at position {} to Node {}, simulation node {}",
194  terminalPosition, mTerminals[terminalPosition]->node()->name(),
195  mTerminals[terminalPosition]->matrixNodeIndex());
196 }
197 
198 template <typename VarType>
200  for (UInt nodeIdx = 0; nodeIdx < mNumTerminals; nodeIdx++) {
201  mMatrixNodeIndices[3 * nodeIdx] =
202  node(nodeIdx)->matrixNodeIndex(PhaseType::A);
203  mMatrixNodeIndices[3 * nodeIdx + 1] =
204  node(nodeIdx)->matrixNodeIndex(PhaseType::B);
205  mMatrixNodeIndices[3 * nodeIdx + 2] =
206  node(nodeIdx)->matrixNodeIndex(PhaseType::C);
207  mMatrixNodeIndexIsGround[nodeIdx] = node(nodeIdx)->isGround();
208  }
209 }
210 
211 // #### Nodes ####
212 template <typename VarType> UInt SimPowerComp<VarType>::nodeNumber() {
213  return static_cast<UInt>(
214  std::count(mTerminals.begin(), mTerminals.end(), nullptr));
215 }
216 
217 template <typename VarType>
219  TopologicalNode::List nodes;
220  for (typename SimTerminal<VarType>::Ptr term : mTerminals) {
221  nodes.push_back(term->node());
222  }
223  return nodes;
224 }
225 
226 // #### Virtual Nodes ####
227 template <typename VarType>
229  mNumVirtualNodes = num;
230  mVirtualNodes.resize(mNumVirtualNodes, nullptr);
231 
232  for (UInt idx = 0; idx < mNumVirtualNodes; idx++) {
233  String nodeName = **mName + "_vnode_" + std::to_string(idx);
234  setVirtualNodeAt(std::make_shared<SimNode<VarType>>(nodeName, mPhaseType),
235  idx);
236  }
237 }
238 
239 template <typename VarType>
241  typename SimNode<VarType>::Ptr virtualNode, UInt nodeNum) {
242  if (mNumVirtualNodes <= nodeNum) {
243  SPDLOG_LOGGER_ERROR(
244  mSLog,
245  "Virtual Node position number too large for Component {} - Ignoring",
246  **mName);
247  }
248  mVirtualNodes[nodeNum] = virtualNode;
249  SPDLOG_LOGGER_INFO(
250  mSLog, "Set virtual Node at position {} to Node {}, simulation node {}",
251  nodeNum, mVirtualNodes[nodeNum]->name(),
252  mVirtualNodes[nodeNum]->matrixNodeIndex());
253 }
254 
255 template <typename VarType>
256 typename SimNode<VarType>::Ptr SimPowerComp<VarType>::virtualNode(UInt index) {
257  if (index >= mVirtualNodes.size()) {
258  throw SystemError("Node not available for " + **mUID);
259  }
260  return mVirtualNodes[index];
261 }
262 
263 // #### Other functions ####
264 template <typename VarType>
265 void SimPowerComp<VarType>::connect(typename SimNode<VarType>::List nodes) {
266  if (mNumTerminals < nodes.size()) {
267  SPDLOG_LOGGER_ERROR(
268  mSLog, "Number of Nodes is too large for Component {} - Ignoring",
269  **mName);
270  return;
271  }
272  for (UInt i = 0; i < nodes.size(); i++) {
273  String name = **mName + "_T" + std::to_string(i);
274  typename SimTerminal<VarType>::Ptr terminal =
276  terminal->setNode(nodes[i]);
277  setTerminalAt(terminal, i);
278  }
279 }
280 
281 template <typename VarType>
282 void SimPowerComp<VarType>::initialize(Matrix frequencies) {
283  mFrequencies = frequencies;
284  mNumFreqs = static_cast<UInt>(mFrequencies.size());
285 
286  if (mPhaseType != PhaseType::ABC) {
287  **mIntfVoltage = MatrixVar<VarType>::Zero(1, mNumFreqs);
288  **mIntfCurrent = MatrixVar<VarType>::Zero(1, mNumFreqs);
289  } else {
290  **mIntfVoltage = MatrixVar<VarType>::Zero(3, mNumFreqs);
291  **mIntfCurrent = MatrixVar<VarType>::Zero(3, mNumFreqs);
292  }
293 
294  for (auto node : mVirtualNodes)
295  node->initialize(frequencies);
296 }
297 
298 // Declare specializations to move definitions to .cpp
299 template class CPS::SimPowerComp<Real>;
300 template class CPS::SimPowerComp<Complex>;
Base class for all components that are transmitting power.
Definition: SimPowerComp.h:17
void setVirtualNodeAt(typename SimNode< VarType >::Ptr virtualNode, UInt nodeNum)
Sets the virtual node at index nodeNum.
SimTerminal< VarType >::List mTerminals
List of Terminals.
Definition: SimPowerComp.h:21
Bool hasVirtualNodes()
Returns true if virtual node number is greater than zero.
UInt terminalNumber()
Returns nominal number of Terminals for this component type.
UInt virtualSimNode(UInt nodeIndex, UInt phaseIndex=0)
Get simulation node number from virtual node.
SimPowerComp(String uid, String name, Logger::Level logLevel=Logger::Level::off)
Basic constructor that takes UID, name and log level.
UInt nodeNumber()
Returns the actual number of Nodes / Terminals that are already set to valid Nodes.
SimNode< VarType >::Ptr node(UInt index)
Get pointer to node.
virtual void initialize(Matrix frequencies)
Initialize components with correct network frequencies.
SimTerminal< VarType >::Ptr terminal(UInt index)
Get pointer to Terminal.
SimTerminal< VarType >::List terminals()
Return list of Terminal pointers.
std::vector< UInt > virtualMatrixNodeIndices(UInt index)
Get vector of simulation node numbers from virtual Node.
void connect(typename SimNode< VarType >::List nodes)
Sets all nodes and checks for nominal number of Nodes for this Component.
SimPowerComp< VarType >::List subComponents()
Get list of subcomponents.
UInt virtualNodesNumber()
Returns nominal number of virtual nodes for this component type.
void setTerminalAt(typename SimTerminal< VarType >::Ptr terminal, UInt terminalPosition)
Sets Terminal at index terminalPosition.
SimNode< VarType >::Ptr virtualNode(UInt index)
Get pointer to virtual node.
TopologicalNode::List topologicalNodes()
Get nodes as base type TopologicalNode.
UInt terminalNumberConnected()
Returns the number of connected Terminals.
void setTerminals(typename SimTerminal< VarType >::List terminals)
Bool hasSubComponents()
Returns true if subcomponents included in this component.
void updateMatrixNodeIndices()
Update the "cached" mMatrixNodeIndices and mMatrixNodeIndexIsGround members.
virtual SimPowerComp< VarType >::Ptr clone(String name)
Returns a modified copy of the component with the given suffix added to the name and without.
TopologicalTerminal::List topologicalTerminals()
Returns the list of terminals as TopologicalTerminal pointers.
std::vector< UInt > matrixNodeIndices(UInt index)
TODO replace with access to mMatrixNodeIndices.