概括
我们正在尝试解决一些物质排放到空气中的模型。在这些模型中,排放在某个点停止。
我们正在使用radau5的DotNumerics实现
我们在寻找正确解决方案时遇到了问题。如果排放停止,空气浓度应该会下降,但情况并非总是如此。
我们能够用一个简单的模型重现这个问题,我们也可以找到分析解决方案。此外,我们检查了 radau5 源代码,发现了一个看起来像优化的测试。由于这个测试,雅可比的许多评估被跳过。如果我们去掉这个测试,结果会好很多。
我们还使用Press et all., Numerical Recipes 2nd edition的隐式四阶 Runge Kutta 来解决我们最初的问题,这种方法没有显示这个问题。我们没有时间对这个问题进行测试。
我们想知道:
- 这是什么测试?有相关文件吗?
- 我们可以安全地删除测试以跳过对雅可比的评估吗?
- 我们能否期望 radau5 能够应对不连续性,或者我们是否应该分别整合这两个轨迹?
详细资料
该模型由两个隔间组成。最初,隔间 I 包含排放到隔间 II 的物质。通过通风从隔间 II 中取出产品。
$$ \begin{array}{rclr} \frac{dC_I}{dt}&=&-k_{12}(C_I- C_{II}) \\ \frac{dC_{II}}{dt}&=&k_ {12}(C_I- C_{II})-k_{02}C_{II} & t < T \\ \frac{dC_{II}}{dt}&=&-k_{02}C_{II} & t > T \\ C_I (0)&=&1 \\ C_{II}(0)&=&0 \end{数组} $$
我们找到了这些分析解决方案:
$$ \begin{array}{rclr} C_{II}(t)&=&C_{II}(T)e^{-k_{02}(tT)} \\ &=&\frac{C_0}{\ sqrt{D}}k_{12}(e^{λ_+ T}-e^{λ_-T})e^{-k_{02}(tT)} & t < T \\ C_{II}(t )&=&\frac{C_0}{\sqrt{D}} k_{12} (e^{λ_+t}-e^{λ_- t}) & t > T \\ D&=&4k_{12}^ 2+k_{02}^2 \\ λ_±&=&-k_{12}-\frac{k_{02}}{2}±\frac{\sqrt{D}}{2} \end{数组} $$
我们在 C# 中实现了这个模型。
公差为 0.01 的数值解如下:
原始 radau5 和相对容差的 jsfiddle:0.01
在这种情况下,Jacobian 仅被评估两次。
翻阅radau5代码,我们发现了一个测试:
if (THETA <= THET) goto LABEL20;
在 .\DotNumerics\ODE\Radau5\radau5.cs 的第 1663 行,
IF (THETA.LE.THET) GOTO 20
在http://www.unige.ch/~hairer/prog/stiff/radau5.f的第 1073 行。
如果我们应用修复,我们会得到:
原始 radau5 和相对容差的 jsfiddle:0.01
将容差降低到 0.001 会产生更好的结果,无论有无修正。
用于原始 radau5 和相对容差 的 jsfiddle:0.001 用于修改的 radau5 和相对容差的 jsfiddle:0.001
然而,如果没有修正,雅可比仍然只被评估了 3 次,所以这可能是一个巧合。
在 GitHub 上提供了一个演示这一点的c# 解决方案。