我正在尝试使用SciPy的integrate.ode来解决ODE,但它失败了。我怀疑它与所涉及的网格的大小有关,所以我尝试了以下两个测试:
from scipy.integrate import ode
def bla(t,x):
return 0
M0=1
t0,y0 = 0.5*M0,0.5*M0
r = ode(bla).set_integrator('dopri5')
r.set_initial_value(y0,t0)
t1 = M0
dt =0.01*M0
bli = np.array([])
while r.successful() and r.t < t1:
r.integrate(r.t+dt)
bli = np.append(bli,r.y)
数组bli
包含50个元素,其值应为0.5
。
from scipy.integrate import ode
def bla(t,x):
return 0
M0=1e13
t0,y0 = 0.5*M0,0.5*M0
r = ode(bla).set_integrator('dopri5')
r.set_initial_value(y0,t0)
t1 = M0
dt =0.01*M0
bli = np.array([])
while r.successful() and r.t < t1:
r.integrate(r.t+dt)
bli = np.append(bli,r.y)
在这种情况下,数组bli
包含值为5e12
的单个元素和r.successful() = False
,因为它不应该是。
我该如何解决这个问题?
答案 0 :(得分:1)
如果在print t,x
中插入bla
语句,您可以观察到,作为初始化的一部分,求解器使用硬编码步长h=1e-5
执行积分步骤以获得最佳效果第一个“真实”步骤的步长。评估的第二个值是偏移量0.1*h=1e-6
。对于t=5e12
,浮点数中的t
和t+0.1*h
或t+h
之间没有区别。这就是你得到错误的原因。
如果没有更改ode
类的代码或使用更动态地处理初始化的不同版本或包,则无法解决此问题。
一般建议是,在使用常规求解程序包重新缩放问题时,求解器所看到的状态向量和步长在一个可感知的范围内,介于1e-3
和1e6
之间。您可以在理论方面通过选择适当的单位或在将状态向量转换为模型变量并返回时在ODE函数中进行重新缩放来实现此目的。