LCOV - code coverage report
Current view: top level - src/utils/traction_wire - Circuit.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 5 5 100.0 %
Date: 2024-05-05 15:31:14 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 matricies
     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, descreases 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 descreaseLastId() {
     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 1.14