1 明確目標——為啥費老大勁兒學習OpenFOAM
學習OpenFOAM主要出於課題需要,希望實現以下幾個目標:
l 【 】學會用SnappyHexMesh生成高質量網格;
l 【 】學習使用OpenFOAM自帶的 Immersed Boundary Method (IBM)處理復雜幾何邊界;
l 【 】實現LES算例;
l 【 】實現CFD的批處理以完成大量算例。
2 前期准備——在Win10上安裝OpenFOAM
這部分主要參CFD大佬【流沙】提供的方法,詳情見網頁:
https://www.cnblogs.com/LSCAX/p/7074326.html
出於方便考慮,直接在Github上下載並安裝BlueCFD,詳情見下載頁:
https://github.com/blueCFD/Core/releases/tag/blueCFD-Core-2017-2
目前已經更新到 2017-2 版,搭載OpenFOAM 5.0 版本,基本能滿足使用要求。
3 入門算例學習—— lid-driven cavity flow
3.1 問題描述
一開始不打算寫問題描述,在找lid-driven cavity flow一詞的中文翻譯的時候才發現也有大佬學習這個算例,而且這個算例能說明湍流的特征,也有相關的實驗支持,所以添加問題描述這個環節,關於這部分的知識主要參考網頁:
【陳十七】cavity算例https://blog.csdn.net/weixin_39124457/article/details/88926300
lid-driven cavity flow 翻譯成中文就是 頂蓋驅動方腔流 (參考知網翻譯),理想模型見 圖 3‑1 。當頂蓋以不同的速度運動時,方腔內的流體會呈現不同的流動特征。方腔流可以反映出不同雷諾數條件下的流場特性, 並且流場中包含了渦旋、二次流、復雜三維流動、不穩定層流、過渡流和紊流等多種現象, 成為研究復雜紊動流場最為理想的物理模型, 也是驗證數值模擬方法准確度和效率的標准(張金鳳,2015)。
圖 3-1 頂蓋驅動方腔流動模型,左為OpenFOAM Tutorial給出的計算模型,右圖為實驗模型
在OpenFOAM中求解這個問題主要分為三個環節:前處理()——求解——后處理。首先將官方指南設置好的算例放入RUN所在的文件夾下,在BlueCFD終端中輸入:
1 cd $FOAM_RUN 2 3 cp -r $FOAM_TUTORIALS/incompressible/icoFoam/cavity/cavity . 4 5 cd cavity
在cavity下面有這樣三個文件夾。
圖 3 ‑ 2 cavity文件夾下所包含的內容
輸入以下代碼也能顯示cavity文件夾下的目錄結構,結果如 圖 3‑3 所示:
1 tree $FOAM_RUN/cavity
圖3-3 在BlueCFD終端下查看cavity文件夾下所包含的內容
一般case文件夾包括三個子文件夾,每部分的內容分別是:
0:存儲物理量的初始值
——p:存儲初始時刻的壓力
——U:存儲初始時刻的速度
constant:存儲網格參數、邊界條件以及物理屬性(如材料參數、湍流參數等)
——polyMesh:blockMesh生成的網格文件
——transportProperties:物理特性
system:存儲求解控制參數
——blockMeshDict:blockMesh網格控制文件
——controlDict:求解時間步的控制參數和輸出控制參數
——fvScheme:離散格式
——fvSlotion:算法格式
上述內容參考:【流沙】的博客http://blog.sina.com.cn/s/blog_599d8faa0102wq09.html
3.2 前處理(pre-processing)
OpenFOAM默認按照三維笛卡爾坐標運行,lid-driven cavity的算例是二維的運動,所以通過設置 empty 的邊界條件實現二維的計算。
3.2.1 創建幾何並生成網格
本例采用OpenFOAM自帶的網格生成器blockMesh實現,包含網格信息的文件名為blockMeshDict,放在目錄cavicity/system下面。
圖 3 ‑ 4 blockMeshDict的存放位置
在BlueCFD終端輸入以下代碼可以查看文件的內容:
1 cat $FOAM_RUN/cavity/system/blockMeshDict
在終端顯示結果如下:
圖 3 ‑ 5 blockMeshDict的內容
可以看到blockMeshDict大致包含以下幾個部分的內容
1. 軟件信息
1 /*--------------------------------*- C++ -*----------------------------------*\ 2 3 | ========= | | 4 5 | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | 6 7 | \\ / O peration | Version: 5 | 8 9 | \\ / A nd | Web: www.OpenFOAM.org | 10 11 | \\/ M anipulation | | 12 13 \*---------------------------------------------------------------------------*/ 14 15 //說明基本信息
2. 基本參數
FoamFile
1 { 2 3 version 2.0; 4 5 format ascii; 6 7 class dictionary; 8 9 object blockMeshDict; 10 11 }
3. 定義縮放比
1 convertToMeters 0.1; //說明縮放尺寸,即模型中1個幾何單位代表0.1m
4. 定義頂點
1 vertices //定義了立方體的頂點坐標,8個頂點,編號0~7 2 3 ( 4 5 (0 0 0) 6 7 (1 0 0) 8 9 (1 1 0) 10 11 (0 1 0) 12 13 (0 0 0.1) 14 15 (1 0 0.1) 16 17 (1 1 0.1) 18 19 (0 1 0.1) 20 21 ); 22 23 5. 定義block和block的網格划分 24 25 blocks 26 27 ( 28 29 hex (0 1 2 3 4 5 6 7) (20 20 1) simpleGrading (1 1 1) 30 31 ); 32 33 //定義了構成block立方體的所有點,x、y和厚度方向分別划分為20、20、1個網格,simpleGrading應該指的是網格的尺寸的比例
6. 定義邊
1 edges 2 3 ( 4 5 ); //定義邊 edge,這里是體網格,所i有沒有edge
7. 定義邊界
1 boundary //定義邊界 2 3 ( 4 5 movingWall //定義頂部的運動壁面,外面的名字是邊界面的名稱 6 7 { 8 9 type wall; //邊界面的類型 10 11 faces 12 13 ( 14 15 (3 7 6 2) //由3762四個點構成的面,其中按照順序以右手法則確定法向量 16 17 ); 18 19 } 20 21 fixedWalls 22 23 { 24 25 type wall; 26 27 faces 28 29 ( 30 31 (0 4 7 3) 32 33 (2 6 5 1) 34 35 (1 5 4 0) 36 37 ); //定義靜止壁面 38 39 } 40 41 frontAndBack 42 43 { 44 45 type empty; //定義前面和后面均為empty以實現二維運動 46 47 faces 48 49 ( 50 51 (0 3 2 1) 52 53 (4 5 6 7) 54 55 ); 56 57 } 58 59 );
8. 定義需要融合的部分
1 mergePatchPairs 2 3 ( 4 5 ); //list of patches to be merged 6 7 blockMeshDict文件編寫好后,在BlueMesh終端輸入以下命令即可執行網格生成blockMesh
返回如圖3‑6所示結果。
圖3 ‑ 6 blockMesh生成網格返回的結果
3.2.2 查看網格
建議采用Paraview查看網格划分結果,為了保持Paraview一直打開,所以在調用Paraview的命令后面空格兵添加&符號:
1 paraFoam &
圖 3 ‑ 7 在Paraview中查看划分的網格
ParaView的使用也不太熟悉,做到這一步的時候真的感覺我是從零學起,哭遼。
注意先選定要繪制的part,點擊apply之后再修改繪圖的控制選項。
圖 3 ‑ 8 在Paraview中設置顯示網格划分的結果
3.2.3 邊界設置和初始條件確定
因為整個過程從時刻 開始,所以如前文所述,初始條件放在0這個文件夾下面,包括壓力(文件夾p)和速度(文件夾U)。首先看p文件包含的信息,如 圖 3‑9 所示。
圖3-9 p文件包含的信息
頭文件略去,其余信息分析如下:
1. 量綱
一個7維向量來定義,每一維表示的量綱如 表 3‑1 所示:
表3-1 OpenFOAM的量綱
維度 |
物理量 |
SI單位 |
USCS單位 |
1 |
質量(Mass) |
Kg |
lbm |
2 |
長度(Length) |
m |
ft |
3 |
時間(Time) |
s |
s |
4 |
溫度(Temperature) |
K |
ºR |
5 |
物質的量(Quantity) |
mol |
mol |
6 |
電流(Current) |
A |
A |
7 |
發光強度(Luminous intensity) |
cd |
cd |
這個p文件里的量綱為m2s-2,即為運動壓力(Kinematic pressure)的量綱
1 dimensions [0 2 -2 0 0 0 0]; //定義量綱,這里指運動壓力
2. 場的初始條件
流場的每個控制點的數值,這里定義為均勻(uniform)並取為0
1 internalField uniform 0; //場的初始值,即流場的每個控制點值,這里定義為均勻(uniform)並取為0
3. 邊界的初始條件
1 boundaryField 2 3 { 4 5 movingWall 6 7 { 8 9 type zeroGradient; 10 11 } 12 13 14 15 fixedWalls 16 17 { 18 19 type zeroGradient; //定義壓力梯度為零,即法向壓力梯度為零 20 21 } 22 23 24 25 frontAndBack 26 27 { 28 29 type empty; //empty使流動為二維 30 31 } 32 33 }
速度場的初始條件也是類似的:
1 dimensions
1 dimension [0 1 -1 0 0 0 0]; //速度的量綱 m/s 2 internalField uniform (0 0 0); //定義速度場的初始值,注意速度場是個矢量,所以是定義的是向量 3 4 5 6 boundaryField //定義的邊界的速度 7 8 { 9 10 movingWall 11 12 { 13 14 type fixedValue; 15 16 value uniform (1 0 0); //和頂蓋的移動速度一致 17 18 } 19 20 21 22 fixedWalls 23 24 { 25 26 type noSlip; //無滑移壁面邊界條件 27 28 } 29 30 31 32 frontAndBack 33 34 { 35 36 type empty; //設置前后為empty來實現二維流動 37 38 } 39 40 }
3.2.4 物理性質
物理性質通常定義在命名為 xxProperties 的文件中,對於本問題只需要定義運動粘度所以放在文件 tansportProperties 中,定義的代碼如下:
1 nu [0 2 -1 0 0 0 0] 0.01; //定義運動粘度nu,前面的向量為量綱
注意在這里,考慮雷諾數為10,根據那么運動粘度取值為0.01
3.2.5 時間控制
時間步的控制及相關的輸出文件在system文件夾下的controlDict文件中。開始和結束時間是必須設定的,比如設定開始時間為0,這意味着OpenFOAM需要從名為0的文件夾中讀取數據。這里將startFrom指定為startTime,並設定值為0,將stopAt指定為endTime,且指定為0.5s(即頂蓋完整地划過10次)。
時間步長的關鍵詞為deltaT,可以通過庫朗數來確定,庫朗數定義為:
其中 表示速度方向的網格尺寸, 為時間,需要保證在每一處地方 ,考慮最極端的情況有:
反算得到 。指定OpenFOAM按照一定的時間步輸出,那么就會在創建相應的時間步的文件夾如0,1.0,2.0等,將相關文件保存在其中。
1 application icoFoam; //求解器選擇icoFoam 2 3 4 5 startFrom startTime; //指定開始的關鍵詞 6 7 8 9 startTime 0; //指定開始時間 10 11 12 13 stopAt endTime; //指定結束的關鍵詞 14 15 16 17 endTime 0.5; //指定結束的時間 18 19 20 21 deltaT 0.005; //指定時間步長 22 23 24 25 writeControl timeStep; //指定文件輸出的方式:按照時間步輸出 26 27 28 29 writeInterval 20; //每20個時間步輸出一個結果 30 31 32 33 purgeWrite 0; 34 35 36 37 writeFormat ascii; 38 39 40 41 writePrecision 6; 42 43 44 45 writeCompression off; 46 47 48 49 timeFormat general; 50 51 52 53 timePrecision 6; 54 55 56 57 runTimeModifiable true;
3.2.6 離散和求解器的設置(Discretisation and linear-solver settings)
若采用有限體積法,則離散格式的設定在system文件夾下的fvSchemes文件中,線性求解器和誤差等算法格式的指定在system文件夾下的fvSolution文件中確定。對於本問題,當考慮為不可壓縮流體時候,采用PISO算法,需要注意的本文采用的是相對壓力(運動壓力),所對需要指定pRefValue和pRefCell兩個關鍵詞。
3.3 求解(Running an application)
當前處理的每個部分都設置好之后,求解實質上就調用求解器,對於低層流,這里調用icoFoam,並指定相應的算例文件:
1 icoFoam -case $FOAM_RUN/cavity
圖 3 ‑ 10 計算結束后生成0.1~0.5結果的文件夾
3.4 后處理(Post-processing)
后處理也是熟悉Paraview的一個重要過程
1. 點擊apply,確保cavity.foam左邊地小眼睛是藍色的。
2. 選擇要編輯的物理量,點擊Edit,在右邊可以調整繪圖的選項。
point icon和 cell icon 的區別:
point icon以每個單元的值插值后繪制
cell icon 每個單元只有賦一個值
3. 【略,媽的paraview好難上手】
3.5 加密網格
3.5.1 在原來算例的基礎上創建新的算例
首先創建cavityFine的算例文件夾,並將原始cavity的文件的設置文件constant和system文件夾拷貝到新的算例文件夾下
1 mkdir cavityFine 2 cp -r cavity/constant cavityFine 3 cp -r cavity/system cavityFine 4 cd cavityFine
3.5.2 修改blockMesh文件
修改blockMesh將網格尺寸變為(40,40,1),,保存文件后重新輸入命令blockMesh即可生成需要的網格。
!!!注意!!!我發現在blueCFD中,當修改網格文本之后,首先要退回到run文件夾下重新進入cavityFine這個時候才能讀取更新后的網格文本。
3.5.3 把粗網格的結果映射到細網格上
mapFields命令能夠將一個幾何的場結果映射到另一個幾何上面,本例中粗細網格的幾何和邊界都是一樣的,因此在調用mapFields命令時輸入的參數選項為-consistent,並將粗網格的最后的結果映射到細網格開始的時刻(細網格中controlDict的startTime相應地要改為0.5):
1 mapFields $FOAM_RUN/cavity -consistent -sourceTime ‘latestTime’
由於網格尺寸減小了,根據庫朗數控制的時間步長也要調整為0.0025s,將輸出控制從timeStep改為從runTime輸出,每0.1s輸出一次結果,因此writeInterval改為0.1。注意因為cavityFine的startTime改為0.5了,所以endTime應該改為0.7s。
1 //… 2 3 application icoFoam; 4 5 6 7 startFrom startTime; 8 9 10 11 startTime 0.5; 12 13 14 15 stopAt endTime; 16 17 18 19 endTime 0.7; 20 21 22 23 deltaT 0.0025; 24 25 26 27 writeControl runTime; 28 29 30 31 writeInterval 0.1; 32 33 //…
可以看到運行icoFoam后,從0.5s開始算到了0.7s,且計算過程沒有輸入到blueCFD的終端上,而是放在了日志文件中:
計算的結果可以看到從0.5s(20網格)到0.7s(40網格)的變化過程