Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/traction_wire/Circuit.h
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4
// This program and the accompanying materials are made available under the
5
// terms of the Eclipse Public License 2.0 which is available at
6
// https://www.eclipse.org/legal/epl-2.0/
7
// This Source Code may also be made available under the following Secondary
8
// Licenses when the conditions for such availability set forth in the Eclipse
9
// Public License 2.0 are satisfied: GNU General Public License, version 2
10
// or later which is available at
11
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
/****************************************************************************/
14
/// @file Circuit.h
15
/// @author Jakub Sevcik (RICE)
16
/// @author Jan Prikryl (RICE)
17
/// @date 2019-12-15
18
///
19
/// @note based on console-based C++ DC circuits simulator,
20
/// https://github.com/rka97/Circuits-Solver by
21
/// Ahmad Khaled, Ahmad Essam, Omnia Zakaria, Mary Nader
22
/// and available under MIT license, see https://github.com/rka97/Circuits-Solver/blob/master/LICENSE
23
///
24
// Representation of electric circuit of overhead wires
25
/****************************************************************************/
26
#pragma once
27
#include <config.h>
28
29
#include <vector>
30
#ifdef HAVE_EIGEN
31
#ifdef _MSC_VER
32
#pragma warning(push)
33
#pragma warning(disable: 4127 4464 5031)
34
#endif
35
// avoid warnings in clang
36
#ifdef __clang__
37
#pragma clang system_header
38
#endif
39
#include <Eigen/Dense>
40
#include <Eigen/Geometry>
41
#include <Eigen/Sparse>
42
#ifdef _MSC_VER
43
#pragma warning(pop)
44
#endif
45
#endif
46
47
#include "Element.h"
48
49
// ===========================================================================
50
// class declarations
51
// ===========================================================================
52
class Node;
53
54
55
// ===========================================================================
56
// class definitions
57
// ===========================================================================
58
/**
59
* All interactions will be through this class, the user will know nothing about the other classes,
60
* and will interact only through the names of the elements/nodes.
61
*/
62
class Circuit {
63
64
private:
65
66
std::vector<Node*>* nodes;
67
std::vector<Element*>* elements;
68
std::vector<Element*>* voltageSources;
69
70
int lastId;
71
bool iscleaned;
72
73
/// @brief The electric current limit of the voltage sources.
74
double circuitCurrentLimit;
75
76
/**
77
* @brief Best alpha scaling value.
78
*
79
* This parameter is used to scale down the power demands of current sources (vehicles
80
* that draw power from the circuit) so that a solution of the system can be found.
81
* Note: the system is nonlinear (quadratic), hence in some cases (typically too high
82
* power demands) a solution cannot be found. In that moment we decrease all power
83
* requirements by `alpha` and try to solve again, until we find alpha that ensures
84
* stable solution. This is then reported as alphaBest.
85
*/
86
double alphaBest;
87
public:
88
/**
89
* @brief Flag of alpha scaling parameter
90
*
91
* returns ALPHA_NOT_APPLIED => alpha should be 1
92
* returns ALPHA_CURRENT_LIMITS => alpha is lower than one due to electric current limits of the substation
93
* returns ALPHA_VOLTAGE_LIMITS => alpha is not one due to inability of network to transfer requested power due to overhead wire resistance
94
* returns ALPHA_NOT_CONVERGING => number of allowed iterations exceeded
95
*/
96
enum alphaFlag {
97
/// @brief The scaling alpha is not applied (is one)
98
ALPHA_NOT_APPLIED = 0,
99
/// @brief The scaling alpha is applied (is not one) due to current limits
100
ALPHA_CURRENT_LIMITS,
101
/// @brief The scaling alpha is applied (is not one] due to voltage limits
102
ALPHA_VOLTAGE_LIMITS,
103
/// @brief The Newton-Rhapson method has reached maximum iterations and no solution of circuit has been found with actual value of alpha
104
ALPHA_NOT_CONVERGING
105
};
106
private:
107
alphaFlag alphaReason;
108
109
public:
110
Node* getNode(std::string name);
111
Element* getElement(std::string name);
112
Node* getNode(int id);
113
Element* getVoltageSource(int id);
114
std::vector<Element*>* getCurrentSources();
115
116
/// @brief The sum of voltage source powers in the circuit
117
double getTotalPowerOfCircuitSources();
118
/// @brief The sum of voltage source currents in the circuit
119
double getTotalCurrentOfCircuitSources();
120
/// @brief List of currents of voltage sources as a string
121
std::string& getCurrentsOfCircuitSource(std::string& currents);
122
123
void lock();
124
void unlock();
125
126
/// @brief return alphaBest variable, the best alpha scaling value
127
double getAlphaBest() {
128
return alphaBest;
129
}
130
131
/// @brief return the reason why `alpha` scaling value has been used
132
alphaFlag getAlphaReason() {
133
return alphaReason;
134
}
135
136
private:
137
138
Element* getElement(int id);
139
/*
140
* detects removable nodes = sets node variable "isremovable" to true if node is removable and adds id of such node to "removable_ids" vector
141
* node is denoted as removable if it is connected just to 2 elements and both of them are resistor
142
* the reason is that in such case there are two serial resistor and we can only sum their resistance value
143
*
144
* "removable_ids" vector is sort from the least to the greatest
145
*/
146
void detectRemovableNodes(std::vector<int>* removable_ids);
147
148
void deployResults(double* vals, std::vector<int>* removable_ids);
149
150
#ifdef HAVE_EIGEN
151
/*
152
* creates all of the equations that represent the circuit
153
* in the form Ax = B(1/x) where A and B are matrices
154
* @param eqn : A
155
* @param vals : B
156
*/
157
bool createEquationsNRmethod(double*& eqs, double*& vals, std::vector<int>* removable_ids);
158
159
/*
160
* creates the nodal equation of the node 'node' GV = I
161
* in the form Ax = B(1/x) where A is a matrix with one row
162
* @param node : the node to be analyzed
163
* @param eqn : A
164
* @param val : B
165
*/
166
bool createEquationNRmethod(Node* node, double* eqn, double& val, std::vector<int>* removable_ids);
167
168
/**
169
* @brief Create the equation of the voltage source.
170
* Create the equation V2 - V1 = E of the voltage source in the form Ax = B,
171
* where A is a matrix with one row, B a value
172
* @param[in] vsource The voltage source
173
* @param[in] eqn : A
174
* @param[in] val : B
175
* @return ???
176
*/
177
bool createEquation(Element* vsource, double* eqn, double& val);
178
179
/*
180
* removes the "colToRemove"-th column from matrix "matrix"
181
*/
182
void removeColumn(Eigen::MatrixXd& matrix, const int colToRemove);
183
184
/*
185
* solves the system of nonlinear equations Ax = B(1/x)
186
* @param eqn : A
187
* @param vals : B
188
*/
189
bool solveEquationsNRmethod(double* eqn, double* vals, std::vector<int>*);
190
191
bool _solveNRmethod();
192
193
#endif
194
public:
195
196
// a Constructor, same functionality as "init" functions
197
Circuit();
198
// RICE_CHECK: Is this a traction substation current limit, global for all substations?
199
/// @brief Constructor with user-specified current limit parameter.
200
Circuit(double currentLimit);
201
202
// adds an element with name "name", type "type" and value "value" to positive node "pNode" and negative node "nNode""
203
Element* addElement(std::string name, double value, Node* pNode, Node* nNode, Element::ElementType et);
204
205
void eraseElement(Element* element);
206
207
// adds a node with name "name"
208
Node* addNode(std::string name);
209
210
// erases a node with name "name"
211
void eraseNode(Node* node);
212
213
// gets current through element "name"
214
double getCurrent(std::string name);
215
216
// gets voltage across element or node "name"
217
double getVoltage(std::string name);
218
219
// gets the resistance of an element.
220
double getResistance(std::string name);
221
222
// gets the number of voltage sources in the circuit.
223
int getNumVoltageSources();
224
225
// checks if the circuit's connections are correct.
226
bool checkCircuit(std::string substationId = "");
227
228
#ifdef HAVE_EIGEN
229
// solves the circuit and deploys the results
230
bool solve();
231
#endif
232
233
// cleans up after superposition.
234
void cleanUpSP();
235
236
//replaces unusedNode with newNode everywhere in the circuit, modifies the ids of other nodes and elements, decreases the id by one and deletes unusedNode
237
void replaceAndDeleteNode(Node* unusedNode, Node* newNode);
238
239
// returns lastId
240
int getLastId() {
241
return lastId;
242
};
243
244
// decreases lastId by one
245
void decreaseLastId() {
246
lastId--;
247
};
248
249
/// RICE_CHECK: Is this identical to the current limit of a traction substation?
250
/// @brief Set the electric current limit of this circuit.
251
void setCurrentLimit(double myCurrentLimit) {
252
circuitCurrentLimit = myCurrentLimit;
253
};
254
255
/// @ brief Get the electric current limit of this circuit.
256
double getCurrentLimit() {
257
return circuitCurrentLimit;
258
};
259
};
260
261