Skip to content

Soil

Soil models supply the propagation medium for the field computation. Every backend in :mod:groundfield.solver consumes a :class:SoilModel instance — currently :class:HomogeneousSoil, :class:TwoLayerSoil and :class:MultiLayerSoil.

Physical background

Below 1 kHz the soil is a quasi-static conductor: displacement currents are negligible (the dielectric relaxation time \(\tau = \varepsilon / \sigma\) of moist soil is on the order of 100 ns) and Laplace's equation \(-\nabla \cdot (\sigma \nabla \varphi) = 0\) governs the potential field. Each soil class therefore reduces to a stack of horizontal layers with constant resistivity \(\rho_i\) and layer thickness \(h_i\). The half-space at infinity acts as a Dirichlet boundary ("remote earth") and the air–soil interface as a Neumann boundary (\(\partial_z\varphi = 0\) at \(z = 0\)).

For the typical case the two-layer model is the primary workhorse: a top layer of resistivity \(\rho_1\) and finite thickness \(h_1\) over a half-space of resistivity \(\rho_2\). The homogeneous case is recovered for \(\rho_1 = \rho_2\); the multilayer case extends the same matching scheme to arbitrarily many layers (used by :mod:groundfield.solver.image_nlayer and the layered Sommerfeld solvers).

Example

import groundfield as gf

# Homogeneous half-space — fastest, used as a sanity baseline.
homo = gf.HomogeneousSoil(resistivity=100.0)

# Two-layer soil — primary default case (e.g. 1 m topsoil over rock).
two_layer = gf.TwoLayerSoil(rho_1=100.0, rho_2=500.0, h_1=1.0)

# Multi-layer soil — generic n-layer stack.
multi = gf.MultiLayerSoil(layers=[
    gf.SoilLayer(resistivity=80.0, thickness=0.5),
    gf.SoilLayer(resistivity=300.0, thickness=2.0),
    gf.SoilLayer(resistivity=50.0),  # bottom half-space (no thickness)
])

world = gf.create_world(soil=two_layer)

The discriminator field kind allows soil instances to be serialised to JSON and reconstructed without prior knowledge of the concrete subtype.

API reference

soil

Soil models for groundfield.

This subpackage describes the propagation medium "soil". Supported models include homogeneous, layered (two- and multi-layer) and frequency-dependent variants in the spirit of Visacro / Alipio. The models supply the effective electromagnetic parameters \(\rho(f)\), \(\varepsilon_r(f)\) required by the field solver, together with the corresponding Green's functions or image-charge coefficients.

Contents

HomogeneousSoil Uniform half-space with a single resistivity. TwoLayerSoil Upper layer of finite thickness over a semi-infinite lower layer. MultiLayerSoil Generic multi-layer model with arbitrarily many horizontal layers. SoilLayer Single layer used by MultiLayerSoil. SoilModel Discriminated union of all supported soil types.

Notes

The two-layer model is the primary case (parameter space: varying resistivities and layer thicknesses). The other classes are extension points for additional soil structures.

HomogeneousSoil

Bases: _SoilBase

Homogeneous soil with a uniform resistivity.

Attributes:

Name Type Description
resistivity float

Resistivity \(\rho\) in \(\Omega\,\mathrm{m}\).

relative_permittivity float

Relative permittivity \(\varepsilon_r\). Default 10 (mid-range value for soil, IEEE Std 80).

MultiLayerSoil

Bases: _SoilBase

Multi-layer, horizontally stratified soil.

The last entry in layers must have thickness=None (semi-infinite). All other layers must have a finite thickness.

SoilLayer

Bases: BaseModel

A single layer used by :class:MultiLayerSoil.

TwoLayerSoil

Bases: _SoilBase

Two-layer model (finite-thickness upper layer over a semi-infinite lower layer).

Attributes:

Name Type Description
rho_1 float

Resistivity of the upper layer \(\rho_1\) in \(\Omega\,\mathrm{m}\).

rho_2 float

Resistivity of the lower (semi-infinite) layer \(\rho_2\) in \(\Omega\,\mathrm{m}\).

h_1 float

Thickness of the upper layer \(h_1\) in metres.

relative_permittivity float

Common relative permittivity for both layers (simplified).

reflection_coefficient property

reflection_coefficient: float

Reflection coefficient \(K = (\rho_2 - \rho_1) / (\rho_2 + \rho_1)\).