如何强制solve_ivp从它调用的函数中采取较小的时间步长

How do I force solve_ivp to take a smaller time step from within the function it calls

提问人:Spaceman98 提问时间:9/12/2023 最后编辑:jaredSpaceman98 更新时间:9/26/2023 访问量:53

问:

我有一个形式的函数调用

ans = scipy.integrate.solve_ivp(dfdz, zbounds, f0, method='RK45', args=argslist, t_eval = zspan, vectorized=True)

如果求解器采用的时间步长太大,则有时无法收敛。我希望能够强制求解器采取较小的步骤。我该怎么做?dfdzdfdz

我试图让 return -f(即“在这个时间步长中,所有值都变为零”),希望这会导致不收敛,或者至少让它明显失败。相反,我看到我的输出 ans 跳下来,但不是一直跳到零,然后求解器继续积分,就好像什么都没发生一样。dfdz

Python Scipy Runge-Kutta 收敛 时间步长

评论

0赞 jared 9/12/2023
您是否因为有一个僵硬的 ODE 而需要更小的时间步长?如果是这种情况,您应该使用更适合刚性常微分方程的方法,例如“LSODA”、“Radau”或“BDF”,如文档所示。
0赞 Spaceman98 9/12/2023
我可以更改方法,但这并不能保证它不会尝试采取太大的步骤,当它这样做时,我仍然需要某种方法来迫使求解器采取较小的步骤。
0赞 jared 9/12/2023
刚性常微分方程需要较小的步长。因此,如果这是导致 RK4 求解器失败的原因,那么切换到可以识别的求解器应该可以解决问题。另外,“Rabau”和“BDF”是隐式方法,它们(如果我没记错的话)是无条件稳定的。
0赞 Lutz Lehmann 9/12/2023
有机地,如果你减少误差容差,你会得到更小的步数。如果要强制使用最大步长,还有一个参数。请描述此处的“收敛”含义,以及您如何观察它以做出正确的行为。若要浏览实际步骤,请保留默认值 ,以便将实际计算的步骤作为返回值。t_eval=None
0赞 Spaceman98 9/13/2023
dfdz 是一个有点复杂的函数:它包括一种需要找到零的射击方法(从已知的最终状态确定初始条件)。有时它找不到这个零,我发现如果scipy.integrate.solve_ivp采取较小的步骤,可以解决数值不稳定性。我现在正在尝试使用max_step,但这是一个非常低效的解决方案。如果我的函数要求前两个步骤是 O(10^(-17)),那么后面的步骤可以是 O(1),设置 max_step = 10^(-17) 会丢失很多。这些数字是我在创建输出 excel 日志文件时看到的。

答:

0赞 Spaceman98 9/23/2023 #1

Julia 似乎提供了我需要的功能 https://www.youtube.com/live/KPEqYtEd-zY?si=zveHs2rYd518PBoD

我仍在为我的代码制定它,但本教程非常有帮助,所以我在这里发布它,供有相同问题并找到此线程的其他人使用

编辑:我被要求澄清。正如这里所讨论的 https://docs.sciml.ai/DiffEqDocs/stable/basics/faq/ isoutofdomain执行了我在开头问题中要求的操作。

评论

0赞 Community 9/25/2023
您的答案可以通过额外的支持信息得到改进。请编辑以添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到有关如何写出好答案的更多信息。