a
    khK                     @   s   d Z ddlmZ ddlmZmZ ddlmZmZm	Z	m
Z
mZmZmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ edddgidZG dd dZdS )zJ
This module can be used to solve probelsm related to 2D parabolic arches
    )sympify)Symbolsymbols)diffsqrtcossinatanradMin)Eq)solve)	Piecewise)plot)limit)doctest_depends_on)import_modulenumpyfromlistarange)Zimport_kwargsc                   @   s   e Zd ZdZdd Zedd Zedd Zedd	 Zed
d Z	edd Z
edd Zd1ddZdd Zd2ddZd3ddZd4ddZdd Zd5ddZd6dd Zd7d!d"Zd#d$ Zed%d&d'd( Zd)d* Zd+d, Zd-d. Zd/d0 ZdS )8Archa  
    This class is used to solve problems related to a three hinged arch(determinate) structure.

    An arch is a curved vertical structure spanning an open space underneath it.

    Arches can be used to reduce the bending moments in long-span structures.


    Arches are used in structural engineering(over windows, door and even bridges)

    because they can support a very large mass placed on top of them.

    Example
    ========
    >>> from sympy.physics.continuum_mechanics.arch import Arch
    >>> a = Arch((0,0),(10,0),crown_x=5,crown_y=5)
    >>> a.get_shape_eqn
    5 - (x - 5)**2/5

    >>> from sympy.physics.continuum_mechanics.arch import Arch
    >>> a = Arch((0,0),(10,1),crown_x=6)
    >>> a.get_shape_eqn
    9/5 - (x - 6)**2/20
    c                 K   s@  d | _ t|d t|d f| _t|d t|d f| _d | _d | _d|v r\t|d | _d|v rrt|d | _| j| _ i | _i | _| j| jd| _	i | _
ddd| _d | _d | _tddtd	dtd
dtddi| _t | _t | _i | _i | _i | _i | _td| _td| _td| _td| _d | _d | _d | _d S )Nr      crown_xcrown_y)concentrateddistributedhinge)leftrightR_A_xR_A_yR_B_xR_B_yr   T)
_shape_eqnr   _left_support_right_support_crown_x_crown_yget_shape_eqn_conc_loads_distributed_loads_loads_loads_applied	_supports_memberZ_member_forcer   _reaction_forceset_points_disc_x_points_disc_y	_moment_x	_moment_y_load_x_load_yr   _moment_x_func_moment_y_func_load_x_func_load_y_func_bending_moment_shear_force_axial_force)selfleft_supportright_supportkwargs rC   T/var/www/auris/lib/python3.9/site-packages/sympy/physics/continuum_mechanics/arch.py__init__&   s>    &



zArch.__init__c                 C   s  | j r| j S td\}}}tddd}| jr| jr| j}| j}||| d  | | }||| jd || jd i}t||}	|	d || d  | }||| jd i| jd krt	dn| jr~| j}||| d  | | }||| jd || jd i}||| jd || jd i}
t||
f||f}	t
|	dk sN|	| dkrVt	d	|	| || d  |	|  }|	| | _ntd
|S )z3returns the equation of the shape of arch developedzx y caF)Zpositive   r   r   zQprovided coordinates of crown and supports are not consistent with parabolic archzYparabolic arch cannot be constructed with the provided coordinates, try providing crown_yz(please provide crown_x to construct arch)r$   r   r   r'   r(   subsr%   r   r&   
ValueErrorlenKeyError)r?   xycrF   x0Zy0Zparabola_eqneq1solutioneq2rC   rC   rD   r)   H   s2    

zArch.get_shape_eqnc                 C   s   | j S )z\
        return the position of the applied load and angle (for concentrated loads)
        )r,   r?   rC   rC   rD   	get_loadsj   s    zArch.get_loadsc                 C   s   | j S )z-
        Returns the type of support
        )r.   rS   rC   rC   rD   supportsq   s    zArch.supportsc                 C   s   | j S )z;
        Returns the position of the left support.
        )r%   rS   rC   rC   rD   r@   x   s    zArch.left_supportc                 C   s   | j S )z<
        Returns the position of the right support.
        )r&   rS   rC   rC   rD   rA      s    zArch.right_supportc                 C   s   | j S )z6
        return the reaction forces generated
        )r0   rS   rC   rC   rD   reaction_force   s    zArch.reaction_forceNc              	   C   s  t d}t d}t d}	t|}t|}t|}|| jv rBtd|dv rRtd|dkrF|du sl||k rttd	|||d
| j|< | j| || jv r| j|  |t	|||  |	|t	|| d   8  < | j
|  |t	|||  7  < nH| t	|||  |	|t	|| d   | j|< |t	|||  | j
|< d| j|< |dkr|du rbtd| jd|i}
||
|tt| |tt| ||d| j|< | j| | j| || jv r| j|  | j| d || j| d   7  < | j|  | j| d 7  < n:| j| d || j| d   | j|< | j| d | j|< || jv r| j|  | j| d |	|  8  < | j
|  | j| d 7  < n2| j| d  |	|  | j|< | j| d | j
|< d| j|< dS )aN  
        This method adds load to the Arch.

        Parameters
        ==========

            order : Integer
                Order of the applied load.

                    - For point/concentrated loads, order = -1
                    - For distributed load, order = 0

            label : String or Symbol
                The label of the load
                - should not use 'A' or 'B' as it is used for supports.

            start : Float

                    - For concentrated/point loads, start is the x coordinate
                    - For distributed loads, start is the starting position of distributed load

            mag : Sympifyable
                Magnitude of the applied load. Must be positive

            end : Float
                Required for distributed loads

                    - For concentrated/point load , end is None(may not be given)
                    - For distributed loads, end is the end position of distributed load

            angle: Sympifyable
                The angle in degrees, the load vector makes with the horizontal
                in the counter-clockwise direction.

        Examples
        ========
        For applying distributed load

        >>> from sympy.physics.continuum_mechanics.arch import Arch
        >>> a = Arch((0,0),(10,0),crown_x=5,crown_y=5)
        >>> a.apply_load(0,'C',start=3,end=5,mag=-10)

        For applying point/concentrated_loads

        >>> from sympy.physics.continuum_mechanics.arch import Arch
        >>> a = Arch((0,0),(10,0),crown_x=5,crown_y=5)
        >>> a.apply_load(-1,'C',start=2,mag=15,angle=45)

        rM   rL   rO   z(load with the given label already exists)ABz1cannot use the given label, reserved for supportsr   Nzprovide end greater than start)startendf_yrG   r   z!please provide direction of force)rL   rM   f_xr[   magangler]   r[   r   )r   r   r-   rI   rK   r+   r3   addr5   r   r7   	TypeErrorr$   rH   r   r
   r   r*   r2   r4   r6   )r?   orderlabelrY   r^   rZ   r_   rM   rL   rO   heightrC   rC   rD   
apply_load   sN    2


6"0


0.&$zArch.apply_loadc           	   	   C   s  t d}t d}t d}|| jv r| j| | j| d }| j| d }| j| d }| j| | j|  |t|||  8  < | j|  |t|||  ||t|| d   7  < | j|}t	d| d	|  n|| j
v r| j| | j
| d }| j| | j| | j|  | j
| d ||  7  < | j|  | j
| d
 || j
| d   8  < | j|  | j
| d
 8  < | j|  | j
| d 8  < | j
|}t	d| d	|  ntddS )a  
        This methods removes the load applied to the arch

        Parameters
        ==========

        label : String or Symbol
            The label of the applied load

        Examples
        ========

        >>> from sympy.physics.continuum_mechanics.arch import Arch
        >>> a = Arch((0,0),(10,0),crown_x=5,crown_y=5)
        >>> a.apply_load(0,'C',start=3,end=5,mag=-10)
        >>> a.remove_load('C')
        removed load C: {'start': 3, 'end': 5, 'f_y': -10}
        rM   rL   rO   rY   rZ   r[   rG   zremoved load : r]   zlabel not foundN)r   r+   r-   popr3   remover7   r   r5   printr*   r2   r4   r6   rI   )	r?   rc   rM   rL   rO   rY   rZ   r^   valrC   rC   rD   remove_load   s2    
 6$.zArch.remove_loadc                 C   sF   |dur|d |d f| _ |dur4|d |d f| _d| _| j| _dS )a.  
        Change position of supports.
        If not provided , defaults to the old value.
        Parameters
        ==========

            left_support: tuple (x, y)
                x: float
                    x-coordinate value of the left_support

                y: float
                    y-coordinate value of the left_support

            right_support: tuple (x, y)
                x: float
                    x-coordinate value of the right_support

                y: float
                    y-coordinate value of the right_support
        Nr   r   )r%   r&   r$   r)   )r?   r@   rA   rC   rC   rD   change_support_position+  s    zArch.change_support_positionc                 C   s   || _ || _d| _| j| _dS )a  
        Change the position of the crown/hinge of the arch

        Parameters
        ==========

            crown_x: Float
                The x coordinate of the position of the hinge
                - if not provided, defaults to old value

            crown_y: Float
                The y coordinate of the position of the hinge
                - if not provided defaults to None
        N)r'   r(   r$   r)   )r?   r   r   rC   rC   rD   change_crown_positionI  s    zArch.change_crown_positionc                 C   sH   ddg}|r&||vrt d|| jd< |rD||vr:t d|| jd< dS )a  
        Add the type for support at each end.
        Can use roller or hinge support at each end.

        Parameters
        ==========

            left_support, right_support : string
                Type of support at respective end

                    - For roller support , left_support/right_support = "roller"
                    - For hinged support, left_support/right_support = "hinge"
                    - defaults to hinge if value not provided

        Examples
        ========

        For applying roller support at right end

        >>> from sympy.physics.continuum_mechanics.arch import Arch
        >>> a = Arch((0,0),(10,0),crown_x=5,crown_y=5)
        >>> a.change_support_type(right_support="roller")

        rollerr   z%supports must only be roller or hinger   r   N)rI   r.   )r?   r@   rA   Zsupport_typesrC   rC   rD   change_support_type]  s    
zArch.change_support_typec                 C   s   || j ks$|t| jd | jd k rLtdt| jd | jd  d| j  td}t| j||| j	d d }t
|| j  | }| j	| }| j	| }|||f| _dS )z
        This method adds a member/rod at a particular height y.
        A rod is used for stability of the structure in case of a roller support.
        r   z&position of support must be between y=z and y=rL   rG   N)r(   minr%   r&   rI   r   r   r$   rH   r'   r   r/   )r?   rM   rL   rF   Zx_diffx1Zx2rC   rC   rD   
add_member  s    $(

zArch.add_memberc                 K   sJ   |du r| j S td}d|v r8|d }t| j |||dS | j ||S dS )zl
        return the shear at some x-coordinates
        if no x value provided, returns the formula
        NrL   dirrs   )r=   r   r   rH   r?   posrB   rL   rs   rC   rC   rD   shear_force_at  s    zArch.shear_force_atc                 K   sJ   |du r| j S td}d|v r8|d }t| j |||dS | j ||S dS )zu
        return the bending moment at some x-coordinates
        if no x value provided, returns the formula
        NrO   rs   rt   )r<   r   r   rH   )r?   rv   rB   rO   rs   rC   rC   rD   bending_moment_at  s    zArch.bending_moment_atc                 K   sJ   |du r| j S td}d|v r8|d }t| j |||dS | j ||S dS )z
        return the axial/normal force generated at some x-coordinate
        if no x value provided, returns the formula
        NrL   rs   rt   )r>   r   r   rH   ru   rC   rC   rD   axial_force_at  s    zArch.axial_force_atc           "      C   sR  t d}t d}t d}t| j}t| j}td| _td| _td| _td| _d}d}d}d}	|D ]T}
||
k}|| j	|
 7 }|| j
|
 7 }t||f| jdf| _t||f| jdf| _qh|D ]T}
||
k}|| j|
 7 }|	| j|
 7 }	t|	|f| jdf| _t||f| jdf| _q| j|| jd || jd | j|| jd || jd  }| j|| j|| j| j|| j|| j }| j|| jd || j| j|| j|| j | j|| jd || j | j|| j|| j }| j|| jd }| j|| jd }| jd d	ksH| jd
 d	kr\| js\td dS td\}}}}}| jd d	kr| jd
 d	kr| jd t| jd | jd krx|dkrtdnt|d}t|d}t|| | d}t|| jd | jd   || jd | jd    | d}t||| jd | j   || jd | j   d}t|||||f|||||f}
qp| jd | jd krt|d}t|d}t|| | d}t|| jd | jd   || jd | jd    | d}t|| d}t|||||f|||||f}n| jd | jd k
rpt|d}t|d}t|| | d}t|| jd | jd   || jd | jd    | d}t|| d}t|||||f|||||f}n| jd d	krj| jd t| jd | jd krt|d}t|| d}t|| | d}t|| jd | jd   || jd | jd    | d}t||| jd | j   || jd | j   d}t|||||f|||||f}
qp| jd | jd krt|d}t|| | d}t|| | d}t|| jd | jd   || jd | jd    || jd | jd    | d}t||| jd | j   || jd | j   d}t|||||f|||||f}n| jd | jd k
rpt|d}t|| | d}t|| | d}t||| jd | j   d}t||| jd | jd    || jd | jd    || jd | jd    d}t|||||f|||||f}n| jd
 d	k	r| jd t| jd | jd kr<t|d}t|| d}t|| | d}t||| jd | j   || jd | j   d}t||| jd | jd    d}t|||||f|||||f}
qp| jd | jd krt|d}t|| | d}t|| | d}t||| jd | j   d}t||| jd | jd    || jd | jd    d}t|||||f|||||f}n| jd | jd k
rpt|d}t|| | d}t|| | d}t||| jd | j   || jd | j   d}t||| jd | jd    || jd | jd    }t|||||f|||||f}nt|| | d}t|| | d}t|| jd | jd   || jd | jd    | d}t||| jd | j   || jd | j   d}t||||f||||f}| jD ]}|| | j|< 
qv| j||| j|| || || jd    || | j||i| jd     | _tt| j|}| j||  }| j||  }|t| |t |  } | t | |t|  }!| | _!|!| _"dS )a  
        This method solves for the reaction forces generated at the supports,

        and bending moment and generated in the arch and tension produced in the member if used.

        Examples
        ========

        >>> from sympy.physics.continuum_mechanics.arch import Arch
        >>> a = Arch((0,0),(10,0),crown_x=5,crown_y=5)
        >>> a.apply_load(0,'C',start=3,end=5,mag=-10)
        >>> a.solve()
        >>> a.reaction_force
        {R_A_x: 8, R_A_y: 12, R_B_x: -8, R_B_y: 8}

        >>> from sympy import Symbol
        >>> t = Symbol('t')
        >>> from sympy.physics.continuum_mechanics.arch import Arch
        >>> a = Arch((0,0),(16,0),crown_x=8,crown_y=5)
        >>> a.apply_load(0,'C',start=3,end=5,mag=t)
        >>> a.solve()
        >>> a.reaction_force
        {R_A_x: -4*t/5, R_A_y: -3*t/2, R_B_x: 4*t/5, R_B_y: -t/2}

        >>> a.bending_moment_at(4)
        -5*t/2
        rM   rL   rO   r#   r   Tr   r   rn   r   z5member must be added if any of the supports is rollerNzR_A_x R_A_y R_B_x R_B_y TrG   zDnet force in x direction not possible under the specified conditions)#r   sortedr2   r3   r   r8   r9   r:   r;   r6   r4   r5   r7   rH   r&   r%   r'   r(   r.   r/   ri   r   maxrI   r   r   r0   r$   r<   r	   r   r   r   r>   r=   )"r?   rM   rL   rO   Zdiscontinuity_points_xZdiscontinuity_points_yZaccumulated_x_momentZaccumulated_y_momentZaccumulated_x_loadZaccumulated_y_loadpointZcondZmoment_AZmoment_hinge_leftZmoment_hinge_rightZnet_xZnet_yr   r    r!   r"   TrP   rR   Zeq3Zeq4Zeq5rQ   Zsymbr_   ZfxZfyZaxial_forceZshear_forcerC   rC   rD   r     s   





  ( "



"

 

""
"
 
""
""
 
 
 z
Arch.solve)r   )modulesc                 C   s6  t d}g }|  }g }|  }||7 }| jd }| jd }t| jd | jd }| j}	t|d |d  d |	d |d  d }
|  }| 	 }||7 }| j
dur4| j
d | jd kr|| j
d d|
  g| j
d ggd	d
ddd | j
d | jd kr4|| j
d d|
  g| j
d ggd	d
ddd || jg| jd|
  ggd	dddd |
|d |d  d krt| jd|
  | j|| jd | jd f|d|||d|
  |d f|d|
  |d fddd}n\t| jd|
  | j|| jd | jd f|d|||d|
  |	d f|d|
  |	d fddd}|S )a7  
        This method returns a plot object containing the diagram of the specified arch along with the supports
        and forces applied to the structure.

        Examples
        ========

        >>> from sympy import Symbol
        >>> t = Symbol('t')
        >>> from sympy.physics.continuum_mechanics.arch import Arch
        >>> a = Arch((0,0),(40,0),crown_x=20,crown_y=12)
        >>> a.apply_load(-1,'C',8,150,angle=270)
        >>> a.apply_load(0,'D',start=20,end=40,mag=-4)
        >>> a.apply_load(-1,'E',10,t,angle=300)
        >>> p = a.draw()
        >>> p # doctest: +ELLIPSIS
        Plot object containing:
        [0]: cartesian line: 11.325 - 3*(x - 20)**2/100 for x over (0.0, 40.0)
        [1]: cartesian line: 12 - 3*(x - 20)**2/100 for x over (0.0, 40.0)
        ...
        >>> p.show()

        rL   r   r   皙?皙?NrG   {Gzt?o   ZwhitenoneargsmarkerZ
markersizecolorZmarkerfacecolor   Q?F皙?brown)markersshowannotations
rectanglesZxlimZylimZaxisZ
line_color)r   _draw_loads_draw_supportsr&   r%   rp   r(   r{   _draw_rectangles_draw_fillerr/   appendr'   r   r$   )r?   rL   r   r   r   rU   xmaxxminyminymaxZlimfillerZ	sing_plotrC   rC   rD   draw  s    

*
z	Arch.drawc                 C   s  g }| j d }| jd }t| jd | j d }| j}td| d|  td| d|  krnd| d|  }nd| d|  }| jd dkr|| jd g| jd d|  ggdd	d
dd n2|| jd g| jd d|  ggddd
dd | jd dkr6|| j d g| j d d|  ggdd	d
dd n2|| j d g| j d d|  ggddd
dd || j d g| j d d|  ggddd
dd || jd g| jd d|  ggddd
dd |S )Nr   r   r   r   r   rn   g{Gz?r      Zblackr   r   gy&1|?      r   g;On?_)r&   r%   rp   r(   absr.   r   )r?   Zsupport_markersr   r   r   r   max_diffrC   rC   rD   r     s    

(





zArch._draw_supportsc           
      C   s  g }| j d }| jd }t| jd | j d }| j}td| d|  td| d|  krnd| d|  }nd| d|  }| jd ur| jd t| jd | j d kr|| jd | jd d|  f| jd | jd  d| ddd	 n| jd | jd krH|| jd | jd d|  f| j d | jd  d| ddd	 nF|| jd | jd d|  ft| jd | jd  d| d
dd	 | jr| jD ]L}| j| d }| j| d }	||| j|d  f|	| |d dd q|S )Nr   r   r   r   rG   r   g{Gz?r   )xywidthrd   r_   r      rY   rZ   333333?oranger   r   rd   r   )	r&   r%   rp   r(   r   r/   r{   r   r+   )
r?   memberr   r   r   r   r   loadsrY   rZ   rC   rC   rD   r   R  s^    

( 



zArch._draw_rectanglesc                 C   s  g }| j d }| jd }t| jd | j d }| j}td| d|  td| d|  krnd| d|  }nd| d|  }| jD ]}| j| d }| j| d }	| j| d }
| j| d }|d	|tt|
| d
  |	t	t|
| d
  f||	fddddddddd || d| ddd|tt|
| d  |	t	t|
| d  fd q| j
D ]f}| j
| d }| j
| d }| j
| d }t|||| |d  }t||}|D ]}|dk r|d	|| j|d  f|| j|d  fddddddd n<|d	|| j|d  f|| j|d  fddddddd q|dk r|| dt| ddd|| d  | j|d!  fd n:|| dt| ddd|| d  | j|d"  fd qh|S )#Nr   r   r   r   rL   rM   r_   r^    g{Gz?
   Zboldg      ?r   Zblue)r   Z
headlengthZ	headwidthZ	facecolorZ	edgecolor)textr   xytextfontsize
fontweight
arrowpropsrf   z NgQ?)r   r   r   r   rY   rZ   r[   g      ?r   r   r   )r   r   r   r   g?z N/mrG   gffffff?g      ?)r&   r%   rp   r(   r   r*   r   r   r
   r   r+   r   r   )r?   Zload_annotationsr   r   r   r   r   loadrL   rM   r_   r^   rY   rZ   x_pointsr|   rC   rC   rD   r     s    

(
.	
	
	zArch._draw_loadsc           
      C   s  t d}g }| jd }| jd }t| jd | jd }| j}td| d|  td| d|  krvd| d|  }nd| d|  }t| jd | jd | jd | jd  ||  }|D ]J}	||	| j	
||	|d  f| jd | jd  ||  |d dd q|S )	NrL   r   r   r   r   r   r   r   )r   r&   r%   rp   r(   r   r   r   r   r$   rH   )
r?   rL   r   r   r   r   r   r   r   r|   rC   rC   rD   r     s&    

(2	zArch._draw_filler)NN)NN)NN)NN)N)N)N)__name__
__module____qualname____doc__rE   propertyr)   rT   rU   r@   rA   rV   re   rk   rl   rm   ro   rr   rw   rx   ry   r   r   r   r   r   r   r   rC   rC   rC   rD   r      s>   "
!





k3


&


 M
j_AUr   N)r   Zsympy.core.sympifyr   Zsympy.core.symbolr   r   Zsympyr   r   r   r   r	   r
   r   Zsympy.core.relationalr   Zsympy.solvers.solversr   Zsympy.functionsr   Zsympy.plottingr   r   Zsympy.utilities.decoratorr   Zsympy.external.importtoolsr   r   r   rC   rC   rC   rD   <module>   s   $