pandapower

pandapower combines the data analysis library pandas and the power flow solver PYPOWER to create an easy to use network calculation program aimed at automation of analysis and optimization in power systems.

_images/pp.svg




More information about pandapower can be found on www.pandapower.org.

If you are interested in the newest pandapower developments, subscribe to our mailing list!

pandapower is a joint development of the research group Energy Management and Power System Operation, University of Kassel and the Department for Distribution System Operation at the Fraunhofer Institute for Energy Economics and Energy System Technology (IEE), Kassel.

_images/iee.png _images/e2n.png





About pandapower

pandapower combines the data analysis library pandas and the power flow solver PYPOWER to create an easy to use network calculation program aimed at automation of analysis and optimization in power systems.

_images/pp.svg




More information about pandapower can be found on www.pandapower.org.

About pandapower:

Getting Started:

If you are interested in the newest pandapower developments, subscribe to our mailing list!

pandapower is a joint development of the research group Energy Management and Power System Operation, University of Kassel and the Department for Distribution System Operation at the Fraunhofer Institute for Energy Economics and Energy System Technology (IEE), Kassel.

_images/iee.png _images/e2n.png





Unit System and Conventions

Naming Conventions

Parameters are always named in the form of <parameter>_<unit>, such as:

Parameter read as
vm_pu \(v_m [pu]\)
loading_percent \(loading [\%]\)
pl_kw \(p_l [kw]\)
r_ohm_per_km \(r [\Omega / km]\)

Constraint parameters are always named with max or min as the prefix to the variable which is constrained, for example:

Parameter read as
min_vm_pu \(v_m^{min} [pu]\)
max_loading_percent \(loading^{max} [\%]\)
max_p_kw \(p^{max} [kw]\)
min_q_kvar \(q^{min} [kvar]\)

It is advised to keep consistent with these naming conventions when extending the framework and introducing new parameters.

Three Phase System

For the three phase system, the following conventions apply:

  • voltage values are given as phase-to-phase voltages
  • current values are given as phase currents
  • power values are given as three-phase power flows

The power equation in the three phase system is therefore given as \(S = \sqrt3 \cdot V \cdot I\).

Since pandapower was developed for distribution systems, all power values are given in kW or kVar.

Per Unit System

Bus voltages are given in the per unit system. The per unit values are relative to the phase-to-phase voltages defined in net.bus.vn_kv for each bus.

The rated apparent power for the per unit system can be defined with the net.sn_kva parameter when creating an empty network. The default value is \(S_{N} = 1000 kVA\). The value should not be relevant in most applications since all power values are given in physical units.

Signing System

For all bus-based power values, the signing is based on the consumer viewpoint:

  • positive active power is power consumption, negative active power is power generation
  • positive reactive power is inductive consumption, negative reactive power is capacitive consumption

The power flow values for branch elements (lines & transformer) are always defined as the power flow into the branch element.

Frequency

The frequency can be defined when creating an empty network. The frequency is only used to calculate the shunt admittance of lines, since the line reactance is given directly in ohm per kilometer. The frequency is also relevant when calculating the peak factor \(\kappa\) in the short circuit calculation.

The standard frequency in pandapower is 50 Hz, and the pandapower standard types are also chosen for 50 Hz systems. If you use a different frequency, please be aware that the line reactance values might not be realistic.

Authors

Copyright (c) 2016-2018 by University of Kassel and Fraunhofer Institute for Energy Economics and Energy System Technology (IEE), Kassel. All rights reserved.

Lead Developers:
  • Leon Thurner
  • Alexander Scheidler
Main Contributers:
  • Julian Dollichon
  • Florian Schäfer
  • Friederike Meier
  • Jan-Hendrik Menke
  • Steffen Meinecke
  • Roman Bolgaryn
  • Jakov Krstulović Opara
  • Winfried Lorenzen
Further Contributions by:
  • Tobias Deß
  • Bastian Junker
  • Jannis Kupka
  • Lothar Löwer
  • Jan Ulffers
  • Nils Bornhorst
  • Jonathan Schütt
  • Elisabeth Drayer
  • Daniel Lohmeier
  • Massimo di Pierro
Coordination:
  • Martin Braun
  • Johann-Christian Töbermann
  • Stefan Gehler

Change Log

[1.6.1] - 2019-02-18

  • [CHANGED] Patch size in create_bus_collection is not duplicated for rectangles anymore #181
  • [CHANGED] Mask colormap z array to ensure nan handling
  • [FIXED] active power distribution in DC OPF for multiple generators at one bus
  • [ADDED] support for networkx graphs in json IO
  • [ADDED] support for shapely objects in json IO
  • [ADDED] switches for three winding transformers #30
  • [ADDED] net.bus_geodata.coords to store line representation of busbars and create_busbar_collection to plot them
  • [CHANGED] draw_collections also supports tuples of collections
  • [ADDED] OPF logging output for verbose=True
  • [ADDED] compatibility for pandas 0.24
  • [FIXED] bug for single bus networks in DC PF #288

[1.6.0] - 2018-09-18

  • [CHANGED] Cost definition changed for optimal powerflow, see OPF documentation (http://pandapower.readthedocs.io/en/v1.6.0/powerflow/opf.html) and opf_changes-may18.ipynb
  • [ADDED] OPF data (controllable, max_loading, costs, min_p_kw, …) in Power System Test Cases
  • [ADDED] case_ieee30, case5, case_illinois200
  • [FIXED] 1 additional Trafo in case39, vn_kv change in case118, sgen indices in polynomial_cost in case 1888rte, case2848rte
  • [ADDED] toolbox functions replace_impedance_by_line(), replace_line_by_impedance() and get_element_indices() including tests
  • [CHANGED] new implementation of to_json, from_json for loading and saving grids using functools.singledispatch
  • [FIXED] checking similar to “if x: …” or “x = x or …” when it is meant “if x is None: …”, because it is potentially problematic with some types
  • [FIXED] convert_format: some older pandapower grids had “0” as “tp_side” in net.trafo, this is checked now as well
  • [FIXED] create_buses: accepts a single tuple (set the same geodata for all buses) or an array of the corresponding shape (for individual geodata)
  • [CHANGED] create_ext_grid_collection (plotting): ext_grid and ext_grid buses can be specified if a collection should only include some of ext grids
  • [ADDED] ability to define phase shifting transformers with tp_st_percent #117
  • [ADDED] support for multiple voltage controlling elements (ext_grid, gen, dcline) at one bus #134
  • [CHANGED] reduced number of arguments in runpp by moving some less important arguments to kwargs #122
  • [ADDED] parameters init_vm_pu and init_va_degree to allow independent initialization of bus magnitude and angle #113
  • [ADDED] number of power flow iterations are now saved
  • [ADDED] calculation of r, x and z for networkx branches
  • [ADDED] support for plotly 3.2
  • [FIXED] plotly bugfixes for trafo traces and result representation
  • [ADDED] Iwamoto algorithm for solving ill-conditioned power flow problems

[1.5.1] - 2018-05-04

  • [FIXED] delta-wye transformation for 3W-transformers #54
  • [ADDED] bus-bus switches collection #76
  • [FIXED] some broken documentation links

[1.5.0] - 2018-04-25

  • [FIXED] plotly hover function for edges (only if use_line_geodata == False)
  • [FIXED] from_ppc trafo parameter calculation now also considers baseMVA != 100
  • [CHANGED] update create_collection docstrings
  • [CHANGED] update HV/MV transformer standard type data
  • [ADDED] pp_elements() toolbox function
  • [ADDED] new parameter g_us_per_km to model dielectric losses in lines
  • [ADDED] single phase short-circuit calculation with negative sequence models
  • [ADDED] generic storage model (sgen/load like element with negative / positive power allowed)
  • [ADDED] modelling of the complex (voltage magnitude and angle) tap changer for cross control
  • [ADDED] modelling of the tap changer of a 3-winding transformer at star point or terminals
  • [ADDED] losses of 3W transformers can be modeled at star point, HV, MV or LV side

[1.4.3] - 2018-02-06

  • [CHANGED] change of collection function names
  • [ADDED] sgen collections and ration functionality for sgen and load collections
  • [ADDED] cosphi_from_pq toolbox function
  • [ADDED] create_nxgraph: respect_switches includes transformer switches

[1.4.2] - 2017-12-05

  • [ADDED] compatbility with networkx 2.0 (see #82)
  • [ADDED] compatibility with pandas 0.21 (see #83)
  • [CHANGED] implementation of ZIP loads changed to constant current magnitude paradigm (see #62)
  • [ADDED] max_step parameter for shunt
  • [ADDED] added warning for large bus index values
  • [FIXED] bug in short-circuit results of trafo3w
  • [FIXED] bugfix in find_bridges and refactoring
  • [CHANGED] faster implementation of result cleanup
  • [CHANGED] faster implementation of line index handling in power flow
  • [FIXED] bug in plotly label display (#75)
  • [ADDED] several fixes, extensions, tests for toolbox
  • [ADDED] additional MV line standard types
  • [FIXED] kerber extrem vorstadtnetz mv bus voltage
  • [FIXED] removed incorrect estimation result tables for load, sgen, gen

[1.4.1] - 2017-09-19

  • [FIXED] ZIP load issue that led to incorrect calculation of I part with voltage angle shifts
  • [FIXED] Bug that set voltage constraints to 0.9/1.2 if no voltage constraints was given in OPF
  • [ADDED] possibility to access J matrix after power flow
  • [ADDED] opf cost conversion
  • [ADDED] opf costs in power system test cases

[1.4.0] - 2017-07-27

  • [ADDED] possibility to save networks to an sql database
  • [CAHNGED] major change in fileIO: all networks are converted to a uniform dataframe only version before they are saved as excel, json or sql. Old files can still be loaded, but all files saved with v1.4 can only be loaded with v1.4!
  • [FIXED] all tests now pass if numba is not installed (although pandapower might be slow without numba)
  • [FIXED] state estimation bug with phase shift transformers
  • [CHANGED] OPF now raises specific warning if parameters are missing instead of generic exception
  • [ADDED] geographical data for cigre and IEEE case networks
  • [ADDED] Dickert LV Networks

[1.3.1] - 2017-06-16

  • [CHANGED] to_pickle saves only python datatypes and no pickle objects
  • [ADDED] html representation of pandapower nets
  • [ADDED] collections for trafos, loads, ext_grids
  • [CHANGED] renamed create_shunt_as_condensator to create_shunt_as_capacitor
  • [FIXED] mock problem in create docstrings
  • [ADDED] Synthetic Voltage Control LV Networks

[1.3.0] - 2017-05-10

  • [ADDED] ZIP loads integrated in power flow
  • [ADDED] numba implementation of dissolving switch buses
  • [ADDED] Current source representation of full converter elements in short circuit calculations
  • [ADDED] Method C for calculation of factor kappa in short circuit calculation
  • [CHANGED] Speedup for calculation of branch short circuit currents
  • [CHANGED] Branch results for minimum short circuit calculations are calculated as minimal currents
  • [ADDED] Interactive plots with plotly
  • [CHANGED] included pypower files for power flow and index files
  • [FIXED] compatibility with numpy 1.12
  • [CHANGED] -1 is a valid value for net.bus_geodata.x
  • [CHANGED] allow transformers with negative xk to provide large scale IEEE cases (RTE, PEGASE, Polish)
  • [ADDED] large scale IEEE cases (RTE, PEGASE, Polish)
  • [ADDED] rated voltage and step variable for shunts
  • [ADDED] lagrange multiplier included in bus results after OPF

[1.2.2] - 2017-03-22

  • [CHANGED] Minor refactoring in pd2ppc
  • [ADDED] Technical Report

[1.2.1] - 2017-03-21

  • [FIXED] Readme for PyPi

[1.2.0] - 2017-03-21

  • [CHANGED] net.line.imax_ka to net.line.max_i_ka for consistency reasons
  • [ADDED] net.line.tp_st_degree for phase shift in trafo tap changers
  • [ADDED] sn_kva parameter in create_empty network for per unit system reference power
  • [ADDED] parameter parallel for trafo element
  • [ADDED] connectivity check for power flow to deal with disconnected network areas
  • [ADDED] backward/forward sweep power flow algorithm specially suited for radial and weakly-meshed networks
  • [ADDED] linear piece wise and polynomial OPF cost functions
  • [ADDED] possibility to make loads controllable in OPF
  • [ADDED] to_json and from_json functions to save/load networks with a JSON format
  • [ADDED] generator lookup to allow multiple generators at one bus
  • [CHANGED] Initialization of calculate_voltage_angles and init for high voltage networks
  • [ADDED] bad data detection for state estimation
  • [CHANGED] from_ppc: no detect_trafo anymore, several gen at each node possible
  • [CHANGED] validate_from_ppc: improved validation behaviour by means of duplicated gen and branch rearangement
  • [ADDED] networks: case33bw, case118, case300, case1354pegase, case2869pegase, case9241pegase, GBreducednetwork, GBnetwork, iceland, cigre_network_mv with_der=’all’ der
  • [ADDED] possibility to add fault impedance for short-circuit current calculation
  • [ADDED] branch results for short circuits
  • [ADDED] static generator model for short circuits
  • [ADDED] three winding transformer model for short circuits
  • [FIXED] correctly neglecting shunts and tap changer position for short-circuits
  • [ADDED] two phase short-circuit current calculation
  • [ADDED] tests for short circuit currents with validation against DIgSILENT PowerFactory

[1.1.1] - 2017-01-12

  • [ADDED] installation description and pypi files from github
  • [ADDED] automatic inversion of active power limits in convert format to account for convention change in version 1.1.0
  • [CHANGED] install_requires in setup.py

[1.1.0] - 2017-01-11

  • [ADDED] impedance element can now be used with unsymetric impedances zij != zji
  • [ADDED] dcline element that allows modelling DC lines in PF and OPF
  • [ADDED] simple plotting function: call pp.simple_plot(net) to directly plot the network
  • [ADDED] measurement table for networks. Enables the definition of measurements for real-time simulations.
  • [ADDED] estimation module, which provides state estimation functionality with weighted least squares algorithm
  • [ADDED] shortcircuit module in beta version for short-circuit calculation according to IEC-60909
  • [ADDED] documentation of model validation and tests
  • [ADDED] case14, case24_ieee_rts, case39, case57 networks
  • [ADDED] mpc and ppc converter
  • [CHANGED] convention for active power limits of generators. Generator with max. feed in of 50kW before: p_min_kw=0, p_max_kw=-50. Now p_max_kw=0, p_min_kw=50
  • [ADDED] DC power flow function pp.rundcopp
  • [FIXED] bug in create_transformer function for tp_pos parameter
  • [FIXED] bug in voltage ratio for low voltage side tap changers
  • [FIXED] bug in rated voltage calculation for opf line constraints

[1.0.2] - 2016-11-30

  • [CHANGED] changed in_service dtype from f8 to bool for shunt, ward, xward
  • [CHANGED] included i_from_ka and i_to_ka in net.res_line
  • [ADDED] recycle parameter added. ppc, Ybus, _is_elements and bus_lookup can be reused between multiple powerflows if recycle[“ppc”] == True, ppc values (P,Q,V) only get updated.
  • [FIXED] OPF bugfixes: cost scaling, correct calculation of res_bus.p_kw for sgens
  • [ADDED] loadcase added as pypower_extension since unnecessary deepcopies were removed
  • [CHANGED] supress warnings parameter removed from loadflow, casting warnings are automatically supressed

[1.0.1] - 2016-11-09

  • [CHANGED] update short introduction example to include transformer
  • [CHANGED] included pypower in setup.py requirements (only pypower, not numpy, scipy etc.)
  • [CHANGED] mpc / ppc renamed to ppci / ppc
  • [FIXED] MANIFEST.ini includes all relevant doc files and exclude report
  • [FIXED] handling of tp_pos parameter in create_trafo and create_trafo3w
  • [FIXED] init=”result” for open bus-line switches

License

pandapower is published under the following 3-clause BSD license:

 Copyright (c) 2018 by University of Kassel and Fraunhofer Institute for Fraunhofer Institute for
 Energy Economics and Energy System Technology (IEE) Kassel and individual contributors
(see AUTHORS file for details). All rights reserved.

 Redistribution and use in source and binary forms, with or without modification, are permitted
 provided that the following conditions are met:

 1. Redistributions of source code must retain the above copyright notice, this list of conditions
 and the following disclaimer.

 2. Redistributions in binary form must reproduce the above copyright notice, this list of
 conditions and the following disclaimer in the documentation and/or other materials provided
 with the distribution.

 3. Neither the name of the copyright holder nor the names of its contributors may be used to
 endorse or promote products derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
 WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Datastructure and Elements

A pandapower network consists of an element table for each electric element in the network. Each element table consists of a column for each parameter and a row for each element.

pandapower provides electric models for 13 electric elements, for each of which you can find detailed information about the definition and interpretation of the parameters in the following documentation:

Empty Network

Create Function

Bus

Create Function

Input Parameters

net.bus

Parameter Datatype Value Range Explanation
name string   name of the bus
vn_kv* float \(>\) 0 rated voltage of the bus [kV]
type string
naming conventions:
“n” - node
“b” - busbar
“m” - muff
type variable to classify buses
zone string   can be used to group buses, for example network groups / regions
max_vm_pu** float \(>\) 0 Maximum voltage
min_vm_pu** float \(>\) 0 Minimum voltage
in_service* boolean True / False specifies if the bus is in service.

*necessary for executing a power flow calculation
**optimal power flow parameter

Note

Bus voltage limits can not be set for slack buses and will be ignored by the optimal power flow.

net.bus_geodata

Parameter Datatype Explanation
x float x coordinate of bus location
y float y coordinate of bus location

Electric Model

alternate Text

Result Parameters

net.res_bus

Parameter Datatype Explanation
vm_pu float voltage magnitude [p.u]
va_degree float voltage angle [degree]
p_kw float resulting active power demand [kW]
q_kvar float resulting reactive power demand [kvar]

The power flow bus results are defined as:

\begin{align*} vm\_pu &= \lvert \underline{V}_{bus} \rvert \\ va\_degree &= \angle \underline{V}_{bus} \\ p\_kw &= Re(\sum_{n=1}^N \underline{S}_{bus, n}) \\ q\_kvar &= Im(\sum_{n=1}^N \underline{S}_{bus, n}) \end{align*}

net.res_bus_est

The state estimation results are put into net.res_bus_est with the same definition as in net.res_bus.

Parameter Datatype Explanation
vm_pu float voltage magnitude [p.u]
va_degree float voltage angle [degree]
p_kw float resulting active power demand [kW]
q_kvar float resulting reactive power demand [kvar]

Note

All power values are given in the consumer system. Therefore a bus with positive p_kw value consumes power while a bus with negative active power supplies power.

Line

Create Function

Lines can be either created from the standard type library (create_line) or with custom values (create_line_from_parameters).

Input Parameters

net.line

Parameter Datatype Value Range Explanation
name string   name of the line
std_type string   standard type which can be used to easily define line parameters with the pandapower standard type library
from_bus* integer   Index of bus where the line starts
to_bus* integer   Index of bus where the line ends
length_km* float \(>\) 0 length of the line [km]
r_ohm_per_km* float \(\geq\) 0 resistance of the line [Ohm per km]
x_ohm_per_km* float \(\geq\) 0 inductance of the line [Ohm per km]
c_nf_per_km* float \(\geq\) 0 capacitance of the line [nano Farad per km]
g_us_per_km* float \(\geq\) 0 dielectric conductance of the line [micro Siemens per km]
max_i_ka* float \(>\) 0 maximal thermal current [kilo Ampere]
parallel* integer \(\geq\) 1 number of parallel line systems
df* float 0…1 derating factor (scaling) for max_i_ka
type string
Naming conventions:
“ol” - overhead line
“cs” - underground cable system
type of line
max_loading_percent** float \(>\) 0 Maximum loading of the line
endtemp_degree*** float \(>\) 0 Short-Circuit end temperature of the line
in_service* boolean True / False specifies if the line is in service.

*necessary for executing a power flow calculation
**optimal power flow parameter
***short-circuit calculation parameter

Note

Defining a line with length zero leads to a division by zero in the power flow and is therefore not allowed. Lines with a very low impedance might lead to convergence problems in the power flow for the same reason. If you want to directly connect two buses, please use the switch element instead of a line with a small impedance!

net.line_geodata

Parameter Datatype Explanation
coords list List of (x,y) tuples that mark the inflexion points of the line

Electric Model

Lines are modelled with the \(\pi\)-equivalent circuit:

alternate Text

The elements in the equivalent circuit are calculated from the parameters in the net.line dataframe as:

\begin{align*} \underline{Z} &= (r\_ohm\_per\_km + j \cdot x\_ohm\_per\_km) \cdot \frac{length\_km}{parallel} \\ \underline{Y}&= (g\_us\_per\_km \cdot 1 \cdot 10^-6 + j \cdot 2 \pi f \cdot c\_nf\_per\_km \cdot 1 \cdot 10^-9) \cdot length\_km \cdot parallel \end{align*}

The power system frequency \(f\) is defined when creating an empty network, the default value is \(f = 50 Hz\).

The parameters are then transformed in the per unit system:

\begin{align*} Z_{N} &= \frac{V_{N}^2}{S_{N}} \\ \underline{z} &= \frac{\underline{Z}}{Z_{N}} \\ \underline{y} &= \underline{Y} \cdot Z_{N} \\ \end{align*}

Where the reference voltage \(V_{N}\) is the nominal voltage at the from bus and the rated apparent power \(S_{N}\) is defined system wide in the net object (see Unit Systems and Conventions).

Note

pandapower assumes that nominal voltage of from bus and to bus are equal, which means pandapower does not support lines that connect different voltage levels. If you want to connect different voltage levels, either use a transformer or an impedance element.

Result Parameters

net.res_line

Parameter Datatype Explanation
p_from_kw float active power flow into the line at “from” bus [kW]
q_from_kvar float reactive power flow into the line at “from” bus [kVar]
p_to_kw float active power flow into the line at “to” bus [kW]
q_to_kvar float reactive power flow into the line at “to” bus [kVar]
pl_kw float active power losses of the line [kW]
ql_kvar float reactive power consumption of the line [kVar]
i_from_ka float Current at to bus [kA]
i_to_ka float Current at from bus [kA]
i_ka float Maximum of i_from_ka and i_to_ka [kA]
loading_percent float line loading [%]

The power flow results in the net.res_line table are defined as:

\begin{align*} p\_from\_kw &= Re(\underline{v}_{from} \cdot \underline{i}^*_{from}) \\ q\_from\_kvar &= Im(\underline{v}_{from} \cdot \underline{i}^*_{from}) \\ p\_to\_kw &= Re(\underline{v}_{to} \cdot \underline{i}^*_{to}) \\ q\_to\_kvar &= Im(\underline{v}_{to} \cdot \underline{i}^*_{to}) \\ pl\_kw &= p\_from\_kw + p\_to\_kw \\ ql\_kvar &= q\_from\_kvar + q\_to\_kvar \\ i\_from\_ka &= i_{from} \\ i\_to\_ka &= i_{to} \\ i\_ka &= max(i_{from}, i_{to}) \\ loading\_percent &= \frac{i\_ka}{imax\_ka \cdot df \cdot parallel} \cdot 100 \end{align*}

net.res_line_est

The state estimation results are put into net.res_line_est with the same definition as in net.res_line.

Parameter Datatype Explanation
p_from_kw float active power flow into the line at “from” bus [kW]
q_from_kvar float reactive power flow into the line at “from” bus [kVar]
p_to_kw float active power flow into the line at “to” bus [kW]
q_to_kvar float reactive power flow into the line at “to” bus [kVar]
pl_kw float active power losses of the line [kW]
ql_kvar float reactive power consumption of the line [kVar]
i_from_ka float Current at to bus [kA]
i_to_ka float Current at from bus [kA]
i_ka float Maximum of i_from_ka and i_to_ka [kA]
loading_percent float line loading [%]

Switch

Create Function

Input Parameters

net.switch

Parameter Datatype Value Range Explanation
bus* integer   index of connected bus
name string   name of the switch
element* integer  
index of the element the switch is connected to:
- bus index if et = “b”
- line index if et = “l”
- trafo index if et = “t”
et* string
“b” - bus-bus switch
“l” - bus-line switch
“t” - bus-trafo
“t3” - bus-trafo3w switch
element type the switch connects to
type string
naming conventions:
“CB” - circuit breaker
“LS” - load switch
“LBS” - load break switch
“DS” - disconnecting switch
type of switch
closed* boolean True / False signals the switching state of the switch

*necessary for executing a power flow calculation.

Electric Model

Bus-Bus-Switches:

Two buses that are connected with a closed bus-bus switches are fused internally for the power flow, open bus-bus switches are ignored:

alternate Text

This has the following advantages compared to modelling the switch as a small impedance:

  • there is no voltage drop over the switch (ideal switch)
  • no convergence problems due to small impedances / large admittances
  • less buses in the admittance matrix

Bus-Element-Switches:

When the power flow is calculated internally for every open bus-element switch an auxilary bus is created in the pypower case file. The pypower branch that corresponds to the element is then connected to this bus. This has the following advantages compared to modelling the switch by setting the element out of service:

  • loading current is considered
  • information about switch position is preserved
  • difference between open switch and out of service line (e.g. faulty line) can be modelled

Closed bus-element switches are ignored:

alternate Text

Load

Create Function

Input Parameters

net.load

Parameter Datatype Value Range Explanation
name string   name of the load
bus * integer   index of connected bus
p_kw* float \(\geq 0\) active power of the load [kW]
q_kvar* float   reactive power of the load [kVar]
const_z_percent* float \([0,100]\) percentage of p_kw and q_kvar that is associated to constant impedance load at rated voltage [\(\%\)]
const_i_percent* float \([0,100]\) percentage of p_kw and q_kvar that is associated to constant current load at rated voltage [\(\%\)]
sn_kva float \(>0\) rated power of the load [kVA]
scaling * float \(\geq 0\) scaling factor for active and reactive power
in_service* boolean True / False specifies if the load is in service.
controllable** bool   States if load is controllable or not, load will not be used as a flexibilty if it is not controllable
max_p_kw** float   Maximum active power
min_p_kw** float   Minimum active power
max_q_kvar** float   Maximum reactive power
min_q_kvar** float   Minimum reactive power

*necessary for executing a power flow calculation.

Note

Loads should always have a positive p_kw value, since all power values are given in the consumer system. If you want to model constant generation, use a Static Generator (sgen element) instead of a negative load.

Note

The apparent power value sn_kva is provided as additional information for usage in controller or other applications based on panadapower. It is not considered in the power flow!

Electric Model

Loads are modelled as PQ-buses in the power flow calculation, with an option to use the so-called ZIP load model, where a load is represented as a composition of constant power (P), constant current (I) and constant impedance (Z):

alternate Text

What part of the load is considered constant with constant power, constant current or constant impedance is defined as follows:

\begin{align*} z_{const} =& const\_z\_percent / 100 \\ i_{const} =& const\_i\_percent / 100 \\ p_{const} =& (100 - const\_z\_percent - const\_i\_percent) / 100 \end{align*}

The load power values are then defines as:

\begin{align*} P_{load} =& p\_kw \cdot scaling \cdot (p_{const} + z_{const} \cdot V^2 + i_{const} \cdot V ) \\ Q_{load} =& q\_kvar \cdot scaling \cdot (p_{const} + z_{const} \cdot V^2 + i_{const} \cdot V) \end{align*}

Result Parameters

net.res_load

Parameter Datatype Explanation
p_kw float resulting active power demand after scaling and after considering voltage dependence [kW]
q_kvar float resulting reactive power demand after scaling and after considering voltage dependence [kVar]

The power values in the net.res_load table are equivalent to \(P_{load}\) and \(Q_{load}\).

Static Generator

Create Function

Input Parameters

net.sgen

Parameter Datatype Value Range Explanation
name string   name of the static generator
type string
naming conventions:
“PV” - photovoltaic system
“WP” - wind power system
“CHP” - combined heating and power system
type of generator
bus* integer   index of connected bus
p_kw* float \(\leq\) 0 active power of the static generator [kW]
q_kvar* float   reactive power of the static generator [kVar]
sn_kva float \(>\) 0 rated power ot the static generator [kVA]
scaling* float \(\geq\) 0 scaling factor for the active and reactive power
max_p_kw** float   Maximum active power
min_p_kw** float   Minimum active power
max_q_kvar** float   Maximum reactive power
min_q_kvar** float   Minimum reactive power
controllable** bool   States if sgen is controllable or not, sgen will not be used as a flexibilty if it is not controllable
k*** float \(\geq\) 0 Ratio of nominal current to short circuit current
rx*** float \(\geq\) 0 R/X ratio for short circuit impedance. Only relevant if type is specified as motor so that sgen is treated as asynchronous motor
in_service* boolean True / False specifies if the generator is in service.

*necessary for executing a power flow calculation
**optimal power flow parameter

Electric Model

Static Generators are modelled as PQ-buses in the power flow calculation:

alternate Text

The PQ-Values are calculated from the parameter table values as:

\begin{align*} P_{sgen} &= p\_kw \cdot scaling \\ Q_{sgen} &= q\_kvar \cdot scaling \\ \end{align*}

Note

Static generators should always have a negative p_kw value, since all power values are given in the consumer system. If you want to model constant power consumption, please use the load element instead of a static generator with positive active power value. If you want to model a voltage controlled generator, use the generator element.

Note

The apparent power value sn_kva is provided as additional information for usage in controller or other applications based on panadapower. It is not considered in the power flow!

Result Parameters

net.res_sgen

Parameter Datatype Explanation
p_kw float resulting active power demand after scaling [kW]
q_kvar float resulting reactive power demand after scaling [kVar]

The power values in the net.res_sgen table are equivalent to \(P_{sgen}\) and \(Q_{sgen}\).

External Grid

Create Function

Input Parameters

net.ext_grid

Parameter Datatype Value Range Explanation
name string   name of the external grid
bus* integer   index of connected bus
vm_pu* float \(>\) 0 voltage set point [p.u]
va_degree* float   angle set point [degree]
max_p_kw** float   Maximum active power
min_p_kw** float   Minimum active power
max_q_kvar** float   Maximum reactive power
min_q_kvar** float   Minimum reactive power
s_sc_max_mva*** float \(>\) 0 maximum short circuit power provision [MVA]
s_sc_min_mva*** float \(>\) 0 minimum short circuit power provision [MVA]
rx_max*** float 0…1 maxium R/X ratio of short-circuit impedance
rx_min*** float 0…1 minimum R/X ratio of short-circuit impedance
in_service* boolean True / False specifies if the external grid is in service.

*necessary for executing a power flow calculation
**optimal power flow parameter
***short-circuit calculation parameter

Electric Model

The external grid is modelled as a voltage source in the power flow calculation, which means the node the grid is connected to is treated as a slack node:

alternate Text

with:

\begin{align*} \underline{v}_{bus} &= vm\_pu \cdot e^{j \cdot \theta} \\ \theta &= shift\_degree \cdot \frac{\pi}{180} \end{align*}

Result Parameters

net.res_ext_grid

Parameter Datatype Explanation
p_kw float active power supply at the external grid [kW]
q_kvar float reactive power supply at the external grid [kVar]

Active and reactive power feed-in / consumption at the slack node is a result of the power flow:

\begin{align*} p\_kw &= P_{eg} \\ q\_kvar &= Q_{eg} \end{align*}

Note

All power values are given in the consumer system, therefore p_kw is positive if the external grid is absorbing power and negative if it is supplying power.

Transformer

Create Function

Transformers can be either created from the standard type library (create_transformer) or with custom values (create_transformer_from_parameters).

Input Parameters

net.trafo

Parameter Datatype Value Range Explanation
name string   name of the transformer
std_type string   transformer standard type name
hv_bus* integer   high voltage bus index of the transformer
lv_bus* integer   low voltage bus index of the transformer
sn_kva* float \(>\) 0 rated apparent power of the transformer [kVA]
vn_hv_kv* float \(>\) 0 rated voltage at high voltage bus [kV]
vn_lv_kv* float \(>\) 0 rated voltage at low voltage bus [kV]
vsc_percent* float \(>\) 0 short circuit voltage [%]
vscr_percent* float \(\geq\) 0 real component of short circuit voltage [%]
pfe_kw* float \(\geq\) 0 iron losses [kW]
i0_percent* float \(\geq\) 0 open loop losses in [%]
shift_degree* float   transformer phase shift angle
tp_side string “hv”, “lv” defines if tap changer is at the high- or low voltage side
tp_mid integer   rated tap position
tp_min integer   minimum tap position
tp_max integer   maximum tap position
tp_st_percent float \(>\) 0 tap step size for voltage magnitude [%]
tp_st_degree float \(\geq\) 0 tap step size for voltage angle
tp_pos integer   current position of tap changer
tp_phase_shifter bool   defines whether the transformer is an ideal phase shifter
parallel int \(>\) 0 number of parallel transformers
max_loading_percent** float \(>\) 0 Maximum loading of the transformer with respect to sn_kva and its corresponding current at 1.0 p.u.
df float 1 \(\geq\) df :math:`>`0 derating factor: maximal current of transformer in relation to nominal current of transformer (from 0 to 1)
in_service* boolean True / False specifies if the transformer is in service.

*necessary for executing a power flow calculation
**optimal power flow parameter

Note

The transformer loading constraint for the optimal power flow corresponds to the option trafo_loading=”current”:

Electric Model

The equivalent circuit used for the transformer can be set in the power flow with the parameter “trafo_model”.

trafo_model=’t’:

_images/trafo_t.png

trafo_model=’pi’:

_images/trafo_pi.png
Transformer Ratio

The magnitude of the transformer ratio is given as:

\begin{align*} n &= \frac{V_{ref, HV, transformer}}{V_{ref, LV, transformer}} \cdot \frac{V_{ref, LV bus}}{V_{ref, HV bus}} \end{align*}

The reference voltages of the high- and low voltage buses are taken from the net.bus table. The reference voltage of the transformer is taken directly from the transformer table:

\begin{align*} V_{ref, HV, transformer} &= vn\_hv\_kv \\ V_{ref, LV, transformer} &= vn\_lv\_kv \end{align*}

If the power flow is run with voltage_angles=True, the complex ratio is given as:

\begin{align*} \underline{n} &= n \cdot e^{j \cdot \theta \cdot \frac{\pi}{180}} \\ \theta &= shift\_degree \end{align*}

Otherwise, the ratio does not include a phase shift:

\begin{align*} \underline{n} &= n \end{align*}
Impedance Values

The short-circuit impedance is calculated as:

\begin{align*} z_k &= \frac{vsc\_percent}{100} \cdot \frac{1000}{sn\_kva} \\ r_k &= \frac{vscr\_percent}{100} \cdot \frac{1000}{sn\_kva} \\ x_k &= \sqrt{z^2 - r^2} \\ \underline{z}_k &= r_k + j \cdot x_k \end{align*}

The magnetising admittance is calculated as:

\begin{align*} y_m &= \frac{i0\_percent}{100} \\ g_m &= \frac{pfe\_kw}{sn\_kva \cdot 1000} \cdot \frac{1000}{sn\_kva} \\ b_m &= \sqrt{y_m^2 - g_m^2} \\ \underline{y_m} &= g_m - j \cdot b_m \end{align*}

The values calculated in that way are relative to the rated values of the transformer. To transform them into the per unit system, they have to be converted to the rated values of the network:

\begin{align*} Z_{N} &= \frac{V_{N}^2}{S_{N}} \\ Z_{ref, trafo} &= \frac{vn\_lv\_kv^2 \cdot 1000}{sn\_kva} \\ \underline{z} &= \underline{z}_k \cdot \frac{Z_{ref, trafo}}{Z_{N}} \\ \underline{y} &= \underline{y}_m \cdot \frac{Z_{N}}{Z_{ref, trafo}} \\ \end{align*}

Where the reference voltage \(V_{N}\) is the nominal voltage at the low voltage side of the transformer and the rated apparent power \(S_{N}\) is defined system wide in the net object (see Unit Systems and Conventions).

Tap Changer

Longitudinal regulator

A longitudinal regulator can be modeled by setting tp_phase_shifter to False and defining the tap changer voltage step with tp_st_percent.

The reference voltage is then multiplied with the tap factor:

\begin{align*} n_{tap} = 1 + (tp\_pos - tp\_mid) \cdot \frac{tp\_st\_percent}{100} \end{align*}

On which side the reference voltage is adapted depends on the \(tp\_side\) variable:

  tp_side=”hv” tp_side=”lv”
\(V_{n, HV, transformer}\) \(vnh\_kv \cdot n_{tap}\) \(vnh\_kv\)
\(V_{n, LV, transformer}\) \(vnl\_kv\) \(vnl\_kv \cdot n_{tap}\)

Note

The variables tp_min and tp_max are not considered in the power flow. The user is responsible to ensure that tp_min < tp_pos < tp_max!

Cross regulator

In addition to tp_st_percent a value for tp_st_degree can be defined to model an angle shift for each tap, resulting in a cross regulator that affects the magnitude as well as the angle of the transformer ratio.

Ideal phase shifter

If tp_phase_shifter is set to True, the tap changer is modeled as an ideal phase shifter, meaning that a constant angle shift is added with each tap step:

\begin{align*} \underline{n} &= n \cdot e^{j \cdot (\theta + \theta_{tp}) \cdot \frac{\pi}{180}} \\ \theta &= shift\_degree \end{align*}

The angle shift can be directly defined in tp_st_degree, in which case:

\begin{align*} \theta_{tp} = tp\_st\_degree \cdot (tp\_pos - tp\_mid) \end{align*}

or it can be given as a constant voltage step in tp_st_percent, in which case the angle is calculated as:

\begin{align*} \theta_{tp} = 2 \cdot arcsin(\frac{1}{2} \cdot \frac{tp\_st\_percent}{100}) \cdot (tp\_pos - tp\_mid) \end{align*}

If both values are given for an ideal phase shift transformer, the power flow will raise an error.

Result Parameters

net.res_trafo

Parameter Datatype Explanation
p_hv_kw float active power flow at the high voltage transformer bus [kW]
q_hv_kvar float reactive power flow at the high voltage transformer bus [kVar]
p_lv_kw float active power flow at the low voltage transformer bus [kW]
q_lv_kvar float reactive power flow at the low voltage transformer bus [kVar]
pl_kw float active power losses of the transformer [kW]
ql_kvar float reactive power consumption of the transformer [kvar]
i_hv_ka float current at the high voltage side of the transformer [kA]
i_lv_ka float current at the low voltage side of the transformer [kA]
loading_percent float load utilization relative to rated power [%]
\begin{align*} p\_hv\_kw &= Re(\underline{v}_{hv} \cdot \underline{i}^*_{hv}) \\ q\_hv\_kvar &= Im(\underline{v}_{hv} \cdot \underline{i}^*_{hv}) \\ p\_lv\_kw &= Re(\underline{v}_{lv} \cdot \underline{i}^*_{lv}) \\ q\_lv\_kvar &= Im(\underline{v}_{lv} \cdot \underline{i}^*_{lv}) \\ pl\_kw &= p\_hv\_kw + p\_lv\_kw \\ ql\_kvar &= q\_hv\_kvar + q\_lv\_kvar \\ i\_hv\_ka &= i_{hv} \\ i\_lv\_ka &= i_{lv} \end{align*}

The definition of the transformer loading depends on the trafo_loading parameter of the power flow.

For trafo_loading=”current”, the loading is calculated as:

\begin{align*} loading\_percent &= max(\frac{i_{hv} \cdot vn\_hv\_kv}{sn\_kva}, \frac{i_{lv} \cdot vn\_lv\_kv}{sn\_kva}) \cdot 100 \end{align*}

For trafo_loading=”power”, the loading is defined as:

\begin{align*} loading\_percent &= max( \frac{i_{hv} \cdot v_{hv}}{sn\_kva}, \frac{i_{lv} \cdot v_{lv}}{sn\_kva}) \cdot 100 \end{align*}

Three Winding Transformer

Create Function

Note

All short circuit voltages are given relative to the maximum apparent power flow. For example vsc_hv_percent is the short circuit voltage from the high to the medium level, it is given relative to the minimum of the rated apparent power in high and medium level: min(sn_hv_kva, sn_mv_kva). This is consistent with most commercial network calculation software (e.g. PowerFactory). Some tools (like PSS Sincal) however define all short ciruit voltages relative to the overall rated apparent power of the transformer: max(sn_hv_kva, sn_mv_kva, sn_lv_kva). You might have to convert the values depending on how the short-circuit voltages are defined.

Input Parameters

net.trafo3w

Parameter Datatype Value Range Explanation
name string   name of the transformer
std_type string   transformer standard type name
hv_bus* integer   high voltage bus index of the transformer
mv_bus integer   medium voltage bus index of the transformer
lv_bus* integer   low voltage bus index of the transformer
vn_hv_kv* float   rated voltage at high voltage bus [kV]
vn_mv_kv* float \(>\) 0 rated voltage at medium voltage bus [kV]
vn_lv_kv* float \(>\) 0 rated voltage at low voltage bus [kV]
sn_hv_kva* float \(>\) 0 rated apparent power on high voltage side [kVA]
sn_mv_kva* float \(>\) 0 rated apparent power on medium voltage side [kVA]
sn_lv_kva* float \(>\) 0 rated apparent power on low voltage side [kVA]
vsc_hv_percent* float \(>\) 0 short circuit voltage from high to medium voltage [%]
vsc_mv_percent* float \(>\) 0 short circuit voltage from medium to low voltage [%]
vsc_lv_percent* float \(>\) 0 short circuit voltage from high to low voltage [%]
vscr_hv_percent* float \(\geq\) 0 real part of short circuit voltage from high to medium voltage [%]
vscr_mv_percent* float \(\geq\) 0 real part of short circuit voltage from medium to low voltage [%]
vscr_lv_percent* float \(\geq\) 0 real part of short circuit voltage from high to low voltage [%]
pfe_kw* float \(\geq\) 0 iron losses [kW]
i0_percent* float \(\geq\) 0 open loop losses [%]
shift_mv_degree float   transformer phase shift angle at the MV side
shift_lv_degree float   transformer phase shift angle at the LV side
tp_side string “hv”, “mv”, “lv” defines if tap changer is positioned on high- medium- or low voltage side
tp_mid integer    
tp_min integer   minimum tap position
tp_max integer   maximum tap position
tp_st_percent float \(>\) 0 tap step size [%]
tp_st_degree float   tap step size for voltage angle
tp_at_star_point bool   whether the tap changer is modelled at terminal or at star point
tp_pos integer   current position of tap changer
in_service* boolean True/False specifies if the transformer is in service.

*necessary for executing a power flow calculation.

Note

Three Winding Transformer loading can not yet be constrained with the optimal power flow.

Electric Model

Three Winding Transformers are modelled by three two-winding transformers:

alternate Text

The parameters of the three transformers are defined as follows:

  T1 T2 T3
hv_bus hv_bus auxiliary bus auxiliary bus
lv_bus auxiliary bus mv_bus lv_bus
sn_kva sn_hv_kva sn_mv_kva sn_lv_kva
vn_hv_kv vn_hv_kv vn_hv_kv vn_hv_kv
vn_lv_kv vn_hv_kv vn_mv_kv vn_lv_kv
vsc_percent \(v_{k, t1}\) \(v_{k, t2}\) \(v_{k, t3}\)
vscr_percent \(v_{r, t1}\) \(v_{r, t2}\) \(v_{r, t3}\)
pfe_kw pfe_kw 0 0
i0_percent i0_percent 0 0
shift_degree shift_degree 0 0

The definition of the two winding transformer parameter can be found here.

To calculate the short-circuit voltages \(v_{k, t1..t3}\) and \(v_{r, t1..t3}\), first all short-circuit voltages are converted to the high voltage level:

\begin{align*} v'_{k, h} &= vsc\_hv\_percent \\ v'_{k, m} &= vsc\_mv\_percent \cdot \frac{sn\_hv\_kva}{sn\_mv\_kva} \\ v'_{k, l} &= vsc\_lv\_percent \cdot \frac{sn\_hv\_kva}{sn\_lv\_kva} \end{align*}

The short-circuit voltages of the three transformers are then calculated as follows:

\begin{align*} v'_{k, t1} &= \frac{1}{2} (v'_{k, h} + v'_{k, l} - v'_{k, m}) \\ v'_{k, t2} &= \frac{1}{2} (v'_{k, m} + v'_{k, h} - v'_{k, l}) \\ v'_{k, t3} &= \frac{1}{2} (v'_{k, m} + v'_{k, l} - v'_{k, h}) \end{align*}

Since these voltages are given relative to the high voltage side, they have to be transformed back to the voltage level of each transformer:

\begin{align*} v_{k, t1} &= v'_{k, t1} \\ v_{k, t2} &= v'_{k, t2} \cdot \frac{sn\_mv\_kva}{sn\_hv\_kva} \\ v_{k, t3} &= v'_{k, t3} \cdot \frac{sn\_lv\_kva}{sn\_hv\_kva} \end{align*}

The real part of the short-circuit voltage is calculated in the same way.

Note

All short circuit voltages are given relative to the maximum apparent power flow. For example vsc_hv_percent is the short circuit voltage from the high to the medium level, it is given relative to the minimum of the rated apparent power in high and medium level: min(sn_hv_kva, sn_mv_kva). This is consistent with most commercial network calculation software (e.g. PowerFactory). Some tools (like PSS Sincal) however define all short circuit voltages relative to the overall rated apparent power of the transformer: max(sn_hv_kva, sn_mv_kva, sn_lv_kva). You might have to convert the values depending on how the short-circuit voltages are defined.

The tap changer adapts the nominal voltages of the transformer in the equivalent to the 2W-Model:

  tp_side=”hv” tp_side=”mv” tp_side=”lv”
\(V_{n, HV, transformer}\) \(vnh\_kv \cdot n_{tap}\) \(vnh\_kv\) \(vnh\_kv\)
\(V_{n, MV, transformer}\) \(vnm\_kv\) \(vnm\_kv \cdot n_{tap}\) \(vnm\_kv\)
\(V_{n, LV, transformer}\) \(vnl\_kv\) \(vnl\_kv\) \(vnl\_kv \cdot n_{tap}\)

with

\begin{align*} n_{tap} = 1 + (tp\_pos - tp\_mid) \cdot \frac{tp\_st\_percent}{100} \end{align*}

Result Parameters

net.res_trafo3w

Parameter Datatype Explanation
p_hv_kw float active power flow at the high voltage transformer bus [kW]
q_hv_kvar float reactive power flow at the high voltage transformer bus [kVar]
p_mv_kw float active power flow at the medium voltage transformer bus [kW]
q_mv_kvar float reactive power flow at the medium voltage transformer bus [kVar]
p_lv_kw float active power flow at the low voltage transformer bus [kW]
q_lv_kvar float reactive power flow at the low voltage transformer bus [kVar]
pl_kw float active power losses of the transformer [kW]
ql_kvar float reactive power consumption of the transformer [kvar]
i_hv_ka float current at the high voltage side of the transformer [kA]
i_mv_ka float current at the medium voltage side of the transformer [kA]
i_lv_ka float current at the low voltage side of the transformer [kA]
loading_percent float transformer utilization [%]
\begin{align*} p\_hv\_kw &= Re(\underline{v}_{hv} \cdot \underline{i}_{hv}) \\ q\_hv\_kvar &= Im(\underline{v}_{hv} \cdot \underline{i}_{hv}) \\ p\_mv\_kw &= Re(\underline{v}_{mv} \cdot \underline{i}_{mv}) \\ q\_mv\_kvar &= Im(\underline{v}_{mv} \cdot \underline{i}_{mv}) \\ p\_lv\_kw &= Re(\underline{v}_{lv} \cdot \underline{i}_{lv}) \\ q\_lv\_kvar &= Im(\underline{v}_{lv} \cdot \underline{i}_{lv}) \\ pl\_kw &= p\_hv\_kw + p\_lv\_kw \\ ql\_kvar &= q\_hv\_kvar + q\_lv\_kvar \\ i\_hv\_ka &= i_{hv} \\ i\_mv\_ka &= i_{mv} \\ i\_lv\_ka &= i_{lv} \end{align*}

The definition of the transformer loading depends on the trafo_loading parameter of the power flow.

For trafo_loading=”current”, the loading is calculated as:

\begin{align*} loading\_percent &= max(\frac{i_{hv} \cdot vn\_hv\_kv}{sn\_hv\_kva}, \frac{i_{mv} \cdot vn\_mv\_kv}{sn\_mv\_kva}, \frac{i_{lv} \cdot vn\_lv\_kv}{sn\_lv\_kva}) \cdot 100 \end{align*}

For trafo_loading=”power”, the loading is defined as:

\begin{align*} loading\_percent &= max( \frac{i_{hv} \cdot v_{hv}}{sn\_hv\_kva}, \frac{i_{mv} \cdot v_{mv}}{sn\_mv\_kva}, \frac{i_{lv} \cdot v_{lv}}{sn\_lv\_kva}) \cdot 100 \end{align*}

Generator

Create Function

Input Parameters

net.gen

Parameter Datatype Value Range Explanation
name string   name of the generator
type string
naming conventions:
“sync” - synchronous generator
“async” - asynchronous generator
type variable to classify generators
bus* integer   index of connected bus
p_kw* float \(\leq\) 0 the real power of the generator [kW]
vm_pu* float   voltage set point of the generator [p.u]
sn_kva float \(>\) 0 nominal power of the generator [kVA]
min_q_kvar float   minimal reactive power of the generator [kVar]
max_q_kvar float   maximal reactive power of the generator [kVar]
scaling* float \(\leq\) 0 scaling factor for the active power
max_p_kw** float   Maximum active power
min_p_kw** float   Minimum active power
max_q_kvar** float   Maximum reactive power
min_q_kvar** float   Minimum reactive power
controllable** bool True/False States if a gen is controllable or not. Currently gens must be controllable, because there is no method to respect uncontrollable gens yet.
vn_kv*** float    
xdss*** float \(>\) 0  
rdss*** float \(>\) 0 Rated voltage of the generator
cos_phi*** float \(0 \leq\) 1 Subtransient generator reactance
in_service* boolean True / False Subtransient generator resistence
      Rated generator cosine phi
      specifies if the generator is in service.

*necessary for executing a power flow calculation
**optimal power flow parameter
***short-circuit calculation parameter

Note

Active power should normally be negative to model a voltage controlled generator, since all power values are given in the load reference system. A generator with positive active power represents a voltage controlled machine. If you want to model constant generation without voltage control, use the Static Generator element.

Electric Model

Generators are modelled as PV-nodes in the power flow:

alternate Text

Voltage magnitude and active power are defined by the input parameters in the generator table:

\begin{align*} P_{gen} &= p\_kw * scaling \\ v_{bus} &= vm\_pu \end{align*}

Result Parameters

net.res_gen

Parameter Datatype Explanation
p_kw float resulting active power demand after scaling [kW]
q_kvar float resulting reactive power demand after scaling [kVar]
va_degree float generator voltage angle [degree]
vm_pu float voltage at the generator [p.u]

The power flow returns reactive generator power and generator voltage angle:

\begin{align*} p\_kw &= P_{gen} \\ q\_kvar &= Q_{gen} \\ va\_degree &= \angle \underline{v}_{bus} \\ vm\_degree &= |\underline{v}_{bus}| \end{align*}

Note

If the power flow is run with the enforce_qlims option and the generator reactive power exceeds / underruns the maximum / minimum reactive power limit, the generator is converted to a static generator with the maximum / minimum reactive power as constant reactive power generation. The voltage at the generator bus is then no longer equal to the voltage set point defined in the parameter table.

Shunt

Create Function

Input Parameters

net.shunt

Parameter Datatype Value Range Explanation
name string   name of the shunt
bus* integer   index of bus where the impedance starts
p_kw* float \(\geq\) 0 shunt active power in kW at v= 1.0 p.u.
q_kvar* float   shunt reactive power in kvar at v= 1.0 p.u.
vn_kv* float \(>\) 0 rated voltage of the shunt element
step* integer \(\geq\) 1 step position of the shunt
in_service* boolean True / False specifies if the shunt is in service.

*necessary for executing a power flow calculation.

Electric Model

alternate Text

The power values are given at \(v = 1\) pu and are scaled linearly with the number of steps:

\begin{align*} \underline{S}_{shunt, ref} &= (p\_kw + j \cdot q\_kvar) \cdot step \end{align*}

Since \(\underline{S}_{shunt, ref}\) is the apparent power at the nominal voltage, we know that:

\begin{align*} \underline{Y}_{shunt} = \frac{\underline{S}_{shunt, ref}}{vn\_kv^2} \end{align*}

Converting to the per unit system results in:

\begin{align*} \underline{y}_{shunt} &= \frac{\underline{S}_{shunt, ref}}{V_{N}^2} \cdot Z_{N}\\ &= \frac{\underline{S}_{shunt, ref}}{V_{N}^2} \cdot \frac{V_{N}^2}{S_{N}} \\ &= \frac{S_{shunt, ref}}{S_{N}} \end{align*}

with the reference values for the per unit system as defined in Unit Systems and Conventions.

Result Parameters

net.res_shunt

Parameter Datatype Explanation
p_kw float shunt active power consumption [kW]
q_kvar float shunt reactive power consumption [kVAr]
vm_pu float voltage magnitude at shunt bus [pu]
\begin{align*} p\_kw &= Re(\underline{v}_{bus} \cdot \underline{i}_{shunt}) \\ q\_kvar &= Im(\underline{v}_{bus} \cdot \underline{i}_{shunt}) \\ vm\_pu &= v_{bus} \end{align*}

Impedance

Create Function

Input Parameters

net.impedance

Parameter Datatype Value Range Explanation
name string   name of the impedance
from_bus* integer   index of bus where the impedance starts
to_bus* integer   index of bus where the impedance ends
rft_pu* float \(>\) 0 resistance of the impedance from ‘from’ to ‘to’ bus [p.u]
xft_pu* float \(>\) 0 reactance of the impedance from ‘from’ to ‘to’ bus [p.u]
rtf_pu* float \(>\) 0 resistance of the impedance from ‘to’ to ‘from’ bus [p.u]
xtf_pu* float \(>\) 0 reactance of the impedance from ‘to’ to ‘from’ bus [p.u]
sn_kva* float \(>\) 0 reference apparent power for the impedance per unit values [kVA]
in_service* boolean True / False specifies if the imepdance is in service.

*necessary for executing a power flow calculation.

Electric Model

The impedance is modelled as a longitudinal per unit impedance with \(\underline{z}_{ft} \neq \underline{z}_{tf}\) :

alternate Text

The per unit values given in the parameter table are assumed to be relative to the rated voltage of from and to bus as well as to the apparent power given in the table. The per unit values are therefore transformed into the network per unit system:

\begin{align*} \underline{z}_{ft} &= (rft\_pu + j \cdot xft\_pu) \cdot \frac{S_{N}}{sn\_kva} \\ \underline{z}_{tf} &= (rft\_pu + j \cdot xtf\_pu) \cdot \frac{S_{N}}{sn\_kva} \\ \end{align*}

where \(S_{N}\) is the reference power of the per unit system (see Unit Systems and Conventions).

The asymetric impedance results in an asymetric nodal point admittance matrix:

\begin{bmatrix} Y_{00} & \dots & \dots & Y_{nn} \\ \vdots & \ddots & \underline{y}_{ft} & \vdots \\ \vdots & \underline{y}_{tf} & \ddots & \vdots \\ \underline{Y}_{n0} & \dots & \dots & \underline{y}_{nn}\\ \end{bmatrix}

Result Parameters

net.res_impedance

Parameter Datatype Explanation
p_from_kw float active power flow into the impedance at “from” bus [kW]
q_from_kvar float reactive power flow into the impedance at “from” bus [kVAr]
p_to_kw float active power flow into the impedance at “to” bus [kW]
q_to_kvar float reactive power flow into the impedance at “to” bus [kVAr]
pl_kw float active power losses of the impedance [kW]
ql_kvar float reactive power consumption of the impedance [kVar]
i_from_ka float current at from bus [kA]
i_to_ka float current at to bus [kA]
\begin{align*} i\_from\_ka &= i_{from}\\ i\_to\_ka &= i_{to}\\ p\_from\_kw &= Re(\underline{v}_{from} \cdot \underline{i}^*_{from}) \\ q\_from\_kvar &= Im(\underline{v}_{from} \cdot \underline{i}^*_{from}) \\ p\_to\_kw &= Re(\underline{v}_{to} \cdot \underline{i}^*_{to}) \\ q\_to\_kvar &= Im(\underline{v}_{to} \cdot \underline{i}^*_{to}) \\ pl\_kw &= p\_from\_kw + p\_to\_kw \\ ql\_kvar &= q\_from\_kvar + q\_to\_kvar \\ \end{align*}

Ward

Create Function

Input Parameters

net.ward

Parameter Datatype Value Range Explanation
name string   name of the ward equivalent
bus* integer   index of connected bus
ps_kw* float   constant active power demand [kW]
qs_kvar* float   constant reactive power demand [kVar]
pz_kw* float   constant impedance active power demand at 1.0 pu [kW]
qz_kvar* float   constant impedance reactive power demand at 1.0 pu [kVar]
in_service* boolean True / False specifies if the ward equivalent is in service.

*necessary for executing a power flow calculation.

Electric Model

_images/ward.png

The ward equivalent is a combination of a constant apparent power consumption and a constant impedance load. The constant apparent power is given by:

\begin{align*} P_{const} &= ps\_kw\\ Q_{const} &= qs\_kvar\\ \end{align*}

The shunt admittance part of the ward equivalent is calculated as described here:

\begin{align*} \underline{y}_{shunt} &= \frac{pz\_kw + j \cdot qz\_kvar}{S_{N}} \end{align*}

Result Parameters

net.res_ward

Parameter Datatype Explanation
p_kw float active power demand of the ward equivalent [kW]
q_kvar float reactive power demand of the ward equivalent [kVar]
vm_pu float voltage at the ward bus [p.u]
\begin{align*} vm\_pu &= v_{bus} \\ p\_kw &= P_{const} + Re(\frac{\underline{V}_{bus}^2}{\underline{Y}_{shunt}}) \\ q\_kvar &= Q_{const} + Im(\frac{\underline{V}_{bus}^2}{\underline{Y}_{shunt}}) \end{align*}

Extended Ward

Create Function

Result Parameters

net.xward

Parameter Datatype Value Range Explanation
name string   name of the extended ward equivalent
bus* integer   index of connected bus
ps_kw* float   constant active power demand [kW]
qs_kvar* float   constant reactive power demand [kVar]
pz_kw* float   constant impedance active power demand at 1.0 pu [kW]
qz_kvar* float   constant impedance reactive power demand at 1.0 pu [kVar]
r_pu* float \(>\) 0 internal resistance of the voltage source [p.u]
x_pu* float \(>\) 0 internal reactance of the voltage source [p.u]
vm_pu* float \(>\) 0 voltage source set point [p.u]
in_service* boolean True / False specifies if the extended ward equivalent is in service.

*necessary for executing a power flow calculation.

Electric Model

The extended ward equivalent is a ward equivalent: with additional PV-node with an internal resistance.

_images/xward.png

The constant apparent power is given by:

\begin{align*} P_{const} &= ps\_kw\\ Q_{const} &= qs\_kvar\\ \end{align*}

The shunt admittance part of the extended ward equivalent is calculated as described here:

\begin{align*} \underline{y}_{shunt} &= \frac{pz\_kw + j \cdot qz\_kvar}{S_{N}} \end{align*}

The internal resistance is defined as:

\begin{align*} \underline{z}_{int} &= r\_pu + j \cdot x\_pu \end{align*}

The internal voltage source is modelled as a PV-node (generator) with:

\begin{align*} p\_kw &= 0 \\ vm\_pu &= vm\_pu \end{align*}

Result Parameters

net.res_xward

Parameter Datatype Explanation
p_kw float active power demand of the ward equivalent [kW]
q_kvar float reactive power demand of the ward equivalent [kVar]
vm_pu float voltage at the ward bus [p.u]
\begin{align*} vm\_pu &= v_{bus} \\ p\_kw &= P_{const} + Re(\frac{\underline{V}_{bus}^2}{\underline{Y}_{shunt}}) + Re(\underline{I}_{int} \cdot \underline{V}_{bus}) \\ q_kvar &= Q_{const} + Im(\frac{\underline{V}_{bus}^2}{\underline{Y}_{shunt}} + Im(\underline{I}_{int} \cdot \underline{V}_{bus}) ) \end{align*}

DC Line

Create Function

Input Parameters

net.dcline

Parameter Datatype Value Range Explanation
name string   name of the generator
from_bus* integer   Index of bus where the dc line starts
to_bus* integer   Index of bus where the dc line ends
p_kw* float \(>\) 0 Active power transmitted from ‘from_bus’ to ‘to_bus’
loss_percent* float \(>\) 0 Relative transmission loss in percent of active power transmission
loss_kw* float \(>\) 0 Total transmission loss in kW
vm_from_pu* float \(>\) 0 Voltage setpoint at from bus
vm_to_pu* float \(>\) 0 Voltage setpoint at to bus
max_p_kw** float \(>\) 0 Maximum active power transmission
min_q_from_kvar** float   Minimum reactive power at from bus
max_q_from_kvar** float   Maximum reactive power at from bus
min_q_to_kvar** float   Minimum reactive power at to bus
max_q_to_kvar** float   Maximum reactive power at to bus
in_service* bool True/False specifies if DC line is in service

*necessary for executing a power flow calculation
**optimal power flow parameter

Note

DC line is only able to model one-directional loadflow for now, which is why p_kw / max_p_kw have to be > 0.

Electric Model

A DC line is modelled as two generators in the loadflow:

alternate Text alternate Text

The active power at the from side is defined by the parameters in the dcline table. The active power at the to side is equal to the active power on the from side minus the losses of the DC line.

\begin{align*} P_{from} &= p\_kw \\ P_{to} &= - (p\_kw - loss\_kw) \cdot (1 - \frac{loss\_percent}{100}) \end{align*}

The voltage control with reactive power works just as described for the generator model. Maximum and Minimum reactive power limits are considered in the OPF, and in the PF if it is run with enforce_q_lims=True.

Result Parameters

net.res_dcline

Parameter Datatype Explanation
p_from_kw float active power flow into the line at ‘from_bus’ [kW]
q_from_kvar float reactive power flow into the line at ‘from_bus’ [kVar]
p_to_kw float active power flow into the line at ‘to_bus’ [kW]
q_to_kvar float reactive power flow into the line at ‘to_bus’ [kVar]
pl_kw float active power losses of the line [kW]
vm_from_pu float voltage magnitude at ‘from_bus’ [p.u]
va_from_degree float voltage angle at ‘from_bus’ [degree]
vm_to_pu float voltage magnitude at ‘to_bus’ [p.u]
va_to_degree float voltage angle at ‘to_bus’ [degree]
\begin{align*} p\_from\_kw &= P_{from} \\ p\_to\_kw &= P_{to} \\ pl\_kw &= p\_from\_kw + p\_to\_kw \\ q\_from\_kvar &= Q_{from} \\ q\_to\_kvar &= Q_{to} \\ va\_from\_degree &= \angle \underline{v}_{from} \\ va\_to\_degree &= \angle \underline{v}_{to} \\ vm\_from\_degree &= |\underline{v}_{from}| \\ vm\_to\_degree &= |\underline{v}_{to}| \\ \end{align*}

Measurement

Create Function

Input Parameters

net.measurement

Parameter Datatype Value Range Explanation
type string
“p”
“q”
“i”
“v”
Defines what physical quantity is measured
element_type string
“bus”
“line”
“transformer”
Defines which element type is equipped with the measurement
value float   Measurement value
std_dev float   Standard deviation (same unit as measurement)
bus int
must be in
net.bus.index
Defines the bus at which the measurement is placed. For line or transformer measurement it defines the side at which the measurement is placed (from_bus or to_bus).
element int
must be in
net.line.index or
net.trafo.index
If the element_type is “line” or “transformer”, element is the index of the relevant element. For “bus” measurements it is None (default)
check_existing bool   Checks if a measurement of the type already exists and overwrites it. If set to False, the measurement may be added twice (unsafe behaviour), but the performance increases
index int   Defines a specific index for the new measurement (if possible)

Storage

Create Function

Input Parameters

net.storage

Parameter Datatype Value Range Explanation
name string   name of the storage unit
bus* integer   index of connected bus
p_kw* float \(\leq\) 0 Momentary real power of the storage (positive for charging, negative for discharging)
q_kvar* float   Reactive power of the storage [kVar]
sn_kva float \(>\) 0 Nominal power ot the storage [kVA]
scaling* float \(\geq\) 0 scaling factor for the active and reactive power
soc_percent float 0 \(\leq\) soc_percent \(\leq\) 100 The state of charge of the storage
max_e_kwh float   The maximum energy content of the storage (maximum charge level)
min_e_kwh float   The minimum energy content of the storage (minimum charge level)
max_p_kw** float   Maximum active power
min_p_kw** float   Minimum active power
max_q_kvar** float   Maximum reactive power
min_q_kvar** float   Minimum reactive power
controllable** bool   States if sgen is controllable or not, sgen will not be used as a flexibilty if it is not controllable
in_service* boolean True / False specifies if the generator is in service.

*necessary for executing a power flow calculation
**optimal power flow parameter

Electric Model

Storages are modelled as PQ-buses in the power flow calculation:

alternate Text

The PQ-Values are calculated from the parameter table values as:

\begin{align*} P_{storage} &= p\_kw \cdot scaling \\ Q_{storage} &= q\_kvar \cdot scaling \\ \end{align*}

Note

Since all power values are given in the consumer system, negative power models charging and positive activee power models discharging.

Note

The apparent power value sn_kva, state of charge soc and storage capacity max_e_kwh are provided as additional information for usage in controller or other applications based on panadapower. It is not considered in the power flow!

Result Parameters

net.res_storage

Parameter Datatype Explanation
p_kw float resulting active power after scaling [kW]
q_kvar float resulting reactive power after scaling [kVar]

The power values in the net.res_storage table are equivalent to \(P_{storage}\) and \(Q_{storage}\).

Standard Type Libraries

Lines and transformers have two different categories of parameters: parameter that depend on the specific element (like the length of a line or the bus to which a transformer is connected to etc.) and parameter that only depend on the type of line or transformer which is used (like the rated power of a transformer or the resistance per kilometer line).

The standard type library provides a database of different types for transformer and lines, so that you only have to chose a certain type and not define all parameters individually for each line or transformer. The standard types are saved in the network as a dictionary in the form of:

net.std_types = {"line": {"standard_type": {"parameter": value, ...},..},
                "trafo": {"standard_type": {"parameter": value, ...},..},
                "trafo3w": {"standard_type": {"parameter": value, ...},..}}

The create_line and create_transformer functions use this database when you create a line or transformer with a certain standard type. You can also use the standard type functions directly to create new types in the database, directly load type data, change types or check if a certain type exists. You can also add additional type parameters which are not added to the pandas table by default (e.g. diameter of the conductor).

For a introduction on how to use the standard type library, see the interactive tutorial on standard types.

Basic Standard Types

Every pandapower network comes with a default set of standard types.

Note

The pandapower standard types are compatible with 50 Hz systems, please be aware that the standard type values might not be realistic for 60 Hz (or other) power systems.

Lines

  r_ohm_per_km x_ohm_per_km c_nf_per_km max_i_ka type q_mm2
149-AL1/24-ST1A 10.0 0.194 0.315 11.25 0.47 ol 149
149-AL1/24-ST1A 110.0 0.194 0.41 8.75 0.47 ol 149
149-AL1/24-ST1A 20.0 0.194 0.337 10.5 0.47 ol 149
15-AL1/3-ST1A 0.4 1.8769 0.35 11 0.105 ol 16
184-AL1/30-ST1A 110.0 0.1571 0.4 8.8 0.535 ol 184
184-AL1/30-ST1A 20.0 0.1571 0.33 10.75 0.535 ol 184
24-AL1/4-ST1A 0.4 1.2012 0.335 11.25 0.14 ol 24
243-AL1/39-ST1A 110.0 0.1188 0.39 9 0.645 ol 243
243-AL1/39-ST1A 20.0 0.1188 0.32 11 0.645 ol 243
305-AL1/39-ST1A 110.0 0.0949 0.38 9.2 0.74 ol 305
48-AL1/8-ST1A 0.4 0.5939 0.3 12.2 0.21 ol 48
48-AL1/8-ST1A 10.0 0.5939 0.35 10.1 0.21 ol 48
48-AL1/8-ST1A 20.0 0.5939 0.372 9.5 0.21 ol 48
490-AL1/64-ST1A 220.0 0.059 0.285 10 0.96 ol 490
490-AL1/64-ST1A 380.0 0.059 0.253 11 0.96 ol 490
94-AL1/15-ST1A 0.4 0.306 0.29 13.2 0.35 ol 94
94-AL1/15-ST1A 10.0 0.306 0.33 10.75 0.35 ol 94
94-AL1/15-ST1A 20.0 0.306 0.35 10 0.35 ol 94
N2XS(FL)2Y 1x120 RM/35 64/110 kV 0.153 0.166 112 0.366 cs 120
N2XS(FL)2Y 1x185 RM/35 64/110 kV 0.099 0.156 125 0.457 cs 185
N2XS(FL)2Y 1x240 RM/35 64/110 kV 0.075 0.149 135 0.526 cs 240
N2XS(FL)2Y 1x300 RM/35 64/110 kV 0.06 0.144 144 0.588 cs 300
NA2XS2Y 1x185 RM/25 12/20 kV 0.161 0.117 273 0.362 cs 185
NA2XS2Y 1x240 RM/25 12/20 kV 0.122 0.112 304 0.421 cs 240
NA2XS2Y 1x95 RM/25 12/20 kV 0.313 0.132 216 0.252 cs 95
NAYY 4x120 SE 0.225 0.08 264 0.242 cs 120
NAYY 4x150 SE 0.208 0.08 261 0.27 cs 150
NAYY 4x50 SE 0.642 0.083 210 0.142 cs 50

Transformers

  sn_kva vn_hv_kv vn_lv_kv vsc_percent vscr_percent pfe_kw i0_percent shift_degree tp_side tp_mid tp_min tp_max tp_st_percent tp_st_degree
0.25 MVA 10/0.4 kV 250 10 0.4 4 1.2 0.6 0.24 150 hv 0 -2 2 2.5 0
0.25 MVA 20/0.4 kV 250 20 0.4 6 1.44 0.8 0.32 150 hv 0 -2 2 2.5 0
0.4 MVA 10/0.4 kV 400 10 0.4 4 1.325 0.95 0.2375 150 hv 0 -2 2 2.5 0
0.4 MVA 20/0.4 kV 400 20 0.4 6 1.425 1.35 0.3375 150 hv 0 -2 2 2.5 0
0.63 MVA 10/0.4 kV 630 10 0.4 4 1.0794 1.18 0.1873 150 hv 0 -2 2 2.5 0
0.63 MVA 20/0.4 kV 630 20 0.4 6 1.206 1.65 0.2619 150 hv 0 -2 2 2.5 0
100 MVA 220/110 kV 100000.0 220.0 110.0 12.0 0.26 55 0.06 0 hv 0 -9 9 1.5 0
160 MVA 380/110 kV 160000.0 380.0 110.0 12.2 0.25 60 0.06 0 hv 0 -9 9 1.5 0
25 MVA 110/10 kV 25000 110 10 10.04 0.276 28.51 0.073 150 hv 0 -9 9 1.5 0
25 MVA 110/20 kV 25000 110.0 20.0 11.2 0.282 29 0.071 150 hv 0 -9 9 1.5 0
40 MVA 110/10 kV 40000 110 10 10.04 0.295 30.45 0.076 150 hv 0 -9 9 1.5 0
40 MVA 110/20 kV 40000 110.0 20.0 11.2 0.302 31 0.08 150 hv 0 -9 9 1.5 0
63 MVA 110/10 kV 63000 110 10 10.04 0.31 31.51 0.078 150 hv 0 -9 9 1.5 0
63 MVA 110/20 kV 63000 110.0 20.0 11.2 0.322 33 0.086 150 hv 0 -9 9 1.5 0

Three Winding Transformers

  sn_hv_kva sn_mv_kva sn_lv_kva vn_hv_kv vn_mv_kv vn_lv_kv vsc_hv_percent vsc_mv_percent vsc_lv_percent vscr_hv_percent vscr_mv_percent vscr_lv_percent pfe_kw i0_percent shift_mv_degree shift_lv_degree tp_side tp_mid tp_min tp_max tp_st_percent
63/25/38 MVA 110/10/10 kV 63000 25000 38000 110 10 10 10.4 10.4 10.4 0.28 0.32 0.35 35 0.89 0 0 hv 0 -10 10 1.2
63/25/38 MVA 110/20/10 kV 63000 25000 38000 110 20 10 10.4 10.4 10.4 0.28 0.32 0.35 35 0.89 0 0 hv 0 -10 10 1.2

Manage Standard Types

Show all Available Standard Types

Create Standard Type

Copy Standard Types

Load Standard Types

Check if Standard Type Exists

Change Standard Type

Load Additional Parameter from Library

Find Standard Type

Delete Standard Type

Power Flow

The power flow is the most import static network calculation operation. This section shows you how to run different power flows (AC/DC), what known problems and caveats there are and how you can identify problems using the pandapower diagnostic function.

Run a Power Flow

pandapower provides an AC and linearized (DC) powerflow.

Power Flow

pandapower uses PYPOWER to solve the power flow problem:

alternate Text

Note

If you are interested in the pypower casefile that pandapower is using for power flow, you can find it in net[“_ppc”]. However all necessary informations are written into the pandpower format net, so the pandapower user should not usually have to deal with pypower.

DC Power flow

Warning

To run an AC power flow with DC power flow initialization, use the AC power flow with init=”dc”.

pandapower uses PYPOWER to solve the DC power flow problem:

alternate Text

Note

If you are interested in the pypower casefile that pandapower is using for power flow, you can find it in net[“_ppc”]. However all necessary informations are written into the pandpower format net, so the pandapower user should not usually have to deal with pypower.

Known Problems and Caveats

Zero Impedance Branches

Branches with zero impedance will lead to a non-converging power flow:

alternate Text

This is due to the fact that the power flow is based on admittances, which would be infinite for an impedance of zero. The same problem might occur with impedances very close to zero.

Zero impedance branches occur for:

  • lines with length_km = 0
  • lines with r_ohm_per_km = 0 and x_ohm_per_km = 0
  • transformers with vsc_percent=0

If you want to directly connect to buses without voltage drop, use a bus-bus switch.

Diagnostic Function

A power flow calculation on a pandapower network can fail to converge for a vast variety of reasons, which often makes debugging difficult, annoying and time consuming. To help with that, the diagnostic function automatically checks pandapower networks for the most common issues leading to errors. It provides logging output and diagnoses with a controllable level of detail.

Usage ist very simple: Just call the function and pass the net you want to diagnose as an argument. Optionally you can specify if you want detailed logging output or summaries only and if the diagnostic should log all checks performed vs. errors only.

Check functions

The diagnostic function includes the following checks:

  • invalid values (e.g. negative element indeces)
  • check, if at least one external grid exists
  • check, if there are buses with more than one gen and/or ext_grid
  • overload: tries to run a power flow calculation with loads scaled down to 10%
  • switch_configuration: tries to run a power flow calculation with all switches closed
  • inconsistent voltages: checks, if there are lines or switches that connect different voltage levels
  • lines with impedance zero
  • closed switches between in_service and out_of_service buses
  • components whose nominal voltages differ from the nominal voltages of the buses they’re connected to
  • elements, that are disconnected from the network
  • usage of wrong reference system for power values of loads and gens

Logging Output

Here are a few examples of what logging output looks like:

detailed_report = True/False

Both reports show the same result, but on the left hand picture with detailed information, on the right hand picture summary only.

alternate Text

warnings_only = True/False

alternate Text

Result Dictionary

Aditionally all check results are returned in a dict to allow simple access to the indeces of all element where errors were found.

alternate Text

Optimal Power Flow

The power flow is the most import static network calculation operation. This section shows you how to run different power flows (AC, DC, OPF), what known problems and caveats there are and how you can identify problems using the pandapower diagnostic function.

Optimisation problem

The equation describes the basic formulation of the optimal power flow problem. The pandapower optimal power flow can be constrained by either, AC and DC loadflow equations. The branch constraints represent the maximum apparent power loading of transformers and the maximum line current loadings. The bus constraints can contain maximum and minimum voltage magnitude and angle. For the external grid, generators, loads, DC lines and static generators, the maximum and minimum active resp. reactive power can be considered as operational constraints for the optimal power flow. The constraints are defined element wise in the respective element tables.

\[\begin{split}& min & \sum_{i \ \epsilon \ gen, sgen, load, extgrid }{f_{i}(P_i)} \\ & subject \ to \\ & & Loadflow \ equations \\ & & branch \ constraints \\ & & bus \ constraints \\ & & operational \ power \ constraints \\\end{split}\]

Generator Flexibilities / Operational power constraints

The active and reactive power generation of generators, loads, dc lines and static generators can be defined as a flexibility for the OPF.

Constraint Defined in
\(P_{min,i} \leq P_{g} \leq P_{max,g}, g \ \epsilon \ gen\) net.gen.min_p_kw / net.gen.max_p_kw
\(Q_{min,g} \leq Q_{g} \leq Q_{max,g}, g \ \epsilon \ gen\) net.gen.min_q_kvar / net.gen.max_q_kvar
\(P_{min,sg} \leq P_{sg} \leq P_{max,sg}, sg \ \epsilon \ sgen\) net.sgen.min_p_kw / net.sgen.max_p_kw
\(Q_{min,sg} \leq Q_{sg} \leq Q_{max,sg}, sg \ \epsilon \ sgen\) net.sgen.min_q_kvar / net.sgen.max_q_kvar
\(P_{max,g}, g \ \epsilon \ dcline\) net.dcline.max_p_kw
\(Q_{min,g} \leq Q_{g} \leq Q_{max,g}, g \ \epsilon \ dcline\) net.dcline.min_q_from_kvar / net.dcline.max_q_from_kvar / net.dcline.min_q_to_kvar / net.dcline.max_q_to_kvar
\(P_{min,eg} \leq P_{eg} \leq P_{max,eg}, eg \ \epsilon \ ext_grid\) net.ext_grid.min_p_kw / net.ext_grid.max_p_kw
\(Q_{min,eg} \leq Q_{eg} \leq Q_{max,eg}, eg \ \epsilon \ ext_grid\) net.ext_grid.min_q_kvar / net.ext_grid.max_q_kvar
\(P_{min,ld} \leq P_{ld} \leq P_{max,ld}, ld \ \epsilon \ load\) net.sgen.min_p_kw / net.sgen.max_p_kw
\(Q_{min,ld} \leq Q_{ld} \leq Q_{max,ld}, ld \ \epsilon \ load\) net.sgen.min_q_kvar / net.sgen.max_q_kvar

Note

Defining operational constraints is indispensable for the OPF, it will not start if contraints are not defined.

Network Constraints

The network constraints contain constraints for bus voltages and branch flows:

Constraint Defined in
\(V_{min,j} \leq V_{g,i} \leq V_{min,i}, j \ \epsilon \ bus\) net.bus.min_vm_pu / net.bus.max_vm_pu
\(L_{k} \leq L_{max,k}, k \ \epsilon \ trafo\) net.trafo.max_loading_percent
\(L_{l} \leq L_{max,l}, l \ \epsilon \ line\) net.line.max_loading_percent
\(L_{l} \leq L_{max,l}, l \ \epsilon \ trafo_{3w}\) net.trafo3w.max_loading_percent

The defaults are 100% loading for branch elements and +-0.1 p.u. for bus voltages.

Cost functions

The cost function is specified element wise and is organized in tables as well, which makes the parametrization user friendly. There are two options formulating a cost function for each element: A piecewise linear function with $n$ data points.

\[\begin{split}f_{pwl}(p) = f_{\alpha} +(p-p_{\alpha}) \frac{f_{\alpha + 1}-f_{\alpha}}{p_{\alpha + 1}-p_{\alpha}} \ , \ (p_{\alpha},f_{\alpha}) \ =\begin{cases} (p_{0},f_{0}) \ , \ & p_{0} < p <p_{1}) \\ ...\\ (p_{n-1},f_{n-1}) \ , & \ p_{n-1} < p <p_{n}) \end{cases} \\ \\ f_{pwl}(q) = f_{1} +(q-q_{1}) \frac{f_{2}-f_{1}}{q_{2}-q_{1}}\end{split}\]

Piecewise linear cost functions can be specified using create_piecewise_linear_costs():

The other option is to formulate a n-polynomial cost function:

\[\begin{split}f_{pol}(p) = c_n p^n + ... + c_1 p + c_0 \\ f_{pol}(q) = c_2 q^2 + c_1 q + c_0\end{split}\]

Polynomial cost functions can be speciefied using create_polynomial_cost():

Note

Please note, that polynomial costs for reactive power can only be quadratic, linear or constant. Piecewise linear cost funcions for reactive power are not working at the moment with 2 segments or more. Loads can only have 2 data points in their piecewise linear cost function for active power.

Active and reactive power costs are calculted seperately. The costs of all types are summed up to determine the overall costs for a grid state.

Visualization of cost functions

Minimizing Generation

The most common optimization goal is the minimization of the overall generator feed in. The according cost function would be formulated like this:

pp.create_polynomial_cost(net, 0, 'sgen', np.array([-1, 0]))
pp.create_polynomial_cost(net, 0, 'gen', np.array([-1, 0]))
pp.create_polynomial_cost(net, 0, 'ext_grid', np.array([-1, 0]))
pp.create_piecewise_linear_cost(net, 0, "sgen", np.array([[net.sgen.min_p_kw.at[0], 1000], [0, 0]]))
pp.create_piecewise_linear_cost(net, 0, "gen", np.array([[net.gen.min_p_kw.at[0], 1000], [0, 0]]))
pp.create_piecewise_linear_cost(net, 0, "ext_grid", np.array([[-1e9, 1e9], [1e9, -1e9]]))

It is a straight with a negative slope, so that it has the highest cost value at p_min_kw and is zero when the feed in is zero:

alternate Text

Maximizing generation

This cost function may be used, when the curtailment of renewables should be minimized, which at the same time means that the feed in of those renewables should be maximized. This can be realized by the following cost function definitions:

pp.create_polynomial_cost(net, 0, 'sgen', np.array([1, 0]))
pp.create_polynomial_cost(net, 0, 'gen', np.array([1, 0]))
pp.create_piecewise_linear_cost(net, 0, "sgen", np.array([[net.sgen.min_p_kw.at[0], -1000], [0, 0]]))
pp.create_piecewise_linear_cost(net, 0, "gen", np.array([[net.gen.min_p_kw.at[0], -1000], [0, 0]]))
pp.create_piecewise_linear_cost(net, 0, "ext_grid", np.array([[-1e9, -1e9], [1e9, 1e9]]))

It is a straight with a positive slope, so that the cost is zero at p_min_kw and is at its maximum when the generation equals zero.

alternate Text

Maximize load

In case that the load should be maximized, the cost function could be defined like this:

pp.create_polynomial_cost(net, 0, 'load', np.array([-1, 0]))
pp.create_polynomial_cost(net, 0, 'storage', np.array([-1, 0]))
pp.create_piecewise_linear_cost(net, 0, "sgen", np.array([[0, 0], [net.load.max_p_kw.at[0], -1000]]))
pp.create_piecewise_linear_cost(net, 0, "gen", np.array([[net.storage.min_p_kw.at[0], 1000], [net.storage.max_p_kw.at[0], -1000]]))
alternate Text

Minimizing load

In case that the load should be minimized, the cost function could be defined like this:

pp.create_polynomial_cost(net, 0, 'load', np.array([1, 0]))
pp.create_polynomial_cost(net, 0, 'storage', np.array([1, 0]))
pp.create_piecewise_linear_cost(net, 0, "sgen", np.array([[0, 0], [net.load.max_p_kw.at[0], 1000]]))
pp.create_piecewise_linear_cost(net, 0, "gen", np.array([[net.storage.min_p_kw.at[0], -1000], [net.storage.max_p_kw.at[0], 1000]]))
alternate Text

DC line behaviour

Please note, that the costs of the DC line transmission are always related to the power at the from_bus!

You can always check your Optimization result by comparing your result (From res_sgen, res_load etc.).

Optimization with PowerModels.jl

Installation

  1. If you are not yet using Julia, install it.

    Note

    You need a version that is supported PowerModels, PyCall and pyjulia for the interface to work. Currently, the most recent version of Julia that supports all these packages is Julia 0.64.

    You don’t necessarily need a Julia IDE if you are using PowerModels through pandapower, but it might help for debugging to install an IDE such as Juno.

  2. Install PowerModels.jl

  3. Configure Julia to be able to call Python

    • open the Julia console
    • set ENV[“PYTHON”] to your Python executable (e.g. ENV[“PYTHON”]=”C:\Anaconda\python.exe”)
    • Install PyCall with Pkg.add(“PyCall”)
    • test if calling Python from Julia works as described here

    Note

    PyCall is only tested with Python 3.6 and 3.7, so make sure to use one of those versions

  4. Configure Python to be able to call Julia

    • Add the Julia binary folder (e.g. /Julia-0.6.4/bin) to the system variable PATH
    • Install pyjulia with pip install julia
    • test if everything works by importing PowerModels from Python with: from julia.PowerModels import run_ac_opf. This takes some time, since Python starts a julia instance in the background, but it if the import completes without error everything is configured correctly and you can now use PowerModels to optimize pandapower networks.

Usage

The usage is explained in the PowerModels tutorial.

Short-Circuit

The shortcircuit module is used to calculate short-circuits according to DIN/IEC EN 60909.

Running a Short-Circuit Calculation

The short circuit calculation is carried out with the calc_sc function:

import pandapower.shortcircuit as sc
import pandapower.networks as nw

net = nw.mv_oberrhein()
net.ext_grid["s_sc_min_mva"] = 100
net.ext_grid["rx_min"] = 0.1

net.line["endtemp_degree"] = 20
sc.calc_sc(net, case="min")
print(net.res_bus_sc)

Short-Circuit Currents

The short-circuit currents are calculated with the equivalent voltage source at the fault location. For an explanation of the theory behind short-circuit calculations according to IEC 60909 please refer to the norm or secondary literature:

See also

IEC 60909-0:2016 Short-circuit currents in three-phase a.c. systems

According to the IEC 60909 on openelectrical

pandapower currently implements symmetrical and two-phase faults. One phase faults and two-phase faults with earthing are not yet available.

Initial Short-Circuit Current

The general ohmic network equation is given as:

The SC is calculated in two steps:
  • calculate the SC contribution \(I''_{kI}\) of all voltage source elements
  • calculate the SC contribution \(I''_{kII}\) of all current source elements

These two currents are then combined into the total initial SC current \(I''_{k} = I''_{kI} + I''_{kII}\).

Equivalent Voltage Source

For the short-circuit calculation with the equivalent voltage source, all voltage sources are replaced by one equivalent voltage source \(V_Q\) at the fault location. The voltage magnitude at the fault bus is assumed to be:

\[\begin{split}V_Q = \left\{ \begin{array}{@{}ll@{}} \frac{c \cdot \underline{V}_{N}}{\sqrt{3}} & \text{for three phase short circuit currents} \\ \frac{c \cdot \underline{V}_{N}}{2} & \text{for two phase short circuit currents} \end{array}\right.\end{split}\]

where \(V_N\) is the nominal voltage at the fault bus and c is the voltage correction factor, which accounts for operational deviations from the nominal voltage in the network.

The voltage correction factors \(c_{min}\) for minimum and \(c_{max}\) for maximum short-circuit currents are defined for each bus depending on the voltage level. In the low voltage level, there is an additional distinction between networks with a tolerance of 6% vs. a tolerance of 10% for \(c_{max}\):

Voltage Level \(c_{min}\) \(c_{max}\)
< 1 kV Tolerance 6% 0.95 1.05
Tolerance 10% 1.10
> 1 kV 1.00
Voltage Source Contribution

To calculate the contribution of all voltage source elements, the following assumptions are made:

  1. Operational currents at all buses are neglected
  2. All current source elements are neglected
  3. The voltage at the fault bus is equal to \(V_Q\)

For the calculation of a short-circuit at bus \(j\), this yields the following network equations:

\[\begin{split}\begin{bmatrix} \underline{Y}_{11} & \dots & \dots & \underline{Y}_{n1} \\[0.3em] \vdots & \ddots & & \vdots \\[0.3em] \vdots & & \ddots & \vdots \\[0.3em] \underline{Y}_{1n} & \dots & \dots & \underline{Y}_{nn} \end{bmatrix} \begin{bmatrix} \underline{V}_{1} \\ \vdots \\ V_{Qj} \\ \vdots \\ \underline{V}_{n} \end{bmatrix} = \begin{bmatrix} 0 \\ \vdots \\ \underline{I}''_{kIj} \\ \vdots \\ 0 \end{bmatrix}\end{split}\]

where \(\underline{I}''_{kIj}\) is the voltage source contribution of the short-circuit current at bus \(j\). The voltages at all non-fault buses and the current at the fault bus are unknown. To solve for \(\underline{I}''_{kIj}\) , we multipliy with the inverted nodal point admittance matrix (impedance matrix):

\[\begin{split}\begin{bmatrix} \underline{V}_{1} \\ \vdots \\[0.4em] V_{Qj} \\[0.4em] \vdots \\ \underline{V}_{n} \end{bmatrix} = \begin{bmatrix} \underline{Z}_{11} & \dots & \dots & \dots & \underline{Z}_{n1} \\ \vdots & \ddots & & & \vdots \\ \vdots & & \underline{Z}_{jj} & & \vdots \\ \vdots & & & \ddots & \vdots \\ \underline{Z}_{1n} & \dots & \dots & \dots & \underline{Z}_{nn} \end{bmatrix} \begin{bmatrix} 0 \\ \vdots \\[0.25em] \underline{I}''_{kIj} \\[0.25em] \vdots \\ 0 \end{bmatrix}\end{split}\]

The short-circuit current for bus m is now given as:

\[I''_{kIj} = \frac{V_{Qj}}{Z_{jj}}\]

To calculate the vector of the short-circuit currents at all buses, the equation can be expanded as follows:

\[\begin{split}\begin{bmatrix} \underline{V}_{Q1} & \dots & \underline{V}_{n1} \\[0.4em] \vdots & \ddots & \vdots \\[0.4em] \underline{V}_{1n} & \dots & \underline{V}_{Qn} \end{bmatrix} = \begin{bmatrix} \underline{Z}_{11} & \dots & \underline{Z}_{n1} \\[0.8em] \vdots & \ddots & \vdots \\[0.8em] \underline{Z}_{1n} & \dots & \underline{Z}_{nn} \end{bmatrix} \begin{bmatrix} \underline{I}''_{kI1} & \dots & 0 \\[0.8em] \vdots & \ddots & \vdots \\[0.8em] 0 & \dots & \underline{I}''_{kIn} \end{bmatrix}\end{split}\]

which yields:

\[\begin{split}\begin{bmatrix} I''_{kI1} \\[0.25em] \vdots \\[0.25em] I''_{kIn} \\ \end{bmatrix} = \begin{bmatrix} \frac{V_{Q1}}{Z_{11}} \\ \vdots \\ \frac{V_{Qn}}{Z_{nn}} \end{bmatrix}\end{split}\]

In that way, all short-circuit currents can be calculated at once with one inversion of the nodal point admittance matrix.

In case a fault impedance is specified, it is added to the diagonal of the impedance matrix. The short-circuit currents at all buses are then calculated as:

\[\begin{split}\begin{bmatrix} I''_{kI1} \\[0.25em] \vdots \\[0.25em] I''_{kIn} \\ \end{bmatrix} = \begin{bmatrix} \frac{V_{Q1}}{Z_{11} + Z_{fault}} \\ \vdots \\ \frac{V_{Qn}}{Z_{nn} + Z_{fault}} \end{bmatrix}\end{split}\]
Current Source Contribution

To calculate the current source component of the SC current, all voltage sources are short circuited and only current sources are considered. The bus currents are then given as:

\[\begin{split}\begin{bmatrix} I_1 \\[0.2em] \vdots \\[0.2em] I_m \\[0.2em] \vdots \\ I_n \end{bmatrix} = \begin{bmatrix} 0 \\[0.2em] \vdots \\[0.2em] \underline{I}''_{kIIj} \\[0.2em] \vdots \\ 0 \end{bmatrix} - \begin{bmatrix} I''_{kC1} \\[0.2em] \vdots \\[0.2em] \underline{I}''_{kCj} \\[0.2em] \vdots \\ I''_{kCn} \end{bmatrix} = \begin{bmatrix} -I''_{kC1} \\[0.2em] \vdots \\[0.2em] \underline{I}''_{kIIj} - \underline{I}''_{kCj} \\[0.2em] \vdots \\ -I''_{kCn} \end{bmatrix}\end{split}\]

where \(I''_{kC}\) are the SC currents that are fed in by converter element at each bus and \(\underline{I}''_{kIIj}\) is the contribution of converter elements at the fault bus \(j\). With the voltage at the fault bus known to be zero, the network equations are given as:

\[\begin{split}\begin{bmatrix} \underline{V}_{1} \\ \vdots \\[0.4em] 0 \\[0.4em] \vdots \\ \underline{V}_{n} \end{bmatrix} = \begin{bmatrix} \underline{Z}_{11} & \dots & \dots & \dots & \underline{Z}_{n1} \\ \vdots & \ddots & & & \vdots \\ \vdots & & {Z}_{jj} & & \vdots \\ \vdots & & & \ddots & \vdots \\ \underline{Z}_{1n} & \dots & \dots & \dots & \underline{Z}_{nn} \end{bmatrix} \begin{bmatrix} -I''_{kC1} \\[0.2em] \vdots \\[0.2em] \underline{I}''_{kIIj} - \underline{I}''_{kCj} \\[0.2em] \vdots \\ -I''_{kCn} \end{bmatrix}\end{split}\]

From which row \(j\) of the equation yields:

\[0 = \underline{Z}_{jj} \cdot \underline{I}''_{kIIj} - \sum_{m=1}^{n}{\underline{Z}_{jm} \cdot \underline{I}_{kCj}}\]

which can be converted into:

\[\underline{I}''_{kIIj} = \frac{1}{\underline{Z}_{jj}} \cdot \sum_{m=1}^{n}{\underline{Z}_{jm} \cdot \underline{I}_{kC, m}}\]

To calculate all SC currents for faults at each bus simultaneously, this can be generalized into the following matrix equation:

\[\begin{split}\begin{bmatrix} \underline{I}''_{kII1} \\[0.5em] \vdots \\[0.5em] \vdots \\[0.5em] \underline{I}''_{kIIn} \end{bmatrix} = \begin{bmatrix} \underline{Z}_{11} & \dots & \dots & \underline{Z}_{n1} \\[0.3em] \vdots & \ddots & & \vdots \\[0.3em] \vdots & & \ddots & \vdots \\[0.3em] \underline{Z}_{1n} & \dots & \dots & \underline{Z}_{nn} \end{bmatrix} \begin{bmatrix} \frac{I''_{kC1}}{\underline{Z}_{11}} \\[0.25em] \vdots \\ \vdots \\[0.25em] \frac{I''_{kCn}}{\underline{Z}_{nn}} \end{bmatrix}\end{split}\]

Peak Short-Circuit Current

Current Calculation

The peak short-circuit current is calculated as:

\[\begin{split}\begin{bmatrix} i_{p, 1} \\ \vdots \\ i_{p, n} \\ \end{bmatrix} = \sqrt{2} \left( \begin{bmatrix} \kappa_{1} \\ \vdots \\ \kappa_{1} \\ \end{bmatrix} \begin{bmatrix} \underline{I}''_{kI, 1} \\ \vdots \\ \underline{I}''_{kI, n} \\ \end{bmatrix} + \begin{bmatrix} \underline{I}''_{kII, 1} \\ \vdots \\ \underline{I}''_{kII, n} \\ \end{bmatrix} \right)\end{split}\]

where \(\kappa\) is the peak factor.

Peak Factor \(\kappa\)

In radial networks, \(\kappa\) is given as:

\[\kappa = 1.02 + 0.98 e^{-{3}{R/X}}\]

where \(R/X\) is the R/X ratio of the equivalent short-circuit impedance \(Z_k\) at the fault location.

In meshed networks, the standard defines three possibilities for the calculation of \(\kappa\):

  • Method A: Uniform Ratio R/X
  • Method B: R/X ratio at short-circuit location
  • Method C: Equivalent frequency

The user can chose between Methods B and C when running a short circuit calculation. Method C yields the most accurate results according to the standard and is therefore the default option. Method A is only suited for estimated manual calculations with low accuracy and therefore not implemented in pandapower.

Method C: Equivalent frequency

For method C, the same formula for \(\kappa\) is used as for radial grids. The R/X value that is inserter is however not the

Method B: R/X Ratio at short-circuit location

For method B, \(\kappa\) is given as:

\[\kappa = [1.02 + 0.98 e^{-{3}{R/X}}] \cdot 1.15\]

while being limited with \(\kappa_{min} < \kappa < \kappa_{max}\) depending on the voltage level:

Voltage Level \(\kappa_{min}\) \(\kappa_{max}\)
< 1 kV 1.0 1.8
> 1 kV 2.0

Thermal Short-Circuit Current

Current Calculation

The equivalent thermal current is calculated as:

\[\begin{split}\begin{bmatrix} \underline{I}_{th, 1} \\ \vdots \\ \underline{I}_{th, n} \\ \end{bmatrix} = \begin{bmatrix} \sqrt{m_1 + n_1} \\ \vdots \\ \sqrt{m_n + n_n} \\ \end{bmatrix} \begin{bmatrix} \underline{I}''_{k, 1} \\ \vdots \\ \underline{I}''_{k, n} \\ \end{bmatrix}\end{split}\]

where m and n represent the dc and ac part of the thermal load.

Correction Factors m and n

For short-circuit currents far from synchronous generators, the factors are given as:

\[n = 1 m = \frac{1}{2 \cdot f \cdot T_k \cdot ln(\kappa - 1)} [e^{4 \cdot f \cdot T_k \cdot ln(\kappa - 1)} - 1]\]

where \(\kappa\) is the peak factor defined here and \(T_k\) is the duration of the short-circuit current that can be defined as a parameter when running the short-circuit calculation.

Network Elements

Correction factors for generator and branch elements are implemented as defined in the IEC 60909 standard. The results for all elements are tested against commercial software to ensure that correction factors are correctly applied.

Voltage Source Elements

Voltage source elements are represented by their internal voltage source with an internal resistance \(Z_k\):

_images/bus_voltage.png

since the voltage source is moved to the fault location for with methodology of the equivalent voltage source, the bus elements can be reduced to a single shunt impedance:

_images/bus_equivalent.png

The contribution of loads and shunts are negligible according to the standard and therefore neglected in the short-circuit calculation.

External Grid

When calculating maximum short-circuit currents, the impedance of an external grid connection is given as:

\[\begin{split}z_{k, eg} =& \frac{c_{max}}{s\_sc\_max\_mva} \\[1em] x_{k, eg} =& \frac{z_{sg}}{\sqrt{1 + rx\_max^2}} \\[1em] r_{k, eg} =& rx\_max \cdot x_{sg}\end{split}\]

where \(rx\_max\) and \(s\_sc\_max\_mva\) are parameters in the ext_grid table and \(c_{max}\) is the voltage correction factor of the external grid bus.

In case of minimal short-circuit currents, the impedance is calculated accordingly:

\[\begin{split}z_{k, eg} =& \frac{c_{min}}{s\_sc\_min\_mva} \\[1em] x_{k, eg} =& \frac{z_{sg}}{\sqrt{1 + rx\_min^2}} \\[1em] r_{k, eg} =& rx\_min \cdot x_{sg}\end{split}\]
Asynchronous Motor

Asynchronous motors can be considered by setting the type variable of an sgen element to “motor”. The internal impedance is then calculated as:

\[\begin{split}Z_{k, m} = \frac{1}{k} \cdot \frac{vn\_kv^2 \cdot 1000}{sn\_kva} \\ X_{k, m} = \frac{Z_{sg}}{\sqrt{1 + rx^2}} \\ R_{k, m} = rx \cdot X_{sg}\end{split}\]

where \(sn\_kva\) is the rated power of the motor, \(k\) is the ratio of nominal to short circuit current and \(rx\) is the R/X ratio of the motor. \(vn\_kv\) is the rated voltage of the bus the motor is connected to.

Synchronous Generator

Synchronous generators are considered with the short-circuit impedance of:

\[\underline{Z}_{k, gen} = K_G \cdot (R''_d + jX''_d)\]

The short-circuit impedance is calculated as:

\[z_k = xdss\]

The generator correction factor \(K_G\) is given as:

\[K_G = \frac{V_{N, gen}}{V_{N, bus}} \cdot \frac{c_{max}}{1 + x_{dss} \cdot sin(\varphi)}\]

where \(V_{N, bus}\) is the rated voltage of the bus the generator is connected to and \(V_{N, gen}\) is the rated voltage of the generator which is defined by the parameter \(\text{sn\_kva}\) in the gen table. The rated phasor angle \(\varphi\) is given as:

\[\varphi = arcos(cos\_phi)\]

where \(cos\_phi\) is defined in the gen table.

Current Source Elements

Full converter elements, such as PV plants or wind parks, are modeled as current sources:

_images/bus_current.png

All static generator elements are assumed to be full converter elements except if the type is specified as “motor”, in which case they are treated as asynchronous machines.

The inductive short circuit current is calculated from the parameters given in the sgen table as:

\[\underline{I}_k = -j \cdot \frac{k \cdot s\_n\_kva}{\sqrt{3} \cdot vn\_kv}\]

where \(s\_n\_kva\) is the rated power of the generator and \(k\) is the ratio of nominal to short circuit current. \(vn\_kv\) is the rated voltage of the bus the generator is connected to.

Branch Elements

Branches are represented by a single short circuit impedance:

_images/branch2.png

Shunt admittances are neglected for all branch elements.

Line
\begin{align*} \underline{R}_k &= r\_ohm\_per\_km \cdot \frac{length\_km}{parallel} \cdot K_L\\ \underline{X}_k &= x\_ohm\_per\_km \cdot \frac{length\_km}{parallel} \end{align*}

where the correction factor for the short-circuit resistance \(K_L\) is defined as:

\[\begin{split}K_L=\left\{ \begin{array}{@{}ll@{}} 1 & \text{ for maximum short-circuit calculations} \\ 1 + 0.04 K^{-1} (endtemp\_degree - 20°C) & \text{ for minimum short-circuit calculations} \end{array}\right.\end{split}\]

The end temperature in degree after a fault has to be defined with the parameter endtemp_degre in the line table.

Two-Winding Transformer

The short-circuit impedance is calculated as:

\begin{align*} z_k &= \frac{vsc\_percent}{100} \cdot \frac{1000}{sn\_kva} \cdot K_T \\ r_k &= \frac{vscr\_percent}{100} \cdot \frac{1000}{sn\_kva} \cdot K_T \\ x_k &= \sqrt{z^2 - r^2} \\ \end{align*}

where the correction factor \(K_T\) is defined in the standard as:

\[K_{T} = 0.95 \frac{c_{max}}{1 + 0.6 x_T}\]

where \(c_{max}\) is the voltage correction factor on the low voltage side of the transformer and \(x_T\) is the transformer impedance relative to the rated values of the transformer.

The ratio of the transformer is considered to be the nominal ratio, the tap changer positions are not considered according to the standard.

Three-Winding Transformer

Three Winding Transformers are modelled by three two-winding transformers:

alternate Text

The conversion from one two to three two winding transformer parameter is described here.

For the short-circuit calculation, the loss parameters are neglected and the transformer correction factor is applied for the equivalent two-winding transformers as follows:

\begin{align*} v'_{k, t1} &= \frac{1}{2} (v'_{k, h} \cdot K_{T, h} + v'_{k, l} \cdot K_{T, l} - v'_{k, m} \cdot K_{T, m}) \\ v'_{k, t2} &= \frac{1}{2} (v'_{k, m} \cdot K_{T, m} + v'_{k, h} \cdot K_{T, h} - v'_{k, l} \cdot K_{T, l}) \\ v'_{k, t3} &= \frac{1}{2} (v'_{k, m} \cdot K_{T, m} + v'_{k, l} \cdot K_{T, l} - v'_{k, h} \cdot K_{T, h}) \end{align*}

Note that the correction factor has to be applied to the transformers before the wye-delta and not on the resulting two-winding transformers.

Impedance

The impedance element is a generic element that is not desribed in the standard. It is considered in the short-circuit calculation just as in the power flow as described here.

State Estimation

The module provides a state estimation for pandapower networks.

Theoretical Background

State Estimation is a process to estimate the electrical state of a network by eliminating inaccuracies and errors from measurement data. Various measurements are placed around the network and transferred to the operational control center via SCADA. Unfortunately measurements are not perfect: There are tolerances for each measurement device, which lead to an inherent inaccuracy in the measurement value. Analog transmission of data can change the measurement values through noise. Faulty devices can return completely wrong measurement values. To account for the measurement errors, the state estimation processes all available measurements and uses a regression method to identify the likely real state of the electrical network. The output of the state estimator is therefore a set of voltage absolutes and voltage angles for all buses in the grid. The input is the network in pandapower format and a number of measurements.

Amount of Measurements

There is a minimum amount of required measurements necessary for the regression to be mathematically possible. Assuming the network contains \(n\) buses, the network is then described by \(2n\) variables, namely \(n\) voltage absolute values and \(n\) voltage angles. A slack bus serves as the reference, its voltage angle is set to zero or the value provided in the corresponding net.ext_grid.va_degree entry (see init parameter) and is not altered in the estimation process. The voltage angles of the other network buses are relative to the voltage angles of the connected slack bus. The state estimation therefore has to find \(2n-k\) variables, where \(k\) is the number of defined slack buses. The minimum amount of measurements \(m_{min}\) needed for the method to work is therefore:

\(m_{min} = 2n-k\)

To perform well however, the number of redundant measurements should be higher. A value of \(m \approx 4n\) is often considered reasonable for practical purposes.

Standard Deviation

Since each measurement device may have a different tolerance and a different path length it has to travel to the control center, the accuracy of each measurement can be different. Therefore each measurement is assigned an accuracy value in the form of a standard deviation. Typical measurement errors are 1 % for voltage measurements and 1-3 % for power measurements.

For a more in-depth explanation of the internals of the state estimation method, please see the following sources:

See also

  • Power System State Estimation: Theory and Implementation by Ali Abur, Antonio Gómez Expósito, CRC Press, 2004.
  • State Estimation in Electric Power Systems - A Generalized Approach by A. Monticelli, Springer, 1999.

Defining Measurements

Measurements are defined via the pandapower “create_measurement” function. There are different physical properties, which can be measured at different elements. The following lists and table clarify the possible combinations. Bus power injection measurements are given in the producer system. Generated power is positive, consumed power is negative. Measurements for three winding transformers (trafo3w) can not yet be added. Please use a workaround of an artificial line or the like.

Types of Measurements

  • “v” for voltage measurements (in per-unit)
  • “p” for active power measurements (in kW)
  • “q” for reactive power measurements (in kVar)
  • “i” for electrical current measurements at a line (in A)

Element Types

  • “bus” for bus measurements
  • “line” for line measurements
  • “trafo” for transformer measurements

Available Measurements per Element

Element Type Available Measurement Types
bus v, p, q
line i, p, q
trafo i, p, q

The “create_measurement” function is defined as follows:

Running the State Estimation

The state estimation can be used with the wrapper function “estimate”, which prevents the need to deal with the state_estimation class object and functions. It can be imported from “estimation.state_estimation”.

Handling of bad data

Note

The bad data removal is not very robust at this time. Please treat the results with caution!

The state estimation class allows additionally the removal of bad data, especially single or non-interacting false measurements. For detecting bad data the Chi-squared distribution is used to identify the presence of them. Afterwards follows the largest normalized residual test that identifys the actual measurements which will be removed at the end. Both methods are combined in the perform_rn_max_test function that is part of the state estimation class. To access it, the following wrapper function remove_bad_data has been created.

Nevertheless the Chi-squared test is available as well to allow a identification of topology errors or, as explained, false measurements. It is named as chi2_analysis. The detection’s result of present bad data of the Chi-squared test is stored internally as bad_data_present (boolean, class member variable) and returned by the function call.

Background information about this topic can be sourced from the following literature:

See also

  • Power System State Estimation: Theory and Implementation by Ali Abur, Antonio Gómez Expósito, CRC Press, 2004.
  • Power Generation, Operation, and Control by Allen J. Wood, Bruce Wollenberg, Wiley Interscience Publication, 1996.

Example

As an example, we will define measurements for a simple pandapower network net with 4 buses. Bus 4 is out-of-service. The external grid is connected at bus 1.

There are multiple measurements available, which have to be defined for the state estimator. There are two voltage measurements at buses 1 and 2. There are two power measurements (active and reactive power) at bus 2. There are also line power measurements at bus 1. The measurements are both for active and reactive power and are located on the line from bus 1 to bus 2 and from bus 1 to bus 3. This yields the following code:

pp.create_measurement(net, "v", "bus", 1.006, .004, bus1)      # V at bus 1
pp.create_measurement(net, "v", "bus", 0.968, .004, bus2)      # V at bus 2

pp.create_measurement(net, "p", "bus", -501, 10, bus2)         # P at bus 2
pp.create_measurement(net, "q", "bus", -286, 10, bus2)         # Q at bus 2

pp.create_measurement(net, "p", "line", 888, 8, bus=bus1, element=line1)    # Pline (bus 1 -> bus 2) at bus 1
pp.create_measurement(net, "p", "line", 1173, 8, bus=bus1, element=line2)   # Pline (bus 1 -> bus 3) at bus 1
pp.create_measurement(net, "q", "line", 568, 8, bus=bus1, element=line1)    # Qline (bus 1 -> bus 2) at bus 1
pp.create_measurement(net, "q", "line", 663, 8, bus=bus1, element=line2)    # Qline (bus 1 -> bus 3) at bus 1

Now that the data is ready, the state_estimation can be initialized and run. We want to use the flat start condition, in which all voltages are set to 1.0 p.u..

success = estimate(net, init="flat")
V, delta = net.res_bus_est.vm_pu, net.res_bus_est.va_degree

The resulting variables now contain the voltage absolute values in V, the voltage angles in delta, an indication of success in success. The bus power injections can be accessed similarly with net.res_bus_est.p_kw and net.res_bus_est.q_kvar. Line data is also available in the same format as defined in res_line.

If we like to check our data for fault measurements, and exclude them in in our state estimation, we use the following code:

success_rn_max = remove_bad_data(net, init="flat")
V_rn_max, delta_rn_max = net.res_bus_est.vm_pu, net.res_bus_est.va_degree

In the case that we only like to know if there is a likelihood of fault measurements (probabilty of fault can be adjusted), the Chi-squared test should be performed separatly. If the test detects the possibility of fault data, the value of the added class member variable bad_data_present would be true as well as the boolean variable success_chi2 that is used here:

success_chi2 = chi2_analysis(net, init="flat")

Topological Searches

pandapower provides the possibility of graph searches using the networkx package, which is “a Python language software package for the creation, manipulation, and study of the structure, dynamics, and function of complex networks.” (see NetworkX documentation http:/networkx.github.io/documentation/networkx-1.10/index.html )

pandapower provides a function to translate pandapower networks into networkx graphs. Once the electric network is translated into an abstract networkx graph, all network operations that are available in networkx can be used to analyse the network. For example you can find the shortest path between two nodes, find out if two areas in a network are connected to each other or if there are cycles in a network. For a complete list of all NetworkX algorithms see http:/networkx.github.io/documentation/networkx-1.10/reference/algorithms.html

pandapower also provides some search algorithms specialiced for electric networks, such as finding all buses that are connected to a slack node.

Create networkx graph

The basis of all topology functions is the conversion of a padapower network into a NetworkX MultiGraph. A MultiGraph is a simplified representation of a network’s topology, reduced to nodes and edges. Busses are being represented by nodes (Note: only buses with in_service = 1 appear in the graph), edges represent physical connections between buses (typically lines or trafos). Multiple parallel edges between nodes are possible.

This is a very simple example of a pandapower network being converted to a MultiGraph. (Note: The MultiGraph’s shape is completely arbitrary since MultiGraphs have no inherent shape unless geodata is provided.)

alternate Text

Nodes have the same indicees as the buses they originate from. Edges are defined by the nodes they connect. Additionally nodes and edges can hold key/value attribute pairs.

The following attributes get transferred into the MultiGraph:

lines trafos
  • from_bus
  • to_bus
  • length_km
  • index
  • in_service
  • max_i_ka
  • hv_bus
  • lv_bus
  • index
  • in_service

Apart from these there are no element attributes contained in the MultiGraph!

Creating a multigraph from a pandapower network

The function create_nxgraph function from the pandapower.topology package allows you to convert a pandapower network into a MultiGraph:

Examples

create_nxgraph(net, respect_switches = False)
alternate Text
create_nxgraph(net, include_lines = False, include_impedances = False)
alternate Text
create_nxgraph(net, include_trafos = False)
alternate Text
create_nxgraph(net, nogobuses = [4])
alternate Text
create_nxgraph(net, notravbuses = [4])
alternate Text

Topological Searches

Once you converted your network into a MultiGraph there are several functions to perform topological searches and analyses at your disposal. You can either use the general-purpose functions that come with NetworkX (see http:/networkx.github.io/documentation/networkx-1.10/reference/algorithms.html) or topology’s own ones which are specialized on electrical networks.

calc_distance_to_bus

connected_component

connected_components

unsupplied_buses

determine_stubs

Examples

The combination of a suitable MultiGraph and the availabe topology functions enables you to perform a wide range of topological searches and analyses.

Here are a few examples of what you can do:

basic example network

import pandapower as pp

net = pp.create_empty_network()

pp.create_bus(net, name = "110 kV bar", vn_kv = 110, type = 'b')
pp.create_bus(net, name = "20 kV bar", vn_kv = 20, type = 'b')
pp.create_bus(net, name = "bus 2", vn_kv = 20, type = 'b')
pp.create_bus(net, name = "bus 3", vn_kv = 20, type = 'b')
pp.create_bus(net, name = "bus 4", vn_kv = 20, type = 'b')
pp.create_bus(net, name = "bus 5", vn_kv = 20, type = 'b')
pp.create_bus(net, name = "bus 6", vn_kv = 20, type = 'b')

pp.create_ext_grid(net, 0, vm_pu = 1)

pp.create_line(net, name = "line 0", from_bus = 1, to_bus = 2, length_km = 1, std_type = "NAYY 150")
pp.create_line(net, name = "line 1", from_bus = 2, to_bus = 3, length_km = 1, std_type = "NAYY 150")
pp.create_line(net, name = "line 2", from_bus = 3, to_bus = 4, length_km = 1, std_type = "NAYY 150")
pp.create_line(net, name = "line 3", from_bus = 4, to_bus = 5, length_km = 1, std_type = "NAYY 150")
pp.create_line(net, name = "line 4", from_bus = 5, to_bus = 6, length_km = 1, std_type = "NAYY 150")
pp.create_line(net, name = "line 5", from_bus = 6, to_bus = 1, length_km = 1, std_type = "NAYY 150")

pp.create_transformer_from_parameters(net, hv_bus = 0, lv_bus = 1, i0_percent= 0.038, pfe_kw = 11.6,
        vscr_percent = 0.322, sn_kva = 40000.0, vn_lv_kv = 22.0,
        vn_hv_kv = 110.0, vsc_percent = 17.8)

pp.create_load(net, 2, p_kw = 1000, q_kvar = 200, name = "load 0")
pp.create_load(net, 3, p_kw = 1000, q_kvar = 200, name = "load 1")
pp.create_load(net, 4, p_kw = 1000, q_kvar = 200, name = "load 2")
pp.create_load(net, 5, p_kw = 1000, q_kvar = 200, name = "load 3")
pp.create_load(net, 6, p_kw = 1000, q_kvar = 200, name = "load 4")

pp.create_switch(net, bus = 1, element = 0, et = 'l')
pp.create_switch(net, bus = 2, element = 0, et = 'l')
pp.create_switch(net, bus = 2, element = 1, et = 'l')
pp.create_switch(net, bus = 3, element = 1, et = 'l')
pp.create_switch(net, bus = 3, element = 2, et = 'l')
pp.create_switch(net, bus = 4, element = 2, et = 'l')
pp.create_switch(net, bus = 4, element = 3, et = 'l', closed = 0)
pp.create_switch(net, bus = 5, element = 3, et = 'l')
pp.create_switch(net, bus = 5, element = 4, et = 'l')
pp.create_switch(net, bus = 6, element = 4, et = 'l')
pp.create_switch(net, bus = 6, element = 5, et = 'l')
pp.create_switch(net, bus = 1, element = 5, et = 'l')

Using NetworkX algorithms: shortest path

For many basic network analyses the algorithms that come with the NetworkX package will work just fine and you won’t need one of the spezialised topology functions. Finding the shortest path between two buses is a good example for that.

import pandapower.topology as top
import networkx as nx

mg = top.create_nxgraph(net)
nx.shortest_path(mg, 0, 5)
Out: [0, 1, 6, 5]
alternate Text

Find disconnected buses

With unsupplied_buses you can easily find buses that are not connected to an external grid.

import pandapower.topology as top

net.switch.closed.at[11] = 0
top.unsupplied_buses(net)
Out: {5, 6}
alternate Text

Calculate distances between buses

calc_distance_to_bus allows you to calculate the distance ( = shortest network route) from one bus all other ones. This is possible since line lengths are being transferred into the MultiGraph as an edge attribute. (Note: bus-bus-switches and trafos are interpreted as edges with length = 0)

import pandapower.topology as top

net.switch.closed.at[6] = 1
net.switch.closed.at[8] = 0
top.calc_distance_to_bus(net, 1)
Out:
0    0
1    0
2    1
3    2
4    3
5    4
6    1

Interpretation: The distance between bus 1 and itself is 0 km. Bus 1 is also 0 km away from bus 0, since they are connected with a transformer. The shortest path between bus 1 and bus 5 is 4 km long.

alternate Text

Find connected buses with the same voltage level

import pandapower.topology as top

mg_no_trafos = top.create_nxgraph(net, include_trafos = False)
cc = top.connected_components(mg_no_trafos)
In      : next(cc)
Out     : {0}
In      : next(cc)
Out     : {1, 2, 3, 4, 5, 6}
alternate Text

Find rings and ring sections

Another example of what you can do with the right combination of input arguments when creating the MultiGraph is finding rings and ring sections in your network. To achieve that for our example network, the trafo buses needs to be set as a nogobuses. With respect_switches = True you get the ring sections, with respect_switches = False the whole ring.

import pandapower.topology as top

mg_ring_sections = top.create_nxgraph(net, nogobuses = [0, 1])
cc_ring_sections = top.connected_components(mg_ring_sections)
In      : next(cc_ring_sections)
Out     : {2, 3, 4}

In      : next(cc_ring_sections)
Out     : {5, 6}
alternate Text
import pandapower.topology as top

mg_ring = top.create_nxgraph(net, respect_switches = False, nogobuses = [0,1])
cc_ring = top.connected_components(mg_ring)
In      : next(cc_ring)
Out     : {2, 3, 4, 5, 6}
alternate Text

Find stubs

determine_stubs lets you identify buses and lines that are stubs. Open switches are being ignored. Busses that you want to exclude should be defined as roots. Ext_grid buses are roots by default.

This is a small extension for the example network:

pp.create_bus(net, name = "bus 7", vn_kv = 20, type = 'b')
pp.create_bus(net, name = "bus 8", vn_kv = 20, type = 'b')

pp.create_line(net, name = "line 6", from_bus = 6, to_bus = 7, length_km = 1, std_type = "NAYY 150")
pp.create_line(net, name = "line 7", from_bus = 7, to_bus = 8, length_km = 1, std_type = "NAYY 150")

pp.create_load(net, 7, p_kw = 1000, q_kvar = 200, name = "load 5")
pp.create_load(net, 8, p_kw = 1000, q_kvar = 200, name = "load 6")
import pandapower.topology as top
top.determine_stubs(net, roots = [0,1])
In: net.bus

Out:
         name  vn_kv  min_vm_pu  max_vm_pu type  zone in_service auf_stich
0  110 kV bar    110      NaN      NaN    b  None       True     False
1   20 kV bar     20      NaN      NaN    b  None       True     False
2       bus 2     20      NaN      NaN    b  None       True     False
3       bus 3     20      NaN      NaN    b  None       True     False
4       bus 4     20      NaN      NaN    b  None       True     False
5       bus 5     20      NaN      NaN    b  None       True     False
6       bus 6     20      NaN      NaN    b  None       True     False
7       bus 7     20      NaN      NaN    b  None       True      True
8       bus 8     20      NaN      NaN    b  None       True      True

In: net.line

Out:
     name  std_type  from_bus  to_bus  length_km  r_ohm_per_km  x_ohm_per_km  c_nf_per_km  max_i_ka  df type in_service is_stich
0  line 0  NAYY 150         1       2          1         0.206         0.091            0    0.284   1   cs       True    False
1  line 1  NAYY 150         2       3          1         0.206         0.091            0    0.284   1   cs       True    False
2  line 2  NAYY 150         3       4          1         0.206         0.091            0    0.284   1   cs       True    False
3  line 3  NAYY 150         4       5          1         0.206         0.091            0    0.284   1   cs       True    False
4  line 4  NAYY 150         5       6          1         0.206         0.091            0    0.284   1   cs       True    False
5  line 5  NAYY 150         6       1          1         0.206         0.091            0    0.284   1   cs       True    False
6  line 6  NAYY 150         6       7          1         0.206         0.091            0    0.284   1   cs       True     True
7  line 7  NAYY 150         7       8          1         0.206         0.091            0    0.284   1   cs       True     True
alternate Text

Networks

Besides creating your own grids through the pandapower API, pandapower provides synthetic and Benchmark networks through the networks module.

The pandapower networks modul contains example networks, simple test networks, randomly generated networks, CIGRE test networks, IEEE case files and synthetic low voltage networks from Georg Kerber and Lindner et. al. and Dickert et. al..

You can find documentation for the individual modules here:

Example Networks

There are two example networks available. The simple example network shows the basic principles of how to create a pandapower network. If you like to study a more advanced and thus more complex network, please take a look at the more multi-voltage level example network.

Simple Example Network

The following example contains all basic elements that are supported by the pandapower format. It is a simple example to show the basic principles of creating a pandapower network.

alternate Text

The stepwise creation of this network is shown in the pandapower tutorials.

Multi-Voltage Level Example Network

The following example contains all elements that are supported by the pandapower format. It is a more realistic network than the simple example and of course more complex. Using typically voltage levels for european distribution networks (high, medium and low voltage) the example relates characteristic topologies, utility types, line lengths and generator type distribution to the various voltage levels. To set network size limits the quantity of nodes in every voltage level is restricted and one medium voltage open ring and only two low voltage feeder are considered. Other feeders are represented by equivalent loads. As an example one double busbar and one single busbar are considered.

alternate Text

The stepwise creation of this network is shown in the pandapower tutorials.

Simple pandapower Test Networks

Four load branch

alternate Text

Four loads with branches out

alternate Text

Four bus system

alternate Text

Medium voltage open ring

alternate Text

CIGRE Networks

CIGRE-Networks were developed by the CIGRE Task Force C6.04.02 to “facilitate the analysis and validation of new methods and techniques” that aim to “enable the economic, robust and environmentally responsible integration of DER” (Distributed Energy Resources). CIGRE-Networks are a set of comprehensive reference systems to allow the “analysis of DER integration at high voltage, medium voltage and low voltage and at the desired degree of detail”.

Note

Source for this network is the final Report of Task Force C6.04.02: “Benchmark Systems for Network Integration of Renewable and Distributed Energy Resources”, 2014

See also a correlating Paper with tiny changed network parameters: K. Rudion, A. Orths, Z. A. Styczynski and K. Strunz, Design of benchmark of medium voltage distribution network for investigation of DG integration 2006 IEEE Power Engineering Society General Meeting, Montreal, 2006

High voltage transmission network

import pandapower.networks as pn

# You may specify a length for the connection line between buses 6a and 6b
net = pn.create_cigre_network_hv(length_km_6a_6b=0.1)

'''
This pandapower network includes the following parameter tables:
  - shunt (3 elements)
  - trafo (6 elements)
  - bus (13 elements)
  - line (9 elements)
  - load (5 elements)
  - ext_grid (1 elements)
  - gen (3 elements)
  - bus_geodata (13 elements)
'''
alternate Text

Medium voltage distribution network

import pandapower.networks as pn

net = pn.create_cigre_network_mv(with_der=False)

'''
This pandapower network includes the following parameter tables:
  - switch (8 elements)
  - load (18 elements)
  - ext_grid (1 elements)
  - line (15 elements)
  - trafo (2 elements)
  - bus (15 elements)
  - bus_geodata (15 elements)
'''
alternate Text

Medium voltage distribution network with PV and Wind DER

Note

This network contains additional 9 distributed energy resources compared to medium voltage distribution network:

  • 8 photovoltaic generators
  • 1 wind turbine

Compared to the case study of CIGRE Task Force C6.04.02 paper all pv and wind energy resources are considered but 2 Batteries, 2 residential fuel cells, 1 CHP diesel and 1 CHP fuel cell are neglected. Although the case study mentions the High Voltage as 220 kV, we assume 110 kV again because of no given 220 kV-Trafo data.

import pandapower.networks as pn

net = pn.create_cigre_network_mv(with_der="pv_wind")

'''
This pandapower network includes the following parameter tables:
  - switch (8 elements)
  - load (18 elements)
  - ext_grid (1 elements)
  - sgen (9 elements)
  - line (15 elements)
  - trafo (2 elements)
  - bus (15 elements)
  - bus_geodata (15 elements)
'''
alternate Text

Medium voltage distribution network with all DER

Note

This network contains additional 15 distributed energy resources compared to medium voltage distribution network:

  • 8 photovoltaic generators
  • 1 wind turbine
  • 2 Batteries
  • 2 residential fuel cells
  • 1 CHP diesel
  • 1 CHP fuel cell

Compared to the case study of CIGRE Task Force C6.04.02 paper all distributed energy resources are considered. Although the case study mentions the High Voltage as 220 kV, we assume 110 kV again because of no given 220 kV-Trafo data.

import pandapower.networks as pn

net = pn.create_cigre_network_mv(with_der="all")

'''
This pandapower network includes the following parameter tables:
  - switch (8 elements)
  - load (18 elements)
  - ext_grid (1 elements)
  - sgen (15 elements)
  - line (15 elements)
  - trafo (2 elements)
  - bus (15 elements)
  - bus_geodata (15 elements)
'''
alternate Text

Low voltage distribution network

import pandapower.networks as pn

net = pn.create_cigre_network_lv()

'''
This pandapower network includes the following parameter tables:
  - switch (3 elements)
  - load (15 elements)
  - ext_grid (1 elements)
  - line (37 elements)
  - trafo (3 elements)
  - bus (44 elements)
  - bus_geodata (44 elements)
'''
alternate Text

MV Oberrhein

Note

The MV Oberrhein network is a generic network assembled from openly available data supplemented with parameters based on experience.

The geographical representation of the network looks like this:

_images/plotting_tutorial1.png

The different colors of the MV/LV stations indicate the feeders which are galvanically seperated by open switches. If you are interested in how to make plots such as these, check out the pandapower tutorial on plotting.

The power flow results of the network in the different worst case scenarios look like this:

_images/oberrhein_loadcases.png

As you can see, the network is designed to comply with a voltage band of 0.975 < u < 1.03 and line loading of <60 % in the high load case (for n-1 security) and <100% in the low load case.

Power System Test Cases

Note

All Power System Test Cases were converted from PYPOWER or MATPOWER case files.

Case 4gs


Case 5


Case 6ww


Case 9


Case 14


Case 24_ieee_rts



Case 30


Case IEEE30


Case 33bw

Case 39


Case 57


Case 89pegase


Case 118


Case 145


Case case_illinois200


Case 300


Case 1354pegase


Case 1888rte


Case 2848rte


Case 2869pegase


Case 3120sp


Case 6470rte


Case 6495rte


Case 6515rte


Case 9241pegase


Case GB network


Case GB reduced network


Case iceland

Kerber Networks

The kerber networks are based on the grids used in the dissertation “Aufnahmefähigkeit von Niederspannungsverteilnetzen für die Einspeisung aus Photvoltaikanlagen” (Capacity of low voltage distribution networks with increased feed-in of photovoltaic power) by Georg Kerber. The following introduction shows the basic idea behind his network concepts and demonstrate how you can use them in pandapower.

“The increasing amount of new distributed power plants demands a reconsideration of conventional planning strategies in all classes and voltage levels of the electrical power networks. To get reliable results on loadability of low voltage networks statistically firm network models are required. A strategy for the classification of low voltage networks, exemplary results and a method for the generation of reference networks are shown.” (source: https:/mediatum.ub.tum.de/doc/681082/681082.pdf)

Warning

The representative grids for sub-urban areas (Vorstadt) were deduced as open-ring grids from meshed grids. They are therefore only valid under the assumption of homogeneous load and generation profiles, and not for inhomogeneous operation or even short-circuit situations.

Average Kerber networks

Kerber Landnetze:

  • Low number of loads per transformer station
  • High proportion of agriculture and industry
  • Typical network topologies: line

Kerber Dorfnetz:

  • Higher number of loads per transformer station (compared to Kerber Landnetze)
  • Lower proportion of agriculture and industry
  • Typical network topologies: line, open ring

Kerber Vorstadtnetze:

  • Highest number of loads per transformer station (compared to Kerber Landnetze/Dorfnetz)
  • no agriculture and industry
  • high building density
  • Typical network topologies: open ring, meshed networks
  Lines Total Length Loads Installed Power
Kerber Landnetze        
Freileitung 1 13 0.273 km 13 104 kW
Freileitung 2 8 0.390 km 8 64 kW
Kabel 1 16 1.046 km 8 64 kW
Kabel 2 28 1.343 km 14 112 kW
         
Kerber Dorfnetz 114 3.412 km 57 342 kW
         
Kerber Vorstadtnetze        
Kabel 1 292 4.476 km 146 292 kW
Kabel 2 288 4.689 km 144 288 kW

You can include the kerber networks by simply using:

import pandapower.networks as pn

net1 = pn.create_kerber_net()
Kerber Landnetze
import pandapower.networks as pn

net1 = pn.create_kerber_landnetz_freileitung_1()

'''
This pandapower network includes the following parameter tables:
  - load (13 elements) p_load_in_kw=8,  q_load_in_kw=0
  - bus (15 elements)
  - line (13 elements) std_type="Al 120", l_lines_in_km=0.021
  - trafo (1 elements)  std_type="0.125 MVA 10/0.4 kV Dyn5 ASEA"
  - ext_grid (1 elements)
'''

net2 = pn.create_kerber_landnetz_freileitung_2()

'''
This pandapower network includes the following parameter tables:
  - load (8 elements) p_load_in_kw=8,  q_load_in_kw=0
  - bus (10 elements)
  - line (8 elements)  std_type="AL 50", l_lines_1_in_km=0.038, l_lines_2_in_km=0.081
  - trafo (1 elements)  std_type="0.125 MVA 10/0.4 kV Dyn5 ASEA"
  - ext_grid (1 elements)
'''
alternate Text
import pandapower.networks as pn

net1 = pn.create_kerber_landnetz_kabel_1()

'''
This pandapower network includes the following parameter tables:
  - load (8 elements)  p_load_in_kw=8,  q_load_in_kw=0
  - bus (18 elements)
  - line (16 elements)  std_type="NAYY 150", std_type_branchout_line="NAYY 50"
  - trafo (1 elements)  std_type = "0.125 MVA 10/0.4 kV Dyn5 ASEA"
  - ext_grid (1 elements)
'''

net2 = pn.create_kerber_landnetz_kabel_2()

'''
This pandapower network includes the following parameter tables:
 - load (14 elements)  p_load_in_kw=8,  q_load_in_kw=0
 - bus (30 elements)
 - line (28 elements)  std_type="NAYY 150", std_type_branchout_line="NAYY 50"
 - trafo (1 elements)  std_type="0.125 MVA 10/0.4 kV Dyn5 ASEA"
 - ext_grid (1 elements)
'''
alternate Text

Kerber Dorfnetz
import pandapower.networks as pn

net = pn.create_kerber_dorfnetz()

'''
This pandapower network includes the following parameter tables:
  - load (57 elements) p_load_in_kw=6,  q_load_in_kw=0
  - bus (116 elements)
  - line (114 elements) std_type="NAYY 150"; std_type_branchout_line="NAYY 50"
  - trafo (1 elements) std_type="0.4 MVA 10/0.4 kV Yyn6 4 ASEA"
  - ext_grid (1 elements)
'''
alternate Text

Kerber Vorstadtnetze
import pandapower.networks as pn

net1 = pn.create_kerber_vorstadtnetz_kabel_1()

'''
This pandapower network includes the following parameter tables:
  - load (146 elements) p_load_in_kw=2,  q_load_in_kw=0
  - bus (294 elements)
  - line (292 elements) std_type="NAYY 150", std_type_branchout_line_1="NAYY 50", std_type_branchout_line_2="NYY 35"
  - trafo (1 elements) std_type="0.63 MVA 20/0.4 kV Yyn6 wnr ASEA"
  - ext_grid (1 elements)
'''
alternate Text
import pandapower.networks as pn

net2 = pn.create_kerber_vorstadtnetz_kabel_2()

'''
This pandapower network includes the following parameter tables:
  - load (144 elements) p_load_in_kw=2,  q_load_in_kw=0
  - bus (290 elements)
  - line (288 elements) std_type="NAYY 150", std_type_branchout_line_1="NAYY 50", std_type_branchout_line_2="NYY 35"
  - trafo (1 elements) "std_type=0.63 MVA 20/0.4 kV Yyn6 wnr ASEA"
  - ext_grid (1 elements)
'''
alternate Text

Extreme Kerber networks

The typical kerber networks represent the most common low-voltage distribution grids. To produce statements of universal validity or check limit value, a significant part of all existing grids have to be involved. The following grids obtain special builds of parameters (very high line length, great number of branches or high loaded transformers). These parameters results in high loaded lines and low voltage magnitudes within the extreme network. By including the extreme networks, kerber reached the 95% confidence interval.

Therefore 95% of all parameter results in an considered distribution grid are equal or better compared to the outcomes from kerber extreme networks. Besides testing for extreme parameters you are able to check for functional capability of reactive power control. Since more rare network combination exist, the total number of extreme grids is higher than the amount of typical kerber networks.

  Lines Total Length Loads Installed Power
Kerber Landnetze        
Freileitung 1 26 0.312 km 26 208 kW
Freileitung 2 27 0.348 km 27 216 kW
Kabel 1 52 1.339 km 26 208 kW
Kabel 2 54 1.435 km 27 216 kW
         
Kerber Dorfnetze        
Kabel 1 116 3.088 km 58 348 kW
Kabel 2 234 6.094 km 117 702 kW
         
Vorstadtnetze        
Kabel_a Type 1 290 3.296 km 145 290 kW
Kabel_b Type 1 290 4.019 km 145 290 kW
Kabel_c Type 2 382 5.256 km 191 382 kW
Kabel_d Type 2 384 5.329 km 192 384 kW

The Kerber extreme networks are categorized into two groups:

Type I: Kerber networks with extreme lines

Type II: Kerber networks with extreme lines and high loaded transformer

Note

Note that all Kerber exteme networks (no matter what type / territory) consist of various branches, linetypes or line length.

Extreme Kerber Landnetze
import pandapower.networks as pn

'''Extrem Landnetz Freileitung Typ I'''
net = pn.kb_extrem_landnetz_freileitung()


'''Extrem Landnetz Kabel Typ I'''
net = pn.kb_extrem_landnetz_kabel()
alternate Text
import pandapower.networks as pn

'''Extrem Landnetz Freileitung Typ II'''
net = pn.kb_extrem_landnetz_freileitung_trafo()


'''Extrem Landnetz Kabel Typ II'''
net = pn.kb_extrem_landnetz_kabel_trafo()
alternate Text
Extreme Kerber Dorfnetze
import pandapower.networks as pn

'''Extrem Dorfnetz Kabel Typ I'''
net = pn.kb_extrem_dorfnetz()
alternate Text
import pandapower.networks as pn

'''Extrem Dorfnetz Kabel Typ II'''
net = pn.kb_extrem_dorfnetz_trafo()
alternate Text
Extreme Kerber Vorstadtnetze
import pandapower.networks as pn

'''Extrem Vorstadtnetz Kabel_a Typ I'''
net = pn.kb_extrem_vorstadtnetz_1()
alternate Text
import pandapower.networks as pn

'''Extrem Vorstadtnetz Kabel_b Typ I'''
net = pn.kb_extrem_vorstadtnetz_2()
alternate Text
import pandapower.networks as pn

'''Extrem Vorstadtnetz Kabel_c Typ II'''
net = pn.kb_extrem_vorstadtnetz_trafo_1()
alternate Text
import pandapower.networks as pn

'''Extrem Vorstadtnetz Kabel_d Typ II'''
net = pn.kb_extrem_vorstadtnetz_trafo_2()
alternate Text

Synthetic Voltage Control LV Networks

alternate Text alternate Text alternate Text alternate Text alternate Text

Dickert LV Networks

For all given Dickert LV Networks (in numbers: 12) the number of delivery points of tapped lines (n_DP) and the distance between delivery points (d_DP) is given in this table:

Feeders range Line type Customer Case d_DP n_DP
short cable single good 60 1
      average 120 1
      bad 80 2
    multiple good 80 3
      average 50 6
      bad 40 10
middle cable multiple good 40 15
      average 35 20
      bad 30 25
  C&OHL multiple good 50 10
      average 45 13
      bad 40 16
long cable multiple good 30 30
      average 30 40
      bad 30 50
  C&OHL multiple good 40 20
      average 40 30
      bad 40 40

The next figure shows the topology of the paper’s example with lv network with mid-range, cable type and in good case:

alternate Text

Plotting Networks

pandapower includes enables plotting networks with two plotting packages: Matplotlib and Plotly .

Matplotlib Network Plots

pandapower provides the functionality to translate pandapower network elements into matplotlib collections. The different collections for lines, buses or transformers can than be drawn with pyplot.

If no coordinates are available for the buses, pandapower provides possibility to create generic coordinates through the igraph package. If no geocoordinates are available for the lines, they can be plotted as direct connections between the buses.

Simple Plotting

The function simple_plot() can be used for simple plotting. For advanced possibilities see the tutorials

Create Collections

Matplotlib collections can be created from pandapower networks with the following functions:

Bus Collections
Branch Collections

Create Colormaps

Discrete
Continous

Draw Collections

Example plot with mv_oberrhein network from the pandapower.networks package:

_images/plotting_tutorial1.png

Generic Coordinates

If there are no geocoordinates in a network, generic coordinates can be created. There are two possibilities:

  1. igraph (http:/igraph.org/python) (recommended) based on
    • python-igraph
    • pycairo
  2. graphviz (http:/www.graphviz.org) based on
    • networkx
    • graphviz

Two avoid having two compile C libraries, precompiled wheels are available on https://www.lfd.uci.edu/%7Egohlke/pythonlibs/ (unofficial)

Generically created geocoordinates can then be plotted in the same way as real geocoordinates.

Example plot with mv_oberrhein network from the pandapower.networks package as geographical plan (respect_switches=False):

_images/plotting_tutorial2.png

and as structural plan (respect_switches=True):

_images/plotting_tutorial3.png

Plotly Network Plots

pandapower provides interactive network plots using Plotly. These plots are built with arguments and functionalities to be as much as possible analogous with pandapower’s matlpotlib plotting library. There is a functionality to translate pandapower network elements into plotly collections (traces). The different collections for lines, buses or transformers can than be drawn.

In order to get idea about interactive plot features and possibilities see the tutorial.

If a network has geocoordinates, there is a possibility to represent interactive plots on Mapbox maps.

Note

Plots on Mapbox maps are available only considering you have a Mapbox account and a Mapbox Access Token. After getting a mabox token it can be set to pandapower as the following

from pandapower.plotting.plotly.mapbox_plot import set_mapbox_token
set_mapbox_token('<token>')

Built-in plot functions

In order to get idea about interactive plot features and possibilities see the tutorial.

Simple Plotting

The function simple_plotly() can be used for a simple interactive plotting.

Example plot with mv_oberrhein network from the pandapower.networks package:

_images/simple_plotly_mvoberr_sample.png

Example simple plot

from pandapower.plotting.plotly import simple_plotly
from pandapower.networks import mv_oberrhein
net = mv_oberrhein()
simple_plotly(net)
_images/simple_plotly_map_mvoberr_sample.png

Example simple plot on a map:

net = mv_oberrhein()
simple_plotly(net, on_map=True, projection='epsg:31467')
_images/simple_plotly_mapsatelite_mvoberr_sample.png
Network coloring according to voltage levels

The function vlevel_plotly() is used to plot a network colored and labeled according to voltage levels.

Example plot with mv_oberrhein network from the pandapower.networks package:

from pandapower.plotting.plotly import vlevel_plotly
from pandapower.networks import mv_oberrhein
net = mv_oberrhein()
vlevel_plotly(net)
_images/vlevel_plotly_mvoberr_sample.png
Power Flow results

The function pf_res_plotly() is used to plot a network according to power flow results where a colormap is used to represent line loading and voltage magnitudes. For advanced possibilities see the tutorials.

Example power flow results plot:

from pandapower.plotting.plotly import pf_res_plotly
from pandapower.networks import mv_oberrhein
net = mv_oberrhein()
pf_res_plotly(net)
_images/pf_res_plotly_mvoberr_sample.png

Power flow results on a map:

net = mv_oberrhein()
pf_res_plotly(net, on_map=True, projection='epsg:31467', map_style='dark')
_images/pf_res_plotly_map_mvoberr_sample.png

Create & Draw Traces

Plotly traces can be created from pandapower networks with the following functions.

Bus Traces
Branch Traces
Draw Traces

Transforming network geodata from any projection to lat/long

In case network geodata are not in The World Geodetic System (WGS84), that is latitude/longitude format, but in some of the map-projections, it may be converted to lat/long by providing name of the projection (in the form 'epsg:<projection_number>' according to spatialreference). A sample of converting geodata from mv_oberrhein network can be found in the tutorial.

HTML

Save and Load Networks

  Advantage Disadvantage
Example: saving
case9241pegase
pickle
Allows storing of objects
- large filesize
- Stored objects might become
incompatible when loading
with different versions
- Savetime: 1.2s
- Loadtime: 0.65s
- Filesize: 18.4 MB
Excel
Human readable
- Long time to save and load
- Needs libraries that are not part of
standard python distribution
- Savetime: 23.9s
- Loadtime: 10.9s
- Filesize: 4.9 MB
SQL    
- Savetime: 1.32s
- Loadtime: 0.6s
- Filesize: 5.1 MB
json
can be interpreted in
other languages
potential insecurity with additional
translation in json notation
-Savetime: 0.19s
-Loadtime: 0.79s
- Filesize: 5.3 MB

pickle

Excel

Json

SQL

Converter

Pandapower provides some very useful converters which enable an exchange of network data with other Power System analysis tools.

These tools are:

PYPOWER

The following functions are provided to enable a network data exchange with PYPOWER.

MATPOWER

To communicate to MATPOWER to exchange network data these functions are available.

Toolbox

The pandapower toolbox is a collection of helper functions that are implemented for the pandapower framework. It is designed for functions of common application that fit nowhere else. Have a look at the available functions to save yourself the effort of maybe implementing something twice. If you develop some functionality which could be interesting to other users as well and do not fit into one of the specialized packages, feel welcome to add your contribution. To improve overview functions are loosely grouped by functionality, please adhere to this notion when adding your own functions and feel free to open new groups as needed.

Note

If you implement a function that might be useful for others, it is mandatory to add a short docstring to make browsing the toolbox practical. Ideally further comments if appropriate and a reference of authorship should be added as well.

Result Information

Simulation Setup and Preparation

Topology Modification

Item/Element Selection