pycsamt.forward.maxwell.mesh#
Construct solver meshes from geological models and topography.
The builder preserves the canonical (z, x) / (z, y, x) array order,
adds geometric padding and air layers, extends boundary conductivity by nearest
cells, and records earth/air regions explicitly. It constructs meshes and
models only; discretization and boundary conditions remain backend concerns.
Functions
|
Build a padded Maxwell mesh from a geological cell-centre model. |
|
Calculate electromagnetic skin depth for a non-magnetic conductor. |
Classes
|
Configure geometric padding, air treatment, and quality targets. |
|
Summarize numerical mesh quality and skin-depth resolution. |
|
Store a padded mesh, conductivity, regions, and construction record. |
- class pycsamt.forward.maxwell.mesh.MeshDesign(horizontal_padding_cells=6, bottom_padding_cells=8, air_layers=8, padding_expansion=1.35, air_expansion=1.25, air_conductivity_s_m=1e-08, minimum_cells_per_skin_depth=4.0, maximum_adjacent_ratio=1.5, maximum_aspect_ratio=20.0)[source]
Bases:
objectConfigure geometric padding, air treatment, and quality targets.
- Parameters:
horizontal_padding_cells (int or pair of int, default=6) – Number of padding cells before/after each horizontal core axis. A scalar is applied symmetrically.
bottom_padding_cells (int, default=8) – Number of cells beneath the geological model.
air_layers (int, default=8) – Number of cells above the geological reference surface.
padding_expansion (float, default=1.35) – Geometric growth factor away from the core mesh.
air_expansion (float, default=1.25) – Geometric growth factor upward through the air.
air_conductivity_s_m (float, default=1e-8) – Positive numerical conductivity assigned to air cells.
minimum_cells_per_skin_depth (float, default=4.0) – Advisory resolution target evaluated at the smallest skin depth.
maximum_adjacent_ratio (float, default=1.5) – Advisory upper bound for adjacent cell-width ratios.
maximum_aspect_ratio (float, default=20.0) – Advisory upper bound across cell widths.
Examples
>>> design = MeshDesign(horizontal_padding_cells=(3, 5), air_layers=4) >>> design.horizontal_padding (3, 5)
- bottom_padding_cells: int = 8
- air_layers: int = 8
- padding_expansion: float = 1.35
- air_expansion: float = 1.25
- air_conductivity_s_m: float = 1e-08
- minimum_cells_per_skin_depth: float = 4.0
- maximum_adjacent_ratio: float = 1.5
- maximum_aspect_ratio: float = 20.0
- property horizontal_padding: tuple[int, int][source]
Return normalized before/after horizontal padding counts.
Examples
>>> MeshDesign(horizontal_padding_cells=3).horizontal_padding (3, 3)
- to_dict()[source]
Return a JSON-compatible design representation.
- Returns:
Versioned design state.
- Return type:
Examples
>>> MeshDesign(air_layers=2).to_dict()["air_layers"] 2
- classmethod from_dict(data)[source]
Restore a validated mesh design.
- Parameters:
data (mapping) – State returned by
to_dict().- Returns:
Restored design.
- Return type:
Examples
>>> design = MeshDesign(horizontal_padding_cells=2) >>> MeshDesign.from_dict(design.to_dict()).horizontal_padding (2, 2)
- class pycsamt.forward.maxwell.mesh.MeshQuality(cell_count, minimum_cell_width_m, maximum_cell_width_m, maximum_aspect_ratio, maximum_adjacent_ratio, minimum_skin_depth_m, cells_per_minimum_skin_depth, warnings=())[source]
Bases:
objectSummarize numerical mesh quality and skin-depth resolution.
- Parameters:
cell_count (int) – Total number of cells including air and padding.
minimum_cell_width_m (float) – Extreme cell widths over all axes.
maximum_cell_width_m (float) – Extreme cell widths over all axes.
maximum_aspect_ratio (float) – Ratio of maximum to minimum cell width.
maximum_adjacent_ratio (float) – Worst neighboring width expansion on any axis.
minimum_skin_depth_m (float) – Smallest skin depth across the requested physics range.
cells_per_minimum_skin_depth (float) – Skin depth divided by the largest core cell width.
Examples
>>> quality = MeshQuality(10, 1, 5, 5, 1.2, 100, 20, ()) >>> quality.acceptable True
- cell_count: int
- minimum_cell_width_m: float
- maximum_cell_width_m: float
- maximum_aspect_ratio: float
- maximum_adjacent_ratio: float
- minimum_skin_depth_m: float
- cells_per_minimum_skin_depth: float
- class pycsamt.forward.maxwell.mesh.SolverMeshModel(mesh, conductivity_s_m, earth_mask, core_slices, design, quality, source_shape)[source]
Bases:
objectStore a padded mesh, conductivity, regions, and construction record.
- Parameters:
mesh (MaxwellMesh) – Solver-neutral padded mesh.
conductivity_s_m (ndarray) – Positive conductivity shaped like
mesh. Air cells contain the configured small numerical conductivity.earth_mask (ndarray of bool) – True for cells on or below local terrain.
core_slices (tuple of slice) – Geological core location in canonical array order.
design (MeshDesign) – Construction settings.
quality (MeshQuality) – Mesh-quality diagnostics for the requested frequency range.
source_shape (tuple of int) – Original geological model shape.
Examples
Instances are normally created with
build_solver_mesh().- mesh: MaxwellMesh
- conductivity_s_m: ndarray
- earth_mask: ndarray
- design: MeshDesign
- quality: MeshQuality
- property air_mask: ndarray[source]
Return the read-only complement of the earth mask.
- Returns:
Air-region mask shaped like
mesh.- Return type:
ndarray of bool
Examples
air_maskandearth_maskalways partition the complete mesh.
- property model_hash: str[source]
Return a deterministic digest of mesh, model, regions, and design.
- Returns:
SHA-256 digest suitable for provenance checks.
- Return type:
Examples
A valid model hash always contains 64 hexadecimal characters.
- assess_receivers(receivers)[source]
Return receiver-placement errors without modifying coordinates.
- Parameters:
receivers (ReceiverSet) – Candidate locations in the mesh coordinate system.
- Returns:
Empty when all receivers lie inside mesh bounds and no receiver is below the discretized local terrain surface.
- Return type:
Examples
Use this check before
to_problem()when receiver coordinates are assembled independently from the mesh.
- to_problem(frequencies_hz, receivers, *, components=('zxy', 'zyx'), mark_air_inactive=False, time_dependence='exp(+iwt)', magnetic_permeability_h_m=1.2566370614359173e-06, metadata=None)[source]
Create a validated Maxwell problem from this mesh model.
- Parameters:
frequencies_hz (sequence of float) – Positive simulation frequencies.
receivers (ReceiverSet) – Receiver locations matching the mesh dimension.
components (sequence of str, default=("zxy", "zyx")) – Requested canonical impedance components.
mark_air_inactive (bool, default=False) – Use
earth_maskas active cells. Keep false for formulations that solve conductive air explicitly.time_dependence (str, default="exp(+iwt)") – Complex phasor convention.
magnetic_permeability_h_m (float, default=4e-7*pi) – Uniform magnetic permeability.
metadata (mapping or None, optional) – Additional problem provenance.
- Returns:
Solver-neutral problem ready for adapter assessment.
- Return type:
Examples
The generated problem includes
mesh_model_hashin its metadata.
- provenance()[source]
Return JSON-compatible mesh-construction provenance.
- Returns:
Mesh, design, quality, source shape, and core slices.
- Return type:
Examples
The returned schema version is currently one.
- to_npz(path)[source]
Persist a solver mesh model without enabling pickle.
- Parameters:
path (str or pathlib.Path) – Destination archive.
- Returns:
Requested destination.
- Return type:
Examples
Archives can be restored with
from_npz().
- classmethod from_npz(path)[source]
Restore and validate a solver mesh archive without pickle.
- Parameters:
path (str or pathlib.Path) – Archive written by
to_npz().- Returns:
Restored immutable mesh model.
- Return type:
Examples
Restored arrays remain read-only after construction.
- pycsamt.forward.maxwell.mesh.skin_depth_m(resistivity_ohm_m, frequency_hz)[source]
Calculate electromagnetic skin depth for a non-magnetic conductor.
- Parameters:
resistivity_ohm_m (array-like) – Positive resistivity and frequency, broadcast using NumPy rules.
frequency_hz (array-like) – Positive resistivity and frequency, broadcast using NumPy rules.
- Returns:
Skin depth in metres,
sqrt(rho / (pi * mu0 * f)).- Return type:
ndarray
Examples
>>> round(float(skin_depth_m(100, 1))) 5033 >>> skin_depth_m([100, 400], 1).shape (2,)
- pycsamt.forward.maxwell.mesh.build_solver_mesh(grid, *, conductivity_s_m=None, resistivity_ohm_m=None, frequencies_hz, topography=None, design=None)[source]
Build a padded Maxwell mesh from a geological cell-centre model.
- Parameters:
grid (pycsamt.ai.geology.GeologyGrid) – Source grid in canonical geological order. Its upper cell edge must be depth zero, the reference used by topography and receiver coordinates.
conductivity_s_m (array-like or None) – Supply exactly one positive model shaped like
grid.resistivity_ohm_m (array-like or None) – Supply exactly one positive model shaped like
grid.frequencies_hz (sequence of float) – Frequencies used only for skin-depth quality diagnostics.
topography (pycsamt.ai.geology.TopographicSurface or None, optional) – Terrain aligned to
grid. When omitted, the geological top edge is treated as a flat earth surface.design (MeshDesign or None, optional) – Padding and quality configuration.
- Returns:
Padded conductivity, earth/air regions, core mapping, and diagnostics.
- Return type:
Examples
>>> from pycsamt.ai.geology import GeologyGrid >>> grid = GeologyGrid.regular_2d(nx=3, nz=2, dx_m=100, dz_m=50) >>> model = build_solver_mesh( ... grid, ... resistivity_ohm_m=np.full(grid.shape, 100), ... frequencies_hz=[10, 1], ... design=MeshDesign( ... horizontal_padding_cells=1, ... bottom_padding_cells=1, ... air_layers=1, ... ), ... ) >>> model.mesh.shape, model.core_slices ((4, 5), (slice(1, 3, None), slice(1, 4, None)))