目次
まずはレーシングカーの3Dモデルを探す<おぃ
自分で作ればいいんでしょうが、そこも手抜きで、落ちているものをいろいろ探してみました。なかなか stlとかobjファイルで落ちているものはなくて。。探すの実は苦労します(笑)
ちょうど、Racing Car for cfd trainingっていうのを見つけました!!
https://grabcad.com/library/racing-car-for-cfd-training
これをダウンロードしてくると、Zipファイルの中身は
こんな感じになっています。
その中に、Test.stpというファイルがあります。stlでもobjでもなくstpファイルです(笑)
OpenFOAMで使えるフォーマットに変換
ちなみに、OpenFOAMで使えるフォーマットは、以下のフォーマットです。
File extension | Format description |
.ftr | OpenFOAM triangulated format |
.stl | Stereolithography (STL), ASCII |
.stlb | Stereolithography (STL), binary |
.obj | Wavefront object (OBJ) |
.off | 3D Object File Format (OFF) |
.vtk | Visualisation Toolkit (VTK) |
.tri | Triangle format |
.ac | Inivis AC3D |
.smesh | TenGen surface mesh format |
.gts | Midas Geotechnical & Tunnel analysis System (GTS) |
.dx | OpenDX format |
で、stpというのは、Stlのパーツモデルのようで、ひとつのStlにするには、FreeCADの場合は、パーツを全部選んで、エキスポートするといいようです。stlでもobjでもOKです。
ただし、注意が必要で、FreeCADでは.stlがバイナリーで、.astがstlのアスキー形式らしいです。なので、ファイル名.astで保存して名前をあとでファイル名.stlに変更する必要があります。
なお、DEXCS版のFreeCADには、マクロが入っていてexportStl.pyでアスキー形式で保存できるようです。(なんかエラー出ますが。。)
スケールの変換
OpenFOAMは基本m単位で指定するようです。このCADファイルは、mm単位で入っていました(簡単に書いてますが、これに気づくのに2日ほどかかってたりします(笑) 下記ではstlで書いていますが、最初からObjでエキスポートした方が楽です)
Paraview ファイル名.stl
で開き、モデルを選んだ状態で、InfomationタブのBoundsというところを見ると、どんな数値で入っているのかがわかります。
X range -465 to 3222.76 (delta: 3687.76)
となっているので、mm単位だというのがわかりますね。
STL や、OBJファイルのスケール (単位) の変換を行うには、OpenFOAM のユーティリティ surfaceConvert を使う。たとえば mm から m に変換する場合は次のようにする。
$ surfaceConvert -scale 0.001 carmodel.stl carmodel2.stl
などのようにします。日本語で書かれたヘルプは便利です。
paraviewで出来たファイルを見てみると、Infomation のBoundsのところの値がm単位になっているのがわかります。x Rangeを見てみると3.6mほどの車になってますよね。
ここで、あとあと面倒にならないように、STLファイルをOBJファイルに変えて、名前もmotorBike.objにしておくといいです。(計算設定ファイル類をmotorBikeのものを使うためです)
計算テンプレート(チュートリアル)のコピー
cd cd $FOAM_RUN cp -r $FOAM_TUTORIALS/incompressible/simpleFoam/motorBike ./CarModel
motorBikeのチュートリアルをディレクトリにコピーします。
先ほど作ったモデルのファイルを、以下のディレクトリに入れます。ついでにobjに形式を入れ替えます。
cp コピー元 constant/triSurface/motorBike.stl surfaceConvert motorBike.stl motorBike.obj
メッシュ作成
まずは、surfaceCheckです。
surfaceCheck motorBike.obj > log.surfaceCheck
grep 'illegal triangles' log.surfaceCheck
Surface has no illegal triangles.
と出てくればOK。
出てこない場合は、
surfaceConvert motorBike.obj motorBike-1.obj -clean > /dev/null
ですが。。詳しくは、前回の記事を読んでください。
ついでにvtkファイルも必要なので、作っておきます
surfaceConvert motorBike.obj motorBike.vtk
計算エリア(風洞)を作る(BlockMesh)
計算エリアを作るのですが、blockMeshを使います。これの制御用ファイルが、system/blockMeshDictというファイルです。
これの詳しい説明は、ここ か ここ か ここを見てみてください。
元のファイルから変更しなければならないところは、赤字のところです。
convertToMeters 1; vertices ( (-5 -4 0) (15 -4 0) (15 4 0) (-5 4 0) (-5 -4 8) (15 -4 8) (15 4 8) (-5 4 8) ); blocks ( hex (0 1 2 3 4 5 6 7) (20 8 8) simpleGrading (1 1 1) );
つまりは、風洞自体の大きさを車が入るようにしてあげないといけないのです。それの位置を決めているのが、vertices(頂点)で、その分割数が、blocks hex の赤字の部分です。
風洞の大きさを決める
先ほど、surfaceCheckしましたが、その時に作ったlog.surfaceCheckを見ると、
Bounding Box : (-0.465 -0.84 -0.06) (3.22276 0.76 0.815657)
ってあります。モデルの最小値と最大値です。
surfaceCheck motorBike.obj -blockMesh >bMtext
と打つと、bMtextの中にblockMeshDict infoができます。これはぎりぎり車が入るサイズのです。
// blockMeshDict info vertices ( (-0.465 -0.84 -0.06) (3.22276 -0.84 -0.06) (3.22276 0.76 -0.06) (-0.465 0.76 -0.06) (-0.465 -0.84 0.815657) (3.22276 -0.84 0.815657) (3.22276 0.76 0.815657) (-0.465 0.76 0.815657) ); blocks ( hex (0 1 2 3 4 5 6 7) (10 10 10) simpleGrading (1 1 1) ); edges (); patches (); // end blockMeshDict info
ブロックゲージ比 風洞の大きさ
まずは、前面投影面積に対して、風洞の幅と高さがどれくらい必要か?っていう概念で、ブロックゲージと呼ばれるそうです。この資料や、この資料によると
ブロッケージ比=車の断面積/測定区間の断面積 = 0.2%
ってあります。ここまで大きいと計算も時間がかかるので、30m、10m 10mくらいでも良さそうです。
さっきのBounding Boxの値から、だいたい計算で出すと、こんな感じになります。
車体 | x | y | z |
Point 1 | -0.465 | -0.84 | -0.06 |
Point 2 | 3.22276 | 0.76 | 0.815657 |
Offset | -0.04 | ||
3.68776 | 1.6 | 0.875657 | |
風洞 | 30 | 10 | 10 |
Point 1 | -3.78 | -5.04 | -0.06 |
Point 2 | 26.22 | 4.96 | 9.94 |
で、Hexの方は 30 10 10に変更かな?
blockMeshDictを以下のように変更します。
vertices ( (-3.78 -5.04 -0.06) (26.22 -5.04 -0.06) (26.22 4.96 -0.06) (-3.78 4.96 -0.06) (-3.78 -5.04 9.94) (26.22 -5.04 9.94) (26.22 4.96 9.94) (-3.78 4.96 9.94) ); blocks ( hex (0 1 2 3 4 5 6 7) (30 10 10) simpleGrading (1 1 1) );
やっと。。
blockMesh
と打ち込めます(笑)
一応、確認
paraFoam
と打ち込むと、風洞部分だけが見えます。wireframeにしておいて、triSurfaceにあるmotorBike.objを読み込むと確認できます。
なんとなく大きさ関係がわかりますね。当然だけど、blockMeshもだいたい立方体に切れている。
次はsnappyHexMesh
今度は、レーシングカーを、さきほど作った風洞の中に入れる作業です。
まずは、特徴線の抽出です
surfaceFeatureExtract
motorBike.eMesh が出来ているはずです。
snappyHexMeshDictの編集
snappyHexMeshのOpenFOAM 1712のWikiはこちら。。使い方は、こちらとこちらも参考に。。
で。。実はこれでハマったんですよね。もしモデル名をmotorBike.obj以外にしていると、これがまた大変で、snappyHexMeshDictの中にあるmotorBikeを全部変更しないとダメです。
次に、
geometry { motorBike.obj { type triSurfaceMesh; name motorBike; } refinementBox { type searchableBox; min (-1.0 -0.7 0.0); max ( 8.0 0.7 2.5); } };
このsearchableBoxで細分化している領域を決めています。メッシュを細かくきる部分ですね。モデルより少し大きくしていないとダメです。
Bounding Box : (-0.465 -0.84 -0.06) (3.22276 0.76 0.815657)
ですから、
min (-1.0 -1.04 -0.06)
max (8.0 0.96 2.5)
と変更します。(値は適当ですが、後ろを少し長めにして、上方向も高めにしてます)
そしていよいよsnappyHexMeshです。
snappyHexMesh -overwrite
結構時間かかります。
できたら、checkMeshしてParaviewで確認
checkMesh paraFoam
こんなメッシュが切れてたら、計算ができるってことです。 タイヤを回転させたり、本当は、空気の入り口で道路面の流速を落とすとかもできるようです。
simpleFoamの実行
うまく行ってたら、シミュレーションの実行です。
サイズなどほとんどいっしょなので、何も変更せずに動きました。動かし方は以下を参照ください。
一応、やるコマンドは
初期条件のコピー
cp -r 0.orig/* 0
並列計算ファイル作成
systemのフォルダ内
mv decomposeParDict.6 decomposeParDict
decomposePar
(decomposeParは、解析対象フォルダのトップで実行)
初期条件を計算して、計算実行
mpiexec -np 6 potentialFoam -noFunctionObjects -parallel
mpiexec -np 6 simpleFoam -parallel> log &
再結合
reconstructPar
で並列計算のファイルを再結合します。
表示
paraFoam
です。
結果の表示
読み込んだら、圧力を選んで、Wireframeにして、StreamTracerで流れ線を書いてみると、こんな感じで表示されます。Sliceなどで圧力を表現してみたり、面白いです。
StreamTracerとかを出すには、まず○○.OpenFOAMを選んでおいて、左のところのApplyを幼いと、Stream Tracerとか出てこないので注意
solidで書いてみると
もう少しかっこいいですね(笑)
ちなみに、これ20m/s (62km/h)の風があたっているという想定です。
空気抵抗係数Cd、リフト係数Clなど、あまり落ち着いていないので、正しいのかどうか??わかりませんが。。レーシングカーだとCdが0.8くらいあるんですね。F1でだいたい1って言われているので、そんなもんかも知れません。Clが小さいですけどねぇ。
やっと、実寸の場合のものができました。ラジコン用にしようと思うと、レイノルズ数が。。とかいろいろ内容がわかってないとだめみたいですが。。
誰か一緒に勉強してみません??(笑)
Paraviewについて詳しく乗っているサイト見つけました。
https://www.rccm.co.jp/icem/pukiwiki/index.php?%E5%8F%AF%E8%A6%96%E5%8C%96-Tips
[…] ≫【OpenFOAM】やっとレーシングカーボディを仮想風洞実験しました エアロダイナミクスチュートリアル【CFD】≫Chapter6_Aircraft.pdf […]