volumential.interpolation#

Interpolation between box meshes and meshmode discretizations.

Interpolation from functions given by DoF vectors of meshmode. The underlying mesh on the meshmode side must be discretizing the same bounding box.

The intersection testing assumes a boundedness property for the supported element types: each element is bounded inside the smallest \(l^\infty\) ball that is centered at the element’s center and covers all its vertices. This property might be broken, for example, by high order elements that warp the element boundary too much.

class volumential.interpolation.ElementsToSourcesLookup(valuedict: Mapping[str, Any] | None = None, exclude: Sequence[str] | None = None, **kwargs: Any)[source]#

Bases: DeviceDataRecord

tree#

The boxtree.Tree instance representing the box mesh.

discr#

The meshmode.discretization.Discretization instance representing the external mesh and DoF distribution.

sources_in_element_starts#

Indices into sources_in_element_lists.

sources_in_element_lists[
    sources_in_element_starts[global_iel]
    :sources_in_element_starts[global_iel] + 1
    ]

contains the list of source nodes residing in the given element.

Note

global_iel is the global element id in meshmode. global_iel = mesh.groups[igrp].element_nr_base + iel.

sources_in_element_lists#

Indices into tree.sources.

class volumential.interpolation.LeavesToNodesLookup(valuedict: Mapping[str, Any] | None = None, exclude: Sequence[str] | None = None, **kwargs: Any)[source]#

Bases: DeviceDataRecord

trav#

The boxtree.traversal.FMMTraversalInfo instance representing the box mesh with metadata needed for interpolation. It contains a reference to the underlying tree as trav.tree.

discr#

The meshmode.discretization.Discretization instance representing the external mesh and DoF distribution.

nodes_in_leaf_starts#

Indices into nodes_in_leaf_lists.

nodes_in_leaf_lists[
    nodes_in_leaf_starts[box_id]:nodes_in_leaf_starts[box_id] + 1]

contains the list of discretization nodes residing in the given leaf box.

Note

Only leaf boxes have non-empty entries in this table. Nonetheless, this list is indexed by the global box index.

nodes_in_leaf_lists#

Indices into discr.nodes().

Note

Unlike ElementsToSourcesLookup, lists are not disjoint in the leaves-to-nodes lookup. volumential automatically computes the average contribution from overlapping boxes.

leaves_near_ball_starts#

Precomputed target-major lookup starts from the underlying area query, aligned with flattened discretization nodes.

leaves_near_ball_lists#

Precomputed target-major lookup lists from the underlying area query, aligned with flattened discretization nodes.

class volumential.interpolation.ElementsToSourcesLookupBuilder(context, tree, discr)[source]#

Bases: object

Given a meshmode mesh and a boxtree.Tree, both discretizing the same bounding box, this class helps to build a look-up table from element to source nodes that are positioned inside the element.

codegen_get_dimension_specific_snippets()[source]#

Dimension-dependent code loopy instructions.

get_simplex_lookup_kernel()[source]#

Returns a loopy kernel that computes a potential vector representing the (q_point –> element_id) relationship. When a source q_point lies on the element boundary, it will be assigned an element depending on code scheduling. This ensures that the resulting lookup lists are disjoint.

The kernel assumes that the mesh uses one single group of simplex elements. Also, the test only works for affine elements.

compute_short_lists(actx, wait_for=None)[source]#

balls –> overlapping leaves

class volumential.interpolation.LeavesToNodesLookupBuilder(context, trav, discr)[source]#

Bases: object

Given a meshmode mesh and a boxtree.Tree, both discretizing the same bounding box, this class helps to build a look-up table from leaf boxes to mesh nodes that are positioned inside the box.

volumential.interpolation.compute_affine_transform(source_simplex, target_simplex)[source]#

Computes A and b for the affine transform \(y = A x + b\) that maps source_simplex to target_simplex.

Parameters:
  • source_simplex – a dim-by-(dim+1) numpy array

  • target_simplex – a dim-by-(dim+1) numpy array

volumential.interpolation.invert_affine_transform(mat_a, disp_b)[source]#

Inverts an affine transform given by \(y = A x + b\).

Parameters:
  • mat_A – a dim*(dim+1)-by-dim*(dim+1) numpy array

  • disp_b – a dim*(dim+1) numpy array

volumential.interpolation.interpolate_from_meshmode(actx, dof_vec, elements_to_sources_lookup, order='tree')[source]#

Interpolate a DoF vector from meshmode.

Parameters:
  • dof_vec – a DoF vector representing a field in meshmode of shape (..., nnodes).

  • elements_to_sources_lookup – a ElementsToSourcesLookup.

  • order – order of the output potential, either “tree” or “user”.

Note

This function currently supports meshes with just one element group. Also, the element group must be simplex-based.

Note

Affine inverse mapping, basis tabulation, and local matrix-vector application are carried out by loopy kernels.

volumential.interpolation.interpolate_to_meshmode(actx, potential, leaves_to_nodes_lookup, order='tree')[source]#
Parameters:
  • potential – a DoF vector representing a field in volumential, in tree order.

  • leaves_to_nodes_lookup – a LeavesToNodesLookup.

  • order – order of the input potential, either “tree” or “user”.

Returns:

a pyopencl.array.Array of shape (nnodes, 1) containing the interpolated data.