From ad5cd8f995a0dcf37f47089dc0dc62d43e68d10d Mon Sep 17 00:00:00 2001
From: Andreas Kloeckner <inform@tiker.net>
Date: Thu, 18 Jul 2013 16:32:32 -0400
Subject: [PATCH] Make P2{M,L}2P tests work for Laplace, Helmholtz

---
 test/test_kernels.py | 117 +++++++++++++++++++++++++++++++------------
 1 file changed, 85 insertions(+), 32 deletions(-)

diff --git a/test/test_kernels.py b/test/test_kernels.py
index 3839e28b..67bdd452 100644
--- a/test/test_kernels.py
+++ b/test/test_kernels.py
@@ -33,7 +33,7 @@ from pyopencl.tools import (  # noqa
         pytest_generate_tests_for_pyopencl as pytest_generate_tests)
 
 from sumpy.expansion.multipole import VolumeTaylorMultipoleExpansion
-from sumpy.expansion.local import VolumeTaylorLocalExpansion
+from sumpy.expansion.local import VolumeTaylorLocalExpansion, H2DLocalExpansion
 from sumpy.kernel import LaplaceKernel, HelmholtzKernel, AxisTargetDerivative
 
 import logging
@@ -82,16 +82,16 @@ def test_p2p(ctx_getter):
 
 @pytools.test.mark_test.opencl
 @pytest.mark.parametrize("order", [2, 3, 4, 5])
-@pytest.mark.parametrize("expn_class", [
-    VolumeTaylorLocalExpansion,
-    VolumeTaylorMultipoleExpansion,
-    ])
-@pytest.mark.parametrize("knl", [
-    LaplaceKernel(2),
-    #HelmholtzKernel(2)
+@pytest.mark.parametrize(("knl", "expn_class"), [
+    (LaplaceKernel(2), VolumeTaylorLocalExpansion),
+    (LaplaceKernel(2), VolumeTaylorMultipoleExpansion),
+
+    (HelmholtzKernel(2), VolumeTaylorMultipoleExpansion),
+    (HelmholtzKernel(2), VolumeTaylorLocalExpansion),
+    (HelmholtzKernel(2), H2DLocalExpansion),
     ])
 def test_p2e2p(ctx_getter, knl, expn_class, order):
-    logging.basicConfig(level=logging.INFO)
+    #logging.basicConfig(level=logging.INFO)
 
     ctx = ctx_getter()
     queue = cl.CommandQueue(ctx)
@@ -99,15 +99,15 @@ def test_p2e2p(ctx_getter, knl, expn_class, order):
     np.random.seed(17)
 
     res = 100
-    nsources = 500
+    nsources = 100
 
     extra_kwargs = {}
     if isinstance(knl, HelmholtzKernel):
-        extra_kwargs["k"] = 2
+        extra_kwargs["k"] = 0.05
 
     out_kernels = [
             knl,
-            AxisTargetDerivative(0, knl)
+            AxisTargetDerivative(0, knl),
             ]
     expn = expn_class(knl, order=order)
 
@@ -120,21 +120,36 @@ def test_p2e2p(ctx_getter, knl, expn_class, order):
     eoc_rec_pot = EOCRecorder()
     eoc_rec_grad_x = EOCRecorder()
 
-    for dist in [3, 5, 7]:
-        from sumpy.expansion.local import LocalExpansionBase
+    from sumpy.expansion.local import LocalExpansionBase
+    if issubclass(expn_class, LocalExpansionBase):
+        h_values = [1/5, 1/7, 1/20]
+    else:
+        h_values = [1/2, 1/3, 1/5]
+
+    center = np.array([2, 1], np.float64)
+    sources = (0.7*(-0.5+np.random.rand(knl.dim, nsources).astype(np.float64))
+            + center[:, np.newaxis])
+
+    strengths = np.ones(nsources, dtype=np.float64) * (1/nsources)
+
+    source_boxes = np.array([0], dtype=np.int32)
+    box_source_starts = np.array([0], dtype=np.int32)
+    box_source_counts_nonchild = np.array([nsources], dtype=np.int32)
+
+    for h in h_values:
+        from sumpy.visualization import FieldPlotter
         if issubclass(expn_class, LocalExpansionBase):
-            centers = np.array([0.5+dist, 0.5], dtype=np.float64).reshape(knl.dim, 1)
+            loc_center = np.array([5.5, 0.0]) + center
+            centers = np.array(loc_center, dtype=np.float64).reshape(knl.dim, 1)
+            fp = FieldPlotter(loc_center, extent=h, npoints=res)
         else:
-            centers = np.array([0.5, 0.5], dtype=np.float64).reshape(knl.dim, 1)
+            eval_center = np.array([1/h, 0.0]) + center
+            fp = FieldPlotter(eval_center, extent=0.1, npoints=res)
+            centers = (
+                    np.array([0.0, 0.0], dtype=np.float64).reshape(knl.dim, 1)
+                    + center[:, np.newaxis])
 
-        sources = np.random.rand(knl.dim, nsources).astype(np.float64)
-        strengths = np.ones(nsources, dtype=np.float64)
-        targets = np.mgrid[dist:dist + 1:res*1j, 0:1:res*1j] \
-                .reshape(knl.dim, -1).astype(np.float64)
-
-        source_boxes = np.array([0], dtype=np.int32)
-        box_source_starts = np.array([0], dtype=np.int32)
-        box_source_counts_nonchild = np.array([nsources], dtype=np.int32)
+        targets = fp.points
 
         # {{{ apply p2e
 
@@ -145,6 +160,7 @@ def test_p2e2p(ctx_getter, knl, expn_class, order):
                 centers=centers,
                 sources=sources,
                 strengths=strengths,
+                #flags="print_hl_cl",
                 out_host=True, **extra_kwargs)
 
         # }}}
@@ -156,7 +172,7 @@ def test_p2e2p(ctx_getter, knl, expn_class, order):
         box_target_starts = np.array([0], dtype=np.int32)
         box_target_counts_nonchild = np.array([ntargets], dtype=np.int32)
 
-        evt, (pot, grad_x) = e2p(
+        evt, (pot, grad_x, ) = e2p(
                 queue,
                 expansions=mpoles,
                 target_boxes=source_boxes,
@@ -164,14 +180,14 @@ def test_p2e2p(ctx_getter, knl, expn_class, order):
                 box_target_counts_nonchild=box_target_counts_nonchild,
                 centers=centers,
                 targets=targets,
-                #flags="print_hl",
+                #flags="print_hl_cl",
                 out_host=True, **extra_kwargs)
 
         # }}}
 
         # {{{ compute (direct) reference solution
 
-        evt, (pot_direct, grad_x_direct) = p2p(
+        evt, (pot_direct, grad_x_direct, ) = p2p(
                 queue,
                 targets, sources, (strengths,),
                 out_host=True,
@@ -180,21 +196,58 @@ def test_p2e2p(ctx_getter, knl, expn_class, order):
         err_pot = la.norm((pot - pot_direct)/res**2)
         err_grad_x = la.norm((grad_x - grad_x_direct)/res**2)
 
+        if 1:
+            err_pot = err_pot / la.norm((pot_direct)/res**2)
+            err_grad_x = err_grad_x / la.norm((grad_x_direct)/res**2)
+
+        if 0:
+            import matplotlib.pyplot as pt
+            from matplotlib.colors import Normalize
+
+            pt.subplot(131)
+            im = fp.show_scalar_in_matplotlib(pot.real)
+            im.set_norm(Normalize(vmin=-0.1, vmax=0.1))
+
+            pt.subplot(132)
+            im = fp.show_scalar_in_matplotlib(pot_direct.real)
+            im.set_norm(Normalize(vmin=-0.1, vmax=0.1))
+            pt.colorbar()
+
+            pt.subplot(133)
+            im = fp.show_scalar_in_matplotlib(np.log10(1e-15+np.abs(pot-pot_direct)))
+            im.set_norm(Normalize(vmin=-6, vmax=1))
+
+            pt.colorbar()
+            pt.show()
+
         # }}}
 
-        eoc_rec_pot.add_data_point(1/dist, err_pot)
-        eoc_rec_grad_x.add_data_point(1/dist, err_grad_x)
+        eoc_rec_pot.add_data_point(h, err_pot)
+        eoc_rec_grad_x.add_data_point(h, err_grad_x)
 
-    print expn_class, order
+    print expn_class, knl, order
     print("POTENTIAL:")
     print(eoc_rec_pot)
     print("X TARGET DERIVATIVE:")
     print(eoc_rec_grad_x)
 
     tgt_order = order + 1
+    if issubclass(expn_class, LocalExpansionBase):
+        tgt_order_grad = tgt_order - 1
+        slack = 0.7
+        grad_slack = 0.5
+    else:
+        tgt_order_grad = tgt_order + 1
+
+        slack = 0.5
+        grad_slack = 1
+
+        if order <= 2:
+            slack += 1
+            grad_slack += 1
 
-    assert eoc_rec_pot.order_estimate() > tgt_order - 0.5
-    assert eoc_rec_grad_x.order_estimate() > tgt_order - 1.5
+    assert eoc_rec_pot.order_estimate() > tgt_order - slack
+    assert eoc_rec_grad_x.order_estimate() > tgt_order_grad - grad_slack
 
 
 @pytools.test.mark_test.opencl
-- 
GitLab