Discretizations#

QBX discretization#

To compute a layer potential as an an end user, create a meshmode.discretization.Discretization with a meshmode.discretization.poly_element.InterpolatoryQuadratureSimplexGroupFactory as a discretization for the density.

Then create pytential.qbx.QBXLayerPotentialSource, pytential.bind() a layer potential operator to it, and you can start computing.

class pytential.qbx.QBXLayerPotentialSource(density_discr: ~meshmode.discretization.Discretization, fine_order: ~typing.Optional[int], qbx_order: ~typing.Optional[int] = None, fmm_order: ~typing.Optional[~typing.Union[bool, int]] = None, fmm_level_to_order: ~typing.Optional[~typing.Union[bool, ~typing.Callable[[...], int]]] = None, expansion_factory: ~typing.Optional[~sumpy.expansion.DefaultExpansionFactory] = None, target_association_tolerance: ~typing.Optional[float] = <class 'pytential.qbx._not_provided'>, debug: bool = True, _disable_refinement: bool = False, _expansions_in_tree_have_extent: bool = True, _expansion_stick_out_factor: float = 0.5, _max_leaf_refine_weight: ~typing.Optional[int] = None, _box_extent_norm: ~typing.Optional[str] = None, _tree_kind: str = 'adaptive', _well_sep_is_n_away: int = 2, _from_sep_smaller_crit: ~typing.Optional[str] = None, _from_sep_smaller_min_nsources_cumul: ~typing.Optional[int] = None, _use_target_specific_qbx: ~typing.Optional[bool] = None, geometry_data_inspector: ~typing.Optional[~typing.Callable[[...], bool]] = None, cost_model: ~typing.Optional[~pytential.qbx.cost.AbstractQBXCostModel] = None, fmm_backend: str = 'sumpy')[source]#

A source discretization for a QBX layer potential.

qbx_order#
fmm_order#
__init__(density_discr: ~meshmode.discretization.Discretization, fine_order: ~typing.Optional[int], qbx_order: ~typing.Optional[int] = None, fmm_order: ~typing.Optional[~typing.Union[bool, int]] = None, fmm_level_to_order: ~typing.Optional[~typing.Union[bool, ~typing.Callable[[...], int]]] = None, expansion_factory: ~typing.Optional[~sumpy.expansion.DefaultExpansionFactory] = None, target_association_tolerance: ~typing.Optional[float] = <class 'pytential.qbx._not_provided'>, debug: bool = True, _disable_refinement: bool = False, _expansions_in_tree_have_extent: bool = True, _expansion_stick_out_factor: float = 0.5, _max_leaf_refine_weight: ~typing.Optional[int] = None, _box_extent_norm: ~typing.Optional[str] = None, _tree_kind: str = 'adaptive', _well_sep_is_n_away: int = 2, _from_sep_smaller_crit: ~typing.Optional[str] = None, _from_sep_smaller_min_nsources_cumul: ~typing.Optional[int] = None, _use_target_specific_qbx: ~typing.Optional[bool] = None, geometry_data_inspector: ~typing.Optional[~typing.Callable[[...], bool]] = None, cost_model: ~typing.Optional[~pytential.qbx.cost.AbstractQBXCostModel] = None, fmm_backend: str = 'sumpy') None[source]#
Parameters:
  • fine_order – The total degree to which the (upsampled) underlying quadrature is exact.

  • fmm_order – Use False for direct calculation or an integer otherwise. May not be given (i.e. left as None) if fmm_level_to_order is given.

  • fmm_level_to_order – A callable that takes arguments of (kernel, kernel_args, tree, level) and returns the expansion order to be used on a given level of tree with kernel, where kernel is the sumpy.kernel.Kernel being evaluated, and kernel_args is a set of (key, value) tuples with evaluated kernel arguments. May not be given if fmm_order is given.

  • fmm_backend – a string denoting the desired FMM backend to use, either “sumpy” or “fmmlib”. Only used if fmm_order or fmm_level_to_order are provided.

  • expansion_factory – used to get local and multipole expansions for the FMM evaluations.

  • target_association_tolerance – passed on to pytential.qbx.target_assoc.associate_targets_to_qbx_centers().

Experimental arguments without a promise of forward compatibility:

Parameters:
copy(density_discr=None, fine_order=None, qbx_order=None, fmm_order=<class 'pytential.qbx._not_provided'>, fmm_level_to_order=<class 'pytential.qbx._not_provided'>, expansion_factory=None, target_association_tolerance=<class 'pytential.qbx._not_provided'>, _expansions_in_tree_have_extent=<class 'pytential.qbx._not_provided'>, _expansion_stick_out_factor=<class 'pytential.qbx._not_provided'>, _max_leaf_refine_weight=None, _box_extent_norm=None, _from_sep_smaller_crit=None, _tree_kind=None, _use_target_specific_qbx=<class 'pytential.qbx._not_provided'>, geometry_data_inspector=None, cost_model=<class 'pytential.qbx._not_provided'>, fmm_backend=None, debug=<class 'pytential.qbx._not_provided'>, _disable_refinement=<class 'pytential.qbx._not_provided'>)[source]#

See QBX internals for some information on the inner workings of this.

class pytential.qbx.QBXTargetAssociationFailedException(refine_flags, failed_target_flags, message)[source]#
refine_flags#
failed_target_flags#
class pytential.qbx.DefaultExpansionFactory[source]#

A expansion factory to create QBX local, local and multipole expansions

class pytential.qbx.NonFFTExpansionFactory[source]#

A expansion factory to create QBX local, local and multipole expansions with no FFT for multipole-to-local translations

Unregularized discretization#

class pytential.unregularized.UnregularizedLayerPotentialSource(density_discr, fmm_order=False, fmm_level_to_order=None, expansion_factory=None, debug=True)[source]#

A source discretization for a layer potential discretized with a Nyström method that uses element-based quadrature and does not modify the kernel.

fmm_level_to_order#

Sources#

class pytential.source.PotentialSource[source]#
preprocess_optemplate(name, discretizations, expr)[source]#
op_group_features(expr)#

Return a characteristic tuple by which operators that can be executed together can be grouped.

expr is a subclass of pytential.symbolic.primitives.IntG.

class pytential.source.PointPotentialSource(nodes)[source]#
nodes[source]#

An pyopencl.array.Array of shape [ambient_dim, ndofs].

ndofs#
cost_model_compute_potential_insn(actx, insn, bound_expr, evaluate, costs)[source]#
exec_compute_potential_insn(actx, insn, bound_expr, evaluate, return_timing_data)[source]#
class pytential.source.LayerPotentialSourceBase(density_discr)[source]#

A discretization of a layer potential using element-based geometry, with support for refinement and upsampling.

Discretization data

density_discr#
cl_context#
ambient_dim#
dim#
real_dtype#
complex_dtype#

Targets#

Target discretizations are a simpler version of the full meshmode.discretization.Discretization interface. They do not provide any evaluation of integrals, norms, or layer potentials, but are instead only geared towards being used as evaluation targets.

class pytential.target.TargetBase[source]#
ambient_dim#
nodes()#

Shape: [ambient_dim, ndofs]

ndofs#
class pytential.target.PointsTarget(nodes, normals=None)[source]#

The point of this class is to act as a container for some target points while presenting enough of the meshmode.discretization.Discretization interface to not necessitate a lot of special cases in that code path.

Geometry Collection#

class pytential.collection.GeometryLike#

Types accepted by the GeometryCollection.

class pytential.collection.GeometryCollection(places: Union[pytential.collection.GeometryLike, Tuple[pytential.collection.GeometryLike, pytential.collection.GeometryLike], Dict[Hashable, pytential.collection.GeometryLike]], auto_where: Optional[Union[pytential.symbolic.dof_desc.DOFDescriptorLike, Tuple[pytential.symbolic.dof_desc.DOFDescriptorLike, pytential.symbolic.dof_desc.DOFDescriptorLike]]] = None)[source]#

A mapping from symbolic identifiers (“place IDs”, typically strings) to ‘geometries’, where a geometry can be a PotentialSource, a TargetBase or a Discretization.

This class is meant to hold a specific combination of sources and targets serve to host caches of information derived from them, e.g. FMM trees of subsets of them, as well as related common subexpressions such as metric terms.

Refinement of pytential.qbx.QBXLayerPotentialSource entries is performed on demand, i.e. on calls to get_discretization() with a specific discr_stage. To perform refinement explicitly, call pytential.qbx.refinement.refine_geometry_collection(), which allows more customization of the refinement process through parameters.

__init__(places: Union[pytential.collection.GeometryLike, Tuple[pytential.collection.GeometryLike, pytential.collection.GeometryLike], Dict[Hashable, pytential.collection.GeometryLike]], auto_where: Optional[Union[pytential.symbolic.dof_desc.DOFDescriptorLike, Tuple[pytential.symbolic.dof_desc.DOFDescriptorLike, pytential.symbolic.dof_desc.DOFDescriptorLike]]] = None) None[source]#
Parameters:
  • places – a scalar, tuple of or mapping of symbolic names to geometry objects. Supported objects are PotentialSource, TargetBase and Discretization. If this is a mapping, the keys that are strings must be valid Python identifiers. The tuple should contain only two entries, denoting the source and target geometries for layer potential evaluation, identified by auto_where.

  • auto_where – a single or a tuple of two DOFDescriptors, or values that can be converted to one using as_dofdesc(). The two descriptors are used to define the default source and target geometries for layer potential evaluations. By default, they are set to DEFAULT_SOURCE and DEFAULT_TARGET for sources and targets, respectively.

auto_source#

Default DOFDescriptor for the source geometry.

auto_target#

Default DOFDescriptor for the target geometry.

get_geometry(geometry: Hashable) pytential.collection.GeometryLike[source]#
Parameters:

geometry – the identifier of the geometry in the collection.

get_discretization(geometry: Hashable, discr_stage: Optional[pytential.symbolic.dof_desc.DiscretizationStages] = None) pytential.collection.GeometryLike[source]#

Get the geometry or discretization in the collection.

If a specific QBX stage discretization is requested, refinement is performed on demand and cached for subsequent calls.

Parameters:
Returns:

a geometry object in the collection or a Discretization corresponding to discr_stage.

get_connection(from_dd: pytential.symbolic.dof_desc.DOFDescriptorLike, to_dd: pytential.symbolic.dof_desc.DOFDescriptorLike)[source]#

Construct a connection from from_dd to to_dd geometries.

Returns:

an object compatible with the DiscretizationConnection interface.

copy(places: Optional[Dict[Hashable, pytential.collection.GeometryLike]] = None, auto_where: Optional[Union[pytential.symbolic.dof_desc.DOFDescriptorLike, Tuple[pytential.symbolic.dof_desc.DOFDescriptorLike, pytential.symbolic.dof_desc.DOFDescriptorLike]]] = None) GeometryCollection[source]#

Get a shallow copy of the geometry collection.

merge(places: Union[GeometryCollection, Dict[Hashable, pytential.collection.GeometryLike]]) GeometryCollection[source]#

Merges two geometry collections and returns the new collection.

Parameters:

places – a dict or GeometryCollection to merge with the current collection. If it is empty, a copy of the current collection is returned.

pytential.collection.add_geometry_to_collection(places: GeometryCollection, geometries: Dict[Hashable, pytential.collection.GeometryLike]) GeometryCollection[source]#

Adds a dict of geometries to an existing collection.

This function is similar to GeometryCollection.merge(), but it makes an attempt to maintain the caches in places. In particular, a shallow copy of the following are pased to the new collection

  • Any cached discretizations from refine_geometry_collection().

  • Any cached expressions marked with cse_scope.DISCRETIZATION from the evaluation mapper.

This allows adding new targets to the collection without recomputing the source geometry data.