groundinsight¶
Simulation of grounding systems in electrical power grids.
groundinsight is an open-source Python package for analysing networked grounding
systems during single-phase-to-ground faults. It computes the earth potential rise
(EPR), branch (shield) currents, reduction factors and the resulting grounding
impedance at the fault location for arbitrary bus/branch topologies including
line, ring and mesh networks.
What groundinsight does¶
Modern medium-voltage distribution networks are meshed through shared grounding conductors (cable shields, overhead-line earth wires, substation grounding grids). During a single-phase-to-ground fault, current returns to the source via this grounding network. To assess touch-voltage safety and EMC effects, two questions have to be answered for a given fault location:
- How much of the fault current actually flows through the local earth (as opposed to returning through the cable shield)? This is captured by the reduction factor \(r\).
- What earth-potential rise does the grounding grid reach, and what is the effective grounding impedance \(Z_G\) seen at the fault bus?
groundinsight answers both questions by assembling a nodal-admittance model
from user-defined frequency- and \(\rho_E\)-dependent impedance formulas and
solving it for every harmonic of interest.
Governing equation¶
All computations happen per frequency \(f\) in the phasor domain:
where \(Y\) is the nodal admittance matrix (bus grounding admittances on the diagonal, branch self-admittances off-diagonal), \(\underline{u}\) is the EPR vector and \(\underline{i}\) combines injected source currents and the Norton equivalents of the mutual coupling between phase and shield conductors.
Minimal example¶
import groundinsight as gi
net = gi.create_network(name="Demo", frequencies=[50])
bus_type = gi.BusType(
name="SubstationBus", system_type="Substation", voltage_level=20,
impedance_formula="rho * 0.01 + j * f * 1/50 * 0.1",
)
cable_type = gi.BranchType(
name="MSCable", grounding_conductor=True,
self_impedance_formula="(0.25 + j * f * 0.012) * l",
mutual_impedance_formula="(0.0 + j * f * 0.012) * l",
)
gi.create_bus(name="src", type=bus_type, network=net)
gi.create_bus(name="flt", type=bus_type, network=net)
gi.create_branch(
name="c1", type=cable_type,
from_bus="src", to_bus="flt", length=5.0, network=net,
)
gi.create_source(name="infeed", bus="src", values={50: 1000.0}, network=net)
gi.create_fault(name="f1", bus="flt", scalings={50: 1.0}, network=net)
gi.run_fault(network=net, fault_name="f1")
print(net.res_all_impedances())
See the Quickstart for the full walkthrough.
Feature overview¶
- Bus, branch, source and fault objects modelled as Pydantic v2 classes
- Symbolic impedance formulas in \(\rho_E\), \(f\) and line length \(l\), evaluated through SymPy
- Sparse LU solver for every frequency (SciPy
splu) - Mutual coupling treated as Norton sources along the path from source to fault
- Two reduction factors, both reported: the EPR ratio with and without
mutual coupling at the fault bus (
value), and the share of the fault current returning through earth (value_current) — the EN 50522 quantity, and the one that responds to the electrode at the fault bus, see Concepts - Phase currents from a solve on the phase-conductor network
(
phase_current_mode="auto"), so rings, meshes and parallel cables no longer collapse onto enumerated paths;BranchType.phase_impedance_formuladescribes the faulted conductor - Splitting the network at the fault (
gi.Cut,gi.analyze_cuts) — what each direction contributes, from source-free current division, see Fault-location decomposition - Parameter sweeps (
run_sweep,rho_f_points) into long-format frames, withsummarizeandclassifyfor statistics and user-supplied limit bands, see Parameter sweeps - Characterising a location without its electrode (
bus_response): two solves determine the response for every electrode impedance, see Location response - Closed-form reference cases (
run_reference_cases) — six configurations checked against results derived from first principles, see Reference cases - SQLite persistence and JSON export/import of networks and type libraries
- Polars DataFrames for result access; Matplotlib helpers for bar plots
- Time-domain transient simulation (FFT and modified-nodal-analysis state-space solvers) on top of the same Pydantic network, see Transient simulation
- Import of external distribution networks from pandapower — the topology
via
from_pandapower, and a solved short-circuit case as IEC 60909 quantities viaread_shortcircuit_results/apply_shortcircuit_characteristics, see I/O - Conductor thermal-limit check (
check_conductor_limits): the IEC 60909 thermally equivalent current \(I_{th}\) against the IEC 60949 adiabatic limit \(k\,S/\sqrt{t_k}\), per grounding branch, see Analysis
Where to go next¶
- Installation — how to get
groundinsightonto your system. - Quickstart — end-to-end walkthrough of a minimal network.
- Concepts — the physical and numerical model behind the code.
- Transient simulation — FFT and state-space solver paths for time-domain studies on top of the stationary network.
- Examples — notebooks covering the minimal case, stationary and transient MV ring studies, a pandapower import and a fault sweep across an MV cable line.
- API reference — function-by-function documentation.
Citation¶
If you use groundinsight for scientific work, please cite it using the
CITATION.cff
metadata shipped with the repository.
License¶
groundinsight is released under the MIT License.