こんにちは(@t_kun_kamakiri)
本記事はOpenFOAMのメッシャーであるcfMeshを使ったメッシュ作成の解説を行います。
cfMeshの使い方について解説する
GPL版のcfMeshはソースコードが公開されています。
ESI版のOpenFOAMであれば、OpenFOAMをインストールすると「$WM_PROJECT_DIR/modules/cfmesh」(「/opt/OpenFOAM/OpenFOAM-v2012/modules/cfmesh/」)にcfMeshがインストールされているので、追加でインストールすることなく使うことができます。
- OpenFOAMをインストール済(OpenFOAMv2012(ESI版))
- cfMeshをこれから使ってみたい方
cfMeshはsnappyHexMeshより設定項目が少なくテトラメッシュやポリヘドラルメッシュにも対応しているため、初心者にとっても使いやすいメッシャーといえます。
本記事では前回FreeCADで作成したモデル(stlファイル)を使って、cfMeshでメッシュ作成を行いたいと思います。
- WSL2
- OpenFOAMv2012(ESI版)
- cfMesh(OpenFOAMv2012(ESI版)にインストール済)
- ParaView5.9.0
チュートリアルファイルのコピー
cfMeshのチュートリアルを自身の解析フォルダにコピーします。
1 2 |
cp -r /opt/OpenFOAM/OpenFOAM-v2012/modules/cfmesh/tutorials cd tutorials/cartesianMesh/asmoOctree/ |
本記事では「tutorials/cartesianMesh/asmoOctree」のチュートリアルを使ってメッシュ生成を行いますが、「system/meshDict」ファイルの設定はメッシュパターンで共通しているためどのチュートリアルを使っても構いません。
1 2 3 4 5 6 7 8 9 10 |
├── Allclean ├── Allrun ├── geom.stl ├── model000.stl ├── post.foam └── system ├── controlDict ├── fvSchemes ├── fvSolution └── meshDict |
「model1000.stl」が形状ファイルです。
メッシュ生成には「Allrun」スクリプトを使うと便利です。
1 2 3 4 5 6 |
#!/bin/sh cd ${0%/*} || exit 1 # Run from this directory . $WM_PROJECT_DIR/bin/tools/RunFunctions # Tutorial run functions runApplication cartesianMesh runApplication checkMesh |
「runApplication cartesianMesh」のcartesianMeshの部分を
- tetMesh
テトラメッシュ(四面体メッシュ) - cartesian2DMesh
四分木法による2Dメッシュ - cartesianMesh
八分木法によるメッシュ - pMesh
ポリヘドラルメッシュ
のいずれかにすることでメッシュのパターンを変えることができます。
本記事ではtetMeshをメインに解説を行います。
stlファイル作成
形状ファイルは前回の記事で作成した以下のモデルを使います。
前回作成した「model1000.stl」はFreeCADで作成したモデルです。寸法は数値のみ意味を持つため、例えば以下の絵のようにΦ80だと、解析する単位がメートル単位だと直径80mという意味になります。ですので、後程1/1000倍します。
cfMeshにはstlファイルかfmsファイルが必要です。
fmsファイルは、この後示す特徴線を持ったファイルで「surfaceFeatureEdges」コマンドで変換することができます。
スケールを変換
FreeCADで寸法を作成した場合、FreeCAD上の単位がmmだったとしても出力したファイルは数値しか拾っていません。そのため、CAE解析での単位がmであった場合は1000倍のスケールになってしまうため、m単位にする必要があります。
※以下のコマンドはFreeCADでmm単位でモデルを作った場合に、モデルを1/1000倍にすうるコマンドです。
1 |
surfaceConvert -scale 0.001 model000.stl model000_m.stl |
特徴線の抽出
特徴線の抽出には以下のコマンドを行う必要があります。
1 |
surfaceFeatureEdges model000_m.stl model000_m.fms |
また、隣り合った面での法線ベクトルがなす角度を指定して出力することもできます。
以下の例は角度30°以下の角度の線は特徴線とみなされます。
指定なしの場合は角度は45°。
1 |
surfaceFeatureEdges model000_m.stl model000_m.fms -angle 30 |
ここまででファイル構成は以下となります。
1 2 3 4 5 6 7 8 9 10 11 12 |
├── Allclean ├── Allrun ├── geom.stl ├── model000.stl ├── model000_m.fms ├── model000_m.stl ├── post.foam └── system ├── controlDict ├── fvSchemes ├── fvSolution └── meshDict |
- model000_m.stl:m単位の形状ファイル
- model000_m.fms:特徴線を持った形状ファイル
fmsの方が精度よくメッシュ生成を行うことができるため、基本的にはfmsを使うことをお勧めします。
※といってもfmsファイルを直接ParaViewで確認することができないので、今回はstlファイルを形状ファイルとして使います。
ちなみにfmsファイルからstlファイルには以下のコマンドで変換可能です。stlファイルにするとParaViewで可視化ができます。
1 |
FMSToSurface geom.fms geom.stl |
メッシュ生成
メッシュの設定は「system/meshDict」ファイルで行います。
meshDictの設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
surfaceFile “mesh.fms”; // 形状ファイル(stl, fms形式) maxCellSize 10.0; // 最大セルサイズ(絶対値指定) boundaryCellSize 1.0; // 境界層セルサイズ(option) boundaryCellSizeRefinementThickness 1.0; // 境界層厚さ(option) minCellSize 1.0; // 最小セルサイズ(option) boundaryLayers { } // 境界層の設定ブロック localRefinement { } // パッチ名によるリファイン設定 surfaceMeshRefinement { } // サーフェスのリファイン設定 edgeMeshRefinement { } // エッジベースのリファイン設定 objectRefinements { } // オブジェクトによるリファイン設定 anisotropicSources { } // 異方性メッシュの設定 renameBoundary { } // パッチ名の変更 workflowControls { } // メッシュ生成のコントロール keepCellsIntersectingBoundary 1; checkGluedMesh 0; enforceGeometryConstraints 1; |
cfMeshに最低限必要なのが、
1 2 |
surfaceFile "model000_m.stl"; maxCellSize 0.01; |
の2つです。
- surfaceFile:stlファイルかfmsファイル
- maxCellSize:ベースのメッシュサイズ
では、まず「maxCellSize」のみを変更してメッシュ作成してみましょう。
コマンド実行
メッシュ生成のコマンドは、3D形状の場合は「Allrun」スクリプトか「tetMesh/cartesianMesh/pMesh」のいずれかで行います。
今回はtetMeshを使うので「tetMesh 」コマンドでメッシュ生成が実行されます。
1 2 3 |
tetMesh // テトラメッシュ(←今回使うのはこれ) cartesianMesh // 六面体ベースのメッシュ pMesh //ポリヘドラルメッシュ |
最大セルサイズの指定
maxCellSize 0.01;
今回のモデルは細い円筒がΦ10なので最低でも10mmのメッシュサイズが必要です。
もう少しベースメッシュを小さくしていきます。
ベースメッシュ指定(1):maxCellSize 0.005;
1 2 3 |
surfaceFile "model000_m.stl"; maxCellSize 0.005; |
これでようやく全体のメッシュができています。
細い円筒Φ10の部分にメッシュ5mmというのはギリギリすぎるので、さすがにメッシュがガタガタですね。
ベースメッシュ指定(2):maxCellSize 0.0025;
変化に対して4点あれば形状をとらえることができるという考えでいくと、Φ10であればメッシュサイズは2.5mmでそこそこきれいにメッシュ生成ができると考えられます。
1 2 3 |
surfaceFile "model000_m.stl"; maxCellSize 0.0025; |
しかし、全ての領域でベースメッシュ2.5mmだと太い円筒Φ80の方はすこし細かくなりすぎています。なので、次はオプションとして最小セルサイズを指定してメッシュ生成を行います。
最小セルサイズの指定
minCellSize 0.0025;
1 2 3 4 5 |
surfaceFile "model000_m.stl"; maxCellSize 0.1; minCellSize 0.0025; |
最小のセルサイズを指定することで最小のセルサイズまでは細かくメッシュ生成されていることがわかります。
しかし、断面を切ると太い円筒の部分の真ん中あたりは表面も内部も荒いメッシュになっていますが、それ以外は細かくメッシュになっています。
minCellSizeを設定すると意図しない面のメッシュサイズもminCellSizeの数字になりメッシュ数が膨大になることがあります。個人的にはminCellSizeは使わずに以下のlocalRefinementで指定した面のセルサイズを決めてメッシュ生成することをお勧めします。
指定した面のセルサイズ指定:localRefinement
今回はstlファイルの中で以下のように面に名前を付けています。
特にメッシュサイズを細かくしたいのは「thinwall1」「thinwall2」なので、「localRefinement」で指定した面のセルサイズを小さくします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
surfaceFile "model000_m.stl"; maxCellSize 0.1; localRefinement { thinwall1 { cellSize 0.0025; } thinwall2 { cellSize 0.0025; } } |
これにより「thinwall1」「thinwall2」の面のセルサイズだけが小さくなりました。
面の名前として「thinwall」までは同じなので、正規表現で表しても同じ結果となります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
surfaceFile "model000_m.stl"; maxCellSize 0.1; // minCellSize 0.0025; //boundaryCellSize 0.0025; //boundaryCellSizeRefinementThickness 1.0; localRefinement { "thinwall.*" // 「thinwall」で始まる文字列 { cellSize 0.0025; } } |
cellSizeの指定ではなく分割数を指定したい場合は以下のようにします。
1 2 3 4 5 6 7 8 |
localRefinement { "thinwall.*" // 「thinwall」で始まる文字列 { //cellSize 0.0025; additionalRefinementLevels 2; } } |
次は境界層も入れてみましょう。
境界層の指定
境界層のセルサイズ0.0025
1 2 3 4 5 6 7 |
surfaceFile "model000_m.stl"; maxCellSize 0.1; minCellSize 0.0025; boundaryCellSize 0.0025; |
全ての面の表面のセルサイズが2.5mmになっているので、表面の見た目は細かいメッシュになっていますが、中のメッシュは粗い部分があります。
次は指定した面にセルサイズを指定してメッシュ生成してみましょう。
指定した面の境界層:boundaryLayers
境界層を5層入れてみましょう。
まずはベースとなる境界層を設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
surfaceFile "model000_m.stl"; maxCellSize 0.1; // minCellSize 0.0025; //boundaryCellSize 0.0025; localRefinement { "thinwall.*" { cellSize 0.0025; } } boundaryLayers { nLayers 5; // 境界層の挿入 thicknessRatio 1.1; // (全5層, 拡大比1.1, 第1層最大厚0.5m) maxFirstLayerThickness 0.0025; } // ************************************************************************* // |
ちょっと不自然ですが5層の境界層メッシュが入りました。
「sidewall1」と「sidewall2」の境界層を7層入れたいので正規表現で「”side.*”」と指定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
surfaceFile "model000_m.stl"; maxCellSize 0.1; // minCellSize 0.0025; //boundaryCellSize 0.0025; //boundaryCellSizeRefinementThickness 1.0; localRefinement { "thinwall.*" { cellSize 0.0025; } } boundaryLayers { nLayers 5; // 境界層の挿入 thicknessRatio 1.1; // (全5層, 拡大比1.1, 第1層最大厚0.5m) maxFirstLayerThickness 0.5; patchBoundaryLayers { "side.*" //正規表現で指定可能 { nLayers 7; thicknessRatio 1.1; maxFirstLayerThickness 0.02; /* “allowDiscontinuty”は異なるパッチ面で境界層の層数や拡大率の影響が出ないようにする(1) 境界層同士が滑らかに接続するようにする(0) */ allowDiscontinuity 0; } } } |
細い円筒のメッシュが生成されない場合
今回のようにΦ80の円筒からΦ10への円筒ように形状変化がある場合、メッシュ生成の設定によって上手くメッシュが生成されないということがあります。
その場合、今まで見てきたようにmaxCellsizeを変更するか、minCellsizeを指定するか、面に名前を付けてメッシュサイズを指定するかなど工夫が必要であり、ちょっと面倒です。
そんな場合、keepCellsIntersectingBoundary の有効化をすると良いです。
今回はtetMeshでは違いが出なかったため、cartesianMeshで比較してみました。
1 2 3 4 5 |
surfaceFile "model000_m.stl"; maxCellSize 0.01; keepCellsIntersectingBoundary 1; |
- keepCellsIntersectingBoundary 0; 0は無効
- keepCellsIntersectingBoundary 1; 1は有効
メッシュ生成が上手くいかないときに有効にしておくと良いです。
特徴線まわりでメッシュ分割数指定
snappyHexMeshを使用しているときに、特徴線を利用することが多いのですが、cfMeshでも特徴線を利用することができます。
- surfaceFeatureExtructでmodel_m.eMeshを生成
- surfaceFeatureConvert constant/triSurface/model_m.eMesh constant/triSurface/model_m.obj
試してはいませんが、特徴線まわりでメッシュを抽出するには以下のように記述します。
1 2 3 4 5 6 7 8 |
edgeMeshRefinement { model_m { edgeFile "model_m.obj"; additionalRefinementLevels 4; } } |
特徴線のmodel_m.objで4分割の再分割を行うという設定です。
ちなみにmodel_m.objはParaViewでも読み込むことができるので、特徴線を確認することができます。
特定領域の再分割
こちらも試していませんが、特定領域の再分割もcfMeshで設定できます。
1 2 3 4 5 6 7 8 9 10 11 12 |
objectRefinements { refinement1 { additionalRefinementLevels 2; type box; centre (0 -0.015 0); lengthX 0.1; lengthY 0.015; lengthZ 0.1; } } |
typeは「box, cone, plane」などありますので好みで使い分ければよいかと思います。
まとめ
今回はtetMeshをメインにcfMeshの基本的な使い方を見てきました。
本記事で紹介した設定に対して「tetMesh/cartesianMesh/pMesh」のいずれかで行えば、メッシュパターンを変えることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
surfaceFile "model000_m.stl"; maxCellSize 0.005; keepCellsIntersectingBoundary 1; localRefinement { "thinwall.*" { cellSize 0.0025; } } |
参考書
OpenFOAMの基本的な設定を学ぶことができる書籍として以下の参考書がお勧めです。
改訂新版 OpenFOAMの歩き方 (技術の泉シリーズ(NextPublishing))
本記事で紹介したcfMeshについて設定方法など詳しく書かれている書籍としては以下のものがあります。ただし、本書はESI版ではなくFoundation版でありOpenFOAMv2.xで書かれたやや古い内容です。
その点に注意してESI版のお使いのversionとの違いを丁寧に調べることができる方であれば、十分参考になる書籍です。
OpenFOAM全般の設定などまとめられた書籍として以下のものがあります。
こちらもFoundation版なので、ESI版のお使いのversionとの違いを丁寧に調べることができる方であれば、十分参考になる書籍です。
cfMeshに関しては↓こちらのオープンCAE学会から技術書典にOpenFOAMでメッシュ作成【PDF版】が出ています。難しい内容ではありますが、OpenFOAMのメッシュに関する内容が1000円で学べます。