关于水槽灌水出现数值爆炸问题的调查

8月11日, 我们收到了一则计算过程中出现数值爆炸现象的报告
对此, 我们展开了调查,现公布调查结果以及修复:

  1. 原现象:
    据用户报告, 当事人所使用的解算发生了数值爆炸, 结果如下所示

origin

我们的调查方式:
为了加快调查速度, 我们采纳了更大的dx = 0.2, 并且一开始就让水槽灌满水, 从而展开调查, 并且我们把“最大子步数量”开到了10.
image

我们发现运行得到的结果会产生数值爆炸

经调查, 此问题的发生源于两处求解器的问题:
1 . p2g操作将粒子信息体素化到网格时归一化权重时忽视了epsilon的问题
2. 求解泊松方程时当MGPCG算法求解失败时, 会转为纯MultiGrid算法求解, 此时的最高迭代次数没有开够
3. 当转为纯MultiGrid求解时, pre和post smooth的次数过小, 设置的收敛条件过小

经排查, 其中问题 1 , 3为主要矛盾。 2 为次要矛盾。 这是因为在修复过程中, 我们有如下发现:

首先, 如果我们只修复问题2, 而不修复问题1, 我们依然会得到数值爆炸的结果:
capture_6

仔细观察, 我们发现数值爆炸发生之前在某些部位产生了速度能量局部很大的粒子, 这些粒子形成了一个局部巨大的压差,进而催生了数值爆炸。
capture_7

这个观察促使我们去调查了问题 1 , 并进行了相关修复, 修复后, 同样的解算设置不再会发生数值爆炸:
capture_6
尽管还是有粒子闪点, 但很快就被消解掉了。

此时, 我们即使把最大子步开到5, 也不会出问题:
capture5

当我们回到更高的解析度, dx=0.08时, 我们会发现, 修复了 2 和 1 依旧会有数值爆炸:
capture_8

当我们修复了3以后, 就不会数值爆炸了:
capture_7

现在, 问题1 ,问题2 , 问题3 都已经修复制最稳定的程度

附录:
问题 1 会导致数值爆炸的原因:


可以通过给归一化权重加一个人为设定的 ε 来解决。 按理来说, 这个操作应该是求解器代码里的常规写法, 我们十分意外, 我们可能在某一次代码提交中忽略了这个 ε 。

问题 3 会导致数值爆炸的原因:
压强求解不收敛会导致数值爆炸。设置的收敛条件过小会导致之后的迭代被数值误差主导, 反而产生不精确的数据。

解决方法:更新到815(或最新版本)

1 个赞