ということで、これまでmeshの剛体回転ばかりやってきたので、少し目先を変えてmesh morphing関係の調査。まずはチュートリアルから。
① tutorials/incompressible/pimpleDyMFoam/movingCone
円筒領域(くさび型で2D化)の中をconeが平行移動する。メッシュ変形は以下のdynamicMeshDictに記述の通り、移動する部分速度を指定して、それに応じてメッシュが拡大・縮小する。
メッシュ数の増減はないタイプ。
dynamicFvMesh dynamicMotionSolverFvMesh;
motionSolverLibs ( "libfvMotionSolvers.so" );
solver velocityComponentLaplacian;
velocityComponentLaplacianCoeffs
{
component x;
diffusivity directional (1 200 0);
}
移動する部分(patch "movingWall")の速度の指定は、0/pointMotionUx でx軸成分の速度を指定している。
boundaryField
{
movingWall
{
type uniformFixedValue;
uniformValue constant 1;
}
farFieldMoving
{
type slip;
}
fixedWall
{
type uniformFixedValue;
uniformValue constant 0;
}
left
{
type uniformFixedValue;
uniformValue constant 0;
}
② tutorials/incompressible/pimpleDyMFoam/wingMotion
翼型(patch "wing")が6DOFベースで運動方程式に基づいた運動を行い、それに伴ってメッシュが変形する。同じフォルダに3つケースがあるが、sHMでメッシュを作り、simpleFoamで初期値を作成し、mapFieldでpimpleDyMFoamで実際にメッシュ移動を計算しているという流れ。
constant/dynamicMeshDictを見てみると、運動方程式を解くのに必要な質量、重心、慣性モーメント、重力などを指定しているほか、constraintsで拘束条件、restraintsで制約条件を追加しており、かなり複雑な移動をシミュレートできそう。このあたり、詳しい解説がどこかにないだろうか。
メッシュの変形結果については、各時刻フォルダにpointDisplacementが生成されるほか、polyMeshフォルダも作成される。
dynamicFvMesh dynamicMotionSolverFvMesh;
motionSolverLibs ("libsixDoFRigidBodyMotion.so");
solver sixDoFRigidBodyMotion;
sixDoFRigidBodyMotionCoeffs
{
patches (wing);
innerDistance 0.3;
outerDistance 1;
mass 22.9;
centreOfMass (0.4974612746 -0.01671895744 0.125);
momentOfInertia (1.958864357 3.920839234 2.057121362);
orientation
(
0.9953705935 0.09611129781 0
-0.09611129781 0.9953705935 0
0 0 1
);
angularMomentum (0 0 -2);
g (0 -9.81 0);
rho rhoInf;
rhoInf 1;
report on;
solver
{
type symplectic;
}
constraints
{
yLine
{
sixDoFRigidBodyMotionConstraint line;
centreOfRotation (0.25 0.007 0.125);
direction (0 1 0);
}
zAxis
{
sixDoFRigidBodyMotionConstraint axis;
axis (0 0 1);
}
}
restraints
{
verticalSpring
{
sixDoFRigidBodyMotionRestraint linearSpring;
anchor (0.25 0.007 0.125);
refAttachmentPt (0.25 0.007 0.125);
stiffness 4000;
damping 2;
restLength 0;
}
axialSpring
{
sixDoFRigidBodyMotionRestraint linearAxialAngularSpring;
axis (0 0 1);
stiffness 700;
damping 0.5;
referenceOrientation $orientation;
}
}
}
③tutorials/mesh/moveDynamicMesh/SnakeRiverCanyon
blockMeshで作成したベースメッシュのパッチminZを、moveDynamichMeshコマンドを用いてtriSurface/AcrossRiver.stl(地形)に合うように変形させるチュートリアル。
ベースメッシュは、stl地形データよりもちょっとz方向上に生成されている。
motionSolverLibs ("libfvMotionSolvers.so");
solver displacementSBRStress; //displacementLaplacian;
//solver velocityComponentLaplacian z;
displacementSBRStressCoeffs
{
// diffusivity uniform;
// diffusivity directional (1 200 0);
// diffusivity motionDirectional (1 1000 0);
// diffusivity file motionDiffusivity;
diffusivity quadratic inverseDistance 1(minZ);
}
実際のメッシュ変形は、0/pointDisplacementに記載。
上面のmaxZパッチは移動なし、minX, minYなどの側面はそれぞれの法線方向ベクトルnに対し、fixedNormalSlipと指定して、nに直交方向する方向のみ許可している。
実際に変形するminZパッチ面については、指定速度で指定stlに向かって変形していく、すなわち時間変化する。プロジェクションの設定から単純にz軸方向のみのプロジェクションを行っていることがわかる。
boundaryField
{
maxZ
{
type fixedValue;
value uniform (0 0 0);
}
minZ
{
type surfaceDisplacement;
value uniform (0 0 0);
// Clip displacement to surface by max deltaT*velocity.
velocity (10 10 10);
geometry
{
AcrossRiver.stl
{
type triSurfaceMesh;
}
};
// Find projection with surface:
// fixedNormal : intersections along prespecified direction
// pointNormal : intersections along current pointNormal of patch
// nearest : nearest point on surface
// Other
projectMode fixedNormal;
// if fixedNormal : normal
projectDirection (0 0 1);
//- -1 or component to knock out before doing projection
wedgePlane -1;
//- Points that should remain fixed
//frozenPointsZone fixedPointsZone;
}
[snip]
maxX
{
type fixedNormalSlip;
n (1 0 0);
}
[snip]
}
④tutorials/mesh/refineMesh/refineFieldDirs
refineMeshコマンドの使い方らしいので、ちょっと違うかも。