二维体光子晶体的平面波展开法代码

这篇具有很好参考价值的文章主要介绍了二维体光子晶体的平面波展开法代码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

%书上的代码,和FEM符合的更好
%在这个代码里试着把单位原胞的相对介电常数分布画出来
%这个代码的单位原胞的中心就是(0,0)点,也就是坐标原点
%The program for the computation of the PhC photonic
%band structure for 2D PhC.
%Parameters of the structure are defined by the PhC
%period, elements radius, and by the permittivities
%of elements and background material.
%Input parameters: PhC period, radius of an
%element, permittivities
%Output data: The band structure of the 2D PhC.
clear all;clc;close all
%The variable a defines the period of the structure.
%It influences on results in case of the frequency
%normalization.
a=1e-6; % in meters,晶格常数,单位m
%The variable r contains elements radius. Here it is
%defined as a part of the period.
r=0.4*a; % in meters,单位m,介质柱半径
%The variable eps1 contains the information about
%the relative background material permittivity.
eps1=9;%背景材料介电常数
%The variable eps2 contains the information about
%permittivity of the elements composing PhC. In our
%case permittivities are set to form the structure
%perforated membrane
eps2=1;%介质柱的相对介电常数
%The variable precis defines the number of k-vector
%points between high symmetry points
precis=20;%和BZ区的离散有关
%The variable nG defines the number of plane waves.
%Since the number of plane waves cannot be
%arbitrary value and should be zero-symmetric, the
%total number of plane waves may be determined
%as (nG*2-1)^2
nG=15;%和平面波的数量有关
%The variable precisStruct defines contains the
%number of nodes of discretization mesh inside in
%unit cell discretization mesh elements.
precisStruct=50;%单位原胞离散份数,最好设为偶数
%The following loop carries out the definition
%of the unit cell. The definition is being
%made in discreet form by setting values of inversed
%dielectric function to mesh nodes.
nx=1;
for countX=-a/2:a/precisStruct:a/2%就是网格节点的x坐标
ny=1;
for countY=-a/2:a/precisStruct:a/2%就是网格节点的y坐标
%The following condition allows to define the circle
%with of radius r
if(sqrt(countX^2+countY^2)<r)%判断网格节点坐标是否处于中心的介质柱内
%Setting the value of the inversed dielectric
%function to the mesh node
struct(nx,ny)=1/eps2;
%Saving the node coordinate
xSet(nx)=countX;
ySet(ny)=countY;
else
struct(nx,ny)=1/eps1;
xSet(nx)=countX;
ySet(ny)=countY;
end
ny=ny+1;
end
nx=nx+1;
end
%The computation of the area of the mesh cell. It is
%necessary for further computation of the Fourier
%expansion coefficients.
dS=(a/precisStruct)^2;%单位微元的面积
%Forming 2D arrays of nods coordinates
xMesh=meshgrid(xSet(1:length(xSet)-1));
yMesh=meshgrid(ySet(1:length(ySet)-1))';
%Transforming values of inversed dielectric function
%for the convenience of further computation
structMesh=struct(1:length(xSet)-1,...
1:length(ySet)-1)*dS/(max(xSet)-min(xSet))^2;%就是(C10)的一部分

%Defining the k-path within the Brilluoin zone. The
%k-path includes all high symmetry points and precis
%points between them
kx(1:precis+1)=0:pi/a/precis:pi/a;
ky(1:precis+1)=zeros(1,precis+1);
kx(precis+2:precis+precis+1)=pi/a;
ky(precis+2:precis+precis+1)=...
pi/a/precis:pi/a/precis:pi/a;
kx(precis+2+precis:precis+precis+1+precis)=...
pi/a-pi/a/precis:-pi/a/precis:0;
ky(precis+2+precis:precis+precis+1+precis)=...
pi/a-pi/a/precis:-pi/a/precis:0;
%After the following loop, the variable numG will
%contain real number of plane waves used in the
%Fourier expansion
numG=1;
%The following loop forms the set of reciprocal
%lattice vectors.
for Gx=-nG*2*pi/a:2*pi/a:nG*2*pi/a
for Gy=-nG*2*pi/a:2*pi/a:nG*2*pi/a
G(numG,1)=Gx;
G(numG,2)=Gy;
numG=numG+1;
end
end
%numG为82,实际上多了1
%The next loop computes the Fourier expansion
%coefficients which will be used for matrix
%differential operator computation.
for countG=1:numG-1
    Mark0=countG/(numG-1)
for countG1=1:numG-1
    temp=exp(1i*((G(countG,1)-G(countG1,1))*...
xMesh+(G(countG,2)-G(countG1,2))*yMesh));

CN2D_N(countG,countG1)=sum(sum(structMesh.*...
temp));
end
end




%The next loop computes matrix differential operator
%in case of TE mode. The computation
%is carried out for each of earlier defined
%wave vectors.
for countG=1:numG-1
     Mark=countG/(numG-1)
for countG1=1:numG-1
for countK=1:length(kx)
M(countK,countG,countG1)=...
CN2D_N(countG,countG1)*((kx(countK)+G(countG,1))*...
(kx(countK)+G(countG1,1))+...
(ky(countK)+G(countG,2))*(ky(countK)+G(countG1,2)));
end
end
end
%The computation of eigen-states is also carried
%out for all wave vectors in the k-path.
for countK=1:length(kx)
%Taking the matrix differential operator for current
%wave vector.
MM(:,:)=M(countK,:,:);
%Computing the eigen-vectors and eigen-states of
%the matrix
[D,V]=eig(MM);
%Transforming matrix eigen-states to the form of
%normalized frequency.
dispe(:,countK)=sqrt(V*ones(length(V),1))*a/2/pi;
end
%Plotting the band structure
%Creating the output field
figure(3);
%Creating axes for the band structure output.
ax1=axes;
%Setting the option
%drawing without cleaning the plot
hold on;
%Plotting the first 8 bands
for u=1:8
plot(abs(dispe(u,:)),'r','LineWidth',2);
%If there are the PBG, mark it with blue rectangle
if(min(dispe(u+1,:))>max(dispe(u,:)))
rectangle('Position',[1,max(dispe(u,:)),...
length(kx)-1,min(dispe(u+1,:))-...
max(dispe(u,:))],'FaceColor','b',...
'EdgeColor','b');
end
end
%Signing Labeling the axes
%下面是和FEM算的数据比较,没有的话可以删除下面这段%%
Data=csvread('C:\Users\LUO1\Desktop\ComsolDate.csv');
uniX=unique(Data(:,1));
Ymat=[];
for zz=1:length(uniX)
    Ymat=[Ymat,Data(Data(:,1)==uniX(zz),2)];    
end
plot(1:size(Ymat,2),Ymat,'bo','MarkerSize',3)
%%%%%绘制FEM的数据%%%%%%%

set(ax1,'xtick',...
[1 precis+1 2*precis+1 3*precis+1]);
set(ax1,'xticklabel',['G';'X';'M';'G']);
ylabel('Frequency \omegaa/2\pic','FontSize',16);
xlabel('Wavevector','FontSize',16);
xlim([1 length(kx)])
set(ax1,'XGrid','on');
 title('book')



二维体光子晶体的平面波展开法代码,计算电磁学,matlab,matlab,矩阵,算法,经验分享
蓝色小圆是FEM绘制的能带。我原先按照自己的理解改动了下上面的代码,但是和FEM的结果符合得没上面的代码好。

抄的书上的代码: Photonic Crystals Physics and Practical Modeling (Igor A. Sukhoivanov, Igor V. Guryev (auth.))

下面是相同参数,但按照我自己的理解改了一点点的代码,结果和FEM的结果符合得不是很好,有无这方面的大佬评论区解释下原因?或者任何见解也行

%这份代码和FEM符合的不是很好
%在这个代码里试着把单位原胞的相对介电常数分布画出来
%这个代码的单位原胞的中心就是(0,0)点,也就是坐标原点
%The program for the computation of the PhC photonic
%band structure for 2D PhC.
%Parameters of the structure are defined by the PhC
%period, elements radius, and by the permittivities
%of elements and background material.
%Input parameters: PhC period, radius of an
%element, permittivities
%Output data: The band structure of the 2D PhC.
clear all;clc;close all
%The variable a defines the period of the structure.
%It influences on results in case of the frequency
%normalization.
a=1e-6; % in meters,晶格常数,单位m
%The variable r contains elements radius. Here it is
%defined as a part of the period.
r=0.4*a; % in meters,单位m,介质柱半径
%The variable eps1 contains the information about
%the relative background material permittivity.
eps1=9;%背景材料介电常数
%The variable eps2 contains the information about
%permittivity of the elements composing PhC. In our
%case permittivities are set to form the structure
%perforated membrane
eps2=1;%介质柱的相对介电常数
%The variable precis defines the number of k-vector
%points between high symmetry points
precis=20;%和BZ区的离散有关
%The variable nG defines the number of plane waves.
%Since the number of plane waves cannot be
%arbitrary value and should be zero-symmetric, the
%total number of plane waves may be determined
%as (nG*2-1)^2
nG=15;%和平面波的数量有关
%The variable precisStruct defines contains the
%number of nodes of discretization mesh inside in
%unit cell discretization mesh elements.
precisStruct=50;%单位原胞离散份数,最好设为偶数
%The following loop carries out the definition
%of the unit cell. The definition is being
%made in discreet form by setting values of inversed
%dielectric function to mesh nodes.
nx=1;
for countX=-a/2:a/precisStruct:a/2%就是网格节点的x坐标
ny=1;
for countY=-a/2:a/precisStruct:a/2%就是网格节点的y坐标
%The following condition allows to define the circle
%with of radius r
if(sqrt(countX^2+countY^2)<r)%判断网格节点坐标是否处于中心的介质柱内
%Setting the value of the inversed dielectric
%function to the mesh node
struct(nx,ny)=1/eps2;
%Saving the node coordinate
xSet(nx)=countX;
ySet(ny)=countY;
else
struct(nx,ny)=1/eps1;
xSet(nx)=countX;
ySet(ny)=countY;
end
ny=ny+1;
end
nx=nx+1;
end
%The computation of the area of the mesh cell. It is
%necessary for further computation of the Fourier
%expansion coefficients.
dS=(a/precisStruct)^2;%单位微元的面积
%Forming 2D arrays of nods coordinates
xMesh=meshgrid(xSet(1:length(xSet)));
yMesh=meshgrid(ySet(1:length(ySet)))';
%Transforming values of inversed dielectric function
%for the convenience of further computation
structMesh=struct(1:length(xSet),...
1:length(ySet))*dS/(max(xSet)-min(xSet))^2;%就是(C10)的一部分

%Defining the k-path within the Brilluoin zone. The
%k-path includes all high symmetry points and precis
%points between them
kx(1:precis+1)=0:pi/a/precis:pi/a;
ky(1:precis+1)=zeros(1,precis+1);
kx(precis+2:precis+precis+1)=pi/a;
ky(precis+2:precis+precis+1)=...
pi/a/precis:pi/a/precis:pi/a;
kx(precis+2+precis:precis+precis+1+precis)=...
pi/a-pi/a/precis:-pi/a/precis:0;
ky(precis+2+precis:precis+precis+1+precis)=...
pi/a-pi/a/precis:-pi/a/precis:0;
%After the following loop, the variable numG will
%contain real number of plane waves used in the
%Fourier expansion
numG=1;
%The following loop forms the set of reciprocal
%lattice vectors.
for Gx=-nG*2*pi/a:2*pi/a:nG*2*pi/a
for Gy=-nG*2*pi/a:2*pi/a:nG*2*pi/a
G(numG,1)=Gx;
G(numG,2)=Gy;
numG=numG+1;
end
end
%numG为82,实际上多了1
%The next loop computes the Fourier expansion
%coefficients which will be used for matrix
%differential operator computation.
for countG=1:numG-1
    Mark0=countG/(numG-1)
for countG1=1:numG-1
    temp=exp(1i*((G(countG,1)-G(countG1,1))*...
xMesh+(G(countG,2)-G(countG1,2))*yMesh));

CN2D_N(countG,countG1)=sum(sum(structMesh.*...
temp));
end
end




%The next loop computes matrix differential operator
%in case of TE mode. The computation
%is carried out for each of earlier defined
%wave vectors.
for countG=1:numG-1
    Mark=countG/(numG-1)
for countG1=1:numG-1
for countK=1:length(kx)
M(countK,countG,countG1)=...
CN2D_N(countG,countG1)*((kx(countK)+G(countG,1))*...
(kx(countK)+G(countG1,1))+...
(ky(countK)+G(countG,2))*(ky(countK)+G(countG1,2)));
end
end
end
%The computation of eigen-states is also carried
%out for all wave vectors in the k-path.
for countK=1:length(kx)
%Taking the matrix differential operator for current
%wave vector.
MM(:,:)=M(countK,:,:);
%Computing the eigen-vectors and eigen-states of
%the matrix
[D,V]=eig(MM);
%Transforming matrix eigen-states to the form of
%normalized frequency.
dispe(:,countK)=sqrt(V*ones(length(V),1))*a/2/pi;
end
%Plotting the band structure
%Creating the output field
figure(3);
%Creating axes for the band structure output.
ax1=axes;
%Setting the option
%drawing without cleaning the plot
hold on;
%Plotting the first 8 bands
for u=1:8
plot(abs(dispe(u,:)),'r','LineWidth',2);
%If there are the PBG, mark it with blue rectangle
if(min(dispe(u+1,:))>max(dispe(u,:)))
rectangle('Position',[1,max(dispe(u,:)),...
length(kx)-1,min(dispe(u+1,:))-...
max(dispe(u,:))],'FaceColor','b',...
'EdgeColor','b');
end
end
Data=csvread('C:\Users\LUO1\Desktop\ComsolDate.csv');
uniX=unique(Data(:,1));
Ymat=[];
for zz=1:length(uniX)
    Ymat=[Ymat,Data(Data(:,1)==uniX(zz),2)];    
end
plot(1:size(Ymat,2),Ymat,'bo','MarkerSize',3)
%Signing Labeling the axes
set(ax1,'xtick',...
[1 precis+1 2*precis+1 3*precis+1]);
set(ax1,'xticklabel',['G';'X';'M';'G']);
ylabel('Frequency \omegaa/2\pic','FontSize',16);
xlabel('Wavevector','FontSize',16);
xlim([1 length(kx)])
set(ax1,'XGrid','on');
 title('test')



和FEM的对比:
二维体光子晶体的平面波展开法代码,计算电磁学,matlab,matlab,矩阵,算法,经验分享

%================================================%我明白为什么我改动后的代码是错的了,原因是需要把xMesh、yMesh当作每个离散小微元的中心坐标,所以书上的代码更准确。

上面的理解又是错的,书上代码参考的那个数值求傅里叶系数的公式应该理解成二维离散傅里叶级数(2D DFS),总之这个知识点的却非常细微,不注意很容易以为自己搞懂了,但实际上理解是错的。正确的离散方法求介电分布函数的傅里叶系数的公式如下:

二维体光子晶体的平面波展开法代码,计算电磁学,matlab,matlab,矩阵,算法,经验分享

这实际上是个2D DFS,但fft2也可以间接计算这个式子。
二维体光子晶体的平面波展开法代码,计算电磁学,matlab,matlab,矩阵,算法,经验分享
上图是正确的正空间原胞划分网格示意图,四个红点勾勒出了正空间原胞的大小,蓝色的点就是计算中用到的节点数据。中间的红点是(0,0)点,红圈是介质柱轮廓。

=======================================

%=======================================%
为何下面两段代码的结果之差不是严格等于0?非常奇怪。有无这方面的大佬解释下?

Kappa(countG,countG1)*...
 (norm([kx(countK)+G(countG,1),ky(countK)+G(countG,2)])*...
 norm([kx(countK)+G(countG1,1),ky(countK)+G(countG1,2)]))
Kappa(countG,countG1)*...
norm([kx(countK)+G(countG,1),ky(countK)+G(countG,2)])*...
norm([kx(countK)+G(countG1,1),ky(countK)+G(countG1,2)])

写PWEM算法的时候只有用第一段代码得到的结果才是对的。
%=======================================%

%=========================================%
在某些nG参数下,书上代码绘制的能带会全部挤到0附近不知道为何,
但是如果加大precisStruct结果又会变回正常;在使用数值方法计算相对介电函数的傅里叶系数时nG和precisStruct参数的相对大小需要小心设置

后面我找到了这一现象可能的原因,和离散傅里叶变换(DFT),离散傅里叶级数(DFS)的公式具体形式有关。基于此我猜测有关系:2nG+1应小于或等于precisStruct(本质是2nG+1大小应小于等于正空间原胞离散份数)

%=========================================%

对书上代码的改写(TE、TM都可以计算,数值或解析方法算相对介电函数的傅里叶系数)

实际上无论算TE 还是TM能带 数值方法算的相对介电函数的傅里叶系数得到的能带反而比解析方法得到的能带和FEM方法误差更小(实际上解析方法算的相对介电函数比数值方法的质量好些),不清楚为何会这样。
图像如下:
二维体光子晶体的平面波展开法代码,计算电磁学,matlab,matlab,矩阵,算法,经验分享
二维体光子晶体的平面波展开法代码,计算电磁学,matlab,matlab,矩阵,算法,经验分享

代码:文章来源地址https://www.toymoban.com/news/detail-689874.html

%为什么按照我的想法去设置微元的中心坐标效果不行?
%数值法算Kappa的结果和FEM更接近,不知道为何
clear ;clc;close all
TEorTM='TM';
NUMorANA='ANA';%数值或解析方法算Kappa矩阵(傅里叶系数)
a=1e-6; % in meters,晶格常数,单位m

r=0.4*a; % in meters,单位m,介质柱半径

eps1=9;%背景材料介电常数

eps2=1;%介质柱的相对介电常数

precis=20;%和BZ区的离散有关

nG=16;%和平面波的数量有关

precisStruct=44;%单位原胞离散段数(x、y方向),最好设为偶数,
%因此节点数为precisStruct+1

%%%正空间基矢(可自己设置)%%%
a1=[a,0,0];%为方便求倒格子基矢,必须是三维矢量
a2=[0,a,0];
%%%正空间基矢%%%%%%%%%

%%%%求倒格子基矢%%%%%
a3=[0,0,1];%单位向量
Omega=abs(a3*cross(a1,a2)');%正空间单位原胞面积
s=2*pi./Omega;
b1(1,1)=a2(1,2);b1(1,2)=-a2(1,1);
b2(1,1)=-a1(1,2);b2(1,2)=a1(1,1);
b1=b1.*s;%行数组,最终结果(必须是行数组)
b2=b2.*s;%行数组,最终结果(必须是行数组)
%%%%求倒格子基矢%%%%%



nodeSet=-a/2:a/precisStruct:a/2;
len_nodeSet=length(nodeSet);
%初始化
struct=zeros(len_nodeSet,len_nodeSet);
xMesh0=zeros(len_nodeSet,len_nodeSet);
yMesh0=zeros(len_nodeSet,len_nodeSet);

for nx=1:len_nodeSet
    countX=nodeSet(nx);
    for ny=1:len_nodeSet
        
        countY=nodeSet(ny);
        if(sqrt(countX^2+countY^2)<r)%判断网格节点坐标是否处于中心的介质柱内
            
            struct(nx,ny)=1/eps2;%其实就是每个节点的相对介电常数
            xMesh0(nx,ny)=countX;%其实就是每个节点的x坐标
            yMesh0(nx,ny)=countY;%其实就是每个节点的y坐标
        else
            struct(nx,ny)=1/eps1;
            xMesh0(nx,ny)=countX;
            yMesh0(nx,ny)=countY;
        end
        
    end
    
end
xMesh0(:,end)=[];
xMesh0(end,:)=[];
yMesh0(:,end)=[];
yMesh0(end,:)=[];

%其实xSet=ySet=[-a/2:a/precisStruct:a/2]


dS=(a/precisStruct)^2;%单位微元的面积
%Forming 2D arrays of nods coordinates

%注意xMesh=xMesh0.'
%注意yMesh=yMesh0.'
%注意xMesh=yMesh0
%注意yMesh=xMesh0
%xMesh0、yMesh0其实是节点的坐标?
%=======================%
%=======================%
figure
for ii = 1:numel(xMesh0)
    plot(xMesh0(ii),yMesh0(ii),'b.','Markersize',8)
    hold on
    
    rectangle('Position',[xMesh0(ii)-0.5*(a/precisStruct),...
        yMesh0(ii)-0.5*(a/precisStruct),(a/precisStruct),(a/precisStruct)]);
    
end
xx1=a/2;
siteSto=[xx1,xx1;xx1,-xx1;-xx1,xx1;-xx1,-xx1];
hold on
scatter(siteSto(:,1),siteSto(:,2),'r.')
hold on
plot(0,0,'r.','Markersize',8)
hold on
% x y是中心,r是半径
rectangle('Position',[0-r,0-r,2*r,2*r],'Curvature',[1,1],'edgecolor',[1,0,0])
hold off
axis equal
title('xMesh、yMesh')
%=======================%
%=======================%

structMesh=struct(1:precisStruct,...
    1:precisStruct)*dS/Omega;%就是公式(C10)的一部分
%注意struct(1:length(xSet)-1,1:length(ySet)-1)等价于
%struct(:,end)=[];struct(end,:)=[];

%========离散不可约布里渊区(只适用于正方晶格)==========%
kx(1:precis+1)=0:pi/a/precis:pi/a;
ky(1:precis+1)=zeros(1,precis+1);
kx(precis+2:precis+precis+1)=pi/a;
ky(precis+2:precis+precis+1)=...
    pi/a/precis:pi/a/precis:pi/a;
kx(precis+2+precis:precis+precis+1+precis)=...
    pi/a-pi/a/precis:-pi/a/precis:0;
ky(precis+2+precis:precis+precis+1+precis)=...
    pi/a-pi/a/precis:-pi/a/precis:0;

%========离散不可约布里渊区(只适用于正方晶格)==========%


%The following loop forms the set of reciprocal
%lattice vectors.
G=zeros((2*nG+1)^2,2);
numG=0;
for m=-nG:nG
    for n=-nG:nG
        numG=numG+1;
        
        G(numG,1:2)=m.*b1+n.*b2;
        
    end
end
%G里面没有重复的G_{||}向量
numG=size(G,1);
%The next loop computes the Fourier expansion
%coefficients which will be used for matrix
%differential operator computation.
%遍历G数组

Kappa=zeros(numG,numG);
Indexset=-nG:nG;
if strcmp(NUMorANA,'NUM')==1%数值法计算Kappa
    
    for countG=1:numG
        Mark0=countG/(numG)
        for countG1=1:numG
            
            temp=exp(-1i*((G(countG,1)-G(countG1,1)).*...
                xMesh0+(G(countG,2)-G(countG1,2)).*yMesh0));%矩阵
            
            Kappa(countG,countG1)=sum(sum(structMesh.*...
                temp));%其实就是kappa(G_{||}-G_{||}^{\prime}})构成的矩阵
            %G(countG,1:2)其实就是G_{||},
            %G(countG1,1:2)其实就是G_{||}^{\prime}
            
            
        end
    end
    
    %%%%%%%%计算kappa(G_{||})%%%%%%%%
    Gmat=zeros(length(Indexset),length(Indexset));
    Kapmat=zeros(length(Indexset),length(Indexset));
    for m=1:length(Indexset)
        for n=1:length(Indexset)
            g0=Indexset(m).*b1+Indexset(n).*b2;%行数组
            Gmat(m,n)=g0(1)+1j.*g0(2);
            
            temp=exp(-1i*(g0(1).*...
                xMesh0+g0(2).*yMesh0));%矩阵
            
            Kapmat(m,n)=sum(sum(structMesh.*...
                temp));
         
        end
    end
    %%%%%%%%%%%%%%%%%%%%%%%
    
    
    
end


f=(pi*r^2)/Omega;
if strcmp(NUMorANA,'ANA')==1%解析法计算Kappa
    
    for countG=1:numG
        Mark0=countG/(numG)
        for countG1=1:numG
            temp=norm(G(countG,1:2)-G(countG1,1:2))*r;%|G|r
            
            if temp==0
                Kappa(countG,countG1)=1/eps1+f*(1/eps2-1/eps1);
            else
                Kappa(countG,countG1)=2*f*(1/eps2-1/eps1)*besselj(1,temp)/temp;
            end
            
            
            %其实就是kappa(G_{||}-G_{||}^{\prime}})构成的矩阵
            %G(countG,1:2)其实就是G_{||},
            %G(countG1,1:2)其实就是G_{||}^{\prime}
        end
    end
    
      %%%%%%%%计算kappa(G_{||})%%%%%%%%
    Gmat=zeros(length(Indexset),length(Indexset));
    Kapmat=zeros(length(Indexset),length(Indexset));
    for m=1:length(Indexset)
        for n=1:length(Indexset)
            g0=Indexset(m).*b1+Indexset(n).*b2;%行数组
            normG=norm(g0);%|G|
            Gmat(m,n)=g0(1)+1j.*g0(2);
            
            if Indexset(m)==0 && Indexset(n)==0
                Kapmat(m,n)=1/eps1+f*(1/eps2-1/eps1);
            else
                Kapmat(m,n)=2*f*(1/eps2-1/eps1)*besselj(1,(normG*r))/(normG*r);
            end
        
        end
    end
    %%%%%%%%%%%%%%%%%%%%%%%
    
    
end


%======绘制Kappa(G_{||})还原的相对介电常数分布==========%
%G_{||}-G_{||}^{\prime}}包含了很多重复元素
%因此kappa(G_{||}-G_{||}^{\prime}})不能用来恢复相对介电常数
%分布,只能用kappa(G_{||})
EpsMat=zeros(precisStruct+1,precisStruct+1);
for uu=1:precisStruct+1
    uu/(precisStruct+1)
    X=nodeSet(uu);
    for vv=1:precisStruct+1
        Y=nodeSet(vv);
        EpsMat(uu,vv)=sum(sum(Kapmat.*exp(1j*(X.*real(Gmat)+Y.*imag(Gmat)))));
        
    end
end
figure
mesh(1./real(EpsMat)) %画图
title([NUMorANA,'  RealEps','   e1=',num2str(eps1),'   e2=',num2str(eps2)])

figure
mesh(1./imag(EpsMat)) %画图
title([NUMorANA,'  ImagEps','   e1=',num2str(eps1),'   e2=',num2str(eps2)])

figure
imagesc(1./real(EpsMat))
colorbar


%======绘制Kappa(G_{||})还原的相对介电常数分布==========%

%构建特征矩阵

M=zeros(numG,numG,length(kx));%特征矩阵初始化
for countK=1:length(kx)
    Mark=countK/length(kx)
    for countG=1:numG
        for countG1=1:numG
            
            if strcmp(TEorTM,'TE')==1%TE
                M(countG,countG1,countK)=...
                    Kappa(countG,countG1)*...
                    ([kx(countK)+G(countG,1),ky(countK)+G(countG,2)]*...
                    ([kx(countK)+G(countG1,1),ky(countK)+G(countG1,2)].'));
            end
            
            if strcmp(TEorTM,'TM')==1%TM
                M(countG,countG1,countK)=...
                    Kappa(countG,countG1)*...
                    (norm([kx(countK)+G(countG,1),ky(countK)+G(countG,2)])*...
                    norm([kx(countK)+G(countG1,1),ky(countK)+G(countG1,2)]));
            end
            
            
        end
    end
end

%The computation of eigen-states is also carried
%out for all wave vectors in the k-path.
for countK=1:length(kx)
    %Taking the matrix differential operator for current
    %wave vector.
    MM(:,:)=M(:,:,countK);
    %Computing the eigen-vectors and eigen-states of
    %the matrix
    [D,V]=eig(MM);
    %Transforming matrix eigen-states to the form of
    %normalized frequency.
    dispe(:,countK)=sqrt(V*ones(length(V),1))*a/2/pi;
end
%Plotting the band structure
%Creating the output field
figure;
%Creating axes for the band structure output.
ax1=axes;
%Setting the option
%drawing without cleaning the plot
hold on;
%Plotting the first 8 bands
for u=1:8
    plot(abs(dispe(u,:)),'r','LineWidth',2);
    %If there are the PBG, mark it with blue rectangle
    if(min(dispe(u+1,:))>max(dispe(u,:)))
        rectangle('Position',[1,max(dispe(u,:)),...
            length(kx)-1,min(dispe(u+1,:))-...
            max(dispe(u,:))],'FaceColor','b',...
            'EdgeColor','b');
    end
end
%Signing Labeling the axes
%下面是和FEM算的数据比较,没有的话可以删除下面这段%%
if strcmp(TEorTM,'TE')==1
    Data=csvread('C:\Users\LUO1\Desktop\ComsolDateTE.csv');
end
if strcmp(TEorTM,'TM')==1
    Data=csvread('C:\Users\LUO1\Desktop\ComsolDateTM.csv');
end

uniX=unique(Data(:,1));
Ymat=[];
for zz=1:length(uniX)
    Ymat=[Ymat,Data(Data(:,1)==uniX(zz),2)];
end

plot(1:size(Ymat,2),Ymat,'bo','MarkerSize',3)
hold off
%%%%%绘制FEM的数据%%%%%%%

set(ax1,'xtick',...
    [1 precis+1 2*precis+1 3*precis+1]);
set(ax1,'xticklabel',['G';'X';'M';'G']);
ylabel('Frequency \omegaa/2\pic','FontSize',16);
xlabel('Wavevector','FontSize',16);
xlim([1 length(kx)])
set(ax1,'XGrid','on');
title([TEorTM,'  ',NUMorANA,'   book'])



实际上nG不是越大越收敛于FEM的能带结果,它和precisStruct大小有个很有趣的关系。

precisStruct最好设为偶数(经验发现,设为偶数,TE模式的收敛效果会更好),2nG+1<=precisStruct(按照DFS的定义),并且2nG+1不应和precisStruct相差很大。

到了这里,关于二维体光子晶体的平面波展开法代码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【多维定向滤波器组和表面波】表面变换:用于高效表示多维 s 的多分辨率变换(Matlab代码实现)

    【多维定向滤波器组和表面波】表面变换:用于高效表示多维 s 的多分辨率变换(Matlab代码实现)

    💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码实现 文献来源

    2024年02月13日
    浏览(10)
  • 晶体热学性能研究的方法:第一性原理声子谱计算

    晶体热学性能研究的方法:第一性原理声子谱计算

    晶体热学性能研究的方法:第一性原理声子谱计算 第一性原理声子谱计算是一种基于量子力学的计算方法,用于研究物质中声子的性质和行为。声子是晶体中的量子态,它描述了晶体中原子振动的性质。声子谱计算可以提供关于晶体结构、热力学性质、相变等方面的重要信息

    2024年02月08日
    浏览(7)
  • 计算机图形学:二维图形的几何变换(算法原理及代码实现)

    计算机图形学:二维图形的几何变换(算法原理及代码实现)

    对于一个二维图形作平移、旋转、放缩变换,可以转换为在二维坐标系中图形的所有点分别可以对应到在x,y轴方向分别平移tx,ty(平移)、绕一点旋转固定的角(旋转)、在x,y轴方向分别放缩sx,sy倍。 对于变换的原理,只需要将原图形的点通过极坐标或者相加、相乘,再

    2024年02月11日
    浏览(48)
  • 【JavaScript&&Threejs】判断路径在二维平面上投影的方向顺逆时针

    【JavaScript&&Threejs】判断路径在二维平面上投影的方向顺逆时针

    可以将路径每个连续的两点向量叉乘相加,根据正负性判断路径顺逆时针性 当我们计算两个向量的叉积时,结果是一个新的向量,其方向垂直于这两个向量所在的平面,并且其大小与这两个向量构成的平行四边形的面积成正比。这个新向量的方向由右手定则确定:如果你将右

    2024年04月26日
    浏览(13)
  • 【Lidar】基于Python的三维点云数据转二维平面+散点图绘制

    【Lidar】基于Python的三维点云数据转二维平面+散点图绘制

            最近一直在搞点云相关的操作,有时候在处理点云数据时需要查看处理后的数据是否满足需求,所以就想着写一套展示点云的代码。之前已经分享过如何可视化点云了,感兴趣的可以自己去看下:【Lidar】基于Python的Open3D库可视化点云数据。但是这个是3维展示,不满

    2024年02月21日
    浏览(18)
  • 【计算几何】凸多面体重叠判断算法:GJK 算法详解 & C++代码实现二维情形的凸多边形重叠判断

    【计算几何】凸多面体重叠判断算法:GJK 算法详解 & C++代码实现二维情形的凸多边形重叠判断

    GJK 算法是由 Gilbert,Johnson,Keerthi 三位前辈发明的, 用来计算两个凸多面体之间的碰撞检测 ,以及最近距离。 GJK 算法可以在 O ( M + N ) O(M+N) O ( M + N ) 的时间复杂度内,检测出碰撞,算法在每次迭代的过程中,都会优先选择靠近原点的方向,因此收敛速度会很快。算法的证明

    2024年02月08日
    浏览(11)
  • 计算机网络之网络层:数据平面

    计算机网络之网络层:数据平面

    网络层被分解为两个相互作用的部分,即数据平面和控制平面。 数据平面决定到达路由器输入链路之一的数据报如何转发到该路由器的输出链路之一,转发方式有: 传统的IP转发:转发基于数据报的目的地址 通用的转发:可以使用数据报首部中的几个不同域的值执行转发和

    2024年02月09日
    浏览(15)
  • vscode折叠代码展开快捷键

    vscode折叠代码展开快捷键

    1.折叠所有代码 (按住ctrl 分别点击k和0) ctrl+k,ctrl+0 2.展开所有代码 (按住ctrl 分别点击k和j) ctrl+k,ctrl+j 3. 折叠鼠标竖线所在位置的节点以及当前节点下的子节点(递归折叠) ctrl+k,ctrl+[ 4. 展开鼠标竖线所在位置的节点以及当前节点下的子节点(递归展开) ctrl+k,ctrl+] 5.折叠除所

    2024年02月11日
    浏览(8)
  • 计算机网络|第四章:网络层:数据平面

    计算机网络|第四章:网络层:数据平面

    前文回顾 :第三章:传输层 运输层依赖于网络层的主机到主机的通信服务,提供各种形式的进程到进程的通信。 网络层与传输层和应用层不同的是, 在网络中的每一台主机和路由器中都有一个网络层部分 。正因如此,网络层协议是协议栈中最具挑战性的部分。 网络层分为

    2024年02月12日
    浏览(10)
  • 利用python计算两个平面相交直线的方向向量

    利用python计算两个平面相交直线的方向向量

    利用两平面的法向量做”叉乘“运算获得两平面交线的方向向量。 如图所示,两平面相交关系为: 图中 n 1 ⃗ vec{n_1} n 1 ​ ​ 为平面1的法向量, n 2 ⃗ vec{n_2} n 2 ​ ​ 为平面2的法向量, l ⃗ vec{l} l 为两平面交线的方向向量。根据丘维声所著《解析几何(第三版)》第3

    2024年02月05日
    浏览(11)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包