1. 程式人生 > >有限元剛度矩陣的一維變頻寬儲存用C++實現(二)

有限元剛度矩陣的一維變頻寬儲存用C++實現(二)

我們接著上一篇有限元剛度矩陣的一維變頻寬儲存用C++實現(一)介紹。上一篇中,我們得到了輔助陣列pDiag中儲存的是總體剛度矩陣[K]每行的半頻寬。經過上一篇中節點自由度重編號,總剛矩陣[K]形式為:

此時,所有的非零元素都集中在帶內。

一維變頻寬儲存的思路為:

將總剛度矩陣[K]的下三角部分的每一行,從第一個帶內元素開始按行將元素排成一序列,存放於一維陣列pGK[L]中,其中L是一維陣列元素的個數,也就是總剛矩陣下三角部分的帶內元素總數。

但是為了確定pGK中的元素在[K]中的行列號,還需將[K]中各行對角線上的元素在一維陣列pGK中的下標(稱作對角元地址),存放在另一輔助陣列pDiag[n]中,其中n是總剛矩陣[K]的階數。現舉例說明這一儲存法,設有一系數矩陣:

它的下三角矩陣各行半帶內的元素總共有13個,它們在一維陣列pGK[13]中的存放次序是:

{4.5,0.2,5.3,-1.3,0,10.2,5.1,8.4,0.6,-1.7,0,0,3.1}

而輔助陣列pDiag[6]存放的對角元地址是:

{0,2,5,7,8,12}

經過上一篇中的計算,一維輔助陣列pDiag[i]中儲存的是總體剛度矩陣[K]第i行的最大半頻寬,但是在一維變頻寬儲存中,需要pDiag[i]中儲存的為總體剛度矩陣[K]第i行對角元素在pGK陣列中的下標,以配合pGK陣列儲存總剛矩陣。故對pDiag[]陣列做如下變換:

pDiag[0]=0; //將pDiag中儲存的節點自由度編號為0(即,剛度矩陣第0行)的主對角元在一維變頻寬陣列pGK中的地址設為0
	for(i=1;i<nTotalDOF;i++) //從pDiag陣列中的第二個節點自由度編號開始迴圈
//pDiag[i]儲存的是剛度矩陣中當前行的半頻寬,pDiag[i-1]儲存的是剛度矩陣中上一行的半頻寬
		pDiag[i]=pDiag[i]+pDiag[i-1]; //得到一維壓縮儲存演算法中,剛度矩陣中每行上主對角元在”存放剛度矩陣所有非0元素的一維陣列“中的地址

經過前面的鋪墊後,根據有限元原理,計算各單元的單元剛度矩陣,並將其轉換到全域性座標下,之後再根據單元剛度矩陣[pKe]的元素總體剛度矩陣[K]的元素對應關係,將單元剛度矩陣[pKe]疊加到儲存總體剛度矩陣[K]的一維陣列pGK[L]上。

由於具體程式碼還涉及到非齊次邊界條件化簡、LDLT解方程等操作,比較複雜,此處僅給出計算一維陣列pGK[L]的演算法流程圖如下: