o
    3IhK                     @   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)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_member_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 rE   f/home/air/sanwanet/gpt-api/venv/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)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)rA   xycrH   x0y0parabola_eqneq1solutioneq2rE   rE   rF   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-   rA   rE   rE   rF   	get_loadsj      zArch.get_loadsc                 C   rX   )z-
        Returns the type of support
        )r/   rY   rE   rE   rF   supportsq   r[   zArch.supportsc                 C   rX   )z;
        Returns the position of the left support.
        )r&   rY   rE   rE   rF   rB   x   r[   zArch.left_supportc                 C   rX   )z<
        Returns the position of the right support.
        )r'   rY   rE   rE   rF   rC      r[   zArch.right_supportc                 C   rX   )z6
        return the reaction forces generated
        )r2   rY   rE   rE   rF   reaction_force   r[   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)

        rP   rO   rR   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_yrJ   r   z!please provide direction of force)rO   rP   f_xrb   maganglerd   rb   r   )r   r   r.   rL   rN   r,   r5   addr7   r   r9   	TypeErrorr%   rK   r   r
   r   r+   r4   r6   r8   )rA   orderlabelr`   re   ra   rf   rP   rO   rR   heightrE   rE   rF   
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}
        rP   rO   rR   r`   ra   rb   rJ   zremoved load : rd   zlabel not foundN)r   r,   r.   popr5   remover9   r   r7   printr+   r4   r6   r8   rL   )	rA   rj   rP   rO   rR   r`   ra   re   valrE   rE   rF   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*   )rA   rB   rC   rE   rE   rF   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*   )rA   r   r   rE   rE   rF   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)rL   r/   )rA   rB   rC   support_typesrE   rE   rF   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=rO   rJ   N)r)   minr&   r'   rL   r   r   r%   rK   r(   r   r0   )rA   rP   rO   rH   x_diffx1x2rE   rE   rF   
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
        NrO   dirr~   )r?   r   r   rK   rA   posrD   rO   r~   rE   rE   rF   shear_force_at     zArch.shear_force_atc                 K   r}   )zu
        return the bending moment at some x-coordinates
        if no x value provided, returns the formula
        NrR   r~   r   )r>   r   r   rK   )rA   r   rD   rR   r~   rE   rE   rF   bending_moment_at  r   zArch.bending_moment_atc                 K   r}   )z
        return the axial/normal force generated at some x-coordinate
        if no x value provided, returns the formula
        NrO   r~   r   )r@   r   r   rK   r   rE   rE   rF   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
        rP   rO   rR   r$   r   Tr   r   ru   r   z5member must be added if any of the supports is rollerNzR_A_x R_A_y R_B_x R_B_y TrJ   zDnet force in x direction not possible under the specified conditions)#r   sortedr4   r5   r   r:   r;   r<   r=   r8   r6   r7   r9   rK   r'   r&   r(   r)   r/   r0   rp   r   maxrL   r   r   r2   r%   r>   r	   r   r   r   r@   r?   )"rA   rP   rO   rR   discontinuity_points_xdiscontinuity_points_yaccumulated_x_momentaccumulated_y_momentaccumulated_x_loadaccumulated_y_loadpointcondmoment_Amoment_hinge_leftmoment_hinge_rightnet_xnet_yr    r!   r"   r#   TrU   rW   eq3eq4eq5rV   symbrf   fxfyaxial_forceshear_forcerE   rE   rF   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()

        rO   r   r   皙?皙?NrJ   {Gzt?o   whitenoneargsmarker
markersizecolormarkerfacecolor   Q?F皙?brown)markersshowannotations
rectanglesxlimylimaxis
line_color)r   _draw_loads_draw_supportsr'   r&   rx   r)   r   _draw_rectangles_draw_fillerr0   appendr(   r   r%   )rA   rO   r   r   r   r\   xmaxxminyminymaxlimfiller	sing_plotrE   rE   rF   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   ru   g{Gz?r      blackr   r   gy&1|?      r   g;On?_)r'   r&   rx   r)   absr/   r   )rA   support_markersr   r   r   r   max_diffrE   rE   rF   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   rJ   r   g{Gz?r   )xywidthrk   rf   r      r`   ra   333333?oranger   r   rk   r   )	r'   r&   rx   r)   r   r0   r   r   r,   )
rA   memberr   r   r   r   r   loadsr`   ra   rE   rE   rF   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   rO   rP   rf   re    g{Gz?
   boldg      ?r   blue)r   
headlength	headwidth	facecolor	edgecolor)textr   xytextfontsize
fontweight
arrowpropsrm   z NgQ?)r   r   r   r   r`   ra   rb   g      ?r   r   r   )r   r   r   r   g?z N/mrJ   gffffff?g      ?)r'   r&   rx   r)   r   r+   r   r   r
   r   r,   r   r   )rA   load_annotationsr   r   r   r   r   loadrO   rP   rf   re   r`   ra   x_pointsr   rE   rE   rF   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 )	NrO   r   r   r   r   r   r   r   )r   r'   r&   rx   r)   r   r   r   r   r%   rK   )
rA   rO   r   r   r   r   r   r   r   r   rE   rE   rF   r     s&   

(2	zArch._draw_filler)NN)N)__name__
__module____qualname____doc__rG   propertyr*   rZ   r\   rB   rC   r]   rl   rr   rs   rt   rw   r|   r   r   r   r   r   r   r   r   r   r   rE   rE   rE   rF   r      s@    "
!





k
3

&


 M
j_AUr   N)r   sympy.core.sympifyr   sympy.core.symbolr   r   sympyr   r   r   r   r	   r
   r   sympy.core.relationalr   sympy.solvers.solversr   sympy.functionsr   sympy.plottingr   r   sympy.utilities.decoratorr   sympy.external.importtoolsr   r   r   rE   rE   rE   rF   <module>   s    $