LCOV - code coverage report
Current view: top level - src/utils/traction_wire - Circuit.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 5 5
Test Date: 2024-11-20 15:55:46 Functions: - 0 0

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2024 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: 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          360 :         return alphaBest;
     129              :     };
     130              : 
     131              :     /// @brief return the reason why `alpha` scaling value has been used
     132              :     alphaFlag getAlphaReason() {
     133          180 :         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          203 :         return lastId;
     242              :     };
     243              : 
     244              :     // decreases lastId by one
     245              :     void decreaseLastId() {
     246          195 :         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          180 :         return circuitCurrentLimit;
     258              :     };
     259              : };
        

Generated by: LCOV version 2.0-1