載流子遷移率通常指半導體內部電子和空穴整體的運動快慢情況,是衡量半導體器件性能的重要物理量。2004年,石墨烯的成功剝離引起了研究人員對於二維材料性質探索的濃厚興趣。石墨烯、黑磷等二維材料展現出的高載流子遷移率是其中的一個重要研究課題,科研人員在理論計算方面已經做了大量的工作。由於電子在運動過程中不僅受到外電場力的作用,還會不斷的與晶格、雜質、缺陷等發生無規則的碰撞,大大增加了理論計算的難度。
目前計算載流子遷移率比較常用的理論是形變勢理論和玻爾茲曼輸運理論,前者沒有考慮電子和聲子(晶格振動)以及電子與電子之間的相互作用等因素,計算結果存在一定的誤差,但筆者的計算結果與實驗值在數量級上是吻合的;玻爾茲曼輸運理論的一種計算考慮了電子-聲子的相互作用,基於第一性原理計算和最大局域化Wannier函數插值方法,藉助於Quantum-ESPRESSO和EPW軟體可以完成載流子遷移率計算。缺點是計算量太大,一般的課題組很難承受起高昂的計算費用,另外EPW軟體對於二維材料的計算存在部分問題,在其官方論壇也有討論,計算過程在後續文章中會提到。
本文以形變勢理論方法為基礎,詳細介紹了二維InSe的電子和空穴的有效質量與載流子遷移率的計算方法。
基於Bardeen和Shockley[1]提出的形變勢理論,二維材料載流子遷移率可以根據下式計算:
其中,m∗是傳輸方向上的有效質量,T是溫度,kB是玻爾茲曼常數。E1表示沿著傳輸方向上位於價帶頂(VBM)的空穴或聚於導帶底(CBM)的電子的形變勢常數,由公式E1=ΔE/(Δl/l0)確定,ΔE為在壓縮或拉伸應變下CBM或VBM 的能量變化,l0是傳輸方向上的晶格常數,Δl是l0的變形量。md是載流子的平均有效質量,由下面公式定義。
C2D是均勻變形晶體的彈性模量,對於2D材料,彈性模量可以通過下面公式來計算,
其中E是總能量,S0是優化後的面積。
下面對公式中的單位(量綱)做一個簡單換算,具體如下:
換算過程:
http://muchong.com/bbs/viewthread.php?tid=7149817&fpage=1
#! /usr/bin/python# This program reads in base vectors from a given file, calculates reciprocal vectors# then writes to outfile in different units# LinuxUsage: crecip.py infile outfile# Note: the infile must be in the form below:# inunit ang/bohr# _begin_vectors# 46.300000000 0.000000000 0.000000000# 0.000000000 40.500000000 0.000000000# 0.000000000 0.000000000 10.000000000# _end_vectors# # Note: LATTICE VECTORS ARE SPECIFIED IN ROWS !def GetInUnit( incontent ): inunit = "" for line in incontent: if line.find("inunit") == 0: inunit = line.split()[1] break return inunitdef GetVectors( incontent ): indstart = 0 indend = 0 for s in incontent: if s.find("_begin_vectors") != -1: indstart = incontent.index(s) else: if s.find("_end_vectors") != -1: indend = incontent.index(s) result = [] for i in range( indstart + 1, indend ): line = incontent[i].split() result.append( [ float(line[0]), float(line[1]), float(line[2]) ] ) return resultdef Ang2Bohr( LattVecAng ): LattVecBohr = LattVecAng for i in range(0,3): for j in range(0,3): LattVecBohr[i][j] = LattVecAng[i][j] * 1.8897261246 return LattVecBohrdef DotProduct( v1, v2 ): dotproduct = 0.0 for i in range(0,3): dotproduct = dotproduct + v1[i] * v2[i] return dotproductdef CrossProduct( v1, v2 ): # v3 = v1 WILL LEAD TO WRONG RESULT v3 = [] v3.append( v1[1] * v2[2] - v1[2] * v2[1] ) v3.append( v1[2] * v2[0] - v1[0] * v2[2] ) v3.append( v1[0] * v2[1] - v1[1] * v2[0] ) return v3def CalcRecVectors( lattvec ): pi = 3.141592653589793 a1 = lattvec[0] a2 = lattvec[1] a3 = lattvec[2] b1 = CrossProduct( a2, a3 ) b2 = CrossProduct( a3, a1 ) b3 = CrossProduct( a1, a2 ) volume = DotProduct( a1, CrossProduct( a2, a3 ) ) RecVec = [ b1, b2, b3 ] # it follows the definition for b_j: a_i * b_j = 2pi * delta(i,j) for i in range(0,3): for j in range(0,3): RecVec[i][j] = RecVec[i][j] * 2 * pi / volume return RecVec def main(argv = None): argv = sys.argv infilename = argv[1] outfilename = argv[2] pi = 3.141592653589793 bohr2ang = 0.5291772109253 ang2bohr = 1.889726124546 infile = open(infilename,"r") incontent = infile.readlines() infile.close() inunit = GetInUnit( incontent ) LattVectors = GetVectors( incontent ) # convert units from ang to bohr if inunit == "ang": LattVectors = Ang2Bohr( LattVectors ) # calculate reciprocal vectors in 1/bohr RecVectors = CalcRecVectors( LattVectors ) # open outfile for output ofile = open(outfilename,"w") # output lattice vectors in bohr ofile.write("lattice vectors in bohr:\n") for vi in LattVectors: ofile.write("%14.9f%14.9f%14.9f\n" % (vi[0], vi[1], vi[2])) ofile.write("\n") # output lattice vectors in ang convfac = bohr2ang ofile.write("lattice vectors in ang:\n") for vi in LattVectors: ofile.write("%14.9f%14.9f%14.9f\n" % (vi[0]*convfac, vi[1]*convfac, vi[2]*convfac)) ofile.write("\n") # output reciprocal vectors in 1/bohr ofile.write("reciprocal vectors in 1/bohr:\n") for vi in RecVectors: ofile.write("%14.9f%14.9f%14.9f\n" % (vi[0], vi[1], vi[2])) ofile.write("\n") # output reciprocal vectors in 1/ang convfac = ang2bohr ofile.write("reciprocal vectors in 1/ang:\n") for vi in RecVectors: ofile.write("%14.9f%14.9f%14.9f\n" % (vi[0]*convfac, vi[1]*convfac, vi[2]*convfac)) ofile.write("\n") # output reciprocal vectors in 2pi/bohr convfac = 1.0/(2.0*pi) ofile.write("reciprocal vectors in 2pi/bohr:\n") for vi in RecVectors: ofile.write("%14.9f%14.9f%14.9f\n" % (vi[0]*convfac, vi[1]*convfac, vi[2]*convfac)) ofile.write("\n") # output reciprocal vectors in 2pi/ang convfac = ang2bohr/(2.0*pi) ofile.write("reciprocal vectors in 2pi/ang:\n") for vi in RecVectors: ofile.write("%14.9f%14.9f%14.9f\n" % (vi[0]*convfac, vi[1]*convfac, vi[2]*convfac)) # close ofile.close() return 0if __name__ == "__main__": import sys sys.exit(main())4.1 建模
由於計算過程中需要對二維InSe施加應變,但二維InSe原胞是六角結構,不容易施加應變。但是侯柱峰老師講了對石墨烯原胞施加應變的方法,筆者認為雖然可行,但過於繁瑣,故不採用此法。我們可以利用根號建模的方法講六角結構InSe原胞變為方形結構的InSe超胞,然後施加應變可大大提高操作效率,但計算量的增加再可接受範圍之內。下面給出關鍵的建模步驟,更多的根號建模部分可參考我的往期博客文章。
切面並構建二維InSe原胞,同時調整晶格基矢,使其變為方形結構:
4.2 結構優化
INCAR
SYSTEM = InSe ISTART = 0 NWRITE = 2 PREC = AccurateENCUT = 500GGA = PE NSW = 200ISIF = 3 ISYM = 2 IBRION = 2 NELM = 80 EDIFF = 1E-05 EDIFFG = -0.01 ALGO = Normal LDIAG = .TRUE. LREAL = .FALSE. ISMEAR = 0 SIGMA = 0.05 ICHARG = 2LWAVE = .FALSE. LCHARG = .FALSE.NPAR = 4KPOINTS
Monkhorst Pack0Gamma11 7 1.0 .0 .0POSCAR
Se In1.000 4.083622259999999 -0.000000000000001 0.000000000000000 0.000000000000000 7.073041233239241 0.000000000000000 0.000000000000000 0.000000000000000 25.377516849029359Se In4 4Direct0.5000005000000000 0.1666665000000000 0.5271404971815050 !Se0.0000004999999997 0.6666665000000004 0.5271404971815050 !Se0.5000005000000000 0.1666665000000000 0.3152396685456632 !Se0.0000004999999997 0.6666665000000004 0.3152396685456632 !Se0.4999995000000003 0.8333335000000002 0.4767849697227853 !In-0.0000005000000000 0.3333335000000000 0.4767849697227853 !In0.4999995000000003 0.8333335000000002 0.3655951960043828 !In-0.0000005000000000 0.3333335000000000 0.3655951960043828 !InOPTCELL
POTCAR
cat Se/POTCAR In_d/POTCAR > POTCAR4.3 靜態自洽
INCAR
SYSTEM = InSe ISTART = 0 NWRITE = 2 PREC = AccurateENCUT = 500GGA = PE NSW = 0ISIF = 2 ISYM = 2 IBRION = -1 NELM = 80 EDIFF = 1E-05 EDIFFG = -0.01 ALGO = Normal LDIAG = .TRUE. LREAL = .FALSE. ISMEAR = 0 SIGMA = 0.05 ICHARG = 2NPAR = 4KPOINTS
Monkhorst Pack0Gamma21 13 1.0 .0 .0POSCAR
4.4 能帶計算
INCAR
SYSTEM = InSe ISTART = 1 NWRITE = 2 PREC = AccurateENCUT = 500GGA = PE NSW = 0ISIF = 2 ISYM = 2 IBRION = -1 NELM = 80 EDIFF = 1E-05 EDIFFG = -0.01 ALGO = Normal LDIAG = .TRUE. LREAL = .FALSE. ISMEAR = 0 SIGMA = 0.05 ICHARG = 2LORBIT = 11LWAVE = .FALSE. LCHARG = .FALSE.NPAR = 4
KPOINTS
k-points along high symmetry lines80Line-modeRec 0 0.5 0 !Y 0 0 0 !gamma
0 0 0 !gamma 0.5 0 0 !X
0.5 0 0 !X 0.5 0.5 0 !S
0.5 0.5 0 !S 0 0.5 0 !Y4.5 有效質量計算(有效質量詳細教程)
計算說明:對於包含了晶格周期性的有效質量的表達式如下所示:
在帶入物理量進行有效質量計算時,涉及單位制問題。一般寫輸入文件時,長度單位為Å;而程序輸出的能帶結構中,能量單位為eV,計算起來比較繁瑣。
原子單位制有兩種,一種為Hartree原子單位制,另一種為Rydberg單位制。這兩種單位制的區別在於,Hartree單位制下基本物理量簡單,電子電荷和質量都為1;而Rydberg單位制下薛丁格方程簡單,係數為1。Hartree單位制下,一個長度單位等於1Lbohr = 0.5292Å,一個能量單位1EHartree = 27.21eV,約化普朗克常數ℏ=1。這樣有效質量表達式中的約化普朗克常數就沒了。
將VASP計算band時的k點坐標(分數坐標)轉變為笛卡爾坐標:
4.6 求每個K點的位置值
根據VASP計算能帶時各高對稱點間均勻撒點,求出每個點的位置值,第一個點設為0,本例中為80個點,在excel中進行操作。
因計算時均勻撒點80個,故有79個小間隔,對於|YΓ|來說,每個小間隔為0.002975210683544,故1-80個點的坐標值都可算出,以此類推,後面的點的坐標在前面點的基礎上加上間隔即可(注意:在80個點結束處和81個點開始處的值是一樣的,後面的點類似)。
4.7 畫出價帶頂和導帶底的能帶
在origin中找出能帶數據的價帶頂(VBM)和導帶底(CBM)的數據,把上面計算得到的K點路徑做為X軸,VBM和CBM作為Y軸,在origin中畫圖如下:
4.8 計算有效質量(以x方向電子的有效質量為例)
首先換算能量單位,由eV換算為原子單位制下的能量CBM/27.21然後選取Γ-X方向上以Γ開始的4-8個點的數據畫能帶圖,如下:
有效質量為1/2C,其中C=2.69188,算得有效質量為0.19 ,為電子沿x方向的質量。文獻計算結果為0.19,符合一致。
本文載流子遷移率的計算依據的是形變勢理論,因此需要對二維InSe的x方向和y方向施加應變,施加應變的範圍是-2%~2%。為了計算的準確性,計算過程中考慮了泊松效應,即對x軸施加應變時,固定x軸和z軸,優化y方向的晶格常數;對y軸施加應變時,固定y軸和z軸,優化x方向的晶格常數。
5.1 準備輸入文件
首先建立mobility-x文件夾,然後在該文件夾下建立初始文件夾,命名為IS,其結構目錄如下:
$ tree mobilitymobility├── IS│ ├── 2_scf│ │ ├── band│ │ │ ├── INCAR│ │ │ ├── KPOINTS│ │ │ └── POTCAR│ │ ├── INCAR│ │ ├── KPOINTS│ │ └── POTCAR│ ├── INCAR│ ├── KPOINTS│ ├── OPTCELL│ ├── pbs│ ├── POSCAR│ └── POTCAR└── mobility.sh
說明:
#!/bin/bash#PBS -N mobility#PBS -l nodes=1:ppn=16#PBS -m abe#PBS -j n##PBS -o job.log##PBS -e job.err#PBS -l walltime=120:00:00cd $PBS_O_WORKDIRdate "+01 Today's date is: %D. The time execution %T" >> time.infompirun -np 16 /opt/soft/strainvasp5.4.4/vasp.5.4.4/build/std/vasp > logdate "+02 Today's date is: %D. The time finish %T" >> time.infocp ./CONTCAR ./2_scf/POSCARcd ./2_scf/date "+01 Today's date is: %D. The time execution %T" >> time.infompirun /opt/soft/strainvasp5.4.4/vasp.5.4.4/build/std/vasp > logdate "+02 Today's date is: %D. The time finish %T" >> time.infocp ./CONTCAR ./band/POSCARcp ./WAVECAR ./band/cd ./band/date "+01 Today's date is: %D. The time execution %T" >> time.infompirun -np 16 /opt/soft/strainvasp5.4.4/vasp.5.4.4/build/std/vasp > logdate "+02 Today's date is: %D. The time finish %T" >> time.infoX方向
Y方向
#!/bin/bash#3 November, 2018#To use it: bash mobility.shmkdir mobility-xcd mobility-xx=4.083622259999999 #"x" stands for the lattice constant in x directionfor i in $(seq 0.98 0.005 1.02) #"i" defines the range of straindocp -r ../IS ./$i #"IS" stands for the origin file sed -i "3s/$x/$(echo "$x*$i"|bc)/g" $i/POSCARcd $i#qsub ./pbscd $OLDPWDdonecd ../mkdir mobility-ycd mobility-yy=7.073041233239241 #"y" stands for the lattice constant in y directionfor j in $(seq 0.98 0.005 1.02) #"j" defines the range of straindocp -r ../IS ./$j #"IS" stands for the origin file sed -i "4s/$y/$(echo "$y*$j"|bc)/g" $j/POSCARcd $j#qsub ./pbscd $OLDPWDdoneNote:計算過程中需要根據自己的體系修改x和y方向的晶格常數值
其餘文件與前面計算能帶過程的輸入文件相同,在mobility文件夾下輸入bash mobility.sh文件即可完成全部計算。
6.1 計算形變勢常數E1
6.2 計算彈性模量C2D(以x方向為例)
6.3 計算遷移率
現已得到有效質量、形變勢常數和彈性模量,依據載流子遷移率計算公式,並注意單位換算,即可得到載流子的遷移率具體數值。計算結果可參考我的JPCC文章(J. Phys. Chem. C2019, 123, 20, 12781-12790),如下(點擊放大看):
因時間關係,本文寫作比較倉促,文中一些數據處理的細節沒有詳細給出,並且可能存在一些小的錯誤,歡迎大家閱讀過程中積極指出,以便在後續更正過程中改正。另外,本文公式較多,但mathjax環境對公式編輯不是很友好,排版過程中公式很容易亂,故而部分公式以插圖的形式放入了本文中,看起來版面攪亂,後續會想辦法處理。
參考文獻:
[1] Bardeen J, Shockley W. Deformation Potentials and Mobilities in Non-Polar Crystals[J]. Physical Review, 2008, 801:72-80.
本文轉載於賀勇個人博客,請大家多多關注他!
連結: https://yh-phys.github.io
(1) 人大遷移率計算軟體包(ReMoC)
https://gitee.com/jigroupruc
(2) The Calculation of Carrier Mobility for 2D Materials
https://chempeng.github.io/2017/09/01/The-Calculation-of-Carrier-Mobility/
往期精彩:
QE計算能帶詳細教程
vasp計算聲子譜教程
常用計算資料庫(長期更新)
第一性原理計算VASP零基礎教程