o
    GZhK                     @   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d1ddZd1ddZd1ddZdd Zd2ddZd2dd Zd2d!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 )3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 r9t|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   U/var/www/auris/lib/python3.10/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r^t	d|S | jr| j}||| d  | | }||| jd || jd i}||| jd || jd i}
t||
f||f}	t
|	dk s|	| dkrt	d	|	| || d  |	|  }|	| | _|S td
)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   s4   

zArch.get_shape_eqnc                 C      | j S )z\
        return the position of the applied load and angle (for concentrated loads)
        )r,   r?   rC   rC   rD   	get_loadsj      zArch.get_loadsc                 C   rS   )z-
        Returns the type of support
        )r.   rT   rC   rC   rD   supportsq   rV   zArch.supportsc                 C   rS   )z;
        Returns the position of the left support.
        )r%   rT   rC   rC   rD   r@   x   rV   zArch.left_supportc                 C   rS   )z<
        Returns the position of the right support.
        )r&   rT   rC   rC   rD   rA      rV   zArch.right_supportc                 C   rS   )z6
        return the reaction forces generated
        )r0   rT   rC   rC   rD   reaction_force   rV   zArch.reaction_forceNc              	   C   s  t d}t d}t d}	t|}t|}t|}|| jv r!td|dv r)td|dkr|du s5||k r9td	|||d
| j|< | j| || jv ry| j|  |t	|||  |	|t	|| d   8  < | j
|  |t	|||  7  < n$| t	|||  |	|t	|| d   | j|< |t	|||  | j
|< d| j|< |dkrk|du rt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 rK| j|  | j| d |	|  8  < | j
|  | j| d 7  < n| j| d  |	|  | j|< | j| d | j
|< d| j|< dS 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labelr[   r`   r\   ra   rM   rL   rO   heightrC   rC   rD   
apply_load   sP   2

6"0

0.&$zArch.apply_loadc           	   	   C   s  t d}t d}t d}|| jv ro| j| | j| d }| j| d }| j| d }| j| | j|  |t|||  8  < | j|  |t|||  ||t|| d   7  < | j|}t	d| d	|  dS || 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	|  dS td)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   r[   r\   r]   rG   zremoved load : r_   zlabel not foundN)r   r+   r-   popr3   remover7   r   r5   printr*   r2   r4   r6   rI   )	r?   re   rM   rL   rO   r[   r\   r`   valrC   rC   rD   remove_load   s2   
 6
$.zArch.remove_loadc                 C   sF   |dur|d |d f| _ |dur|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   sL   ddg}|r||vrt d|| jd< |r$||vrt d|| jd< dS 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 r&t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   F   |du r| j S td}d|v r|d }t| j |||dS | j ||S )zl
        return the shear at some x-coordinates
        if no x value provided, returns the formula
        NrL   dirrv   )r=   r   r   rH   r?   posrB   rL   rv   rC   rC   rD   shear_force_at     zArch.shear_force_atc                 K   ru   )zu
        return the bending moment at some x-coordinates
        if no x value provided, returns the formula
        NrO   rv   rw   )r<   r   r   rH   )r?   ry   rB   rO   rv   rC   rC   rD   bending_moment_at  r{   zArch.bending_moment_atc                 K   ru   )z
        return the axial/normal force generated at some x-coordinate
        if no x value provided, returns the formula
        NrL   rv   rw   )r>   r   r   rH   rx   rC   rC   rD   axial_force_at  r{   zArch.axial_force_atc           "      C   sT  t d}t d}t d}t| j}t| j}td| _td| _td| _td| _d}d}d}d}	|D ]*}
||
k}|| j	|
 7 }|| j
|
 7 }t||f| jdf| _t||f| jdf| _q4|D ]*}
||
k}|| j|
 7 }|	| j|
 7 }	t|	|f| jdf| _t||f| jdf| _qa| 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s$| jd
 d	kr.| js.td dS td\}}}}}| jd d	kra| jd
 d	kra| jd t| jd | jd kr|dkratdt|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}n~| 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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 d	kr| 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}nc| jd | jd krKt|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rt|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}n| jd | jd kr}t|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rt|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}nUt|| | 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|< q<| 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   rp   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/   rk   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symbra   ZfxfyZaxial_forceZshear_forcerC   rC   rD   r     s  





  ( "


"

"

"
"
"
"
""
 

 
z
Arch.solve)r   )modulesc                 C   s2  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r| j
d | jd kru|| j
d d|
  g| j
d ggd	d
ddd | j
d | jd kr|| 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}|S 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   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%   rr   r(   r   _draw_rectangles_draw_fillerr/   appendr'   r   r$   )r?   rL   r   r   r   rW   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r7d| d|  }nd| d|  }| jd dkr`|| jd g| jd d|  ggdd	d
dd n|| jd g| jd d|  ggddd
dd | jd dkr|| j d g| j d d|  ggdd	d
dd n|| 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   rp   g{Gz?r      blackr   r   gy&1|?      r   g;On?_)r&   r%   rr   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r7d| d|  }nd| d|  }| jd ur| jd t| jd | j d krv|| jd | jd d|  f| jd | jd  d| ddd	 nO| 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 d|  ft| jd | jd  d| d
dd	 | jr| jD ]%}| j| d }| j| d }	||| j|d  f|	| |d dd q|S )Nr   r   r   r   rG   r   g{Gz?r   )xywidthrf   ra   r      r[   r\   333333?oranger   r   rf   r   )	r&   r%   rr   r(   r   r/   r   r   r+   )
r?   memberr   r   r   r   r   loadsr[   r\   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r7d| d|  }nd| d|  }| jD ]n}| 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 qB| j
D ]}| j
| d }| j
| d }| j
| d }t|||| |d  }t||}|D ]D}|dk r|d	|| j|d  f|| j|d  fddddddd q|d	|| j|d  f|| j|d  fddddddd q|dk rH|| dt| ddd|| d  | j|d!  fd q|| dt| ddd|| d  | j|d"  fd q|S )#Nr   r   r   r   rL   rM   ra   r`    g{Gz?
   boldg      ?r   blue)r   Z
headlengthZ	headwidthZ	facecolorZ	edgecolor)textr   xytextfontsize
fontweight
arrowpropsrh   z NgQ?)r   r   r   r   r[   r\   r]   g      ?r   r   r   )r   r   r   r   g?z N/mrG   gffffff?g      ?)r&   r%   rr   r(   r   r*   r   r   r
   r   r+   r   r   )r?   Zload_annotationsr   r   r   r   r   loadrL   rM   ra   r`   r[   r\   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r;d| d|  }nd| d|  }t| jd | jd | jd | jd  ||  }|D ]%}	||	| j	
||	|d  f| jd | jd  ||  |d dd q^|S )	NrL   r   r   r   r   r   r   r   )r   r&   r%   rr   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)N)__name__
__module____qualname____doc__rE   propertyr)   rU   rW   r@   rA   rX   rg   rm   rn   ro   rq   rt   rz   r|   r}   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    $