動網格算例 - 攪拌容器
本文將詳細介紹 OpenFOAM mixerVesselAMI2D 這個算例。這算例有很多值得注意的地方,比如 AMI 邊界條件、動網格配置方法、用宏生成網格和 topoSet 等等。
這個攪拌容器可能是一個化工反應容器,我對這個算例的研究背景不太了解,不過算例的幾何跟邊條都不複雜,很容易搞懂。圓筒容器中間有個轉子,圓筒周圍是固定的,圓筒里充滿了流體,題圖是轉子轉起來後的流速分布。
這個算例的位置是 $FOAM_TUTORIALS/incompressible/pimpleDyMFoam/mixerVesselAMI2D,算例目錄里有 0/、constant/、system/ 三個文件夾和 Allrun、makeMesh 兩個腳本。Allrun 腳本和其他算例相比,特別之處在於運行了一個 makeMesh 腳本,其他語句的含義都很直觀,不再贅述。我們再來看 makeMesh 腳本做了些什麼。
#!/bin/shncd ${0%/*} || exit 1 # Run from this directoryn# Source tutorial run functionsn. $WM_PROJECT_DIR/bin/tools/RunFunctionsnm4 < system/blockMeshDict.m4 > system/blockMeshDictnrunApplication blockMeshnrunApplication topoSetn
一個特別的命令是 m4,用 man m4 命令可以查閱命令手冊,手冊中的描述是這樣的
NAMEn m4 - macro processornnSYNOPSISn m4 [OPTION]... [FILE]...nnDESCRIPTIONn Process macros in FILEs. If no FILE or if FILE is `-, standard inputn is read.n
這下我們就明白了,這個算例用 blockMeshDict.m4 這個宏生成了 blockMeshDict 字典,這個用法非常的原生態,非常 Unix,有關 m4 的更多內容,請參閱 GNU M4 - GNU Project。簡單看下 blockMeshDict.m4 和 blockMeshDict,重點在這裡。
boundaryn(n rotorn {n type wall;n facesn (n ...n );n }nn statorn {n type wall;n facesn (n ...n );n }nn AMI1n {n type cyclicAMI;n neighbourPatch AMI2;n transform noOrdering;n facesn (n ...n );n }nn AMI2n {n type cyclicAMI;n neighbourPatch AMI1;n transform noOrdering;n facesn (n ...n );n }nn ...n);n
可見,容器的轉子 rotor 和定子 stator 都是壁面,而 AMI1 和 AMI2 是什麼呢?它們的類型是 cyclicAMI,具體介紹在這兒OpenFOAM 2.3.0: Arbitrary Mesh Interface,簡而言之,它們是固定網格和動網格的分界面。我們可以運行 ./makeMesh 後用 paraFoam 查看這些邊界和網格,如下圖,紅色的是 stator,藍色的是 AIM1 和 AIM2,白色的是 rotor,半透明的線是網格。
好了,現在我們知道,這些炫酷的操作最終生成了如上圖所示的網格。接下來我們拋開這些複雜的底層細節,看下動網格是怎麼實現的。
constant/dynamicMeshDict 字典規定了「網格怎麼動」,內容如下
dynamicFvMesh solidBodyMotionFvMesh;nnmotionSolverLibs ( "libfvMotionSolvers.so" );nnsolidBodyMotionFvMeshCoeffsn{n cellZone rotor;n solidBodyMotionFunction rotatingMotion;n rotatingMotionCoeffsn {n origin (0 0 0);n axis (0 0 1);n omega 6.2832; // rad/sn }n}n
dynamicFvMesh 關鍵字還有以下幾個值可選
dynamicInkJetFvMeshndynamicMotionSolverFvMeshndynamicRefineFvMeshnmovingConeTopoFvMeshnmultiSolidBodyMotionFvMeshnrawTopoChangerFvMeshnsolidBodyMotionFvMeshnstaticFvMeshn
可見,動網格可以細分為很多不同的類型,選擇哪種類型、怎麼讓網格動起來是個複雜的問題。在另一個動網格的算例 movingCone 中,這個關鍵字的值是 dynamicMotionSolverFvMesh。這一問題已經超出了本文討論的範圍,我們不再展開。
接下來我們看下邊界條件和初始條件,這個邊條一定要和 blockMesh 中的 type 對應,比如 type 為 patch 的邊界可以是入口出口之類的,type 為 wall 的邊界只能是 wall 或者 movingWall 之類的,AIM cycle 同理。以 0/U 為例
boundaryFieldn{n rotorn {n type movingWallVelocity;n value uniform (0 0 0);n }nn statorn {n type movingWallVelocity;n value uniform (0 0 0);n }nn frontn {n type empty;n }nn backn {n type empty;n }nn AMI1n {n type cyclicAMI;n value $internalField;n }nn AMI2n {n type cyclicAMI;n value $internalField;n }n}n
可以看到 stator 和 rotor 都用了 movingWallVelocity 邊條,而不是簡單的 wall,一個解釋是這樣的
Rotating walls that generally non-symmetric (though preferably at least periodic) and inside of the rotating zone need the boundary condition movingWallVelocity, which corrects fluxes for moving boundaries. If the boundary does not move, it behaves exactly asfixedValue. The value is zero, because it is the boundary velocity with respect to the moving frame.
https://www.cfdsupport.com/Turbomachinery-CFD-manual/node380.html
此外,topoSet、decomposePar 都很常規,沒什麼特別之處,不再討論了。
這個算例的複雜之處不在動網格,而在炫酷的網格生成技巧。除了網格,也就是 AIM 比較有特點,是這個算例的亮點。在動網格配置上,和 movingCone 類似。
動網格在 OpenFOAM 上的實現方法十分簡單,只是配置一個 constant/dynamicMeshDict 字典,並使用特別的邊界條件就行。困難仍然在於「用什麼方法讓網格動起來」這個計算流體力學問題。
推薦閱讀:
※【重磅】化工智能製造的方向 | 人工智慧並不靠譜
※天津塘沽大爆炸是因為電石么?什麼化工材料碰水就炸?
※從零開始的一生——紀念侯德榜先生誕辰127周年
※弈慧周小康重磅:從化工品談如何區分真套利和偽套利【撲克峰會】
※自我革命玩到極致了:化工巨頭阿克蘇諾貝爾,大家感受下