当我使用大长度的梁(管道)时,我在使用scipy.solve_ivp解决偏转曲线时遇到了失败。以下是我的脚本。
# -*- coding: utf-8 -*- # # Calculate deflection curve under gravity # import numpy as np from scipy.integrate import solve_ivp import matplotlib.pyplot as plt # round pipe's sectional area def area_round(D,t): d = D - 2 * t return np.pi*(D*D-d*d)/4.0 # area moment of inertia section properties of round pipe def moi_round(D,t): d = D - 2 * t return np.pi/64.0*(D**4-d**4) # gravity force per unit length for round pipe def G_round(dens,D,t): g = 9.8 # gravity coef, N/kg A = area_round(D,t) return A*dens*g # Calculate 2D plane(xy) bending of a beam undering self-gravity # minus y is the gravity direction # - Young's modules E # - area moment of inertia: Iz # x: coordinate position along x-axis # u=[y,dydx]: deflection at y direction , first order derivative on x def deflection(x,u,E,Iz,G,LG): y,dy_dx = u MG = np.select([x<=LG,x>LG],[G*(0.5*LG**2+0.5*x**2-LG*x),0]) # distributed force ddy_ddx = np.power(1.0+dy_dx*dy_dx,3.0/2.0)*MG/E/Iz return [dy_dx,ddy_ddx] # solve initial value problem using numerical method # Given x list, calcuate y and y' def solve_deflection(E,Iz,Gy,Lg,x_list): # initial value y0 = 0.0 dy_dx_x0 = 0.0 sol = solve_ivp(deflection,t_span=[0.0,Lg],y0=[y0,dy_dx_x0],method='RK45',t_eval=x_list,vectorized=True,args=(E,Iz,Gy,Lg),rtol=1.0e-3,atol=1.0e-4) print("sol:",sol) return sol.y[0,:],sol.y[1,:] # test of solving deflection equation # unit sytem: length mm force:N pressure:N/mm^2/MPa def test(): dens = 7880.0e-9 # Kg/mm^3 E = 210e3 # elastic modulus, N/mm^2 # round pipe Dp = 60.0 # mm, outer diameter tp = 3.0 # mm ,thickness print("Dp:",Dp,' tp:',tp) Iz= moi_round(Dp,tp) # section const Gy = -G_round(dens,Dp,tp) # gravity force per unit print(" Iz:",Iz,' Gy:',Gy) # Lg = 10000.0 # mm, this length is OK Lg = 20000.0 # mm, this length leads to failure print("Lg=",Lg) xlist = np.linspace(0.0,Lg,num=100,endpoint=True) res = solve_deflection(E, Iz, Gy=Gy, Lg=Lg, x_list=xlist) plt.plot(xlist,res[0]) plt.show() if __name__ == '__main__': test() pass
当长度为10000mm时,可以给出正确的结果,如下图所示
但当我将其更改为20000mm时,它失败并输出以下消息:,
sol: message: 'Required step size is less than spacing between numbers.' nfev: 944 njev: 0 nlu: 0 sol: None status: -1 success: False t: array([ 0. , 202.02020202, 404.04040404, 606.06060606, 808.08080808, 1010.1010101 , 1212.12121212, 1414.14141414, 1616.16161616, 1818.18181818, 2020.2020202 , 2222.22222222, 2424.24242424, 2626.26262626, 2828.28282828, 3030.3030303 , 3232.32323232, 3434.34343434, 3636.36363636, 3838.38383838, 4040.4040404 , 4242.42424242, 4444.44444444, 4646.46464646, 4848.48484848, 5050.50505051, 5252.52525253, 5454.54545455, 5656.56565657, 5858.58585859, 6060.60606061, 6262.62626263, 6464.64646465, 6666.66666667, 6868.68686869, 7070.70707071, 7272.72727273, 7474.74747475, 7676.76767677, 7878.78787879, 8080.80808081, 8282.82828283, 8484.84848485, 8686.86868687, 8888.88888889]) t_events: None y: array([[ 0.00000000e+00, -3.66155907e+00, -1.45618988e+01, -3.25951385e+01, -5.76794150e+01, -8.97565181e+01, -1.28794030e+02, -1.74786625e+02, -2.27730361e+02, -2.87640987e+02, -3.54556806e+02, -4.28538678e+02, -5.09670018e+02, -5.98056798e+02, -6.93827544e+02, -7.97133338e+02, -9.08147821e+02, -1.02706718e+03, -1.15411018e+03, -1.28951811e+03, -1.43356488e+03, -1.58659673e+03, -1.74895654e+03, -1.92104924e+03, -2.10335332e+03, -2.29642078e+03, -2.50087718e+03, -2.71742163e+03, -2.94684282e+03, -3.19021861e+03, -3.44843893e+03, -3.72265946e+03, -4.01447603e+03, -4.32592470e+03, -4.65948174e+03, -5.01806360e+03, -5.40502733e+03, -5.82494500e+03, -6.28452879e+03, -6.79299154e+03, -7.36408180e+03, -8.02047137e+03, -8.80421033e+03, -9.81478548e+03, -1.15113253e+04], [ 0.00000000e+00, -3.61399978e-02, -7.16869806e-02, -1.06770973e-01, -1.41512819e-01, -1.76024795e-01, -2.10415154e-01, -2.44799321e-01, -2.79258778e-01, -3.13875788e-01, -3.48738932e-01, -3.83943102e-01, -4.19589504e-01, -4.55785660e-01, -4.92645404e-01, -5.30288885e-01, -5.68842566e-01, -6.08439223e-01, -6.49217947e-01, -6.91324142e-01, -7.34921284e-01, -7.80235186e-01, -8.27461362e-01, -8.76842769e-01, -9.28683414e-01, -9.83348358e-01, -1.04126372e+00, -1.10291665e+00, -1.16888799e+00, -1.24022057e+00, -1.31734604e+00, -1.40101902e+00, -1.49267854e+00, -1.59444811e+00, -1.70913565e+00, -1.84023352e+00, -1.99191927e+00, -2.17052401e+00, -2.38680965e+00, -2.65797898e+00, -3.01398821e+00, -3.51651158e+00, -4.31409773e+00, -5.92506745e+00, -1.41760305e+01]]) y_events: None Traceback (most recent call last): File "mwe.py", line 82, in <module> test() File "mwe.py", line 76, in test plt.plot(xlist,res[0]) File "\lib\site-packages\matplotlib\pyplot.py", line 3019, in plot return gca().plot( File "\lib\site-packages\matplotlib\axes\_axes.py", line 1605, in plot lines = [*self._get_lines(*args, data=data, **kwargs)] File "\lib\site-packages\matplotlib\axes\_base.py", line 315, in __call__ yield from self._plot_args(this, kwargs) File "\lib\site-packages\matplotlib\axes\_base.py", line 501, in _plot_args raise ValueError(f"x and y must have same first dimension, but " ValueError: x and y must have same first dimension, but have shapes (100,) and (45,)
我读过关于solve_ivp错误的类似问题:“所需步长小于数字之间的间距。”但我不能理解。
我也尝试了不同的环礁价值,但无法解决这个问题。我为此奋斗了好几天。
有人能帮我吗?非常感谢。