平面波法-简单立方能带计算

平面波法公式

其中 $\mathbf{k}$ 为第一布里渊区内的点, $\mathbf{K_n}$ 为整数倍倒格矢。求解该方程需要选择合适的平面波截断维数以及势能的傅里叶级数展开数,以保证在计算效率。

势能处理

简单立方元胞内,势能

其中

对势能进行傅里叶级数展开并离散化得到

由此可利用FFT处理势能。

具体代码如下

自由哈密顿量与相互作用哈密顿量的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import numpy as np
import matplotlib.pyplot as plt
import scipy.integrate as inte
import scipy.fft as scifft
import scipy.linalg as lin
def H_3D(k1,k2,k3,a,N):
H_3d=np.zeros([2*N-1,2*N-1,2*N-1,2*N-1,2*N-1,2*N-1])
V_3d=np.zeros([2*N-1,2*N-1,2*N-1,2*N-1,2*N-1,2*N-1])
G=2*np.pi/a
for i in range(0,2*N-1):
for j in range(0,2*N-1):
for k in range(0,2*N-1):
H_3d[i,j,k,i,j,k]=(k3+(i-N+1)*G)**2+(k2+(j-N+1)*G)**2+(k1+(k-N+1)*G)**2
#H_gra[i,j,i,j]=(k1+np.abs(i-N-1))**2*b1@b1+(k2+np.abs(j-N-1))**2*b2@b2

return 0.05*H_3d.reshape((2*N-1)*(2*N-1)*(2*N-1),(2*N-1)*(2*N-1)*(2*N-1))

def HV3d(V_3df,N):
VN=len(V_3df)

V_3d=np.zeros([2*N-1,2*N-1,2*N-1,2*N-1,2*N-1,2*N-1])
for i in range(2*N-1):
for j in range(2*N-1):
for k in range(2*N-1):
for l in range(2*N-1):
for m in range(2*N-1):
for n in range(2*N-1):
if (np.abs(i-l)>VN-1)or(np.abs(j-m)>VN-1)or(np.abs(k-n)>VN-1):
continue
else:
V_3d[i,j,k,l,m,n]=V_3df[np.abs(i-l),np.abs(j-m),np.abs(k-n)]
return V_3d.reshape((2*N-1)*(2*N-1)*(2*N-1),(2*N-1)*(2*N-1)*(2*N-1))

势能

1
2
3
4
5
6
7
8
9
def V3dcubic(N,a):
epsilon=0.05*a
x=np.linspace(0,1,N)
V=np.zeros([N,N,N])
for i in range(N):
for j in range(N):
for k in range(N):
V[i,j,k]=1/(epsilon+np.sqrt(x[i]**2+x[j]**2+x[k]**2))+1/(epsilon+np.sqrt((x[i]-a)**2+x[j]**2+x[k]**2))+1/(epsilon+np.sqrt((x[i]-a)**2+(x[j]-a)**2+x[k]**2))+1/(epsilon+np.sqrt((x[i]-a)**2+(x[j]-a)**2+(x[k]-a)**2))+1/(epsilon+np.sqrt((x[i]-a)**2+(x[j])**2+(x[k]-a)**2))+1/(epsilon+np.sqrt((x[i])**2+(x[j])**2+(x[k]-a)**2))+1/(epsilon+np.sqrt((x[i])**2+(x[j]-a)**2+(x[k])**2))+1/(epsilon+np.sqrt((x[i])**2+(x[j]-a)**2+(x[k]-a)**2))
return V

由于势函数关于中心对称,故只需要傅里叶展开系数的实部

1
2
3
4
5
6
a=1
n=15
l=2*n+1
V3d=V3dcubic(l,a)
V_3df=scifft.fftn(V3d)/(l**3)
V_3df=np.round(V_3df[:n,:n,:n],5).real

沿着高对称性路径扫描

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
a=1
n=50
ln=2*n+1
V3d=V3dcubic(l,a)
V_3df=scifft.fftn(V3d)/(l**3)
V_3df=V_3df[:20,:20,:20]
N=5
E1=[]
E2=[]
E3=[]
E4=[]
e1=np.array([np.pi,0,0])
e2=np.array([0,np.pi,0])
e3=np.array([0,0,np.pi])
lam=np.arange(0,ln,3)/ln
#Gamma to X
for i in range(len(lam)):
k=lam[i]*e1
w,v=lin.eigh(H_3D(k[0],k[1],k[2],a,N)+HV3d(V_3df.real,N))
E1.append(w)
#X to M
for i in range(len(lam)):
k=lam[i]*e2+e1
w,v=lin.eigh(H_3D(k[0],k[1],k[2],a,N)+HV3d(V_3df.real,N))
E2.append(w)
#M to R
for i in range(len(lam)):
k=lam[i]*e3+e2+e1
w,v=lin.eigh(H_3D(k[0],k[1],k[2],a,N)+HV3d(V_3df.real,N))
E3.append(w)
#R to Gamma
for i in range(len(lam)):
k=lam[::-1][i]*(e3+e2+e1)
w,v=lin.eigh(H_3D(k[0],k[1],k[2],a,N)+HV3d(V_3df.real,N))
E4.append(w)