diff --git a/examples/laplace-dirichlet-3d.py b/examples/laplace-dirichlet-3d.py index 4166dddfa8d8e1606885e167fa65a8881fe64484..db93fadff90cc35b5eed01cdb5ce1ae7180c769c 100644 --- a/examples/laplace-dirichlet-3d.py +++ b/examples/laplace-dirichlet-3d.py @@ -66,7 +66,7 @@ def main(): QBXLayerPotentialSource, QBXTargetAssociationFailedException) qbx, _ = QBXLayerPotentialSource( pre_density_discr, fine_order=bdry_ovsmp_quad_order, qbx_order=qbx_order, - fmm_order=fmm_order + fmm_order=fmm_order, ).with_refinement() density_discr = qbx.density_discr diff --git a/pytential/qbx/fmmlib.py b/pytential/qbx/fmmlib.py index 2d21a3d2ac6865d0d8d3c3d3f41c388b0fe160b0..0cda4945db781af8582c88578177a840fb18b552 100644 --- a/pytential/qbx/fmmlib.py +++ b/pytential/qbx/fmmlib.py @@ -120,6 +120,16 @@ class ToHostTransferredGeoDataWrapper(object): """All (not just non-QBX) targets packaged into a single array.""" return np.array(list(self.tree().targets)) + @memoize_method + def m2l_rotation_angles(self): + # Already on host + return self.geo_data.m2l_rotation_angles() + + @memoize_method + def m2l_rotation_lists(self): + # Already on host + return self.geo_data.m2l_rotation_lists() + # }}} @@ -136,8 +146,9 @@ class QBXFMMLibExpansionWrangler(FMMLibExpansionWrangler): # FMMLib is CPU-only. This wrapper gets the geometry out of # OpenCL-land. - self.geo_data = ToHostTransferredGeoDataWrapper(queue, geo_data) + geo_data = ToHostTransferredGeoDataWrapper(queue, geo_data) + self.geo_data = geo_data self.qbx_order = qbx_order # {{{ digest out_kernels @@ -215,13 +226,14 @@ class QBXFMMLibExpansionWrangler(FMMLibExpansionWrangler): frozenset([("k", helmholtz_k)]), tree, level) super(QBXFMMLibExpansionWrangler, self).__init__( - self.geo_data.tree(), + geo_data.tree(), helmholtz_k=helmholtz_k, dipole_vec=dipole_vec, dipoles_already_reordered=True, fmm_level_to_nterms=inner_fmm_level_to_nterms, + rotation_data=geo_data, ifgrad=ifgrad) diff --git a/pytential/qbx/geometry.py b/pytential/qbx/geometry.py index 4eadefbe8c2b8f1e31e79f0af266d7e9dc11c79b..72b054f52b47d0fdcc4ba91e638632a0d2e162a7 100644 --- a/pytential/qbx/geometry.py +++ b/pytential/qbx/geometry.py @@ -29,6 +29,7 @@ import pyopencl as cl import pyopencl.array # noqa from pytools import memoize_method from boxtree.tools import DeviceDataRecord +from boxtree.pyfmmlib_integration import FMMLibRotationDataInterface import loopy as lp from loopy.version import MOST_RECENT_LANGUAGE_VERSION from cgen import Enum @@ -254,6 +255,12 @@ class QBXFMMGeometryCodeGetter(TreeCodeContainerMixin): knl = lp.split_iname(knl, "i", 128, inner_tag="l.0", outer_tag="g.0") return knl + @property + @memoize_method + def rotation_classes_builder(self): + from boxtree.rotation_classes import RotationClassesBuilder + return RotationClassesBuilder(self.cl_context) + # }}} @@ -300,7 +307,7 @@ class CenterToTargetList(DeviceDataRecord): """ -class QBXFMMGeometryData(object): +class QBXFMMGeometryData(FMMLibRotationDataInterface): """ .. rubric :: Attributes @@ -350,6 +357,12 @@ class QBXFMMGeometryData(object): .. automethod:: center_to_tree_targets() .. automethod:: non_qbx_box_target_lists() .. automethod:: plot() + + The following methods implement the + :class:`boxtree.pyfmmlib_integration.FMMLibRotationDataInterface`. + + .. method:: m2l_rotation_lists() + .. method:: m2l_rotation_angles() """ def __init__(self, code_getter, lpot_source, @@ -824,6 +837,26 @@ class QBXFMMGeometryData(object): return result.with_queue(None) + @memoize_method + def build_rotation_classes_lists(self): + trav = self.traversal() + tree = self.tree() + + with cl.CommandQueue(self.cl_context) as queue: + return (self + .code_getter + .rotation_classes_builder(queue, trav, tree)[0].get(queue)) + + @memoize_method + def m2l_rotation_lists(self): + return self.build_rotation_classes_lists().from_sep_siblings_rotation_classes + + @memoize_method + def m2l_rotation_angles(self): + return (self + .build_rotation_classes_lists() + .from_sep_siblings_rotation_class_to_angle) + # {{{ plotting (for debugging) def plot(self, draw_circles=False, draw_center_numbers=False, diff --git a/setup.py b/setup.py index e2a1ae90b75867829508b789fbe340e15b29c426..8e1a66c4a570c22aae64e381c56548f57fad164f 100644 --- a/setup.py +++ b/setup.py @@ -100,12 +100,12 @@ setup(name="pytential", "pytools>=2018.2", "modepy>=2013.3", "pyopencl>=2013.1", - "boxtree>=2018.2", + "boxtree>=2019.1", "pymbolic>=2013.2", "loo.py>=2017.2", "sumpy>=2013.1", "cgen>=2013.1.2", - "pyfmmlib>=2018.1", + "pyfmmlib>=2019.1.1", "six", ])