Reputation: 33
I am trying to use sympy
to start with a PDE, manipulate it symbolically to obtain a finite element formulation, and then apply code generation to obtain a code snippet for applying the results in an application.
As such, I want to start with Derivative objects, but at some point substitute a simple function in place of those derivatives, as the basis functions and derivatives of those basis functions will be stored by the code. In simple situations, this works:
>>> from sympy import *
>>> init_printing()
>>> i = Idx('i')
>>> x = Symbol('x')
>>> phi = Function('phi')(i,x)
>>> expr = Derivative(phi,x) + phi
>>> expr
d
φ(i, x) + ──(φ(i, x))
dx
>>> phi_x = Function('phi_x')(i,x)
>>> expr.subs(Derivative(phi,x), phi_x)
φ(i, x) + φₓ(i, x)
But if the derivatives appear within a summation, the substitution fails:
>>> N = Symbol('N', integer=True)
>>> expr = summation(Derivative(phi,x) + phi, (i,0,N-1))
>>> expr
N - 1
____
╲
╲ ⎛ d ⎞
╲ ⎜φ(i, x) + ──(φ(i, x))⎟
╱ ⎝ dx ⎠
╱
╱
‾‾‾‾
i = 0
>>> expr.subs(Derivative(phi,x), phi_x)
N - 1
____
╲
╲ ⎛ d ⎞
╲ ⎜φ(i, x) + ──(φ(i, x))⎟
╱ ⎝ dx ⎠
╱
╱
‾‾‾‾
i = 0
Does anyone have an idea why this might be, or what a workaround might be? TIA!
Upvotes: 0
Views: 159
Reputation: 3372
I'm not sure why this doesn't work (as it should according to expression semantics), but here's a workaround:
from sympy import *
def substitution_in_sum(expr,old_sub_expr,new_sub_expr):
if expr == old_sub_expr:
return new_sub_expr
elif expr.args==():
return expr
else:
result_list = []
for arg in expr.args:
result_list.append(substitution_in_sum(arg,old_sub_expr,new_sub_expr))
return expr.func(*tuple(result_list))
Upvotes: 1