DPsim
Loading...
Searching...
No Matches
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
11using namespace CPS;
12
13template <typename VarType>
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
22template <typename VarType>
23typename SimPowerComp<VarType>::Ptr SimPowerComp<VarType>::clone(String name) {
24 return nullptr;
25}
26
27template <typename VarType> UInt SimPowerComp<VarType>::terminalNumber() {
28 return mNumTerminals;
29}
30
31template <typename VarType>
32typename SimTerminal<VarType>::List SimPowerComp<VarType>::terminals() {
33 return mTerminals;
34}
35
36template <typename VarType>
37typename 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
44template <typename VarType>
45UInt SimPowerComp<VarType>::matrixNodeIndex(UInt nodeIndex) {
46 return mMatrixNodeIndices[nodeIndex * 3];
47}
48
49template <typename VarType>
50UInt SimPowerComp<VarType>::matrixNodeIndex(UInt nodeIndex, UInt phaseIndex) {
51 return mMatrixNodeIndices[nodeIndex * 3 + phaseIndex];
52}
53
54template <typename VarType>
55std::vector<UInt> SimPowerComp<VarType>::matrixNodeIndices(UInt index) {
56 return node(index)->matrixNodeIndices();
57}
58
59template <typename VarType> UInt SimPowerComp<VarType>::virtualNodesNumber() {
60 return mNumVirtualNodes;
61}
62
63template <typename VarType> Bool SimPowerComp<VarType>::hasVirtualNodes() {
64 return mNumVirtualNodes > 0;
66
67template <typename VarType> Bool SimPowerComp<VarType>::hasSubComponents() {
68 return mSubComponents.size() > 0;
69}
70
71template <typename VarType>
72typename SimPowerComp<VarType>::List SimPowerComp<VarType>::subComponents() {
74}
76template <typename VarType>
77typename SimNode<VarType>::List &SimPowerComp<VarType>::virtualNodes() {
78 return mVirtualNodes;
79}
81template <typename VarType>
83 return virtualNode(index)->matrixNodeIndices();
84}
85
86template <typename VarType>
87UInt SimPowerComp<VarType>::virtualSimNode(UInt nodeIndex, UInt phaseIndex) {
88 return virtualMatrixNodeIndices(nodeIndex)[phaseIndex];
89}
91template <typename VarType>
92const MatrixVar<VarType> &SimPowerComp<VarType>::intfCurrent() {
93 return **mIntfCurrent;
94}
95
96template <typename VarType>
97const MatrixVar<VarType> &SimPowerComp<VarType>::intfVoltage() {
98 return **mIntfVoltage;
99}
101template <typename VarType>
102MatrixComp SimPowerComp<VarType>::initialVoltage(UInt index) {
103 return mTerminals[index]->initialVoltage();
105
106template <typename VarType>
107Complex SimPowerComp<VarType>::initialSingleVoltage(UInt index) {
108 return mTerminals[index]->initialSingleVoltage();
109}
111template <typename VarType>
112Bool SimPowerComp<VarType>::terminalNotGrounded(UInt index) {
113 return !mMatrixNodeIndexIsGround[index];
115
116template <typename VarType>
117void SimPowerComp<VarType>::setIntfCurrent(MatrixVar<VarType> current) {
118 **mIntfCurrent = current;
119}
120
121template <typename VarType>
122void SimPowerComp<VarType>::setIntfVoltage(MatrixVar<VarType> voltage) {
123 **mIntfVoltage = voltage;
124}
125
126// #### Terminals ####
127template <typename VarType>
129 return (UInt)(mNumTerminals -
130 std::count(mTerminals.begin(), mTerminals.end(), nullptr));
131}
132
133template <typename VarType>
134Bool SimPowerComp<VarType>::hasUnconnectedTerminals() {
135 return (std::count(mTerminals.begin(), mTerminals.end(), nullptr) > 0);
136}
137
138template <typename VarType>
139void SimPowerComp<VarType>::checkForUnconnectedTerminals() {
140 if (hasUnconnectedTerminals()) {
141 throw SystemError("Found unconnected Terminals for " + **mUID);
142 }
143}
144
145template <typename VarType>
146typename 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
153template <typename VarType>
155 TopologicalTerminal::List terminals;
156 for (typename SimTerminal<VarType>::Ptr term : mTerminals) {
157 terminals.push_back(term);
158 }
159 return terminals;
160}
161
162template <typename VarType>
163void SimPowerComp<VarType>::setTerminalNumber(UInt num) {
164 mNumTerminals = num;
165 mTerminals.resize(mNumTerminals, nullptr);
166 mMatrixNodeIndices.resize(3 * num);
167 mMatrixNodeIndexIsGround.resize(num);
168}
169
170template <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 }
180}
181
182template <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
198template <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 ####
212template <typename VarType> UInt SimPowerComp<VarType>::nodeNumber() {
213 return static_cast<UInt>(
214 std::count(mTerminals.begin(), mTerminals.end(), nullptr));
215}
216
217template <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 ####
227template <typename VarType>
228void SimPowerComp<VarType>::setVirtualNodeNumber(UInt num) {
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
239template <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
255template <typename VarType>
256typename 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 ####
264template <typename VarType>
265void 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 if (nodes[i] == nullptr) {
274 throw SystemError(
275 fmt::format("Node is nullptr for Component {}", **mName));
276 }
277 String name = **mName + "_T" + std::to_string(i);
278 typename SimTerminal<VarType>::Ptr terminal =
279 SimTerminal<VarType>::make(name);
280 terminal->setNode(nodes[i]);
282 }
283}
284
285template <typename VarType>
286void SimPowerComp<VarType>::initialize(Matrix frequencies) {
287 mFrequencies = frequencies;
288 mNumFreqs = static_cast<UInt>(mFrequencies.size());
289
290 if (mPhaseType != PhaseType::ABC) {
291 **mIntfVoltage = MatrixVar<VarType>::Zero(1, mNumFreqs);
292 **mIntfCurrent = MatrixVar<VarType>::Zero(1, mNumFreqs);
293 } else {
294 **mIntfVoltage = MatrixVar<VarType>::Zero(3, mNumFreqs);
295 **mIntfCurrent = MatrixVar<VarType>::Zero(3, mNumFreqs);
296 }
297
298 for (auto node : mVirtualNodes)
299 node->initialize(frequencies);
300}
301
302// Declare specializations to move definitions to .cpp
303template class CPS::SimPowerComp<Real>;
304template class CPS::SimPowerComp<Complex>;
const Attribute< String >::Ptr mName
Human readable name.
String uid()
Returns unique id.
const Attribute< String >::Ptr mUID
Unique identifier.
AttributeList::Ptr mAttributes
Attribute List.
Base class for all components that are transmitting power.
UInt mNumFreqs
Number of network frequencies.
void setVirtualNodeAt(typename SimNode< VarType >::Ptr virtualNode, UInt nodeNum)
Sets the virtual node at index nodeNum.
const Attribute< MatrixVar< VarType > >::Ptr mIntfCurrent
Current through component.
SimTerminal< VarType >::List mTerminals
List of Terminals.
Bool hasVirtualNodes()
Returns true if virtual node number is greater than zero.
std::vector< bool > mMatrixNodeIndexIsGround
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.
std::vector< UInt > mMatrixNodeIndices
Matrix mFrequencies
List of considered network frequencies.
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.
const Attribute< MatrixVar< VarType > >::Ptr mIntfVoltage
Voltage between terminals.
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< Complex >::Ptr virtualNode(UInt index)
TopologicalNode::List topologicalNodes()
Get nodes as base type TopologicalNode.
UInt terminalNumberConnected()
Returns the number of connected Terminals.
SimNode< Complex >::List mVirtualNodes
std::vector< std::shared_ptr< SimPowerComp< VarType > > > mSubComponents
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.
UInt mNumTerminals
Determines the number of Terminals which can be connected to network Nodes.
UInt mNumVirtualNodes
Determines the number of virtual or internal Nodes.
Logger::Log mSLog
Component logger.
TopologicalPowerComp(String uid, String name, Logger::Level logLevel=Logger::Level::off)
Basic constructor that takes UID, name and log level.