Matlab编程使用三角形单元求解平面问题(提供全部代码)

这篇文章是我的某次课程大作业,问题的求解参考了 @肖田变强不变秃 的文章https://blog.csdn.net/hjuihui/article/details/118483382,在此感谢。
  1. 问题描述

如下图所示,一矩形薄板右端部受集中力 F=1000kN 作用,材料弹性模量 E= 210GPa、 泊松比v= 0.2,悬臂梁的厚度(板厚)为 10mm。请编写程序计算弹性板 右上角和右下角的位移和应力。

2. 计算结果(云图显示)

3. Matlab所有程序

%% 有限元求解平面问题。使用三角形单元,网格密度由单元边长 h 控制。
% 程序计算思路:划分网格、求单元刚度矩阵、集成总体刚度矩阵、求解位移、会代求解应力。
clear;
clc;

%% 根据题目要求与计算需要输入参数,主函数计算求解
a=2;
b=1;
t=10e-3;
E=210e9;
mu=0.2;
F=1e6; %参数输入使用“米-帕”单位制
h=0.1; %单元边长(米),可以控制网格密度
[Node_info,Ele_info]=Meshing(a,b,h); %划分网格
[K,D,BB]=Assembly(Node_info,Ele_info,E,mu,t); %求解单刚并进行总刚与“总应变矩阵”的组装
R=Load(Node_info,F); %节点等效载荷
[KK,RR]=BC(Node_info,K,R); %引入边界条件消除总刚奇异性 
u=lsqminnorm(KK,RR); %求解节点位移
[sigma_x,sigma_y,sigma_xy]=Stress(BB,Ele_info,D,u); %求单元应力
figure(1);Plot_u(u,Node_info); %绘制位移分布云图
figure(2);sigma_x_node=Plot_sx_node(sigma_x,Node_info,Ele_info); %绘制 sigma_x 应力云图,并输出节点平均应力值
figure(3);sigma_y_node=Plot_sy_node(sigma_y,Node_info,Ele_info); %绘制 sigma_y 应力云图,并输出节点平均应力值
figure(4);sigma_xy_node=Plot_sxy_node(sigma_xy,Node_info,Ele_info); %绘制 sigma_xy 应力云图,并输出节点平均应力值
figure(5);Mise_stress(Node_info,sigma_x_node,sigma_y_node,sigma_xy_node); %绘制 Mises 应力云图

%% 网格划分函数(要求输入物体边长和单元边长,将输出包含节点编号、节点坐标的节点信息与包含单元编号、单元包含节点编号
的单元信息)
function [Node_info,Ele_info]=Meshing(a,b,h)
axis equal
hold on
%节点信息
Num_nodes=0;
Node_info=[];
for i=0:h:a
 for j=0:h:b
 Num_nodes=Num_nodes+1;
 Node_info=[Node_info;Num_nodes,i,j];
 end
end
%单元信息
Num_eles=0;
Ele_info=[];
%该问题按直角三角形单元划分,单元坐标有两种形式,以下为左下角为直角的单元形式。
for i=h:h:a
 for j=h:h:b
 Num_eles=Num_eles+1;
 node_local=[i-h,j-h;
 i,j-h;
 i-h,j];
 node_list=[];
%已经有了单元的三个节点坐标,需要找到对应的节点编号
 for k=1:3
 row_x=find(abs(Node_info(:,2)-node_local(k,1))<1e-6);
 row_y=find(abs(Node_info(:,3)-node_local(k,2))<1e-6);
 num_node=intersect(row_x,row_y);
 %这样就找到了与 Node_info 中与节点横纵坐标均相等的节点编号了
 node_list=[node_list;num_node];
 %3x1 的矩阵,单元三个节点编号均找到
 end 
 Ele_info=[Ele_info;Num_eles,node_list'];
%以下为右上角为直角的单元信息
 Num_eles=Num_eles+1;
 node_local=[i,j;i-h,j;i,j-h];
 node_list=[];
 for k=1:3
 row_x=find(abs(Node_info(:,2)-node_local(k,1))<1e-6);
 row_y=find(abs(Node_info(:,3)-node_local(k,2))<1e-6);
 num_node=intersect(row_x,row_y);
 node_list=[node_list;num_node];
 end
 Ele_info=[Ele_info;Num_eles,node_list'];
 end
end
end

%% 整体刚度矩阵集成函数 (输入节点、单元信息,输出总纲、修改后的应变矩阵)
function [K,D,BB]=Assembly(Node_info,Ele_info,E,mu,t)
Num_nodes=size(Node_info,1);
Num_eles=size(Ele_info,1);
K=zeros(2*Num_nodes);
BB=[];
for i=1:Num_eles
 node_info_local=[Ele_info(i,2),Node_info(Ele_info(i,2),2),Node_info(Ele_info(i,2),3);
 Ele_info(i,3),Node_info(Ele_info(i,3),2),Node_info(Ele_info(i,3),3);
 Ele_info(i,4),Node_info(Ele_info(i,4),2),Node_info(Ele_info(i,4),3)];
 %3x3 的矩阵,第一列为节点编号,二、三列为节点横、纵坐标
 [ke,D,B]=Ke(node_info_local,E,mu,t);
 BB=[BB;B]; 
 j=node_info_local(1,1);
 k=node_info_local(2,1);
 m=node_info_local(3,1);
 num=[2*j-1,2*j,2*k-1,2*k,2*m-1,2*m];
 for n1=1:6
 for n2=1:6
 K(num(n1),num(n2))=K(num(n1),num(n2))+ke(n1,n2);
 end
 end
end
end 

%% 单元刚度矩阵计算函数 (输入节点、单元信息,输出单刚、弹性矩阵、应变矩阵)
function [ke,D,B]=Ke(node_info,E,mu,t)
C=[1,node_info(1,2),node_info(1,3);
 1,node_info(2,2),node_info(2,3);
 1,node_info(3,2),node_info(3,3)];
A=0.5*det(C);
B=0.5/A*[node_info(2,3)-node_info(3,3),0,node_info(3,3)-node_info(1,3),0,node_info(1,3)-node_info(2,3),0;
 0,node_info(3,2)-node_info(2,2),0,node_info(1,2)-node_info(3,2),0,node_info(2,2)-node_info(1,2);
 node_info(3,2)-node_info(2,2),node_info(2,3)-node_info(3,3),node_info(1,2)-node_info(3,2),...
 node_info(3,3)-node_info(1,3),node_info(2,2)-node_info(1,2),node_info(1,3)-node_info(2,3)];
D=E/(1-mu^2)*[1,mu,0;
 mu,1,0;
 0,0,(1-mu)/2];
ke=B'*D*B*A*t;
end

%% 节点载荷列阵
function R=Load(Node_info,F)
R=zeros(size(Node_info,1)*2,1);
row1_x=find(Node_info(:,2)==2);
row1_y=find(Node_info(:,3)==0);
num1=intersect(row1_x,row1_y);
row2_x=find(Node_info(:,2)==2);
row2_y=find(Node_info(:,3)==1);
num2=intersect(row2_x,row2_y);
R(2*num1)=-F/2;
R(2*num2)=-F/2;
end

%% 引入边界条件,修改总刚和载荷列阵 (划一置零法)
function [KK,RR]=BC(Node_info,K,R)
num=find(Node_info(:,2)<1e-9);
KK=K;
RR=R;
for i=1:size(num,1)
 r=num(i);
 KK(2*r-1,:)=0;
 KK(:,2*r-1)=0;
 KK(2*r-1,2*r-1)=1;
 KK(2*r,:)=0;
 KK(:,2*r)=0;
 KK(2*r,2*r)=1;
 RR(2*r-1)=0;
 RR(2*r)=0;
end
end

%% 单元应力计算函数 (输入应变总矩阵、单元总信息、计算得到的位移解,输出每个单元的应力)
function [sigma_x,sigma_y,sigma_xy]=Stress(BB,Ele_info,D,u)
Num_eles=size(Ele_info,1);
sigma=[];
sigma_x=[];
sigma_y=[];
sigma_xy=[];
for i=1:Num_eles
 node_local=Ele_info(i,2:4);
 u_local=[u(2*node_local(1)-1);
 u(2*node_local(1));
 u(2*node_local(2)-1);
 u(2*node_local(2));
 u(2*node_local(3)-1);
 u(2*node_local(3))];
 sigma=D*BB(3*i-2:3*i,:)*u_local;
 sigma_x=[sigma_x;sigma(1)];
 sigma_y=[sigma_y;sigma(2)];
 sigma_xy=[sigma_xy;sigma(3)];
end
end

%% 后处理函数 绘制节点位移云图
function []=Plot_u(u,Node_info)
u1=[];
u2=[];
for i=1:231
 u1=[u1;u(2*i-1)];
 u2=[u2;u(2*i)];
end
u11=u1;
u22=u2; %将 u1、u2 的数值进行保护,后续标注会用到
X1=linspace(min(Node_info(:,2)),max(Node_info(:,2)),100); %将坐标均分成 100 份
Y1=linspace(min(Node_info(:,3)),max(Node_info(:,3)),100);
[X,Y,u1]=griddata(Node_info(:,2),Node_info(:,3),u1,X1',Y1,'v4'); %'v4'代表插值方法为 matlab4 样条函数内插
[X,Y,u2]=griddata(Node_info(:,2),Node_info(:,3),u2,X1',Y1,'v4');
subplot(2,1,1);
pcolor(X,Y,u1);
shading interp %色彩平滑
colorbar %分布柱图 
axis equal
title('水平方向位移分布云图')
box on;
x_row=find(abs(Node_info(:,2)-2)<1e-9); %找到右上角和右下角的节点标号,在云图中标注数值
y1_row=find(abs(Node_info(:,3)-1)<1e-9);
y2_row=find(abs(Node_info(:,3))<1e-9);
node_num1=intersect(x_row,y1_row);
node_num2=intersect(x_row,y2_row);
text_x2y1=u11(node_num1);
text_x2y2=u11(node_num2);
text_1=['[','(',num2str(Node_info(node_num1,2)),',',num2str(Node_info(node_num1,3)),')',',',num2str(text_x2y1),']'];
text_2=['[','(',num2str(Node_info(node_num2,2)),',',num2str(Node_info(node_num2,3)),')',',',num2str(text_x2y2),']'];
text(Node_info(node_num1,2),Node_info(node_num1,3),text_1,'HorizontalAlignment', 'right');
text(Node_info(node_num2,2),Node_info(node_num2,3),text_2,'HorizontalAlignment', 'right');
subplot(2,1,2);
pcolor(X,Y,u2);
shading interp %色彩平滑
colorbar %分布柱图 
axis equal
title('竖直方向位移分布云图/m')
box on;
x_row=find(abs(Node_info(:,2)-2)<1e-9); %找到右上角和右下角的节点标号,在云图中标注数值
y1_row=find(abs(Node_info(:,3)-1)<1e-9);
y2_row=find(abs(Node_info(:,3))<1e-9);
node_num1=intersect(x_row,y1_row);
node_num2=intersect(x_row,y2_row);
text_x2y1=u22(node_num1);
text_x2y2=u22(node_num2);
text_1=['[','(',num2str(Node_info(node_num1,2)),',',num2str(Node_info(node_num1,3)),')',',',num2str(text_x2y1),']'];
text_2=['[','(',num2str(Node_info(node_num2,2)),',',num2str(Node_info(node_num2,3)),')',',',num2str(text_x2y2),']'];
text(Node_info(node_num1,2),Node_info(node_num1,3),text_1,'HorizontalAlignment', 'right');
text(Node_info(node_num2,2),Node_info(node_num2,3),text_2,'HorizontalAlignment', 'right');
end

%% 后处理函数 绘制 sigma_x 云图
%每一个节点的应力值取周围单元的应力平均值
function sigma_xx_node=Plot_sx_node(sigma_x,Node_info,Ele_info)
sigma_x_node=[];
for i=1:size(Node_info,1)
 E=[];
 E1=find(abs(Ele_info(:,2)-i)<1e-9);
 E2=find(abs(Ele_info(:,3)-i)<1e-9);
 E3=find(abs(Ele_info(:,4)-i)<1e-9);
 E=[E;E1;E2;E3];
 n=size(E,1);
 sx_sum=0;
 for j=1:n
 sx_sum=sx_sum+sigma_x(E(j));
 end
 sigma_x_node=[sigma_x_node;sx_sum/n]; 
end
sigma_xx_node=sigma_x_node; %将 sigma_x_node 的数值进行保护,后续标注会用到
X1=linspace(min(Node_info(:,2)),max(Node_info(:,2)),100); %将坐标均分成 100 份
Y1=linspace(min(Node_info(:,3)),max(Node_info(:,3)),100);
[X,Y,sigma_x_node]=griddata(Node_info(:,2),Node_info(:,3),sigma_x_node,X1',Y1,'v4'); 
pcolor(X,Y,sigma_x_node); %绘制云图
x_row=find(abs(Node_info(:,2)-2)<1e-9); %找到右上角和右下角的节点标号,在云图中标注数值
y1_row=find(abs(Node_info(:,3)-1)<1e-9);
y2_row=find(abs(Node_info(:,3))<1e-9);
node_num1=intersect(x_row,y1_row);
node_num2=intersect(x_row,y2_row);
text_x2y1=sigma_xx_node(node_num1);
text_x2y2=sigma_xx_node(node_num2);
text_1=['[','(',num2str(Node_info(node_num1,2)),',',num2str(Node_info(node_num1,3)),')',',',num2str(text_x2y1),']'];
text_2=['[','(',num2str(Node_info(node_num2,2)),',',num2str(Node_info(node_num2,3)),')',',',num2str(text_x2y2),']'];
text(Node_info(node_num1,2),Node_info(node_num1,3),text_1,'HorizontalAlignment', 'right');
text(Node_info(node_num2,2),Node_info(node_num2,3),text_2,'HorizontalAlignment', 'right');
shading interp %色彩平滑
colorbar %分布柱图 
axis equal
title('\sigma_x 应力分布云图/Pa')
box on;
end

%% 后处理函数 绘制 sigma_y 应力云图
function sigma_yy_node=Plot_sy_node(sigma_y,Node_info,Ele_info)
sigma_y_node=[];
for i=1:size(Node_info,1)
 E=[];
 E1=find(abs(Ele_info(:,2)-i)<1e-9);
 E2=find(abs(Ele_info(:,3)-i)<1e-9);
 E3=find(abs(Ele_info(:,4)-i)<1e-9);
 E=[E;E1;E2;E3];
 n=size(E,1);
 sy_sum=0;
 for j=1:n
 sy_sum=sy_sum+sigma_y(E(j));
 end
 sigma_y_node=[sigma_y_node;sy_sum/n]; 
end
sigma_yy_node=sigma_y_node; %将 sigma_y_node 的数值进行保护,后续标注会用到
X1=linspace(min(Node_info(:,2)),max(Node_info(:,2)),100); %将坐标均分成 100 份
Y1=linspace(min(Node_info(:,3)),max(Node_info(:,3)),100);
[X,Y,sigma_y_node]=griddata(Node_info(:,2),Node_info(:,3),sigma_y_node,X1',Y1,'v4'); 
pcolor(X,Y,sigma_y_node);
x_row=find(abs(Node_info(:,2)-2)<1e-9); %找到右上角和右下角的节点标号,在云图中标注数值
y1_row=find(abs(Node_info(:,3)-1)<1e-9);
y2_row=find(abs(Node_info(:,3))<1e-9);
node_num1=intersect(x_row,y1_row);
node_num2=intersect(x_row,y2_row);
text_x2y1=sigma_yy_node(node_num1);
text_x2y2=sigma_yy_node(node_num2);
text_1=['[','(',num2str(Node_info(node_num1,2)),',',num2str(Node_info(node_num1,3)),')',',',num2str(text_x2y1),']'];
text_2=['[','(',num2str(Node_info(node_num2,2)),',',num2str(Node_info(node_num2,3)),')',',',num2str(text_x2y2),']'];
text(Node_info(node_num1,2),Node_info(node_num1,3),text_1,'HorizontalAlignment', 'right');
text(Node_info(node_num2,2),Node_info(node_num2,3),text_2,'HorizontalAlignment', 'right');
shading interp %色彩平滑
colorbar %分布柱图 
axis equal
title('\sigma_y 应力分布云图/Pa')
box on;
end

%% 后处理函数 绘制剪应力云图
function sigma_xxyy_node=Plot_sxy_node(sigma_xy,Node_info,Ele_info)
sigma_xy_node=[];
for i=1:size(Node_info,1)
 E=[];
 E1=find(abs(Ele_info(:,2)-i)<1e-9);
 E2=find(abs(Ele_info(:,3)-i)<1e-9);
 E3=find(abs(Ele_info(:,4)-i)<1e-9);
 E=[E;E1;E2;E3];
 n=size(E,1);
 sxy_sum=0;
 for j=1:n
 sxy_sum=sxy_sum+sigma_xy(E(j));
 end
 sigma_xy_node=[sigma_xy_node;sxy_sum/n]; 
end
sigma_xxyy_node=sigma_xy_node; %将 sigma_xy_node 的数值进行保护,后续标注会用到
X1=linspace(min(Node_info(:,2)),max(Node_info(:,2)),100); %将坐标均分成 100 份
Y1=linspace(min(Node_info(:,3)),max(Node_info(:,3)),100);
[X,Y,sigma_xy_node]=griddata(Node_info(:,2),Node_info(:,3),sigma_xy_node,X1',Y1,'v4'); 
pcolor(X,Y,sigma_xy_node);
x_row=find(abs(Node_info(:,2)-2)<1e-9); %找到右上角和右下角的节点标号,在云图中标注数值
y1_row=find(abs(Node_info(:,3)-1)<1e-9);
y2_row=find(abs(Node_info(:,3))<1e-9);
node_num1=intersect(x_row,y1_row);
node_num2=intersect(x_row,y2_row);
text_x2y1=sigma_xxyy_node(node_num1);
text_x2y2=sigma_xxyy_node(node_num2);
text_1=['[','(',num2str(Node_info(node_num1,2)),',',num2str(Node_info(node_num1,3)),')',',',num2str(text_x2y1),']'];
text_2=['[','(',num2str(Node_info(node_num2,2)),',',num2str(Node_info(node_num2,3)),')',',',num2str(text_x2y2),']'];
text(Node_info(node_num1,2),Node_info(node_num1,3),text_1,'HorizontalAlignment', 'right');
text(Node_info(node_num2,2),Node_info(node_num2,3),text_2,'HorizontalAlignment', 'right');
shading interp %色彩平滑
colorbar %分布柱图 
axis equal
title('\tau_{xy}分布云图/Pa')
box on;
end

%% 后处理函数 绘制 Mises 应力分布云图
function []=Mise_stress(Node_info,sigma_xx_node,sigma_yy_node,sigma_xxyy_node)
% 先求主应力
sigma_m=[];
for i=1:size(Node_info,1)
 sigma1=(sigma_xx_node(i)+sigma_yy_node(i))/2+0.5*sqrt((sigma_xx_node(i)-sigma_yy_node(i))^2+4*sigma_xxyy_node(i)*sigma_xxyy_node(i));
 sigma2=(sigma_xx_node(i)+sigma_yy_node(i))/2-0.5*sqrt((sigma_xx_node(i)-sigma_yy_node(i))^2+4*sigma_xxyy_node(i)*sigma_xxyy_node(i));
% 求 Von-Mise 等效应力
 sigma_m=[sigma_m;sqrt(sigma1^2+sigma2^2-sigma1*sigma2)];
end
sigma_mm=sigma_m; %将 sigma_m 的数值进行保护,后续标注会用到
X1=linspace(min(Node_info(:,2)),max(Node_info(:,2)),100); %将坐标均分成 100 份
Y1=linspace(min(Node_info(:,3)),max(Node_info(:,3)),100);
[X,Y,sigma_m]=griddata(Node_info(:,2),Node_info(:,3),sigma_m,X1',Y1,'v4'); 
pcolor(X,Y,sigma_m); %绘制云图
x_row=find(abs(Node_info(:,2)-2)<1e-9); %根据坐标找到右上角和右下角的节点标号,在云图中标注数值
y1_row=find(abs(Node_info(:,3)-1)<1e-9);
y2_row=find(abs(Node_info(:,3))<1e-9);
node_num1=intersect(x_row,y1_row);
node_num2=intersect(x_row,y2_row);
text_x2y1=sigma_mm(node_num1);
text_x2y2=sigma_mm(node_num2);
text_1=['[','(',num2str(Node_info(node_num1,2)),',',num2str(Node_info(node_num1,3)),')',',',num2str(text_x2y1),']'];
text_2=['[','(',num2str(Node_info(node_num2,2)),',',num2str(Node_info(node_num2,3)),')',',',num2str(text_x2y2),']'];
text(Node_info(node_num1,2),Node_info(node_num1,3),text_1,'HorizontalAlignment', 'right');
text(Node_info(node_num2,2),Node_info(node_num2,3),text_2,'HorizontalAlignment', 'right');
shading interp %色彩平滑
colorbar %分布柱图 
axis equal
title('Mises 应力分布云图/Pa')
box on;
end

4. 有限元软件计算结果

建立相应的 shell 部件,按照编程所用尺寸进行网格划分,同时也注意直角 三角形单元的方向(因为与加载力作用点相关)。最终选择使用 S3 单元,单元数 为 400. 另外,为了计算保持一致,软件分析并未考虑将加载点耦合在自由端面。

5. 自编程序与软件计算结果对比

  • 12
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
Matlab有限元三角形单元是一种在有限元分析中常用的数学模型,用于模拟实际结构的力学行为。这些三角形单元可以用来计算结构的刚度矩阵和应力分布,从而可以评估结构的强度和变形情况。 在给定的代码中,引用给出了计算单个三角形单元刚度矩阵的函数。该函数接弹性模量、泊松比、厚度和单元节点坐标作为输入,并返回单元的刚度矩阵。 引用给出了计算总体刚度矩阵的函数。该函数利用之前的单元刚度矩阵函数,根据给定的弹性模量、泊松比、厚度、单元节点编号和节点坐标,计算每个单元的刚度矩阵,并将它们组合成总体刚度矩阵。 引用给出了求解过程的代码。该代码使用总体刚度矩阵和给定的力边界条件,通过求解控制方程,计算出结构的位移和节点力。同时,还可以计算每个单元的应力。 综上所述,引用的代码提供了计算有限元三角形单元的刚度矩阵和应力的功能,可以用于模拟和分析结构的力学行为。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Matlab二维三角形单元有限元程序](https://blog.csdn.net/qq_42909159/article/details/118963820)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值