Getting started with Roseau Load Flow¶
Make sure you have followed the installation instructions.
In this tutorial you will learn how to:
Creating a network¶
An electrical network can be built by assembling basic elements described in the Models section. The following is a summary of the available elements:
Buses:
Bus
: A multi-phase node where other elements can be connected. The bus optionally defines the nominal voltages and voltage limits of the network to study violations.
Branches:
Line
: An impedant connection between two buses on the same voltage level. The impedance of the line and its physical characteristics are defined by theLineParameters
object. This object can be defined once and used to describe multiple lines.Switch
: An ideal connection between two buses on the same voltage level. Currently, a switch cannot be opened.Transformer
: A transformer connecting a buses on potentially different voltage levels called the high-voltage side and the low-voltage side. The impedance of the transformer and its physical characteristics including its winding configuration are defined by aTransformerParameters
object. This object can be defined once and used to describe multiple transformers.
Loads:
The ZIP load model is available via the following load classes:
ImpedanceLoad
: A constant impedance (Z) load: \(S = |V|^2 \times \overline{Z}\), \(|S|\) is proportional to \(|V|^2\).CurrentLoad
A constant current (I) load: \(S = V \times \overline{I}\), \(|S|\) is proportional to \(|V|^1\).PowerLoad
: A constant power (P) load: \(S = \mathrm{constant}\), \(|S|\) is proportional to \(|V|^0\).A power load can be made flexible (controllable) by using
FlexibleParameter
objects. This object defines the parameters of the flexible load’s control (Maximum power, projection, type, etc.) Note that flexible loads are an advanced feature that most users don’t need. They are explained in details here.
Sources:
VoltageSource
: An infinite power ideal source with a constant voltage.
Other elements:
Ground
: A perfect conductor that can be connected to various elements. If two elements are connected to the same ground, the potentials at the connection points are always equal.PotentialRef
: Sets the reference of potentials in the network. It can be connected to buses or grounds.
Let’s use some of these elements to build the following simple low voltage network. A voltage source represents the upstream medium voltage network. A MV/LV transformer, a simple three-phase four-wire line and a constant power load represent the low voltage network.
>>> import numpy as np
... import roseau.load_flow as rlf
>>> # Define the upstream MV network represented by an infinite voltage source
... # ------------------------------------------------------------------------
... # Define the MV bus with a nominal voltage of 20 kV
... mv_bus = rlf.Bus(
... # ⮦ Required parameters
... id="MV_Bus", # Unique identifier
... phases="abc", # no neutral (typical MV bus)
... # ⮦ Optional parameters for analyzing network violations
... nominal_voltage=20e3, # 20 kV (typical MV voltage)
... min_voltage_level=0.95, # 95% of the nominal voltage
... max_voltage_level=1.05, # 105% of the nominal voltage
... )
... # Create a three-phase voltage source at the MV bus
... vs = rlf.VoltageSource(id="Source", bus=mv_bus, voltages=20e3)
>>> # Define the LV network: 2km line ending with a 30kW load
... # -------------------------------------------------------
... lv_bus1 = rlf.Bus(
... id="LV_Bus1",
... phases="abcn", # with neutral (typical LV bus)
... nominal_voltage=400, # 400 V (typical LV voltage)
... min_voltage_level=0.9,
... max_voltage_level=1.1,
... )
... lv_bus2 = rlf.Bus(
... id="LV_Bus2",
... phases="abcn",
... nominal_voltage=400,
... min_voltage_level=0.9,
... max_voltage_level=1.1,
... )
... # Add a 2 km line between the LV buses with R = 0.1 Ohm/km and X = 0
... lp = rlf.LineParameters("LP", z_line=(0.1 + 0j) * np.eye(4), ampacities=500)
... line = rlf.Line(id="LV_Line", bus1=lv_bus1, bus2=lv_bus2, parameters=lp, length=2.0)
... # Add a 30kW load at the second bus (balanced load, 10 kW per phase)
... load = rlf.PowerLoad(id="Load", bus=lv_bus2, powers=10e3 + 0j) # In VA
>>> # Define the MV/LV transformer connecting the two networks
... # --------------------------------------------------------
... # For simplicity, we choose a transformer from the catalogue
... tp = rlf.TransformerParameters.from_catalogue("SE Minera AA0Ak 160kVA 20kV 410V Dyn11")
... transformer = rlf.Transformer(
... id="MV/LV_Transformer",
... bus_hv=mv_bus,
... bus_lv=lv_bus1,
... parameters=tp,
... )
... # Earth the neutral wire of transformer's neutral on the LV side
... ground = rlf.Ground(id="Ground") # Represents the earth
... rlf.GroundConnection(ground=ground, element=lv_bus1, phase="n")
... # # Optionally earth the load's neutral
... # rlf.GroundConnection(ground=ground, element=lv_bus2, phase="n")
>>> # Set the references of potentials for each network (explained later)
... # -------------------------------------------------------------------
... pref_mv = rlf.PotentialRef(id="PRef_MV", element=mv_bus)
... pref_lv = rlf.PotentialRef(id="PRef_LV", element=ground) # or lv_bus1
Notice how the phases of the elements are not explicitly given. They are inferred from the buses
they are connected to. The load and line will have their phases set to "abcn"
while the source
will have its phases set to "abc"
. You can also explicitly declare the phases of these elements.
For example, to create a star-connected (Wye) source instead, you can explicitly set its phases to
"abcn"
:
>>> # A star-connected source has "abcn" phases
... vs_star = rlf.VoltageSource(
... id="Y Source", bus=mv_bus, voltages=un / rlf.SQRT3, phases="abcn"
... )
Here, the source voltages become phase-to-neutral (un / rlf.SQRT3
), and not phase-to-phase (un
).
This is because, everywhere in roseau-load-flow
, the voltages
of an element depend on the
element’s phases
. Voltages of elements connected in a Star (wye) configuration (elements that
have a neutral connection indicated by the presence of the 'n'
character in their phases
attribute) are the phase-to-neutral voltages. Voltages of elements connected in a Delta
configuration (elements that do not have a neutral connection indicated by the absence of the 'n'
char from their phases
attribute) are the phase-to-phase voltages. To see between which phases
the voltage is defined, you can use the voltage_phases
property of the element.
>>> vs.voltage_phases
['ab', 'bc', 'ca']
>>> vs_star.voltage_phases
['an', 'bn', 'cn']
When creating the load, we passed a single value to the powers
argument. This is a convenience
feature that assumes that the load is balanced and that the value passed for the power should be
used for all phases. If the load is unbalanced, you can pass a list of powers
for each phase:
>>> load = rlf.PowerLoad(id="Load", bus=lv_bus2, powers=[10e3, 5e3, 5e3])
At this point, all the basic elements of the network have been defined and connected. Now,
everything can be encapsulated in an ElectricalNetwork
object, but first, some important
notes on the Ground
and PotentialRef
elements:
Important
The Ground
element does not have a fixed potential as one would expect from a real ground
connection. The ground element here merely represents a “perfect conductor”, equivalent to a
single-conductor line with zero impedance. The potential reference, 0 Volts, is defined by the
PotentialRef
element that itself can be connected to any bus or ground in the network. This
gives the users more flexibility to define the potential reference of their network.
A PotentialRef
defines the potential reference for the network. It is a mandatory reference
for the load flow resolution to be well-defined. A network MUST have one and only one potential
reference per galvanically isolated section.
When in doubt, define the ground and potential references similar to the example above.
An ElectricalNetwork
object can now be created using the from_element
constructor. The source
bus mv_bus
is given to this constructor. All the elements connected to this bus are automatically
included into the network.
>>> en = rlf.ElectricalNetwork.from_element(mv_bus)
... en
<ElectricalNetwork: 3 buses, 1 line, 1 transformer, 0 switches, 1 load, 1 source, 1 ground, 2 potential refs>
Solving a load flow¶
A license is required. You can use the free but limited licence key or get a personal and unlimited key by contacting us at contact@roseautechnologies.com. Once you have your license key, you can activate it by following the License activation instructions.
Afterwards, the load flow can be solved by calling the solve_load_flow
method of the ElectricalNetwork
>>> en.solve_load_flow()
(2, 1.8595620332462204e-07)
It returns the number of iterations performed by the solver, and the residual error after convergence. Here, the load flow converged in 2 iterations with a residual error of \(1.86 \times 10^{-7}\).
Getting the results¶
Results can be accessed through the properties prefixed with res_
on each element. For instance,
the potentials of the load bus ("LV_Bus2"
) can be accessed using the lv_bus2.res_potentials
property. It contains 4 values representing the potentials of its phases a
, b
, c
and n
(neutral). The potentials are returned as complex numbers. Calling abs(lv_bus2.res_potentials)
returns their magnitude (in Volts) and np.angle(lv_bus2.res_potentials)
returns their angle
(phase shift) in radians.
Roseau Load Flow uses Pint’s Quantity
objects to present
unit-aware data to the user. Most input data (load powers, source voltages, etc.) are expected
to be either given in SI units or using the pint Quantity interface for non-SI units (example below).
Look at the documentation of a method to see its default units.
In the following example, we create a load with powers expressed in kVA:
>>> load = rlf.PowerLoad(id="load", bus=lv_bus2, phases="abcn", powers=rlf.Q_(10, "kVA"))
The results returned by the res_
properties are also Quantity
objects.
Available results¶
The available results depend on the type of element. The models page of each element lists its available results.
Getting results per object¶
All results shown below are rounded to 2 decimal places for better presentation.
In order to get the potentials of a bus, use its res_potentials
property:
>>> lv_bus2.res_potentials
<Quantity([ 227.4 -1.71j -115.18-196.08j -112.22+197.79j -0. +0.j ], 'volt')>
>>> abs(lv_bus2.res_potentials)
<Quantity([227.41 227.41 227.41 0. ], 'volt')>
As the results are pint quantities, they can be converted to different units easily.
>>> abs(lv_bus2.res_potentials).to("kV") # Get a Quantity in kV
<Quantity([0.23 0.23 0.23 0. ], 'kilovolt')>
>>> abs(lv_bus2.res_potentials).m_as("kV") # Get the magnitude in kV
array([0.23, 0.23, 0.23, 0. ])
>>> abs(lv_bus2.res_potentials).m # Get the magnitude in the default unit (V)
array([227.41, 227.41, 227.41, 0. ])
Note
Voltages of a bus can be accessed similar to the potentials using the res_voltages
property. This
returns the phase-to-neutral voltages of the bus if it has a neutral, and the phase-to-phase voltages
otherwise. If you want to always get the phase-to-neutral voltages, use the res_voltages_pn
property (only available for buses with a neutral). If you want to always get the phase-to-phase
voltages, use the res_voltages_pp
property (only available for buses with more than one phase).
For a list of available results for buses, see the Bus model page.
The currents of the line are available using the res_currents
property of the line
object.
It contains two arrays:
the first is the current flowing from the first bus of the line to the second bus of the line. It contains 4 values: one per phase and the neutral current.
the second is the current flowing from the second bus of the line to the first bus of the line.
>>> line.res_currents
(<Quantity([ 43.97 -0.33j -22.27-37.92j -21.7 +38.25j 0. -0.j ], 'ampere')>,
<Quantity([-43.97 +0.33j 22.27+37.92j 21.7 -38.25j -0. +0.j ], 'ampere')>)
>>> line.res_currents[0] + line.res_currents[1]
<Quantity([0.+0.j 0.+0.j 0.+0.j 0.+0.j], 'ampere')>
Here, the sum of these currents is 0 as we have chosen a simple line model, i.e, a line with only series impedance elements without shunt components. If shunt components were modelled, the sum would have been non-zero.
Dataframe network results¶
The results can also be retrieved for the entire network using res_
properties of the
ElectricalNetwork
instance as pandas dataframes.
The main results available on the network are:
res_buses
: Buses potentials indexed by (bus id, phase)res_transformers
: Transformers currents, powers, potentials, and power limits indexed by (transformer id, phase)res_lines
: Lines currents, powers, potentials, series losses, series currents, and current limits indexed by (line id, phase)res_switches
: Switches currents, powers, and potentials indexed by (switch id, phase)res_loads
: Loads currents, powers, and potentials indexed by (load id, phase)res_sources
: Sources currents, powers, and potentials indexed by (source id, phase)res_grounds
: Grounds potentials indexed by ground idres_potential_refs
: Potential references currents indexed by potential ref id (always zero for a successful load flow)
The following additional results are also available for the network:
res_buses_voltages
: Buses voltages and voltage limits indexed by (bus id, voltage phase²)res_buses_voltages_pn
: Buses phase-to-neutral voltages and voltage limits indexed by (bus id, voltage phase²). Only buses with a neutral are includedres_buses_voltages_pp
: Buses phase-to-phase voltages and voltage limits indexed by (bus id, voltage phase²). Only buses with more than one phase are includedres_loads_voltages
: Loads voltages indexed by (load id, voltage phase)res_loads_voltages_pn
: Loads phase-to-neutral voltages indexed by (load id, voltage phase) Only loads with a neutral are includedres_loads_voltages_pp
: Loads phase-to-phase voltages indexed by (load id, voltage phase). Only loads with more than one phase are includedres_loads_flexible_powers
: Loads flexible powers indexed by (load id, voltage phase). Only flexible loads are includedres_sources_voltages
: Sources voltages indexed by (source id, voltage phase)res_sources_voltages_pn
: Sources phase-to-neutral voltages indexed by (source id, voltage phase) Only sources with a neutral are includedres_sources_voltages_pp
: Sources phase-to-phase voltages indexed by (source id, voltage phase). Only sources with more than one phase are included
² a “voltage phase” is a composite phase like an
or ab
All the results are complex numbers. You can always access the magnitude of the results using
the abs
function and the angle in radians using the np.angle
function. For instance,
abs(network.res_loads)
gives you the magnitude of the loads’ results in SI units.
Below are the results of the load flow for en
:
>>> en.res_buses
bus_id |
phase |
potential |
---|---|---|
MV_Bus |
a |
10000.00-5773.50j |
MV_Bus |
b |
-10000.00-5773.50j |
MV_Bus |
c |
0.00+11547.01j |
LV_Bus1 |
a |
236.19-1.77j |
LV_Bus1 |
b |
-119.63-203.66j |
LV_Bus1 |
c |
-116.56+205.44j |
LV_Bus1 |
n |
0.00+0.00j |
LV_Bus2 |
a |
227.40-1.71j |
LV_Bus2 |
b |
-115.18-196.08j |
LV_Bus2 |
c |
-112.22+197.79j |
LV_Bus2 |
n |
-0.00+0.00j |
>>> en.res_lines
line_id |
phase |
current1 |
current2 |
power1 |
power2 |
potential1 |
potential2 |
series_losses |
series_current |
violated |
loading |
max_loading |
ampacity |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
LV_Line |
a |
43.97-0.33j |
-43.97+0.33j |
10386.74+0.00j |
-10000.00-0.00j |
236.19-1.77j |
227.40-1.71j |
386.74+0.00j |
43.97-0.33j |
False |
0.09 |
1.00 |
500.00 |
LV_Line |
b |
-22.27-37.92j |
22.27+37.92j |
10386.74+0.00j |
-10000.00-0.00j |
-119.63-203.66j |
-115.18-196.08j |
386.74+0.00j |
-22.27-37.92j |
False |
0.09 |
1.00 |
500.00 |
LV_Line |
c |
-21.70+38.25j |
21.70-38.25j |
10386.74+0.00j |
-10000.00-0.00j |
-116.56+205.44j |
-112.22+197.79j |
386.74+0.00j |
-21.70+38.25j |
False |
0.09 |
1.00 |
500.00 |
LV_Line |
n |
0.00-0.00j |
-0.00+0.00j |
0.00+0.00j |
0.00-0.00j |
0.00+0.00j |
-0.00+0.00j |
0.00-0.00j |
0.00-0.00j |
False |
0.00 |
1.00 |
500.00 |
>>> en.res_transformers
transformer_id |
phase |
current_hv |
current_lv |
power_hv |
power_lv |
potential_hv |
potential_lv |
violated |
loading |
max_loading |
sn |
---|---|---|---|---|---|---|---|---|---|---|---|
MV/LV_Transformer |
a |
0.44-1.06j |
-43.97+0.33j |
10471.96+8077.92j |
-10386.74-0.00j |
10000.00-5773.50j |
236.19-1.77j |
False |
0.25 |
1.00 |
160000.00 |
MV/LV_Transformer |
b |
-1.14+0.15j |
22.27+37.92j |
10471.96+8077.92j |
-10386.74-0.00j |
-10000.00-5773.50j |
-119.63-203.66j |
False |
0.25 |
1.00 |
160000.00 |
MV/LV_Transformer |
c |
0.70+0.91j |
21.70-38.25j |
10471.96+8077.92j |
-10386.74-0.00j |
0.00+11547.01j |
-116.56+205.44j |
False |
0.25 |
1.00 |
160000.00 |
MV/LV_Transformer |
n |
nan+0.00j |
0.00-0.00j |
nan+0.00j |
0.00+0.00j |
nan+0.00j |
0.00+0.00j |
False |
0.25 |
1.00 |
160000.00 |
>>> en.res_switches # empty as the network does not contain switches
switch_id |
phase |
current1 |
current2 |
power1 |
power2 |
potential1 |
potential2 |
---|
>>> en.res_loads
load_id |
phase |
type |
current |
power |
potential |
---|---|---|---|---|---|
Load |
a |
power |
43.97-0.33j |
10000.00+0.00j |
227.40-1.71j |
Load |
b |
power |
-22.27-37.92j |
10000.00+0.00j |
-115.18-196.08j |
Load |
c |
power |
-21.70+38.25j |
10000.00+0.00j |
-112.22+197.79j |
Load |
n |
power |
0.00-0.00j |
-0.00-0.00j |
-0.00+0.00j |
>>> en.res_sources
source_id |
phase |
type |
current |
power |
potential |
---|---|---|---|---|---|
Source |
a |
voltage |
-0.44+1.06j |
-10471.96-8077.92j |
10000.00-5773.50j |
Source |
b |
voltage |
1.14-0.15j |
-10471.96-8077.92j |
-10000.00-5773.50j |
Source |
c |
voltage |
-0.70-0.91j |
-10471.96-8077.92j |
0.00+11547.01j |
>>> en.res_grounds
ground_id |
potential |
---|---|
Ground |
0.00+0.00j |
>>> en.res_potential_refs
potential_ref_id |
current |
---|---|
PRef_MV |
0.00+0.00j |
PRef_LV |
0.00-0.00j |
And some voltage results:
>>> en.res_buses_voltages
bus_id |
phase |
voltage |
violated |
voltage_level |
min_voltage_level |
max_voltage_level |
nominal_voltage |
---|---|---|---|---|---|---|---|
MV_Bus |
ab |
20000.00+0.00j |
False |
1.00 |
0.95 |
1.05 |
20000.00 |
MV_Bus |
bc |
-10000.00-17320.51j |
False |
1.00 |
0.95 |
1.05 |
20000.00 |
MV_Bus |
ca |
-10000.00+17320.51j |
False |
1.00 |
0.95 |
1.05 |
20000.00 |
LV_Bus1 |
an |
236.19-1.77j |
False |
1.02 |
0.90 |
1.10 |
400.00 |
LV_Bus1 |
bn |
-119.63-203.66j |
False |
1.02 |
0.90 |
1.10 |
400.00 |
LV_Bus1 |
cn |
-116.56+205.44j |
False |
1.02 |
0.90 |
1.10 |
400.00 |
LV_Bus2 |
an |
227.40-1.71j |
False |
0.98 |
0.90 |
1.10 |
400.00 |
LV_Bus2 |
bn |
-115.18-196.08j |
False |
0.98 |
0.90 |
1.10 |
400.00 |
LV_Bus2 |
cn |
-112.22+197.79j |
False |
0.98 |
0.90 |
1.10 |
400.00 |
The voltage results are a mix of phase-to-phase and phase-to-neutral voltages. To get only
phase-to-phase voltages, use the res_buses_voltages_pp
property:
>>> en.res_buses_voltages_pp
bus_id |
phase |
voltage |
violated |
voltage_level |
min_voltage_level |
max_voltage_level |
nominal_voltage |
---|---|---|---|---|---|---|---|
MV_Bus |
ab |
20000.00+0.00j |
False |
1.00 |
0.95 |
1.05 |
20000.00 |
MV_Bus |
bc |
-10000.00-17320.51j |
False |
1.00 |
0.95 |
1.05 |
20000.00 |
MV_Bus |
ca |
-10000.00+17320.51j |
False |
1.00 |
0.95 |
1.05 |
20000.00 |
LV_Bus1 |
ab |
355.83+201.89j |
False |
1.02 |
0.90 |
1.10 |
400.00 |
LV_Bus1 |
bc |
-3.07-409.10j |
False |
1.02 |
0.90 |
1.10 |
400.00 |
LV_Bus1 |
ca |
-352.76+207.21j |
False |
1.02 |
0.90 |
1.10 |
400.00 |
LV_Bus2 |
ab |
342.58+194.37j |
False |
0.98 |
0.90 |
1.10 |
400.00 |
LV_Bus2 |
bc |
-2.96-393.87j |
False |
0.98 |
0.90 |
1.10 |
400.00 |
LV_Bus2 |
ca |
-339.62+199.50j |
False |
0.98 |
0.90 |
1.10 |
400.00 |
And to get only phase-to-neutral voltages, use the res_buses_voltages_pn
property. Note that
only buses with a neutral are included in the results:
>>> en.res_buses_voltages_pn
bus_id |
phase |
voltage |
violated |
voltage_level |
min_voltage_level |
max_voltage_level |
nominal_voltage |
---|---|---|---|---|---|---|---|
LV_Bus1 |
an |
236.19-1.77j |
False |
1.02 |
0.90 |
1.10 |
400.00 |
LV_Bus1 |
bn |
-119.63-203.66j |
False |
1.02 |
0.90 |
1.10 |
400.00 |
LV_Bus1 |
cn |
-116.56+205.44j |
False |
1.02 |
0.90 |
1.10 |
400.00 |
LV_Bus2 |
an |
227.40-1.71j |
False |
0.98 |
0.90 |
1.10 |
400.00 |
LV_Bus2 |
bn |
-115.18-196.08j |
False |
0.98 |
0.90 |
1.10 |
400.00 |
LV_Bus2 |
cn |
-112.22+197.79j |
False |
0.98 |
0.90 |
1.10 |
400.00 |
The same can be done for the loads:
>>> en.res_loads_voltages
load_id |
phase |
type |
voltage |
---|---|---|---|
Load |
an |
power |
227.40-1.71j |
Load |
bn |
power |
-115.18-196.08j |
Load |
cn |
power |
-112.22+197.79j |
Using the transform
method of data frames, the results can easily be converted from complex values
to magnitude and angle values (radians).
>>> en.res_buses_voltages_pp["voltage"].transform([np.abs, np.angle])
bus_id |
phase |
absolute |
angle |
---|---|---|---|
MV_Bus |
ab |
20000.00 |
0.00 |
MV_Bus |
bc |
20000.00 |
-2.09 |
MV_Bus |
ca |
20000.00 |
2.09 |
LV_Bus1 |
ab |
409.11 |
0.52 |
LV_Bus1 |
bc |
409.11 |
-1.58 |
LV_Bus1 |
ca |
409.11 |
2.61 |
LV_Bus2 |
ab |
393.88 |
0.52 |
LV_Bus2 |
bc |
393.88 |
-1.58 |
LV_Bus2 |
ca |
393.88 |
2.61 |
Or, if you prefer the angles in degrees:
>>> import functools as ft
... en.res_buses_voltages_pp["voltage"].transform([np.abs, ft.partial(np.angle, deg=True)])
bus_id |
phase |
absolute |
angle |
---|---|---|---|
MV_Bus |
ab |
20000.00 |
0.00 |
MV_Bus |
bc |
20000.00 |
-120.00 |
MV_Bus |
ca |
20000.00 |
120.00 |
LV_Bus1 |
ab |
409.11 |
29.57 |
LV_Bus1 |
bc |
409.11 |
-90.43 |
LV_Bus1 |
ca |
409.11 |
149.57 |
LV_Bus2 |
ab |
393.88 |
29.57 |
LV_Bus2 |
bc |
393.88 |
-90.43 |
LV_Bus2 |
ca |
393.88 |
149.57 |
Analyzing the results and detecting violations¶
In the example network above, min_voltage_level
, max_voltage_level
and nominal_voltage
arguments
were passed to the Bus
constructor and ampacities
was passed to the LineParameters
constructor.
In addition with the max_loading
parameters of the Line
and Transformer
, these arguments define
the limits of the network that can be used to check if the network is in a valid state or not. Note
that these limits have no effect on the load flow calculation.
If you set nominal_voltage
with min_voltage_level
or max_voltage_level
on a bus, the
res_violated
property will tell you if the voltage limits are violated or not at this bus. Here,
the voltage limits are not violated.
>>> lv_bus2.res_violated
array([False, False, False])
Similarly, if you set ampacities
on a line parameters and max_loading
(defaults to 100% of the
ampacity) on a line, the res_loading
property will give you the current loading of each phase of
the line. The res_violated
property will tell you if the current loading of the line in any phase
exceeds its limit. Here, the current limit is not violated.
>>> line.res_loading
<Quantity([0.09 0.09 0.09 0. ], 'dimensionless')>
>>> line.res_violated
array([False, False, False, False])
The maximum loading of the transformer can be defined using the max_loading
argument of the
Transformer
(defaults to 100% of the nominal power). Transformers also have a res_loading
to
indicate the loading of the transformer and a res_violated
property that indicates whether the
power loading of the transformer exceeds its limit.
>>> transformer.res_loading
<Quantity(0.247978811, 'dimensionless')>
>>> transformer.res_violated
False
The data frame results on the electrical network also include a loading
, a max_loading
and a
violated
columns.
Tip
You can use the Bus.propagate_limits()
method to
propagate the limits from a bus to buses connected to it galvanically (i.e. via lines or switches).
Updating elements of the network¶
Network elements can be updated. For example, we can change the load’s power values to create an unbalanced situation.
>>> # 15 kW on phase "a", 0 W on phases "b" and "c"
... load.powers = rlf.Q_([15 + 0j, 0 + 0j, 0 + 0j], "kVA")
>>> en.solve_load_flow()
(3, 1.1027623258996755e-11)
>>> abs(lv_bus2.res_potentials)
<Quantity([221.36 236.71 236.71 14.5 ], 'volt')>
Notice how the unbalance is manifested in the neutral’s potential of the bus no longer being at 0 V. You can also obtain the voltage unbalance factor (VUF) according to the IEC definition:
>>> lv_bus2.res_voltage_unbalance()
<Quantity(2.24730245, 'percent')>
More information on modifying the network elements can be found here.
Saving/loading the network¶
An electrical network can be written to a JSON file for later analysis or for sharing with others
using the to_json()
method.
>>> en.to_json("my_network.json")
For more information, see network JSON serialization.