有限元非齐次边界条件的刚度方程的化简,用C++实现

刚度方程:[F]=[K][D],其中,[F]为力向量,[K]为刚度矩阵,[D]为位移向量。本文讨论的内容为[D]向量中有些元素已知的情况。

1.1 适用情况

部分位移已知,则位移已知的那些方程就是非齐次边界条件的方程。

1.2 原理

在有限元中有一个原理:如果某个节点在给定方向的位移已知,则在相同节点相同方向的力F并不是已知的。该力可以在求解未知节点位移后确定。

 也就是说,在总刚方程[k][d]=[f]方程组的每一个方程中,要么位移d已知f未知,要么f已知位移d未知。

现在考虑非齐次边界条件的情况。对于这种情况,一个或多个指定的位移不为0。为化简起见,在总刚方程中令位移u1=σ, σ是一个已知的位移(即,受约束的自由度)。由此得出:

将上述方程展开,变为方程组形式:

其中,F1x是支撑移动量σ产生的未知反力。因为上述方程中第2个方程和第3个方程右端项为已知节点力F2x和F3x,所以考虑该方程组的第2和第3个方程,将已知σ项移动至方程的右端得出:

重新将上述方程写成矩阵形式,得:

至此,非齐次边界条件消除,总刚方程化简,由于已知节点力F2x和F3x,故可求出u2和u3,进而得出所有位移值。

1.3 C++实现算法

1.3.1 创建位移一维数组pDisp[nTotalDOF],其中nTotalDOF为自由度总个数,一个自由度编号对应一个位移数组pDisp[]的下标。对于已知位移的那些自由度i,pDisp[i]中存储的是位移值;对于未知位移(已知对应的外力)的那些自由度j,pDisp[j]中存储的是外力荷载值

1.3.2 创建载荷一维数组pLoadVect[nTotalDOF]用于存储[k][d]=[f]中的向量[f]

1.3.3 由于自由度编号已经完成(详见上一篇文章:一维变带宽存储的半带宽计算C++算法),首先遍历那些受约束自由度i(已知位移),其编号范围从nFreeDOF至nTotalDOF,从pDisp[i]中取出当前已知位移σ,再从总刚矩阵中分别取出第i列的第j行上的元素kji(取出方法为dBuf=GetElementInGK(nTotalDOF,j,i,pDiag,pGK)请看下篇文章讲述),做运算使得向量[f]中的第j行上元素变为fj-kjiσ,存入pLoadVect[j]中。至此,pLoadVect[j]中存放了方程(a)中右边项的(-k1)σ

1.3.4 程序流程图如下:

 

1.3.5 程序代码如下

void LoadVectorModify(int nTotalDOF,int nFreeDOF,int *pDiag,double *pGK,double *pDisp,double *pLoadVect) //加载支座位移
//利用“非齐次边界条件下刚度方程的化简”原理,计算刚度方程中位移未知的那些行的化简方程形式:[k][d]=[F-kσ]
//nTotalDOF为总自由度数;nFreeDOF为所有节点未知自由度数总个数;
//pDisp为存储位移分量的一维数组首地址,此处的pDisp已经过LoadVectorAssembly()函数做了一些修改,里面存了一些载荷值,不是仅仅初始化的!
//pGK为总刚矩阵中的下三角部分一维变带宽存储的一维数组
//一维变带宽存储的辅助数组pDiag中存储的是总刚矩阵中对角元在一维变带宽数组pGK中的下标
//pLoadVect为一维荷载数组,长度为自由度总个数,一个荷载对应一个自由度对于位移已知的元素,存储的是位移值,对于位移未知的元素,存储的是载荷值
{
	int i,j;
	double dBuf;
	for(i=nFreeDOF;i<nTotalDOF;i++) //遍历节点已知自由度总个数
	//对于已知位移的那些自由度,其pDisp中对应的“载荷值”其实是已知的位移值!因为有限元中有一个原则:如果某个节点某个方向上的位移已知,则相同节点相同方向上的力必未知!
	//所谓受约束自由度,就是位移已知,对应于“刚度法”中是要挪到刚度方程力的那边去的项:kσ
	//在受约束自由度范围内搜索,因为从编号nFreeDOF之后的节点自由度编号都是编给受约束自由度的!
	{
		if(pDisp[i]!=0.0) //当前受约束自由度上受到荷载分量作用,其实是位移不为0的意思!
		{
			for(j=0;j<nFreeDOF;j++) //遍历未知自由度总个数,对于“非齐次边界条件的刚度方程化简”,每个已知位移的影响kσ都要加到所有未知位移的行上去
			//对于位移未知的每一行,都要把已知位移σ的影响挪到刚度方程中力的那边[k][d]=[F-kσ]
			{
				dBuf=GetElementInGK(nTotalDOF,j,i,pDiag,pGK); //取出总刚矩阵中第j行第i列上的元素值放入dBuf中
				//将总自由度数、未知自由度编号j、已知自由度编号i、辅助数组pDiag、一维变带宽数组pGk传入函数
				if(dBuf!=0) //总刚矩阵中当前元素dBuf为非0元素,可能在带内,可能在带外
					//将刚度方程中位移已知项挪到力的那一边:[k][d]=[F-kσ]
					pLoadVect[j]-=dBuf*pDisp[i]; //修改载荷向量
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/ybdjq/article/details/82252093
今日推荐