VASP计算二维材料的载流子迁移率(vasp二维材料优化)
ztj100 2025-05-02 22:38 19 浏览 0 评论
1、前言
载流子迁移率通常指半导体内部电子和空穴整体的运动快慢情况,是衡量半导体器件性能的重要物理量。2004年,石墨烯的成功剥离引起了研究人员对于二维材料性质探索的浓厚兴趣。石墨烯、黑磷等二维材料展现出的高载流子迁移率是其中的一个重要研究课题,科研人员在理论计算方面已经做了大量的工作。由于电子在运动过程中不仅受到外电场力的作用,还会不断的与晶格、杂质、缺陷等发生无规则的碰撞,大大增加了理论计算的难度。
目前计算载流子迁移率比较常用的理论是形变势理论和玻尔兹曼输运理论,前者没有考虑电子和声子(晶格振动)以及电子与电子之间的相互作用等因素,计算结果存在一定的误差,但笔者的计算结果与实验值在数量级上是吻合的;玻尔兹曼输运理论的一种计算考虑了电子-声子的相互作用,基于第一性原理计算和最大局域化Wannier函数插值方法,借助于Quantum-ESPRESSO和EPW软件可以完成载流子迁移率计算。缺点是计算量太大,一般的课题组很难承受起高昂的计算费用,另外EPW软件对于二维材料的计算存在部分问题,在其官方论坛也有讨论,计算过程在后续文章中会提到。
本文以形变势理论方法为基础,详细介绍了二维InSe的电子和空穴的有效质量与载流子迁移率的计算方法。
2、理论基础
基于Bardeen和Shockley[1]提出的形变势理论,二维材料载流子迁移率可以根据下式计算:
其中,m*是传输方向上的有效质量,T是温度,kB是玻尔兹曼常数。E1表示沿着传输方向上位于价带顶(VBM)的空穴或聚于导带底(CBM)的电子的形变势常数,由公式E1=ΔE/(Δl/l0)确定,ΔE为在压缩或拉伸应变下CBM或VBM 的能量变化,l0是传输方向上的晶格常数,Δl是l0的变形量。md是载流子的平均有效质量,由下面公式定义。
C2D是均匀变形晶体的弹性模量,对于2D材料,弹性模量可以通过下面公式来计算,
其中E是总能量,S0是优化后的面积。
下面对公式中的单位(量纲)做一个简单换算,具体如下:
换算过程:
3、计算与数据处理工具
VASP.5.4.4软件 可以手动控制优化晶格方向
OriginLab软件
Excel
Materials Studio软件
正格矢到倒格矢转化脚本,来源于小木虫(见下面链接)
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 inunit
def 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 result
def 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 LattVecBohr
def DotProduct( v1, v2 ):
dotproduct = 0.0
for i in range(0,3):
dotproduct = dotproduct + v1[i] * v2[i]
return dotproduct
def 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 v3
def 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 0
if __name__ == "__main__":
import sys
sys.exit(main)
4、二维InSe有效质量计算过程
4.1 建模
由于计算过程中需要对二维InSe施加应变,但二维InSe原胞是六角结构,不容易施加应变。但是侯柱峰老师讲了对石墨烯原胞施加应变的方法,笔者认为虽然可行,但过于繁琐,故不采用此法。我们可以利用根号建模的方法讲六角结构InSe原胞变为方形结构的InSe超胞,然后施加应变可大大提高操作效率,但计算量的增加再可接受范围之内。下面给出关键的建模步骤,更多的根号建模部分可参考我的往期博客文章。
切面并构建二维InSe原胞,同时调整晶格基矢,使其变为方形结构:
4.2 结构优化
INCAR
SYSTEM = InSe
ISTART = 0
NWRITE = 2
PREC = Accurate
ENCUT = 500
GGA = PE
NSW = 200
ISIF = 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 = 2
LWAVE = .FALSE.
LCHARG = .FALSE.
NPAR = 4
KPOINTS
Monkhorst Pack
0
Gamma
11 7 1
.0 .0 .0
POSCAR
Se In
1.000
4.083622259999999 -0.000000000000001 0.000000000000000
0.000000000000000 7.073041233239241 0.000000000000000
0.000000000000000 0.000000000000000 25.377516849029359
Se In
4 4
Direct
0.5000005000000000 0.1666665000000000 0.5271404971815050 !Se
0.0000004999999997 0.6666665000000004 0.5271404971815050 !Se
0.5000005000000000 0.1666665000000000 0.3152396685456632 !Se
0.0000004999999997 0.6666665000000004 0.3152396685456632 !Se
0.4999995000000003 0.8333335000000002 0.4767849697227853 !In
-0.0000005000000000 0.3333335000000000 0.4767849697227853 !In
0.4999995000000003 0.8333335000000002 0.3655951960043828 !In
-0.0000005000000000 0.3333335000000000 0.3655951960043828 !In
OPTCELL
100
010
000
POTCAR
cat Se/POTCAR In_d/POTCAR > POTCAR
4.3 静态自洽
INCAR
SYSTEM = InSe
ISTART = 0
NWRITE = 2
PREC = Accurate
ENCUT = 500
GGA = PE
NSW = 0
ISIF = 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 = 2
NPAR = 4
KPOINTS
Monkhorst Pack
0
Gamma
21 13 1
.0 .0 .0
POSCAR
cp CONTCAR scf/POSCAR
4.4 能带计算
INCAR
SYSTEM = InSe
ISTART = 1
NWRITE = 2
PREC = Accurate
ENCUT = 500
GGA = PE
NSW = 0
ISIF = 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 = 2
LORBIT = 11
LWAVE = .FALSE.
LCHARG = .FALSE.
NPAR = 4
KPOINTS
k-points along high symmetry lines
80
Line-mode
Rec
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 !Y
4.5 有效质量计算(有效质量详细教程)
计算说明:对于包含了晶格周期性的有效质量的表达式如下所示:
在带入物理量进行有效质量计算时,涉及单位制问题。一般写输入文件时,长度单位为A;而程序输出的能带结构中,能量单位为eV,计算起来比较繁琐。
原子单位制有两种,一种为Hartree原子单位制,另一种为Rydberg单位制。这两种单位制的区别在于,Hartree单位制下基本物理量简单,电子电荷和质量都为1;而Rydberg单位制下薛定谔方程简单,系数为1。Hartree单位制下,一个长度单位等于1Lbohr = 0.5292A,一个能量单位1EHartree = 27.21eV,约化普朗克常数h=1。这样有效质量表达式中的约化普朗克常数就没了。
根据原胞基矢和正倒格子基矢间对应关系,算出倒格子基矢:
将VASP计算band时的k点坐标(分数坐标)转变为笛卡尔坐标:
根据两点间的距离公式,计算出各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个点的数据画能带图,如下:
用y = a+bx+cx^2函数拟合,操作如下:
有效质量为1/2C,其中C=2.69188,算得有效质量为0.19 ,为电子沿x方向的质量。文献计算结果为0.19,符合一致。
5、二维InSe载流子迁移率计算过程
本文载流子迁移率的计算依据的是形变势理论,因此需要对二维InSe的x方向和y方向施加应变,施加应变的范围是-2%~2%。为了计算的准确性,计算过程中考虑了泊松效应,即对x轴施加应变时,固定x轴和z轴,优化y方向的晶格常数;对y轴施加应变时,固定y轴和z轴,优化x方向的晶格常数。
5.1 准备输入文件
首先建立mobility-x文件夹,然后在该文件夹下建立初始文件夹,命名为IS,其结构目录如下:
$ tree mobility
mobility
├── IS
│ ├── 2_scf
│ │ ├── band
│ │ │ ├── INCAR
│ │ │ ├── KPOINTS
│ │ │ └── POTCAR
│ │ ├── INCAR
│ │ ├── KPOINTS
│ │ └── POTCAR
│ ├── INCAR
│ ├── KPOINTS
│ ├── OPTCELL
│ ├── pbs
│ ├── POSCAR
│ └── POTCAR
└── mobility.sh
说明:
pbs文件
#!/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:00
cd $PBS_O_WORKDIR
date "+01 Today's date is: %D. The time execution %T" >> time.info
mpirun -np 16 /opt/soft/strainvasp5.4.4/vasp.5.4.4/build/std/vasp > log
date "+02 Today's date is: %D. The time finish %T" >> time.info
cp ./CONTCAR ./2_scf/POSCAR
cd ./2_scf/
date "+01 Today's date is: %D. The time execution %T" >> time.info
mpirun /opt/soft/strainvasp5.4.4/vasp.5.4.4/build/std/vasp > log
date "+02 Today's date is: %D. The time finish %T" >> time.info
cp ./CONTCAR ./band/POSCAR
cp ./WAVECAR ./band/
cd ./band/
date "+01 Today's date is: %D. The time execution %T" >> time.info
mpirun -np 16 /opt/soft/strainvasp5.4.4/vasp.5.4.4/build/std/vasp > log
date "+02 Today's date is: %D. The time finish %T" >> time.info
OPTCELL文件
X方向
000
010
000
Y方向
100
000
000
自洽计算时INCAR文件中加入计算真空能级的命令
LVHAR = .TRUE.
mobility.sh文件
#!/bin/bash
#3 November, 2018
#To use it: bash mobility.sh
mkdir mobility-x
cd mobility-x
x=4.083622259999999 #"x" stands for the lattice constant in x direction
for i in $(seq 0.98 0.005 1.02) #"i" defines the range of strain
do
cp -r ../IS ./$i #"IS" stands for the origin file
sed -i "3s/$x/$(echo "$x*$i"|bc)/g" $i/POSCAR
cd $i
#qsub ./pbs
cd $OLDPWD
done
cd ../
mkdir mobility-y
cd mobility-y
y=7.073041233239241 #"y" stands for the lattice constant in y direction
for j in $(seq 0.98 0.005 1.02) #"j" defines the range of strain
do
cp -r ../IS ./$j #"IS" stands for the origin file
sed -i "4s/$y/$(echo "$y*$j"|bc)/g" $j/POSCAR
cd $j
#qsub ./pbs
cd $OLDPWD
done
Note:计算过程中需要根据自己的体系修改x和y方向的晶格常数值
其余文件与前面计算能带过程的输入文件相同,在mobility文件夹下输入bash mobility.sh文件即可完成全部计算。
6、数据处理(以x方向为例)
6.1 计算形变势常数E1
以真空能级为参考,确定VBM和CBM的位置。思路是读取能带计算结果中的最高占据态VBM和最低非占据态CBM(未扣除费米能级)的结果,然后减去真空能级就可得到我们需要的结果。
对得到的数据以应变量为x轴(-0.02~0.02),VBM和CBM为y轴画图,然后在origin中做线性拟合,即可得到形变势常数,最终结果如下:
6.2 计算弹性模量C2D(以x方向为例)
读取每个应变下的体系总能量,然后画图。
对其做二次函数拟合,然后带入C2D的计算公式,并对单位做换算后,得到的结果如下:
6.3 计算迁移率
现已得到有效质量、形变势常数和弹性模量,依据载流子迁移率计算公式,并注意单位换算,即可得到载流子的迁移率具体数值。计算结果可参考我的JPCC文章(J. Phys. Chem. C2019, 123, 20, 12781-12790),如下(点击放大看):
7、后记
因时间关系,本文写作比较仓促,文中一些数据处理的细节没有详细给出,并且可能存在一些小的错误,欢迎大家阅读过程中积极指出,以便在后续更正过程中改正。另外,本文公式较多,但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
8、补充:三维材料迁移率计算(欢迎留言讨论)
9、友情链接:
(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/
相关推荐
- 其实TensorFlow真的很水无非就这30篇熬夜练
-
好的!以下是TensorFlow需要掌握的核心内容,用列表形式呈现,简洁清晰(含表情符号,<300字):1.基础概念与环境TensorFlow架构(计算图、会话->EagerE...
- 交叉验证和超参数调整:如何优化你的机器学习模型
-
准确预测Fitbit的睡眠得分在本文的前两部分中,我获取了Fitbit的睡眠数据并对其进行预处理,将这些数据分为训练集、验证集和测试集,除此之外,我还训练了三种不同的机器学习模型并比较了它们的性能。在...
- 机器学习交叉验证全指南:原理、类型与实战技巧
-
机器学习模型常常需要大量数据,但它们如何与实时新数据协同工作也同样关键。交叉验证是一种通过将数据集分成若干部分、在部分数据上训练模型、在其余数据上测试模型的方法,用来检验模型的表现。这有助于发现过拟合...
- 深度学习中的类别激活热图可视化
-
作者:ValentinaAlto编译:ronghuaiyang导读使用Keras实现图像分类中的激活热图的可视化,帮助更有针对性...
- 超强,必会的机器学习评估指标
-
大侠幸会,在下全网同名[算法金]0基础转AI上岸,多个算法赛Top[日更万日,让更多人享受智能乐趣]构建机器学习模型的关键步骤是检查其性能,这是通过使用验证指标来完成的。选择正确的验证指...
- 机器学习入门教程-第六课:监督学习与非监督学习
-
1.回顾与引入上节课我们谈到了机器学习的一些实战技巧,比如如何处理数据、选择模型以及调整参数。今天,我们将更深入地探讨机器学习的两大类:监督学习和非监督学习。2.监督学习监督学习就像是有老师的教学...
- Python 模型部署不用愁!容器化实战,5 分钟搞定环境配置
-
你是不是也遇到过这种糟心事:花了好几天训练出的Python模型,在自己电脑上跑得顺顺当当,一放到服务器就各种报错。要么是Python版本不对,要么是依赖库冲突,折腾半天还是用不了。别再喊“我...
- 神经网络与传统统计方法的简单对比
-
传统的统计方法如...
- 自回归滞后模型进行多变量时间序列预测
-
下图显示了关于不同类型葡萄酒销量的月度多元时间序列。每种葡萄酒类型都是时间序列中的一个变量。假设要预测其中一个变量。比如,sparklingwine。如何建立一个模型来进行预测呢?一种常见的方...
- 苹果AI策略:慢哲学——科技行业的“长期主义”试金石
-
苹果AI策略的深度原创分析,结合技术伦理、商业逻辑与行业博弈,揭示其“慢哲学”背后的战略智慧:一、反常之举:AI狂潮中的“逆行者”当科技巨头深陷AI军备竞赛,苹果的克制显得格格不入:功能延期:App...
- 时间序列预测全攻略,6大模型代码实操
-
如果你对数据分析感兴趣,希望学习更多的方法论,希望听听经验分享,欢迎移步宝藏公众号...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)