Pergunta

Playing around a lot with sympy lately, I came up with the problem of calculating divergence and gradient for scalar and vector fields. What I want to do for now is solving the heat equation, i.e.

d/dt u(x,t) - a * lap(u(x,t)) = 0, with lap(x) = (div(grad(x))

on a scalar field. Since I could not find lap, div and grad in sympy.physics.mechanics, I tried to implement them by myself

from sympy import *
from sympy.physics.mechanics import *


o = ReferenceFrame('o')

x,y,z = symbols('x y z')


class div(Function):
    @classmethod
    def eval(cls, F):
        return F.diff(x, o).dot(o.x)+F.diff(y, o).dot(o.y)+F.diff(z, o).dot(o.z)

class grad(Function):
    @classmethod
    def eval(cls, F):
        return o.x * F.diff(x) + o.y * F.diff(y) + o.z * F.diff(z)

f = x**2 + y**3 + z*0.5

print grad(f)
print type(grad(f))
print div(grad(f))

unluckily, this gives

2*x*o.x + 3*y**2*o.y + 0.500000000000000*o.z
Traceback (most recent call last):
  File "/home/fortmeier/Desktop/autokernel/autokernel/tools/GenerateCode.py", line 24, in <module>
    print div(grad(f))
  File "/usr/local/lib/python2.7/dist-packages/sympy/core/cache.py", line 93, in wrapper
    r = func(*args, **kw_args)
  File "/usr/local/lib/python2.7/dist-packages/sympy/core/function.py", line 368, in __new__
    result = super(Function, cls).__new__(cls, *args, **options)
  File "/usr/local/lib/python2.7/dist-packages/sympy/core/cache.py", line 93, in wrapper
    r = func(*args, **kw_args)
  File "/usr/local/lib/python2.7/dist-packages/sympy/core/function.py", line 188, in __new__
    args = list(map(sympify, args))
  File "/usr/local/lib/python2.7/dist-packages/sympy/core/sympify.py", line 313, in sympify
    expr = parse_expr(a, local_dict=locals, transformations=transformations, evaluate=evaluate)
  File "/usr/local/lib/python2.7/dist-packages/sympy/parsing/sympy_parser.py", line 757, in parse_expr
    return eval_expr(code, local_dict, global_dict)
  File "/usr/local/lib/python2.7/dist-packages/sympy/parsing/sympy_parser.py", line 691, in eval_expr
    code, global_dict, local_dict)  # take local objects in preference
  File "<string>", line 1, in <module>
AttributeError: 'Symbol' object has no attribute 'x'
[Finished in 0.3s with exit code 1]

I know that I could do something with the galgebra module, but first I'd like to understand more whats going on here. The question thus is what am I missing?

Foi útil?

Solução

This looks like a bug in SymPy. sympify(ReferenceFrame('o').x) does not work.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top