溫度場有限容積法程序入門之五:展望及問題

  首先總結一下以上[傳輸過程數值模擬可視化編程開發]程序的特點:

1,邊界上的節點當作內部節點處理,所有節點公用一個迭代公式;

2,可以設置多種材質,多種材料時,注意及時更新每個節點的物性參數,如密度,比熱,熱導,一般使用調和平均,參見文獻[1]。

      存在的問題:

1 ,筆者花了大約一天冒着猝死的危險寫完的,時間倉促,通用性不夠;

2,當前程序最致命的缺點在於似乎只能計算矩形區域和矩形網格,對於這些問題,可以參考直接差分法(DFDM,但是直接差分在網格扭曲度較大的情況下誤差較大),可以有效處理不規則圖形。

      其次,程序的拓展:

1, 3D拓展:

         節點需要除了東南西北增加上下兩個熱導,沒做過,但是原理是一樣的。

2,對流傳熱:

          節點熱量來源除了擴散傳導,源相外還有對流傳熱部分,如何計算對流引起的熱量傳遞呢?其實傳輸現象的微分方程中對流項是最難以計算的,表面上看是一個一階導數,實際上它還是個一階導數,只不過需要注意傳導熱和對流熱的量級關係,只有他倆量級相當,使用中心差分才能得到有意義的解。

 

          這裏講一個小故事:狼羊同飲,羊位於下游,狼意欲吃羊,曰:“你他媽污染老子的水源,拿命來”,羊說“小弟我在下游怎麼會污染大哥的水源”。如果我是狼而且懂的Pe準數(讀者快查Pe準數的意義)的話,也不會浪費口舌去吃。在羊的思維裏,下游是不會污染上游的,智商低下,果然可以被任何肉絲動物吃。事實上,當水速很低,下游會通過擴散污染上游的,所以嘛,狼吃羊就是應該的,不懂還死攪蠻纏。於是人們就發明了一階迎風、混合、二階迎風、指數、QUICK等格式去離散對流項,以考慮上游對當前節點傳輸行爲的重要性。話說筆者年青時小解順風冒三丈,可見流動的上游確實對傳輸現象有不可忽略的影響,如今老了:“廉頗老矣,尚能尿遠?”。

        曾經一位老師大吹自己年輕時流體流動傳輸編程多麼強悍,後來我一個師弟問他什麼是“一階迎風格式”,他說不知,我笑了。

       扯遠了,編程時如果考慮對流換熱,請查閱文獻[1],裏面有離散格式,在本文後面附上關於1D對流-擴散方程迭代計算學習筆記摘錄一二,就不在這裏班門弄斧了。

3,非線性材料:

         當物性參數隨溫度或位置等參數變化時,如何計算?留給讀者思考吧,筆者也不擅長。有人說將物性參數線性化,其實未必完全妥當,因爲有時就是非線性的,線性化了,反而誤差大了。提示一下,更新物性參數,多次迭代,直到兩次計算結果接近到一定程度,此時,該時刻下方程的解收斂了,以該收斂解爲初值可以迭代計算下一個時間步長的解了。

 

4,非均勻網格:

         這個也留給讀者吧,需要對過程的物理意義十分明晰。如果對整個物理方程的建立都不清楚,肯定算不對的。本文引入熱導的概念,使得計算在一定程度上得到簡化。

         

       到此,貼出來的代碼可以獨立運行了。


  附1: 一維擴散-對流方程迭代格式學習筆記(摘錄自參考文獻1):

    比如2D對流-擴散方程(pp.177)如下:

      對其在控制體體積內積分(pp.177):

     整理爲代數迭代方式,只考慮1D情形(pp.178):

    其中,不同座標系下係數計算不同(pp.179):

    上述表達式中有函數A(),其計算根據不同離散格式而不同,具體如下(pp.151):

需要特別注意的是:與積累項和源項不同的是,擴散項和對流項是從控制體邊界進入到控制體的,所以AeAw的計算使用到的物性參數及速度不是主節點的物性參數和主節點的速度(使用同位網格的話),而是需要插值計算得到的邊界上的值,具體加權平均計算公式要根據具體物理意義而定。   

 

    對於已知氣體壓強分佈的一維N-S方程,就不用SIMPLE算法迭代計算壓強了,如果使用同位網格,N-S方程解等同於對流-擴散方程的求解。附帶介紹一個自己開發的程序Demo:



    附2,FAQ:

Q1:爲什麼用熱導而不是熱阻的概念?

A:其一通用性;其二筆者印象裏,乘法的CPU時間小於除法;也許也有人會繼續問,你算熱導不是也用了除法嗎?免不了用除法,在本算例下,只在初始化時用除法算了熱導一批,而迭代過程,很多循環中用了乘法,利大於弊。

 

Q2:爲什麼網格四周添加2層多餘的網格,是爲了浪費內存嗎?

A:比如對端點處某量進行邊界條件處理,一階導數、二階導數等,對流項中高階離散格式(比如QUICK格式)的計算會用到。

 

Q3:爲什麼沒有計算迭代的穩定性?

A:樓主很懶惰,愛收斂不收斂,收斂不了把時間步長弄小。我計算每一節點的最大時間步長,浪費多少CPU時間啊。

 

 Q4:爲什麼不用隱式迭代方法,據說這種方法絕對穩定?

A:因爲顯示迭代格式物理意義清晰,隱式迭代格式精度與解析解存在一定誤差,一般用C-N格式。

這裏給出一段顯示迭代過程可能會用到的代碼,切忌不要草草照搬代碼,我的代碼main函數中矩陣係數A中首尾項在程序中無用,用於求解上對焦矩陣線性方程組,而且只是一維的;二維的是5對角矩陣;三維的是7對角矩陣。

// TDMA.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#define REAL float

#define idxA(i,j) (i*2+j-2)
#define idxL(i,j) (i+j-2)
#define idxU(i,j) (i-1)
#define idxb(i) (i-1)
#define idxz(i) (i-1)

void TDMASolver(int dim,REAL* A,REAL*b,REAL* root);

void main()
{
	REAL A[12]={0,1,2,
			  2,3,4,
			  4,5,6,
			  6,7,8};

	REAL b[4]={3,9,15,13};

	REAL root[4];

	TDMASolver(4,A,b,root);

	printf("Hello World!\n");

	
}

void TDMASolver(int dim,REAL* A,REAL* b,REAL* root)
{
	int i=0;

	REAL* L=new REAL[dim<<1-1];
	REAL* U=new REAL[dim-1];
	REAL* z=new REAL[dim];

	// Step 1
	L[idxL(1,1)]=A[idxA(1,1)];
	U[idxU(1,2)]=A[idxA(1,2)]/L[idxL(1,1)];
	z[idxz(1)]=b[idxb(1)]/L[idxL(1,1)];
	
	//Step 2
	for (i=2;i<dim;i++)
	{
		L[idxL(i,i-1)]=A[idxA(i,i-1)];
		L[idxL(i,i)]=A[idxA(i,i)]-L[idxL(i,i-1)]*U[idxU(i-1,i)];
		U[idxU(i,i+1)]=A[idxA(i,i+1)]/L[idxL(i,i)];
		z[idxz(i)]=(b[idxb(i)]-L[idxL(i,i-1)]*z[idxz(i-1)])/L[idxL(i,i)];
	}
	
	//Step 3, Now i=n
	L[idxL(i,i-1)]=A[idxA(i,i-1)];
	L[idxL(i,i)]=A[idxA(i,i)]-L[idxL(i,i-1)]*U[idxU(i-1,i)];
	z[idxz(i)]=(b[idxb(i)]-L[idxL(i,i-1)]*z[idxb(i-1)])/L[idxL(i,i)];

	//Step 4
	root[dim-1]=z[dim-1];
	
	//Step 5
	for (i=dim-1;i>0;i--)
	{
		root[i-1]=z[idxz(i)]-U[idxU(i,i+1)]*root[i];
	}

	delete[] L;
	delete[] U;
	delete[] z;
}

 

Q5:用AS3寫性能低下?

A:必須的,Adobe太懶惰了,停滯不前,曾經答應使AS3性能達到C的80%,後來取消了,昨天Unity還取消支持Flash了,筆者也很鬱悶。不過如果非要使用Flash以便於網絡展示,可以使用其FlasCC編譯技術;如果希望使用其低學習成本的3D技術且主要爲桌面部署,還是在應用程序中嵌入Flash控件吧。最後還是希望大家使用原生語言開發本地(Native)程序,而不是腳本語言。

參考文獻:

1,陶文銓:數值傳熱學(第2版)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章