Skip to content

Commit 49b52ad

Browse files
ShawnL00inducer
andcommitted
Add test_lpot_dx_jump_relation_convergence
Co-authored-by: Andreas Kloeckner <inform@tiker.net>
1 parent 852666b commit 49b52ad

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

sumpy/test/test_target_deriv.py

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
from __future__ import annotations
2+
3+
4+
__copyright__ = """
5+
Copyright (C) 2025 Shawn Lin
6+
Copyright (C) 2025 University of Illinois Board of Trustees
7+
"""
8+
9+
__license__ = """
10+
Permission is hereby granted, free of charge, to any person obtaining a copy
11+
of this software and associated documentation files (the "Software"), to deal
12+
in the Software without restriction, including without limitation the rights
13+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14+
copies of the Software, and to permit persons to whom the Software is
15+
furnished to do so, subject to the following conditions:
16+
17+
The above copyright notice and this permission notice shall be included in
18+
all copies or substantial portions of the Software.
19+
20+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26+
THE SOFTWARE.
27+
"""
28+
29+
import sys
30+
from typing import TYPE_CHECKING
31+
32+
import numpy as np
33+
import pytest
34+
35+
from arraycontext import (
36+
PyOpenCLArrayContext,
37+
pytest_generate_tests_for_array_contexts,
38+
)
39+
from pytools.convergence import EOCRecorder
40+
41+
from sumpy.array_context import PytestPyOpenCLArrayContextFactory, _acf # noqa: F401
42+
from sumpy.expansion.local import LineTaylorLocalExpansion
43+
from sumpy.kernel import AxisTargetDerivative, Kernel, LaplaceKernel
44+
from sumpy.test.geometries import make_starfish
45+
46+
47+
if TYPE_CHECKING:
48+
from arraycontext import ArrayContextFactory
49+
50+
pytest_generate_tests = pytest_generate_tests_for_array_contexts([
51+
PytestPyOpenCLArrayContextFactory,
52+
])
53+
54+
55+
@pytest.mark.parametrize("knl", [LaplaceKernel(2)])
56+
def test_lpot_dx_jump_relation_convergence(
57+
actx_factory: ArrayContextFactory,
58+
knl: Kernel):
59+
"""Test convergence of jump relations for single layer potential derivatives."""
60+
61+
actx = actx_factory()
62+
if not isinstance(actx, PyOpenCLArrayContext):
63+
pytest.skip()
64+
65+
qbx_order = 5
66+
nelements = [100, 150, 200]
67+
target_order = 5
68+
upsampling_factor = 5
69+
70+
ntargets = 20
71+
target_geo = make_starfish(npoints=ntargets)
72+
targets_h = target_geo.nodes
73+
targets = actx.from_numpy(targets_h)
74+
75+
from sumpy.qbx import LayerPotential
76+
expansion = LineTaylorLocalExpansion(knl, qbx_order)
77+
lplot_dx = LayerPotential(
78+
actx.context,
79+
expansion=expansion,
80+
target_kernels=(AxisTargetDerivative(0, knl),),
81+
source_kernels=(knl,)
82+
)
83+
lplot_dy = LayerPotential(
84+
actx.context,
85+
expansion=expansion,
86+
target_kernels=(AxisTargetDerivative(1, knl),),
87+
source_kernels=(knl,)
88+
)
89+
eocrec = EOCRecorder()
90+
91+
for nsources in [320, 640, 1280, 2560]:
92+
source_geo = make_starfish(npoints=nsources)
93+
sources = actx.from_numpy(source_geo.nodes)
94+
95+
weights_nodes_h = source_geo.area_elements * source_geo.weights
96+
weights_nodes = actx.from_numpy(weights_nodes_h)
97+
98+
expansion_radii_h = 4 * target_geo.area_elements / nsources
99+
centers_in = actx.from_numpy(
100+
targets_h - target_geo.normals * expansion_radii_h)
101+
centers_out = actx.from_numpy(
102+
targets_h + target_geo.normals * expansion_radii_h)
103+
104+
strengths = (weights_nodes,)
105+
_, (eval_in_dx,) = lplot_dx(
106+
actx.queue,
107+
targets, sources, centers_in, strengths,
108+
expansion_radii=expansion_radii_h
109+
)
110+
111+
_, (eval_in_dy,) = lplot_dy(
112+
actx.queue,
113+
targets, sources, centers_in, strengths,
114+
expansion_radii=expansion_radii_h
115+
)
116+
117+
_, (eval_out_dx,) = lplot_dx(
118+
actx.queue,
119+
targets, sources, centers_out, strengths,
120+
expansion_radii=expansion_radii_h
121+
)
122+
123+
_, (eval_out_dy,) = lplot_dy(
124+
actx.queue,
125+
targets, sources, centers_out, strengths,
126+
expansion_radii=expansion_radii_h
127+
)
128+
129+
eval_in_dx = actx.to_numpy(eval_in_dx)
130+
eval_in_dy = actx.to_numpy(eval_in_dy)
131+
eval_out_dx = actx.to_numpy(eval_out_dx)
132+
eval_out_dy = actx.to_numpy(eval_out_dy)
133+
134+
eval_in = eval_in_dx * target_geo.normals[0] + \
135+
eval_in_dy * target_geo.normals[1]
136+
eval_out = eval_out_dx * target_geo.normals[0] + \
137+
eval_out_dy * target_geo.normals[1]
138+
139+
# check jump relation: S'_int - S'_ext = sigma (=1 for constant density)
140+
jump_error = np.abs(eval_in - eval_out - 1)
141+
142+
h_max = 1/nsources
143+
eocrec.add_data_point(h_max, np.max(jump_error))
144+
145+
print(eocrec)
146+
assert eocrec.order_estimate() > qbx_order - 1.5
147+
148+
149+
if __name__ == "__main__":
150+
if len(sys.argv) > 1:
151+
exec(sys.argv[1])
152+
else:
153+
pytest.main([__file__])

0 commit comments

Comments
 (0)