Skip to content

Commit eee3d55

Browse files
committed
Renamed functions in recurrence.py, added off-axis section
1 parent a6fe10e commit eee3d55

File tree

4 files changed

+139
-119
lines changed

4 files changed

+139
-119
lines changed

sumpy/recurrence.py

Lines changed: 59 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -379,34 +379,6 @@ def _get_initial_order_off_axis(recurrence):
379379
r_c = recurrence.subs(n, i)
380380
return i
381381

382-
def move_center_origin_source_arbitrary_expression(pde: LinearPDESystemOperator) -> sp.Expr:
383-
r"""
384-
A function that "shifts" the recurrence so it's center is placed
385-
at the origin and source is the input for the recurrence generated.
386-
Outputs an expression that evaluates to 0 rather than s(n) in terms
387-
of s(n-1), etc. This is different from move_center_origin_source_arbitrary,
388-
because we are "shifting" an EXPRESSION, not s(n) in terms of s(n-1), etc.
389-
390-
:arg recurrence: a recurrence relation in :math:`s(n)`
391-
"""
392-
r = recurrence_from_pde(pde)
393-
394-
idx_l, terms = _extract_idx_terms_from_recurrence(r)
395-
396-
# How much do we need to shift the recurrence relation
397-
shift_idx = max(idx_l)
398-
399-
n = sp.symbols("n")
400-
r = r.subs(n, n-shift_idx)
401-
402-
idx_l, terms = _extract_idx_terms_from_recurrence(r)
403-
404-
r_ret = r
405-
for i in range(len(idx_l)):
406-
r_ret = r_ret.subs(terms[i], (-1)**(n+idx_l[i])*terms[i])
407-
408-
return r_ret, (max(idx_l)+1-min(idx_l))
409-
410382

411383
def move_center_origin_source_arbitrary(r: sp.Expr) -> sp.Expr:
412384
r"""
@@ -415,8 +387,8 @@ def move_center_origin_source_arbitrary(r: sp.Expr) -> sp.Expr:
415387
Assuming the recurrence is formulated so that evaluating it gives
416388
s(n) in terms of s(n-1), .., etc. We do NOT want a recurrence
417389
EXPRESSION as input, i.e. an expression containing s(n), s(n-1),
418-
..., that evaluates to 0.
419-
Use move_center_origin_source_arbitrary_expression for this.
390+
..., that evaluates to 0.
391+
Use move_center_origin_source_arbitrary_expression for EXPRESSIONS.
420392
421393
:arg recurrence: a recurrence relation in :math:`s(n)`
422394
"""
@@ -431,7 +403,7 @@ def move_center_origin_source_arbitrary(r: sp.Expr) -> sp.Expr:
431403
return r_ret*((-1)**(n+1))
432404

433405

434-
def get_reindexed_and_center_origin_recurrence(pde) -> tuple[int, int,
406+
def get_reindexed_and_center_origin_on_axis_recurrence(pde) -> tuple[int, int,
435407
sp.Expr]:
436408
r"""
437409
A function that "shifts" the recurrence so the expansion center is placed
@@ -453,24 +425,70 @@ def get_reindexed_and_center_origin_recurrence(pde) -> tuple[int, int,
453425
return n_initial, order, r_s
454426

455427
# ================ OFF-AXIS RECURRENCE =================
456-
def get_off_axis_recurrence(pde: LinearPDESystemOperator) -> sp.Expr:
428+
def move_center_origin_source_arbitrary_expression(pde: LinearPDESystemOperator) -> sp.Expr:
457429
r"""
458-
A function that takes in as input a pde and outputs a SHIFTED
459-
+ REINDEXED off-axis recurrence
430+
A function that "shifts" the recurrence so it's center is placed
431+
at the origin and source is the input for the recurrence generated.
432+
Outputs an expression that evaluates to 0 rather than s(n) in terms
433+
of s(n-1), etc. This is different from move_center_origin_source_arbitrary,
434+
because we are "shifting" an EXPRESSION, not s(n) in terms of s(n-1), etc.
435+
436+
:arg recurrence: a recurrence relation in :math:`s(n)`
437+
"""
438+
r = recurrence_from_pde(pde)
439+
440+
idx_l, terms = _extract_idx_terms_from_recurrence(r)
441+
n = sp.symbols("n")
442+
443+
r_ret = r
444+
for i in range(len(idx_l)):
445+
r_ret = r_ret.subs(terms[i], (-1)**(n+idx_l[i])*terms[i])
446+
447+
return r_ret
448+
449+
def get_reindexed_and_center_origin_off_axis_recurrence(pde: LinearPDESystemOperator) -> sp.Expr:
450+
r"""
451+
A function that takes in as input a pde and outputs a off-axis recurrence
452+
for derivatives taken at the origin with an arbitrary source location.
453+
The recurrence is reindexed so it gives s(n) in terms of s(n-1), ..., etc.
460454
"""
461455
var = _make_sympy_vec("x", 1)
462-
r_exp = move_center_origin_source_arbitrary_expression(pde)[0].subs(var[0], 0)
456+
r_exp = move_center_origin_source_arbitrary_expression(pde).subs(var[0], 0)
463457
recur_order, recur = reindex_recurrence_relation(r_exp)
464-
print(recur)
465458
start_order = _get_initial_order_off_axis(recur)
466459
return start_order, recur_order, recur
467460

468-
def get_taylor_expression(pde, deriv_order, taylor_order=4):
469-
#recursively substitute, and output the "order" of the taylor expression
470-
t_recurrence = get_off_axis_recurrence(pde)[2]
471-
var = _make_sympy_vec("x", 2)
461+
462+
def get_off_axis_expression(pde, taylor_order=4):
463+
r"""
464+
A function that takes in as input a pde, and outputs
465+
the Taylor expression that gives the deriv_order th derivative
466+
to a taylor_order order Taylor series with respect to x_1 and
467+
s(i) where s(i) comes from the off-axis recurrence. See
468+
get_reindexed_and_center_origin_off_axis_recurrence.
469+
"""
470+
s = sp.Function("s")
472471
n = sp.symbols("n")
472+
deriv_order = n
473+
474+
t_recurrence = get_reindexed_and_center_origin_off_axis_recurrence(pde)[2]
475+
var = _make_sympy_vec("x", 2)
473476
exp = 0
474477
for i in range(taylor_order):
475478
exp += t_recurrence.subs(n, deriv_order+i)/math.factorial(i) * var[0]**i
476-
return exp
479+
480+
#While derivatives w/order larger than the deriv_order exist in our taylor expression
481+
#replace them with smaller order derivatives
482+
idx_l, _ = _extract_idx_terms_from_recurrence(exp)
483+
max_idx = max(idx_l)
484+
485+
while max_idx > 0:
486+
for ind in idx_l:
487+
if ind > 0:
488+
exp = exp.subs(s(n+ind), t_recurrence.subs(n, n+ind))
489+
490+
idx_l, _ = _extract_idx_terms_from_recurrence(exp)
491+
max_idx = max(idx_l)
492+
exp_range = max(idx_l) - min(idx_l)
493+
494+
return exp, exp_range

sumpy/recurrence_qbx.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
import numpy as np
4040
import sympy as sp
4141

42-
from sumpy.recurrence import _make_sympy_vec, get_reindexed_and_center_origin_recurrence, get_off_axis_recurrence, eval_taylor_recurrence_laplace_processed
42+
from sumpy.recurrence import _make_sympy_vec, get_reindexed_and_center_origin_on_axis_recurrence, get_reindexed_and_center_origin_off_axis_recurrence, eval_taylor_recurrence_laplace_processed
4343

4444

4545
# ================ Transform/Rotate =================
@@ -97,8 +97,8 @@ def recurrence_qbx_lp(sources, centers, normals, strengths, radius, pde, g_x_y,
9797
var_t = _make_sympy_vec("t", ndim)
9898

9999
# ------------ 5. Compute recurrence
100-
n_initial, order, recurrence = get_reindexed_and_center_origin_recurrence(pde)
101-
t_order, t_recurrence = get_off_axis_recurrence(pde)
100+
n_initial, order, recurrence = get_reindexed_and_center_origin_on_axis_recurrence(pde)
101+
t_order, t_recurrence = get_reindexed_and_center_origin_off_axis_recurrence(pde)
102102
t_order += 2
103103

104104
# ------------ 6. Set order p = 5

test/gridfree_taylor_recurrence.ipynb

Lines changed: 15 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
" make_identity_diff_op,\n",
2121
")\n",
2222
"\n",
23-
"from sumpy.recurrence import get_taylor_expression, get_off_axis_recurrence\n",
23+
"from sumpy.recurrence import get_off_axis_expression, get_reindexed_and_center_origin_off_axis_recurrence, _extract_idx_terms_from_recurrence\n",
2424
"\n",
2525
"import sympy as sp\n",
2626
"from sympy import hankel1\n",
@@ -53,21 +53,15 @@
5353
"source": [
5454
"from sumpy.expansion.diff_op import laplacian,make_identity_diff_op\n",
5555
"w = make_identity_diff_op(2)\n",
56-
"laplace2d = laplacian(w)"
56+
"laplace2d = laplacian(w)\n",
57+
"helmholtz2d = laplacian(w) + w"
5758
]
5859
},
5960
{
6061
"cell_type": "code",
6162
"execution_count": 4,
6263
"metadata": {},
6364
"outputs": [
64-
{
65-
"name": "stdout",
66-
"output_type": "stream",
67-
"text": [
68-
"(-5*n + (n + 1)**2 + 1)*s(n - 2)/x1**2\n"
69-
]
70-
},
7165
{
7266
"data": {
7367
"text/latex": [
@@ -83,98 +77,52 @@
8377
}
8478
],
8579
"source": [
86-
"get_off_axis_recurrence(laplace2d)[2].subs(n, 3)"
80+
"get_reindexed_and_center_origin_off_axis_recurrence(laplace2d)[2].subs(n, 3)"
8781
]
8882
},
8983
{
9084
"cell_type": "code",
91-
"execution_count": 5,
92-
"metadata": {},
93-
"outputs": [
94-
{
95-
"name": "stdout",
96-
"output_type": "stream",
97-
"text": [
98-
"(-6*n + (n + 1)**2 + 2)*s(n - 4)/x1**2 + (-5*n + (n + 1)**2 + 1)*s(n - 2)/x1**2\n"
99-
]
100-
},
101-
{
102-
"data": {
103-
"text/plain": [
104-
"(3,\n",
105-
" 4,\n",
106-
" (-6*n + (n + 1)**2 + 2)*s(n - 4)/x1**2 + (-5*n + (n + 1)**2 + 1)*s(n - 2)/x1**2)"
107-
]
108-
},
109-
"execution_count": 5,
110-
"metadata": {},
111-
"output_type": "execute_result"
112-
}
113-
],
114-
"source": [
115-
"w = make_identity_diff_op(2)\n",
116-
"helmholtz2d = laplacian(w) + w\n",
117-
"get_off_axis_recurrence(helmholtz2d)"
118-
]
119-
},
120-
{
121-
"cell_type": "code",
122-
"execution_count": 6,
85+
"execution_count": 9,
12386
"metadata": {},
12487
"outputs": [
125-
{
126-
"name": "stdout",
127-
"output_type": "stream",
128-
"text": [
129-
"(-6*n + (n + 1)**2 + 2)*s(n - 4)/x1**2 + (-5*n + (n + 1)**2 + 1)*s(n - 2)/x1**2\n"
130-
]
131-
},
13288
{
13389
"data": {
134-
"text/latex": [
135-
"$\\displaystyle \\frac{3 s{\\left(0 \\right)}}{x_{1}^{2}} + \\frac{6 s{\\left(2 \\right)}}{x_{1}^{2}}$"
136-
],
13790
"text/plain": [
138-
"3*s(0)/x1**2 + 6*s(2)/x1**2"
91+
"(x0**3*(((-6*n + (n + 2)**2 - 4)*s(n - 3)/x1**2 + (-5*n + (n + 2)**2 - 4)*s(n - 1)/x1**2)*(-5*n + (n + 4)**2 - 14)/(6*x1**2) + (-6*n + (n + 4)**2 - 16)*s(n - 1)/(6*x1**2)) + x0**2*((-6*n + (n + 3)**2 - 10)*s(n - 2)/(2*x1**2) + (-5*n + (n + 3)**2 - 9)*s(n)/(2*x1**2)) + x0*((-6*n + (n + 2)**2 - 4)*s(n - 3)/x1**2 + (-5*n + (n + 2)**2 - 4)*s(n - 1)/x1**2) + (-6*n + (n + 1)**2 + 2)*s(n - 4)/x1**2 + (-5*n + (n + 1)**2 + 1)*s(n - 2)/x1**2,\n",
92+
" 4)"
13993
]
14094
},
141-
"execution_count": 6,
95+
"execution_count": 9,
14296
"metadata": {},
14397
"output_type": "execute_result"
14498
}
14599
],
146100
"source": [
147-
"get_off_axis_recurrence(helmholtz2d)[2].subs(n, 4)"
101+
"exp = get_off_axis_expression(helmholtz2d)\n",
102+
"exp"
148103
]
149104
},
150105
{
151106
"cell_type": "code",
152-
"execution_count": 9,
107+
"execution_count": 11,
153108
"metadata": {},
154109
"outputs": [
155-
{
156-
"name": "stdout",
157-
"output_type": "stream",
158-
"text": [
159-
"(-5*n + (n + 1)**2 + 1)*s(n - 2)/x1**2\n"
160-
]
161-
},
162110
{
163111
"data": {
164112
"text/latex": [
165-
"$\\displaystyle \\frac{x_{0}^{3} s{\\left(1 \\right)}}{3 x_{1}^{2}} + \\frac{2 s{\\left(-2 \\right)}}{x_{1}^{2}}$"
113+
"$\\displaystyle \\frac{x_{0}^{3} \\left(- x_{1}^{2} \\left(6 n - \\left(n + 4\\right)^{2} + 16\\right) s{\\left(n - 1 \\right)} + \\left(\\left(5 n - \\left(n + 2\\right)^{2} + 4\\right) s{\\left(n - 1 \\right)} + \\left(6 n - \\left(n + 2\\right)^{2} + 4\\right) s{\\left(n - 3 \\right)}\\right) \\left(5 n - \\left(n + 4\\right)^{2} + 14\\right)\\right) + 3 x_{1}^{2} \\left(- x_{0}^{2} \\left(\\left(5 n - \\left(n + 3\\right)^{2} + 9\\right) s{\\left(n \\right)} + \\left(6 n - \\left(n + 3\\right)^{2} + 10\\right) s{\\left(n - 2 \\right)}\\right) - 2 x_{0} \\left(\\left(5 n - \\left(n + 2\\right)^{2} + 4\\right) s{\\left(n - 1 \\right)} + \\left(6 n - \\left(n + 2\\right)^{2} + 4\\right) s{\\left(n - 3 \\right)}\\right) + 2 \\left(- 6 n + \\left(n + 1\\right)^{2} + 2\\right) s{\\left(n - 4 \\right)} + 2 \\left(- 5 n + \\left(n + 1\\right)^{2} + 1\\right) s{\\left(n - 2 \\right)}\\right)}{6 x_{1}^{4}}$"
166114
],
167115
"text/plain": [
168-
"x0**3*s(1)/(3*x1**2) + 2*s(-2)/x1**2"
116+
"(x0**3*(-x1**2*(6*n - (n + 4)**2 + 16)*s(n - 1) + ((5*n - (n + 2)**2 + 4)*s(n - 1) + (6*n - (n + 2)**2 + 4)*s(n - 3))*(5*n - (n + 4)**2 + 14)) + 3*x1**2*(-x0**2*((5*n - (n + 3)**2 + 9)*s(n) + (6*n - (n + 3)**2 + 10)*s(n - 2)) - 2*x0*((5*n - (n + 2)**2 + 4)*s(n - 1) + (6*n - (n + 2)**2 + 4)*s(n - 3)) + 2*(-6*n + (n + 1)**2 + 2)*s(n - 4) + 2*(-5*n + (n + 1)**2 + 1)*s(n - 2)))/(6*x1**4)"
169117
]
170118
},
171-
"execution_count": 9,
119+
"execution_count": 11,
172120
"metadata": {},
173121
"output_type": "execute_result"
174122
}
175123
],
176124
"source": [
177-
"get_taylor_expression(laplace2d, 0)"
125+
"exp[0].simplify()"
178126
]
179127
},
180128
{

0 commit comments

Comments
 (0)