剛体力学のためのFEM:クォータニオンによる回転処理と慣性テンソル
FEM剛体シミュレーションにおけるクォータニオンによる回転表現と慣性テンソルの扱い方
剛体力学の基本方程式#
流体-構造連成(FSI)解析や離散要素法(DEM)シミュレーションにおいて、剛体の運動を正確に記述することは不可欠です。剛体は変形のない物体であり、任意の2点間の距離が常に一定に保たれます。
剛体内の任意の粒子 の速度は、次のように分解されます。
ここで、 は重心の速度、 は角速度、 は重心から粒子 までの変位ベクトルです。
線形運動量と角運動量#
ニュートンの第2法則より、全体の線形運動量は次のようになります。
ここで、 は全質量です。重心の加速度は、
全体の角運動量は、
ここで、 は慣性テンソル(inertia tensor)、 は全トルク(torque)です。
慣性テンソル#
慣性テンソルは重心を基準として、
連続体へと拡張すると、
ここで、 は単位テンソル、 は外積(outer product)です。
物体が回転すると、慣性テンソルは方位行列(orientation matrix) によって変換されます。
ここで、 は物体座標系(body frame)における初期慣性テンソルであり、シミュレーション開始時に一度だけ計算すれば十分です。
クォータニオンを用いた回転表現#
オイラー角(Euler angles)で回転を表現すると、ジンバルロック(gimbal lock)の問題が発生します。これを避けるために、**クォータニオン(quaternion)**を使用します。
クォータニオン は、スカラー部分とベクトル部分で構成されます。
単位軸 に対して角度 だけ回転させる場合、
2つのクォータニオン と の合成回転は、積として表現されます。
これを利用すると、方位行列 はクォータニオン成分によって明示的に表現されます。
クォータニオンの時間微分は、角速度 と結びついています。
FEM離散化と四面体形状関数#
FEMで剛体の変位場を離散化する場合、四面体要素の形状関数(shape function)は次のようになります。
ここで、 は無次元体積座標(barycentric coordinates)であり、 の条件を満たします。
線形四面体要素における変位補間は、
剛体拘束条件を適用すると、自由度は6個(並進3 + 回転3)に減少します。
Python実装例#
import numpy as np
class RigidBody:
def __init__(self, mass, I_body):
self.M = mass
self.I0 = I_body # 物体座標系における慣性テンソル (3x3)
self.x_cm = np.zeros(3) # 重心の位置
self.v_cm = np.zeros(3) # 重心の速度
self.q = np.array([1., 0., 0., 0.]) # クォータニオン (w, x, y, z)
self.omega = np.zeros(3) # 角速度
def quaternion_to_rotation(self):
w, x, y, z = self.q
return np.array([
[1-2*(y**2+z**2), 2*(x*y - w*z), 2*(x*z + w*y)],
[2*(x*y + w*z), 1-2*(x**2+z**2), 2*(y*z - w*x)],
[2*(x*z - w*y), 2*(y*z + w*x), 1-2*(x**2+y**2)]
])
def inertia_world(self):
R = self.quaternion_to_rotation()
return R @ self.I0 @ R.T
def step(self, F_ext, tau_ext, dt):
# 並進運動の積分
a_cm = F_ext / self.M
self.v_cm += a_cm * dt
self.x_cm += self.v_cm * dt
# 回転運動の積分
I_world = self.inertia_world()
alpha = np.linalg.solve(I_world, tau_ext - np.cross(self.omega, I_world @ self.omega))
self.omega += alpha * dt
# クォータニオンのアップデート
omega_q = np.concatenate([[0.], self.omega])
q_dot = 0.5 * quaternion_multiply(omega_q, self.q)
self.q += q_dot * dt
self.q /= np.linalg.norm(self.q) # 単位クォータニオンの正規化
def quaternion_multiply(q1, q2):
w1, x1, y1, z1 = q1
w2, x2, y2, z2 = q2
return np.array([
w1*w2 - x1*x2 - y1*y2 - z1*z2,
w1*x2 + x1*w2 + y1*z2 - z1*y2,
w1*y2 - x1*z2 + y1*w2 + z1*x2,
w1*z2 + x1*y2 - y1*x2 + z1*w2
])実務上の注意点#
1. クォータニオンの正規化忘れ
数値積分が繰り返されると、 となり、回転行列が非直交(non-orthogonal)になります。毎タイムステップごとに q /= norm(q) を必ず実行する必要があります。
2. 慣性テンソルの座標系の混同 は物体固定座標系(body frame)で定義されます。ワールド座標系(world frame)でトルクを計算した場合は、 に変換してから適用する必要があります。
3. タイムステップの選択 剛体の最高固有振動数 に対して、 条件(CFL類似条件)を満たすことで数値安定性が保証されます。高速回転する物体ほど、小さな が必要です。
4. クォータニオン補間 (SLERP) 2つの方位間を補間する場合は、線形補間(LERP)の代わりに球面線形補間(SLERP)を使用することで、等速回転が保証されます。
剛体力学とFEMの結合は、FSI、DEM、マルチボディダイナミクスシミュレーションの基盤となります。クォータニオンベースの回転表現を正しく実装することで、ジンバルロックなしに任意の3次元回転を安定してシミュレーションできます。
回転軸と ω を変えてジンバルロックのない回転を確認しよう。
주황 화살표가 회전축. 사원수 q를 직접 곱해 매 프레임 큐브를 회전시킨다 — 짐벌락 없이 안정.
役に立ったらシェアしてください。