pycsamt.forward.maxwell.benchmarks#

Canonical analytic benchmarks for Maxwell backend validation.

The module defines executable benchmark cases rather than certifying any backend by name. A backend becomes verified only when stored benchmark outcomes identify its exact version, problem hashes, thresholds, and metrics.

Functions

half_space_benchmark(mesh, receivers, ...[, ...])

Build a uniform-earth analytic benchmark.

half_space_impedance(resistivity_ohm_m, ...)

Return analytic plane-wave impedance of a uniform half-space.

layered_earth_benchmark(mesh, receivers, ...)

Build a laterally uniform layered-earth benchmark.

layered_earth_impedance(resistivity_ohm_m, ...)

Return analytic 1-D MT impedance by upward layer recursion.

run_benchmarks(backend, benchmarks)

Run an ordered benchmark collection with one backend version.

Classes

BenchmarkMetrics(normalized_rms, ...)

Store errors measured against one analytic reference.

BenchmarkOutcome(benchmark_name, ...[, failures])

Record the auditable outcome of one backend benchmark.

BenchmarkReport(outcomes)

Aggregate ordered outcomes from one backend benchmark run.

BenchmarkThresholds([...])

Define quantitative acceptance limits for one benchmark.

MaxwellBenchmark(name, description, problem, ...)

Define one immutable problem and its expected impedance.

class pycsamt.forward.maxwell.benchmarks.BenchmarkThresholds(maximum_normalized_rms=0.05, maximum_amplitude_relative_error=0.05, maximum_phase_error_deg=2.0, minimum_valid_fraction=1.0, require_convergence=True)[source]

Bases: object

Define quantitative acceptance limits for one benchmark.

Parameters:
  • maximum_normalized_rms (float, default=0.05) – Maximum complex root-sum-square error normalized by the reference.

  • maximum_amplitude_relative_error (float, default=0.05) – Maximum pointwise relative impedance-amplitude error.

  • maximum_phase_error_deg (float, default=2.0) – Maximum absolute circular phase error in degrees.

  • minimum_valid_fraction (float, default=1.0) – Minimum fraction of output values marked valid.

  • require_convergence (bool, default=True) – Require every solve in backend diagnostics to converge.

Examples

>>> limits = BenchmarkThresholds(maximum_phase_error_deg=1)
>>> limits.maximum_phase_error_deg
1.0
maximum_normalized_rms: float = 0.05
maximum_amplitude_relative_error: float = 0.05
maximum_phase_error_deg: float = 2.0
minimum_valid_fraction: float = 1.0
require_convergence: bool = True
to_dict()[source]

Return JSON-compatible acceptance limits.

Returns:

Versioned threshold state.

Return type:

dict

Examples

>>> BenchmarkThresholds().to_dict()["schema_version"]
1
classmethod from_dict(data)[source]

Restore validated benchmark thresholds.

Parameters:

data (mapping) – State returned by to_dict().

Returns:

Restored limits.

Return type:

BenchmarkThresholds

Examples

>>> limits = BenchmarkThresholds(maximum_normalized_rms=0.1)
>>> BenchmarkThresholds.from_dict(limits.to_dict()) == limits
True
class pycsamt.forward.maxwell.benchmarks.BenchmarkMetrics(normalized_rms, maximum_amplitude_relative_error, maximum_phase_error_deg, valid_fraction, converged)[source]

Bases: object

Store errors measured against one analytic reference.

Parameters:
  • normalized_rms (float) – Complex normalized root-sum-square error.

  • maximum_amplitude_relative_error (float) – Worst pointwise relative amplitude error.

  • maximum_phase_error_deg (float) – Worst circular phase difference.

  • valid_fraction (float) – Fraction of output values marked valid and finite.

  • converged (bool) – Whether all backend solves converged.

Examples

>>> BenchmarkMetrics(0.01, 0.02, 0.5, 1, True).converged
True
normalized_rms: float
maximum_amplitude_relative_error: float
maximum_phase_error_deg: float
valid_fraction: float
converged: bool
to_dict()[source]

Return JSON-compatible benchmark metrics.

Returns:

Error values, validity, and convergence status.

Return type:

dict

Examples

>>> BenchmarkMetrics(0, 0, 0, 1, True).to_dict()["valid_fraction"]
1.0
class pycsamt.forward.maxwell.benchmarks.BenchmarkOutcome(benchmark_name, benchmark_hash, backend_name, backend_version, passed, metrics, failures=())[source]

Bases: object

Record the auditable outcome of one backend benchmark.

Parameters:
  • benchmark_name (str) – Stable case identity and full content digest.

  • benchmark_hash (str) – Stable case identity and full content digest.

  • backend_name (str) – Exact adapter identity from the result.

  • backend_version (str) – Exact adapter identity from the result.

  • passed (bool) – Whether every configured acceptance criterion passed.

  • metrics (BenchmarkMetrics) – Quantitative comparison with the reference.

  • failures (tuple of str) – Human-readable failed criteria.

Examples

>>> metrics = BenchmarkMetrics(0, 0, 0, 1, True)
>>> outcome = BenchmarkOutcome(
...     "half-space", "0" * 64, "demo", "1", True, metrics
... )
>>> outcome.passed
True
benchmark_name: str
benchmark_hash: str
backend_name: str
backend_version: str
passed: bool
metrics: BenchmarkMetrics
failures: tuple[str, ...] = ()
to_dict()[source]

Return a JSON-compatible benchmark outcome.

Returns:

Case identity, backend identity, metrics, and failures.

Return type:

dict

Examples

>>> metrics = BenchmarkMetrics(0, 0, 0, 1, True)
>>> value = BenchmarkOutcome(
...     "case", "0" * 64, "demo", "1", True, metrics
... )
>>> value.to_dict()["passed"]
True
class pycsamt.forward.maxwell.benchmarks.MaxwellBenchmark(name, description, problem, reference_impedance_v_a, thresholds=BenchmarkThresholds(maximum_normalized_rms=0.05, maximum_amplitude_relative_error=0.05, maximum_phase_error_deg=2.0, minimum_valid_fraction=1.0, require_convergence=True), tags=(), metadata=<factory>)[source]

Bases: object

Define one immutable problem and its expected impedance.

Parameters:
  • name (str) – Stable identifier and scientific purpose.

  • description (str) – Stable identifier and scientific purpose.

  • problem (MaxwellProblem) – Exact solver input.

  • reference_impedance_v_a (complex ndarray) – Analytic reference with canonical problem output shape.

  • thresholds (BenchmarkThresholds, optional) – Quantitative acceptance criteria.

  • tags (sequence of str, optional) – Searchable labels such as analytic and half-space.

  • metadata (mapping, optional) – Finite JSON-compatible provenance.

Examples

Cases are normally built with half_space_benchmark() or layered_earth_benchmark().

name: str
description: str
problem: MaxwellProblem
reference_impedance_v_a: ndarray
thresholds: BenchmarkThresholds = BenchmarkThresholds(maximum_normalized_rms=0.05, maximum_amplitude_relative_error=0.05, maximum_phase_error_deg=2.0, minimum_valid_fraction=1.0, require_convergence=True)
tags: tuple[str, ...] = ()
metadata: Mapping[str, Any]
property benchmark_hash: str[source]

Return a deterministic digest of case inputs and thresholds.

Returns:

SHA-256 benchmark identity.

Return type:

str

Examples

Benchmark hashes contain 64 hexadecimal characters.

evaluate(result)[source]

Compare one canonical result with the analytic reference.

Parameters:

result (ForwardResult) – Backend result for this exact problem.

Returns:

Metrics and every failed acceptance criterion.

Return type:

BenchmarkOutcome

Raises:

ValueError – If the result belongs to a different problem or output axes.

Examples

Exact references produce zero error when wrapped as backend results.

run(backend)[source]

Execute and evaluate this case with a conforming backend.

Parameters:

backend (MaxwellBackend) – Backend compatible with the benchmark problem.

Returns:

Auditable validation outcome.

Return type:

BenchmarkOutcome

Examples

Backend exceptions propagate so infrastructure failures cannot be mistaken for numerical benchmark failures.

provenance()[source]

Return JSON-compatible benchmark provenance.

Returns:

Case identity, problem hash, limits, tags, and metadata.

Return type:

dict

Examples

The full conductivity model remains identified by problem_hash.

class pycsamt.forward.maxwell.benchmarks.BenchmarkReport(outcomes)[source]

Bases: object

Aggregate ordered outcomes from one backend benchmark run.

Parameters:

outcomes (sequence of BenchmarkOutcome) – Non-empty ordered outcomes from one backend version.

Examples

>>> metrics = BenchmarkMetrics(0, 0, 0, 1, True)
>>> outcome = BenchmarkOutcome(
...     "case", "0" * 64, "demo", "1", True, metrics
... )
>>> BenchmarkReport((outcome,)).passed
True
outcomes: tuple[BenchmarkOutcome, ...]
property passed: bool[source]

Return whether every benchmark passed.

Returns:

Aggregate acceptance status.

Return type:

bool

Examples

A report fails if any contained outcome fails.

property pass_fraction: float[source]

Return the fraction of cases that passed.

Returns:

Passed case count divided by total cases.

Return type:

float

Examples

The value lies in the closed interval [0, 1].

to_dict()[source]

Return a JSON-compatible benchmark report.

Returns:

Backend identity, summary, and ordered outcomes.

Return type:

dict

Examples

Serialized reports retain every individual failure message.

pycsamt.forward.maxwell.benchmarks.half_space_impedance(resistivity_ohm_m, frequencies_hz, *, time_dependence='exp(+iwt)')[source]

Return analytic plane-wave impedance of a uniform half-space.

Parameters:
  • resistivity_ohm_m (float) – Positive half-space resistivity.

  • frequencies_hz (array-like) – Positive frequencies.

  • time_dependence ({"exp(+iwt)", "exp(-iwt)"}) – Complex phasor convention.

Returns:

sqrt(i*omega*mu0*rho) or its conjugate convention.

Return type:

ndarray of complex

Examples

>>> round(float(np.angle(half_space_impedance(100, 1), deg=True)))
45
pycsamt.forward.maxwell.benchmarks.layered_earth_impedance(resistivity_ohm_m, thickness_m, frequencies_hz, *, time_dependence='exp(+iwt)')[source]

Return analytic 1-D MT impedance by upward layer recursion.

Parameters:
  • resistivity_ohm_m (sequence of float) – Layer resistivities from surface to basal half-space.

  • thickness_m (sequence of float) – Thickness of every layer except the basal half-space.

  • frequencies_hz (array-like) – Positive evaluation frequencies.

  • time_dependence ({"exp(+iwt)", "exp(-iwt)"}) – Complex phasor convention.

Returns:

Surface impedance in frequency order.

Return type:

ndarray of complex

Examples

A single layer reduces exactly to the half-space expression:

>>> np.allclose(
...     layered_earth_impedance([100], [], [1, 10]),
...     half_space_impedance(100, [1, 10]),
... )
True
pycsamt.forward.maxwell.benchmarks.half_space_benchmark(mesh, receivers, frequencies_hz, *, resistivity_ohm_m=100.0, components=('zxy', 'zyx'), time_dependence='exp(+iwt)', thresholds=None)[source]

Build a uniform-earth analytic benchmark.

Parameters:
  • mesh (MaxwellMesh, ReceiverSet) – Solver geometry and observation locations.

  • receivers (MaxwellMesh, ReceiverSet) – Solver geometry and observation locations.

  • frequencies_hz (sequence of float) – Positive benchmark frequencies.

  • resistivity_ohm_m (float, default=100) – Uniform earth resistivity.

  • components (sequence of str, default=("zxy", "zyx")) – Requested components. Diagonal 3-D components are excluded because their analytic reference is zero and relative metrics are undefined.

  • time_dependence (str, default="exp(+iwt)") – Complex phasor convention.

  • thresholds (BenchmarkThresholds or None, optional) – Acceptance limits.

Returns:

Executable half-space case.

Return type:

MaxwellBenchmark

Examples

>>> mesh = MaxwellMesh([0, 1, 2], [0, 1, 2])
>>> receivers = ReceiverSet([[0.5, 0]], ["S"])
>>> half_space_benchmark(mesh, receivers, [1]).name
'half-space'
pycsamt.forward.maxwell.benchmarks.layered_earth_benchmark(mesh, receivers, frequencies_hz, resistivity_ohm_m, thickness_m, *, components=('zxy', 'zyx'), time_dependence='exp(+iwt)', thresholds=None)[source]

Build a laterally uniform layered-earth benchmark.

Parameters:
  • mesh (MaxwellMesh) – Solver geometry, observations, and frequencies.

  • receivers (ReceiverSet) – Solver geometry, observations, and frequencies.

  • frequencies_hz (Sequence[float]) – Solver geometry, observations, and frequencies.

  • resistivity_ohm_m (sequence of float) – Layer resistivities ending with a basal half-space.

  • thickness_m (sequence of float) – Finite-layer thicknesses. Every cumulative interface must coincide with a mesh z edge.

  • components (Sequence[str]) – Output components, phasor convention, and acceptance limits.

  • time_dependence (str) – Output components, phasor convention, and acceptance limits.

  • thresholds (BenchmarkThresholds | None) – Output components, phasor convention, and acceptance limits.

Returns:

Executable analytic layered-earth case.

Return type:

MaxwellBenchmark

Examples

>>> mesh = MaxwellMesh([0, 1, 2], [0, 1, 2])
>>> receivers = ReceiverSet([[0.5, 0]], ["S"])
>>> case = layered_earth_benchmark(mesh, receivers, [1], [10, 100], [1])
>>> case.name
'layered-earth'
pycsamt.forward.maxwell.benchmarks.run_benchmarks(backend, benchmarks)[source]

Run an ordered benchmark collection with one backend version.

Parameters:
Returns:

Aggregate and per-case outcomes.

Return type:

BenchmarkReport

Examples

Backend and numerical exceptions propagate rather than becoming false benchmark failures.