こんにちは(@t_kun_kamakiri)
OpenFOAMで流体解析をする際のメッシャーであるsnappyHexMeshを使ったメッシュ再分割について自身の理解を深めるためにまとめました。
特に形状が複雑である場合にデフォルトの設定でメッシュ生成を行うと、形状変化が激しい部分でメッシュが作れていなかった、メッシュが潰れてガタガタになったりします。
本記事ではこのような形状の場合を考えます。
※形状に特に意味はありません。
太い円筒では粗いメッシュとし、細い円筒では細かいメッシュにしたいという場合を考えます。blockMeshやsnappyHexMeshは少し触ってみたけど、これからメッシュ再分割について検討していきたい方を対象としています。
- blockMeshやsnappyHexMeshを使ったことがある方
- OpenFOAMのメッシュ再分割を行いたい方
FreeCAD:0.20
OpenFOAM ESI版:v2012
本記事のモデルはこちらから入手可能です。
snappyHexMeshの使い方
snappyHexMeshの使い方に関しては以下の資料を参考にしてください。
詳細の設定は公式サイトをご参考ください。
モデルの作成はXsim
基本的な設定はXsimを使って行いました。
XsimはGUI上で簡単にOpenFOAMの設定が行えるWebアプリです。設定のひな形を作る際にはよく利用させてもらっています。
注意としてはXsimがFoundationのOpenFOAMでの出力を前提としているためESI版のOpenFOAMを使う方はAllrunのスクリプトを実行してもエラーとなります。特に特徴線を抽出するファイルで、
- Foundation版:surfaceFeaturesDict
- ESI版:surfaceFeatureExtractDict
と、まずファイル名が違いますし、中身の記述も異なります。
そういった違いを認識していればXsimは強力なツールとなります。
blockMeshでのメッシュが粗い場合
では、まずblockMeshでのベースメッシュが粗い場合にどうなるかを見ていきます。
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 | FoamFile { version 2.0; format ascii; class dictionary; location "system"; object blockMeshDict; } vertices ( (-0.04799582 -0.04799872 -0.00799962) (0.04799962 -0.04799872 -0.00799962) (0.04799962 0.04799872 -0.00799962) (-0.04799582 0.04799872 -0.00799962) (-0.04799582 -0.04799872 0.30799962) (0.04799962 -0.04799872 0.30799962) (0.04799962 0.04799872 0.30799962) (-0.04799582 0.04799872 0.30799962) ); blocks ( hex (0 1 2 3 4 5 6 7) (15 15 50) simpleGrading (1 1 1) ); edges (); patches (); mergePatchPairs (); |
メッシュの分割数は以下で設定しています。
1 2 3 4 | blocks ( hex (0 1 2 3 4 5 6 7) (15 15 50) simpleGrading (1 1 1) ); |
x方向のBoxサイズ100mmに対して15分割なので、ひとセルの一辺が6mm程度ということになります。
細い円筒の半径が5mmなので、メッシュのセルが1つ入るかどうかという際どいところです。よって、下の絵のようにメッシュを切ることができず、大きい円筒のみメッシュ作成されてしまい、中途半端なメッシュができています。
形状の変化をとらえるのであれば最低4点は必要なので、今よりさらに4分割は必要でしょう。
ちなみに、snappyHexMeshでの設定はどうなっているかというと・・・・
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | FoamFile { version 2.0; format ascii; class dictionary; location "system"; object snappyHexMeshDict; } castellatedMesh true; snap true; addLayers true; geometry { model_m.stl { type triSurfaceMesh; name test; } refinementBox1 { type searchableBox; min (-0.03 -0.03 0.05); max ( 0.03 0.03 0.25); } refinementBox1 { type searchableBox; min (-0.01 -0.01 0.1); max ( 0.01 0.01 0.2); } } castellatedMeshControls { features ( { file "model_m.eMesh"; level 0; } ); refinementSurfaces { test { level (0 0); patchInfo { type wall; } } } refinementRegions { refinementBox1 { mode inside; levels ((0 0)); } refinementBox2 { mode inside; levels ((0 0)); } } locationInMesh (0 0 0.05); maxLocalCells 100000000; maxGlobalCells 100000000; minRefinementCells 1; nCellsBetweenLevels 9; resolveFeatureAngle 30; allowFreeStandingZoneFaces false; } snapControls { nSolveIter 30; nSmoothPatch 3; tolerance 4.0; nRelaxIter 5; nFeatureSnapIter 10; //implicitFeatureSnap false; explicitFeatureSnap true; //multiRegionFeatureSnap false; } addLayersControls { layers { test_walls { nSurfaceLayers 0; } } relativeSizes true; expansionRatio 1.0; finalLayerThickness 0.3; minThickness 0.03; nGrow 1; featureAngle 60; nRelaxIter 5; nSmoothSurfaceNormals 1; nSmoothNormals 3; nSmoothThickness 10; maxFaceThicknessRatio 0.5; maxThicknessToMedialRatio 0.3; minMedianAxisAngle 130; nBufferCellsNoExtrude 0; nLayerIter 50; nRelaxedIter 20; } meshQualityControls { maxNonOrtho 65; maxBoundarySkewness 20; maxInternalSkewness 4; maxConcave 80; minFlatness 0.5; minVol 1.00E-13; minTetQuality -1e30; minArea -1; minTwist 0.05; minDeterminant 0.001; minFaceWeight 0.05; minVolRatio 0.01; minTriangleTwist -1; nSmoothScale 4; errorReduction 0.75; relaxed { maxNonOrtho 180; } } debug 0; mergeTolerance 1e-5; |
メッシュの再分割などは行っていません。
現状では形状通りにメッシュ作成を行っておらず、改善が必要です。
改善方法は以下の通りです。
上記の考えをファイルの設定に反映させてどのようになるのかを見ていきます。
blockMeshの分割数を上げる
まずはblockMeshでの分割数を1つ上げてみます。
細い円筒の半径5mmなので最低でも5mmのメッシュサイズにする必要だろうという考えです(9mmでも良いかもしれませんが・・・)。
これでようやくギリギリメッシュが作成できるサイズです。
system/blockMeshDict(抜粋)
1 2 3 4 | blocks ( hex (0 1 2 3 4 5 6 7) (20 20 65) simpleGrading (1 1 1) ); |
上記のように分割数を増やしメッシュのセルの1辺が5mmくらいになるようにします。
こちらの変更により形状通りにメッシュ作成ができるようになりました。
しかし、細い円筒部分のメッシュサイズが大きので円筒形状というより円柱の形状になっています。
まだまだ分割数が足りていません。やはり、形状の再現にはもうひと分割以上が必要ということで以下のように分割数を増やしていきます。
blockMeshでの分割数が80×80×206 = 1664000(160万)ともなるとさすがに手元のPCでもちょっと時間がかかる印象です。数分程度ですが・・・
全体のベースメッシュのサイズを細かくすることは不必要にメッシュ数を増やすことになるので、もし実務で大きいサイズのモデルを扱った場合にメッシュ生成に膨大な時間がかかることが予想されます。
全体のベースメッシュのサイズを変えずに、形状変化が大きい部分(太い円筒)は粗く、形状変化が小さい部分(細い円筒)は細かくするようにしたいですね。
snappyHexMeshで再分割を行う
snappyHexMeshでメッシュ再分割を行います。
再分割の方法は主に以下の設定があります。
- 特徴線まわりの再分割
- 特定領域の再分割
- 面全体で再分割
- 特定の面で再分割
特徴線まわりのメッシュ再分割
特徴線まわりでメッシュ再分割する場合は以下の部分で設定します。
system/snappyHexMeshDict(抜粋)
1 2 3 4 5 6 7 8 9 10 | castellatedMeshControls { features ( { file "model_m.eMesh"; level 1; } ); 以下省略 } |
これは特徴線のまわりでメッシュの再分割を行う設定です。
特徴線は以下のようになっています。特徴線は「system/surfaceFeatureExtractDict」で.eMeshファイルを作成します。
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 | FoamFile { version 2.0; format ascii; class dictionary; object surfaceFeatureExtractDict; } model_m.stl { extractionMethod extractFromSurface; extractFromSurfaceCoeffs { includedAngle 150; } subsetFeatures { nonManifoldEdges no; openEdges yes; } writeObj yes; } |
ParaViewでは.eMeshファイルは直接読み込むことができないので.objファイルに変換する必要があります。
変換のコマンドは以下です。
1 | surfaceFeatureConvert constant/triSurface/model_m.eMesh constant/triSurface/model_m.obj |
※model_m.eMeshは今回の「model_m.stl」のファイル名に対応していますので、使っているstlファイルの名前に合わせて変更してください。
特徴線まわりでメッシュ再分割を行うと以下のような変化になります。
左が元の設定、右が特徴線まわりで再分割した場合です。
太い円筒と細い円筒での繋ぎ目には特徴線があるためメッシュの再分割がされていますが、細い円筒に沿って特徴線があるわけではないので、細い円筒の真ん中あたりはメッシュが粗いままです。
特定領域の再分割
形状に合わせてというわけではなく、指定した領域のメッシュの再分割の設定を行います。
system/snappyHexMeshDict(抜粋)
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 | geometry { 省略 refinementBox1 { type searchableBox; min (-0.03 -0.03 0.05); max ( 0.03 0.03 0.25); } refinementBox1 { type searchableBox; min (-0.01 -0.01 0.1); max ( 0.01 0.01 0.2); } } 省略 refinementRegions { refinementBox1 { mode inside; levels ((2 2)); } refinementBox2 { mode inside; levels ((1 1)); } } |
geometryの中で「type searchableBox;」により最小と最大の座標を設定して再分割する直方体領域を設定します。
refinementRegionsで再分割するレベルを設定します。
これにより指定した領域のメッシュ再分割ができました。
しかし、形状が複雑になってくると細かくしたい領域が複数でてきて、全てに上記の設定をするのはとても面倒なので、何とか指定した面に対して再分割を行うようにしたいものです
面全体で再分割(1)
特定の面全体で再分割を行います。
CADソフトで形状を作成してstlファイルにするとソリッドに面が生成されて出力されます。面の再分割の簡単な設定としてはstlで生成された面全体に対してメッシュの再分割を行うことです。
system/snappyHexMeshDict(抜粋)
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 | geometry { model_m.stl { type triSurfaceMesh; name test; } 省略 } 以下省略 castellatedMeshControls { 省略 refinementSurfaces { test { level (0 0); patchInfo { type wall; } } } 以下省略 |
geometryでmodel_m.stlの全体の表面の名前を「name test;」でtestと名前を付けています。その面を「refinementSurfaces」で分割するという設定です。
表面全体が再分割されているので全体のメッシュが細かくなっているように見えますが、断面を見るとメッシュの表面だけ(nameで名前を付けた部分だけ)が再分割されています。
特定の面で再分割(2)
面で再分割(1)ではメッシュの表面全体の再分割でしたが、これも無駄にメッシュ数を多くする可能性があるので、特定の面だけを再分割したいですね。
今は以下のように面に名前がついています。
今回はwallsという面で再分割を行います。
system/snappyHexMeshDict(抜粋)
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 | geometry { model_m.stl { type triSurfaceMesh; name test; regions { walls { name walls; } } } 省略 } castellatedMeshControls { 省略 refinementSurfaces { test { level (0 0); regions { walls { level (1 1); patchInfo { type wall; } } } } } |
wallsという面でメッシュ再分割が行われています。
ちなみにstlファイルで面に名前を付けたとしてもgeometryのregionsで面に名前を定義しない場合は、左のようにgeometryで面に名前を付けた「test」にアンダーバーを付けて「test_walls」などという名前に付け変わります。
ここに注意しないと境界層を入れようとした際に面の名前が変わっているので、境界層が生成されずにハマります・・・
右のようにgeometryのregionsで面に名前を定義していれば、面の名前は「walls」のままです。
特定の面で再分割(2)–さらに面を分割
先ほどは太い円筒も細い円筒もwallsという面の名前でしたが、さらに面分割を行います。
具体的にはFreeCADで以下のようにwallsをさらに面分割してstlとして出力しなおします。
面分割のマクロは以下の記事に書いているように、自動化しているためそれほど手間な作業ではありません。
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 38 39 40 41 42 43 44 45 46 | import os import Mesh import MeshPart import re # 現在のディレクトリ doc = App.ActiveDocument PWD = re.findall("(.*)/",doc.FileName)[0] print('現在のディレクトリ:',PWD) labels = [] for obj in doc.Objects: if obj.Visibility == True: if obj.Label[0:3] == 'bc:': mesh = doc.addObject("Mesh::Feature", "Mesh") print(mesh) # mefisto #mesh.Mesh = MeshPart.meshFromShape(Shape=obj.Shape, MaxLength=10) # standard mesh.Mesh = Mesh.Mesh(obj.Shape.tessellate(0.01)) print(mesh.Mesh) label = obj.Label[3:] labels.append(label) Mesh.export([mesh], fr'{PWD}/{label}.ast') print(label) doc.removeObject(mesh.Name) print(doc.Label) print(labels, type(labels)) with open(rf'{PWD}/{doc.Label}.stl', 'w') as f: print('test') for label in labels: with open(rf'{PWD}/{label}.ast', 'r') as fi: for line in fi: if line[:5] == 'solid': line = 'solid ' + label + '\n' elif line[:8] == 'endsolid': line = 'endsolid ' + label + '\n' f.write(line) for label in labels: os.remove(rf'{PWD}/{label}.ast') |
少し余談ですが、FreeCADでmmと書いていても出力された際には数値しか拾ってきていないの解析でm単位で行う場合に1000倍大きな形状で解析を行ってしまいます。
なので、以下のようなコマンドで1/1000倍に変換しておく必要があります。
1 | surfaceConvert -scale 0.001 constant/triSurface/model.stl constant/triSurface/model_m.stl |
今回は「thin_wall」(細い円筒)だけメッシュの再分割を行います。
system/snappyHexMeshDict(抜粋)
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 38 39 40 41 | geometry { model_m.stl { type triSurfaceMesh; name test; regions { thin_wall { name thin_wall; } } } max ( 0.03 0.03 0.25); } 省略 } castellatedMeshControls { 省略 ); refinementSurfaces { test { level (0 0); regions { thin_wall { level (1 1); patchInfo { type wall; } } } } } 以下省略 |
右のようにgeometryのregionsで面に名前を定義していれば、面の名前は「thin_wall」のままですね。
境界層を入れる
壁側は流れが0になり壁から少し離れると流速が壁と平行になっているため、メッシュを層にして入れると精度よく解析が行えるため境界層メッシュを入れる場合があります。
system/snappyHexMeshDict(抜粋)
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 | geometry { model_m.stl { type triSurfaceMesh; name test; regions { thin_wall { name thin_wall; } wall3 { name wall3; } } } 省略 } addLayersControls { layers { wall3 { nSurfaceLayers 3; } } 省略 } |
addLayersControlsで「walls」という面に3層の境界層を入れるようにしています。
しかし、snappyHexMeshはメッシュの再分割と境界層の相性がわるいのか端でメッシュが潰れてしまって上手く境界層が入らない場合があります。
snappyHexMeshで境界層がなかなかうまくいかない。 pic.twitter.com/v4HnZvWMDh
— カマキリ🐲Python頑張る昆虫 (@t_kun_kamakiri) October 8, 2022
このあたりの設定は追々検証して別途記事にしたいと思います。
snappyHexMeshDictファイルの全体
最終的なsnappyHexMeshDictの設定を載せておきますので、記事内のどの部分を触っているのか確認してみてください。
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | FoamFile { version 2.0; format ascii; class dictionary; location "system"; object snappyHexMeshDict; } castellatedMesh true; snap true; addLayers true; geometry { model_m.stl { type triSurfaceMesh; name test; regions { thin_wall { name thin_wall; } wall3 { name wall3; } } } refinementBox1 { type searchableBox; min (-0.03 -0.03 0.05); max ( 0.03 0.03 0.25); } refinementBox1 { type searchableBox; min (-0.01 -0.01 0.1); max ( 0.01 0.01 0.2); } } castellatedMeshControls { features ( { file "model_m.eMesh"; level 0; } ); refinementSurfaces { test { level (0 0); regions { thin_wall { level (1 1); patchInfo { type wall; } } } } } refinementRegions { refinementBox1 { mode inside; levels ((0 0)); } refinementBox2 { mode inside; levels ((0 0)); } } locationInMesh (0 0 0.05); maxLocalCells 100000000; maxGlobalCells 100000000; minRefinementCells 1; nCellsBetweenLevels 9; resolveFeatureAngle 30; allowFreeStandingZoneFaces false; } snapControls { nSolveIter 30; nSmoothPatch 3; tolerance 4.0; nRelaxIter 5; nFeatureSnapIter 10; //implicitFeatureSnap false; explicitFeatureSnap true; //multiRegionFeatureSnap false; } addLayersControls { layers { wall3 { nSurfaceLayers 3; } } relativeSizes true; expansionRatio 1.0; finalLayerThickness 0.3; minThickness 0.03; nGrow 1; featureAngle 60; nRelaxIter 5; nSmoothSurfaceNormals 1; nSmoothNormals 3; nSmoothThickness 10; maxFaceThicknessRatio 0.5; maxThicknessToMedialRatio 0.3; minMedianAxisAngle 130; nBufferCellsNoExtrude 0; nLayerIter 50; nRelaxedIter 20; } meshQualityControls { maxNonOrtho 65; maxBoundarySkewness 20; maxInternalSkewness 4; maxConcave 80; minFlatness 0.5; minVol 1.00E-13; minTetQuality -1e30; minArea -1; minTwist 0.05; minDeterminant 0.001; minFaceWeight 0.05; minVolRatio 0.01; minTriangleTwist -1; nSmoothScale 4; errorReduction 0.75; relaxed { maxNonOrtho 180; } } debug 0; mergeTolerance 1e-5; |
ちなみにメッシュ品質は
1 | checkMesh |
により確認ができます。
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | Mesh stats points: 20659 faces: 56602 internal faces: 52666 cells: 18070 faces per cell: 6.04693 boundary patches: 7 point zones: 0 face zones: 0 cell zones: 0 Overall number of cells of each type: hexahedra: 16209 prisms: 1088 wedges: 0 pyramids: 0 tet wedges: 0 tetrahedra: 0 polyhedra: 773 Breakdown of polyhedra by number of faces: faces number of cells 4 32 5 16 6 261 7 48 9 243 12 106 15 67 Checking topology... Boundary definition OK. Cell to face addressing OK. Point usage OK. Upper triangular ordering OK. Face vertices OK. Number of regions: 1 (OK). Checking patch topology for multiply connected surfaces... Patch Faces Points Surface topology test_zmin 208 229 ok (non-closed singly connected) test_zmax 364 385 ok (non-closed singly connected) test_wall1 880 940 ok (non-closed singly connected) test_wall2 556 608 ok (non-closed singly connected) wall3 880 940 ok (non-closed singly connected) test_wall4 712 764 ok (non-closed singly connected) thin_wall 336 360 ok (non-closed singly connected) Checking faceZone topology for multiply connected surfaces... No faceZones found. Checking basic cellZone addressing... No cellZones found. Checking geometry... Overall domain bounding box (-0.0399962 -0.0399974 -5.89695e-06) (0.04 0.0399974 0.300009) Mesh has 3 geometric (non-empty/wedge) directions (1 1 1) Mesh has 3 solution (non-empty) directions (1 1 1) Boundary openness (1.34606e-16 8.22112e-18 -5.78301e-17) OK. Max cell openness = 2.97032e-16 OK. Max aspect ratio = 5.42524 OK. Minimum face area = 1.52599e-06. Maximum face area = 3.84114e-05. Face area magnitudes OK. Min volume = 7.29907e-09. Max volume = 1.62253e-07. Total volume = 0.00100852. Cell volumes OK. Mesh non-orthogonality Max: 45.9609 average: 6.58619 Non-orthogonality check OK. Face pyramids OK. Max skewness = 1.91894 OK. Coupled point location match (average 0) OK. Mesh OK. |
以下の部分は最低確認するようにしましょう。
- Max aspect ratio:アスペクト比(縦横の比率)→境界層で大きくなりやすいので大きすぎる場合は確認
- non-orthogonality:直交性→70°以上であれば修正
- Max skewness:歪度→4以上だと修正
メッシュ品質の基準は以下のファイルにも記載がありますで確認してみましょう。
1 | $WM_PROJECT_DIR/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/ |
コマンドでファイルを探す場合は、
1 | find $FOAM_SRC -name "primitiveMeshCheck*" |
以下のように出力されます。
1 2 3 4 5 6 7 | /opt/OpenFOAM/OpenFOAM-v2012/src/OpenFOAM/lnInclude/primitiveMeshCheckEdgeLength.C /opt/OpenFOAM/OpenFOAM-v2012/src/OpenFOAM/lnInclude/primitiveMeshCheckPointNearness.C /opt/OpenFOAM/OpenFOAM-v2012/src/OpenFOAM/lnInclude/primitiveMeshCheck.C /opt/OpenFOAM/OpenFOAM-v2012/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck /opt/OpenFOAM/OpenFOAM-v2012/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshCheckEdgeLength.C /opt/OpenFOAM/OpenFOAM-v2012/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshCheckPointNearness.C /opt/OpenFOAM/OpenFOAM-v2012/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshCheck.C |
primitiveMeshCheck.Cの中身を確認しましょう。
1 | vi /opt/OpenFOAM/OpenFOAM-v2012/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshCheck.C |
該当箇所は「:primitiveMesh」と打って「n(下へ)」「shift + n(上へ)」で探すことができます。
viを終了するには
ESCボタンを押して「:q」か「:q!」で終了することができます。
1 2 3 4 5 | Foam::scalar Foam::primitiveMesh::closedThreshold_ = 1.0e-6; Foam::scalar Foam::primitiveMesh::aspectThreshold_ = 1000; Foam::scalar Foam::primitiveMesh::nonOrthThreshold_ = 70; // deg Foam::scalar Foam::primitiveMesh::skewThreshold_ = 4; Foam::scalar Foam::primitiveMesh::planarCosAngle_ = 1.0e-6; |
シミュレーションを行う場合、低品質なセルや面によって生じる数値誤差を低減できる数値スキームを選択します。
もう少しメッシュは綺麗にすることができますが(そんなときもある・・・)、細かなこだわりはこの辺までにしておきます。再分割として本記事で紹介した方法があるというのを知っているとsnappyHexMeshでの設定で迷うことはないと思います。
まとめ
メッシュの再分割の色々な設定を見てきました。
特徴線まわりのメッシュ再分割と境界層を入れると、やはり境界層が上手くできません。
snappyHexMeshに関してはメッシュの分割と境界層との相性が良くないのかもしれません。
OpenFOAMのメッシュ作成としてはcfMeshもあるので別の記事で紹介します_(._.)_
ちょっとがたついているけどcfMeshの方が簡単? https://t.co/vR1mfx5cyX pic.twitter.com/wZS67nW7bu
— カマキリ🐲Python頑張る昆虫 (@t_kun_kamakiri) October 9, 2022
cfmeshはテトラメッシュやポリヘドラルメッシュも可能でsnappyHexMeshより設定がずいぶんと簡単でした。
参考書
FreeCADは以下の書籍で勉強ができます。
OpenFOAMの数少ない日本語の書籍としては以下のものがあります。
改訂新版 OpenFOAMの歩き方 (技術の泉シリーズ(NextPublishing))
バージョンが古いですがOpenFOAMのプログラミング(C++)を学ぶには以下の書籍がわかりやすいです。