使用变分力学分析弹簧质点系统
单弹簧
假设存在空间中的两个质点
x0=x0y0z0x1=x1y1z1
它们由静止长度为 l0 的弹簧相连
显然,这个 3 维弹簧物理系统与两个质点的坐标有关,所以 广义坐标 是
q=[x0x1]
它是一个 6 维向量,我们求它的时间导数得到 广义速度
q˙=[x˙0x˙1]=[v0v1]
我们想要构建这个系统的 拉格朗日量
L=T−V
所以我们要求系统的 动能 T 和 势能 V
系统的 动能 是两个质点的动能之和
T=i=0∑121mi∥vi∥22=i=0∑121miviTvi=i=0∑121viTMimx000my000mzivi
- 其中速度向量的二范数平方可以表示为速度向量与自身的内积
- 其中质点的质量可以写成矩阵形式,质点的质量可以是 各向异性 的,即在不同方向上有不同的质量分量
我们可以使用刚刚计算的 广义速度 进一步简化动能等式
MT=[M000M1]=21q˙TMq˙
这利用 广义速度 将两个质点的速度写成一个向量的紧凑形式,将两个质点的质量也写为一个紧凑的质量对角矩阵
系统的 势能 是存储在弹簧中的 弹性势能,弹性势能 以某种形式和弹簧的形变程度相关,总的来说,它需要满足以下条件
- 在没有外力的情况下,应当趋于其初始状态,例如弹簧在不受外力的情况下应该倾向于恢复到静止长度,也就是说能量的最低值应该由静止状态 (未形变状态) 定义
- 刚性变换,例如位移、旋转不应该改变 弹性势能
- 弹性势能 应当仅依赖于质点位置
我们首先将弹簧的 形变程度 定义弹簧的 应变 Strain
Strain=l−l0
- l 是弹簧的形变长度,l0 是弹簧的静止长度
然后我们可以根据 应变 定义弹簧的 弹性势能 为
Potential Energy=21k(l−l0)2
- k 是弹簧的 刚度参数 Stiffness Parameter
我们需要将弹簧的形变长度 l 定义为质点的坐标形式,首先计算 Δx
Δx=x1−x0=[−II][x0x1]
我们可以看到
[x0x1]
实际上是我们之前定义的 广义坐标 q,若我们做如下定义
B=[−II]q=[x0x1]
那么可以将 Δx 写成由广义坐标定义
Δx=Bq
Δx 向量的模长就是弹簧的形变长度 l
l=ΔxTΔx=qTBTBq
我们将这个广义坐标形式的形变长度代入,得到最终的弹性势能函数
V=21k(qTBTBq−l0)2
由此,我们可以得到单弹簧质点系统的 拉格朗日量
L=T−V=21q˙TMq˙−21k(qTBTBq−l0)2
接着,我们可以考虑 欧拉-拉格朗日方程 Euler-Lagrange Equation
dtd∂q˙∂L=∂q∂L
我们注意到,拉格朗日量 对 广义坐标 的偏导数仅和 势能函数 有关
∂q∂L=∂q∂(T−V)=∂q∂T−∂q∂V=0−∂q∂V=−∂q∂V
代回 欧拉-拉格朗日方程,可得
dtd∂q˙∂L=−∂q∂V
我们将 −∂q∂V 定义为 广义力 Generalized Forces,也就是说力 f 是势能场 V 的负梯度,这表示力的方向总是朝向势能下降的方向,例如,在重力场中,物体会自发地沿着势能减小的方向移动
f=−∇V=−∂q∂V
我们接着分析等式的左边
dtd∂q˙∂L=dtd∂q˙∂(21q˙TMq˙)
其中 21q˙TMq˙ 可以认为是 q˙ 的二次项,所以有
dtd∂q˙∂(21q˙TMq˙)=dtdMq˙=Mq¨
将结果代回 欧拉-拉格朗日方程,我们获得 Equation of Motion 运动方程
Mq¨=−∂q∂V
我们通过 时间积分 对这个方程进行仿真
多弹簧系统
我们可以将物体离散为多个弹簧质点组成的整体系统
假设系统中有 n 个 质点,那么我们的广义坐标是
q=x0x1x2⋮xn
若其中每个 x⋯ 都是一个三维坐标,那么 q∈R3n×1
同样的,我们可以得出广义速度
q˙=v0v1v2⋮vn∈R3n×1
接着,我们计算系统的 动能,系统的总动能是所有质点的动能之和
T=i=0∑n−121viTMimx000my000mzivi
和之前一样,我们可以通过使用 广义速度 以及将所有质点质量矩阵放到一个巨大的对角矩阵内,来简化掉求和符号
MT=M0⋮0⋯⋱⋯0⋮Mn∈R3n×3n=21q˙TMq˙
与计算 动能 类似,系统的总 势能 是所有弹簧的势能之和,假设系统中有 m 个弹簧
V=j=0∑m−1Vj(xA,xB)
由于每个弹簧的弹性势能都和其端点的两个质点坐标 xA,xB 相关,所以我们需要从广义坐标 q 中选出当前弹簧所对应的端点坐标,我们引入 坐标选择矩阵
[A0A1⋯An]x0x1x2⋮xn=i=1∑nAixi
若我们想要选取第 i 个质点的坐标,那么只需要将 Ai=I,其余所有都设置为零 Aj=i=0,例如选择第二个质点坐标 x1 是
S1[0I⋯0]x0x1x2⋮xn=x1
我们将 坐标选择矩阵 记为 S,有了它,我们就可以从完整的 广义坐标 q 中选择出我们想要的第 j 个弹簧的两端质点坐标 xA 和 xB 组成的广义坐标 qj
qj=[xAxB]=Ej[SASB]q
我们将 SA 和 SB 组成的 坐标选择矩阵 记为 Ej
所以原总势能也变为可以由广义坐标来表述
V=j=0∑m−1Vj(Ejq)
然后,我们可以构建多弹簧质点系统的 拉格朗日量
L=T−V=21q˙TMq˙−j=0∑m−1Vj(Ejq)
然后我们分析 广义力 形式的 欧拉-拉格朗日方程
dtd∂q˙∂L=−∂q∂V
我们首先分析等式的左边
dtd∂q˙∂L=dtd∂q˙∂(21q˙TMq˙)=dtdMq˙=Mq¨
可以发现这一部分的形式没有改变,我们同样得到 运动方程
Mq¨=−∂q∂V
当然,这次的 质量矩阵 M 和 广义坐标 q 包含了多个弹簧质点,所以要比之前大很多
我们接着分析等式右边的 广义力 项
−∂q∂V=−∂q∂j=0∑m−1Vj(Ejq)
由于梯度算子 ∂q∂ 是线性算子,所以可以将它移入求和
−∂q∂j=0∑m−1Vj(Ejq)=−j=0∑m−1∂q∂Vj(Ejq)=−j=0∑m−1EjT∂qj∂Vj(qj)
可以发现我们需要求每个弹簧的 弹性势能函数 Vj 对其两端点质点广义坐标 qj 的梯度,其中 弹性势能函数 一般和单个弹簧定义相同,即
V=21k(qTBTBq−l0)2
可以看到,每个 弹性势能函数 对其两端点 广义坐标 的偏导数 (梯度) 就是该弹簧产生的 广义力,所以我们也可以写为如下形式
∂qj∂Vj(qj)−∂q∂V=−j=0∑m−1EjT∂qj∂Vj(qj)=fj(qj)=−j=0∑m−1EjTfj(qj)
其中 fj(qj) 是第 j 个弹簧产生的 广义力,它是弹簧两端质点的力组成的向量,在三维情况下,它是
fj=[fAfB]∈R6
它通过对 第 j 个弹簧的弹性势能求对 广义坐标 的偏导 (梯度) 得到
∂qj∂Vj(qj)=fj(qj)
然后我们通过对应的 第 j 个 选择矩阵 的 转置 EjT 将 fj 放到最终大型 广义力 向量 f 的对应位置 (每个弹簧的力只作用在广义坐标的一部分分量上),也就是说,这一步得到是多个只在某些分量有值的向量,求和以后才是每个分量都有值的广义力向量
−j=0∑m−1EjTfj(qj)=f=f0f1⋮fn∈R3n×1
- 注意负号,这里的负号是必要的,因为我们求的是势能的负梯度,代表的是从势能中导出的广义力,力指向势能减少的方向
注意,每个质点可能连接多个弹簧,所以质点最终的力是所有连接到该质点的弹簧对其产生的合力,也就是说,每个弹簧都会对不同质点产生分力,即对不同的坐标分量有贡献,而合力是每个弹簧力对不同分量的总贡献
有了 广义力 向量,我们就可以进行 时间积分 了,并且我们导出了最终 运动方程
Mq¨=f
我们发现这实际上就是牛顿的 f=ma,根据 拉格朗日-欧拉方程 推导出 运动方程 以后,我们可以通过计算势能函数的梯度得到 广义力 f,然后根据 运动方程 进行 时间积分 得到 广义加速度 q¨,然后再进行 时间积分 得到 广义速度 q˙,最后进行 时间积分 得到 广义位置 q
时间积分 Time Integration
我们采用 反向欧拉 Backward Euler 作为时间积分方法,这是一种隐式积分方法,它通过在当前积分步骤中使用 “未来的位置” 来保持数值积分的稳定性
我们首先进行一次积分以得到 广义速度
Mq˙t+1=Mq˙t+Δt f(qt+1)
- M 是质量矩阵
- q˙t+1 是下一步的 广义速度
- f(qt+1) 是下一步位置的 广义力
- Δt 是时间步长
然后再对 广义速度 积分,得到 广义位置
qt+1=qt+Δt q˙t+1
- qt+1 是下一步的 广义位置
- qt 是当前步的 广义位置
- q˙t+1 是下一步的 广义速度
- Δt 是时间步长
我们发现 广义力 f(qt+1) 是非线性函数,直接求解比较困难,所以我们需要进行线性化近似,我们使用泰勒展开对其进行一阶近似
f(qt+1)≈f(qt)+∂q∂fqt(qt+1−qt)
- f(qt) 是当前时刻 t 的 广义力
- ∂q∂fqt 是当前时刻 广义力 对 广义坐标 的导数,也就是力梯度
根据之前的 广义位置 积分等式,可得
qt+1−qtf(qt+1)=Δt q˙t+1=f(qt)+∂q∂fqtΔt q˙t+1
我们将这个结果代回 广义速度 积分公式
Mq˙t+1=Mq˙t+Δt (f(qt)+∂q∂fqtΔt q˙t+1)=Mq˙t+Δt f(qt)+∂q∂fqtΔt2 q˙t+1
这里我们特别关注一下 ∂q∂fqt,它是力梯度,也被称为 刚度矩阵 Stiffness Matrix,记为 K
K=∂q∂fqt
同时,由于 Hessian 矩阵 是某个标量函数 (例如我们的势能函数 V(q) 就是一个标量函数) 的二阶导数矩阵,描述了该标量函数的曲率
H=∂q2∂2V
而我们的力函数 f(q) 是根据势能函数的 负梯度 (负一阶偏导) 定义的,所以它也是 势能的 Hessian (差了个负号)
K=∂q∂f=∂q∂(−∂q∂V)=−∂q2∂2V=−H
如此,我们的积分等式变为
Mq˙t+1=Mq˙t+Δt f(qt)+KΔt2 q˙t+1
重新整理,我们得到
(M−KΔt2)q˙t+1qt+1=Mq˙t+Δt f(qt)=qt+Δtq˙t+1
其中也可以用 −H 取代 K,具体来说,也就是
fKK=−∂q∂j=0∑m−1Vj(Ejq)=∂q∂f=−∂q2∂2j=0∑m−1Vj(Ejq)=−j=0∑m−1∂q2∂2Vj(Ejq)=j=0∑m−1(−EjT∂qj2∂2VjEj)=j=0∑m−1(EjT(−Hj)Ej)=j=0∑m−1(EjTKjEj)
- 引入了逐弹簧的 −Hj 和 Kj
和之前一样,所有单弹簧的矩阵加起来合成了大的 K 矩阵