U
    ZÊ¹j‘!  ã                   @   sš   d dl mZ d dlmZ d dlmZ d dlmZmZ d dl	m
Z
 d dlmZ ddd	d
dddgZdd„ Zdd„ Zdd	„ Zdd
„ Zdd„ Zdd„ Zdd„ ZdS )é    )Údiff)ÚS)Ú	integrate)ÚVectorÚexpress)Ú_check_frame)Ú_check_vectorÚcurlÚ
divergenceÚgradientÚis_conservativeÚis_solenoidalÚscalar_potentialÚscalar_potential_differencec                 C   sÈ   t | ƒ | dkrtdƒS t| |dd�} |  |j¡}|  |j¡}|  |j¡}tdƒ}|t||d ƒt||d ƒ |j 7 }|t||d ƒt||d ƒ |j 7 }|t||d ƒt||d ƒ |j 7 }|S )aP  
    Returns the curl of a vector field computed wrt the coordinate
    symbols of the given frame.

    Parameters
    ==========

    vect : Vector
        The vector operand

    frame : ReferenceFrame
        The reference frame to calculate the curl in

    Examples
    ========

    >>> from sympy.physics.vector import ReferenceFrame
    >>> from sympy.physics.vector import curl
    >>> R = ReferenceFrame('R')
    >>> v1 = R[1]*R[2]*R.x + R[0]*R[2]*R.y + R[0]*R[1]*R.z
    >>> curl(v1, R)
    0
    >>> v2 = R[0]*R[1]*R[2]*R.x
    >>> curl(v2, R)
    R_x*R_y*R.y - R_x*R_z*R.z

    r   T©Ú	variablesé   é   )r   r   r   ÚdotÚxÚyÚzr   )ÚvectÚframeÚvectxÚvectyÚvectzÚoutvec© r   úb/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/physics/vector/fieldfunctions.pyr	      s    &&&c                 C   sˆ   t | ƒ | dkrtjS t| |dd�} |  |j¡}|  |j¡}|  |j¡}tj}|t||d ƒ7 }|t||d ƒ7 }|t||d ƒ7 }|S )ab  
    Returns the divergence of a vector field computed wrt the coordinate
    symbols of the given frame.

    Parameters
    ==========

    vect : Vector
        The vector operand

    frame : ReferenceFrame
        The reference frame to calculate the divergence in

    Examples
    ========

    >>> from sympy.physics.vector import ReferenceFrame
    >>> from sympy.physics.vector import divergence
    >>> R = ReferenceFrame('R')
    >>> v1 = R[0]*R[1]*R[2] * (R.x+R.y+R.z)
    >>> divergence(v1, R)
    R_x*R_y + R_x*R_z + R_y*R_z
    >>> v2 = 2*R[1]*R[2]*R.y
    >>> divergence(v2, R)
    2*R_z

    r   Tr   r   r   )	r   r   ÚZeror   r   r   r   r   r   )r   r   r   r   r   Úoutr   r   r   r
   :   s    c                 C   sJ   t |ƒ tdƒ}t| |dd�} t|ƒD ]\}}|t| || ƒ| 7 }q&|S )a…  
    Returns the vector gradient of a scalar field computed wrt the
    coordinate symbols of the given frame.

    Parameters
    ==========

    scalar : sympifiable
        The scalar field to take the gradient of

    frame : ReferenceFrame
        The frame to calculate the gradient in

    Examples
    ========

    >>> from sympy.physics.vector import ReferenceFrame
    >>> from sympy.physics.vector import gradient
    >>> R = ReferenceFrame('R')
    >>> s1 = R[0]*R[1]*R[2]
    >>> gradient(s1, R)
    R_y*R_z*R.x + R_x*R_z*R.y + R_x*R_y*R.z
    >>> s2 = 5*R[0]**2*R[2]
    >>> gradient(s2, R)
    10*R_x*R_z*R.x + 5*R_x**2*R.z

    r   Tr   )r   r   r   Ú	enumerater   )Zscalarr   r   Úir   r   r   r   r   e   s    c                 C   s6   | t dƒkrdS t|  ¡ ƒd }t| |ƒ ¡ t dƒkS )aÀ  
    Checks if a field is conservative.

    Parameters
    ==========

    field : Vector
        The field to check for conservative property

    Examples
    ========

    >>> from sympy.physics.vector import ReferenceFrame
    >>> from sympy.physics.vector import is_conservative
    >>> R = ReferenceFrame('R')
    >>> is_conservative(R[1]*R[2]*R.x + R[0]*R[2]*R.y + R[0]*R[1]*R.z)
    True
    >>> is_conservative(R[2] * R.y)
    False

    r   T)r   ÚlistÚseparater	   Úsimplify©Úfieldr   r   r   r   r   Š   s    c                 C   s4   | t dƒkrdS t|  ¡ ƒd }t| |ƒ ¡ tjkS )a¶  
    Checks if a field is solenoidal.

    Parameters
    ==========

    field : Vector
        The field to check for solenoidal property

    Examples
    ========

    >>> from sympy.physics.vector import ReferenceFrame
    >>> from sympy.physics.vector import is_solenoidal
    >>> R = ReferenceFrame('R')
    >>> is_solenoidal(R[1]*R[2]*R.x + R[0]*R[2]*R.y + R[0]*R[1]*R.z)
    True
    >>> is_solenoidal(R[1] * R.y)
    False

    r   T)r   r$   r%   r
   r&   r   r    r'   r   r   r   r   ©   s    c                 C   s¬   t | ƒstdƒ‚| tdƒkr"tjS t|ƒ t| |dd�} t|ƒ}t|  	|d ¡|d ƒ}t
|dd… ƒD ]>\}}t|||d  ƒ}|  	|¡| }|t|||d  ƒ7 }qh|S )aÊ  
    Returns the scalar potential function of a field in a given frame
    (without the added integration constant).

    Parameters
    ==========

    field : Vector
        The vector field whose scalar potential function is to be
        calculated

    frame : ReferenceFrame
        The frame to do the calculation in

    Examples
    ========

    >>> from sympy.physics.vector import ReferenceFrame
    >>> from sympy.physics.vector import scalar_potential, gradient
    >>> R = ReferenceFrame('R')
    >>> scalar_potential(R.z, R) == R[2]
    True
    >>> scalar_field = 2*R[0]**2*R[1]*R[2]
    >>> grad_field = gradient(scalar_field, R)
    >>> scalar_potential(grad_field, R)
    2*R_x**2*R_y*R_z

    zField is not conservativer   Tr   r   N)r   Ú
ValueErrorr   r   r    r   r   r$   r   r   r"   r   )r(   r   Ú
dimensionsZtemp_functionr#   ÚdimZpartial_diffr   r   r   r   È   s    c                 C   sœ   t |ƒ t| tƒrt| |ƒ}n| }t| |¡|dd�}t| |¡|dd�}i }i }	t|ƒD ],\}
}| |¡|||
 < | |¡|	||
 < qZ| |	¡| |¡ S )a*  
    Returns the scalar potential difference between two points in a
    certain frame, wrt a given field.

    If a scalar field is provided, its values at the two points are
    considered. If a conservative vector field is provided, the values
    of its scalar potential function at the two points are used.

    Returns (potential at position 2) - (potential at position 1)

    Parameters
    ==========

    field : Vector/sympyfiable
        The field to calculate wrt

    frame : ReferenceFrame
        The frame to do the calculations in

    point1 : Point
        The initial Point in given frame

    position2 : Point
        The second Point in the given frame

    origin : Point
        The Point to use as reference point for position vector
        calculation

    Examples
    ========

    >>> from sympy.physics.vector import ReferenceFrame, Point
    >>> from sympy.physics.vector import scalar_potential_difference
    >>> R = ReferenceFrame('R')
    >>> O = Point('O')
    >>> P = O.locatenew('P', R[0]*R.x + R[1]*R.y + R[2]*R.z)
    >>> vectfield = 4*R[0]*R[1]*R.x + 2*R[0]**2*R.y
    >>> scalar_potential_difference(vectfield, R, O, P, O)
    2*R_x**2*R_y
    >>> Q = O.locatenew('O', 3*R.x + R.y + 2*R.z)
    >>> scalar_potential_difference(vectfield, R, P, Q, O)
    -2*R_x**2*R_y + 18

    Tr   )	r   Ú
isinstancer   r   r   Zpos_fromr"   r   Úsubs)r(   r   Zpoint1Zpoint2ÚoriginZ	scalar_fnZ	position1Z	position2Z
subs_dict1Z
subs_dict2r#   r   r   r   r   r   ú   s    /
N)Zsympy.core.functionr   Zsympy.core.singletonr   Zsympy.integrals.integralsr   Zsympy.physics.vectorr   r   Zsympy.physics.vector.framer   Zsympy.physics.vector.vectorr   Ú__all__r	   r
   r   r   r   r   r   r   r   r   r   Ú<module>   s"    þ,+%2