Lambdify or evaluate CoordSys3D… here is a solution to the problem.
Lambdify or evaluate CoordSys3D
How do I calculate points on a Sympy CoordSys3D expression?
With the Sympy physical module, this process works as expected:
from sympy import *
from sympy.physics.vector import ReferenceFrame, CoordinateSym, divergence
R = ReferenceFrame('R')
field = R[0]*R[1]*R[2]*(R.x+R.y+R.z)
div = divergence(vect=field, frame=R)
div_func = lambdify([R[0], R[1], R[2]], div, modules='numpy')
print('Function evaluated at a point = {}'.format(div_func(1,2,8)))
However, if I use CoordSys3D
instead, the process of lambdify is not clear :
from sympy.vector import CoordSys3D, divergence, curl
A = CoordSys3D('A')
field = A.x*A.y*A.z*(A.i + A.j + A.k)
div = divergence(field)
# How do I lambdify / evaluate this?
# This fails:
# File "<lambdifygenerated-5>", line 1
# def _lambdifygenerated(A.x, A.y, A.z):
# SyntaxError: invalid syntax
# div_func = lambdify([A.x, A.y, A.z], div, modules='numpy')
# This fails:
# "name 'x' is not defined"
# div_func = lambdify([x, y, z], div, modules='numpy')
print('Function evaluated at a point = {}'.format(div_func(1,2,8)))
Some observations:
R[0]
is asympy.physics.vector.frame.coordinateSym
A.x
is asympy.vector.scalar.BaseScalar
CoordSys3D
seems to be the format I want, especially since the support for spherical coordinate systems is simple.
For example:
A = CoordSys3D('A', transformation='spherical') # transformation requires Sympy 1.2
vec_field = a*A.r**2*A.i + c*cos(A.theta)/A.r*A.j + b * A.k
div = divergence(vec_field)
Solution
It looks like lambdify
didn’t interpret A.x
correctly (which it should) when generating the code, so you’ll have to replace it with symbols.
vars = symbols('A.x A.y A.z')
div_func = lambdify(vars, div.subs(dict(zip([A.x, A.y, A.z], vars))), modules='numpy')
print(div_func(1, 2, 8)) # 26
It
doesn’t matter what the symbol vars
is called, I named them “A.x” and so on just to be consistent. They can also be vars = symbols('v0:3').