XIAN-FEM-2026June/三维matlab代码/matlab 3D二阶矢量本征问题/Eigenfre_3Ddemo.m

136 lines
5.4 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.

clc
clear all
% 算例配置(改材料/模态数请编辑 case_config.m
[phy, cfg] = case_config();
% 四面体体积分:高斯积分节点与权重
IntegralOrder=cfg.IntegralOrder;
xt = [0.25,...
0.0919710780526,0.0919710780526,0.0919710780526,0.724086765841,...
0.319793627829,0.319793627829,0.319793627829,0.0406191165118,...
0.0563508326895,0.0563508326895,0.44364916731,0.0563508326895,...
0.44364916731,0.44364916731];
yt = [0.25,...
0.0919710780526,0.0919710780526,0.724086765841,0.0919710780526,...
0.319793627829,0.319793627829,0.0406191165118,0.319793627829,...
0.0563508326895,0.44364916731,0.0563508326895,0.44364916731,...
0.0563508326895,0.44364916731];
zt = [0.25,...
0.0919710780526,0.724086765841,0.0919710780526,0.0919710780526,...
0.319793627829,0.0406191165118,0.319793627829,0.319793627829,...
0.44364916731,0.0563508326895,0.0563508326895,0.44364916731,...
0.44364916731,0.0563508326895];
pt = [0.0197530864198,...
0.0119895139632,0.0119895139632,0.0119895139632,0.0119895139632,...
0.011511367871,0.011511367871,0.011511367871,0.011511367871,...
0.00881834215168,0.00881834215168,0.00881834215168,0.00881834215168,...
0.00881834215168,0.00881834215168];
model=mphload(cfg.mphFile);
[m1, m2]=mphmeshstats(model);
NbrNodes=max(size(m2.vertex)); % 顶点数
NbrElements=max(size(m2.elem{2})); % 四面体数
Nodes=m2.vertex; % 顶点坐标 3*n
Domains=m2.elementity{2}; % 四面体区域索引 n*1
Elements=m2.elem{2}+1; % 四面体顶点索引 4*nCOMSOL 0-based -> MATLAB 1-based
% 四面体顶点重新排序,节点按从小到大顺序排列
Elements = sort(Elements);
el2no=Elements;
% 面排序
f1=el2no([1 1 1 2],:);
f2=el2no([2 2 3 3],:);
f3=el2no([3 4 4 4],:);
f_array=[f1(:) f2(:) f3(:)];
% Faces 全局面 n*3FacesOfElements 四面体面索引 4N*1
[Faces,~,FacesOfElements]=unique(f_array,'rows');
NbrFaces=max(size(Faces)); % 面数
% 边排序
n1=el2no([1 1 1 2 2 3],:);
n2=el2no([2 3 4 3 4 4],:);
el_ed2no_array=[n1(:) n2(:)];
% Edges 全局边 n*2EdgesOfElements 四面体边索引 6N*1
[Edges,~,EdgesOfElements]=unique(el_ed2no_array,'rows');
NbrEdges=max(size(Edges)); % 边数
epsilon=phy.eps; % 相对介电常数
Dof=NbrEdges*2+NbrFaces*2; % 自由度:二阶矢量基,边数*2+面数*2
A=zeros(Dof,Dof);
B=zeros(Dof,Dof);
for n=1:NbrElements
% 网格坐标
x=zeros(4,1);y=zeros(4,1);z=zeros(4,1);
x(1)=Nodes(1,Elements(1,n));y(1)=Nodes(2,Elements(1,n));z(1)=Nodes(3,Elements(1,n));
x(2)=Nodes(1,Elements(2,n));y(2)=Nodes(2,Elements(2,n));z(2)=Nodes(3,Elements(2,n));
x(3)=Nodes(1,Elements(3,n));y(3)=Nodes(2,Elements(3,n));z(3)=Nodes(3,Elements(3,n));
x(4)=Nodes(1,Elements(4,n));y(4)=Nodes(2,Elements(4,n));z(4)=Nodes(3,Elements(4,n));
% 边长度
l=zeros(6,1);
l(1)=sqrt((x(1)-x(2))*(x(1)-x(2))+(y(1)-y(2))*(y(1)-y(2))+(z(1)-z(2))*(z(1)-z(2)));
l(2)=sqrt((x(1)-x(3))*(x(1)-x(3))+(y(1)-y(3))*(y(1)-y(3))+(z(1)-z(3))*(z(1)-z(3)));
l(3)=sqrt((x(4)-x(1))*(x(4)-x(1))+(y(4)-y(1))*(y(4)-y(1))+(z(4)-z(1))*(z(4)-z(1)));
l(4)=sqrt((x(2)-x(3))*(x(2)-x(3))+(y(2)-y(3))*(y(2)-y(3))+(z(2)-z(3))*(z(2)-z(3)));
l(5)=sqrt((x(4)-x(2))*(x(4)-x(2))+(y(4)-y(2))*(y(4)-y(2))+(z(4)-z(2))*(z(4)-z(2)));
l(6)=sqrt((x(4)-x(3))*(x(4)-x(3))+(y(4)-y(3))*(y(4)-y(3))+(z(4)-z(3))*(z(4)-z(3)));
ll=zeros(20,1); % 基函数归一化系数
ll(1)=l(1);ll(2)=l(1);ll(3)=l(2);ll(4)=l(2);ll(5)=l(3);ll(6)=l(3);
ll(7)=l(4);ll(8)=l(4);ll(9)=l(5);ll(10)=l(5);ll(11)=l(6);ll(12)=l(6);
ll(13)=1.5*l(1);ll(14)=1.5*l(2);ll(15)=1.5*l(1);ll(16)=1.5*l(3);
ll(17)=1.5*l(2);ll(18)=1.5*l(3);ll(19)=1.5*l(4);ll(20)=1.5*l(5);
% 雅可比矩阵
Jac=zeros(3,3);
Jac(1,1)=x(1)-x(4);Jac(1,2)=y(1)-y(4);Jac(1,3)=z(1)-z(4);
Jac(2,1)=x(2)-x(4);Jac(2,2)=y(2)-y(4);Jac(2,3)=z(2)-z(4);
Jac(3,1)=x(3)-x(4);Jac(3,2)=y(3)-y(4);Jac(3,3)=z(3)-z(4);
InvJac=inv(Jac);
DetJac=abs(det(Jac));
TJac=Jac'/DetJac;
% 计算高斯节点对应的基函数
tempE=zeros(1,3);E=zeros(20,3,IntegralOrder);curlE=zeros(20,3,IntegralOrder);
for i=1:IntegralOrder
for j=1:20
tempE(:)=BF_E(xt(i),yt(i),zt(i),j)*ll(j);
E(j,:,i)=(InvJac*tempE(:))';
tempE(:)=BF_CurlE(xt(i),yt(i),zt(i),j)*ll(j);
curlE(j,:,i)=(TJac*tempE(:))';
end
end
% 计算映射数组(局部 DOF -> 全局 DOF
map=zeros(20,1);
for i=1:6
map(i*2-1)=EdgesOfElements((n-1)*6+i);
map(i*2)=EdgesOfElements((n-1)*6+i)+NbrEdges;
end
for i=1:4
map(12+i*2-1)=2*NbrEdges+FacesOfElements((n-1)*4+i);
map(12+i*2)=FacesOfElements((n-1)*4+i)+NbrFaces+2*NbrEdges;
end
% 双循环计算子矩阵
Ae=zeros(20,20);Be=zeros(20,20);
for i=1:20
for j=1:20
for k=1:IntegralOrder
Ae(i,j)=Ae(i,j)+pt(k)*DetJac*(curlE(i,1,k)*curlE(j,1,k)+curlE(i,2,k)*curlE(j,2,k)+curlE(i,3,k)*curlE(j,3,k));
Be(i,j)=Be(i,j)+pt(k)*DetJac*(E(i,1,k)*E(j,1,k)+E(i,2,k)*E(j,2,k)+E(i,3,k)*E(j,3,k));
end
end
end
% 矩阵组装
for i=1:20
for j=1:20
A(map(i),map(j))= A(map(i),map(j))+Ae(i,j);
B(map(i),map(j))= B(map(i),map(j))+Be(i,j);
end
end
end
% 广义本征值求解A*x = lambda*B*xlambda = k0^2
[V,D] = eigs(A,B,cfg.NbrMode,cfg.eigsSigma);
k0=diag(sqrt(D))