1D 中移动的非碰撞粒子系统

计算科学 matlab
2021-12-20 02:17:56

我有一个函数的 ODE 系统。在每个时间是粒子的位置。函数具有单调性:在任何时候真实动力学保留了该属性,因为当任何两个靠近时,ODE 中存在一个发散的排斥项。但事实上,它们确实靠得很近。事实上,它们靠得足够近,以至于在数值模拟中很容易发生交叉(如果它们这样做了,那么其余的运行就被破坏了)。fi(t)tfi(t)ifi0<f1(t)<f2(t)<<fn(t)fi

我一直在 MATLAB 中使用 ode15s 模拟我的系统(所有其他求解器都失败了)。我的方法是使用事件函数来搜索碰撞,如果我发现碰撞,那么我就让模拟失败。(这对编程来说相当方便,因为无论如何我都需要事件函数,原因不相关。)我不确定这种方法的效率如何。(使用约定 )构造 ODE ,然后使用 NonNegative 选项,然后仅重构会更有效吗?还是最终会以基本相同的方式在内部实施?(我不太了解 odezero 的工作原理。)gi=fifi1f0=0fi

1个回答

解决此问题的一种方法是为您的时间步长使用一些自适应方案。如果您有固定的时间步长宽度,则可能会发生两个粒子切换位置(如您所说)。如果你在你的算法中建立一个机制,当两个粒子彼此,那么你的发散力将阻止他们实际上交换了位置。根据您的时间步长方案,实施起来应该不会太难。h|fi(x)fi+1(x)|<ϵ

您可以使用一些启发式方法,例如:

h=min(h0  , ωmin(|fi(x)fi+1|))

并玩弄参数直到它运行足够稳定。有了这个,你也有你的时间步错误的上限。ω

另一种方法是在每个时间步之后测试正确的排序。如果您发现两个粒子已经改变了位置,那么您丢弃最后一步并使用更小的时间步重做它。

我还应该提到,如果粒子数量太高,这两种方法将无法很好地扩展,因为任何两个粒子在每个时间实例中彼此靠近的可能性都非常高。