こんにちは(@t_kun_kamakiri)
今回はOpenFOAMで以下のような配管内の水の流れを解析し、境界と任意の断面での流量を計算します。

【OpenFOAM】境界面での流量計算(volFieldValue)
※本記事のモデル作成方法はこちらをご参考ください。
しかし、c1~c5の断面での流量を出力するにはどうしたらいいのかなと思って自分なりに試してみた内容を書いています。
OpenFOAMで任意の断面での流量を計算する。
【使用環境】
OpenFOAM-v2012(WSL2)
流量を出力する方針
流量を計算する方法はパッと考えると以下の方法があるでしょう。
- 流量計測したい断面にあらかじめ面かセル領域を用意しておく
 - cellZoneSetを使ってfunction objectを使う
 - codedFunctionObjectという機能で直接コードを埋め込む
 
①の方法はあらかじめ計算する前に用意する必要があると考えて今回は試しませんでした。
今回は解析計算が終わった後でも出力できる方法として②と③を試したのでご紹介します。
②が本記事の内容
とはいえ、任意の断面での流量を直接出力するのはわからなかったので任意の領域を通過する平均流速を求めて面積を掛けて流量$Q=vA$とする方針にしました。
※任意の面を通過する流量とすると、入ってきて出ていく量の合計を計算するのことになって結局0になってしまいました。なので、いったん平均流速を求めて面積を掛けて流量を求めればいいやと思った次第です。
②cellZoneSetを使ってfunction objectを使う
まずは指定した領域を作るためにcellZoneをtopoSetで作ります。
以下のピンクの領域ですね。

例えば以下のようなコマンドでtopoSetが使われているチュートリアルを探して適当にコピーします。
| 
					 1  | 
						find $FOAM_TUTORIALS -name "topoSetDict"  | 
					
以下のように候補が出てきます。
| 
					 1 2 3 4 5  | 
						/opt/OpenFOAM/OpenFOAM-v2012/tutorials/multiphase/potentialFreeSurfaceDyMFoam/oscillatingBox/system/topoSetDict /opt/OpenFOAM/OpenFOAM-v2012/tutorials/multiphase/compressibleInterDyMFoam/laminar/sphereDrop/system/topoSetDict /opt/OpenFOAM/OpenFOAM-v2012/tutorials/multiphase/driftFluxFoam/RAS/mixerVessel2D/system/topoSetDict /opt/OpenFOAM/OpenFOAM-v2012/tutorials/multiphase/potentialFreeSurfaceFoam/oscillatingBox/system/topoSetDict (以下省略)  | 
					
適当にコピーします。
| 
					 1  | 
						cp -r /opt/OpenFOAM/OpenFOAM-v2012/tutorials/incompressible/pimpleFoam/RAS/TJunctionFan/system/topoSetDict system/  | 
					
topoSetの作り方はこちらの公式サイトを参考にします。
system/topoSetDict
| 
					 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  | 
						actions (     {         name    c1;         type    cellZoneSet;         action  new;  //新規追加         source  boxToCell; //範囲の指定方法 boxToCellは六面体により指定         box     (-0.21 -0.21 0.05) (0.21 0.21 0.06); //Min座標 Max座標     }     {         name    c2;         type    cellZoneSet;         action  new;  //新規追加         source  boxToCell; //範囲の指定方法 boxToCellは六面体により指定         box     (-0.21 -0.21 0.12) (0.21 0.21 0.13); //Min座標 Max座標     }     {         name    c3;         type    cellZoneSet;         action  new;  //新規追加         source  boxToCell; //範囲の指定方法 boxToCellは六面体により指定         box     (-0.21 -0.21 0.17) (0.21 0.21 0.18); //Min座標 Max座標     }     {         name    c4;         type    cellZoneSet;         action  new;  //新規追加         source  boxToCell; //範囲の指定方法 boxToCellは六面体により指定         box     (-0.21 -0.21 0.25) (0.21 0.21 0.26); //Min座標 Max座標     }     {         // Mandatory (inherited) entries         name        c5;         type        cellZoneSet;         action      new;         // Mandatory entries         source      cylinderToCell; //始点終点と半径から円柱領域を指定         p1          (0 -0.15 0.15);         p2          (0 -0.16 0.15);         radius      0.01;         // Optional entries         //innerRadius <radius2>;     } );  | 
					
領域の作り方は1つではありません。
今回は以下の2つを使った方法を示していますが、どちらを使っても良いです。
- boxToCell; //範囲の指定方法 boxToCellは六面体により指定
 - cylinderToCell; //始点終点と半径から円柱領域を指定
 
では、topoSetを実行します。
| 
					 1  | 
						topoSet  | 
					
constant/polyMesh/setに以下のようにファイルができます。
| 
					 1 2 3 4 5 6  | 
						constant/polyMesh/sets/ ├── c1 ├── c2 ├── c3 ├── c4 └── c5  | 
					
例えば「c1」を見ると、
| 
					 1 2 3 4 5 6  | 
						1216 ( 86065 86066 81972 (以下省略)  | 
					
1216個のセルがあるということでしょうか。
この数字は次のcodedFunctionObjectでも出てきますのでちょっと記憶の片隅に残しておきましょう。
topoSetで作ったcellZoneはParaViewで確認することができます。

| 
					 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  | 
						    //Add     volFieldValue1     {         // Mandatory entries (unmodifiable)         type            volFieldValue;         libs            (fieldFunctionObjects);         // Mandatory entries (runtime modifiable)         fields          (U p);         operation       volAverage;         regionType      cellZone;         name            c1;         // Optional entries (runtime modifiable)         postOperation   none;         weightField     alpha1;         // Optional (inherited) entries         writeFields     false;         scalingFactor   1.0;         writePrecision  8;         writeToFile     true;         useUserTime     true;         region          region0;         enabled         true;         log             true;         timeStart       0;         timeEnd         10000;         executeControl  timeStep;         executeInterval 1;         writeControl    timeStep;         writeInterval   100;     }     volFieldValue2     {         $volFieldValue1         name            c2;     }     volFieldValue3     {         $volFieldValue1         name            c3;     }     volFieldValue4     {         $volFieldValue1         name            c4;     }     volFieldValue5     {         $volFieldValue1         name            c5;     }  | 
					
cellZoneによる領域の物理量は平均流速以外にも以下の量を出力することができます。
| 
					 1 2 3 4 5 6 7 8 9 10 11  | 
						none : no operation sum : summation sumMag : sum of magnitude average: average weightedAverage: weighted average volAverage: volume average weightedVolAverage: weighted volume average volIntegrate: volume integral min: minimum max: maximum CoV: coefficient of variation  | 
					
実行すればcellZoneでの平均流速と平均圧力が出力されます。
| 
					 1  | 
						simpleFoam > log.simpleFoam &  | 
					
計算が終わった後にcontrolDictのfunction objectだけを実行したい場合は、
| 
					 1  | 
						simpleFoam -postProcess  | 
					
とします。
例えばc1に対しては、
postProcessing/volFieldValue1/0/volFieldValue.dat
| 
					 1 2 3 4 5 6 7 8 9  | 
						# Region        : cellZone c1 # Cells         : 1216 # Volume        : 1.25374567e-05 # Time          	volAverage(U)	volAverage(p) 100             	(-6.91239995e-06 -5.72589460e-06 1.00545029e-01)	1.80967825e+01 200             	(-6.90135638e-06 -5.60361338e-06 1.00541477e-01)	1.80968310e+01 (省略) 2000            	(-6.71016485e-06 -4.74256383e-06 1.00544414e-01)	1.81051521e+01 2100            	(-6.84017444e-06 -5.02236067e-06 1.00543984e-01)	1.81051721e+01  | 
					
流速が「-6.84017444e-06 -5.02236067e-06 1.00543984e-01」なので断面積を掛けると流量$Q=0.000126284$になりますね。
理論値との誤差は0.54%です。
その他にもc2~c5も同様に平均流速がpostProcessingに出力されています。




まとめ
今回は流量を出力する方法をまとめました。
- 任意の断面の流量計算(topoSet)
 
lob.simpleFoamのログファイルに、以下同じc1領域を計算したものを出力しています。
- topoSetDictで作った領域からvolFieldValueで計算したのが上
 - codedFunctionObjectで計算したのが下
 
| 
					 1 2 3 4 5 6 7 8 9 10 11  | 
						volFieldValue volFieldValue1 write:     volAverage(c1) of U = (-6.71016e-06 -4.74256e-06 0.100544)     volAverage(c1) of p = 18.1052 (省略) ============= codevolFieldValue =============== volFieldValue codevolFieldValue write: volAverage(codevolFieldValue) of U =(-6.71016e-06 -4.74256e-06 0.100544) volAverage(codevolFieldValue) of p =18.1052 volAverage(codevolFieldValue) of phi = U*A = 0.000126284 Vi 1216 End  | 
					
平均流速、平均圧力ともに同じ値になっていますね。
また、topoSetで作ったセルの数が1216でしたが、コードで計算したものも同じ1216です。
さらにコードの中で平均流速に面積を掛けて流量を計算して$Q=vA=0.000126284$と出しています。
topoSetとcodedFuctionの結果は同じになりましたので、慣れればcodedFuctionが汎用性が効きますね。
参考書
有限体積法の勉強にはこの本で間違いないです。
対流項目が中心差分で安定しないことを理論的に評価しておりとても参考になります。
OpenFOAMの基本的な設定を学ぶことができる書籍として以下の参考書がお勧めです。
改訂新版 OpenFOAMの歩き方 (技術の泉シリーズ(NextPublishing))
本書はESI版ではなくFoundation版でありOpenFOAMv2.xで書かれたやや古い内容です。その点に注意してESI版のお使いのversionとの違いを丁寧に調べることができる方であれば、十分参考になる書籍です。
OpenFOAM全般の設定などまとめられた書籍として以下のものがあります。
こちらもFoundation版なので、ESI版のお使いのversionとの違いを丁寧に調べることができる方であれば、十分参考になる書籍です。
こちらのオープンCAE学会から技術書典にOpenFOAMでメッシュ作成【PDF版】が出ています。難しい内容ではありますが、OpenFOAMのメッシュに関する内容が1000円で学べます。


											
![数値流体力学 [第2版]](https://m.media-amazon.com/images/I/51m13QQg5cL._SL500_.jpg)






























