跟踪scipy.integrate中solve_ivp函数的成功步骤

时间:2020-05-25 10:37:24

标签: scipy ode

我有一个问题,需要解决一个ODE系统,并且我正在使用scipy.integrate.solve_ivp。致电集成商时,我要指定集成的时间间隔以及要评估解决方案的时间点。呼叫看起来像这样:

Z_solution  = solve_ivp( fun= lambda t, y:  rhs_of_differential_equation( t, y, args_tuple  ),
                         t_span= time_interval, y0 = initial_array, 
                         method='RK45',
                         t_eval = np.array( [ 0.0 ] ),                                               
                         max_step   = parameters.max_step, 
                         first_step = parameters.initial_step,                                                                  
                         rtol = parameters.adaptive_step_relative_tolerance, 
                         atol = parameters.adaptive_step_absolute_tolerance,
                         )

这意味着我只对t = 0时的解决方案感兴趣,而介于两者之间的其他任何内容都与我的情况无关。但是,在调用solve_ivp时,我正在跟踪积分器正在使用的t值,因此,我正在跟踪算法中的所有“中间”步骤。但是我想知道是否有一种方法可以真正查看哪些步骤成功了,而不是中间步骤。在我看来,上面的调用将整合所有直到t = 0.0的内容,但并没有告诉您整合步骤是否成功...在此,我将不胜感激,谢谢!

附加信息:我的解向量y实际上依赖于一个也随t缩放的网格。也就是说,如果y是我对ODE的解,它将由N个点组成,其中N是网格的大小(对于t的固定值)。这意味着,对于积分t = 0.0的终点,我的解决方案y是具有N个元素的数组。但是,计算值的网格也取决于t的值。有没有办法在整个集成算法中一致地更改网格?我试图在初始条件数组中传递网格,但似乎无法正常工作。

EDIT-2:在这里,我写了一些代码来理解这一点。我的问题的规模变化很大,因此,我想让积分器为我选择必要的时间步长,因此,我不想事先将t_evals选择为固定的点数;我只需要间隔的开始和结束时间。在此期间,积分器将进行必要的步长调整,以不超出公差范围。然后,我的问题是要确定这些内部点(积分器能够计算的[0,10]之间的点)。由solve_ivp函数返回的束对象中的对象SolveODE似乎具有“ ts”值,以及 call 方法,该方法原则上在那些时间步中检索生成的解决方案。这是一个简单的指数衰减函数的代码:

import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as pyt


def my_fun2( t, y, *args ):    
    return -0.5*y    

vals = np.array( [ 100 ] )    
args_tuple = ( 0.01, 0.5 )

Z_solution  = solve_ivp( fun= lambda t, y: my_fun2( t, y, args_tuple  ),
                                         t_span= [0.0, 10], y0 = vals, 
                                         method='RK45',
                                         t_eval =   [0.0, 10],
                                         dense_output  = True,                                                                  
                                         rtol=1e-7, atol = 1e-7,                                           
                   )  

OdeSol  = Z_solution.sol
y_sol = OdeSol.__call__( OdeSol.ts  )[0] 
ts    = OdeSol.ts 

x = np.linspace( 0, 10, 1000 )
analytic = 100*np.exp( -0.5*x )

for s in range( 0, len(vals) ):    
    pyt.plot( ts, y_sol, 'ob', x, analytic, '-r' )
    pyt.show()

以及解析解和(ts,y_sol)的点给出:

code plot

然后,如果我理解正确的话,蓝色点是积分器在[0,10]区间内未超过公差的范围内找到解的点。如果您减小公差,那么蓝点数量当然会减少,有人可以确认吗?

最重要的是,我的系统需要以某种方式告诉每个ts点该函数停止,对在该点找到的y_sol进行一些网格调整,然后继续集成。有没有办法通过使用solve_ivp来做到这一点?我只能考虑自己在Solve_ivp中包含此功能,但我真的不希望这样做,因为这将意味着修改Solve_ivp代码以允许此类功能,非常感谢!

0 个答案:

没有答案