加速 ODEINT 僵硬示例

计算科学 C++
2021-12-18 08:34:54

我正在尝试实现以下 odeint 求解器示例,但我的微分方程不同。

https://github.com/headmyshoulder/odeint-v2/blob/master/examples/stiff_system.cpp

我拥有的系统很僵硬,因此 Rosenbrock 方法非常适合。但是,求解过程确实很慢,通常需要 200 万步才能达到 t = 2.5s。

有什么方法可以调整自适应步进设置并查看求解器正在采取哪些步骤?我还没有找到一个好的文档,我找到的唯一一个是

http://headmyshoulder.github.io/odeint-v2/doc/boost_numeric_odeint/tutorial/stiff_systems.html

如果有一种方法可以在不调整步进的情况下加快速度,那也可以。

谢谢。

1个回答

文档代码中的这个位置可以看出,它正在做 Gustafsson 加速。这通常是一种很好的技术,并且是由 Hairer 提倡的。我在自己的测试中发现,实际上 PI 控制器在高阶 Rosenbrock 方法中运行得非常好,但是 YMMV。这可能是问题和画面依赖。但无论如何,这就是您要修改的代码中的位置。

但我确实想解决另一件事。

我拥有的系统很僵硬,因此 Rosenbrock 方法非常适合。

不一定,我根本不会盲目地说这句话。当您试图求解小于106并且您的方程组不够大(我将指向Hairer IIDiffEqBenchmarks,以及许多其他当前未发布的基准,它们几乎都说了同样的话)。但话又说回来,如果系统每隔一段时间都足够平滑,多步方法仍然可以“偷偷摸摸”,所以这不是一个硬性规则。如果您真的想确定什么对您的问题有好处,我建议您使用一些可以轻松访问 Radau 的套件来解决您实际方程的一小部分,包括高阶和低阶 Rosenbrock、BDF 以及可选的高阶和低阶(E)SDIRK 方法,因为这些方法往往在各种方案中做得最好。您还应该生成一个参考解决方案,因为在不比较错误的情况下比较时序绝不是一个好主意(很多时候,速度越快的错误可能越大),这就是为什么如果您想进行这种比较,工作精度图是一个很好的工具容易地。DiffEqBenchmarks 中的此示例显示了运行此类测试的简单方法,尽管您也可以使用 MATLAB 或使用 Hairer 求解器套件的包装器设置类似的东西,例如查看类似的结果(但在每种情况下都缺少一些方法)。