等几何分析+有限元等参四边形单元的等效节点力


前言

写等几何程序的时候用到等效节点力,只推导了2次B样条单元(一个单元九个节点)的等效节点力公式。

一、有限元等参四边形单元的等效节点力

1.1 有限元等参四边形单元理论

可参考博客:等参单元与数值积分 或者图书《有限元法与MATLAB程序设计》

1.2 等参四边形单元的等效节点力

内容来自于:图书《有限元法与MATLAB程序设计》

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、等几何分析的等效节点力

2.1 等几何分析的理论

等几何分析的相关理论可以查看博客:等几何分析编程记录

2.2 等效节点力

理论推导:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

写程序时的分析:

在这里插入图片描述

对应的C++函数:

// 求等效节点载荷公式  在参数域  的函数 N' *  P * |jacobi|
	MatrixXd return_F_function(MatrixXd WF, MatrixXd elCpts, double u, int num_of_ele)
	{
		// ------------------------------------------------------------------------------------------------------
		// 计算边界的等效节点载荷公式中积分里面的函数 N' *  P * |jacobi|
		// 输入
		//      u:变换到标准高斯区间的高斯点
		//     WF:外力载荷
		//         2维:  WF = [Px, Py] 
		//         3维:  WF = [Px, Py, Pz] 
		//     elCpts : 控制点坐标 ------- 将边界点坐标传入 从下到上(对应基函数)
		//              coordinates of element control points 单元控制点坐标
		// 输出: 
		//   F --- 等效节点载荷
		//         不细化  F:6行1列的向量
		// -------------------------------------------------------------------------------------------------------
		//  边界对应的形函数(基函数)
		MatrixXd N(2, 6);
		N.setZero();
		int len_V = size(V);
		int num1 = num_of_ele;
		for (int i = 0; i < 3; i++)
		{
			N(0, 2 * i) = OneBasisFun_withreturn(2, len_V - 1, V, num1, u);
			N(1, 2 * i + 1) = OneBasisFun_withreturn(2, len_V - 1, V, num1, u);
			num1++;
		}

		//  边界对应的形函数导数(基函数)
		MatrixXd der_B(1, 3);
		//Print_Vector(der_B);
		int num2 = num_of_ele;
		for (int i = 0; i < 3; i++)
		{
			der_B(0, i) = DersOneBasisFun_double_First_Ders(2, V, num2, u);
			num2++;
		}
		double j2 = 0; // jacobi_2:物理域到参数域的jacobi值
		j2 = (der_B * elCpts).norm(); // der_B * elCpts:导函数 * 对应的控制点坐标

		//MatrixXd F = t * j2 * N.transpose() * WF;
		MatrixXd F = j2 * N.transpose() * WF;
		return F;
	}

	// 求单元的等效节点载荷
	MatrixXd ele_F(vector<double> elDoma, MatrixXd WF, MatrixXd elCpts, vector<int> Gauss_num, int num_of_ele)
	{
		// ------------------------------------------------------------------------------------------------------
		// 计算边界单元的等效节点载荷
		// 目前适用于只有右边界施加力的等效节点载荷
		// 输入
		//     elDoma : 传入的单元参数域     
		//         1维:   elDoma = [u1, u2]     
		//         2维:   elDoma = [u1, u2, v1, v2] 
		//         3维:   elDoma = [u1, u2, v1, v2, w1, w2] 
		//     WF:应力
		//         2维:  WF = [Px, Py] 
		//         3维:  WF = [Px, Py, Pz] 
		//     elCpts : 控制点坐标 ------- 将边界点坐标传入 从下到上(对应基函数)
		//   Gauss_num: 高斯积分用到的高斯点数
		//              因为是一维高斯积分,故Gauss_num={2} ----  表示用两点高斯积分求解     
		//              或者Gauss_num={3} ----  表示用3点高斯积分求解 
		// 输出: 
		//   f --- 单元等效节点载荷 
		// -------------------------------------------------------------------------------------------------------
		Gauss gau; //定义一个高斯类,用于调用"gauss.h"中函数
		MatrixXd f(6, 1);
		f.setZero();

		gau.gauss_quadrature(Gauss_num);  //必须先调用这个函数,才能得到 gp 和 wgt 的值
		MatrixXd gp = gau.standard_GaussPoint; //标准高斯区间的高斯点
		int num_gp = gp.cols();//高斯积分用到的高斯点数
		MatrixXd wgt = gau.standard_GaussWeight;//标准高斯区间的权值
		//cout << " gp = \n" << gp << endl;  cout << " wgt = \n" << wgt << endl;
		double u = 0;
		double j1 = gau.jacobian_gauss_mapping(elDoma); //高斯积分映射---参数域区间到标准高斯区间的jacobi

		for (int i = 0; i < num_gp; i++)
		{
			double a = elDoma[0];  //积分下限
			double b = elDoma[1];  //积分上限
			u = (b - a) / 2 * gp(0, i) + (a + b) / 2;
			f += j1 * wgt(i) * return_F_function(WF, elCpts, u, num_of_ele);
		}
		//cout << " f = \n" << f << endl;
		return f;
	}

	//计算整体等效节点载荷
	MatrixXd return_F(VectorXd val_WF)
	{
		// ------------------------------------------------------------------------------------------------------
		// 计算整体等效节点载荷
		// 目前适用于只有右边界施加力的等效节点载荷
		// 输入;
		//       rightNodes: 右边界节点的全局编号
		//     num_of_ele_V: V方向单元个数                                       
		//        Gauss_num: 高斯积分用到的高斯点数   Gauss_num={2} ----  表示用两点高斯积分求解
		//           val_WF: 外力的大小    2维:  WF = [Px, Py]                            
		//          elCpts : 边界控制点坐标 ------- 将边界点坐标传入 从下到上(对应基函数)                                
		// 输出: 
		//             F --- 等效节点载荷        
		//                             
		//   注:  2次基函数, V方向一个单元控制点 只有三个                                          
		// -------------------------------------------------------------------------------------------------------

		MatrixXd F(num_GK, 1);
		F.setZero();
		vector<int> Gauss_num = { 4 }; //高斯积分用到的高斯点数
		//计算施加外力所对应节点的坐标
		num_BasisFun_V;  // V方向基函数个数
		MatrixXd Cpts(num_BasisFun_V, 2);   // elCpts:coordinates of control points 边界控制点坐标
		Cpts.setZero();
		//外力施加在右边界
		for (int i = 0; i < num_BasisFun_V; i++)
		{
			Cpts.row(i) = Node.row(rightNodes[i]);//右边界节点的全局编号对应的坐标取出来
		}
		//elCpts.block<rows, cols>(i, j)表示 从矩阵elCpts的  elCpts(i, j) 位置开始取rows行  cols列
		//计算单元等效节点力
		double Area = t * L; //截面积
		val_WF /= Area;//应力
		/*cout << " val_WF = \n" << val_WF << endl;
		cout << "\n 力边界节点: rightNodes = \n"; Print_Vector(rightNodes);*/

		//组装等效节点力
		for (int num = 0; num < num_of_ele_V; num++)
		{
			// elCpts:coordinates of element control points 单元控制点坐标
			MatrixXd elCpts = Cpts.block<3, 2>(num, 0); //取出右边界(V方向)的 第num个单元的坐标
			// 计算单元节点坐标  对应的参数域
			// elDoma:参数域的积分区间
			vector<double> elDoma = { val_V[num],val_V[num + 1] };
			MatrixXd f1 = ele_F(elDoma, val_WF, elCpts, Gauss_num, num);//求出第num个单元的等效节点力
			//cout << " f1 = \n" << f1 << endl;
			vector<int> num_ele = { rightNodes[num], rightNodes[num + 1],rightNodes[num + 2] };//第num个单元对应节点的全局编号
			//cout << "\n 力边界节点: num_ele = \n";Print_Vector(num_ele);

			//组装等效节点力载荷  将单元等效节点力放到相应位置
			//注意:节点从0开始编号
			//若节点num_ele[0] = 5  对应在等效节点力向量中 2*5 = 10 和 11 行的位置
			F(2 * num_ele[0]) += f1(0);
			F(2 * num_ele[0] + 1) += f1(1);
			F(2 * num_ele[1]) += f1(2);
			F(2 * num_ele[1] + 1) += f1(3);
			F(2 * num_ele[2]) += f1(4);
			F(2 * num_ele[2] + 1) += f1(5);
		}
		//cout << " F = \n" << F << endl;
		return F;
	}
  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的 MATLAB 代码示例,用于计算四节点单元的刚度矩阵。请注意,这个代码只是一个示例,可能需要根据你的具体应用进行调整和修改。 ``` % 定义单元的自由度和节点坐标 ndof = 2; % 自由度数目 nnode = 4; % 节点数目 coord = [0,0; 1,0; 1,1; 0,1]; % 节点坐标 % 定义材料和几何数 E = 210e9; % 弹性模量 nu = 0.3; % 泊松比 t = 0.01; % 单元厚度 % 计算单元的刚度矩阵 Ke = zeros(ndof*nnode,ndof*nnode); for i = 1:ndof*nnode for j = 1:ndof*nnode % 计算局部刚度矩阵 Klocal = E/(1-nu^2) * [1, nu, 0, -nu; nu, 1, -nu, 0; 0, -nu, 1, nu; -nu, 0, nu, 1]; Klocal = Klocal * t/2 * (1/det([1,1,1,1; coord(:,1)', coord(:,2)'])); % 计算全局刚度矩阵 Ke(i,j) = Klocal(mod(i-1,ndof)+1,mod(j-1,ndof)+1) * (i<=ndof*nnode/2) * (j<=ndof*nnode/2); Ke(i,j+ndof*nnode/2) = Klocal(mod(i-1,ndof)+1,mod(j-1,ndof)+1) * (i<=ndof*nnode/2) * (j>ndof*nnode/2); Ke(i+ndof*nnode/2,j) = Klocal(mod(i-1,ndof)+1,mod(j-1,ndof)+1) * (i>ndof*nnode/2) * (j<=ndof*nnode/2); Ke(i+ndof*nnode/2,j+ndof*nnode/2) = Klocal(mod(i-1,ndof)+1,mod(j-1,ndof)+1) * (i>ndof*nnode/2) * (j>ndof*nnode/2); end end % 输出刚度矩阵 disp('Ke = '); disp(Ke); ``` 在这个例子中,我们首先定义了单元的自由度数目和节点坐标。然后,我们定义了材料和几何数。最后,我们循环遍历单元的所有自由度,计算局部刚度矩阵,并将其组装成全局刚度矩阵。最后,我们输出刚度矩阵。 请注意,这里的代码只是一个简单的例子,可能需要根据你的具体应用进行调整和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值