解决 Verlet 约束是否可并行化?

计算科学 并行计算 计算物理学
2021-12-03 18:56:30

我是一名计算机科学专业的学生,​​我遇到了 Verlet Cloth 模拟。这里有一个实现我对这种计算如何适用于并行化很感兴趣。

这个问题看起来像是 N 体计算的变体,我们可以计算每个点的约束,然后它们根据约束的效果移动这些点。我按照这些思路进行了尝试,结果出现了“逻辑”错误。我确信我对物理学的理解是不完整的。

这是我尝试过的。假设 A 和 B 之间有一个约束 C。我没有尝试解析 C 一次并更新 A 和 B,而是尝试解析 C 两次以及 A 的约束并仅更新 A 和一次连同 B 的约束并仅更新 B。

这个链接,我想知道当每个点受到多个其他点的约束时,每个点的约束解析是否可以独立于另一个完成。

dist = Math.abs(A - B)
diff = (dist - r) / dist
moveBy = 0.5 * diff * dist
A = A + moveBy
B = B - moveBy

对每个约束都这样做。但是此刻,我将所有约束的所有这些“moveBy”值一起计算并通过这些值的总和移动点,但事情不起作用。这让我认为,为约束解决点的顺序和应用约束的顺序很重要。对吗?

1个回答

我不太确定这是否回答了你的问题,或者它是否更冗长的评论。如果我在这里完全脱离基地,请告诉我。

所以假设AB是某种类型Point,并且你调用 , 的方法Pointresolve(Point that)它被定义为

dist   = Math.abs(this.x - that.x)
diff   = (dist - r) / dist
moveBy = 0.5 * diff * dist
this.x = this.x + moveBy
that.x = that.x - moveBy

我不太确定我是否正确理解了您,但您是说您正在为 A 和 B 调用此方法, A.resolve(B)and B.resolve(A)别。moveBy在两个调用中是相同的,但是用不同thisthat符号应用它,所以它会抵消。这就是说顺序很重要。请注意,只需调用A.resolve(B) 即可

是的,我想涵盖所有基础,但我认为您实际上并没有按照我上面的建议进行操作。相反,也许您所拥有的是以下内容resolve(Point that)

dist = Math.abs(this.x - that.x)
diff = (dist - r) / dist
this.moveBy = 0.5 * diff * dist

并且只是稍后在另一个函数中才实际应用this.x += this.moveBy. 这几乎没问题。不过,不完全是。原因很简单:Math.abs让我们看一下谐波运动方程。这是粒子A和B之间键的能量:

E=k2(rArBr0)2
使用牛顿运动方程,
mAr¨A=ErA=k(rArBr0)rArBrArB

这与上面的代码相比如何?代码不保留方向性(因为代码中的绝对值),因此所有力都指向一个特定方向(正轴)。xy

如果有更多的粒子,方程并不会变得更复杂:左边我们有和以前一样的东西,右边有更多的力项。这就是说,在您最有可能使用的欧拉积分方案中,您可以首先计算所有力,然后根据这些力计算所有速度,然后根据这些力计算所有位移。计算一个粒子的力应该完全独立于其他粒子的计算(好吧,独立是一个糟糕的选择,因为一半的力是相同的,但根据牛顿第三定律,方向相反,但是在并行计算的意义上,它们不会相互影响)。