XIAN-FEM-2026June/三维matlab代码/2022-11 PML&&ABC/2022-11 PML/matlab代码及对应COMSOL模型/FemAssemble.m

154 lines
4.6 KiB
Matlab
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

function [A,b,EdgesOfElements]=FemAssemble(node,Elements,domain,NbrEdge,lam0,epsilonr,mur,m)
%矩形PML矩阵组装
%m为PML阶次
%物理参数
k0=2*pi/lam0;
E0=[1,1];
%高斯积分点
[xt,yt,pt,IntegralOrder]=GetGuassPoints(4);
% IntegralOrder=4;
% xt= [ 0.333333333333333,0.6,0.2,0.2 ];
% yt= [ 0.3333333333333333,0.2,0.6,0.2 ];
% pt= [ -0.28125,.260416666666,.260416666666,.260416666666 ];
%网格处理
NbrElement=max(size(Elements));
el2no=Elements;
n1=el2no([1 1 2],:);
n2=el2no([2 3 3],:);
el_ed2no_array=[n1(:) n2(:)];
[Edges,~,EdgesOfElements]=unique(el_ed2no_array,'rows');
NbrEdges=max(size(Edges));
Dboudary=zeros(NbrEdge,2);
%矩阵初始化
Dof=NbrEdges;
A=zeros(Dof,Dof);
b=zeros(Dof,1);
%狄利克雷边界
NbrDboudary=0;
%循环网格 组装矩阵
for n=1:NbrElement
%节点坐标
x=zeros(3,1);y=zeros(3,1);l=zeros(3,1);
x(1)=node(Elements(1,n),1);y(1)=node(Elements(1,n),2);
x(2)=node(Elements(2,n),1);y(2)=node(Elements(2,n),2);
x(3)=node(Elements(3,n),1);y(3)=node(Elements(3,n),2);
l(1)=sqrt((x(1)-x(2))*(x(1)-x(2))+(y(1)-y(2))*(y(1)-y(2)));
l(2)=sqrt((x(1)-x(3))*(x(1)-x(3))+(y(1)-y(3))*(y(1)-y(3)));
l(3)=sqrt((x(3)-x(2))*(x(3)-x(2))+(y(3)-y(2))*(y(3)-y(2)));
%雅可比矩阵
Jac=zeros(3,3);
Jac(1,1)=x(2)-x(1);Jac(1,2)=y(2)-y(1);
Jac(2,1)=x(3)-x(1);Jac(2,2)=y(3)-y(1);Jac(3,3)=1;
InvJac=inv(Jac);
DetJac=abs(det(Jac));
TJac=Jac'/DetJac;
%小矩阵
Et=zeros(3,3,IntegralOrder);curlEt=zeros(3,3,IntegralOrder);temp=zeros(3,1);
for i=1:IntegralOrder
for j=1:3
[temp(1),temp(2)]=BF_Et(j,xt(i),yt(i));temp(3)=0;
Et(j,:,i)=InvJac*temp*l(j);
temp(3)=BF_curlEt(j,xt(i),yt(i));temp(1)=0;temp(2)=0;
curlEt(j,:,i)=TJac*temp*l(j);
end
end
if domain(n)==2
xepsilonr=[epsilonr,0,0;0,epsilonr,0;0,0,epsilonr];
xmur=[mur,0,0;0,mur,0;0,0,mur];
averX=(x(1)+x(2)+x(3))/3;
x0=0.5;
d=0.5;
R0=10000;
Sx=1-1i*((averX-x0)/d)^m*(m+1)*R0/2/d/k0;
Lambda=[1/Sx,0,0;0,Sx,0;0,0,Sx];
xepsilonr=xepsilonr*Lambda;
xmur=xmur*Lambda;
invXmur=inv(xmur);
elseif domain(n)==1
xepsilonr=[epsilonr,0,0;0,epsilonr,0;0,0,epsilonr];
xmur=[mur,0,0;0,mur,0;0,0,mur];
invXmur=inv(xmur);
end
Sz=zeros(3,3);Tz=zeros(3,3);
for i=1:3
for j=1:3
for k=1:IntegralOrder
Sz(i,j)=Sz(i,j)+pt(k)*DetJac*dot(curlEt(i,:,k)',invXmur*curlEt(j,:,k)');
Tz(i,j)=Tz(i,j)-pt(k)*DetJac*k0*k0*dot(Et(i,:,k)',xepsilonr*Et(j,:,k)');
end
end
end
for i=1:3
for j=1:3
A(EdgesOfElements((n-1)*3+i),EdgesOfElements((n-1)*3+j))=A(EdgesOfElements((n-1)*3+i),EdgesOfElements((n-1)*3+j))+Sz(i,j)+Tz(i,j);
end
end
%边界处理
%NbrDboudary 边界数
%Dboudary n*2 1:网格 2第几条边
if (x(1)==-1)&&(x(2)==-1)
NbrDboudary=NbrDboudary+1;
Dboudary(NbrDboudary,1)=n;
Dboudary(NbrDboudary,2)=1;
elseif (x(1)==-1)&&(x(3)==-1)
NbrDboudary=NbrDboudary+1;
Dboudary(NbrDboudary,1)=n;
Dboudary(NbrDboudary,2)=2;
elseif (x(2)==-1)&&(x(3)==-1)
NbrDboudary=NbrDboudary+1;
Dboudary(NbrDboudary,1)=n;
Dboudary(NbrDboudary,2)=3;
end
end
%强加狄利克雷边界条件
for n=1:NbrDboudary
numEle=Dboudary(n,1);
outNorm=[-1;0];
if (Dboudary(n,2)==1)
u=0.5;v=0;
elseif (Dboudary(n,2)==2)
u=0;v=0.5;
elseif (Dboudary(n,2)==3)
u=0.5;v=0.5;
end
%节点坐标
x=zeros(3,1);y=zeros(3,1);l=zeros(3,1);
x(1)=node(Elements(1,numEle),1);y(1)=node(Elements(1,numEle),2);
x(2)=node(Elements(2,numEle),1);y(2)=node(Elements(2,numEle),2);
x(3)=node(Elements(3,numEle),1);y(3)=node(Elements(3,numEle),2);
l(1)=sqrt((x(1)-x(2))*(x(1)-x(2))+(y(1)-y(2))*(y(1)-y(2)));
l(2)=sqrt((x(1)-x(3))*(x(1)-x(3))+(y(1)-y(3))*(y(1)-y(3)));
l(3)=sqrt((x(3)-x(2))*(x(3)-x(2))+(y(3)-y(2))*(y(3)-y(2)));
%雅可比矩阵
Jac=zeros(3,3);
Jac(1,1)=x(2)-x(1);Jac(1,2)=y(2)-y(1);
Jac(2,1)=x(3)-x(1);Jac(2,2)=y(3)-y(1);Jac(3,3)=1;
InvJac=inv(Jac);
[temp(1),temp(2)]=BF_Et(Dboudary(n,2),u,v);temp(3)=0;
tempEt=InvJac*temp*l(Dboudary(n,2));
temp2=outNorm(1)*tempEt(2)-outNorm(2)*tempEt(1);
numEdge=EdgesOfElements((Dboudary(n,1)-1)*3+Dboudary(n,2));
temp1=outNorm(1)*E0(2)-outNorm(2)*E0(1);
pp=temp1/temp2;
b(numEdge)=pp;
A(numEdge,:)=0;
b(:)=b(:)-pp*A(:,numEdge);
A(:,numEdge)=0;
A(numEdge,numEdge)=1;
end
end