首页/文章/ 详情

基于有限元计算程序的探究(上)—网格划分、刚度矩阵求解、载荷施加

12月前浏览4865

前言  

在我们从学校踏入职场,从事有限元计算的初期,绝大多数人都是一拿到模型就导入商业软件中,一顿操作,洋洋洒洒从几何处理、网格划分、加载计算,最后看到五颜六色的云图,颔首微笑,自信满满,以为完全掌握了有限元计算这项技能,打算在该领域大显身手、扬名立万。随着从业时间的增长,开始的几年里进步神速,真正实现了“从入门到精通”,但是在以后几年中,还是在“原地踏步”,成长性不够。这可能就是太依赖于商业软件导致的,商业软件是一把双刃剑,给予我们方便的同时,也扼杀了我们探求其内在算法的欲望,没有理论上升的空间。在疲于应付项目的过程中,不经意间可能已经忘记了有限元计算的理论基础:什么是形函数?如何用节点位移来表示单元内任意一点的位移?单元刚度矩阵如何“组装”成整体刚度矩阵?等等。因此在闲暇时刻,有必要翻一翻理论教材,细细品味一下其中的奥秘,对我们真正理解“有限元”是有帮助的。这里推荐周博老师的《有限元法与MATLAB》著作,它是一本非常好的书,在讲解基础知识的同时,也用Matlab程序实现了各知识点的贯穿,帮助我们更好的理解一些“生涩”的词汇。

本人的这篇文章精选了该书的几个程序来帮助大家理解有限元计算的步骤和逻辑,并且根据自己的理解,对程序进行了注释说明,方便大家读懂程序。需要特别说明的是,让大家读懂程序,并不是说以后都要自编程来解决工程问题,对于复杂模型,这是不现实的,也是没有必要的。本篇文章的目的只是想通过简单的例子来领悟有限元的思想及其内在逻辑,更深刻的理解软件后面隐藏的技术体系,这对于更好地使用软件也是有帮助的。  
由于篇幅有限,按照有限元计算流程的顺序,分上下两篇文章介绍。第一篇(上篇)是介绍关于网格划分、单元刚度矩阵的求解、整体刚度矩阵的组装、载荷的施加;第二篇(下篇)是介绍方程的求解、单元应变与应力的计算、后处理(包括变形图与云图)  

1. 网格划分    

有限元计算的第一步,就是划分网格,其函数为:  

[Nxy, Enod]=mesh2d3n(x12,y12,m,n)  

参数意义:  
x12x方向最小值、最大值  
y12y方向最小值、最大值  
mx方向节点数量  
ny方向节点数量  
NxyN(节点总数)3列矩阵, 1-3列分别为节点编号、节点横、纵坐标;  
EnodM(单元总数)4列矩阵,1-4列分别为单元编号、单元所含的3个节点‍‍

源程序:    

function[Nxy,Enod] = mesh2d3n(x12,y12, m, n)  

x =linspace(x12(1),x12(2),m);

y =linspace(y12(1),y12(2),n);

[X,Y] =meshgrid(x,y);

Enod =delaunay(X,Y); %%%生成3结点单元结点信息矩阵

h1 =triplot(Enod,X,Y); %%%绘制三角形单元的离散网格

set(h1,'color','k')

axisequal

[en,ny]= size(Enod); %%%en为单元数,ny为每个单元节点数3

for i =1:en

     x_sum = 0;

     y_sum = 0;

     xy_sum = 0;

           for j = 1:ny

               ID = Enod(i,j);

               x_sum = x_sum + X(ID);

               y_sum = y_sum + Y(ID);

           end

       xc = x_sum/ny;    %%%计算三角形单元形心横坐标

       yc = y_sum/ny;    %%%计算三角形单元形心纵坐标

       h2 = text(xc,yc,num2str(i)); %%%在三角形形心处标注单元编号

       set(h2,'color','b')

       set(h2,'fontsize',10)

end

for k =1:m*n

     Nxy(k,1:3) = [k, X(k), Y(k)];

     h3 = text(X(k), Y(k),num2str(k)); %%%在节点坐标处标注节点编号

    set(h3,'color','r')

    set(h3,'fontsize',10)

end

Enod =[(1:en)', Enod]; %%%把单元编号放在第1列,2-4列为节点编号

end

函数应用实例

clear;clc

x12=[0,3];

y12=[0,3];

[Nxy,Enod] = mesh2d3n(x12,y12, m, n);

Axis([-0.5,3.5,-0.5,3.5]);

运行之后,把区域进行了三角形网格划分,如图1所示。

1 网格划分结果

2. 单元刚度矩阵    
求单元刚度矩阵之前,需要先求其应变矩阵,其函数为:  
B=EstrainM2d3n(xy)  
参数意义:  
xy32列矩阵,1-2列分别是单元节点的横、纵坐标;  
B 36列的单元应变矩阵;  
源程序:
functionB = EstrainM2d3n(xy)
x1 =xy(1,1);
x2 =xy(2,1);
x3 =xy(3,1);
y1 =xy(1,2);
y2 =xy(2,2);
y3 =xy(3,2);
b1 = y2- y3;
b2 = y3- y1;
b3 = y1- y2;
c1 =-(x2 - x3);
c2 = -(x3- x1);
c3 =-(x1 - x2);
A = [1,x1, y1; 1, x2, y2; 1, x3, y3];

A =0.5*det(A); %%%三角形单元面积

B1 =0.5/A*[b1, 0; 0, c1; c1, b1]; %%% 单元应变子矩阵
B2 =0.5/A*[b2, 0; 0, c2; c2, b2];
B3 =0.5/A*[b3, 0; 0, c3; c3, b3];
B = [B1, B2, B3];    %%%单元应变矩阵
end  

求得单元应变矩阵后,再求单元刚度矩阵,其函数为: 

KE=EstiffM2d3n(xy,mat)  

参数意义:  

xy32列矩阵, 1-2列分别是单元节点的横、纵坐标;  

mat13列矩阵,1-3列分别是材料弹性模量、泊松比、单元厚度;  

KE66列单元刚度矩阵  

源程序:  

function KE = EstiffM2d3n(xy, mat)  

E = mat(1);%%%弹性模量
mu = mat(2);%%%泊松比
t = mat(3);%%%单元厚度
D = [1, mu, 0; mu, 1, 0; 0, 0, (1-mu)/2];
D = E/(1 - mu*mu)*D; %%%弹性矩阵
x1 = xy(1,1);
x2 = xy(2,1);
x3 = xy(3,1);
y1 = xy(1,2);
y2 = xy(2,2);
y3 = xy(3,2);
A = [1, x1, y1; 1, x2, y2; 1, x3, y3];
A = 0.5*det(A);
B = EstrainM2d3n(xy); %%% 调用单元应变矩阵函数
KE = A*t*B'*D*B; %%% 根据定义求单元刚度矩阵
end  

函数应用实例

clear;clc;
E= 100e9; % 单位Pa
mu= 0.25;
t= 1e-2; % 单位m
mat=[E,mu, t];
xy1=[0,0;1.5, 0; 0, 1.5]; %%% 一个单元所含3个节点的坐标
KE1= EstiffM2d3n(xy1, mat);%%%这个单元刚度矩阵
xy2=[0,1.5; 1.5, 0; 1.5, 1.5]; %%% 另外一个单元所含3个节点的坐标
KE2 = EstiffM2d3n(xy2, mat);%%%另外这个单元的刚度矩阵

运行程序后,可以得到这两个单元的刚度矩阵,见图2。

图2 计算得到的单元刚度矩阵

3.  整体刚度矩阵  

得到了单元刚度矩阵之后,需要把将单元刚度矩阵组装成“整体刚度矩阵”,其函数为:  

KS=SstiffM2d3n(Nxy,Enod,Emat)  

参数意义:  

Nxy N(节点总数)3列矩阵, 1-3列分别为节点编号、节点横、纵坐标;  

EnodM(单元总数)4列矩阵,1-4列分别为单元编号、单元所含3个节点编号。

EmatM(单元总数)4列矩阵,1-4列分别为单元编号、弹性模量、泊松比、单元厚度

KS2N2N列整体刚度矩阵  

源程序:  

functionKS = SstiffM2d3n(Nxy, Enod, Emat)  

M =size(Enod, 1);%%%单元总数量

N =size(Nxy, 1);%%%节点总数量

KS =zeros(2*N, 2*N); %%% 整体刚度矩阵初始化

for j =1:M

     ii = Enod(j, 2);  %%% 依次提取各单元的节点编号

     jj = Enod(j, 3);

    mm = Enod(j, 4);

    sn = [ii, jj, mm];  %%% 节点编号矩阵

    xy = Nxy(sn,2:3);  %%% 提取节点坐标

    mat = Emat(j, 2:4);  %%% 提取材料属性

    KE = EstiffM2d3n(xy, mat);   %%% 调用EstiffM2d3n生成单元刚度矩阵

    sn = [2*ii-1, 2*ii, 2*jj-1, 2*jj, 2*mm-1,2*mm];   %%% 对号入座数组

    KS(sn, sn) = KS(sn, sn) + KE;   %%%将单元刚度矩阵累加到整体刚度矩阵

end

end  

函数应用实例

clear;clc;

x12= [0,2];

y12= [0,1.5];

[Nxy,Enod]= mesh2d3n(x12,y12, 3, 3); %%%结构的三角形网络离散

axis([-0.2,2.2,-0.2,1.7])

[M,N] = size(Enod);  %%%M为单元个数

Emat(1,1:4)= [1, 180e9, 0.35,  5e-2];  %%%材料属性

fori = 2:M

     Emat(i, 1:4) = Emat(1,1:4); %%%对每一个单元赋材料属性

end  

KS =SstiffM2d3n(Nxy, Enod, Emat) %%%生成整体刚度矩阵

运行后,整体刚度矩阵如图3。

图3 整体刚度矩阵

4. 载荷的施加  

需要根据载荷施加情况,需要计算等效节点载荷,其函数为:  

SP=SloadA2d3n(EP,N)  

参数意义:  

EP4列矩阵,1-4列分别为单元编号、节点编号、载荷方向、载荷大小;  

N:节点总数  

SP2N1列节点载荷矩阵  

源程序:    

functionSP = SloadA2d3n(EP,N)

[n,m]=size(EP);%%% 提取载荷数量n

SP(1:2*N,1)= 0;%%% 载荷矩阵初始化

fori=1:n

      sn = 2*EP(i,2)+EP(i,3)-2;  %%%施加载荷的位置与方向

      SP(sn) = SP(sn) + EP(i,4);  %%%施加载荷的大小

End  

函数应用实例  

clear;clc;  

N= 9;

EP= [7, 8, 1, 3.5e3;

7, 6, 2, -(2+2/3)*1e3;

7, 9, 2, -(2+4/3)*1e3;

5, 3, 2, -2/3*1e3;

5, 6, 2, -4/3*1e3];%%%受载荷信息:1-4列分别为单元编号、节点编号、载荷方向、 载荷大小;

SP= SloadA2d3n(EP,N);%%%载荷列阵  

运行后,得到载荷列阵,结果如图4。  

图4 载荷列阵

以上介绍了有限元计算的前个4步骤,在下一篇文章中再介绍后面3个步骤(方程的求解、单元应变与应力的计后处理)。

来源:CAE与Dynamics学习之友
几何处理MATLABUM理论材料
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2023-12-01
最近编辑:12月前
CAE与Dynamics学习之友
博士 乾坤未定,你我皆是黑马
获赞 26粉丝 69文章 32课程 0
点赞
收藏
未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习 福利任务 兑换礼品
下载APP
联系我们
帮助与反馈