在 1-DOF 质量弹簧系统中实现半隐式后向欧拉

发布于 2024-09-26 15:04:29 字数 624 浏览 0 评论 0原文

我有一个简单的(质量)弹簧系统,有两个点与弹簧连接。一个点固定在天花板上,所以我想用数值方法计算第二个点的位置。因此,基本上我得到了第二个点的位置及其速度,并想知道这两个值在一个时间步后如何更新。

以下力作用于该点:

  • 重力,由 -g * m 给出
  • 弹簧力,由 k * (l - L) 给出,其中 k 为刚度, l 是当前长度,L 是初始长度
  • 阻尼力,由 -d * v 给出

总结起来,这导致

  • F = -g * m + k * (l - L)
  • Fd = -d * v

应用例如显式欧拉,可以推导出以下内容:

  • newPos = oldPos + dt * oldVelocity
  • newVelocity = oldVelocity + dt * (F + Fd) / m,使用 F = m * a

但是,我现在想使用半隐式后向欧拉,但无法确切地弄清楚从哪里导出雅可比行列式等。

I have a simple (mass)-spring system wih two points which are connected with a spring. One point is fixed at a ceiling, so I want to calculate the position of the second point using a numerical method. So, basically I get the position of the second point and it's velocity, and want to know how these two value update after one timestep.

The following forces take effect on the point:

  • Gravitational force, given by -g * m
  • Spring force, given by k * (l - L) with k being the stiffness, l being the current length and L being the initial length
  • Damping force, given by -d * v

Summed up, this leads to

  • F = -g * m + k * (l - L)
  • Fd = -d * v

Applying for example Explicit Euler, one can derive the following:

  • newPos = oldPos + dt * oldVelocity
  • newVelocity = oldVelocity + dt * (F + Fd) / m, using F = m * a.

However, I now want to use semi-implicit backward Euler, but can't exactly figure out where to derive the Jacobians from etc.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

国粹 2024-10-03 15:04:29

因此,最容易理解的是首先考虑完全隐式方法,然后再考虑半隐式方法。

隐式欧拉将有(让我们称这些方程(1)):

newPos = oldPos + dt * newVelocity
newVelocity = oldVelocity + dt * (-g * m + k*(newPos - L) - d*newVelocity)/m

现在我们只测量相对于 L 的位置,这样我们就可以去掉 -kL 项。重新排列我们最终得到

(newPos, newVelocity) - dt * (newVelocity, k/m newPos - d/m newVelocity) = (oldPos, oldVelocity - g*dt)

并将其放入矩阵形式

((1,-dt),(k/m, 1 - d/m)).(newPos, newVelocity) = (oldPos, oldVelocity -g*dt)

\left ( \begin{array}{cc} 1 & -\Delta t \ \frac{k}{m} & 1 - \frac{d}{m}\end{array} \right ) \left ( \begin{array}{c} x^\mathrm{new} \ v ^\mathrm{new} \end{array} \right ) = \left ( \begin{array}{c} x^\mathrm{old} \ v^\mathrm{old} - g \Delta t\end{array } \right )

你知道矩阵中的所有内容以及 RHS 上的所有内容,你只需要求解向量 (newPos, newVelocity)。您可以使用任何 Ax=b 求解器来完成此操作(在这个简单的情况下,可以手动进行高斯消除)。但既然你提到了雅可比行列式,你可能想用牛顿-拉夫森迭代或类似的方法来解决这个问题。

在这种情况下,您本质上是要求解方程的零点

((1,-dt),(k/m, 1-d/m)).(newPos, newVelocity) - (oldPos, oldVelocity -g*dt) = 0

,即 f(newPos, newVelocity) = (0,0)。您有一个先前的值可用作起始猜测(oldPos,oldVelocity)。现在您只想迭代

(x,v)n+1 = (x,v)n + f((x,v)n)/f'((x,v)n)

直到你得到足够好的答案。这里,

f(newPos,newVel) = ((1,-dt),(k/m, 1-d/m)).(newPos, newVelocity) - (oldPos, oldVelocity -g*dt)

f'(newPos, newVel) 是对应于矩阵的雅可比

((1,-dt),(k/m, 1-d/m))

行列式 半隐式的过程是相同的,但更容易一些 - 并非 eqns (1) 中的所有 RHS 项都是新量。通常完成的方式是

newPos = oldPos + dt * newVelocity
newVelocity = oldVelocity + dt * (-g * m + k*oldPos - d*newVelocity)/m

,例如,速度取决于位置的旧时间值,而位置取决于速度的新时间值。 (这与“跨越式”积分非常相似。)您应该能够使用这组稍有不同的方程轻松完成上述步骤。基本上,上面矩阵中的 k/m 项消失了。

So it's probably easiest to see how this goes from considering the fully implicit method first, then going to the semi-implicit.

Implicit Euler would have (let's call these eqn (1)):

newPos = oldPos + dt * newVelocity
newVelocity = oldVelocity + dt * (-g * m + k*(newPos - L) - d*newVelocity)/m

For now let's just measure positions relative to L so we can get rid of that -kL term. Rearranging we end up with

(newPos, newVelocity) - dt * (newVelocity, k/m newPos - d/m newVelocity) = (oldPos, oldVelocity - g*dt)

and putting that into matrix form

((1,-dt),(k/m, 1 - d/m)).(newPos, newVelocity) = (oldPos, oldVelocity -g*dt)

\left ( \begin{array}{cc} 1 & -\Delta t \ \frac{k}{m} & 1 - \frac{d}{m}\end{array} \right ) \left ( \begin{array}{c} x^\mathrm{new} \ v^\mathrm{new} \end{array} \right ) = \left ( \begin{array}{c} x^\mathrm{old} \ v^\mathrm{old} - g \Delta t\end{array} \right )

Where you know everything in the matrix, and everything on the RHS, and you just need to solve for the vector (newPos, newVelocity). You can do this with any Ax=b solver (gaussian elimination by hand works in this simple case). But since you mention Jacobians, you're presumably looking to solve this with Newton-Raphson iteration or something similar.

In that case, you're essentially looking to solve the zeros of the equation

((1,-dt),(k/m, 1-d/m)).(newPos, newVelocity) - (oldPos, oldVelocity -g*dt) = 0

which is to say, f(newPos, newVelocity) = (0,0). You have a previous value to use as a starting guess, (oldPos, oldVelocity). Now you just want to iterate on

(x,v)n+1 = (x,v)n + f((x,v)n)/f'((x,v)n)

until you get a sufficiently good answer. Here,

f(newPos,newVel) = ((1,-dt),(k/m, 1-d/m)).(newPos, newVelocity) - (oldPos, oldVelocity -g*dt)

and f'(newPos, newVel) is the Jacobian corresponding the matrix

((1,-dt),(k/m, 1-d/m))

Going through the process for semi-implicit is the same, but a little easier - not all of the RHS terms in eqns (1) are new quantities. The way it's usually done is

newPos = oldPos + dt * newVelocity
newVelocity = oldVelocity + dt * (-g * m + k*oldPos - d*newVelocity)/m

eg, the velocity depends on the old time value of the position, and the position on the new time value of the velocity. (This is very similar to "leapfrog" integration..) You should be able to work through the above steps pretty easilly with this slightly different set of equations. Basically, the k/m term in the matrix above drops away.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文