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

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

有限元剛度矩陣的一維變頻寬儲存用C++實現(二)中,我們已經把總體剛度矩陣[K]中下三角部分的帶內元素順利存入pGK陣列中,現在我們來討論如何從pGK陣列中取出[K]內的任意元素。

從儲存了總剛矩陣[K]中的帶內元素的一維陣列pGK中取出總剛矩陣[K]的元素,主要是建立總剛矩陣[K]中第i行第j列的元素與pGK[]陣列中元素的對應關係。根據[K]為對稱矩陣的前提,就可以根據pGK[]中的總剛矩陣下三角部分,推斷總剛矩陣的上三角部分的元素。

(1)建立總剛矩陣[K]中第GKi行第GKj列與pGK陣列中元素的對應關係。

1)對於[K]中的下三角部分,GKi> GKj。此時按行取出[K]中元素。

第GKi行主對角元到當前元素的距離為:iBuf=GKi-GKj;

對於[K]中的帶內元素,已存入pGK陣列中,

此時[K]中第GKi行第GKj列的元素在pGK陣列中的下標為:(pDiag儲存的是[K]矩陣主對角元在pGK陣列中的下標)

pDiag[GKi]-iBuf=pDiag[GKi]-(GKi-GKj),原理如下圖所示:

對於[K]中的帶外元素,值是0

2)對於[K]中的上三角部分,GKi<GKj。

根據[K]的對稱性,上三角的GKi行GKj列元素,其值和下三角的GKj行GKi列的元素一致,且GKj行GKi列的元素一定位於下三角區。故從pGK陣列中取出[K]的GKj行GKi列元素即可。

(2)程式流程圖如下:

(3)C++程式如下:

double GetElementInGK(int nRow,int iRow,int iCol,int *pDiag,double *pGK) //將總剛矩陣中當前元素的行號、列號輸入,返回總剛度矩陣當前元素值,無論是在上三角或是下三角部分的元素都可以返回,
//nRow為總剛矩陣總行數;iRow為總剛矩陣中當前行的行號;iCol為總剛矩陣中當前列的列號;
//pGK為總剛矩陣中的下三角部分一維變頻寬儲存的一維陣列
//一維變頻寬儲存的輔助陣列pDiag中儲存的是總剛矩陣中對角元在一維變頻寬陣列pGK中的下標
{
	int iBuf;
	int nHalfBand; //當前行的最大半頻寬
	double dBuf;
	if(iRow>nRow||iCol>nRow) //當前行或當前列越界
	{
		cout<<"行或列越界!"<<endl;
		dBuf=0.0;
		return dBuf; //返回0.0,退出函式
	}
	if(iRow>=iCol) //元素處於矩陣下三角部分,取出元素並返回其值
	{
		if(iRow==0) //當前行為總剛矩陣第0行
			nHalfBand=1; //第0行的下三角部分只有主對角一個元素,半頻寬為1
		else
			nHalfBand=pDiag[iRow]-pDiag[iRow-1]; //第iRow行的最大半頻寬
			iBuf=iRow-iCol; //當前行主對角元到當前元素的距離
		if(nHalfBand<=iBuf) //說明當前元素在當前行的最大半頻寬之外,是0元素!
		{
			dBuf=0.0;
			return dBuf; //返回0.0,退出函式
		}
		else    //當前元素在當前行的最大半頻寬之內,是帶內元素
			return pGK[pDiag[iRow]-iBuf];  //返回總剛矩陣中當前元素值,退出函式
	}
	else  //元素處於矩陣上三角部分,取出元素並返回其值
	{
		//將其對稱到下三角部分,計算當前行的最大半頻寬
		nHalfBand=pDiag[iCol]-pDiag[iCol-1]; //由於剛度矩陣的對稱性,上三角的第i列就是下三角的第i行
		iBuf=iCol-iRow; //上三角的iRow行iCol列就是下三角的iCol行iRow列
		if(nHalfBand<=iBuf) //說明當前元素在當前行的最大半頻寬之外,是0元素!
		{
			dBuf=0.0;
			return dBuf;
		}
		else
			return pGK[pDiag[iCol]-iBuf]; //上三角的iCol列就是下三角的iCol行
	}
}