2727import math
2828from abc import ABC , abstractmethod
2929from dataclasses import dataclass , field
30- from typing import TYPE_CHECKING , Any , cast
30+ from typing import TYPE_CHECKING , cast
3131
3232from typing_extensions import override
3333
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 )
118117class 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