Help us understand the problem. What is going on with this article?

OpenFOAMのチュートリアル改変2 - blockMeshDictの編集

前提

  • VirtualBoxとDEXCSを使ってOpenFOAMを実行していること。(それ以外の環境でも、多少読み替えれば以下を理解できなくもないが、初心者にはお勧めしない。それよりも、自分と同じ環境の人が作った解説ページを探すか、あるいはVirtualBoxとDEXCSを使ってOpenFOAMをインストールしなおすのがよいと思う。)
  • 別ページの「OpenFOAMのチュートリアル実施」を読んだか、またはOpenFOAMのチュートリアルの実行の仕方が分かること。

まずはチュートリアルをそのまま実施

チュートリアルの「pitzDaily」を例に説明する。pitzDailyにはいくつかのバージョンがあるが、今回はpisoFoamという解法のものを例に説明する。

このチュートリアルには「Allrun」ファイルが無いので、各コマンドを手動で入れる必要がある。といっても、このチュートリアルの場合は「blockMesh」と「pisoFoam」の2コマンドを実行するだけでよい。

以下の命令は、(1) チュートリアルからpitzDailyフォルダをコピーし、(2) コピーしたpitzDailyフォルダの中に入り、(3) blockMeshを実行し、(4) pisoFoamを実行し、(5) 結果を表示する、というもの。ただしpisoFoamを単純に実行すると、ログの表示時間が馬鹿にならないので、grepで部分的に表示させている。この行を単に「pisoFoam」としても(「|grep」から行末まで消す)、時間はかかるが同じ結果が得られる。

チュートリアルpitzDailyをそのまま実施
run
cp -r $FOAM_TUTORIALS/incompressible/pisoFoam/LES/pitzDaily .
cd pitzDaily
blockMesh
pisoFoam |grep -E 'Time\s=\s[0-9]*\.[0-9]\s'
paraFoam

paraViewの画面になってから、Play(再生)ボタンを押すと、結果がアニメーション表示される。
無題15.png
左上から流入し、右側から流出する。その際、左下に角があるため、この個所に吹き溜まり生じ、途中に渦ができる様子がシミュレーションされる。

確認出来たら、一度paraViewを終了する。つまり、paraView画面右上のクローズボタン(赤い×ボタン)をクリックする。)

流路形状の構造の説明

流路はブロックからできている

blockMeshを使う場合、全ての領域は、点8個から成る四角いブロックから構成されている。このチュートリアルの流路は、5つのブロックからできている。
無題16.png
上の図を見て分かるように、ブロック同士は面全体で結合している。なお、この図は、見やすくするため、オリジナルよりも厚さを増やしている。

オリジナルのブロック構成は次のようになっている。
無題17.png
オリジナルの青ブロックの上に、もう一つブロックを乗せたいとする。この場合、次の図のようにブロックを足すことはできない、
無題17a.png
追加した茶色いブロックと、元からある青いブロックが、全面では接触していない(青いブロックの右半分のみと接触している)ためである。この形で解析をしたい場合には、元からあるブロックも分割して、例えば、次の図のようにする必要がある。
無題17c.png
この修正には時間がかかるので、今回は簡単に、次の図のように改造することにする。
無題17b.png
以下でこの改造方法を理解すれば、もう一つ上の分割も、手間はかかるが、同様に実行することができるようになる。

改造の前に、オリジナルのブロックがどのように構成されているか説明する。まずは上の図の黄色いブロックについてのみ説明する。

点の定義

ブロックの構成は「system/blockMeshDict」というファイルで定義されている。まずは次のコマンドで、これを開いて見る。

blockMeshDictの編集
xdg-open system/blockMeshDict

すると、次のようなファイルが開く。(ただし行末で「// 0」のように書かれている箇所は、私が書き足した注釈です。)
無題20.png
19行目の「vertices」で定義されているのが、頂点である。行の上の方から点0、点1...となっており、最後が点21である。以下、この点の番号で、図形を定義することになる。点の番号は、(1ではなく)0から始まることに注意。番号は自動で付与されるので、以下で立体形状を定義した後に、気が変わってverticesの途中の行を削除すると、立体形状の定義を全部書き換える必要がある。

立体と分割の定義

立体の定義では、まずはブロックを定義する。このチュートリアルの黄色(右下)のブロックは、次のように構成されている。
無題21.png
つまり、点5, 6, 8, 9, 16, 17, 19, 20の8点で構成されている。このブロックの定義は、先ほどのblockMeshDictファイルの「blocks」の箇所に書かれている。
無題22.png
ブロックの順番に縛りは無いが、このブロックにも0から始まる番号が自動付与され、エラーメッセージが出た場合にはその番号が表示される。

黄色のブロックは、下から2つめのhex、つまり、

hex (5 8 9 6 16 19 20 17)
(25 27 1)
simpleGrading (2.5 1 1)

の3行である。最初の行は、8つの点を並べたものであるが、並べ方にルールがある。ブロックの向かい合った面を1組選び、その1つの面の点を反時計周りにつなげる。例えば黄色のブロックの場合、奥の面と手前の面を選び、奥の面を構成する4点(5, 6, 8, 9)を反時計回りに並べる。例えば次の図の緑の矢印の順につなげる。
無題21b.png
上の図の例では、(5 8 9 6)である。どこから始めてもよいので、例えば(9 6 5 8)としてもよい。次に、その向かい側の面も、対応する順に並べる。最初の面で(5 8 9 6)とした場合は16 19 20 17となるので、まとめると(5 8 9 6 16 19 20 17)となる。最初の面を(9 6 5 8)とした場合は20 17 16 19となるので、まとめると(9 6 5 8 20 17 16 19)となる。

次の行「(25 27 1)」は、立体の分割数である。細かく分割した方が正確な結果が得られるが、計算に時間がかかる。そのため、流れが複雑なところは細かく、流れが単純なところは粗く分割するのが基本である。ブロックを(a b c d e f g h)で定義し、分割を(j, k, l)で定義した場合、辺a-bと、辺e-fがj分割されることになる。このチュートリアルの場合は、辺5-8と、辺16-19が、(25 27 1)の最初である25分割されることになる。
無題21d.png
3行目の「simpleGrading (2.5 1 1)」は、分割のパターンを意味する。「simpleGrading」は「一定の比率で分割をだんだん長くしていく」というものである。辺5-8は、等間隔での分割ではなく、分割区間がだんだんと広くなっていく。辺5-8は、この値が「2.5」と定義されているので、最初(左端)の分割と、最後(右端)の分割の長さの比が1:2.5になっている。この値が「1」の場合は、等間隔で分割される。この値が1よりも小さくなると(例えば0.5)、分割区間がだんだんと狭くなっていく。

なお、隣り合うブロックの分割数と分割ピッチを一致させる必要がある。これは、大変重要なポイントである。
無題23.png
このチュートリアルでは、黄色ブロックの上に桃色ブロックが接しているから、桃色ブロック下辺の分割は、黄色ブロックの分割と一致させる必要がある。黄色ブロックの左に緑ブロックがあるから、黄色ブロックと緑ブロックはY軸方向の分割を一致させる必要がある。

もし一致していないと、blockMeshコマンドを実行した時にエラーとなる。例えば、黄色ブロックの分割数を(24 27 1)に変えてみたら、次のようなエラーが出た。
無題24.png
OpenFOAMのエラーメッセージは、初心者には読みづらいが、上の例では「FOAM FATAL ERROR」の箇所が注目ポイントである。そのすぐ後に「Inconsistent number of face between block pair 3 and 4」とあり、これがエラーの直接原因である。要するに、ブロック3とブロック4の関係に問題あり、ということ。このブロックの番号は、先述したblockMeshDictの「blocks」の節に書かれた0から始まる順番であり、この場合は、ブロック3(黄色)とブロック4(桃色)、つまり「hex (5 8 9 6 16 19 20 17)」と「hex (6 9 10 7 17 20 21 18)」の間に問題があるということである。このエラーが見つかった場合は、例えばこの場合は「blocks」のブロック3とブロック4の定義に矛盾が無いかチェックすること。

次に、境界の定義が必要となる。

境界の名称と種類の定義

このチュートリアルでは、「境界」を5種類に分けている。次の図は、先ほどの立体の壁に、境界の種類別に色を付けて、角度を変えて2つ表示したもの。
無題25.png
図の紫色が「inlet」、緑色が「outlet」、赤色が「upperWall」、水色が「lowerWall」、オレンジ色が「frontAndBack」である。これらの名称は適当に付けられたものであるので、inletを例えばiriguchiなどに変更してもかまわないが、別ファイルでこの名称が何回も使われるので、変更したい場合はそれら全部を変更する必要がある。

このチュートリアルでは「inlet」から水を入れ、「outlet」から水が出る。「upperWall」と「lowerWall」は水を通さない壁、「frontAndBack」は計算しないものとして計算する。まずはblockMeshDictに、これらの名前と境界の種類を定義する。細かい条件は後で別のファイルに記述する。

定義場所は「system/blockMeshDict」の「boundary」の箇所である。
無題26.png
ここで再び点の位置を確認する。
無題16.png
「inlet」は点0, 1, 11, 12で囲まれた四角である。これを立体形状の時計回りに並べる。この例では、例えば(0 1 12 11)である。どこから始めても同じことで、例えば(1 12 11 0)としてもよい。あるいは反時計回りに(0 11 12 1)としてもよい。「inlet」の境界の種類(type)は、液の流入である。境界を液が通過する場合には、「patch」と定義する。つまり、inletは次のように定義される。

inlet
{
    type patch;
    faces
    (
        (0 1 12 11)
    );
}

「outlet」は、点8, 9, 19, 20と、点9, 10, 20, 21で囲まれた四角である。これも4点を時計回り、または反時計回りに並べて面を定義する。outletは、inletとは異なり液が流出する面であるが、境界を液が通過することになるので、ここも種類はpatchとなる。

outlet
{
    type patch;
    faces
    (
        (8 9 20 19)
        (9 10 21 20)
    );
}

「upperWall」は、液が流れないものとして定義する。種類はwallとなる。ここは、先ほどの図の赤い面なので、つまり3面となる。

upperWall
{
    type wall;
    faces
    (
        (1 4 15 12)
        (4 7 18 15)
        (7 10 21 18)
    );
}

「lowerWall」についても「upperWall」と同じような感じで定義する。

2次元解析の場合、「高さ方向」の境界は「empty」として定義する。emptyが定義できるのは、「高さ方向」の厚さが薄く均一な場合に限られる。このチュートリアルは2次元解析であり、先の図ではオレンジ色の面がemptyに当たる。ここを「frontAndBack」として定義する。

frontAndBack
{
    type empty;
    faces
    (
        (0 3 4 1)
        (2 5 6 3)
        (3 6 7 4)
        (5 8 9 6)
        (6 9 10 7)
        (11 14 15 12)
        (13 16 17 14)
        (14 17 18 15)
        (16 19 20 17)
        (17 20 21 18)
    );
}

以上のように、どのブロックとも接しない面は、必ず定義する必要がある。逆に、ブロックとブロックが接する面(つまり流路内部の面)をboundaryで定義すると、エラーになる。

茶色ブロックの追加

前述したように、次のように改造する方針である。
無題17b.png
茶色ブロックを作るためには8つの点が必要であるが、茶色ブロックの下面は青色ブロックの上面と共通なので、上面側の4点のみを追加すればよい。追加する4点は、青色ブロック上面の4点から、Y軸方向に移動させた点にすればよい。青ブロックのY軸方向の長さは25.4mmなので、青ブロック上面の4点をY軸方向に25.4ずつ増やせばよい。
無題16.png
青色ブロック上面の点は、上の図から分かるように、点4, 点7, 点15, 点18である。再びblockMeshDictを開いて、verticesの箇所の末尾に追加する。

blockMeshDictの編集
xdg-open system/blockMeshDict

編集後は次の通り。45-48行目が追加部分である。
無題28.png
例えば45行目は、点4、つまり25行目の「(0 25.4 -0.5)」から、yの値を25.4増やしたものである。

ここで一回blockMeshを実行する。エラーが出なければ、paraFoamをblockMeshチェックモードで開く。

blockMeshの実施とblockMeshモードでparaFoam実施
blockMesh
paraFoam -blockmesh

これらを実施して、paraViewが起動してから、Applyした後に適当にマウスで視点を変えると、次の図が現れる。(ただし、見やすくするため、この図は実際よりも厚みを増してある。)
無題27.png
追加した点が認識されていることが分かる。

次に、茶色のブロックを追加する。茶色のブロックは点4, 7, 15, 18, 11, 22, 23, 24, 25の8点からできている。これを並べ替えてブロックを作る。すぐ下の青いブロックが、前述したようにhex (3 6 7 4 14 17 18 15)と定義されているので、これを参考に、同じように8点をつなげればよい。つまり、hex (4 7 23 22 15 18 25 24)となる。辺の分割パターンは、この場合は青ブロックにだけ合わせればよいので、青ブロックの定義をそのまま借用(コピー)する。
無題29.png
上の93-95行目が、追加部分である。

次に、boundaryの定義をする。まず、青ブロックの上面、つまり(4 7 18 15)は、茶色ブロックに挟まれて内部に隠れるため、upperWallから削除する。茶色ブロックの前後の面、つまり(4 7 23 22)と(15 18 25 24)は、frontAndBackに加える。茶色のinlet側の面である(4 15 24 22)、上面である(22 24 25 23)、outlet側の面である(18 25 23 7)は、upperWallとする。結果は次の通り。
無題31.png
上の127行目が消した箇所(青いブロックの上面)、130-132行目が追加した茶色ブロックの上面、162-163行目が茶色ブロックの前面背面である。

修正後の再実施
blockMesh
pisoFoam |grep -E 'Time\s=\s[0-9]*\.[0-9]\s'
paraFoam

結果は次の通り。
無題30.png

holdingtomato
プログラマーではありませんが、プログラム歴は30年以上です。今はVisual Basic for Application専門ですが、昔はC, Pascal, Delphiなどを主に数値計算に使っていました。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away