第四讲:弹性体模拟-弹性力学基础

初闻不识曲中意,再听已是曲中人

这一讲的主题是弹性体模拟中的弹性力学基础,首先来看一个问题,就是当一个球跟多个球同时发生碰撞,如下图所示(称之为Bernoulli Problem):

或者当第一个球跟第二个球碰撞的瞬间,第二个球同时与第三个球碰撞,如下图所示(称之为Newton's Cradle):

这些问题的求解都可以归结为线性互补问题Linear Complementary Problem(简称LCP)的求解,线性互补问题的定义可以参考物理引擎之约束求解(一)——线性互补问题。假设有两个刚体(分别标注为1号跟2号),由于每个刚体都有六个自由度(translation+rotation),那么这两个刚体的位置就可以用下述公式来表示:
q = \left[ \begin{matrix} q_1 \\ q_2 \end{matrix} \right]
其中
q_1 = \left[ \begin{matrix} x_1 \\ y_1 \\ z_1 \\ r_{x_1} \\ r_{y_1} \\ r_{z_1} \end{matrix} \right]
同样q_2也有对应的变量表达,而由于刚体是不可穿插形变的,因此q还会有一些额外的约束:
g_i(q) \geq 0
这里的i指的是第i个碰撞点,g_i可以表示快要碰撞时候两个物体在第i个碰撞点处的signed distance。

如果用上一讲中的impulse-based方法来解方程,那么就意味着我们需要在碰撞的瞬间为两者施加一个冲量,而要想产生冲量,也就意味着两者产生了穿插,前面的条件将不再满足,即:
g_i(q) < 0

而如果我们希望在下一个timestep回复到正确的状态,那么上面这个函数的导数就需要是为正的:
\dot{g}_i(q)=\nabla g_i(q)\dot q \geq 0

这个表达式的物理意义是,等式后面表达式中的前面部分\nabla g_i(q)表达的是碰撞点处的表面的法线(signed distance的梯度就是signed distance下降最快的方向,即表面法线方向),后面部分是刚体的速度,两者相乘大于等于0表示的是这两个向量的夹角小于九十度,也就是说在这个速度下,会使得两者的signed distance不断变大。

在impulse的作用下,速度会从\dot{q}^-变成\dot{q}^+,即速度从碰撞变成背离。在Houdini中有个叫做restitution coefficient(恢复系数)的参数\alpha,这个参数是做什么的呢?用一个例子来说明,一个球在重力的作用下下坠,碰到地表,如果这个参数为0,那么这个小球在碰撞后,就会贴在地表上,如果是1的话,碰撞之后就会回弹到起始的高度,也就是说,这个参数表达的是经过碰撞之后能量的残留比例。

将恢复系数跟表面法线结合起来看,我们可以得到如下公式(这个条件我们称之为一号条件):
\nabla g_i(q)\dot q ^+ \geq \nabla g_i(q)\dot q ^ - (-\alpha)

如下图所示:

入射方向为\dot q ^ -,出射方向为\dot q ^ +\alpha可以简单看成是是出射方向的速度的长度与入射方向的速度长度的比例,\nabla g_i(q)是法线方向,那么上面这个公式自然就是成立的,毕竟能量是守恒的,出射速度的长度不可能超过入射速度的长度。

上面这个公式是针对单个碰撞点(contact point)而言的,当我们有多个碰撞点的时候,\nabla g_i(q)就变成了一个矩阵,这个矩阵我们称之为G_A^T(这个矩阵的物理含义为,将刚体的速度映射到碰撞点上的沿着法线方向的速度?不是特别理解,如果单个碰撞点的情况,对应的是碰撞点的法线,那么这里就对应的是多个碰撞点法线组成的矩阵,既然是多个碰撞点,也就没有一个整体的法线概念了),这里的转置后面会解释。

另外,这里还有另外一个公式:
\dot q ^ + = \dot q ^ - + M^{-1} \cdot G_A \cdot \lambda

这个公式中M表示的是刚体的质量,G_A是一个矩阵,这个矩阵就是上面梯度向量组成的矩阵的转置(推导这里就不说了,抛开多个碰撞的情况不说,单个碰撞点的情况下,冲量的作用方向肯定是垂直于碰撞表面的,也就是说经过冲量作用后的加速度应该也是与碰撞表面的法线方向保持一致的,从主观上来说,这个结果是可以理解的),\lambda则是前面说的碰撞时的冲量impulse,如果有多个碰撞点的话,这个变量也就是一个向量(几个碰撞点就是几维的)。矩阵G_A跟冲量的乘法得到的是一个力,而作用力除以质量就得到了加速度,通过这个加速度(在时间的作用下)就能完成速度的一个变化。

这个公式中,冲量(每个分量)必须要大于等于0(当刚体碰撞时的速度在表面法线方向上的速度非0,且速度法线方向的分量与法线方向相反,那么就取>0,否则就取等于0),否则在碰撞后,刚体就直接装进另一个刚体中,从而发生穿插,这个条件我们称之为二号条件:
\lambda \geq 0

一号条件跟二号条件组成linear complementary condition(即如果\lambda = 0(对应的是碰撞点碰撞之后没有施加冲量,也就是说碰撞时候的速度与表面法线正好垂直,这种情况下,表面法线与速度正交,一号条件不等式前面的结果就是0)的时候,就不需要考虑一号条件;而如果\lambda > 0就必须要考虑一号条件,我们将这种情况称之为互补),最终我们需要求解的问题就可以表示为,在一二号条件:

\lambda \geq 0

G_A^T(\dot{q}^+ + \alpha \dot{q}^-) \geq 0

约束下,求解:
\dot q ^ + = \dot q ^ - + M^{-1} \cdot G_A \cdot \lambda

即LCP,这个问题如果我们能够求解出冲量向量,那么我们就能得到需要的解,但是在多个碰撞点的情况下,这个会比较复杂。

Bullet物理引擎用的是一种叫做Gauss Siedal Method,一个个碰撞点去考虑,比如先考虑一号碰撞点的impulse是多少,之后再看一号impulse对二号碰撞点的速度的改变,之后再看二号碰撞点的impulse为多少并加上一号碰撞点的影响,同时算出对三号碰撞点的影响,以此类推,直到最后一个碰撞点对一号碰撞点的影响,不断迭代,经历多轮迭代最终达到一个平衡,这种方法是串行计算,对GPU不友好,性能较差。

另一种方法则是将LCP(这是一种timestep的方法)转换成一个优化问题,这种思想是物理模拟中的一种十分重要的思想,在很多问题的求解上都有应用。

先来说说拉格朗日乘子(lagrange multiplier),这是数学上的一种优化策略中的术语,这个优化策略用以在给定的一些等式约束下,求得某个函数的局部极值(极大极小值),这个算法的基本思想可以叙述为,对于一个需要求解极小值(极大值可以转换为极小值)的函数f(x),已知需要满足g(x) = 0条件(或者说,已知极值是在g(x) = 0条件下满足),那么拉格朗日函数可以表示为:
\mathscr{L}(x, \lambda) = f(x) + \lambda g(x)

我们知道,如果不考虑条件函数g(x) = 0的话,f(x)的极值可以直接通过f'(x) = 0来求得,而在加上条件之后,问题就会变得复杂一点,上面的拉格朗日函数是自变量x跟\lambda(这个就叫拉格朗日乘子)的函数,而原函数f(x)的极点则肯定会出现在拉格朗日函数的saddle point(极点)上,所以只需要对拉格朗日函数求偏导,并令各个偏导结果为0进行求解,就能得到取得极值的坐标点。

而如果对上面的情况进行泛化处理,比如将条件从等式变成不等式,那么我们就需要使用KKT(Karush Kuhn Tucker)条件方法,同样的,KKT会将原始的函数f(x),与等式约束g(x) = 0以及不等式约束h(x) \leq 0写到一个式子里:
\mathscr{L}(x, \lambda, \mu) = f(x) + \lambda g(x) + \mu h(x)

f(x)取得极值的条件为:

  1. \mathscr{L}(x, \lambda, \mu)对三个变量的偏导为0
  2. g(x) = 0
  3. \mu h(x) = 0

联合这些等式,就能得到最终的极值点的坐标。这里值得一提的是,上面第三个条件中,由于h(x)是小于等于0的,因此要想条件成立,要么h(x) = 0,要么\mu = 0,也就是说,这个条件可以拆成两个条件:
\mu \geq 0

h(x) \geq 0
且这两个条件是complementary(互补)的,如果移除g(x)的干扰,这个条件就跟前面LCP问题的求解的形式完全一致了,也就是说,LCP的求解就变成了KKT(优化问题)的求解,而这种问题的求解方法就十分丰富了,这里就不做展开,否则可以直接讲一个学期。

但是我们发现,用LCP来求解Bernoulli Problem可以得到正确的结果,但是用来求解Newton Cradle问题的时候结果却是错误的,这是因为理论上LCP问题的求解是不唯一的,也就是说我们得到的解有多个,其中选取的那个可能并不是正确的解。

这里需要注意的是,上面的求解是没有考虑碰撞时的摩擦力的,实际上如果添加了摩擦力的话,问题会变得更为复杂。但是有意思的是,即使加上摩擦力,依然可以表达为LCP问题(不过更为复杂),转化成的优化问题,其限制条件将会变成二次函数,因此其求解也会变得更为复杂。

最后做个总结,在目前情况下的物理引擎,对刚体碰撞的模拟依然是存在较大的精度问题,比如说大多数都没有办法解决上面的Bernoulli跟Newton Cradle问题,即使是不考虑摩擦力的情况,目前都没有物理引擎能给出完善的解决方案,更何况是更为精确的考虑摩擦力的情况。

弹性形变

Continuum Mechanics中描述了形变的相关理论,包括弹性形变与塑性形变,我们这里着重考察弹性形变。

最简单的弹性形变就是前面说的弹簧+质点的粒子系统,当质点不断移动从而压缩弹簧的话,弹簧就会不断的积累势能,当手松开之后,势能可能就会转换为动能,此时弹簧产生的力叫做conservative force。

但是弹性形变不只是局限于弹簧系统,普通的物件也会发生此类形变,但是这里有亮点需要明确:

  1. 形变的数学描述是什么样的?即如何定量来描述形变
  2. 如何将形变变成势能,即经过了一定的形变后,得到了多少的势能。

可以知道,弹性体的形变是一个连续的变化,即形变前相邻的点在形变后依然是相邻的。我们可以利用微分思想来对这个连续的规律进行考虑,假设形变前物体上某一点X(处在material space)经过形变后变成了点x(处在deformed space),那么形变就可以表示成如下的公式:
\phi: X \rightarrow x

对这个映射关系采用泰勒展开:
\phi(X + \delta \mu) = \phi(X) + \frac{\partial \phi}{\partial X} \delta \mu + ...

由于\phi(X)是一个三维的变量(三维空间中的点),因此上面公式中的偏微分项\frac{\partial \phi}{\partial X}就是一个3x3的矩阵,这个矩阵我们叫做deformation gradient(形变梯度矩阵),通常用F来表示。

从这个公式我们可知道,这个矩阵的第一列进行乘法运算时对应的是\delta \mu的第一个元素,换句话说,第一列就是在material space中沿着x方向移动一个距离时,在deformed space中就需要沿着某个方向移动一个相同大小的距离,这个方向就用第一列向量来表示,同理,其他两列就分别对应y/z方向上移动时对应的deformed space中的移动方向。

接下来我们看看要如何用数学公式表示物体的弹性形变长度,假设在material space中某个点移动的位移为\delta \mu,那么移动的长度的平方就可以表示为\delta \mu ^T \delta \mu,而在deformed space中对应点的移动位移就可以用F \cdot \delta \mu来表示,其长度则为\delta \mu ^T \cdot F^T F \cdot \delta \mu,那么具体的形变量就可以用后者开平方后减去前者的开平方,不过这里为了避免因为开平方导致的高额计算消耗,可以先直接用平方之差来表示形变的测度:
\delta \mu ^T \cdot F^T F \cdot \delta \mu - \delta \mu ^T \delta \mu = \delta \mu ^T(F^TF - I)\delta \mu = \delta \mu ^T \epsilon \delta \mu

上面等式中最后的epsilon称之为Green(格林) Strain(形变) Tensor(本质上是个矩阵),这个矩阵可以用来描述微分意义下物体形变的规律,可对于推导或者计算出这个\epsilon的点X而言,在其周边较小的一块区域(微分算子)里的所有点都可以通过这个矩阵来计算其形变量,但是,如果超出这个区域范围,\epsilon可能会不同,也就是说,\epsilon准确来说是物件上某点的一个函数,可以写成\epsilon(X)

接下来,就是如何将前面的\epsilon变成势能,势能可以表示为如下形式的函数:
P(\epsilon)

我们知道,这个函数有如下的性质:

  1. \epsilon = 0时,这个函数取值为0
  2. |\epsilon|变大时,势能也跟着变大,反之亦然,同时也就说明了此函数在0处取得一个极值

根据上面两个性质,我们可以推断,这个函数可以大致用下图来表示:

至少是一个两阶以上的模型,应用泰勒展开,可以得到:
P(\epsilon) = P(0) + P'(0) \epsilon + \frac{1}{2} P''(0) \epsilon ^ 2 + ...

而由于P(0)P'(0)都是0,那么上面公式就变成了:
P(\epsilon) = \frac{1}{2} P''(0) \epsilon ^ 2 + ...

由于\epsilon是个矩阵,那么这个公式就可以改写成如下的形式,这个公式我们称之为constitution model:
P(\epsilon) = \sum_ {i, j, k, l = 1} ^ 3 C_{ijkl} \epsilon_{ij} \epsilon_{kl}

到目前为止,所有的公式都是通过数学推导给出的,没有掺杂物理相关的概念与理论,接下来,为了能够得到上面的公式的具体形式,就需要给出系数C_{ijkl},而物理学中针对这个系数提出了众多的模型,甚至还有人考虑通过神经网络训练得到这个系数,这就造成了不同的势能物理模型。

要知道这个公式是如何在物理中进行应用的,我们就放到下一讲中进行介绍了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容