
笼目晶格

图1 笼目晶格
笼目晶格的基元由三个不等价的原子(A、B、C)构成,三个原子排列成一个三角形。基元按照三角晶格的方式进行排列,紧束缚近似下哈密顿量为
和为子晶格(A、B、C)指标,表示仅考虑最近邻原子间的跃迁,每个原子由四个最近邻原子
最近邻原子间距为,则有,对于B和C原子类似。
通过傅里叶变换可以得到动量空间中的哈密顿量为:
其中,通过对角化求得能带函数为:
态密度为:
基元与基元按照三角晶格的方式进行排列,则该点阵的实空间基矢可取为
由公式,可以求得动量空间的基矢为,取,
则有,因此可以得到三角晶格的第一布里渊区为一个正六边形,同时和能带一起绘制出来,如下图

图2 三维能带(左),E2俯视图(中),E3俯视图(右)

图3 能带(左)和态密度(右)
附:
【哈密顿量的傅里叶变换过程】
傅里叶变换公式,参见《固体理论》--李正中
哈密顿量傅里叶变换
其中,3*3矩阵对角化求能带函数
因此本征值为
其中
解方程过程中还用到了下面关系式
非通用公式,仅在时成立
关系式推导:
【代码】
能带、费米面图像绘制
import time
import numpy as np
import numba as nb
import matplotlib.pyplot as plt
from cmath import nan
from matplotlib import rcParams, colors
# 全局设置字体及大小,设置公式字体即可,若要修改刻度字体,可在此修改全局字体
config = {
"mathtext.fontset":'stix',
"font.family":'serif',
"font.serif": ['SimSun'], #字体设置
"font.size": 14, # 字号,大家自行调节
'axes.unicode_minus': False # 处理负号,即-号
}
rcParams.update(config)
def main3d(): #负责绘制三张图,三维能带及其俯视图,费米面
a0=1; kn=1000; dim=np.shape(h0k(0,0))[0]
evas=np.zeros((dim,kn,kn)); evas0=np.zeros((dim,kn,kn))
kx=np.linspace(-np.pi/(np.sqrt(3)*a0)-0.1, np.pi/(np.sqrt(3)*a0)+0.1, kn)
ky=np.linspace(-2*np.pi/(3*a0)-0.1, 2*np.pi/(3*a0)+0.1, kn)
x0=np.pi/(np.sqrt(3)*a0); y0=np.pi/(3*a0); k=np.sqrt(3)/3; b=2*np.pi/(3*a0)
for nx in range(kn):
for ny in range(kn):
eva,evc = np.linalg.eig(h0k(kx[nx],ky[ny]))
if (-x0<=kx[nx]<=x0 and -y0<=ky[ny]<=y0) or \
(ky[ny]<-y0 and ky[ny]>(-k*kx[nx]-b) and ky[ny]>(k*kx[nx]-b) or \
(ky[ny]>y0 and ky[ny]<(k*kx[nx]+b) and ky[ny]<(-k*kx[nx]+b))):
evas[:,ny,nx] = np.sort(np.real(eva)) #1、2、3对应NN、NNN、TNN配对
else:
evas[:,ny,nx]=nan
evas0[:,ny,nx] = np.sort(np.real(eva))
X,Y = np.meshgrid(kx,ky)
fig1 = plt.figure(); ax1 = plt.axes(projection='3d') #三维能带
vmin=np.min(evas0); vmax=np.max(evas0)
norm=colors.Normalize(vmin=vmin, vmax=vmax)
for i in range(dim):
ax1.plot_surface(X,Y,evas[i,:,:],rstride=10,cstride=10,norm=norm,cmap='jet')
ax1.set_xlabel(r'$k_x$');ax1.set_ylabel(r'$k_y$');ax1.set_zlabel(r'$E(\mathrm{k})$')
ax1.set_xticks([-np.pi/np.sqrt(3), -0.5*np.pi/np.sqrt(3), 0, 0.5*np.pi/np.sqrt(3), np.pi/np.sqrt(3)])
ax1.set_xticklabels([r'$-\frac{\pi}{\sqrt{3}}$',r'$-\frac{\pi}{2\sqrt{3}}$','0',r'$\frac{\pi}{2\sqrt{3}}$',r'$\frac{\pi}{\sqrt{3}}$'])
ax1.set_yticks([-2*np.pi/3, -np.pi/3, 0, np.pi/3, 2*np.pi/3])
ax1.set_yticklabels([r'$-\frac{2\pi}{3}$',r'$-\frac{\pi}{3}$','0',r'$\frac{\pi}{3}$',r'$\frac{2\pi}{3}$'])
# ax1.view_init(elev=90,azim=-90)
zmin = np.min(evas0); zmax = np.max(evas0);
fig2, ax2 = plt.subplots() #三维能带俯视图
fig2.subplots_adjust(top=0.98,bottom=0.15,left=0.15,right=0.9)
levels = np.linspace(zmin,zmax,100)
sf2 = ax2.contourf(X,Y,evas0[0,:,:],levels=levels,cmap='jet')
ax2.set_xlabel(r'$k_x$');ax2.set_ylabel(r'$k_y$')
ax2.set_xticks([-np.pi/np.sqrt(3), -0.5*np.pi/np.sqrt(3), 0, 0.5*np.pi/np.sqrt(3), np.pi/np.sqrt(3)])
ax2.set_xticklabels([r'$-\frac{\pi}{\sqrt{3}}$',r'$-\frac{\pi}{2\sqrt{3}}$','0',r'$\frac{\pi}{2\sqrt{3}}$',r'$\frac{\pi}{\sqrt{3}}$'])
ax2.set_yticks([-2*np.pi/3, -np.pi/3, 0, np.pi/3, 2*np.pi/3])
ax2.set_yticklabels([r'$-\frac{2\pi}{3}$',r'$-\frac{\pi}{3}$','0',r'$\frac{\pi}{3}$',r'$\frac{2\pi}{3}$'])
cb2 = fig2.colorbar(sf2,pad=0.01)
cb2.set_ticks(np.linspace(zmin,zmax,5)); cb2.update_ticks()
fig3, ax3 = plt.subplots() #三维能带俯视图
fig3.subplots_adjust(top=0.98,bottom=0.15,left=0.15,right=0.9)
levels = np.linspace(zmin,zmax,100)
sf3 = ax3.contourf(X,Y,evas0[1,:,:],levels=levels,cmap='jet')
ax3.set_xlabel(r'$k_x$');ax3.set_ylabel(r'$k_y$')
ax3.set_xticks([-np.pi/np.sqrt(3), -0.5*np.pi/np.sqrt(3), 0, 0.5*np.pi/np.sqrt(3), np.pi/np.sqrt(3)])
ax3.set_xticklabels([r'$-\frac{\pi}{\sqrt{3}}$',r'$-\frac{\pi}{2\sqrt{3}}$','0',r'$\frac{\pi}{2\sqrt{3}}$',r'$\frac{\pi}{\sqrt{3}}$'])
ax3.set_yticks([-2*np.pi/3, -np.pi/3, 0, np.pi/3, 2*np.pi/3])
ax3.set_yticklabels([r'$-\frac{2\pi}{3}$',r'$-\frac{\pi}{3}$','0',r'$\frac{\pi}{3}$',r'$\frac{2\pi}{3}$'])
cb3 = fig3.colorbar(sf3,pad=0.01)
cb3.set_ticks(np.linspace(zmin,zmax,5)); cb3.update_ticks()
b1=[-np.pi/(np.sqrt(3)*a0),-np.pi/(3*a0)]; b2=[0,-2*np.pi/(3*a0)]; b3=[np.pi/(np.sqrt(3)*a0),-np.pi/(3*a0)]
b4=[np.pi/(np.sqrt(3)*a0),np.pi/(3*a0)]; b5=[0,2*np.pi/(3*a0)]; b6=[-np.pi/(np.sqrt(3)*a0),np.pi/(3*a0)]
x1=np.linspace(b1[0],b2[0],5); y1=np.linspace(b1[1],b2[1],5)
x2=np.linspace(b2[0],b3[0],5); y2=np.linspace(b2[1],b3[1],5)
x3=np.linspace(b3[0],b4[0],5); y3=np.linspace(b3[1],b4[1],5)
x4=np.linspace(b4[0],b5[0],5); y4=np.linspace(b4[1],b5[1],5)
x5=np.linspace(b5[0],b6[0],5); y5=np.linspace(b5[1],b6[1],5)
x6=np.linspace(b6[0],b1[0],5); y6=np.linspace(b6[1],b1[1],5)
ax2.plot(x1,y1,c='k');ax2.plot(x2,y2,c='k');ax2.plot(x3,y3,c='k');
ax2.plot(x4,y4,c='k');ax2.plot(x5,y5,c='k');ax2.plot(x6,y6,c='k');
ax3.plot(x1,y1,c='k');ax3.plot(x2,y2,c='k');ax3.plot(x3,y3,c='k');
ax3.plot(x4,y4,c='k');ax3.plot(x5,y5,c='k');ax3.plot(x6,y6,c='k');
gam=[0,0]; M=[np.pi/(np.sqrt(3)*a0),0]; K=[np.pi/(np.sqrt(3)*a0),np.pi/(3*a0)]
x5=np.linspace(gam[0],K[0],5); y5=np.linspace(gam[1],K[1],5)
x6=np.linspace(K[0],M[0],5); y6=np.linspace(K[1],M[1],5)
x7=np.linspace(M[0],gam[0],5); y7=np.linspace(M[1],gam[1],5)
ax2.plot(x5,y5,c='k');ax2.plot(x6,y6,c='k');ax2.plot(x7,y7,c='k');
ax3.plot(x5,y5,c='k');ax3.plot(x6,y6,c='k');ax3.plot(x7,y7,c='k');
xd=[gam[0],M[0],K[0]]; yd=[gam[1],M[1],K[1]]
ax2.scatter(xd,yd,c='k'); ax2.text(0,-0.35,r'$\Gamma(0,0)$');
ax2.text(np.pi/3,0.1,r'$M(\frac{\pi}{\sqrt{3}},0)$')
ax2.text(np.pi/3,2*np.pi/(3*np.sqrt(3)),r'$K(\frac{\pi}{\sqrt{3}},\frac{\pi}{3})$')
ax3.scatter(xd,yd,c='k'); ax3.text(0,-0.35,r'$\Gamma(0,0)$');
ax3.text(np.pi/3,0.1,r'$M(\frac{\pi}{\sqrt{3}},0)$')
ax3.text(np.pi/3,2*np.pi/(3*np.sqrt(3)),r'$K(\frac{\pi}{\sqrt{3}},\frac{\pi}{3})$')
def mainhp():
gam=[0,0]; M=[np.pi/np.sqrt(3),0]; K=[np.pi/np.sqrt(3), np.pi/3]
kn1=1732; kn2=1000; kn3=2000; totkn=kn1+kn2+kn3
kx=np.zeros(totkn); ky=np.zeros(totkn);
dim=np.shape(h0k(0,0))[0]; evas=np.zeros((dim,totkn))
#Gamma-M
kx[0:kn1] = np.linspace(gam[0],M[0],kn1)
ky[0:kn1] = np.linspace(gam[1],M[1],kn1)
#M-K
kx[kn1:kn1+kn2] = np.linspace(M[0],K[0],kn2)
ky[kn1:kn1+kn2] = np.linspace(M[1],K[1],kn2)
#K-Gamma
kx[kn1+kn2:totkn] = np.linspace(K[0],gam[0],kn3)
ky[kn1+kn2:totkn] = np.linspace(K[1],gam[1],kn3)
for i in range(totkn):
eva, evc = np.linalg.eig(h0k(kx[i],ky[i]))
evas[:,i] = np.sort(np.real(eva))
fig,ax = plt.subplots()
for i in range(dim):
ax.plot(range(totkn),evas[i,:],c='r')
ax.set_ylabel(r'$E(k)$')
ax.set_xticks([0,kn1,kn1+kn2,totkn])
ax.set_xticklabels([r'$\Gamma(0,0)$',r'$M(\frac{\pi}{\sqrt{3}},0)$',r'$K(\frac{\pi}{\sqrt{3}},\frac{\pi}{3})$',r'$\Gamma(0,0)$'])
ax.set_xlim(0,totkn)
ymin=np.min(evas); ymax=np.max(evas);
ax.set_ylim(ymin,ymax+0.2)
plt.axhline(y=0,ls='--',c='k')
plt.axhline(y=-2,ls='--',c='k')
plt.axvline(x=kn1,ls='--',c='k')
plt.axvline(x=kn1+kn2,ls='--',c='k')
@nb.jit
def h0k(kx,ky):
a0=1; t=1; h0=np.zeros((3,3))+0j
k1=0.5*a0*np.sqrt(3)*kx+0.5*a0*ky; k3=a0*ky
k2=0.5*a0*np.sqrt(3)*kx-0.5*a0*ky
h0[0,1]=-2*t*np.cos(k1); h0[0,2]=-2*t*np.cos(k2); h0[1,2]=-2*t*np.cos(k3)
h0 = h0+np.transpose(np.conj(h0))
return h0
if __name__ == "__main__":
ts = time.time()
main3d()
td = time.time()
print('用时:'+ str((td-ts)//60) + '分' + str((td-ts)%60) + '秒。')
态密度图像绘制
import time
import numpy as np
import numba as nb
import matplotlib.pyplot as plt
import multiprocessing as mp
from matplotlib import rcParams
# 全局设置字体及大小,设置公式字体即可,若要修改刻度字体,可在此修改全局字体
config = {
"mathtext.fontset":'stix',
"font.family":'serif',
"font.serif": ['SimSun'], #字体设置
"font.size": 14, # 字号,大家自行调节
'axes.unicode_minus': False # 处理负号,即-号
}
rcParams.update(config)
def main():
a0=1; kn=3000; en=500; dim=np.shape(h0k(0,0))[0]
kx=np.linspace(-np.pi/(np.sqrt(3)*a0), np.pi/(np.sqrt(3)*a0), kn)
ky=np.linspace(0, -np.pi, kn)
evas=np.zeros((dim,kn,kn))
for nx in range(kn):
for ny in range(kn):
eva,evc = np.linalg.eig(h0k(kx[nx],ky[ny]))
evas[:,ny,nx] = np.sort(np.real(eva))
emax=np.max(evas); emin=np.min(evas)
ex = np.linspace(emin-0.5,emax+0.5,en)
cpun=4; pn=int(en/cpun); rem=en%cpun
if rem != 0:
cpun = cpun+1
pool = mp.Pool(cpun)
res = []
for i in range(cpun):
if i==cpun-1 and rem!=0:
a = pool.apply_async(dos, [ex,evas,i*pn,i*pn+rem])
else:
a = pool.apply_async(dos, [ex,evas,i*pn,(i+1)*pn])
res.append(a)
pool.close(); pool.join()
rhos = [res[i].get() for i in range(cpun)]
rhok = np.concatenate((rhos),axis=-1)
fig, ax = plt.subplots()
plt.subplots_adjust(top=0.9,bottom=0.14,left=0.14,right=0.9)
ax.plot(rhok,ex,c='k')
ax.set_xlabel(r'$\rho(\omega)$'); ax.set_ylabel(r'$\omega$')
ax.set_ylim(emin-0.5,emax+0.5)
ax.set_xlim(0,3)
# plt.legend(frameon=False)
@nb.jit
def dos(ex,evas,n1,n2):
gam=0.0005;kn=evas.shape[1]
rhok=np.zeros((n2-n1)); dim=np.shape(h0k(0,0))[0]
n=0
for i in range(n1,n2):
sumk=0
for j in range(kn):
for d in range(kn):
for g in range(dim):
sumk = sumk + gam/((ex[i]-evas[g,d,j])**2+gam**2)
rhok[n] = sumk/(kn*kn*np.pi)
n=n+1
return rhok
@nb.jit
def h0k(kx,ky):
a0=1; t=1; h0=np.zeros((3,3))+0j
k1=0.5*a0*np.sqrt(3)*kx+0.5*a0*ky; k3=a0*ky
k2=0.5*a0*np.sqrt(3)*kx-0.5*a0*ky
h0[0,1]=-2*t*np.cos(k1); h0[0,2]=-2*t*np.cos(k2); h0[1,2]=-2*t*np.cos(k3)
h0 = h0+np.transpose(np.conj(h0))
return h0
if __name__ == "__main__":
ts = time.time()
main()
td = time.time()
print('用时:'+ str((td-ts)//60) + '分' + str((td-ts)%60) + '秒。')