# QBX internals¶

Note

This page documents pytential internals and is not typically needed in end-user applications.

## Refinement¶

The refiner takes a layer potential source and refines it until it satisfies three global QBX refinement criteria:

• Condition 1 (Expansion disk undisturbed by sources)

A center must be closest to its own source.

• Condition 2 (Sufficient quadrature sampling from all source panels)

The quadrature contribution from each panel is as accurate as from the center’s own source panel.

• Condition 3 (Panel size bounded based on kernel length scale)

The panel size is bounded by a kernel length scale. This applies only to Helmholtz kernels.

### Warnings emitted by refinement¶

class pytential.qbx.refinement.RefinerNotConvergedWarning[source]

### Helper functions¶

pytential.qbx.refinement.make_empty_refine_flags(queue, lpot_source, use_stage2_discr=False)[source]

Return an array on the device suitable for use as element refine flags.

Parameters
Returns

A pyopencl.array.Array suitable for use as refine flags, initialized to zero.

### Refiner driver¶

class pytential.qbx.refinement.RefinerCodeContainer(cl_context, tree_code_container)[source]
class pytential.qbx.refinement.RefinerWrangler(code_container, queue)[source]
pytential.qbx.refinement.refine_for_global_qbx(lpot_source, wrangler, group_factory, kernel_length_scale=None, force_stage2_uniform_refinement_rounds=None, scaled_max_curvature_threshold=None, debug=None, maxiter=None, visualize=None, expansion_disturbance_tolerance=None, refiner=None)[source]

Entry point for calling the refiner.

Parameters
• lpot_source – An instance of QBXLayerPotentialSource.

• wrangler – An instance of RefinerWrangler.

• group_factory – An instance of meshmode.mesh.discretization.ElementGroupFactory. Used for discretizing the coarse refined mesh.

• kernel_length_scale – The kernel length scale, or None if not applicable. All panels are refined to below this size.

• maxiter – The maximum number of refiner iterations.

Returns

A tuple (lpot_source, *conn*) where lpot_source is the refined layer potential source, and conn is a meshmode.discretization.connection.DiscretizationConnection going from the original mesh to the refined mesh.

## Target association¶

The goal of target association is to:
• decide which targets require QBX,

• decide which centers to use for targets that require QBX,

• if no good centers are available for a target that requires QBX, flag the appropriate panels for refinement.

### Requesting a target side¶

A target may further specify how it should be treated by target association.

Values for target side requests

Value

Meaning

0

Volume target. If near a QBX center, the value from the QBX expansion is returned, otherwise the volume potential is returned.

-1

Surface target. Return interior limit from interior-side QBX expansion.

+1

Surface target. Return exterior limit from exterior-side QBX expansion.

-2

Volume target. If within an interior QBX disk, the value from the QBX expansion is returned, otherwise the volume potential is returned.

+2

Volume target. If within an exterior QBX disk, the value from the QBX expansion is returned, otherwise the volume potential is returned.

### Return values¶

class pytential.qbx.target_assoc.QBXTargetAssociation(valuedict=None, exclude=None, **kwargs)[source]
target_to_center

### Target association driver¶

class pytential.qbx.target_assoc.TargetAssociationCodeContainer(cl_context, tree_code_container)[source]
class pytential.qbx.target_assoc.TargetAssociationWrangler(code_container, queue)[source]
pytential.qbx.target_assoc.associate_targets_to_qbx_centers(lpot_source, wrangler, target_discrs_and_qbx_sides, target_association_tolerance, debug=True, wait_for=None)[source]

Associate targets to centers in a layer potential source.

Parameters
• lpot_source – An instance of QBXLayerPotentialSource

• wrangler – An instance of TargetAssociationWrangler

• target_discrs_and_qbx_sides

a list of tuples (discr, sides), where discr is a pytential.discretization.Discretization or a pytential.discretization.target.TargetBase instance, and sides is either a int or an array of (numpy.int8) side requests for each target.

The side request can take on the values in Values for target side requests.

Raises

pytential.qbx.QBXTargetAssociationFailedException – when target association failed to find a center for a target. The returned exception object contains suggested refine flags.

Returns

## Data structures describing geometry¶

For each invocation of the QBX FMM with a distinct set of (target, side request) pairs, pytential.qbx.QBXLayerPotentialSource creates an instance of QBXFMMGeometryData.

The module is described in top-down fashion, with the (conceptually) highest-level objects first.

### Geometry data¶

class pytential.qbx.geometry.QBXFMMGeometryData(code_getter, lpot_source, target_discrs_and_qbx_sides, target_association_tolerance, tree_kind, debug)[source]

Attributes

code_getter

The QBXFMMGeometryCodeGetter for this object.

lpot_source

The pytential.qbx.QBXLayerPotentialSource acting as the source geometry.

target_discrs_and_qbx_sides

a list of tuples (discr, sides), where discr is a pytential.discretization.Discretization or a pytential.discretization.target.TargetBase instance, and sides is an array of (numpy.int8) side requests for each target.

The side request can take on the values found in Values for target side requests.

cl_context
coord_dtype

Expansion centers

ncenters
centers()[source]

Return an object array of (interleaved) center coordinates.

coord_t [ambient_dim][ncenters]

Methods

target_info()[source]

Return a TargetInfo. Output is cached. Use obj.<method_name>.clear_cache(obj) to clear.

tree()[source]

Build and return a boxtree.tree.Tree for this source with these targets.

Output is cached. Use obj.<method_name>.clear_cache(obj) to clear.

traversal()[source]
Parameters

merge_close_lists – Use merged close lists. (See boxtree.traversal.FMMTraversalInfo.merge_close_lists())

Output is cached. Use obj.<method_name>.clear_cache(obj) to clear.

qbx_center_to_target_box()[source]

Return a lookup table of length ncenters indicating the target box in which each QBX disk is located.

Output is cached. Use obj.<method_name>.clear_cache(obj) to clear.

global_qbx_flags()[source]

Return an array of numpy.int8 of length ncenters indicating whether each center can use gloal QBX, i.e. whether a single expansion can mediate interactions from all sources to all targets for which it is valid. If global QBX can be used, the center’s entry will be 1, otherwise it will be 0.

(If not, local QBX is needed, and the center may only be able to mediate some of the interactions to a given target.)

Output is cached. Use obj.<method_name>.clear_cache(obj) to clear.

global_qbx_centers()[source]

Build a list of indices of QBX centers that use global QBX. This indexes into the global list of targets, (see target_info()) of which the QBX centers occupy the first ncenters.

Centers without any associated targets are excluded.

user_target_to_center()[source]

Find which QBX center, if any, is to be used for each target. target_state.NO_QBX_NEEDED if none. target_state.FAILED if a center needs to be used, but none was found. See center_to_tree_targets() for the reverse look-up table.

Shape: [ntargets] of boxtree.Tree.particle_id_dtype, with extra values from target_state allowed. Targets occur in user order.

center_to_tree_targets()[source]

Return a CenterToTargetList. See target_to_center() for the reverse look-up table with targets in user order.

Output is cached. Use obj.<method_name>.clear_cache(obj) to clear.

non_qbx_box_target_lists()[source]

Build a list of targets per box that don’t need to bother with QBX. Returns a boxtree.tree.FilteredTargetListsInTreeOrder. (I.e. a new target order is created for these targets, as we expect there to be many of them.)

Output is cached. Use obj.<method_name>.clear_cache(obj) to clear.

plot()[source]

Plot most of the information contained in a QBXFMMGeometryData object, for debugging.

Parameters

highlight_centers – If not None, an object with which the array of centers can be indexed to find the highlighted centers.

Note

This only works for two-dimensional geometries.

The following methods implement the boxtree.pyfmmlib_integration.FMMLibRotationDataInterface.

m2l_rotation_lists()[source]
m2l_rotation_angles()[source]

Constructor arguments

See the attributes of the same name for the meaning of most of the constructor arguments.

Parameters
• tree_kind – The tree kind to pass to the tree builder

• debug – a bool flag for whether to enable potentially costly self-checks

### Subordinate data structures¶

class pytential.qbx.geometry.TargetInfo[source]

Describes the internal structure of the QBX FMM’s list of targets. The list consists of QBX centers, then target points for each target discretization. The starts of the target points for each target discretization are given by target_discr_starts.

targets

Shape: [dim,ntargets]

target_discr_starts

Shape: [ndiscrs+1]

Start indices of targets for each target discretization.

The first entry here is the start of the targets for the first target discretization. (The QBX centers start at index 0, a fact which is not explicitly represented.)

ntargets
class pytential.qbx.geometry.CenterToTargetList[source]

A lookup table of targets covered by each QBX disk. Indexed by global number of QBX center, lists[start[i]:start[i+1]] indicates numbers of the overlapped targets in tree target order.

starts

Shape: [ncenters+1]

lists

Lists of targets in tree order. Use with starts.

### Enums of special values¶

class pytential.qbx.geometry.target_state[source]

This enumeration contains special values that are used in the array returned by QBXFMMGeometryData.target_to_center().

NO_QBX_NEEDED
FAILED

The code is unable to compute an accurate potential for this target. This happens if it is determined that QBX is required to compute an accurate potential, but no suitable center is found.

### Geometry description code container¶

class pytential.qbx.geometry.QBXFMMGeometryCodeGetter(cl_context, ambient_dim, tree_code_container, debug, _well_sep_is_n_away, _from_sep_smaller_crit)[source]
property build_leaf_to_ball_lookup
property build_traversal
copy_targets_kernel()[source]
filter_center_and_target_ids(particle_id_dtype)[source]
property key_value_sort
property pick_used_centers
qbx_center_to_target_box_lookup(particle_id_dtype, box_id_dtype)[source]
property rotation_classes_builder

## Fast multipole driver¶

class pytential.qbx.fmm.QBXSumpyExpansionWranglerCodeContainer(cl_context, multipole_expansion_factory, local_expansion_factory, qbx_local_expansion_factory, out_kernels)[source]
Parameters
• multipole_expansion_factory – a callable of a single argument (order) that returns a multipole expansion.

• local_expansion_factory – a callable of a single argument (order) that returns a local expansion.

• out_kernels – a list of output kernels

• exclude_self – whether the self contribution should be excluded

class pytential.qbx.fmm.QBXExpansionWrangler(code_container, queue, geo_data, dtype, qbx_order, fmm_level_to_order, source_extra_kwargs, kernel_extra_kwargs, _use_target_specific_qbx=None)[source]

A specialized implementation of the boxtree.fmm.ExpansionWranglerInterface for the QBX FMM. The conventional (‘point’) FMM is carried out on a filtered set of targets (see pytential.discretization.qbx.geometry.QBXFMMGeometryData.non_qbx_box_target_lists()), and thus all non-QBX potential arrays handled by this wrangler don’t include all targets in the tree, just the non-QBX ones.

QBX-specific methods

form_global_qbx_locals(src_weights)[source]
translate_box_local_to_qbx_local(local_exps)[source]
eval_qbx_expansions(qbx_expansions)[source]
pytential.qbx.fmm.drive_fmm(expansion_wrangler, src_weights, timing_data=None, traversal=None)[source]

Top-level driver routine for the QBX fast multipole calculation.

Parameters
• geo_data – A QBXFMMGeometryData instance.

• expansion_wrangler – An object exhibiting the ExpansionWranglerInterface.

• src_weights – Source ‘density/weights/charges’. Passed unmodified to expansion_wrangler.

• timing_data – Either None or a dictionary that collects timing data.

Returns the potentials computed by expansion_wrangler.

See also boxtree.fmm.drive_fmm().

## Cost model¶

Note

This module is experimental. Its interface is subject to change until this notice is removed.

class pytential.qbx.cost.CostModel(translation_cost_model_factory=<function pde_aware_translation_cost_model>, calibration_params=None)[source]
with_calibration_params(calibration_params)[source]

Return a copy of self with a new set of calibration parameters.

__call__(wrangler, geo_data, kernel, kernel_arguments)[source]

Analyze the given geometry and return cost data.

Returns

An instance of ParametrizedCosts.

The cost model relies on a translation cost model. See TranslationCostModel for the translation cost model interface.

Parameters

translation_cost_model_factory – A callable which, given arguments (dim, nlevels), returns a TranslationCostModel.

class pytential.qbx.cost.ParametrizedCosts(raw_costs, params)[source]

A container for data returned by the cost model.

This holds both symbolic costs as well as parameter values. To obtain a prediction of the running time, use get_predicted_times().

raw_costs

A dictionary mapping algorithmic stage names to symbolic costs.

params

A dictionary mapping names of symbolic parameters to values. Parameters appear in raw_costs and may include values such as QBX or FMM order as well as calibration constants.

copy()[source]
with_params(params)[source]

Return a copy of self with parameters updated to include params.

get_predicted_times(merge_close_lists=False)[source]

Return a dictionary mapping stage names to predicted time in seconds.

Parameters

merge_close_lists – If True, the returned estimate combines the cost of “close” lists (Lists 1, 3 close, and 4 close). If False, the time of each “close” list is reported separately.

class pytential.qbx.cost.TranslationCostModel(ncoeffs_qbx, ncoeffs_fmm_by_level, uses_point_and_shoot)[source]

Provides modeled costs for individual translations or evaluations.

pytential.qbx.cost.pde_aware_translation_cost_model(dim, nlevels)[source]

Create a cost model for FMM translation operators that make use of the knowledge that the potential satisfies a PDE.

pytential.qbx.cost.taylor_translation_cost_model(dim, nlevels)[source]

Create a cost model for FMM translation based on Taylor expansions in Cartesian coordinates.

pytential.qbx.cost.estimate_calibration_params(model_results, timing_results)[source]

Given a set of model results and matching timing results, estimate the best calibration parameters for the model.