Exemple #1
0
def _sumpy_kernel_init(param):
    name, dim, order = param.name, param.dim, param.order
    # TODO: add other kernels
    assert name == "m2l"
    from sumpy.expansion.multipole import (
        LinearPDEConformingVolumeTaylorMultipoleExpansion,
    )
    from sumpy.expansion.local import LinearPDEConformingVolumeTaylorLocalExpansion
    from sumpy.kernel import LaplaceKernel
    from sumpy import E2EFromCSR

    ctx = cl.create_some_context()
    np.random.seed(17)

    knl = LaplaceKernel(dim)
    local_expn_class = LinearPDEConformingVolumeTaylorLocalExpansion
    mpole_expn_class = LinearPDEConformingVolumeTaylorMultipoleExpansion
    m_expn = mpole_expn_class(knl, order=order)
    l_expn = local_expn_class(knl, order=order)

    m2l = E2EFromCSR(ctx, m_expn, l_expn, name="loopy_kernel")
    m2l.get_translation_loopy_insns()
    m2l.ctx = None
    m2l.device = None
    return m2l
Exemple #2
0
 def m2l(self, src_order, tgt_order):
     return E2EFromCSR(self.cl_context, self.multipole_expansion(src_order),
                       self.local_expansion(tgt_order))
Exemple #3
0
 def get_l2l(self, from_order, to_order):
     from sumpy import E2EFromCSR
     return E2EFromCSR(
         self.cl_context,
         self.local_expn_class(self.no_target_deriv_kernel, from_order),
         self.local_expn_class(self.no_target_deriv_kernel, to_order))
Exemple #4
0
def test_translations(ctx_factory, knl, local_expn_class, mpole_expn_class):
    logging.basicConfig(level=logging.INFO)

    from sympy.core.cache import clear_cache
    clear_cache()

    ctx = ctx_factory()
    queue = cl.CommandQueue(ctx)

    np.random.seed(17)

    res = 20
    nsources = 15

    out_kernels = [knl]

    extra_kwargs = {}
    if isinstance(knl, HelmholtzKernel):
        extra_kwargs["k"] = 0.05
    if isinstance(knl, StokesletKernel):
        extra_kwargs["mu"] = 0.05

    # Just to make sure things also work away from the origin
    origin = np.array([2, 1, 0][:knl.dim], np.float64)
    sources = (0.7 *
               (-0.5 + np.random.rand(knl.dim, nsources).astype(np.float64)) +
               origin[:, np.newaxis])
    strengths = np.ones(nsources, dtype=np.float64) * (1 / nsources)

    pconv_verifier_p2m2p = PConvergenceVerifier()
    pconv_verifier_p2m2m2p = PConvergenceVerifier()
    pconv_verifier_p2m2m2l2p = PConvergenceVerifier()
    pconv_verifier_full = PConvergenceVerifier()

    from sumpy.visualization import FieldPlotter

    eval_offset = np.array([5.5, 0.0, 0][:knl.dim])

    centers = (
        np.array(
            [
                # box 0: particles, first mpole here
                [0, 0, 0][:knl.dim],

                # box 1: second mpole here
                np.array([-0.2, 0.1, 0][:knl.dim], np.float64),

                # box 2: first local here
                eval_offset + np.array([0.3, -0.2, 0][:knl.dim], np.float64),

                # box 3: second local and eval here
                eval_offset
            ],
            dtype=np.float64) + origin).T.copy()

    del eval_offset

    from sumpy.expansion import VolumeTaylorExpansionBase

    if isinstance(knl, HelmholtzKernel) and \
           issubclass(local_expn_class, VolumeTaylorExpansionBase):
        # FIXME: Embarrassing--but we run out of memory for higher orders.
        orders = [2, 3]
    else:
        orders = [2, 3, 4]
    nboxes = centers.shape[-1]

    def eval_at(e2p, source_box_nr, rscale):
        e2p_target_boxes = np.array([source_box_nr], dtype=np.int32)

        # These are indexed by global box numbers.
        e2p_box_target_starts = np.array([0, 0, 0, 0], dtype=np.int32)
        e2p_box_target_counts_nonchild = np.array([0, 0, 0, 0], dtype=np.int32)
        e2p_box_target_counts_nonchild[source_box_nr] = ntargets

        evt, (pot, ) = e2p(
            queue,
            src_expansions=mpoles,
            src_base_ibox=0,
            target_boxes=e2p_target_boxes,
            box_target_starts=e2p_box_target_starts,
            box_target_counts_nonchild=e2p_box_target_counts_nonchild,
            centers=centers,
            targets=targets,
            rscale=rscale,
            out_host=True,
            **extra_kwargs)

        return pot

    for order in orders:
        m_expn = mpole_expn_class(knl, order=order)
        l_expn = local_expn_class(knl, order=order)

        from sumpy import P2EFromSingleBox, E2PFromSingleBox, P2P, E2EFromCSR
        p2m = P2EFromSingleBox(ctx, m_expn)
        m2m = E2EFromCSR(ctx, m_expn, m_expn)
        m2p = E2PFromSingleBox(ctx, m_expn, out_kernels)
        m2l = E2EFromCSR(ctx, m_expn, l_expn)
        l2l = E2EFromCSR(ctx, l_expn, l_expn)
        l2p = E2PFromSingleBox(ctx, l_expn, out_kernels)
        p2p = P2P(ctx, out_kernels, exclude_self=False)

        fp = FieldPlotter(centers[:, -1], extent=0.3, npoints=res)
        targets = fp.points

        # {{{ compute (direct) reference solution

        evt, (pot_direct, ) = p2p(queue,
                                  targets,
                                  sources, (strengths, ),
                                  out_host=True,
                                  **extra_kwargs)

        # }}}

        m1_rscale = 0.5
        m2_rscale = 0.25
        l1_rscale = 0.5
        l2_rscale = 0.25

        # {{{ apply P2M

        p2m_source_boxes = np.array([0], dtype=np.int32)

        # These are indexed by global box numbers.
        p2m_box_source_starts = np.array([0, 0, 0, 0], dtype=np.int32)
        p2m_box_source_counts_nonchild = np.array([nsources, 0, 0, 0],
                                                  dtype=np.int32)

        evt, (mpoles, ) = p2m(
            queue,
            source_boxes=p2m_source_boxes,
            box_source_starts=p2m_box_source_starts,
            box_source_counts_nonchild=p2m_box_source_counts_nonchild,
            centers=centers,
            sources=sources,
            strengths=(strengths, ),
            nboxes=nboxes,
            rscale=m1_rscale,
            tgt_base_ibox=0,

            #flags="print_hl_wrapper",
            out_host=True,
            **extra_kwargs)

        # }}}

        ntargets = targets.shape[-1]

        pot = eval_at(m2p, 0, m1_rscale)

        err = la.norm((pot - pot_direct) / res**2)
        err = err / (la.norm(pot_direct) / res**2)

        pconv_verifier_p2m2p.add_data_point(order, err)

        # {{{ apply M2M

        m2m_target_boxes = np.array([1], dtype=np.int32)
        m2m_src_box_starts = np.array([0, 1], dtype=np.int32)
        m2m_src_box_lists = np.array([0], dtype=np.int32)

        evt, (mpoles, ) = m2m(
            queue,
            src_expansions=mpoles,
            src_base_ibox=0,
            tgt_base_ibox=0,
            ntgt_level_boxes=mpoles.shape[0],
            target_boxes=m2m_target_boxes,
            src_box_starts=m2m_src_box_starts,
            src_box_lists=m2m_src_box_lists,
            centers=centers,
            src_rscale=m1_rscale,
            tgt_rscale=m2_rscale,

            #flags="print_hl_cl",
            out_host=True,
            **extra_kwargs)

        # }}}

        pot = eval_at(m2p, 1, m2_rscale)

        err = la.norm((pot - pot_direct) / res**2)
        err = err / (la.norm(pot_direct) / res**2)

        pconv_verifier_p2m2m2p.add_data_point(order, err)

        # {{{ apply M2L

        m2l_target_boxes = np.array([2], dtype=np.int32)
        m2l_src_box_starts = np.array([0, 1], dtype=np.int32)
        m2l_src_box_lists = np.array([1], dtype=np.int32)

        evt, (mpoles, ) = m2l(
            queue,
            src_expansions=mpoles,
            src_base_ibox=0,
            tgt_base_ibox=0,
            ntgt_level_boxes=mpoles.shape[0],
            target_boxes=m2l_target_boxes,
            src_box_starts=m2l_src_box_starts,
            src_box_lists=m2l_src_box_lists,
            centers=centers,
            src_rscale=m2_rscale,
            tgt_rscale=l1_rscale,

            #flags="print_hl_cl",
            out_host=True,
            **extra_kwargs)

        # }}}

        pot = eval_at(l2p, 2, l1_rscale)

        err = la.norm((pot - pot_direct) / res**2)
        err = err / (la.norm(pot_direct) / res**2)

        pconv_verifier_p2m2m2l2p.add_data_point(order, err)

        # {{{ apply L2L

        l2l_target_boxes = np.array([3], dtype=np.int32)
        l2l_src_box_starts = np.array([0, 1], dtype=np.int32)
        l2l_src_box_lists = np.array([2], dtype=np.int32)

        evt, (mpoles, ) = l2l(
            queue,
            src_expansions=mpoles,
            src_base_ibox=0,
            tgt_base_ibox=0,
            ntgt_level_boxes=mpoles.shape[0],
            target_boxes=l2l_target_boxes,
            src_box_starts=l2l_src_box_starts,
            src_box_lists=l2l_src_box_lists,
            centers=centers,
            src_rscale=l1_rscale,
            tgt_rscale=l2_rscale,

            #flags="print_hl_wrapper",
            out_host=True,
            **extra_kwargs)

        # }}}

        pot = eval_at(l2p, 3, l2_rscale)

        err = la.norm((pot - pot_direct) / res**2)
        err = err / (la.norm(pot_direct) / res**2)

        pconv_verifier_full.add_data_point(order, err)

    for name, verifier in [
        ("p2m2p", pconv_verifier_p2m2p),
        ("p2m2m2p", pconv_verifier_p2m2m2p),
        ("p2m2m2l2p", pconv_verifier_p2m2m2l2p),
        ("full", pconv_verifier_full),
    ]:
        print(30 * "-")
        print(name)
        print(30 * "-")
        print(verifier)
        print(30 * "-")
        verifier()