Mondaic

salvus.mesh.algorithms.unstructured_mesh.metrics

salvus.mesh.algorithms.unstructured_mesh.metrics salvus mesh algorithms unstructured_mesh metrics

Metrics for unstructured meshes.

Functions

compute_determinants()

def compute_determinants(mesh: UnstructuredMesh) -> npt.NDArray: ...

Compute the determinant of the Jacobian for each element in the mesh.

Parameters
  • mesh UnstructuredMesh — The mesh to compute it for.
Returns npt.NDArray

compute_max_velocity_per_element()

def compute_max_velocity_per_element(
    mesh: UnstructuredMesh,
) -> npt.NDArray: ...

Return the per-element maximum P-wave speed from material fields.

This mirrors what SalvusCompute does internally when computing the time step on the solver side: for each element the maximum P-wave velocity is derived from the element’s material coefficients, and the parametrization is selected by which fields are attached to the mesh.

Recognized parametrizations, in order of preference:

  1. VP (isotropic, velocity form).
  2. VPV and VPH (anisotropic, velocity form) — uses max(VPV, VPH).
  3. LAMBDA, MU, RHO (isotropic elastic, linear form) — uses sqrt((lambda + 2 * mu) / rho).
  4. M0, M1 (acoustic, linear form) — uses sqrt(M1 / M0).

Fully anisotropic Cij parametrizations are currently not supported (the solver extracts the maximum eigenvalue of the elastic tensor per DOF).

Parameters
  • mesh UnstructuredMesh — The mesh whose material fields are inspected.
Returns npt.NDArray — The per-element maximum P-wave velocity, shape (mesh.nelem,).

compute_maximum_edge_length_per_element()

def compute_maximum_edge_length_per_element(
    mesh: UnstructuredMesh, mask: npt.NDArray | None = None
) -> npt.NDArray: ...

Return the max edge size for each element.

Parameters
  • mesh UnstructuredMesh — The mesh to compute it for.
  • mask npt.NDArray | None — Apply a mask on the connectivity.
Returns npt.NDArray

compute_mesh_quality()

def compute_mesh_quality(
    mesh: UnstructuredMesh, quality_metric: str = "edge_aspect_ratio"
) -> npt.NDArray: ...

Compute a few proxies for for mesh quality.

Parameters
  • mesh UnstructuredMesh — The mesh to compute it for.
  • quality_metric str — The quality metric to compute. Currently supported metrics include edge_aspect_ratio, equiangular_skewness, and scaled_jacobian.
Returns npt.NDArray

compute_minimum_edge_length_per_element()

def compute_minimum_edge_length_per_element(
    mesh: UnstructuredMesh,
    mask: npt.NDArray | None = None,
    direction: int | None = None,
    shape_order: int | None = None,
) -> npt.NDArray: ...

Compute the smallest edge-length in an element.

Assumes a first order shape approximation.

Parameters
  • mesh UnstructuredMesh — The mesh to compute it for.
  • mask npt.NDArray | None — Optional mask to only compute it for a subset of elements. True includes elements.
  • direction int | None — Shortest edge-length along a given direction of the reference element in reference coordinates.
  • shape_order int | None — Override shape order for edge length computation.
Returns npt.NDArray

compute_minimum_gll_distance()

def compute_minimum_gll_distance(
    mesh: UnstructuredMesh,
    shape_order: int,
    execution_policy: bindings.ExecutionPolicy = salvus._core.lib.salvus_core_python_bindings.ExecutionPolicy,
    use_bindings: bool = True,
) -> npt.NDArray: ...

Compute the minimum distance between GLL points per element.

Although the mesh is defined at a specific order, the GLL spacing may be computed at any arbitrary order. This is useful when computing spacing for higher order shape functions. For example, Salvus by default uses fourth order shape functions for the wavefield, unless explicitly changed in e.g.:

sn.WaveformSimulationConfiguration(
    spectral_element_order=spectral_element_order,
    ...,
)

To get the spacing required for computing the CFL criterion in those cases, one would need the minimum GLL distance for fourth order shape functions, even if the mesh is first order.

Parameters
  • mesh UnstructuredMesh — The mesh to compute the minimum GLL distance for.
  • shape_order int — The shape order to use for the GLL points.
  • execution_policy bindings.ExecutionPolicy — The execution policy to use for C++ bindings.
  • use_bindings bool — Whether to use the C++ bindings for improved performance.
Returns npt.NDArray — The minimum GLL distance for each element.

compute_minimum_time_step_across_meshes()

def compute_minimum_time_step_across_meshes(
    meshes: list[UnstructuredMesh],
    courant_number: float | None = None,
    simulation_order: int | None = None,
    execution_policy: bindings.ExecutionPolicy = salvus._core.lib.salvus_core_python_bindings.ExecutionPolicy,
    use_bindings: bool = True,
) -> float: ...

Compute the minimum time step across multiple meshes.

This function iterates over a list of meshes and computes the minimum time step of each one using the compute_time_step function. The lowest time step across all of the queried meshes is then returned.

This is useful for cases where one wishes to use a common time axis across multiple simulations, e.g. for visualizations.

Parameters
  • meshes list[UnstructuredMesh] — A list of meshes to compute the minimum time step for.
  • courant_number float | None — The Courant number to use for the CFL condition.
  • simulation_order int | None — The shape order to use for the time step computation.
  • execution_policy bindings.ExecutionPolicy — The execution policy to use for C++ bindings.
  • use_bindings bool — Whether to use the C++ bindings for improved performance.
Returns float — The minimum time step across all meshes.

compute_time_step()

def compute_time_step(
    mesh: UnstructuredMesh,
    max_velocity: npt.NDArray | float,
    courant_number: float | None = None,
    simulation_order: int | None = None,
    attach: bool = False,
    execution_policy: bindings.ExecutionPolicy = salvus._core.lib.salvus_core_python_bindings.ExecutionPolicy,
    use_bindings: bool = True,
) -> tuple[float, npt.NDArray]: ...

Compute the time step for the given mesh and velocity.

The time step is estimated by means of the Courant-Friedrichs-Lewy (CFL) condition, which relates the time step to the spatial discretization and the wave propagation speed. This implementation accounts for deformed higher-order element.

Note that this implementation by defaults uses a shape order of 4 if not specified. This is the default order at which Salvus parametrizes wavefields, but can be changed by e.g.:

sn.WaveformSimulationConfiguration(
    spectral_element_order=spectral_element_order,
    ...,
)

The Courant-number in the CFL condition defaults to 0.6 for 2D meshes and 0.47 for 3D meshes.

Parameters
  • mesh UnstructuredMesh — The mesh to compute the time step for.
  • max_velocity npt.NDArray | float — The maximum velocity to use for the time step computation. Can be passed globally or per element.
  • courant_number float | None — The Courant number to use for the CFL condition.
  • simulation_order int | None — The shape order to use for the time step computation.
  • attach bool — Whether to attach the computed time step to the mesh. Will raise an error if the field time_step is already attached.
  • execution_policy bindings.ExecutionPolicy — The execution policy to use for C++ bindings.
  • use_bindings bool — Whether to use the C++ bindings for improved performance.
Returns tuple[float, npt.NDArray] — The global minimum time step and the minimum time step per element.

estimate_resolved_frequency()

def estimate_resolved_frequency(
    mesh: UnstructuredMesh,
    min_velocity: npt.NDArray,
    elements_per_wavelength: float,
) -> tuple[float, npt.NDArray]: ...

Estimate the highest resolved frequency in each element.

Parameters
  • mesh UnstructuredMesh — The mesh to compute it for.
  • min_velocity npt.NDArray — Minimum velocity in each element.
  • elements_per_wavelength float — The elements per wavelength.
Returns tuple[float, npt.NDArray]

estimate_time_step()

def estimate_time_step(
    mesh: UnstructuredMesh,
    max_velocity: npt.NDArray | float,
    courant_number: float = 1.0,
    min_gll_point_distance: float = 1.0,
    fast: bool = True,
    return_hmin_elemnodes: bool = False,
    shape_order: int | None = None,
    execution_policy: bindings.ExecutionPolicy = salvus._core.lib.salvus_core_python_bindings.ExecutionPolicy,
) -> tuple[float, npt.NDArray] | tuple[float, npt.NDArray, npt.NDArray]: ...

Compute an estimation of the time step set by each element.

This function is deprecated in favor of compute_time_step, which uses more appropriate defaults and a simplified API.

The time step is estimated by means of the Courant-Friedrichs-Lewy (CFL) condition, which relates the time step to the spatial discretization and the wave propagation speed. This method is an estimation, as it does not fully account for heavily deformed elements.

Parameters
  • mesh UnstructuredMesh — The mesh to compute the time step for.
  • max_velocity npt.NDArray | float — Fastest velocity overall or per element. If the velocities are heterogeneous, more accurate (and less conservative) estimates will be provided by passing the varying velocities.
  • courant_number float — The Courant number to use in the CFL-criterion.
  • min_gll_point_distance float — The minimum distance between GLL points.
  • fast bool — Whether to use the fast estimation method.
  • return_hmin_elemnodes bool — Whether to return the minimum within-element distances.
  • shape_order int | None — Override shape order for edge length computation. Useful, as Salvus meshes and wavefields are not necessarily defined at the same order. By default, Salvus will define wavefields on fourth order shape functions.
  • execution_policy bindings.ExecutionPolicy — The execution policy to use for C++ bindings.
Returns tuple[float, npt.NDArray] | tuple[float, npt.NDArray, npt.NDArray]

Used in tutorials