I wrote a Python program to symbolically compute the Magnetic Field from a given Electric field. It computes the curl of the E field correctly, but then when I try to integrate that wrt. time, Python throws an error.
Here is the code:
import numpy as np
import sympy as smp
import matplotlib.pyplot as plt
from sympy import *
from sympy import symbols
from sympy.physics.vector import divergence
from sympy.physics.vector import curl
from sympy.physics.vector import ReferenceFrame
from sympy import diff
from sympy import exp
from sympy import integrate
R = ReferenceFrame('R')
# Variables
X = R[0]
Y = R[1]
Z = R[2]
# Basis Unit Vectors
i = R.x
j = R.y
k = R.z
# Symbols
t = symbols('t')
Ex, Ey, Ez = symbols('Ex Ey Ez')
wavenumber = symbols('k')
E_0 = symbols('E_0') # Amplitude of E field
w = symbols('w')
Ey = E_0 * smp.exp( 1j * (wavenumber*X - w*t ))
E = Ex*i Ey*j Ez*k
init_printing(use_unicode=True, wrap_line=False)
# curl E = - dB/dt
# integrate( (curl E) , t ) = - B
jimmy = curl( E, R )
smp.integrate( jimmy, t )
The error thrown is from the final line of code, when I call integrate():
AttributeError: 'Symbol' object has no attribute 'z'
What gives?
CodePudding user response:
Usually we ask users to include the full traceback when asking about errors.
In a sympy
context I expect to see "won't integrate" description when result is an expression containing the integral sign. Similarly for "can't solve" results, where the result is the original expression, or a barely simplified one.
Your case is an actual error.
In [6]: jimmy = curl( E, R )
In [7]: jimmy
Out[7]:
1.0⋅ⅈ⋅(Rₓ⋅k - t⋅w)
1.0⋅ⅈ⋅E₀⋅k⋅ℯ r_z
In [8]: smp.integrate( jimmy, t )
/usr/local/lib/python3.8/dist-packages/sympy/core/sympify.py:456: SymPyDeprecationWarning:
String fallback in sympify has been deprecated since SymPy 1.6. Use
sympify(str(obj)) or sympy.core.sympify.converter or obj._sympy_
instead. See https://github.com/sympy/sympy/issues/18066 for more
info.
SymPyDeprecationWarning(
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
ValueError: Error from parse_expr with transformed code: "Float ('1.0' )*I *Symbol ('E_0' )*Symbol ('k' )*exp (Float ('1.0' )*I *(Symbol ('R_x' )*Symbol ('k' )-Symbol ('t' )*Symbol ('w' )))*Symbol ('R' ).z "
The above exception was the direct cause of the following exception:
AttributeError Traceback (most recent call last)
<ipython-input-8-8d40c4ce949f> in <module>
----> 1 smp.integrate( jimmy, t )
/usr/local/lib/python3.8/dist-packages/sympy/integrals/integrals.py in integrate(meijerg, conds, risch, heurisch, manual, *args, **kwargs)
1566 'manual': manual
1567 }
-> 1568 integral = Integral(*args, **kwargs)
1569
1570 if isinstance(integral, Integral):
/usr/local/lib/python3.8/dist-packages/sympy/integrals/integrals.py in __new__(cls, function, *symbols, **assumptions)
89 useinstead="the as_expr or integrate methods of Poly").warn()
90
---> 91 obj = AddWithLimits.__new__(cls, function, *symbols, **assumptions)
92 return obj
93
/usr/local/lib/python3.8/dist-packages/sympy/concrete/expr_with_limits.py in __new__(cls, function, *symbols, **assumptions)
496
497 def __new__(cls, function, *symbols, **assumptions):
--> 498 pre = _common_new(cls, function, *symbols, **assumptions)
499 if type(pre) is tuple:
500 function, limits, orientation = pre
/usr/local/lib/python3.8/dist-packages/sympy/concrete/expr_with_limits.py in _common_new(cls, function, *symbols, **assumptions)
23 (function, limits, orientation). This code is common to
24 both ExprWithLimits and AddWithLimits."""
---> 25 function = sympify(function)
26
27 if isinstance(function, Equality):
/usr/local/lib/python3.8/dist-packages/sympy/core/sympify.py in sympify(a, locals, convert_xor, strict, rational, evaluate)
477 try:
478 a = a.replace('\n', '')
--> 479 expr = parse_expr(a, local_dict=locals, transformations=transformations, evaluate=evaluate)
480 except (TokenError, SyntaxError) as exc:
481 raise SympifyError('could not parse %r' % a, exc)
....
AttributeError: 'Symbol' object has no attribute 'z'
So while:
In [9]: R.z
Out[9]: r_z
it has replaced that with:
In [10]: parse_expr(Symbol ('R' ).z)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-10-60a85cf12db4> in <module>
----> 1 parse_expr(Symbol ('R' ).z)
AttributeError: 'Symbol' object has no attribute 'z'
I don't know enough sympy
to understand the issue, but it is more informative than "won't integrate".
CodePudding user response:
I got the code to work. I used CoordSys3d from sympy.vector, instead of ReferenceFrame .
import numpy as np
import sympy as smp
import matplotlib.pyplot as plt
from sympy import *
from sympy import symbols
from sympy.vector import divergence
from sympy.vector import curl
from sympy import diff
from sympy import exp
from sympy import integrate
from sympy.vector import CoordSys3D
R = CoordSys3D('R')
# Variables
X, Y, Z = symbols('X Y Z')
X = R.x
Y = R.y
Z = R.z
# Basis Unit Vectors
i,j,k = symbols('i j k')
i = R.i
j = R.j
k = R.k
# Symbols
x,t = symbols('x t')
Ex = smp.Function('Ex')(x,t)
Ey = smp.Function('Ey')(x,t)
Ez = smp.Function('Ez')(x,t)
wavenumber = symbols('k')
E_0 = symbols('E_0') # Amplitude of E field
w = symbols('w' , real=True, positive=True)
# Define Ey(x,t)
Ey = E_0 * smp.exp( 1j * (wavenumber*X - w*t ))
# The Electric Field
E = Ex*i Ey*j Ez*k
init_printing(use_unicode=True, wrap_line=False)
# curl E = - dB/dt
# integrate( (curl E) , t ) = - B
jimmy = curl( E )
B = -integrate( jimmy, t )
pprint( B )
B = -integrate( jimmy, t ).doit()
pprint( B )