Extra features¶
roseau-load-flow comes with some extra features that can be useful for some users.
Graph theory¶
ElectricalNetwork.to_graph() can be used to get a
networkx.MultiGraph object from the electrical network.
The graph contains the geometries of the buses in the nodes data and the geometries and branch types in the edges data.
Note
This method requires networkx which is not installed by default. You can install it with the "graph" extra using:
pip install "roseau-load-flow[graph]".
In addition, you can use the property
ElectricalNetwork.buses_clusters to get a list of sets of
IDs of buses in galvanically isolated sections of the network. In other terms, to get groups of buses connected by one
or more lines or a switches, stopping at transformers. For example, for a network with a MV feeder, this property
returns a list containing a set of MV buses IDs and all sets of LV subnetworks buses IDs. If you want to get the cluster
of only one bus, you can use Bus.get_connected_buses
If we take the example network from the Getting Started page:
>>> set(source_bus.get_connected_buses())
{'sb', 'lb'}
>>> set(load_bus.get_connected_buses())
{'sb', 'lb'}
>>> en.buses_clusters
[{'sb', 'lb'}]
As there are no transformers between the two buses, they all belong to the same cluster.
Symmetrical components¶
roseau.load_flow.sym contains helpers to work with symmetrical components. For example, to convert a phasor
voltage to symmetrical components:
>>> import numpy as np
>>> import roseau.load_flow as rlf
>>> v = 230 * np.exp([0, -2j * np.pi / 3, 2j * np.pi / 3])
>>> v
array([ 230. +0.j , -115.-199.18584287j, -115.+199.18584287j])
>>> v_sym = rlf.sym.phasor_to_sym(v)
>>> v_sym
array([[ 8.52651283e-14-1.42108547e-14j],
[ 2.30000000e+02+4.19109192e-14j],
[-7.10542736e-14-2.84217094e-14j]])
As you can see, for this positive-sequence balanced voltage, only the positive-sequence component is non-zero. Converting back to phasor, you get the original voltage values back:
>>> sym_to_phasor(v_sym)
array([[ 230.-7.21644966e-16j],
[-115.-1.99185843e+02j],
[-115.+1.99185843e+02j]])
You can also convert pandas Series to symmetrical components. If we take the example network of the Getting Started page:
>>> rlf.sym.series_phasor_to_sym(en.res_buses_voltages["voltage"])
bus_id sequence
lb zero 8.526513e-14-1.421085e-14j
pos 2.219282e+02+4.167975e-14j
neg -5.684342e-14-2.842171e-14j
sb zero 9.947598e-14-1.421085e-14j
pos 2.309401e+02+3.483159e-14j
neg -4.263256e-14-2.842171e-14j
Name: voltage, dtype: complex128
The rlf.sym module also provides useful helpers to create three-phase balanced quantities by only providing the
magnitude of the quantities. For example, to create a three-phase balanced positive sequence voltage:
>>> import numpy as np
>>> import roseau.load_flow as rlf
>>> V = 230 * rlf.sym.PositiveSequence
>>> V
array([ 230. +0.j , -115.-199.18584287j, -115.+199.18584287j])
>>> np.abs(V)
array([230., 230., 230.])
>>> np.angle(V, deg=True)
array([ 0., -120., 120.])
Similarly, you can use rlf.sym.NegativeSequence and rlf.sym.ZeroSequence to create negative-sequence and
zero-sequence quantities respectively. Because these are so common, you can also access them directly from the top-level
module as rlf.PositiveSequence, etc.
Potentials to voltages conversion¶
roseau.load_flow.converters contains helpers to convert a vector of potentials to a vector of voltages. Example:
>>> import numpy as np
>>> import roseau.load_flow as rlf
>>> potentials = 230 * np.array([1, np.exp(-2j * np.pi / 3), np.exp(2j * np.pi / 3), 0])
>>> potentials
array([ 230. +0.j , -115.-199.18584287j, -115.+199.18584287j,
0. +0.j ])
>>> phases = "abcn"
>>> rlf.converters.calculate_voltages(potentials, phases)
array([ 230. +0.j , -115.-199.18584287j, -115.+199.18584287j]) <Unit('volt')>
Because the phases include the neutral, the voltages calculated are phase-to-neutral voltages. You can also calculate phase-to-phase voltages by omitting the neutral:
>>> rlf.converters.calculate_voltages(potentials[:-1], phases[:-1])
array([ 345.+199.18584287j, 0.-398.37168574j, -345.+199.18584287j]) <Unit('volt')>
To get the phases of the voltage, you can use calculate_voltage_phases:
>>> rlf.converters.calculate_voltage_phases(phases)
['an', 'bn', 'cn']
Of course these functions work with arbitrary phases:
>>> rlf.converters.calculate_voltages(potentials[:2], phases[:2])
array([345.+199.18584287j]) <Unit('volt')>
>>> rlf.converters.calculate_voltage_phases(phases[:2])
['ab']
>>> rlf.converters.calculate_voltage_phases("abc")
['ab', 'bc', 'ca']
>>> rlf.converters.calculate_voltage_phases("bc")
['bc']
>>> rlf.converters.calculate_voltage_phases("bcn")
['bn', 'cn']
Kron’s reduction¶
Kron’s reduction is a method to reduce the size of an admittance or impedance matrix by eliminating nodes that are not
of interest, typically the neutral conductor in power systems. You can use the function
roseau.load_flow.converters.kron_reduction() to perform Kron’s reduction on any square matrix of real or complex
numbers. Example:
>>> import numpy as np
... import roseau.load_flow as rlf
>>> matrix_4x4 = np.array(
... [
... [4, 1, 2, 0],
... [1, 3, 0, 1],
... [2, 0, 3, 1],
... [0, 1, 1, 2],
... ],
... dtype=np.float64,
... )
... rlf.converters.kron_reduction(matrix_4x4)
array([[ 4. , 1. , 2. ],
[ 1. , 2.5, -0.5],
[ 2. , -0.5, 2.5]])
Constants¶
roseau.load_flow.constants contains some common mathematical and physical constants like the resistivity and
permeability of common materials in addition to other useful constants. Please refer to the module documentation for
more details. An enumeration of available materials can be found in the roseau.load_flow.types module.
Some commonly used constants can be accessed directly from the top-level module for convenience. Notable top-level constants:
rlf.SQRT3: the square root of 3. Useful for converting between phase-to-phase and phase-to-neutral voltages.rlf.ALPHA: the alpha constant. Rotates a complex number by 120°.rlf.ALPHA2: the alpha constant squared. Rotates a complex number by 240° (or -120°).
Unbalance calculations¶
roseau-load-flow supports common voltage and current unbalance calculations in three-phase elements. Voltage unbalance
definitions are thoroughly discussed in [GMR19].
The res_voltage_unbalance() method on a 3-phase terminal elements
calculates the voltage balance depending on the definition parameter:
IEC’s Voltage Unbalance Factor (VUF) by default (
definition="VUF"):\[VUF = \frac{|V_{\mathrm{n}}|}{|V_{\mathrm{p}}|} \times 100 (\%)\]Where \(V_{\mathrm{n}}\) is the negative-sequence voltage and \(V_{\mathrm{p}}\) is the positive-sequence voltage.
NEMA’s Line Voltage Unbalance Rate (LVUR) (
definition="LVUR"):\[LVUR = \dfrac{\Delta V_\mathrm{Line,Max}}{\Delta V_\mathrm{Line,Mean}} \times 100 (\%)\]Where \(\Delta V_\mathrm{Line,Mean}\) is the arithmetic mean of the line voltages and \(\Delta V_\mathrm{Line,Max}\) is the maximum deviation between the measured line voltages and \(\Delta V_\mathrm{Line,Mean}\).
IEEE’s Phase Voltage Unbalance Rate (PVUR) (
definition="PVUR"):\[PVUR = \dfrac{\Delta V_\mathrm{Phase,Max}}{\Delta V_\mathrm{Phase,Mean}} \times 100 (\%)\]Where \(\Delta V_\mathrm{Phase,Mean}\) is the arithmetic mean of the phase voltages and \(\Delta V_\mathrm{Phase,Max}\) is the maximum deviation between the measured phase voltages and \(\Delta V_\mathrm{Phase,Mean}\).
The res_current_unbalance() method on three-phase bus-connectable
elements (loads, sources, branch sides) calculates the Current Unbalance Factor (CUF) defined as:
Where \(I_{\mathrm{n}}\) is the negative-sequence current and \(I_{\mathrm{p}}\) is the positive-sequence current.
Bibliography¶
Kshitij Girigoudar, Daniel K. Molzahn, and Line A. Roald. On the relationships among different voltage unbalance definitions. In 2019 North American Power Symposium (NAPS), volume, 1–6. 2019. doi:10.1109/NAPS46351.2019.9000231.