Core models¶
Pydantic v2 data classes describing the physical network elements,
the configured faults and sources, the per-frequency results and
the ComplexNumber helper used throughout the package.
Physical / modelling context¶
groundinsight represents a grounding network as a labelled,
undirected graph. The model layer owns four kinds of objects:
- Types —
BusType,BranchType— carry the SymPy formula strings that are compiled to vectorised callables and evaluated per(f, rho, l)triple. Optional lumped RLC formulas (R_formula,L_formula,C_formula,R_self_formula,L_self_formula,C_self_formula,R_mutual_formula,M_mutual_formula) parameterise the state-space transient solver ingroundinsight.simulation.transient. - Instances —
Bus,Branch— carry concrete numerical values (specific_earth_resistance,length,parallel_coefficient) plus the per-frequency impedance dict \(Z(f) \in \mathbb{C}\) that is built from the formulas at network-build time. - Excitation —
Source(current or voltage source per bus) andFault(which bus, which scaling per frequency). - Results —
Result,ResultBus,ResultBranch,ResultReductionFactor,ResultGroundingImpedance— the outcome ofrun_fault. Both per-frequency components and the RMS over all frequencies (computed as \(\sqrt{\sum_f |X(f)|^2}\)) are stored.
ComplexNumber is a small Pydantic wrapper over the native
complex type. It exists because complex is not natively
JSON-serialisable; the wrapper exposes overloaded arithmetic and
serialises as a {"real": ..., "imag": ...} dict.
Example¶
import groundinsight as gi
from groundinsight.models.core_models import (
Bus, BusType, Branch, BranchType, Source, Fault,
Network, ComplexNumber,
)
# Build a model directly (notebook style)
bt = BusType(name="GroundRod", system_type="Substation",
voltage_level=20.0,
impedance_formula="rho/(2*3.14159*1.5)*(1 + j*0.01*f)")
brt = BranchType(name="ShieldCable", grounding_conductor=True,
self_impedance_formula="(0.2 + j*0.4*f/50)*l",
mutual_impedance_formula="(0.0 + j*0.4*f/50)*l")
net = Network(name="demo", frequencies=[50.0, 150.0])
b1 = Bus(name="b1", type=bt, impedance={},
specific_earth_resistance=100.0)
b2 = Bus(name="b2", type=bt, impedance={},
specific_earth_resistance=100.0)
ln = Branch(name="ln", type=brt, from_bus="b1", to_bus="b2",
length=2.0, self_impedance={}, mutual_impedance={})
src = Source(name="s1", bus="b1", values={50.0: 1.0, 150.0: 0.05})
flt = Fault(name="f1", bus="b2",
scalings={50.0: 1.0, 150.0: 0.05})
# JSON round-trip — ComplexNumber serialises as {real, imag}
payload = net.model_dump_json(indent=2)
restored = Network.model_validate_json(payload)
Polars accessors net.res_buses(), net.res_branches() and
net.res_all_impedances() produce DataFrames suitable for
plotting and reporting.
Active subset / cache invalidation¶
Bus.active and Branch.active are plain Pydantic fields that
flip an instance in or out of the topology used by
PathFinder. Two callers therefore matter when a
flag is flipped in-place after define_paths() has already
populated network.paths:
network.pathsitself, which mirrors the previously active topology.- The module-level
_GRAPH_CACHE/_FIND_PATHS_CACHEingroundinsight.pathfinder, which mirror the same topology fingerprint for fast re-use.
Network.invalidate_paths() is the explicit hook for that case:
# Flip a branch out of service mid-notebook and rebuild paths.
net.branches["LN_main"].active = False
net.invalidate_paths() # drops self.paths + this network's cache
gi.create_paths(net) # rebuilds with the new topology
The invalidation is scoped to the calling Network instance:
cache entries belonging to other live networks in the same process
are preserved, so dashboards iterating over a set of feeders do
not pay a global cache eviction every time a single network
mutates.
Since 0.5.0 the invalidation is also an atomic rebind
(self.paths = {} instead of self.paths.clear()), so an external
snapshot saved = dict(network.paths) taken before the call keeps
its entries:
saved = dict(network.paths) # external snapshot
network.invalidate_paths()
# saved still holds the previously-enumerated paths.
Frequency validation and order warning¶
Network.frequencies is validated at construction time:
- Empty /
nan/inf/ strictly-negative inputs are rejected with a clearValueError. DC (f = 0) is permitted because the FFT transient solver ingroundinsight.simulation.transientuses the zero-frequency bin to carry the steady-state offset. - Duplicate frequencies are rejected — the same
ftwice in the list silently doubled the work insolve_networkand doubled the amplitude of the corresponding spectral bin in the FFT transient solver. - Non-strictly-monotone-increasing inputs accept the order but
emit a
NetworkFrequencyOrderWarning(UserWarning)(added in0.5.0). The FFT transient solver maps spectral bins by position inNetwork.frequencies, so a shuffled or descending list is almost always a user error. Mirrorsgroundfield.solver.engine.EngineFrequencyOrderWarningso the three earthing-platform packages share one convention.
import warnings
import groundinsight as gi
with warnings.catch_warnings():
warnings.simplefilter("error", gi.NetworkFrequencyOrderWarning)
# Raises instead of just warning — use during validation.
gi.create_network(name="net", frequencies=[100.0, 50.0])
Top-level set_active_fault factory¶
The keep_results= keyword on Network.set_active_fault is also
reachable via the top-level factory wrapper:
import groundinsight as gi
# Re-plot the previously cached Result without recomputing it.
gi.set_active_fault(net, "F1", keep_results=True)
Field-level validation guards are documented inline (frequency
duplicate / NaN / negative rejection on Network.frequencies,
int-vs-float key coercion on Fault.scalings, …). See the
mkdocstrings dump below for the authoritative list.
API reference¶
core_models ¶
Bus ¶
Bases: BaseModel
Represents a grounding bus within the network.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
The name of the bus. |
description |
(str, optional)
|
A brief description of the bus. |
type |
BusType
|
The type of the bus. |
impedance |
dict of float to ComplexNumber
|
Mapping of frequency to grounding impedance values. |
specific_earth_resistance |
float
|
The specific earth resistance associated with the bus (Ohm * m). |
active |
bool
|
Whether the bus participates in the solve. Inactive buses are
removed from the admittance matrix; paths traversing them are
dropped. Defaults to |
R |
dict of float to float, optional
|
Evaluated lumped resistance per frequency in Ohm. Populated only
if |
L |
dict of float to float, optional
|
Evaluated lumped inductance per frequency in Henry. Populated
only if |
C |
dict of float to float, optional
|
Evaluated lumped capacitance to remote earth per frequency in
Farad. Populated only if |
calculate_impedance ¶
Calculates impedance and -- if specified by the type -- the lumped RLC parameters for each frequency.
impedance is always recomputed from type.impedance_formula.
Each of R, L and C is recomputed only if the matching
formula is set on the type; otherwise the attribute is left as
None. Utilizes the external impedance_calculator to avoid
storing non-pickleable functions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frequencies
|
List[float]
|
A list of frequencies at which to evaluate the formulas. |
required |
Source code in src/groundinsight/models/core_models.py
BusType ¶
Bases: BaseModel
Represents the type of a bus, including its default impedance formula.
The mandatory impedance_formula is used by the frequency-domain
solver (Y(f) u = i) and is the only required parameter for
stationary studies.
For transient simulations the type can additionally carry an explicit
lumped-element decomposition R_formula / L_formula /
C_formula. These are parallel to impedance_formula: the
frequency-domain solver ignores them, the FFT- and state-space-based
transient solvers consume them. The duplication is intentional so
that the stationary model and the transient equivalent can be
parameterised independently — a substation grounding, for example,
may be modelled as a constant R in the stationary formula while
the transient model uses the full R + j*omega*L plus an HF
capacitance to remote earth.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
The name of the bus type. |
description |
(str, optional)
|
A brief description of the bus type. |
system_type |
str
|
The system type associated with the bus, e.g. |
voltage_level |
float
|
The voltage level of the bus, in kV. |
impedance_formula |
str
|
SymPy formula for the frequency-domain grounding impedance
|
R_formula |
(str, optional)
|
SymPy formula for the lumped resistance |
L_formula |
(str, optional)
|
SymPy formula for the lumped inductance |
C_formula |
(str, optional)
|
SymPy formula for the lumped capacitance to remote earth
|
earthing_conductor_material |
({Cu, Al, Steel}, optional)
|
Material of the earthing conductor (Erdungsleiter) — the
lumped connection that carries the earth-fault current from the
installation into the grounding system. Consumed only by
:func: |
earthing_conductor_cross_section_mm2 |
(float, optional)
|
Cross-section of the earthing conductor in mm². Must be strictly positive when given. |
earthing_conductor_theta_initial_C |
float
|
Initial earthing-conductor temperature in °C. Defaults to
|
earthing_conductor_theta_final_C |
(float, optional)
|
Maximum permissible earthing-conductor temperature in °C.
Defaults to the material value in
:data: |
earthing_conductor_current_split |
float
|
Share of the bus injection this conductor carries, in |
electrode_material |
({Cu, Al, Steel}, optional)
|
Material of the earth electrode (Erder) — the part buried in the soil, which only carries the share of the current that is actually dissipated to earth at this bus. |
electrode_cross_section_mm2 |
(float, optional)
|
Cross-section of the earth electrode in mm². Must be strictly positive when given. |
electrode_theta_initial_C |
float
|
Initial electrode temperature in °C. Defaults to |
electrode_theta_final_C |
(float, optional)
|
Maximum permissible electrode temperature in °C. Buried electrodes are usually limited well below a free-air conductor to protect the surrounding soil and any coating; EN 50522 Table 2 is the reference. |
electrode_current_split |
float
|
Share of the dissipated current a single electrode carries, in
|
Notes
The thermal fields are optional throughout. A bus is only assessed by
:func:groundinsight.check_node_limits once both the material and
the cross-section of the respective element are set; the two elements
are independent, so a bus may declare only its electrode or only its
earthing conductor.
Branch ¶
Bases: BaseModel
Represents a branch (conductor) connecting two buses in the network.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
The name of the branch. |
description |
(str, optional)
|
A brief description of the branch. |
type |
BranchType
|
The type of the branch. |
length |
float
|
The length of the branch (km). |
from_bus |
str
|
The name of the originating bus. |
to_bus |
str
|
The name of the destination bus. |
self_impedance |
dict of float to ComplexNumber
|
Self-impedance values mapped by frequency. |
mutual_impedance |
dict of float to ComplexNumber
|
Mutual-impedance values mapped by frequency. |
specific_earth_resistance |
float
|
The specific earth resistance associated with the branch (Ohm * m). |
parallel_coefficient |
(float, optional)
|
The parallel coefficient between 0 and 1, if any. Defaults to
|
active |
bool
|
Whether the branch participates in the solve. An inactive branch
behaves like an open circuit: it contributes neither to the
admittance matrix nor to the mutual-coupling injection, paths
traversing it are dropped, and its branch current in the result
is forced to zero. Defaults to |
calculate_impedance ¶
Calculate self/mutual impedance and -- if specified by the type -- the phase impedance and the lumped RLCM parameters for each frequency.
self_impedance and mutual_impedance are always recomputed.
Each of phase_impedance, R_self, L_self, C_self,
R_mutual, M_mutual is recomputed only if the matching
formula is set on the branch type; otherwise the attribute is left
as None.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frequencies
|
List[float]
|
A list of frequencies at which to evaluate the formulas. |
required |
Source code in src/groundinsight/models/core_models.py
validate_phase_impedance ¶
Accept None or the same shapes as the other impedance dicts.
Source code in src/groundinsight/models/core_models.py
BranchType ¶
Bases: BaseModel
Represents the type of a branch, including its impedance formulas.
The mandatory self_impedance_formula and
mutual_impedance_formula drive the frequency-domain solver.
The optional phase_impedance_formula describes the phase
conductor -- the faulted conductor whose current induces the
longitudinal EMF on the shield -- and is what the automatic
phase-current distribution solves on. It is only needed when the
network contains rings, meshes or parallel branches, because only
then does the source current have more than one way to reach the
fault. Without it the distribution falls back to a documented proxy
and warns; see :meth:~groundinsight.electrical_network.
ElectricalNetwork._compute_phase_currents_auto.
For transient simulations the type can additionally carry a lumped
RLCM decomposition: R_self_formula, L_self_formula,
C_self_formula (shunt-to-ground capacitance per branch, only
relevant for HF studies), R_mutual_formula (Carson earth-return
resistance term) and M_mutual_formula (mutual inductance to the
parallel phase conductor). These are parallel to the impedance
formulas: the frequency-domain solver ignores them, the state-space
and FFT-based transient solvers consume them. The duplication is
intentional so the stationary and transient parameterisations can be
maintained independently.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
The name of the branch type. |
description |
(str, optional)
|
A brief description of the branch type. |
grounding_conductor |
bool
|
Indicates whether the branch has a grounding wire or cable shield. |
self_impedance_formula |
str
|
SymPy formula used to calculate self-impedance per branch. |
mutual_impedance_formula |
str
|
SymPy formula used to calculate mutual impedance. |
phase_impedance_formula |
(str, optional)
|
SymPy formula for the series impedance of the phase conductor
of this branch, in the same symbols |
R_self_formula |
(str, optional)
|
Per-branch series resistance in Ohm. Used only by the transient solvers. |
L_self_formula |
(str, optional)
|
Per-branch series inductance in Henry. Used only by the transient solvers. |
C_self_formula |
(str, optional)
|
Per-branch shunt capacitance to remote earth in Farad. Used only by the transient solvers. |
R_mutual_formula |
(str, optional)
|
Per-branch mutual resistance (Carson earth-return) in Ohm. Used only by the transient solvers. |
M_mutual_formula |
(str, optional)
|
Per-branch mutual inductance in Henry. Used only by the transient solvers. |
validate_impedance_formula ¶
Validate the SymPy self / mutual impedance formula strings.
validate_rlc_formula ¶
Validate the optional lumped RLC formula strings; None is allowed.
Source code in src/groundinsight/models/core_models.py
Source ¶
Bases: BaseModel
Represents a current or Thevenin (voltage) source within the network.
For stationary grounding analyses the default is a current source
with a fixed injected current per frequency
(source_type="current"). This is equivalent to a Norton source
with infinite parallel impedance and matches the conventional
planning practice of grounding engineering, where the prospective
fault current is treated as a constant input.
For transient simulations the source can alternatively be expressed
as a Thevenin equivalent (source_type="voltage") with a
frequency-dependent EMF voltage and a finite
source_impedance. In that case the grounding network sees the
loop impedance Z_src + Z_loop and the effective fault current
results from the solution rather than being prescribed.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
The name of the source. |
description |
(str, optional)
|
A brief description of the source. |
bus |
str
|
The name of the bus where the source is located. |
source_type |
{current, voltage}
|
|
values |
dict of float to ComplexNumber, optional
|
Frequency-dependent current injection. Required when
|
voltage |
dict of float to ComplexNumber, optional
|
Frequency-dependent Thevenin EMF. Required when
|
source_impedance |
dict of float to ComplexNumber, optional
|
Frequency-dependent internal impedance of the Thevenin source.
Required when |
i_k_a |
(float, optional)
|
Initial symmetrical short-circuit current |
r_to_x |
(float, optional)
|
Ratio |
kappa |
(float, optional)
|
IEC 60909-0 peak factor |
Notes
i_k_a, r_to_x and kappa are characteristic quantities.
They do not enter the linear solve at all: the network equations
superpose the RMS injections in values as before. The non-linear
IEC 60909 factors are applied afterwards, to the aggregated branch
current, by
:func:groundinsight.analysis.shortcircuit.resolve_fault_sc_characteristics.
Superposing i_p or I_th of individual sources directly would
be wrong; see that module's docstring for the derivation.
Fault ¶
Bases: BaseModel
Represents a fault within the network.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
The name of the fault. |
description |
(str, optional)
|
A brief description of the fault. |
bus |
str
|
The name of the bus where the fault occurs. |
scalings |
dict of float to float
|
Scaling factors for sources at different frequencies. |
t_k_s |
(float, optional)
|
Short-circuit duration (clearing time) |
n_factor |
float, default 1.0
|
AC heat factor |
Notes
The private _active attribute indicates whether the fault is the
currently active one in the network and is exposed read-only through
the :attr:active computed property.
t_k_s and n_factor live on the fault, not on the sources,
because the clearing time is a property of the protection scheme
reacting to that fault. The IEC 60909 quantities that describe the
feeding side (I_k'', R/X, kappa) live on
:class:Source instead.
Network ¶
Bases: BaseModel
Top-level container for an entire grounding network.
Holds every physical element (buses, branches, sources, faults), the
enumerated source-to-fault paths, the per-fault result objects and a
private :class:ElectricalNetwork helper that owns the numerical
working arrays.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
The name of the network. |
description |
(str, optional)
|
A brief description of the network. |
frequencies |
list of float
|
Frequencies (in Hz) used in calculations. |
buses |
dict of str to Bus
|
Buses keyed by name. |
branches |
dict of str to Branch
|
Branches keyed by name. |
faults |
dict of str to Fault
|
Faults keyed by name. |
sources |
dict of str to Source
|
Sources keyed by name. |
results |
dict of str to Result
|
Per-fault calculation results keyed by fault name. |
paths |
dict of str to Path
|
Source-to-fault paths keyed by path name. |
active_fault |
(str, optional)
|
Name of the currently active fault. |
add_branch ¶
Adds a branch to the network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
branch
|
Branch
|
The branch instance to add. |
required |
overwrite
|
bool
|
If True, overwrites an existing branch with the same name. Defaults to False. |
False
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If a branch with the same name already exists, or if the connected buses are not in the network. |
Source code in src/groundinsight/models/core_models.py
add_bus ¶
Adds a bus to the network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bus
|
Bus
|
The bus instance to add. |
required |
overwrite
|
bool
|
If True, overwrites an existing bus with the same name. Defaults to False. |
False
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If a bus with the same name already exists and overwrite is False. |
Source code in src/groundinsight/models/core_models.py
add_fault ¶
Adds a fault to the network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fault
|
Fault
|
The fault instance to add. |
required |
overwrite
|
bool
|
If True, overwrites an existing fault with the same name. Defaults to False. |
False
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If a fault with the same name already exists, or if the associated bus is not in the network. |
Source code in src/groundinsight/models/core_models.py
add_path ¶
Adds a path to the network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
The path instance to add. |
required |
add_source ¶
Adds a source to the network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
Source
|
The source instance to add. |
required |
overwrite
|
bool
|
If True, overwrites an existing source with the same name. Defaults to False. |
False
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If a source with the same name already exists, or if the associated bus is not in the network. |
Source code in src/groundinsight/models/core_models.py
define_paths ¶
Identifies all paths from all sources to all faults in the network and adds them to the network's paths.
This method utilizes the PathFinder to locate paths and ensures that each path is unique
before adding it to the network.
Source code in src/groundinsight/models/core_models.py
invalidate_paths ¶
Drop the cached pathfinder results for this network.
Rebinds self.paths to a fresh empty dictionary (atomic) and
drops the module-level :mod:groundinsight.pathfinder cache
entries whose key is scoped to this :class:Network instance.
Other networks' cache entries are preserved. This matters
as soon as the user runs more than one network in the same
Python process (notebooks that compare two scenarios,
dashboards iterating over a set of feeders, …).
Earlier revisions called self.paths.clear() in place.
Callers that had snapshot the mapping with
saved = dict(network.paths) before the call observed the
snapshot lose its entries because the snapshot dictionary
shared its Path values with self.paths until the
snapshot was deep-copied. The current atomic-rebind form
— self.paths = {} — leaves the snapshot mapping intact and
mirrors the atomic-rebind pattern in
:func:groundinsight.analysis.inverse_rho_f.evaluate_max_epr_under_k.
Call this whenever the user has flipped Bus.active /
Branch.active flags or added / removed branches outside of
a context manager that performs its own rollback.
Source code in src/groundinsight/models/core_models.py
res_all_impedances ¶
Returns a Polars DataFrame containing the grounding impedance and reduction factor for each fault, bus, and frequency.
The DataFrame includes grounding impedance magnitude and angle, as well as the reduction factor.
Returns:
| Type | Description |
|---|---|
DataFrame
|
A DataFrame containing grounding impedance and reduction factors. |
Notes
- Faults without results are skipped.
- Missing grounding impedance or reduction factor results are noted.
Source code in src/groundinsight/models/core_models.py
2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 | |
res_branches ¶
Returns a Polars DataFrame with branch results for the specified fault.
If no fault is specified, returns results for the active fault.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fault
|
Optional[str]
|
The name of the fault. Defaults to None. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
A DataFrame containing branch results. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no active fault is set or if results for the specified fault are unavailable. |
Source code in src/groundinsight/models/core_models.py
1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 | |
res_buses ¶
Returns a Polars DataFrame with bus results for the specified fault.
If no fault is specified, returns results for the active fault.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fault
|
Optional[str]
|
The name of the fault. Defaults to None. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
A DataFrame containing bus results. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no active fault is set or if results for the specified fault are unavailable. |
Source code in src/groundinsight/models/core_models.py
1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 | |
set_active_fault ¶
Set the specified fault as active and deactivate all other faults.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fault_name
|
str
|
The name of the fault to activate. |
required |
keep_results
|
bool
|
If |
``False``
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If the specified fault does not exist in the network. |
Source code in src/groundinsight/models/core_models.py
Path ¶
Bases: BaseModel
Ordered branch list connecting a source bus to a fault bus.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
The name of the path. |
description |
(str, optional)
|
A brief description of the path. |
source |
str
|
The name of the source at the start of the path. |
fault |
str
|
The name of the fault at the end of the path. |
segments |
list of Branch
|
Ordered list of branches that make up the path, traversed from
|
Result ¶
Bases: BaseModel
Overall result of a single fault calculation.
Attributes:
| Name | Type | Description |
|---|---|---|
buses |
list of ResultBus
|
Per-bus results. |
branches |
list of ResultBranch
|
Per-branch results. |
reduction_factor |
(ResultReductionFactor, optional)
|
The reduction factor result, if available. |
grounding_impedance |
(ResultGroundingImpedance, optional)
|
The grounding impedance result, if available. |
fault |
str
|
The name of the fault that was active during the calculation. |
ResultBus ¶
Bases: BaseModel
Result data for a bus after running a fault calculation.
Three physically distinct currents meet at a grounding bus, and mixing them up is the classic sizing error EN 50522 / IEC 61936-1 guard against:
i_inj— the current injected into the grounding system at this bus by the sources (at a source bus) or drawn out of it by the fault (at the fault bus). It flows through a lumped connection, the earthing conductor (Erdungsleiter), which therefore has to be sized for the full earth-fault current. Zero at every other bus.ia— the share of that current which is actually dissipated into the soil at this bus,u_EPR / Z_B. It flows through the earth electrode (Erder) and is generally much smaller.- the branch shield currents, reported per branch on
:class:
ResultBranch.
i_inj deliberately excludes the mutual Norton-equivalent injections
of the inductively coupled branches: those model a distributed
induced EMF along the line, not a current entering the node through a
lumped conductor. The full nodal balance including them is
ia = i_vector + sum_branches (u_other - u_self) * Y_self.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
The name of the bus. |
uepr |
float
|
RMS earth potential rise at the bus, in volts. |
ia |
float
|
RMS bus current dissipated into the soil through the earth electrode, in amperes. |
i_inj |
float
|
RMS source-side injection at the bus, in amperes — the current
carried by the earthing conductor. Defaults to |
uepr_freq |
dict of float to ComplexNumber
|
Mapping of frequency to complex voltage values. |
ia_freq |
dict of float to ComplexNumber
|
Mapping of frequency to complex electrode current values. |
i_inj_freq |
dict of float to ComplexNumber
|
Mapping of frequency to complex injection values. Defaults to an empty mapping for backwards compatibility. |
ResultBranch ¶
Bases: BaseModel
Result data for a branch after running a fault calculation.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
The name of the branch. |
i_s |
float
|
RMS shield (grounding-conductor) current in the branch, in amperes. |
i_s_freq |
dict of float to ComplexNumber
|
Mapping of frequency to complex shield current values. |
ResultReductionFactor ¶
Bases: BaseModel
Reduction-factor result at the fault bus.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
(str, optional)
|
The name of the reduction factor result. |
fault_bus |
str
|
The bus where the fault occurred. |
value |
dict of float to float, optional
|
Mapping from frequency to the EPR-based reduction factor
|
value_current |
dict of float to float, optional
|
Mapping from frequency to the current-based reduction factor
|
i_earth |
dict of float to complex, optional
|
The earth-return current |
earth_buses |
dict of float to list of str, optional
|
The buses counted as feeding the soil at each frequency -- from the
fault outwards, in every direction, up to where the potential profile
turns. Reported because the split is a modelling statement and should
be inspectable; see :mod: |
u_earthing |
dict of float to complex, optional
|
The earthing voltage |
z_earthing |
dict of float to complex, optional
|
The earthing impedance |
ResultGroundingImpedance ¶
Bases: BaseModel
Grounding impedance result at the fault bus.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
(str, optional)
|
The name of the grounding impedance result. |
fault_bus |
str
|
The bus where the fault occurred. |
value |
dict of float to ComplexNumber, optional
|
Mapping from frequency to grounding impedance |
ComplexNumber ¶
Bases: BaseModel
Pydantic-compatible complex number with real and imaginary parts.
Wraps the native :class:complex type so that Pydantic models can
serialise and deserialise complex numbers through JSON.
Attributes:
| Name | Type | Description |
|---|---|---|
real |
float
|
The real part of the complex number. |
imag |
float
|
The imaginary part of the complex number. |
convert_to_float ¶
Coerce real / imag inputs to float; None becomes NaN.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
Any
|
Numeric input to coerce. |
required |
Returns:
| Type | Description |
|---|---|
float
|
The coerced value. |
Source code in src/groundinsight/models/core_models.py
validate_complex
classmethod
¶
Validates and converts the input value to a ComplexNumber instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
Any
|
The value to validate and convert. Can be a
|
required |
Returns:
| Type | Description |
|---|---|
Union[ComplexNumber, dict]
|
Either the original |
``ComplexNumber`` instance (passed through) or a dictionary
|
|
with ``real`` and ``imag`` keys ready for Pydantic to
|
|
instantiate ``ComplexNumber``.
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If the input string cannot be parsed as a complex number. |
TypeError
|
If the input type is unsupported. |