?? finite_element_tri.m
字號:
% 用有限元法求解三角形形區域上的Possion方程
function Finite_element_tri(Imax,Jmax)
global ndm nel na
% ndm 總節點數
% nel 基元數
% na 活動節點數
Imax=30;Jmax=60;%設定網格數
V=0; J=0;X0=1/Imax;Y0=X0;
domain_tri
[X,Y,NN,NE]=setelm_tri(Imax,Jmax); % 給節點和三角形元素編號,并設定節點坐標
% 求解有限元方程的求系數矩陣
T=zeros(ndm,ndm);
for n=1:nel
n1=NE(1,n); n2=NE(2,n); n3=NE(3,n);
s=abs((X(n2)-X(n1))*(Y(n3)-Y(n1))-(X(n3)-X(n1))*(Y(n2)-Y(n1)))/2;
for k=1:3
if n1<=na|n2<=na
T(n1,n2)=T(n1,n2)+((Y(n2)-Y(n3))*(Y(n3)-Y(n1))+(X(n3)-X(n2))*(X(n1)-X(n3)))/(4*s);
T(n2,n1)=T(n1,n2);
T(n1,n1)=T(n1,n1)+((Y(n2)-Y(n3))^2+(X(n3)-X(n2))^2)/(4*s);
end
k=n1;n1=n2;n2=n3;n3=k;
end
end
M=T(1:na,1:na);
% 求有限元方程的右端項
G=zeros(na,1);
for n=1:nel
n1=NE(1,n); n2=NE(2,n); n3=NE(3,n);
s=abs((X(n2)-X(n1))*(Y(n3)-Y(n1))-(X(n3)-X(n1))*(Y(n2)-Y(n1)))/2;
for k=1:3
if n1<=na
G(n1)=G(n1)+(2*X(n1)+X(n2)+X(n3))*s/12;
end
n4=n1; n1=n2; n2=n3; n3=n4;
end
end
% 求解方程得結果
F=M\G;
NNV=zeros(Imax+1,Jmax+1);
fi=zeros(ndm,1);
fi(1:na)=F(1:na);
fi(na+1:ndm)=V;
for j=0:Jmax
for i=0:Imax
n=NN(i+1,j+1);
if n<=0
n=na+1;
end
NNV(i+1,j+1)=fi(n);
end
end
% 畫等電勢線
X1=zeros(1,Imax+1);
Y1=zeros(1,Jmax+1);
for i=1:Imax+1
X1(i)=(i-1)*X0;
end
for i=1:Jmax+1
Y1(i)=(i-1)*Y0;
end
% 畫解函數的曲面圖
figure(2)
surf(X1,Y1,NNV');
fid=fopen('Finite_element_tri.txt','w');
fprintf(fid,'\n *********有限元法求解三角形區域上Possion方程的結果********** \n \n');
fprintf(fid,'\n 節點編號 \n \n');
Nna=fliplr(NN);
fprintf(fid,'%4d%4d%4d%4d%4d%4d%4d%4d%4d\n',Nna);fprintf(fid,'\n 各節點的電勢 \n \n');
NNV=fliplr(NNV);
fprintf(fid,'%10.6f%10.6f%10.6f%10.6f%10.6f%10.6f%10.6f%10.6f%10.6f\n',NNV);
L=[1:ndm]';
fprintf(fid,'\n\n 節點編號 坐標分量x 坐標分量y u(x,y)的值\n\n');
for i=1:ndm
fprintf(fid,'%8d%14.5f%14.5f%14.5f\n',L(i),X(i),Y(i),fi(i));
end
fclose(fid);
end
function [X,Y,NN,NE]=setelm_tri(Imax,Jmax)
% 給節點和三角形元素編號,并設定節點坐標
global ndm nel na
% I1 I2 J1 J2 Imax Jmax分別描述網線縱向和橫向數目的變量
% X Y表示節點坐標
% NN描述節點編號
% NE 描述各基點局域節點的矩陣
% ndm 總節點數
% nel 基元數
% na 表示活動節點數
nlm=Imax*Jmax;
dx=1/Imax;
dy=1/Jmax;
X=nlm:1;
Y=nlm:1;
NN=zeros(Imax+1,Jmax+1);
n1=0;
% 活動節點編號
for j=3:Jmax/2
for i=2:j-1
n1=n1+1;
NN(i,j)=n1;
X(n1)=(i-1)*dx;
Y(n1)=-1+(j-1)*dy;
end
end
k=Jmax/2+1;
for j=Jmax/2+1:Jmax-1
k=k-1;
for i=2:k
n1=n1+1;
NN(i,j)=n1;
X(n1)=(i-1)*dx;
Y(n1)=1+(j-Jmax-1)*dy;
end
end
na=n1;
for j=Jmax+1:-1:Jmax/2+1
n1=n1+1;
NN(1,j)=n1;
X(n1)=0;
Y(n1)=1+(j-Jmax-1)*dy;
end
for j=Jmax/2:-1:1
n1=n1+1;
NN(1,j)=n1;
X(n1)=0;
Y(n1)=-1+(j-1)*dy;
end
for i=2:Imax+1
n1=n1+1;
NN(i,i)=n1;
X(n1)=(i-1)*dx;
Y(n1)=-1+(i-1)*dy;
end
K=0;
for i=Imax:-1:2
K=K+2;
n1=n1+1;
NN(i,i+K)=n1;
X(n1)=(i-1)*dx;
Y(n1)=1+(i+K-Jmax-1)*dy;
end
% 以上為對節點進行編號
ndm=n1;
NE=zeros(3,2*ndm); n1=0;
for j=3:Jmax/2
for i=2:j-1
n1=n1+1;
NE(1,n1)=NN(i,j);
NE(2,n1)=NN(i-1,j+1);
NE(3,n1)=NN(i-1,j);
n1=n1+1;
NE(1,n1)=NN(i,j);
NE(2,n1)=NN(i,j+1);
NE(3,n1)=NN(i-1,j+1);
end
end
k=Jmax/2+1;
for j=Jmax/2+1:Jmax-1
k=k-1;
for i=2:k
n1=n1+1;
NE(1,n1)=NN(i,j);
NE(2,n1)=NN(i-1,j+1);
NE(3,n1)=NN(i-1,j);
n1=n1+1;
NE(1,n1)=NN(i,j);
NE(2,n1)=NN(i,j+1);
NE(3,n1)=NN(i-1,j+1);
end
end
for i=2:Imax
n1=n1+1;
NE(1,n1)=NN(i,i);
NE(2,n1)=NN(i-1,i);
NE(3,n1)=NN(i-1,i-1);
n1=n1+1;
NE(1,n1)=NN(i,i);
NE(2,n1)=NN(i-1,i+1);
NE(3,n1)=NN(i-1,i);
n1=n1+1;
NE(1,n1)=NN(i,i);
NE(2,n1)=NN(i,i+1);
NE(3,n1)=NN(i-1,i+1);
end
n1=n1+1;
NE(1,n1)=NN(Imax+1,Imax+1);
NE(2,n1)=NN(Imax,Imax+1);
NE(3,n1)=NN(Imax,Imax);
n1=n1+1;
NE(1,n1)=NN(Imax+1,Imax+1);
NE(2,n1)=NN(Imax,Imax+2);
NE(3,n1)=NN(Imax,Imax+1);
K=0;
for i=Imax:-1:2
K=K+2;
n1=n1+1;
NE(1,n1)=NN(i,i+K);
NE(2,n1)=NN(i-1,i+K+1);
NE(3,n1)=NN(i-1,i+K);
end
nel=n1;
end
function domain_tri
% 定義求解區域
xy=[0 -1;-1 1;1 1;];
A=zeros(3,3);
A(1,1)=2; A(1,2)=-1;A(1,3)=-1;
A(2,2)=2; A(2,1)=-1;A(2,3)=-1;
A(3,3)=2; A(3,2)=-1;A(3,1)=-1;
A=sparse(A);
figure(1);
gplot(A,xy);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -