单层石墨烯能带图。方法一用+表示 ,方法2红色实线表示
(1)根据原胞构建哈密顿
%%Nie-Wei Wang,2024-1-8 (分解版,有基础)
clear all
%%%%%%%%晶格矢量 正格矢量
a1=[2.4682263781246880 0.0000000000000000 0.0000000000000000];
a2=[-1.2341131890623440 2.1375467457960933 0.0000000000000000];
a3=[0.0000000000000000 0.0000000000000000 10.0000000000000000];
% C1=[0.0000018561517373 -0.0000018561604471 0.5000000000000000];
% C2=[0.6666682727452335 0.3333317562640553 0.5000000000000000];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
V=dot(a1,cross(a2,a3));% %%%晶胞体积
b1=2*pi*cross(a2,a3)/V; %%%%倒格矢量
b2=2*pi*cross(a3,a1)/V;
b3=2*pi*cross(a1,a2)/V;
a1=a1(1:2); %晶格矢量a1 二维
a2=a2(1:2); %晶格矢量a2
b1=b1(1:2); %%%倒空间晶格矢量b1,二维
b2=b2(1:2); %%%倒格矢b2
gamma=[0 0]; %%%高对称点gamma
M=1/2*b1; %%%高对称点M
K=1/3*b1+1/3*b2; %%%高对称点K
kn=20; %两个高对称点之间分成有kn个点
% Gamma-M段 每个高对称点都有两个 150和151都是M点
kx(1:kn)=linspace(gamma(1),M(1),kn);
ky(1:kn)=linspace(gamma(2),M(2),kn);
% M-K段
kx(kn+1:2*kn)=linspace(M(1),K(1),kn);
ky(kn+1:2*kn)=linspace(M(2),K(2),kn);
% K-Gamma段
kx(2*kn+1:3*kn)=linspace(K(1),0,kn);
ky(2*kn+1:3*kn)=linspace(K(2),0,kn);
k=zeros(3*kn,2);
k(:,1)=kx; %%存储kx
k(:,2)=ky;
Nw=2; %%%%能带条数需要修改
k_new=zeros(1,3*kn); %%%为了沿着高对称点画出能带需要将k做调整,按照路径的模长走
energy=zeros(Nw,kn); %%存放本征值
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i = 1:3*kn %%%%高对称路径
if i<=kn
kv=[kx(i)-gamma(1),ky(i)-gamma(2)];
k_new(i)=norm(kv); %gamma->M
elseif i>kn && i<=2*kn
kv=[kx(i)-M(1),ky(i)-M(2)];
k_new(i)=norm(M-gamma)+norm(kv); %M->K
else
kv=[kx(i)-K(1),ky(i)-K(2)];
k_new(i)=norm(kv)+norm(M-gamma)+norm(K-M); %%%K->gamma
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%路径不要动
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
efermi=0;
e1=-0.91;
e2=e1;
t1=2.877065; %跃迁积分
t2=0.235328;
t3=0.227017;
Nw=2; %两条能带
h0=[e1,t1;t1,e2];
h1=[0,t1;0 0];
h2=[t3,0;0,t3];
%%%%%%%%%%%%%%%%最近邻
R1=a1;
R2=a1+a2;
R3=a2;
R4=-a1;
R5=-(a1+a2);
R6=-a2;
R7=-a2-2*a1;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%k=[k(1,:);k(kn,:);k(2*kn,:)];
for i = 1:3*kn
%%%%%%%%%%%%%%%normal
%最近邻hR4,hR5 12
%次近邻 hR1-6 11
%三近邻 hR3 hR7 hR6 12
hNN=(exp(1i*dot(k(i,:),R4))...
+exp(1i*dot(k(i,:),R5)))*t1; %%12
h2NN=(exp(1i*dot(k(i,:),R1))...
+exp(1i*dot(k(i,:),R2))...
+exp(1i*dot(k(i,:),R3))...
+exp(1i*dot(k(i,:),R4))...
+exp(1i*dot(k(i,:),R5))...
+exp(1i*dot(k(i,:),R6)))*t2; %%11
h3NN=(exp(1i*dot(k(i,:),R3))...
+exp(1i*dot(k(i,:),R6))...
+exp(1i*dot(k(i,:),R7)))*t3; %%11
h=hNN+h3NN;
hsum=h0+[0,h;h',0]+[h2NN,0;0,h2NN];
[V,D] = eig(hsum); %%%计算 A 的特征值D和右特征向量。%https://ww2.mathworks.cn/help/matlab/ref/eig.html
[d,ind]=sort(diag(real(D)));%使用 diag(D) 从 D 的对角线上提取特征值,然后按升序对得到的向量进行排序。
% sort 的第二个输出返回索引的置换向量。
Vs = V(:,ind); %%%对本征矢量进行排序,本征值是一列一列的。
Ds = D(ind,ind); %使用 ind 对 D 的对角线元素进行重新排序。
% 由于 D 中的特征值对应于 V 的各列中的特征向量,因此您还必须使用相同的索引对 V 的列进行重新排序。
energy(:,i)=d;
end
%%%%%%%plot 画图
hold on
for m=1:Nw %%% 原胞中有几个轨道就有几条能带
plot(k_new,energy(m,:)-efermi,'blue','LineWidth',1) %%
hold on
end
%%%%设置xticks布里渊区高对称点
xticks([k_new(1) k_new(kn+1) k_new(2*kn+1) k_new(3*kn)]);
xticklabels({'\Gamma','M','K','\Gamma'})
%%%辅助线
xline(k_new(kn+1),'--');
xline(k_new(2*kn+1),'--');
yline(0,'--');
%grid on
%%%
xlim([k_new(1) k_new(3*kn)])
ylim([-10,15])
ylabel("Energy")
box on
(2) 第二种:matlab 后处理 wannier_hr.dat 。
%%%2023/4/18_wnw_hebust
% $$\begin{aligned}
% h(\vec{k})=\sum_mH_{nm}\text{e}^{\text{i}\vec{k}\cdot(\vec{d}_m-\vec{d}_n)}
% \end{aligned}$$
clear all
efermi=0; %费米能 在求解能带时grep fermi OUTCAR
%在POSCAR 读取晶格矢量a1,a2,a3
a1=[2.4682263781246880 0.0000000000000000 0.0000000000000000];
a2=[-1.2341131890623440 2.1375467457960933 0.0000000000000000];
a3=[0.0000000000000000 0.0000000000000000 10.0000000000000000];
b1=2*pi*cross(a2,a3)/dot(a1,cross(a2,a3)); %%%倒空间晶格矢量b1,三维
b2=2*pi*cross(a3,a1)/dot(a2,cross(a3,a1)); %%%倒格矢b2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 正格矢和倒格矢由三维变成二维
a1=a1(1:2); %晶格矢量a1 二维
a2=a2(1:2); %晶格矢量a2
b1=b1(1:2); %%%倒空间晶格矢量b1,二维
b2=b2(1:2); %%%倒格矢b2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
gamma=[0,0]; %%%高对称点gamma
M=1/2*b1; %%%高对称点M
K=1/3*b1+1/3*b2; %%%高对称点K
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
kn=20; %两个高对称点之间分成有kn个点
% Gamma-M段 每个高对称点都有两个 150和151都是M点
kx(1:kn)=linspace(gamma(1),M(1),kn);
ky(1:kn)=linspace(gamma(2),M(2),kn);
% M-K段
kx(kn+1:2*kn)=linspace(M(1),K(1),kn);
ky(kn+1:2*kn)=linspace(M(2),K(2),kn);
% K-Gamma段
kx(2*kn+1:3*kn)=linspace(K(1),0,kn);
ky(2*kn+1:3*kn)=linspace(K(2),0,kn);
k=zeros(3*kn,2);
k(:,1)=kx; %%存储kx
k(:,2)=ky; %%存储ky
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%读取'wannier90_hr.dat'文件
S = importdata('wannier90_hr.dat'); %将wannier90_hr.dat放入此代码的同一文件夹内
Data = S.data; %按照7个为一组进行排列,竖排。
Nw = Data(1); %num_wannier=22
Data(1) = []; %这个命令表示从数组Data中删除第一个元素。
Nrpts = Data(1); %共取了331个R点,存在简并
Data(1) = []; %这个命令表示从数组Data中删除第一个元素。
Ndegen = Data(1:Nrpts)'; %提取每个R点的简并
Data(1:Nrpts)=[]; %将每个R点的简并值删掉
H = reshape(Data,7,[])'; % 则 reshape(A,2,2,[]) 将 Data 重构为一个 [[],7] 的数组
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
k_new=zeros(1,3*kn); %%%为了沿着高对称点画出能带需要将k做调整,按照路径的模长走
energy=zeros(Nw,kn); %%存放本征值
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i = 1:3*kn
if i<=kn
kv=[kx(i)-gamma(1),ky(i)-gamma(2)];
k_new(i)=norm(kv); %gamma->M
elseif i>kn && i<=2*kn
kv=[kx(i)-M(1),ky(i)-M(2)];
k_new(i)=norm(M-gamma)+norm(kv); %M->K
else
kv=[kx(i)-K(1),ky(i)-K(2)];
k_new(i)=norm(kv)+norm(M-gamma)+norm(K-M); %%%K->gamma
end
h=zeros(Nw);
%%%%%%%%%%%%%%a1,a2,a3的系数范围R=l*a1+m*a2+n*a3,n3=0;
for ii=1:Nw^2:length(H(:,1)) %%H的行数
l=H(ii,1); %第一列l
m=H(ii,2); %第2列m
temp= find(H(:,1)==l & H(:,2)==m); %%%查找符合的行号l,m,n==0;
Htemp= H(min(temp):max(temp),:); %%%将符合的行写入临时变量Htemp
Htemp(:,6:7)=Htemp(:,6:7)/Ndegen(max(temp)/Nw^2);%%%将hoping项除以R的简并数
Hmat = reshape(Htemp(:,6),[Nw,Nw]); %将每个R点的hopping 实步改成num_wannier^2的矩阵
%%只考虑最近邻
for i1=1:Nw
for i2=1:Nw
if abs(Hmat(i1,i2))<0.22
Hmat(i1,i2)=0;
end
end
end
h=h+exp(1i*dot(k(i,:),(l*a1+m*a2)))*Hmat; %倒空间的哈密顿量表示
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[V,D] = eig(h); %%%计算 A 的特征值D和右特征向量。%https://ww2.mathworks.cn/help/matlab/ref/eig.html
[d,ind]=sort(diag(real(D)));%使用 diag(D) 从 D 的对角线上提取特征值,然后按升序对得到的向量进行排序。
% sort 的第二个输出返回索引的置换向量。
Vs = V(:,ind); %%%对本征矢量进行排序,本征值是一列一列的。
Ds = D(ind,ind); %使用 ind 对 D 的对角线元素进行重新排序。
% 由于 D 中的特征值对应于 V 的各列中的特征向量,因此您还必须使用相同的索引对 V 的列进行重新排序。
energy(:,i)=d;
end
%%%%%%%plot 画图
for m=1:Nw %%% 原胞中有几个轨道就有几条能带
plot(k_new,energy(m,:)-efermi,'color','r','LineWidth',1) %%
hold on
end
%%%%设置xticks布里渊区高对称点
xticks([k_new(1) k_new(kn+1) k_new(2*kn+1) k_new(3*kn)]);
xticklabels({'\Gamma','M','K','\Gamma'})
%%%辅助线
xline(k_new(kn+1),'--');
xline(k_new(2*kn+1),'--');
yline(0,'--');
%grid on
%%%
xlim([k_new(1) k_new(3*kn)])
ylim([-10,15])
ylabel("Energy")
box on
补充:DFT 计算结果和wannier90的对比 方法:一文搞定VASP+wannier90构造紧束缚模型一文搞定VASP+wannier90构造紧束缚模型 - 知乎
补充
#检查wannier90.wout的坐标时可能和POSCAR中的不一样,wannier90自动发现对称性了,选了另一种原子。按照右边那个原胞看wannier90hr.dat。(笔记)我用的晶体规范,没考虑原子坐标,上面结果没影响。