在求解耦合微分方程时,我得到了以下错误,但我没有得到它,因为我是python的新手。
“dopri5:步长变得太小 self.messages.get(idid,'Unexpected idid =%s'%idid))
” 请有人帮我解释一下关于颂歌集成商的正确解释。
# zombie apocalypse modeling
import numpy as np
import matplotlib.pyplot as plt
plt.ion()
from scipy.integrate import ode
G=6.67384*10**(-11)
K=5380.3
v=5/3
r0=1
density0=5*10**(7)
Pressure0=K*density0**(v)
mass0=(4/3)*np.pi*density0*r0**(3)
c=299792458
y_0=[mass0,Pressure0]
def f(r,y):
mass1=4*np.pi*(y[1]/K)**(1/v)
Pressure1=G*( ((y[1]/K)**(1/v)) + (y[1]/(c**2)) )*( (y[0])+(4*np.pi*(r**3)*y[1]/(c**2)) )/( 1-G*y[0]/(r*c**2) )
#phi1=( G*y[0] + (4*np.pi*G*r**(3)*P/(c**2)) )/( (r*c**2)*( r-2*G*m/(c**2) )
return([mass1,Pressure1])#,phi1)
def my_odeint(f, y0, t):
'''
ODE integrator compatible with odeint, that uses ode underneath
'''
y0 = np.asarray(y0)
backend = "dopri5"
#backend = "dop853"
solver = ode(f)
solver.set_integrator(backend) # nsteps=1
t0 = t[0]
t_final = t[-1]
solver.set_initial_value(y0, t0)
y_result = [y0]
i = 1
current_t = t[i]
z=y0
while solver.successful() and solver.t < t_final and z[1]>0:
solver.integrate(current_t, step=1)
i += 1
z=solver.y
if i<len(t) :
current_t = t[i]
print(i)
y_result.append(solver.y)
return np.array(y_result)
t_1=np.linspace(10,10**5,10**5)
print(len(t_1))
cal=my_odeint(f,y_0,t_1)
答案 0 :(得分:1)
我不知道如何解决这个问题,特别是因为scipy没有隐含的方法......
dopri5或者也称为rk45是一种Runge-Kutta方法,它混合了order-4和order-5方法。 order-5方法用作精确值的代理,以估计order-4方法的误差。如果误差不落入相对于步长和问题标度的预定范围,则减小或增大步长。这允许引导集成以具有一些预定的全局误差,并且接近最小的努力。
在僵硬的系统中,可能会发生步长减小从未成功将错误驱回到允许的范围内。可能存在一些故障保护,因此在整合间隔的显着部分发现了这种不良行为,使所有错误估计无效。
僵硬系统集成的解决方案是使用隐式方法,例如搭配方法。我没有在scipy中发现它们的暗示。