使用dopri5方法进行Scipy ODE积分

时间:2015-03-16 18:19:40

标签: python

在求解耦合微分方程时,我得到了以下错误,但我没有得到它,因为我是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)

1 个答案:

答案 0 :(得分:1)

我不知道如何解决这个问题,特别是因为scipy没有隐含的方法......

dopri5或者也称为rk45是一种Runge-Kutta方法,它混合了order-4和order-5方法。 order-5方法用作精确值的代理,以估计order-4方法的误差。如果误差不落入相对于步长和问题标度的预定范围,则减小或增大步长。这允许引导集成以具有一些预定的全局误差,并且接近最小的努力。

在僵硬的系统中,可能会发生步长减小从未成功将错误驱回到允许的范围内。可能存在一些故障保护,因此在整合间隔的显着部分发现了这种不良行为,使所有错误估计无效。

僵硬系统集成的解决方案是使用隐式方法,例如搭配方法。我没有在scipy中发现它们的暗示。