有限元剛度矩陣的一維變頻寬儲存用C++實現(三)
阿新 • • 發佈:2018-12-11
在有限元剛度矩陣的一維變頻寬儲存用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行 } }