Skip to content

Commit b3a1b5f

Browse files
committed
Relative error
1 parent a1f528e commit b3a1b5f

File tree

2 files changed

+80
-9
lines changed

2 files changed

+80
-9
lines changed

sumpy/recurrence.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -485,10 +485,11 @@ def get_off_axis_expression(pde, taylor_order=4):
485485
var = _make_sympy_vec("x", 2)
486486
exp = 0
487487
for i in range(taylor_order+1):
488-
exp += t_recurrence.subs(n, deriv_order+i)/math.factorial(i) * var[0]**i
488+
exp += s(deriv_order+i)/math.factorial(i) * var[0]**i
489489

490490
#While derivatives w/order larger than the deriv_order exist in our taylor expression
491491
#replace them with smaller order derivatives
492+
492493
idx_l, _ = _extract_idx_terms_from_recurrence(exp)
493494
max_idx = max(idx_l)
494495

@@ -498,7 +499,9 @@ def get_off_axis_expression(pde, taylor_order=4):
498499
exp = exp.subs(s(n+ind), t_recurrence.subs(n, n+ind))
499500

500501
idx_l, _ = _extract_idx_terms_from_recurrence(exp)
501-
max_idx = max(idx_l)
502-
exp_range = max(idx_l) - min(idx_l) + 1
502+
max_idx = max(idx_l)
503+
504+
idx_l, _ = _extract_idx_terms_from_recurrence(exp)
505+
exp_range = (min(idx_l), max(idx_l))
503506

504-
return exp, exp_range
507+
return exp*(-1)**n, exp_range

test/test_recurrence.py

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,75 @@ def test_laplace2d():
210210
assert max(abs(abs(check))) <= 1e-12
211211

212212

213+
def test_helmholtz_2d_off_axis():
214+
r"""
215+
Tests off-axis recurrence code for orders up to 6 laplace2d.
216+
"""
217+
w = make_identity_diff_op(2)
218+
helmholtz2d = laplacian(w) + w
219+
220+
n = sp.symbols("n")
221+
s = sp.Function("s")
222+
223+
var = _make_sympy_vec("x", 2)
224+
var_t = _make_sympy_vec("t", 2)
225+
abs_dist = sp.sqrt((var[0]-var_t[0])**2 +
226+
(var[1]-var_t[1])**2)
227+
k = 1
228+
g_x_y = (1j/4) * hankel1(0, k * abs_dist)
229+
derivs = [sp.diff(g_x_y,
230+
var_t[0], i).subs(var_t[0], 0).subs(var_t[1], 0)
231+
for i in range(8)]
232+
233+
x_coord = 1e-2 * np.random.rand() # noqa: NPY002
234+
y_coord = np.random.rand() # noqa: NPY002
235+
coord_dict = {var[0]: x_coord, var[1]: y_coord}
236+
start_order, recur_order, recur = get_reindexed_and_center_origin_off_axis_recurrence(helmholtz2d)
237+
238+
ic = []
239+
#Generate ic
240+
241+
for i in range(start_order):
242+
ic.append(derivs[i].subs(var[0], 0).subs(var[1], coord_dict[var[1]]))
243+
244+
n = sp.symbols("n")
245+
for i in range(start_order, 15):
246+
recur_eval = recur.subs(var[0], coord_dict[var[0]]).subs(var[1], coord_dict[var[1]]).subs(n, i)
247+
for j in range(i-recur_order, i):
248+
recur_eval = recur_eval.subs(s(j), ic[j])
249+
ic.append(recur_eval)
250+
251+
ic = np.array(ic)
252+
253+
#true_ic = np.array([derivs[i].subs(var[0], 0).subs(var[1], coord_dict[var[1]]) for i in range(15)])
254+
255+
#assert np.max(np.abs(ic[::2]-true_ic[::2])/np.abs(true_ic[::2])) < 1e-8
256+
#print(np.max(np.abs(ic[::2]-true_ic[::2])/np.abs(true_ic[::2])))
257+
258+
# CHECK ACCURACY OF EXPRESSION FOR deriv_order
259+
deriv_order = 7
260+
exp_order = 4
261+
262+
exp, exp_range = get_off_axis_expression(helmholtz2d, exp_order)
263+
approx_deriv = exp.subs(n, deriv_order)
264+
exp_range = (exp_range[0]+deriv_order, exp_range[1]+deriv_order)
265+
for i in range(exp_range[0], exp_range[1]+1):
266+
approx_deriv = approx_deriv.subs(s(i), ic[i])
267+
268+
rat = coord_dict[var[0]]/coord_dict[var[1]]
269+
if deriv_order + exp_order % 2 == 0:
270+
prederror = abs((ic[deriv_order+exp_order+2] * coord_dict[var[0]]**(exp_order+2)/math.factorial(exp_order+2)).evalf())
271+
else:
272+
prederror = abs((ic[deriv_order+exp_order+1] * coord_dict[var[0]]**(exp_order+1)/math.factorial(exp_order+1)).evalf())
273+
print("PREDICTED ERROR: ", prederror)
274+
relerr = abs(((approx_deriv - derivs[deriv_order])/derivs[deriv_order]).subs(var[0], coord_dict[var[0]]).subs(var[1], coord_dict[var[1]]).evalf())
275+
print("RELATIVE ERROR: ", relerr)
276+
print("RATIO: ", rat)
277+
assert relerr <= prederror
278+
279+
test_helmholtz_2d_off_axis()
280+
281+
213282
def test_laplace_2d_off_axis():
214283
r"""
215284
Tests off-axis recurrence code for orders up to 6 laplace2d.
@@ -251,12 +320,13 @@ def test_laplace_2d_off_axis():
251320

252321
# CHECK ACCURACY OF EXPRESSION FOR deriv_order
253322
deriv_order = 7
254-
exp_order = 5
323+
exp_order = 6
255324

256325
exp, exp_range = get_off_axis_expression(laplace2d, exp_order)
257326
approx_deriv = exp.subs(n, deriv_order)
258-
for i in range(exp_range):
259-
approx_deriv = approx_deriv.subs(s(deriv_order-i), ic[deriv_order-i])
327+
exp_range = (exp_range[0]+deriv_order, exp_range[1]+deriv_order)
328+
for i in range(exp_range[0], exp_range[1]+1):
329+
approx_deriv = approx_deriv.subs(s(i), ic[i])
260330

261331
rat = coord_dict[var[0]]/coord_dict[var[1]]
262332
if deriv_order + exp_order % 2 == 0:
@@ -269,8 +339,6 @@ def test_laplace_2d_off_axis():
269339
print("RATIO: ", rat)
270340
assert relerr <= prederror
271341

272-
test_laplace_2d_off_axis()
273-
274342
import matplotlib.pyplot as plt
275343
def _plot_laplace_2d(max_order_check, max_abs):
276344
w = make_identity_diff_op(2)

0 commit comments

Comments
 (0)