持续不定期更新:CFDC++之拟一维喷管流动的数值解(1)
前言:
學(xué)習(xí)openfoam,或者準(zhǔn)確來說,CFD,斷斷續(xù)續(xù)也有5個(gè)多月。3月底在本科學(xué)校寫下的第一篇openfoam學(xué)習(xí)的博文,到現(xiàn)在在研一的學(xué)校里,嘗試自己寫代碼計(jì)算cfd問題,慢慢一點(diǎn)一點(diǎn)地構(gòu)建自己的自信心。其實(shí)說實(shí)話,學(xué)CFD很難,尤其是前期要戰(zhàn)勝純理論帶來的「空虛」感,找到學(xué)習(xí)的落腳點(diǎn)。我不敢說現(xiàn)在的自己又足夠的自信,但堅(jiān)信「即使沒有希望也要堅(jiān)持下來」,終有一天會(huì)在學(xué)習(xí)中找到自我。
學(xué)習(xí)C++是因?yàn)橹皩W(xué)openfoam時(shí)理解代碼所需,后來漸漸敲起了代碼。在暑假時(shí)看了john D. Anderson教授的計(jì)算流體力學(xué)基礎(chǔ)及其應(yīng)用這本書,這對初學(xué)的我來說無疑是雪中送炭。不僅繪聲繪色地回答我「什么是CFD」、「為什么要有CFD」等等問題,而且還很系統(tǒng)地講解了一些很基礎(chǔ)很基礎(chǔ)的流體、計(jì)算流體的概念。公式推導(dǎo)之詳盡,為我掃清了學(xué)習(xí)CFD的第一道障礙。在此書的第七章之后,便是一些「應(yīng)用」。說是應(yīng)用,其實(shí)離真正的工程應(yīng)用還遠(yuǎn)著呢。作者只是將前面6章講到的知識(shí)、方法,應(yīng)用到一些比價(jià)理論化的模型上罷了。這篇博文便是寫此書的第一個(gè)應(yīng)用的模型「拉伐爾噴管」。
暑假看此書時(shí)便已有自己寫代碼摸索的打算,但彼時(shí)正在看openfoam的代碼和其他的書,覺得需要“做好準(zhǔn)備”。此時(shí)準(zhǔn)備得也差不多,便想著一邊寫代碼一邊寫博文。不求進(jìn)展神速,但求每天進(jìn)步。
正文:
一、摘要
本文首先簡要地介紹了此次CFD問題中的「拉伐爾噴管」的物理模型,并在擬一維定常等熵流動(dòng)的假設(shè)條件之下,得出了解析解用于檢驗(yàn)計(jì)算結(jié)果。然后通過編程實(shí)現(xiàn)流場的初始化,以及算出最小時(shí)間間隔,與書本所給的數(shù)據(jù)基本吻合。
二、物理問題簡介
在這里偷個(gè)懶,直接截書本的圖(侵刪):
得出解析解所需方程(繼續(xù)偷懶!):
這是可以得出解析解的,解和圖像如下:
后面計(jì)算時(shí)上面的解會(huì)用來檢驗(yàn)計(jì)算結(jié)果的準(zhǔn)確性。
三、編程思路
為了與書本所給的數(shù)據(jù)對比,噴管橫截面積、初始流場照搬書本:
橫截面積公式:
效果:
密度、流速、溫度:
for (i = 0; i <= cellNumber; i++){X[i] = i * deltaX;A[i] = 1.0 + 2.2 * (X[i] - 1.5)* (X[i] - 1.5);//公式7-73,p219rho[i] = 1.0 - 0.314 * X[i];//公式7-74a,p220T[i] = 1.0 - 0.2314 * X[i];//公式7-74b,p220V[i] = (0.1 + 1.09 * X[i]) * sqrt(T[i]);//公式7-74c,p220a[i] = sqrt(T[i]);//公式7-75,p222}這是t=0時(shí)刻擬定的流場。密度、問題和流速隨x軸線性變化,這當(dāng)然是假設(shè)的啦!合理的假設(shè)能提高收斂的成功率,加快收斂速度。
為了編程效率,我在一開始定義了一些不變的常量、經(jīng)常出現(xiàn)可能要改的變量:?
constexpr auto gamma = 1.4;//氣體比熱比 constexpr auto R = 287.0;//空氣常數(shù) constexpr auto cfl = 0.5;//庫朗數(shù) constexpr auto timeStep = 1000;//時(shí)間步 constexpr auto deltaX = 0.1;//x方向間距接著,我定義了流場的類。
constexpr auto cellNumber = 30;class cellField { private:double a[cellNumber + 1]; public:cellField(){for (int i = 0; i <= cellNumber; i++){a[i] = 0;}}double& operator[](int i){return a[i];}cellField(double initial){for (int i = 0; i <= cellNumber; i++){a[i] = initial;}}cellField operator+(cellField& b){cellField c;for (int i = 0; i <= cellNumber; i++){c[i] = a[i] + b[i];}return c;}cellField operator-(cellField& b){cellField c;for (int i = 0; i <= cellNumber; i++){c[i] = a[i] - b[i];}return c;}cellField operator*(cellField& b){cellField c;for (int i = 0; i <= cellNumber; i++){c[i] = a[i] * b[i];}return c;}cellField operator/(cellField& b){cellField c;for (int i = 0; i <= cellNumber; i++){c[i] = a[i] / b[i];}return c;}cellField operator+(double b){cellField c;for (int i = 0; i <= cellNumber; i++){c[i] = a[i] + b;}return c;}cellField operator-(double b){cellField c;for (int i = 0; i <= cellNumber; i++){c[i] = a[i] - b;}return c;}cellField operator*(double b){cellField c;for (int i = 0; i <= cellNumber; i++){c[i] = a[i] * b;}return c;}cellField operator/(double b){cellField c;for (int i = 0; i <= cellNumber; i++){c[i] = a[i] / b;}return c;}void inverse(cellField& b ,double e){for (int i = 0; i <= cellNumber; i++){a[i] = e / b[i];}} };//cellield類可相互加減乘除,并可與數(shù)加減乘除。以上是用于整個(gè)計(jì)算過程的流場的類。定義重載函數(shù)使得類和類之間、類和數(shù)之間能直接進(jìn)行加減乘除運(yùn)算。
變量定義都是用英文,程序比較簡單,很好理解,就不一一去解釋啦。
最后放上這一階段的結(jié)果,以及和書本數(shù)據(jù)的對比:
結(jié)果基本吻合。
四、小結(jié)
這一階段還沒有涉及到真正的計(jì)算。真正的挑戰(zhàn)還在最后。可以發(fā)現(xiàn)在流場類那邊有很多還未定義的函數(shù),包括預(yù)估步和校正步等等步驟,但我想也不會(huì)很難,只是需要比較細(xì)心。
一步步建立自信。
?
參考文獻(xiàn):
《C++ Primer Plus 第六版》
約翰D. 安德森. 計(jì)算流體力學(xué)基礎(chǔ)及其應(yīng)用[M]. 北京: 機(jī)械工業(yè)出版社, 2007.
總結(jié)
以上是生活随笔為你收集整理的持续不定期更新:CFDC++之拟一维喷管流动的数值解(1)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CorelDRAW中的三维线条表现方法
- 下一篇: 从数据获取到交通可达性分析【全流程】