Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create operators.py file #12696

Merged
merged 12 commits into from Jun 7, 2017
1 change: 1 addition & 0 deletions sympy/vector/__init__.py
Expand Up @@ -13,3 +13,4 @@
from sympy.vector.point import Point
from sympy.vector.orienters import (AxisOrienter, BodyOrienter,
SpaceOrienter, QuaternionOrienter)
from sympy.vector.operators import Gradient, Divergence, Curl, gradient, curl, divergence
184 changes: 184 additions & 0 deletions sympy/vector/operators.py
@@ -0,0 +1,184 @@
from sympy.core import Expr
from sympy.vector.coordsysrect import CoordSysCartesian
from sympy.vector.vector import Vector
from sympy.vector.deloperator import Del


class Gradient(Expr):
"""
Represents unevaluated Gradient.

Examples
========

>>> from sympy.vector import CoordSysCartesian, Gradient
>>> R = CoordSysCartesian('R')
>>> s = R.x*R.y*R.z
>>> Gradient(s, R)
Gradient(R.x*R.y*R.z, R)

"""

def __new__(cls, scalar, coord_sys):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove the coord_sys dependency, let's define the operators as close as possible to how they are defined in the math books.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. I will remove this parameter and obtain it in similar manner as in funtions

obj = Expr.__new__(cls, scalar, coord_sys)
obj._scalar = scalar
obj._coord_sys = coord_sys
return obj

def doit(self):
return Del(self._coord_sys).gradient(self._scalar).doit()


class Divergence(Expr):
"""
Represents unevaluated Divergence.

Examples
========

>>> from sympy.vector import CoordSysCartesian, Gradient
>>> R = CoordSysCartesian('R')
>>> v = R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k
>>> Divergence(v, R)
Divergence(R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k, R)

"""

def __new__(cls, vect, coord_sys):
obj = Expr.__new__(cls, vect, coord_sys)
obj._vect = vect
obj._coord_sys = coord_sys
return obj

def doit(self):
return Del(self._coord_sys).dot(self._vect).doit()


class Curl(Expr):
"""
Represents unevaluated Curl.

Examples
========

>>> from sympy.vector import CoordSysCartesian, Curl
>>> R = CoordSysCartesian('R')
>>> v = R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k
>>> Curl(v, R)
Curl(R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k, R)

"""

def __new__(cls, vect, coord_sys):
obj = Expr.__new__(cls, vect, coord_sys)
obj._vect = vect
obj._coord_sys = coord_sys
return obj

def doit(self):
return Del(self._coord_sys).cross(self._vect).doit()


def gradient(scalar, coord_sys=None):
"""
Returns the vector gradient of a scalar field computed wrt the
base scalars of the given coordinate system.

Parameters
==========

scalar : SymPy Expr
The scalar field to compute the gradient of

coord_sys : CoordSysCartesian
The coordinate system to calculate the gradient in

Examples
========

>>> from sympy.vector import CoordSysCartesian, gradient
>>> R = CoordSysCartesian('R')
>>> s1 = R.x*R.y*R.z
>>> gradient(s1, R)
R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k
>>> s2 = 5*R.x**2*R.z
>>> gradient(s2, R)
10*R.x*R.z*R.i + 5*R.x**2*R.k

"""

if coord_sys is None:
coord_sys = list(scalar.atoms(CoordSysCartesian))[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put this in a private function, like _get_coord_sys_from_expr(...), this code is shared by all operators.

return Gradient(scalar, coord_sys).doit()
else:
return Gradient(scalar, coord_sys).doit()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repetition of code.



def divergence(vect, coord_sys=None):
"""
Returns the divergence of a vector field computed wrt the base
scalars of the given coordinate system.

Parameters
==========

vect : Vector
The vector operand

coord_sys : CoordSysCartesian
The coordinate system to calculate the gradient in

Examples
========

>>> from sympy.vector import CoordSysCartesian, divergence
>>> R = CoordSysCartesian('R')
>>> v1 = R.x*R.y*R.z * (R.i+R.j+R.k)
>>> divergence(v1)
R.x*R.y + R.x*R.z + R.y*R.z
>>> v2 = 2*R.y*R.z*R.j
>>> divergence(v2, R)
2*R.z

"""

if coord_sys is None:
coord_sys = vect._sys
return Curl(vect, coord_sys).doit()
else:
return Curl(vect, coord_sys).doit()


def curl(vect, coord_sys=None):
"""
Returns the curl of a vector field computed wrt the base scalars
of the given coordinate system.

Parameters
==========

vect : Vector
The vector operand

coord_sys : CoordSysCartesian
The coordinate system to calculate the gradient in

Examples
========

>>> from sympy.vector import CoordSysCartesian, curl
>>> R = CoordSysCartesian('R')
>>> v1 = R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k
>>> curl(v1)
0
>>> v2 = R.x*R.y*R.z*R.i
>>> curl(v2, R)
R.x*R.y*R.j + (-R.x*R.z)*R.k

"""

if coord_sys is None:
coord_sys = vect._sys
return Curl(vect, coord_sys).doit()
else:
return Curl(vect, coord_sys).doit()
29 changes: 29 additions & 0 deletions sympy/vector/tests/test_operators.py
@@ -0,0 +1,29 @@
from sympy.vector import CoordSysCartesian, Gradient, Divergence, Curl, VectorZero


R = CoordSysCartesian('R')
s1 = R.x*R.y*R.z
s2 = R.x + 3*R.y**2
v1 = R.x*R.i + R.z*R.z*R.j
v2 = R.x*R.i + R.y*R.j + R.z*R.k


def test_Gradient():
assert Gradient(s1, R) == Gradient(R.x*R.y*R.z, R)
assert Gradient(s2, R) == Gradient(R.x + 3*R.y**2, R)
assert Gradient(s1, R).doit() == R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k
assert Gradient(s2, R).doit() == R.i + 6*R.y*R.j


def test_Divergence():
assert Divergence(v1, R) == Divergence(R.x*R.i + R.z*R.z*R.j, R)
assert Divergence(v2, R) == Divergence(R.x*R.i + R.y*R.j + R.z*R.k, R)
assert Divergence(v1, R).doit() == 1
assert Divergence(v2, R).doit() == 3


def test_Curl():
assert Curl(v1, R) == Curl(R.x*R.i + R.z*R.z*R.j, R)
assert Curl(v2, R) == Curl(R.x*R.i + R.y*R.j + R.z*R.k, R)
assert Curl(v1, R).doit() == (-2*R.z)*R.i
assert Curl(v2, R).doit() == VectorZero()