Initialisation du repository de Beta
This commit is contained in:
commit
14985f6dbb
9469 changed files with 1903273 additions and 0 deletions
335
venv/lib/python3.12/site-packages/sympy/vector/operators.py
Normal file
335
venv/lib/python3.12/site-packages/sympy/vector/operators.py
Normal file
|
|
@ -0,0 +1,335 @@
|
|||
import collections
|
||||
from sympy.core.expr import Expr
|
||||
from sympy.core import sympify, S, preorder_traversal
|
||||
from sympy.vector.coordsysrect import CoordSys3D
|
||||
from sympy.vector.vector import Vector, VectorMul, VectorAdd, Cross, Dot
|
||||
from sympy.core.function import Derivative
|
||||
from sympy.core.add import Add
|
||||
from sympy.core.mul import Mul
|
||||
|
||||
|
||||
def _get_coord_systems(expr):
|
||||
g = preorder_traversal(expr)
|
||||
ret = set()
|
||||
for i in g:
|
||||
if isinstance(i, CoordSys3D):
|
||||
ret.add(i)
|
||||
g.skip()
|
||||
return frozenset(ret)
|
||||
|
||||
|
||||
def _split_mul_args_wrt_coordsys(expr):
|
||||
d = collections.defaultdict(lambda: S.One)
|
||||
for i in expr.args:
|
||||
d[_get_coord_systems(i)] *= i
|
||||
return list(d.values())
|
||||
|
||||
|
||||
class Gradient(Expr):
|
||||
"""
|
||||
Represents unevaluated Gradient.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.vector import CoordSys3D, Gradient
|
||||
>>> R = CoordSys3D('R')
|
||||
>>> s = R.x*R.y*R.z
|
||||
>>> Gradient(s)
|
||||
Gradient(R.x*R.y*R.z)
|
||||
|
||||
"""
|
||||
|
||||
def __new__(cls, expr):
|
||||
expr = sympify(expr)
|
||||
obj = Expr.__new__(cls, expr)
|
||||
obj._expr = expr
|
||||
return obj
|
||||
|
||||
def doit(self, **hints):
|
||||
return gradient(self._expr, doit=True)
|
||||
|
||||
|
||||
class Divergence(Expr):
|
||||
"""
|
||||
Represents unevaluated Divergence.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.vector import CoordSys3D, Divergence
|
||||
>>> R = CoordSys3D('R')
|
||||
>>> v = R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k
|
||||
>>> Divergence(v)
|
||||
Divergence(R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k)
|
||||
|
||||
"""
|
||||
|
||||
def __new__(cls, expr):
|
||||
expr = sympify(expr)
|
||||
obj = Expr.__new__(cls, expr)
|
||||
obj._expr = expr
|
||||
return obj
|
||||
|
||||
def doit(self, **hints):
|
||||
return divergence(self._expr, doit=True)
|
||||
|
||||
|
||||
class Curl(Expr):
|
||||
"""
|
||||
Represents unevaluated Curl.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.vector import CoordSys3D, Curl
|
||||
>>> R = CoordSys3D('R')
|
||||
>>> v = R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k
|
||||
>>> Curl(v)
|
||||
Curl(R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k)
|
||||
|
||||
"""
|
||||
|
||||
def __new__(cls, expr):
|
||||
expr = sympify(expr)
|
||||
obj = Expr.__new__(cls, expr)
|
||||
obj._expr = expr
|
||||
return obj
|
||||
|
||||
def doit(self, **hints):
|
||||
return curl(self._expr, doit=True)
|
||||
|
||||
|
||||
def curl(vect, doit=True):
|
||||
"""
|
||||
Returns the curl of a vector field computed wrt the base scalars
|
||||
of the given coordinate system.
|
||||
|
||||
Parameters
|
||||
==========
|
||||
|
||||
vect : Vector
|
||||
The vector operand
|
||||
|
||||
doit : bool
|
||||
If True, the result is returned after calling .doit() on
|
||||
each component. Else, the returned expression contains
|
||||
Derivative instances
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.vector import CoordSys3D, curl
|
||||
>>> R = CoordSys3D('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.x*R.y*R.j + (-R.x*R.z)*R.k
|
||||
|
||||
"""
|
||||
|
||||
coord_sys = _get_coord_systems(vect)
|
||||
|
||||
if len(coord_sys) == 0:
|
||||
return Vector.zero
|
||||
elif len(coord_sys) == 1:
|
||||
coord_sys = next(iter(coord_sys))
|
||||
i, j, k = coord_sys.base_vectors()
|
||||
x, y, z = coord_sys.base_scalars()
|
||||
h1, h2, h3 = coord_sys.lame_coefficients()
|
||||
vectx = vect.dot(i)
|
||||
vecty = vect.dot(j)
|
||||
vectz = vect.dot(k)
|
||||
outvec = Vector.zero
|
||||
outvec += (Derivative(vectz * h3, y) -
|
||||
Derivative(vecty * h2, z)) * i / (h2 * h3)
|
||||
outvec += (Derivative(vectx * h1, z) -
|
||||
Derivative(vectz * h3, x)) * j / (h1 * h3)
|
||||
outvec += (Derivative(vecty * h2, x) -
|
||||
Derivative(vectx * h1, y)) * k / (h2 * h1)
|
||||
|
||||
if doit:
|
||||
return outvec.doit()
|
||||
return outvec
|
||||
else:
|
||||
if isinstance(vect, (Add, VectorAdd)):
|
||||
from sympy.vector import express
|
||||
try:
|
||||
cs = next(iter(coord_sys))
|
||||
args = [express(i, cs, variables=True) for i in vect.args]
|
||||
except ValueError:
|
||||
args = vect.args
|
||||
return VectorAdd.fromiter(curl(i, doit=doit) for i in args)
|
||||
elif isinstance(vect, (Mul, VectorMul)):
|
||||
vector = [i for i in vect.args if isinstance(i, (Vector, Cross, Gradient))][0]
|
||||
scalar = Mul.fromiter(i for i in vect.args if not isinstance(i, (Vector, Cross, Gradient)))
|
||||
res = Cross(gradient(scalar), vector).doit() + scalar*curl(vector, doit=doit)
|
||||
if doit:
|
||||
return res.doit()
|
||||
return res
|
||||
elif isinstance(vect, (Cross, Curl, Gradient)):
|
||||
return Curl(vect)
|
||||
else:
|
||||
raise ValueError("Invalid argument for curl")
|
||||
|
||||
|
||||
def divergence(vect, doit=True):
|
||||
"""
|
||||
Returns the divergence of a vector field computed wrt the base
|
||||
scalars of the given coordinate system.
|
||||
|
||||
Parameters
|
||||
==========
|
||||
|
||||
vector : Vector
|
||||
The vector operand
|
||||
|
||||
doit : bool
|
||||
If True, the result is returned after calling .doit() on
|
||||
each component. Else, the returned expression contains
|
||||
Derivative instances
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.vector import CoordSys3D, divergence
|
||||
>>> R = CoordSys3D('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)
|
||||
2*R.z
|
||||
|
||||
"""
|
||||
coord_sys = _get_coord_systems(vect)
|
||||
if len(coord_sys) == 0:
|
||||
return S.Zero
|
||||
elif len(coord_sys) == 1:
|
||||
if isinstance(vect, (Cross, Curl, Gradient)):
|
||||
return Divergence(vect)
|
||||
# TODO: is case of many coord systems, this gets a random one:
|
||||
coord_sys = next(iter(coord_sys))
|
||||
i, j, k = coord_sys.base_vectors()
|
||||
x, y, z = coord_sys.base_scalars()
|
||||
h1, h2, h3 = coord_sys.lame_coefficients()
|
||||
vx = _diff_conditional(vect.dot(i), x, h2, h3) \
|
||||
/ (h1 * h2 * h3)
|
||||
vy = _diff_conditional(vect.dot(j), y, h3, h1) \
|
||||
/ (h1 * h2 * h3)
|
||||
vz = _diff_conditional(vect.dot(k), z, h1, h2) \
|
||||
/ (h1 * h2 * h3)
|
||||
res = vx + vy + vz
|
||||
if doit:
|
||||
return res.doit()
|
||||
return res
|
||||
else:
|
||||
if isinstance(vect, (Add, VectorAdd)):
|
||||
return Add.fromiter(divergence(i, doit=doit) for i in vect.args)
|
||||
elif isinstance(vect, (Mul, VectorMul)):
|
||||
vector = [i for i in vect.args if isinstance(i, (Vector, Cross, Gradient))][0]
|
||||
scalar = Mul.fromiter(i for i in vect.args if not isinstance(i, (Vector, Cross, Gradient)))
|
||||
res = Dot(vector, gradient(scalar)) + scalar*divergence(vector, doit=doit)
|
||||
if doit:
|
||||
return res.doit()
|
||||
return res
|
||||
elif isinstance(vect, (Cross, Curl, Gradient)):
|
||||
return Divergence(vect)
|
||||
else:
|
||||
raise ValueError("Invalid argument for divergence")
|
||||
|
||||
|
||||
def gradient(scalar_field, doit=True):
|
||||
"""
|
||||
Returns the vector gradient of a scalar field computed wrt the
|
||||
base scalars of the given coordinate system.
|
||||
|
||||
Parameters
|
||||
==========
|
||||
|
||||
scalar_field : SymPy Expr
|
||||
The scalar field to compute the gradient of
|
||||
|
||||
doit : bool
|
||||
If True, the result is returned after calling .doit() on
|
||||
each component. Else, the returned expression contains
|
||||
Derivative instances
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.vector import CoordSys3D, gradient
|
||||
>>> R = CoordSys3D('R')
|
||||
>>> s1 = R.x*R.y*R.z
|
||||
>>> gradient(s1)
|
||||
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)
|
||||
10*R.x*R.z*R.i + 5*R.x**2*R.k
|
||||
|
||||
"""
|
||||
coord_sys = _get_coord_systems(scalar_field)
|
||||
|
||||
if len(coord_sys) == 0:
|
||||
return Vector.zero
|
||||
elif len(coord_sys) == 1:
|
||||
coord_sys = next(iter(coord_sys))
|
||||
h1, h2, h3 = coord_sys.lame_coefficients()
|
||||
i, j, k = coord_sys.base_vectors()
|
||||
x, y, z = coord_sys.base_scalars()
|
||||
vx = Derivative(scalar_field, x) / h1
|
||||
vy = Derivative(scalar_field, y) / h2
|
||||
vz = Derivative(scalar_field, z) / h3
|
||||
|
||||
if doit:
|
||||
return (vx * i + vy * j + vz * k).doit()
|
||||
return vx * i + vy * j + vz * k
|
||||
else:
|
||||
if isinstance(scalar_field, (Add, VectorAdd)):
|
||||
return VectorAdd.fromiter(gradient(i) for i in scalar_field.args)
|
||||
if isinstance(scalar_field, (Mul, VectorMul)):
|
||||
s = _split_mul_args_wrt_coordsys(scalar_field)
|
||||
return VectorAdd.fromiter(scalar_field / i * gradient(i) for i in s)
|
||||
return Gradient(scalar_field)
|
||||
|
||||
|
||||
class Laplacian(Expr):
|
||||
"""
|
||||
Represents unevaluated Laplacian.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.vector import CoordSys3D, Laplacian
|
||||
>>> R = CoordSys3D('R')
|
||||
>>> v = 3*R.x**3*R.y**2*R.z**3
|
||||
>>> Laplacian(v)
|
||||
Laplacian(3*R.x**3*R.y**2*R.z**3)
|
||||
|
||||
"""
|
||||
|
||||
def __new__(cls, expr):
|
||||
expr = sympify(expr)
|
||||
obj = Expr.__new__(cls, expr)
|
||||
obj._expr = expr
|
||||
return obj
|
||||
|
||||
def doit(self, **hints):
|
||||
from sympy.vector.functions import laplacian
|
||||
return laplacian(self._expr)
|
||||
|
||||
|
||||
def _diff_conditional(expr, base_scalar, coeff_1, coeff_2):
|
||||
"""
|
||||
First re-expresses expr in the system that base_scalar belongs to.
|
||||
If base_scalar appears in the re-expressed form, differentiates
|
||||
it wrt base_scalar.
|
||||
Else, returns 0
|
||||
"""
|
||||
from sympy.vector.functions import express
|
||||
new_expr = express(expr, base_scalar.system, variables=True)
|
||||
arg = coeff_1 * coeff_2 * new_expr
|
||||
return Derivative(arg, base_scalar) if arg else S.Zero
|
||||
Loading…
Add table
Add a link
Reference in a new issue