当步长 (h) 大于 1 时,ODE 系统不起作用

计算科学 Python 龙格库塔
2021-12-28 11:43:26

我是 Python 的初学者。目前我正在编写一个代码,用于为具有初始值的非线性 ODE 系统开发一个简单的求解器。该系统的方程是

如下

首先对 myu 的函数求值,得到 myu 的值,然后在 dX/dt、dS/dt 和 dDO/dt 中使用。下一步,再次评估 myu 以根据 S 和 DO 的新值获得其新值。

我正在使用 JC Butcher 提出的通用线性方法 (GLM) 作为我的方法。该方法使用转移矩阵,其值和大小取决于我们使用的数值方法。在这种情况下,我使用 Runge Kutta Cash-Karp。

虽然您可能会在等式中发现 D 也是一个函数,但这里我将 D 的值设置为常数。

在初始化时,首先设置 h 的值,以获取步数。我创建了一个名为“initValue”的向量,它有 8 列和 4 行,由每个方程的 k 值(第 1 到第 6 行)、Runge Kutta 四阶的初始值(第 7 行)组成。我将其设置为 0,因为它只是充当“预测器”)和每个方程的初始值(第 8 行)。

转移矩阵是基于 GLM 创建的,其中的值来自 Runge Kutta Cash-Karp 的阶段方程(求 k1 到 k6 的值)和阶跃方程(求解)的常数。

在循环中,我第一次简单地将初始值添加到名为“result”的数组中。第一步,我简单地将转换矩阵与向量“initValue”相乘。在下一步直到最后一步,我根据上一步的结果初始化“initValue”。

我正在寻找的是应该看起来像这样的解决方案。如果 h 小于 1,我的代码可以工作。我将结果与 scipy.integrate.odeint 的结果进行比较。但是当我将 h 设置为大于 1 时,它显示的结果与应有的结果不同。例如,在代码中,我设置了 h = 100,也就是说它只会显示初始值和最终值(当 time = 100 时)。X 和 S 应该向上,DO 和 Xr 应该向下,而我的则相反。当 h 设置为大于 1 时,odeint 的结果显示与预期解相同的结果。

我需要帮助来修复我的代码,以便它可以显示任何 h 值的预期解决方案。

1个回答

增加时间步长也不总是明智的,因为您正在增加数值误差。相反,您应该为错误设置一个请求的值,并让积分器做出实现该错误估计(适应性)所需的步长,或者您需要自己在数值错误和运行时间之间取得平衡。那就是说...

我需要帮助来修复我的代码,以便它可以显示任何 h 值的预期解决方案。

对不起,那是不可能的。这是由于数值稳定性问题。显式积分器(如显式 RK)具有“稳定”的最大步长,超过该步长的小扰动被放大,导致求解器发散到无穷大。这个最大步长是求解器的属性和方程的“刚度”(与方程的最大和最小特征值有关)。

如果您根本不想受到限制dt,则需要使用专为处理刚度而设计的积分器。“无限dt”只出现在ABL-stable方法中,这是一个不合理的目标。不过,像二阶 Rosenbrock 方法、Midpoint 方法或 BDF2 之类的东西显示了这一点。但是,您不能使用该属性获得高于二阶的值,这意味着错误往往更高。所以为了做好这件事,你需要同时调整顺序和时间步长。这就是为什么我建议坚持使用一些专用的 ODE 求解器软件的原因之一:它有大量的花里胡哨来完成这项工作。