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
|
Build a uniform-earth analytic benchmark. |
|
Return analytic plane-wave impedance of a uniform half-space. |
|
Build a laterally uniform layered-earth benchmark. |
|
Return analytic 1-D MT impedance by upward layer recursion. |
|
Run an ordered benchmark collection with one backend version. |
Classes
|
Store errors measured against one analytic reference. |
|
Record the auditable outcome of one backend benchmark. |
|
Aggregate ordered outcomes from one backend benchmark run. |
|
Define quantitative acceptance limits for one benchmark. |
|
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:
objectDefine 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:
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:
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:
objectStore 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
- class pycsamt.forward.maxwell.benchmarks.BenchmarkOutcome(benchmark_name, benchmark_hash, backend_name, backend_version, passed, metrics, failures=())[source]
Bases:
objectRecord 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.
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
- to_dict()[source]
Return a JSON-compatible benchmark outcome.
- Returns:
Case identity, backend identity, metrics, and failures.
- Return type:
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:
objectDefine 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
analyticandhalf-space.metadata (mapping, optional) – Finite JSON-compatible provenance.
Examples
Cases are normally built with
half_space_benchmark()orlayered_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)
- property benchmark_hash: str[source]
Return a deterministic digest of case inputs and thresholds.
- Returns:
SHA-256 benchmark identity.
- Return type:
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:
- 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:
Examples
Backend exceptions propagate so infrastructure failures cannot be mistaken for numerical benchmark failures.
- class pycsamt.forward.maxwell.benchmarks.BenchmarkReport(outcomes)[source]
Bases:
objectAggregate 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:
Examples
A report fails if any contained outcome fails.
- 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:
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:
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:
backend (MaxwellBackend) – Backend under validation.
benchmarks (sequence of MaxwellBenchmark) – Non-empty cases with unique names.
- Returns:
Aggregate and per-case outcomes.
- Return type:
Examples
Backend and numerical exceptions propagate rather than becoming false benchmark failures.