Version:

salvus.mesh.tools.transforms

salvus.mesh.tools.transforms salvus mesh tools transforms
A set of tools to transform meshes and the models they contain.

Functions

interpolate_mesh_to_mesh()

Interpolate element nodal material parameters from mesh_0 to mesh_1.
It is often desirable to interpolate material parameters from one mesh to another. This may be relevant, for example, when changing frequency bands in an ongoing full-waveform inversion, when performing a convergence analysis, when comparing the efficacy of different models, and when using advanced waveform inversion methodologies (i.e. Smoothiesem). In simplest case of a rectilinear -> rectilinear mesh the interpolation is relatively straightforward: interpolate the model stored on mesh_0 to mesh_1 by evaluating the model on mesh_0's basis at the points defined by mesh_1.
For the case of deformed meshes, or models with discontinuities that must be preserved, the story gets a little more complicated. For example: what if the resolution of the new mesh's topography is different than that of the old mesh? In this case, you may get aliasing around the discontinuities or along mesh edges. To remedy issues like this, this function implements several heuristic measures, which can be toggled by selecting the corresponding function arguments (see their descriptions).
As a general rule: any required extrapolations will be performed via a "clamping" approach, where the reference coordinates for a candidate model source element with be clamped to the reference interval [-1, +1]. This helps mitigate any "blow-ups" that could occur by evaluating the model basis too far outside of a given element. In the end, this means that the interpolation performed by this function may not be well defined in some cases. However, we feel that the measures chosen mitigate the most substantial issues, and should be sufficient for most use cases.
SIGNATURE
def interpolate_mesh_to_mesh(
    mesh_0: UnstructuredMesh,
    mesh_1: UnstructuredMesh,
    use_layers: bool,
    use_1d_vertical_coordinate: bool,
    verbose: bool = True,
    exclude_filter: tuple[str, int] | None = None,
    fields_to_interpolate: str | list[str] | None = None,
) -> UnstructuredMesh: ...
ARGUMENTS
Required
mesh_0
Type:UnstructuredMesh
Description:
Source mesh (interpolate parameters from here).
Required
mesh_1
Type:UnstructuredMesh
Description:
Destination mesh (interpolate parameters to here).
Required
use_layers
Type:bool
Description:
Search for the elemental parameter layer in both meshes and, if it exists, restrict the interpolation to matching layers. Useful (in fact, likely essential) when working with models containing discontinuities which should be preserved. Will throw is use_layers is not present as an element nodal field in either mesh.
Required
use_1d_vertical_coordinate
Type:bool
Description:
Search for the element nodal parameter z_node_1D in both meshes and, if it exists, use it to "flatten" any topography before the interpolation occurs. Setting this to true is consistent with what happens when doing certain model interpolations, for instance when considering the interpolation of a MantleModel or a CrustalModel. In those cases the models are interpolated using the spherical 1-D radial coordinate before topographic deformations are applied.
Optional
verbose
Type:bool
Default value:True
Description:
Print a progress bar outlining the overall progress of the interpolation routine. Defaults to True.
Optional
exclude_filter
Type:tuple[str, int] | None
Default value:None
Description:
Exclude from the interpolation elements which have a a certain elemental flag set as an elemental_field. A tuple should be passed containing ("elemental_field_name", field value). Elements flagged will be excluded from the interpolation in both meshes.
Optional
fields_to_interpolate
Type:str | list[str] | None
Default value:None
Description:
Optional list of fields to interpolate. If not given, all valid material parameters defined on mesh_0 will be interpolated.
EXCEPTIONS
ValueError
If use_1d_vertical_coordinate is toggled, but "z_node_1D" does not exist as an element nodal field in either mesh.
ValueError
If use_1d_vertical_coordinate is toggled, but the maximum values of "z_node_1D" are different between meshes.
ValueError
If use_1d_vertical_coordinate is toggled, but the "reference_frame" global variable is not present in either mesh, or if it varies between meshes.
ValueError
If use_layers is toggled, but the "layer" parameter is not present as an elemental variable in either mesh
RETURNS
Return type: UnstructuredMesh
An unstructured mesh with the parameters from mesh_0 interpolated onto the topology of mesh_1.

uniformly_refine()

Refine an unstructured mesh by subdividing all elements uniformly.
This function works by splitting each element evenly into 4 elements in 2-D, and 8 elements in 3-D, resulting in a new mesh with exactly 4 or 8 times as many elements as were present before. Model re-interpolation (of element-nodal fields) from and to arbitrary tensor_orders are supported. Elemental fields and global variables are copied over as well.
A common and practical use case for this function is to increase the frequency band of an ongoing inversion.
SIGNATURE
def uniformly_refine(
    mesh: UnstructuredMesh,
    tensor_order: int,
    refinement_order: int = 2,
    change_tensor_order_kwargs: dict | None = None,
    use_high_order_node_locations: bool = True,
) -> UnstructuredMesh: ...
ARGUMENTS
Required
mesh
Type:UnstructuredMesh
Description:
The mesh which should be refined.
Required
tensor_order
Type:int
Description:
The tensor_order of the new refined mesh.
Optional
refinement_order
Type:int
Default value:2
Description:
The number of subdivisions per dimension, e.g. 2 will lead to a subdivision of a hex into 8 hexes or a quad into 4 quads
Optional
change_tensor_order_kwargs
Type:dict | None
Default value:None
Description:
internally, UnstructuredMesh.change_tensor_order() is used to create the new points as well as to set the tensor order of the new mesh. This dictionary can be used to pass additional arguments such as for spherical interpolation. See the docstring of change_tensor_order for details.
Optional
use_high_order_node_locations
Type:bool
Default value:True
Description:
create new nodes based on the high order shape of the original mesh. Cannot be used together with change_tensor_order_kwargs.
RETURNS
Return type: UnstructuredMesh
A new unstructured mesh, uniformly refined with the model re-interpolated and the relevant variables copied over.

uniformly_refine_chunkwise()

Refine an unstructured mesh by subdividing all elements uniformly, working through the mesh in chunks to avoid a memory bottleneck. The mesh is merged and directly written to a file.
See docstring of uniformly_refine for more details
SIGNATURE
def uniformly_refine_chunkwise(
    mesh: UnstructuredMesh,
    output_filename: str,
    nchunk: int = 10,
    show_progress: bool = True,
    uniformly_refine_kwargs: dict | None = None,
) -> None: ...
ARGUMENTS
Required
mesh
Type:UnstructuredMesh
Description:
The mesh which should be refined.
Required
output_filename
Type:str
Description:
Filename of the mesh file (h5 format).
Optional
nchunk
Type:int
Default value:10
Description:
The number of chunks to use.
Optional
show_progress
Type:bool
Default value:True
Description:
show a progress bar while refining & merging.
Optional
uniformly_refine_kwargs
Type:dict | None
Default value:None
Description:
dictionary of arguments passed to uniformly_refine

Used in tutorials

Functionality from this module is used in the following tutorials.
PAGE CONTENTS