K izdZddlmZddlmZmZddlmZmZm Z m Z m Z m Z m Z mZddlmZddlmZddlmZddlmZGd d Zy ) zA This module can be used to solve problems related to 2D Cables. )sympify)Symbolsymbols)sincospiatandiff Piecewisesolverad)sqrt)linsolve)Matrix)plotceZdZdZdZedZedZedZedZ edZ edZ ed Z ed Z d Zd Zd ZdZdZdZdZdZdZdZdZy)Cablea Cables are structures in engineering that support the applied transverse loads through the tensile resistance developed in its members. Cables are widely used in suspension bridges, tension leg offshore platforms, transmission lines, and find use in several other engineering applications. Examples ======== A cable is supported at (0, 10) and (10, 10). Two point loads acting vertically downwards act on the cable, one with magnitude 3 kN and acting 2 meters from the left support and 3 meters below it, while the other with magnitude 2 kN is 6 meters from the left support and 6 meters below it. >>> from sympy.physics.continuum_mechanics.cable import Cable >>> c = Cable(('A', 0, 10), ('B', 10, 10)) >>> c.apply_load(-1, ('P', 2, 7, 3, 270)) >>> c.apply_load(-1, ('Q', 6, 4, 2, 270)) >>> c.loads {'distributed': {}, 'point_load': {'P': [3, 270], 'Q': [2, 270]}} >>> c.loads_position {'P': [2, 7], 'Q': [6, 4]} cNg|_g|_i|_g|_iid|_i|_d|_i|_i|_td|_ td|_ d|_ d|_ |d|dk(r td|d|dk(r tdt|d}t|d}||g|j|d<t|d}t|d}||g|j|d<|d|dkr|jj||jj||jj||jj||jj|d|jj|dn|jj||jj||jj||jj||jj|d|jj|d|jD]>}d|jt!d|zd z<d|jt!d|zd z<@y) a Initializes the class. Parameters ========== support_1 and support_2 are tuples of the form (label, x, y), where label : String or symbol The label of the support x : Sympifyable The x coordinate of the position of the support y : Sympifyable The y coordinate of the position of the support ) distributed point_loadrNz$Supports can not have the same labelz(Supports can not be at the same locationR__x_y) _left_support_right_support _supports_support_labels_loads_loads_position_length_reaction_loads_tensionr_lowest_x_global_lowest_y_global _cable_eqn _tension_func ValueErrorappendr)self support_1 support_2x1y1x2y2is m/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/physics/continuum_mechanics/cable.py__init__zCable.__init__)sq&  !&(; ! ! '  ' ! Q<9Q< 'CD D q\Yq\ )GH H Yq\ " Yq\ "(*Bxy|$ Yq\ " Yq\ "(*Bxy|$ Q<)A, &    % %b )    % %b )    & &r *    & &r *  ' ' ! 5  ' ' ! 5    % %b )    % %b )    & &r *    & &r *  ' ' ! 5  ' ' ! 5%% >> from sympy.physics.continuum_mechanics.cable import Cable >>> c = Cable(('A', 0, 10), ('B', 10, 10)) >>> c.apply_length(20) >>> c.length 20 rrr?z@length should not be less than the distance between the supportsN)rrr)r")r+rCdists r3 apply_lengthzCable.apply_lengthsw&##A&)<)+>q+AAAEFILN D=_` ` r5c||jvr td|jj|}|j|dzdz}|j|d}|j|d}t |d}t |d}|j D]1} | dt ||k\s| dt||ks(td|jj||jj|jj|jj|jj|||g|j|d<||kr|jj||jj||jj||jj||jj|dn|jj||jj||jj||jj||jjd|d|jD]>}d|jt!d|zdz<d|jt!d|zdz<@y ) a^ This method changes the mentioned support with a new support. Parameters ========== label: String or symbol The label of the support to be changed new_support: Tuple of the form (new_label, x, y) new_label: String or symbol The label of the new support x: Sympifyable The x-coordinate of the position of the new support. y: Sympifyable The y-coordinate of the position of the new support. Examples ======== >>> from sympy.physics.continuum_mechanics.cable import Cable >>> c = Cable(('A', 0, 10), ('B', 10, 10)) >>> c.supports {'A': [0, 10], 'B': [10, 10]} >>> c.change_support('B', ('C', 5, 6)) >>> c.supports {'A': [0, 10], 'C': [5, 6]} z&No support exists with the given labelrrrz>The change in support will throw an existing load out of rangerrrN)rr)rindexrr!maxminpoprclearrr#remover*insertr) r+label new_supportr2 rem_labelr.r/rLyls r3change_supportzCable.change_supportsp<  &EF F  & &u -((!A#q1 ^^I &q ) ^^I &q ) KN # KN #%% cAts1bz!QqTSBZ%7 !abb c 5!   " !!# ""$ ##E**+Q{1~& 6    % %b )    % %b )    & &q )    & &q )  ' ' A 7    % %a (    % %a (    & &r *    & &r *  ' ';q> :%% >> from sympy.physics.continuum_mechanics.cable import Cable >>> c = Cable(('A', 0, 10), ('B', 10, 10)) >>> c.apply_load(-1, ('Z', 5, 5, 12, 30)) >>> c.loads {'distributed': {}, 'point_load': {'Z': [12, 30]}} >>> c.loads_position {'Z': [5, 5]} For a uniformly distributed load of magnitude 9 units: >>> from sympy.physics.continuum_mechanics.cable import Cable >>> c = Cable(('A', 0, 10), ('B', 10, 10)) >>> c.apply_load(0, ('X', 9)) >>> c.loads {'distributed': {'X': 9}, 'point_load': {}} rrzDistributed load already existsrzLabel already existsrrz2The load should be positioned between the supportszPoint load(s) already existzOrder should be either -1 or 0N)lenr r)rrrr!)r+orderloadr[rLr^ magnitude directions r3 apply_loadzCable.apply_loadsdB B;4;;}-.!3 !BCCGE L11 !788Q AQ A4&&q))Q1C1CA1F-F !UVVQ(IQ(I099/EDKK %e ,+,a&D  ' aZ4''(A- !>??GE M22 !788Q(I09DKK &u -=> >r5cz|D]}t|jdk(rA||jdvrtd|zdz|jdj |\||jdvrtd|zdz|jdj ||jj |y)an This methods removes the specified loads. Parameters ========== This input takes multiple label(s) as input label(s): String or symbol The label(s) of the loads to be removed. Examples ======== >>> from sympy.physics.continuum_mechanics.cable import Cable >>> c = Cable(('A', 0, 10), ('B', 10, 10)) >>> c.apply_load(-1, ('Z', 5, 5, 12, 30)) >>> c.loads {'distributed': {}, 'point_load': {'Z': [12, 30]}} >>> c.remove_loads('Z') >>> c.loads {'distributed': {}, 'point_load': {}} rrzError removing load z: no such load exists disrtibutedrN)rer!r r)rW)r+argsr2s r3 remove_loadszCable.remove_loads~s, 0A4''(A-DKK 66$%;a%?BY%YZZKK .2215DKK 55$%;a%?BY%YZZKK -11!4((,,Q/ 0r5c t|jdk7r[t|jjd}|j |j d|j d|j d|jjd}d}d}d}d|_ g}td}tdt|dz D]} | dk(rt|xjt|jd|j|| ddz dz|jd|j|| ddz dzzz c_ n|xjt|j|| dz dd|j|| ddz dz|j|| dz dd|j|| ddz dzzz c_ | t|dz k(rs|xjt|jd|j|| ddz dz|jd|j|| ddz dzzz c_ ||jd|| ddt!t"|jd|| ddzdz zt%|jd|j|| ddz zz }||jd|| ddt't"|jd|| ddzdz zt%|jd|j|| ddz zz }||jd|| ddt!t"|jd|| ddzdz zz }||jd|| ddt't"|jd|| ddzdz zz }t)|| dd z|| dzdz} |j|| dd} |j|| dd} d} d}| t|dz k(r|jd}|jd} n6|j|| dzdd}|j|| dzdd} t+| | z || z z }| t%|jd|j|| ddz t!|zt%|jd|j|| ddz t'|zzz }||j| <|j |||kf||jd|| ddt!t"|jd|| ddzdz zt%|jd|j|| ddz zz }||jd|| ddt't"|jd|| ddzdz zt%|jd|j|| ddz zz }t)|ddd z|ddz} |j|ddd} |j|ddd} |jd}|jd} t+| | z | |z z  }| t%|jd|j|dddz t!|zt%|jd|j|dddz t'|zzz }||j| <|j d||| kft-||_t"dz |z }|j d} t'| |z|j0t)d | zd z<|t'| |zz }t!||z|j0t)d | zd z<|t!||zz }|j d} | |j0t)d | zd z<| |j0t)d | zd z<yt|jd dk7rt|dk(r t3dt5|d}||_t)dd}t)d}t9|jd|z dzd|jdg|jd|z dzd|jdgg}t;t=|||f}t|dk(s |dddk(r t3d|dd}|dd|dd|dzzz}d|ddz|z}|dd|_|j>}t)d}t)d}|||zdzz|||zzz|z|z }t;|jd jA}|d}||jd|z dzzd|jd|z zz }|jjtC||}|t!t+|z |jd <|j d} |jE|jdt!t+|jG||jd|z z|j0t)d | zd z<|jE|jdt't+|jG||jd|z z|j0t)d | zd z<|j d} |jE|jdt!t+|jG||jd|z z|j0t)d | zd z<|jE|jdt't+|jG||jd|z z|j0t)d | zd z<yy)a+ This method solves for the reaction forces at the supports, the tension developed in the cable, and updates the length of the cable. Parameters ========== This method requires no input when solving for point loads For distributed load, the x and y coordinates of the lowest point of the cable are required as x: Sympifyable The x coordinate of the lowest point y: Sympifyable The y coordinate of the lowest point Examples ======== For point loads, >>> from sympy.physics.continuum_mechanics.cable import Cable >>> c = Cable(("A", 0, 10), ("B", 10, 10)) >>> c.apply_load(-1, ('Z', 2, 7.26, 3, 270)) >>> c.apply_load(-1, ('X', 4, 6, 8, 270)) >>> c.solve() >>> c.tension {A_Z: 8.91403453669861, X_B: 19*sqrt(13)/10, Z_X: 4.79150773600774} >>> c.reaction_loads {R_A_x: -5.25547445255474, R_A_y: 7.2, R_B_x: 5.25547445255474, R_B_y: 3.8} >>> c.length 5.7560958484519 + 2*sqrt(13) For distributed load, >>> from sympy.physics.continuum_mechanics.cable import Cable >>> c=Cable(("A", 0, 40),("B", 100, 20)) >>> c.apply_load(0, ("X", 850)) >>> c.solve(58.58) >>> c.tension {'distributed': 36465.0*sqrt(0.00054335718671383*X**2 + 1)} >>> c.tension_at(0) 61717.4130533677 >>> c.reaction_loads {R_A_x: 36465.0, R_A_y: -49793.0, R_B_x: 44399.9537590861, R_B_y: 42868.2071025955} rc|ddSNrritems r3zCable.solve..W[\]W^_`War5keyrrLrr_rrrrz%Provide the lowest point of the cableaT)positivecz2The lowest point is inconsistent with the supportsrIYN)$rer!sorteditemsr*rrZr$rXr"rrangerrrr rrabsrrr r r(r#r)rr%rlistrr&valuesr rNrK) r+rmsorted_positionmoment_sum_from_left_supportmoment_sum_from_right_supportF_xF_y tension_funcrLr2r[r1r0r/r.angle_with_horizontalrGlowest_xr{r}Mcoefficient_solutionrMCBlowest_yrIr temp_list applied_forcehorizontal_force_constanttangent_slope_to_curves r3r z Cable.solves^ t## $ )$T%9%9%?%?%AIabO  " "4#7#7#: ;  " "1d&:&:1&= > MM   !+, (,- )CCDLL A1c/2145$ z6LL$(:(:1(=@T@TUdefUghiUj@klm@n(nqr'rvzwIwIJKwLOSOcOcdstudvwxdyOz{|O}w}@AvA(A#BBLLL$(<(<_QqS=QRS=T(UVW(X[_[o[opABqCDEqF\GHI\J)JMN(NRVRfRfgvwxyzwzg{|}g~R@ARBEIEYEYZijkZlmnZoEpqrEsRsvwQw(w#xxLO,Q..LL$(;(;A(>AUAUVefgVhijVkAlmnAo(ors'sw{xKxKLMxNQUQeQefuvwfxyzf{Q|}~QxBCwC(C#DDL, L0I/Z[J\]^J_0`ab0cfijlosozoz|HpIJYZ[J\]^J_p`abpckcfikigj1jmpquqCqCDEqFIMI]I]^mno^pqr^sItuvIwqwmx1xx,, L0I/Z[J\]^J_0`ab0cfijlosozoz|HpIJYZ[J\]^J_p`abpckcfikigj1jmpquqCqCDEqFIMI]I]^mno^pqr^sItuvIwqwmx1xx,t{{<01CA1FGJSQSVZVaVabnVopABqCDEqFWGHIWJRJMPRPNQQQt{{<01CA1FGJSQSVZVaVabnVopABqCDEqFWGHIWJRJMPRPNQQQq1!4S819Ma9PPQ))/!*$> !56DD !,,Hs As A1x>@AI%aLM)6$:M:Ma:PS[:[^_9_)_deimi|i|}~iCKjKeL)M % MM   !%)!QZ "+DDQgLhHi+jDMM- (((+E<@OODL^L^_`La>> from sympy.physics.continuum_mechanics.cable import Cable >>> c = Cable(("A", 0, 10), ("B", 10, 10)) >>> c.apply_load(-1, ('Z', 2, 7.26, 3, 270)) >>> c.apply_load(-1, ('X', 4, 6, 8, 270)) >>> c.solve() >>> p = c.draw() >>> p # doctest: +ELLIPSIS Plot object containing: [0]: cartesian line: Piecewise((10 - 1.37*x, x <= 2), (8.52 - 0.63*x, x <= 4), (2*x/3 + 10/3, x <= 10)) for x over (0.0, 10.0) ... >>> p.show() For uniformly distributed loads, >>> from sympy.physics.continuum_mechanics.cable import Cable >>> c=Cable(("A", 0, 40),("B", 100, 20)) >>> c.apply_load(0, ("X", 850)) >>> c.solve(58.58) >>> p = c.draw() >>> p # doctest: +ELLIPSIS Plot object containing: [0]: cartesian line: 0.0116550116550117*(x - 58.58)**2 + 0.00447086247086247 for x over (0.0, 100.0) [1]: cartesian line: -7.49552913752915 for x over (0.0, 100.0) ... >>> p.show() rLrrrbrzRsolve method not called and/or values provided for loads and supports not adequaterPF)xlimylim rectanglesshow annotationsaxis)r_draw_supportsrVrr&rUrrer! _draw_cabler' _draw_loadsr r)r)r+rLrsupport_rectanglesxy_minxy_maxmax_diffcab_plots r3drawz Cable.drawPsH 3K !002T''*4+@+@AT((+S1D1DQ1GHZHZ[\H]-^_F? t## $ )"..r2DO 4++B/ /K ]+ , 1"..q1DO 4++A. .Kqr rgg!D,>,>q,A$BUBUVWBX)Yg$S\1&X2EF$S\1&X2EF#5Ek`eg r5cg}t|jd|j}t|jdt|jd|jd}||z }d|z}|j |jd|z |jdf||ddd|j |jd|jdf||ddd|S)Nrr333333?brownF)xywidthheightcolorfill)rVrr&rUrr*)r+member_rectanglesrrr supp_widths r3rzCable._draw_supportssT''*4+@+@AT((+S1D1DQ1GHZHZ[\H]-^_F?8^   ))!,Z78J8J18MN##      **1-d.A.A!.DE##   ! r5c t|jd|j}t|jdt|jd|jd}||z }|dk(rt d\}}g}t |jjd}tt|D]} | dk(r[|| dd|jdz ||jdz z|| dd|jdz z |jdz}nV|| dd|| dz ddz ||| dz ddz z|| dd|| dz ddz z || dz ddz}|j|||| ddkf|t|dz dd|jdz ||jdz z| dd|jdz z |jdz}|j|||jdkft|gS|dk(r|j} |dz} t d\} } }}| || z d zz| z|z }|jd|jdf|jd|jdfg}g}|D])\}}|j|j||||i+t|| | f}|| || z d zz|| z}||j| z gSy) Nrrrbzx yc|ddSrqrrrss r3ruz#Cable._draw_cable..rvr5rwrza c x yr)rVrr&rUrrrr!rrrer*r r%rKr )r+rfrrrrLr^ line_funcrr2x0diff_force_heightr{r} parabola_eqnpoints equationspxpysolutions r3rzCable._draw_cablesT''*4+@+@AT((+S1D1DQ1GHZHZ[\H]-^_F? B;%.CAaI$T%9%9%?%?%AIabO3/0 Ba4)!,Q/2T5G5G5JJQtOaOabcOdMdehwxyhz{|h}~iACGCUCUVWCXiXY\`\n\nop\qqA)!,Q/2_QqS5I!5LQ5OOSTUdefghehUijkUlmnUoSoptCDEtFGHtIJKtLN]^_`a^aNbcdNefgNhthil{|}~|l@ABlCDElFFA  !Aq'9!'!BC DYA/H#A;"qy08A;>L $"7"7:K"KL Lr5c Jt|jd|j}t|jdt|jd|jd}||z }|dk(r~|dz}g}|j dD]b}|j d|j|d|tt|j d|dzz|j|d|tt|j d|dzzf|j|d|j|dfddddd d |j d|d}|j |d |j|d|d ztt|j d|dzz|j|d|d ztt|j d|dzzfd e|S|dk(r/td} g}tddD cgc]7} |jd|jd|jdz dz | zz9} } | D][} |j d| |jdj| | f| |jdj| | fddddd d]d}|j dD]}||j d|z }|j |d|jd|jdzdz |j|dzz fd |Sycc} w)Nrrrbg?rrcblack)r headlength headwidth facecolor)textrxytext arrowpropsNg?)rrrL g @)rrrrrz N/mrg333333?)rVrr&rUrr r*r!rr rrrr'rK) r+rfrrr arrow_length force_arrowsrxmagrLr2x_vals r3rzCable._draw_loadssT''*4+@+@AT((+S1D1DQ1GHZHZ[\H]-^_F? "9#CNsSVW[WbWbcoWpqtWuvwWxSyOz>zz| $ qj ALlqrstvlwxghT''*t/B/B1/EdFXFXYZF[/[]_._ab-bbxEx ##! OOA.33Aa8"  OOA.33Aa8/0cs`g%h   C{{=1 7t{{=1#66 7   !U$<--a01D1DQ1GGJ4K`K`cklpcpKpq   ;ys >> from sympy.physics.continuum_mechanics.cable import Cable >>> c = Cable(("A", 0, 10), ("B", 10, 10)) >>> c.apply_load(-1, ('Z', 2, 7.26, 3, 270)) >>> c.apply_load(-1, ('X', 4, 6, 8, 270)) >>> c.solve() >>> p = c.plot_tension() >>> p Plot object containing: [0]: cartesian line: Piecewise((8.91403453669861, x <= 2), (4.79150773600774, x <= 4), (19*sqrt(13)/10, x <= 10)) for x over (0.0, 10.0) >>> p.show() For uniformly distributed loads, >>> from sympy.physics.continuum_mechanics.cable import Cable >>> c=Cable(("A", 0, 40),("B", 100, 20)) >>> c.apply_load(0, ("X", 850)) >>> c.solve(58.58) >>> p = c.plot_tension() >>> p Plot object containing: [0]: cartesian line: 36465.0*sqrt(0.00054335718671383*X**2 + 1) for X over (0.0, 100.0) >>> p.show() rrLF)rrIr)rer!rrr(rrr$)r+rL tension_plotrIs r3 plot_tensionzCable.plot_tensionsB t## $ ) A !3!3a8J8J18MdNaNabcNd5elqrL A }!=$BTBTUVBWX\XkXklmXn?ov{|Lr5N)__name__ __module__ __qualname____doc__r4propertyr8r:r<r>r@rCrErGrNrRr`rjrnr rrrrrrrr5r3rrs4@rs3 ',AAA9+!a a r5