groovyBC は境界条件を関数で定義したり出来るようにしてくれるが、swak4Foam では、境界条件(patch)だけでなく、内部のソース項に対しても同じようなことを出来るようになっていたはず・・・という記憶があった(事を知人にコメントしてしまった)のでサンプルケースを調べてみた⇒見つかったのが表題のサンプルで、以下のようなファイル構成になっていた。
- interFoamWithSouces がソースファイル一式で、mixingThingがチュートリアルケースということらしい。
- つまり、ソース項そのものを汎用的に扱えるオブジェクトは存在しないので、ソルバーのソースコードを一部書き換える必要があるみたい。このサンプルでは、標準のinterFoamを、InterFoamWithSources に変更して使いなさいということのようです。(変更箇所の説明は後述しますが簡単です)
まずは、これをコンパイル(wmake)して、ケースファイル(mixingThing)を動かしてみる。
- prepare.shがあったので、まずはこれを実行せよということなのだろう。これを実行して、後は、interFoamWithSoureces を実行。待つこと数分。0.1秒間間隔で、5秒後までの時系列データが出力される。
- 各時系列データを調べると、通常のinterFoamの計算と異なって、momSrcというFieldデータが出力されていることがわかる。
paraFoamにて可視化してみる。
- Field変数は、alpha1と、 momSrc を別々にロードして重ね表示している
- 矩形領域の下半分に赤色の体(alpha1)が充填されている。
- 中央の縦長の白っぽくなった部分がmomSrcの値が定義されている部分で、時間とともに揺動する。
- ↓コマ送り画像をサムネール表示したもの
ソース項定義ファイル
- constantフォルダ中、momentumSouceDict というファイル
variables ( "angle=0.6*sin(time());" "direction=vector(sin(angle),cos(angle),0);" "tPos=vector(pos().x*cos(-angle)+pos().y*sin(-angle),pos().y*cos(-angle)-pos().x*sin(-angle),0);" "strength=(time()<2.5? 1000 : (time()>3.5 ? 10000 : (1000+(time()-2.5)*9000)));" ); expression "direction*((tPos.x>-0.05 && tPos.x<0.05 && tPos.y>-0.4 && tPos.y<0.1) ? strength*alpha1 : 0)"; dimensions [1 -2 -2 0 0 0 0];
sinやcosを使って、時間に応じて、場所や方向、強さも変化させているみたいで、なんとなく雰囲気はつかめる。
結局、何をシミュレーションしているのか?
- アニメーションで見ると、momSrcの領域が、攪拌板の役割をしているようで、そうでもない。というのも運動量を板の縦方向に与えているので、実は、吹き飛ばしたたかったんじゃないかと思うんだが、意図したようには吹き飛ばすことができずに、かきまぜるだけで終わってしまった結果ではないかと、勝手に想像している。
- 実は、このサンプルはswak4Foamの初期のヴァージョンから添付されていたものであるが、最近のヴァージョンでは、interFoamWithFixedというサンプルが添付されており、この挙動が、途中まではほぼ同じような動きで、後半でまさに、プールの中から外へ吹き飛ばすことに見事に成功している。
- ↑interFoamWithFixed を実行した場合
- つまり、momSourceは揺動する吸引パイプを模したもので、これでプールから水を吹き飛ばすシミュレーションを、当初考えた方法(interFoamWithSource)では出来なかったので、最近になって別の方法(interFoamWithFixed)を考えた・・・ということじゃなかろうか。
ソースコードの調査結果
標準のinterFOAMに対して変更ソースファイルは3つ
- メインプログラム
- createField.H
- UEqn.H