Skip to content

Conductors

The conductors subpackage describes the current-carrying elements that connect or surround electrodes but are not electrodes themselves: cable shields, PEN conductors of TN distribution networks, overhead earth wires, and auxiliary measurement leads.

Physical background

A conductor segment is a thin cylindrical wire of radius \(a\) between two end-points \(\mathbf{x}_a\) and \(\mathbf{x}_b\), in or above the soil, with material parameters \((\rho_\text{wire}, \mu_r)\). In the frequency-domain assembly each conductor contributes

\[ Z_b(\omega) \;=\; R \;+\; j\omega\, L_\text{Neumann} \;+\; \Delta Z_\text{earth-return}(\omega), \]

with the DC resistance \(R = \rho_\text{wire}\,\ell/A\), the perfect-mirror Neumann inductance \(L_\text{Neumann}\) assembled in Coupling, and the earth-return correction (\(\Delta Z_\text{Carson}\) or the rigorous Sommerfeld kernel, see ADR-0005 / ADR-0006). The conductor type tag steers the default material parameters used by the engines:

conductor_type Typical use
"pen" combined neutral / protective earth in TN systems
"cable_shield" concentric cable screen, returns shield currents
"bare_copper" bare-wire bonding between electrodes
"overhead" overhead earth wire above ground
"generic" user-supplied material parameters

Example

import groundfield as gf

world = gf.create_world(soil=gf.TwoLayerSoil(rho_1=100.0, rho_2=500.0, h_1=1.0))

# Two ring electrodes at neighbouring houses
g1 = gf.create_electrode(world, "ring", name="g1",
                         center=(0.0, 0.0, 0.8), radius=3.0, wire_radius=0.005)
g2 = gf.create_electrode(world, "ring", name="g2",
                         center=(40.0, 0.0, 0.8), radius=3.0, wire_radius=0.005)

# PEN conductor along a 40 m cable trench between them
gf.create_conductor(
    world, name="pen_1", start=g1, end=g2,
    conductor_type="pen",
    discretize_segment_length=2.0,  # split into ~20 inductive segments
)

The conductor object is purely geometric / material-based. Earth-return corrections are delegated to :mod:groundfield.coupling, so the same conductor object can be combined with the perfect-mirror approximation, with the Carson series, or with the rigorous Sommerfeld kernel.

Lumped series resistance (new in 0.6.0)

The optional lumped_series_resistance_ohm field overrides the geometric series resistance \(R = \rho_\text{mat}\,L / A\) with a caller-supplied value in Ω. The :attr:series_resistance property returns this value when set and the solver picks it up transparently through the existing distributed-conductor framework (ADR-0003).

The primary consumer is the lumped concrete-shell path of ADR-0012: :class:~groundfield.generators.tn_network.TnNetworkGenerator reads each foundation's \(R_\text{shell,total} = \rho_c/(2\pi\,L_\text{perim})\,\ln(r_b/r_a)\) from world.concrete_shell_corrections (populated by the foundation-electrode materialiser) and injects it on the PEN service drop between the KVS and the foundation anchor. Setting lumped_series_resistance_ohm requires the conductor to be in the finite-impedance branch — pair it with a non-None cross_section to ensure the override is consumed.

API reference

conductors

Conductors, PEN, and cable shields.

Subpackage for all current-carrying elements above and inside the soil that are not electrodes themselves but still take part in the current distribution:

  • overhead lines (phase conductor, earth wire),
  • cables (phase + shield, concentric or three-core),
  • PEN conductors in TN low-voltage networks,
  • auxiliary electrodes for grounding measurements.
Contents

Conductor Single conductor segment with end-point coordinates and a type tag ("pen", "cable_shield", "bare_copper", "overhead", "generic"). ConductorType Literal union of the supported type tags.

Notes

Carson corrections for the earth-return path are not computed here; they enter via :mod:groundfield.coupling. This keeps the conductor model purely geometric and material-based, so it can be combined with different earth-return models.

Conductor

Bases: BaseModel

Wire segment between two points.

Attributes:

Name Type Description
name str

Unique name within the World.

start, end

Start and end point (x, y, z) in metres. z > 0 puts the conductor inside the soil, z < 0 above ground.

start_electrode, end_electrode

Optional name of the electrode anchored at start / end. If both are set, the solver inserts this conductor as a branch in the nodal analysis: ideal (cross_section=None) → hard cluster constraint, finite section → branch with \(R_\text{ser} = \rho L / A\).

conductor_type ConductorType

Type tag from :data:ConductorType. Drives later choice of coupling and impedance model.

wire_radius float

Wire radius in metres. Default 5 mm. Used for the geometric thin-wire approximation in the segment self-action and as a fallback for cross_section when the latter is given as "from_radius".

resistivity float

Material resistivity in \(\Omega\,\mathrm{m}\). Default: copper (1.68e-8).

cross_section float | Literal['from_radius'] | None

Conductor cross section in \(\mathrm{m}^2\). None (default) means ideal galvanic short — the conductor is a zero-impedance bridge. A finite value enables the nodal-analysis branch model with \(R_\text{ser} = \rho_\text{mat}\, L / A\). The string "from_radius" is a convenience shortcut for \(A = \pi r_\text{wire}^2\).

effective_cross_section property

effective_cross_section: float | None

Resolved cross section in \(\mathrm{m}^2\) or None.

Returns:

Type Description
float or None

None when :attr:cross_section is None (ideal-galvanic mode). Otherwise the explicit cross section in m² ("from_radius" resolved to \(\pi\, r_\text{wire}^2\)).

is_distributed property

is_distributed: bool

True iff the conductor is split into sub-segments.

A distributed conductor has a finite :attr:discretize_segment_length — the solver builds one longitudinal segment per sub-piece. False keeps the conductor lumped (single branch between the two end electrodes).

length property

length: float

Euclidean length of the conductor in m.

n_segments property

n_segments: int

Number of segments produced by the discretiser.

Returns 1 for a lumped conductor. Otherwise \(n = \lceil L / \Delta s \rceil\) with \(L\) the Euclidean length and $\Delta s = $ :attr:discretize_segment_length.

series_resistance property

series_resistance: float

Series DC resistance \(R_\text{ser}\) in Ω.

Resolution order:

  1. If :attr:lumped_series_resistance_ohm is set (ADR-0012 V1 concrete-shell path or any user-supplied lumped override), return that value verbatim.
  2. Otherwise compute the geometric formula \(R = \rho_\text{mat}\, L / A\) from :attr:resistivity, :attr:length and :attr:effective_cross_section.
  3. If :attr:cross_section is None, the conductor is in the ideal-galvanic-short branch and the series resistance is 0.0.

Returns:

Type Description
float

Total series resistance in Ω consumed by the solver's distributed-conductor model (ADR-0003).

is_ideal

is_ideal(
    threshold: float = _IDEAL_RESISTANCE_THRESHOLD,
) -> bool

Return True when the conductor acts as a galvanic short.

Parameters:

Name Type Description Default
threshold float

Resistance threshold in Ω. Conductors at or below this value are treated as ideal by the solver. Default 1e-6 Ω.

_IDEAL_RESISTANCE_THRESHOLD
Source code in src/groundfield/conductors/conductor.py
def is_ideal(
    self, threshold: float = _IDEAL_RESISTANCE_THRESHOLD
) -> bool:
    """Return ``True`` when the conductor acts as a galvanic short.

    Parameters
    ----------
    threshold
        Resistance threshold in Ω. Conductors at or below this
        value are treated as ideal by the solver. Default
        ``1e-6 Ω``.
    """
    if self.cross_section is None:
        return True
    return self.series_resistance <= threshold