pycsamt.ai.inversion.pinn3d#

Physics-informed AI 3-D MT inversion.

PINNInverter3D optimises a quasi-3D resistivity volume — one 1-D column per station arranged in a 2-D horizontal network — by minimising a physics-informed loss that combines per-station 1-D data misfits with a graph-Laplacian spatial smoothness penalty.

The station network is represented as a graph whose adjacency A encodes inter-station proximity. Spatial coupling is imposed via the graph Laplacian \(L = D - A\):

\[\mathcal{L}_{\rm spatial} = \frac{1}{\|m\|} \sum_{k=1}^{L} m_{:,k}^\top L\, m_{:,k}\]

where \(m_{s,k} = \log_{10}\rho_{s,k}\), \(L\) is the graph Laplacian built from the normalized adjacency, and the sum is over layers.

Full loss#

\[\mathcal{L} = \mathcal{L}_{\rm data} + \lambda_z \mathcal{L}_{\rm vert} + \lambda_g \mathcal{L}_{\rm spatial}\]

where \(\mathcal{L}_{\rm data}\) and \(\mathcal{L}_{\rm vert}\) are the same data-misfit and vertical-smoothness terms used in PINNInverter2D.

Example

>>> from pycsamt.ai.inversion import PINNInverter3D
>>> inv = PINNInverter3D(
...     "edi/survey/",
...     n_layers=10,
...     depth_max=3000.0,
...     radius=3000.0,
...     epochs=300,
... )
>>> inv.fit()
PINNInverter3D(n_stations=25, fitted)
>>> vol = inv.resistivity_volume()

Classes

PINNInverter3D(sites, *[, n_layers, ...])

Physics-informed quasi-3D MT inversion.

class pycsamt.ai.inversion.pinn3d.PINNInverter3D(sites, *, n_layers=10, depth_max=2000.0, n_freqs=32, mode='te', smoothness_weight=0.01, graph_weight=0.005, radius=5000.0, adjacency=None, station_coords=None, station_spacing=500.0, epochs=300, lr=0.01, comp_te='xy', comp_tm='yx', device=None, recursive=True, on_dup='replace', verbose=0)[source]

Bases: BasePINNInverter

Physics-informed quasi-3D MT inversion.

Optimises a per-station 1-D column model for all stations simultaneously using the 1-D MT forward with graph-Laplacian spatial smoothness coupling neighbour stations through their shared adjacency.

Parameters:
  • sites (Any) – Path, EDIFile, EDICollection, Site, Sites, APISurvey, or iterable.

  • n_layers (int, default 10) – Number of model layers per station.

  • depth_max (float, default 2000.0) – Target maximum depth in metres.

  • n_freqs (int, default 32) – Frequency-grid points for the common grid.

  • mode ({'te', 'tm', 'both'}, default 'te') – Which polarisation to fit.

  • smoothness_weight (float, default 0.01) – Vertical smoothness weight.

  • graph_weight (float, default 0.005) – Graph-Laplacian spatial smoothness weight.

  • radius (float, default 5000.0) – Edge radius in metres used to build the station adjacency when adjacency is None.

  • adjacency (ndarray (S, S) or None) – Pre-computed normalised adjacency matrix. When None it is built from station positions with build_adjacency().

  • station_coords (ndarray (S, 2) or None) – Explicit (x, y) station positions [m]. Auto-extracted from site metadata if None.

  • station_spacing (float, default 500.0) – Uniform grid spacing [m] used when no geographic coordinates are available.

  • epochs (int, default 300) – Adam iterations.

  • lr (float, default 1e-2) – Adam learning rate.

  • comp_te (str, default 'xy')

  • comp_tm (str, default 'yx')

  • device (str or None)

  • recursive (bool, default True)

  • on_dup (str, default 'replace')

  • verbose (int, default 0)

fit(*, verbose=True, log_every=50)[source]

Run the joint 3-D physics-informed inversion.

Return type:

self

Parameters:
resistivity_volume(*, as_log10=True)[source]

Return the quasi-3D resistivity volume.

Returns:

Column i is the 1-D model at station i in the same order as stations.

Return type:

ndarray (n_layers, n_stations)

Parameters:

as_log10 (bool)

thickness_volume()[source]

Return layer thicknesses in metres.

Return type:

ndarray (n_layers-1, n_stations)

station_coords()[source]

Return station (x, y) positions [m].

Return type:

ndarray

adjacency()[source]

Return the station adjacency matrix.

Return type:

ndarray

convergence_curve()[source]

Return Adam loss history.

Returns:

Columns: epoch, loss.

Return type:

pandas.DataFrame

residuals()[source]

Observed vs predicted data fit.

Returns:

Columns: station, freq, rho_obs, rho_pred, phase_obs, phase_pred.

Return type:

pandas.DataFrame

property stations: list[str][source]

Station names in order.

property n_sites: int[source]

Number of loaded stations.