Skip to content

Commit bb6f2ea

Browse files
committed
LineTaylorExpansion Modification
1 parent ed46dfe commit bb6f2ea

7 files changed

Lines changed: 208 additions & 114 deletions

File tree

examples/curve-pot.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ def map_to_curve(t: NDArray[np.floating]):
171171
targets = actx.from_numpy(fp.points)
172172
sources = actx.from_numpy(native_curve.pos)
173173
ovsmp_sources = actx.from_numpy(ovsmp_curve.pos)
174+
if expn_class is LineTaylorLocalExpansion:
175+
lpot_kwargs["expansion_vec"] = actx.from_numpy(native_curve.pos - centers)
174176

175177
if 0:
176178
# {{{ build matrix

sumpy/expansion/local.py

Lines changed: 99 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import math
2828
from abc import ABC, abstractmethod
2929
from dataclasses import dataclass, field
30-
from typing import TYPE_CHECKING, Any, cast
30+
from typing import TYPE_CHECKING, cast
3131

3232
from typing_extensions import override
3333

@@ -67,7 +67,6 @@
6767
.. autoclass:: H2DLocalExpansion
6868
.. autoclass:: Y2DLocalExpansion
6969
.. autoclass:: LineTaylorLocalExpansion
70-
.. autoclass:: AsymptoticDividingLineTaylorExpansion
7170
"""
7271

7372

@@ -116,8 +115,6 @@ def translate_from(self,
116115

117116
@dataclass(frozen=True)
118117
class LineTaylorLocalExpansion(LocalExpansionBase, ABC):
119-
tau: float = field(kw_only=True, default=1)
120-
121118
@property
122119
@override
123120
def m2l_translation(self) -> M2LTranslationBase:
@@ -148,7 +145,8 @@ def coefficients_from_source(self,
148145
"formation")
149146

150147
tau = sym.Symbol("tau")
151-
avec_line = cast("sym.Matrix", avec + tau*bvec)
148+
expansion_line = bvec
149+
avec_line = avec + tau*expansion_line
152150
line_kernel = kernel.get_expression(avec_line)
153151

154152
from sumpy.symbolic import USE_SYMENGINE
@@ -179,15 +177,25 @@ def evaluate(self,
179177
coeffs: Sequence[sym.Expr],
180178
bvec: sym.Matrix,
181179
rscale: sym.Expr,
182-
sac: SymbolicAssignmentCollection | None = None) -> sym.Expr:
180+
sac: SymbolicAssignmentCollection | None = None,
181+
*,
182+
expansion_vec: sym.Matrix) -> sym.Expr:
183183
# no point in heeding rscale here--just ignore it
184184

185185
# NOTE: We can't meaningfully apply target derivatives here.
186186
# Instead, this is handled in LayerPotentialBase._evaluate.
187187

188+
if expansion_vec == bvec:
189+
return sym.Add(*(
190+
coeffs[self.get_storage_index(i)] / math.factorial(i[0])
191+
for i in self.get_coefficient_identifiers()))
192+
193+
tau = ((bvec.T*expansion_vec)[0, 0]
194+
/ (expansion_vec.T*expansion_vec)[0, 0])
195+
188196
return sym.Add(*(
189197
coeffs[self.get_storage_index(i)] / math.factorial(i[0])
190-
* self.tau**i[0]
198+
* tau**i[0]
191199
for i in self.get_coefficient_identifiers()))
192200

193201
@override
@@ -208,89 +216,90 @@ def translate_from(self,
208216

209217
# {{{ Asymptotic dividing line Taylor expansion
210218

211-
@dataclass(frozen=True)
212-
class AsymptoticDividingLineTaylorExpansion(LineTaylorLocalExpansion):
213-
r"""
214-
A target-specific modified line Taylor expansion.
215-
216-
The expansion line is defined as :math:`l(\tau) = \text{avec} + \tau \cdot
217-
\text{bvec}` at a target point :math:`x`. The modified line Taylor expansion takes
218-
the form:
219-
220-
.. math::
221-
222-
\sum_{k=0}^{\text{order}} \frac{g_k}{k!} \tau^k,
223-
224-
where:
225-
226-
.. math::
227-
228-
g_k := \frac{d^k}{d\tau^k} \left(
229-
\frac{\text{kernel}(l(\tau))}{\text{asymptotic}(l(\tau))}
230-
\right) \bigg|_{\tau=0}
231-
232-
.. automethod:: get_asymptotic_expression
233-
"""
234-
235-
asymptotic: Any = field(kw_only=True)
236-
237-
def get_asymptotic_expression(self, scaled_dist_vec: sym.Matrix) -> sym.Expr:
238-
from sumpy.symbolic import PymbolicToSympyMapperWithSymbols, Symbol
239-
240-
expr = PymbolicToSympyMapperWithSymbols()(self.asymptotic)
241-
expr = expr.xreplace({Symbol(f"d{i}"): dist_vec_i
242-
for i, dist_vec_i in enumerate(scaled_dist_vec)})
243-
244-
tau = sym.Symbol("tau")
245-
246-
b = scaled_dist_vec.applyfunc(lambda expr: expr.coeff(tau))
247-
a = scaled_dist_vec - tau*b
248-
expr = expr.subs({Symbol(f"a{i}"): a_i for i, a_i in enumerate(a)})
249-
expr = expr.subs({Symbol(f"b{i}"): b_i for i, b_i in enumerate(b)})
250-
251-
return expr
252-
253-
@override
254-
def coefficients_from_source(self,
255-
kernel: Kernel,
256-
avec: sym.Matrix,
257-
bvec: sym.Matrix | None,
258-
rscale: sym.Expr,
259-
sac: SymbolicAssignmentCollection | None = None
260-
) -> Sequence[sym.Expr]:
261-
# no point in heeding rscale here--just ignore it
262-
if bvec is None:
263-
raise RuntimeError("cannot use line-Taylor expansions in a setting "
264-
"where the center-target vector is not known at coefficient "
265-
"formation")
266-
267-
tau = sym.Symbol("tau")
268-
269-
avec_line = cast("sym.Matrix", avec + tau*bvec)
270-
line_kernel = (
271-
kernel.get_expression(avec_line)
272-
/ self.get_asymptotic_expression(avec_line))
273-
274-
from sumpy.symbolic import USE_SYMENGINE
275-
if USE_SYMENGINE:
276-
from sumpy.derivative_taker import ExprDerivativeTaker
277-
deriv_taker = ExprDerivativeTaker(line_kernel, (tau,), sac=sac,
278-
rscale=sym.sympify(1))
279-
280-
return [kernel.postprocess_at_source(deriv_taker.diff(i), avec)
281-
.subs(tau, 0)
282-
for i in self.get_coefficient_identifiers()]
283-
else:
284-
# Workaround for sympy. The automatic distribution after
285-
# single-variable diff makes the expressions very large
286-
# (https://github.com/sympy/sympy/issues/4596), so avoid doing
287-
# single variable diff.
288-
#
289-
# See also https://gitlab.tiker.net/inducer/pytential/merge_requests/12
290-
291-
return [kernel.postprocess_at_source(line_kernel.diff(tau, i), avec)
292-
.subs(tau, 0)
293-
for i, in self.get_coefficient_identifiers()]
219+
# @dataclass(frozen=True)
220+
# class AsymptoticDividingLineTaylorExpansion(LineTaylorLocalExpansion):
221+
# r"""
222+
# A target-specific modified line Taylor expansion.
223+
#
224+
# The expansion line is defined as :math:`l(\tau) = \text{avec} + \tau \cdot
225+
# \text{bvec}` at a target point :math:`x`. The modified line Taylor expansion
226+
# takes the form:
227+
#
228+
# .. math::
229+
#
230+
# \sum_{k=0}^{\text{order}} \frac{g_k}{k!} \tau^k,
231+
#
232+
# where:
233+
#
234+
# .. math::
235+
#
236+
# g_k := \frac{d^k}{d\tau^k} \left(
237+
# \frac{\text{kernel}(l(\tau))}{\text{asymptotic}(l(\tau))}
238+
# \right) \bigg|_{\tau=0}
239+
#
240+
# .. automethod:: get_asymptotic_expression
241+
# """
242+
#
243+
# asymptotic: Any = field(kw_only=True)
244+
#
245+
# def get_asymptotic_expression(self, scaled_dist_vec: sym.Matrix) -> sym.Expr:
246+
# from sumpy.symbolic import PymbolicToSympyMapperWithSymbols, Symbol
247+
#
248+
# expr = PymbolicToSympyMapperWithSymbols()(self.asymptotic)
249+
# expr = expr.xreplace({Symbol(f"d{i}"): dist_vec_i
250+
# for i, dist_vec_i in enumerate(scaled_dist_vec)})
251+
#
252+
# tau = sym.Symbol("tau")
253+
#
254+
# b = scaled_dist_vec.applyfunc(lambda expr: expr.coeff(tau))
255+
# a = scaled_dist_vec - tau*b
256+
# expr = expr.subs({Symbol(f"a{i}"): a_i for i, a_i in enumerate(a)})
257+
# expr = expr.subs({Symbol(f"b{i}"): b_i for i, b_i in enumerate(b)})
258+
#
259+
# return expr
260+
#
261+
# @override
262+
# def coefficients_from_source(self,
263+
# kernel: Kernel,
264+
# avec: sym.Matrix,
265+
# bvec: sym.Matrix | None,
266+
# rscale: sym.Expr,
267+
# sac: SymbolicAssignmentCollection | None = None
268+
# ) -> Sequence[sym.Expr]:
269+
# # no point in heeding rscale here--just ignore it
270+
# if bvec is None:
271+
# raise RuntimeError("cannot use line-Taylor expansions in a setting "
272+
# "where the center-target vector is not known at coefficient "
273+
# "formation")
274+
#
275+
# tau = sym.Symbol("tau")
276+
#
277+
# line_vec = bvec
278+
# avec_line = avec + tau*line_vec
279+
# line_kernel = (
280+
# kernel.get_expression(avec_line)
281+
# / self.get_asymptotic_expression(avec_line))
282+
#
283+
# from sumpy.symbolic import USE_SYMENGINE
284+
# if USE_SYMENGINE:
285+
# from sumpy.derivative_taker import ExprDerivativeTaker
286+
# deriv_taker = ExprDerivativeTaker(line_kernel, (tau,), sac=sac,
287+
# rscale=sym.sympify(1))
288+
#
289+
# return [kernel.postprocess_at_source(deriv_taker.diff(i), avec)
290+
# .subs(tau, 0)
291+
# for i in self.get_coefficient_identifiers()]
292+
# else:
293+
# # Workaround for sympy. The automatic distribution after
294+
# # single-variable diff makes the expressions very large
295+
# # (https://github.com/sympy/sympy/issues/4596), so avoid doing
296+
# # single variable diff.
297+
# #
298+
# # See also https://gitlab.tiker.net/inducer/pytential/merge_requests/12
299+
#
300+
# return [kernel.postprocess_at_source(line_kernel.diff(tau, i), avec)
301+
# .subs(tau, 0)
302+
# for i, in self.get_coefficient_identifiers()]
294303

295304
# }}}
296305

0 commit comments

Comments
 (0)