VASP教程:带隙的温度依赖性计算

本文主要介绍利用单次方法计算钻石中零点重整化(ZPR)和间接带隙的温度依赖性。教程来源VASP官网案例:

https://www.vasp.at/wiki/Band_gap_renormalization_in_diamond_using_one-shot_method#Task

案例文件下载:

https://www.vasp.at/wiki/images/7/7b/EPC_cd-C.tgz

准备文件

  • 原始晶胞(POSCAR.prim):

C_2_fcc

1.00000000000000

0.0000000000000000 1.783493 1.783493

1.783493 0.0000000000000000 1.783493

1.783493 1.783493 0.0000000000000000

C

2

Direct

0.0000000000000000 0.0000000000000000 0.0000000000000000

0.7500000000000000 0.7500000000000000 0.7500000000000000

官网教程使用4×4×4超胞进行演示,实际情况中需要进行超胞的收敛性测试,即3×3×3,4×4×4,5×5×5等超胞大小进行计算并判断所得带隙值是否随超胞变大而逐渐收敛。

4×4×4超胞POSCAR.4x4x4如下
C_128_fcc

1.00000000000000

0.00000000 7.13397200 7.13397200

7.13397200 0.00000000 7.13397200

7.13397200 7.13397200 0.00000000

C

128

Direct

0.00000000 0.00000000 0.00000000

0.25000000 0.00000000 0.00000000

0.50000000 0.00000000 0.00000000

0.75000000 0.00000000 0.00000000

0.00000000 0.25000000 0.00000000

0.25000000 0.25000000 0.00000000

0.50000000 0.25000000 0.00000000

0.75000000 0.25000000 0.00000000

0.00000000 0.50000000 0.00000000

0.25000000 0.50000000 0.00000000

0.50000000 0.50000000 0.00000000

0.75000000 0.50000000 0.00000000

0.00000000 0.75000000 0.00000000

0.25000000 0.75000000 0.00000000

0.50000000 0.75000000 0.00000000

0.75000000 0.75000000 0.00000000

0.00000000 0.00000000 0.25000000

0.25000000 0.00000000 0.25000000

0.50000000 0.00000000 0.25000000

0.75000000 0.00000000 0.25000000

0.00000000 0.25000000 0.25000000

0.25000000 0.25000000 0.25000000

0.50000000 0.25000000 0.25000000

0.75000000 0.25000000 0.25000000

0.00000000 0.50000000 0.25000000

0.25000000 0.50000000 0.25000000

0.50000000 0.50000000 0.25000000

0.75000000 0.50000000 0.25000000

0.00000000 0.75000000 0.25000000

0.25000000 0.75000000 0.25000000

0.50000000 0.75000000 0.25000000

0.75000000 0.75000000 0.25000000

0.00000000 0.00000000 0.50000000

0.25000000 0.00000000 0.50000000

0.50000000 0.00000000 0.50000000

0.75000000 0.00000000 0.50000000

0.00000000 0.25000000 0.50000000

0.25000000 0.25000000 0.50000000

0.50000000 0.25000000 0.50000000

0.75000000 0.25000000 0.50000000

0.00000000 0.50000000 0.50000000

0.25000000 0.50000000 0.50000000

0.50000000 0.50000000 0.50000000

0.75000000 0.50000000 0.50000000

0.00000000 0.75000000 0.50000000

0.25000000 0.75000000 0.50000000

0.50000000 0.75000000 0.50000000

0.75000000 0.75000000 0.50000000

0.00000000 0.00000000 0.75000000

0.25000000 0.00000000 0.75000000

0.50000000 0.00000000 0.75000000

0.75000000 0.00000000 0.75000000

0.00000000 0.25000000 0.75000000

0.25000000 0.25000000 0.75000000

0.50000000 0.25000000 0.75000000

0.75000000 0.25000000 0.75000000

0.00000000 0.50000000 0.75000000

0.25000000 0.50000000 0.75000000

0.50000000 0.50000000 0.75000000

0.75000000 0.50000000 0.75000000

0.00000000 0.75000000 0.75000000

0.25000000 0.75000000 0.75000000

0.50000000 0.75000000 0.75000000

0.75000000 0.75000000 0.75000000

0.18750000 0.18750000 0.18750000

0.43750000 0.18750000 0.18750000

0.68750000 0.18750000 0.18750000

0.93750000 0.18750000 0.18750000

0.18750000 0.43750000 0.18750000

0.43750000 0.43750000 0.18750000

0.68750000 0.43750000 0.18750000

0.93750000 0.43750000 0.18750000

0.18750000 0.68750000 0.18750000

0.43750000 0.68750000 0.18750000

0.68750000 0.68750000 0.18750000

0.93750000 0.68750000 0.18750000

0.18750000 0.93750000 0.18750000

0.43750000 0.93750000 0.18750000

0.68750000 0.93750000 0.18750000

0.93750000 0.93750000 0.18750000

0.18750000 0.18750000 0.43750000

0.43750000 0.18750000 0.43750000

0.68750000 0.18750000 0.43750000

0.93750000 0.18750000 0.43750000

0.18750000 0.43750000 0.43750000

0.43750000 0.43750000 0.43750000

0.68750000 0.43750000 0.43750000

0.93750000 0.43750000 0.43750000

0.18750000 0.68750000 0.43750000

0.43750000 0.68750000 0.43750000

0.68750000 0.68750000 0.43750000

0.93750000 0.68750000 0.43750000

0.18750000 0.93750000 0.43750000

0.43750000 0.93750000 0.43750000

0.68750000 0.93750000 0.43750000

0.93750000 0.93750000 0.43750000

0.18750000 0.18750000 0.68750000

0.43750000 0.18750000 0.68750000

0.68750000 0.18750000 0.68750000

0.93750000 0.18750000 0.68750000

0.18750000 0.43750000 0.68750000

0.43750000 0.43750000 0.68750000

0.68750000 0.43750000 0.68750000

0.93750000 0.43750000 0.68750000

0.18750000 0.68750000 0.68750000

0.43750000 0.68750000 0.68750000

0.68750000 0.68750000 0.68750000

0.93750000 0.68750000 0.68750000

0.18750000 0.93750000 0.68750000

0.43750000 0.93750000 0.68750000

0.68750000 0.93750000 0.68750000

0.93750000 0.93750000 0.68750000

0.18750000 0.18750000 0.93750000

0.43750000 0.18750000 0.93750000

0.68750000 0.18750000 0.93750000

0.93750000 0.18750000 0.93750000

0.18750000 0.43750000 0.93750000

0.43750000 0.43750000 0.93750000

0.68750000 0.43750000 0.93750000

0.93750000 0.43750000 0.93750000

0.18750000 0.68750000 0.93750000

0.43750000 0.68750000 0.93750000

0.68750000 0.68750000 0.93750000

0.93750000 0.68750000 0.93750000

0.18750000 0.93750000 0.93750000

0.43750000 0.93750000 0.93750000

0.68750000 0.93750000 0.93750000

0.93750000 0.93750000 0.93750000

对于超胞使用仅1个Γ点的KPOINTS
K-Points

0

Gamma

1 1 1

0 0 0

用于计算零点重整化(ZPR)的INCAR.init
general:

System = cd-C

PREC = Accurate

ALGO = FAST

ISMEAR = 0; SIGMA = 0.1;

IBRION = 6

PHON_LMC = .TRUE.

PHON_NSTRUCT = 0

PHON_TLIST = 0.0

自洽INCAR.scf
general:

System = cd-C

PREC = Accurate

ALGO = FAST

ISMEAR = 0; SIGMA = 0.1;

计算0K下的ZPR
使用4×4×4超胞

cp POSCAR.4x4x4 POSCAR

和INCAR.init,

cp INCAR.init INCAR

生成含特殊位移的POSCAR
运行VASP计算后,记录原始带隙

cp OUTCAR OUTCAR.init
复制位移结构:

cp POSCAR.T=0. POSCAR
使用自洽计算INCAR:

cp INCAR.scf INCAR

运行VASP后,保存结果:

cp OUTCAR OUTCAR.T=0.
执行脚本,提取ZPR和重整化的带隙

bash extract_zpr.sh
#!/bin/bash

i="OUTCAR.T=0."

j="OUTCAR.init"

homo1=`awk '/NELECT/ {print 3/2}' i`

homo2=`awk '/NELECT/ {print 3/2-1}' i`

homo3=`awk '/NELECT/ {print 3/2-2}' i`

lumo1=`awk '/NELECT/ {print 3/2+var+1}' i`

lumo2=`awk '/NELECT/ {print 3/2+var+2}' i`

lumo3=`awk '/NELECT/ {print 3/2+var+3}' i`

lumo4=`awk '/NELECT/ {print 3/2+var+4}' i`

lumo5=`awk '/NELECT/ {print 3/2+var+5}' i`

lumo6=`awk '/NELECT/ {print 3/2+var+6}' i`

e1a=`grep " homo1 " i | head -nkpt \| sort -n -k 2 \| tail -1 \| awk '{print 2}'`

e1b=`grep " homo2 " i | head -nkpt \| sort -n -k 2 \| tail -1 \| awk '{print 2}'`

e1c=`grep " homo3 " i | head -nkpt \| sort -n -k 2 \| tail -1 \| awk '{print 2}'`

e2a=`grep " lumo1 " i | head -nkpt \| sort -n -k 2 \| head -1 \| awk '{print 2}'`

e2b=`grep " lumo2 " i | head -nkpt \| sort -n -k 2 \| head -1 \| awk '{print 2}'`

e2c=`grep " lumo3 " i | head -nkpt \| sort -n -k 2 \| head -1 \| awk '{print 2}'`

e2d=`grep " lumo4 " i | head -nkpt \| sort -n -k 2 \| head -1 \| awk '{print 2}'`

e2e=`grep " lumo5 " i | head -nkpt \| sort -n -k 2 \| head -1 \| awk '{print 2}'`

e2f=`grep " lumo6 " i | head -nkpt \| sort -n -k 2 \| head -1 \| awk '{print 2}'`

homo_ref=`awk '/NELECT/ {print 3/2}' j`

lumo_ref=`awk '/NELECT/ {print 3/2+var+1}' j`

h_ref=`grep " homo_ref " j | head -nkpt \| sort -n -k 2 \| tail -1 \| awk '{print 2}'`

l_ref=`grep " lumo_ref " j | head -nkpt \| sort -n -k 2 \| head -1 \| awk '{print 2}'`

echo "The band gap (in eV) without zero-point vibrations is:"

echo "h_ref l_ref" |awk '{print (2-1)}'

echo "The band gap (in eV) including zero-point vibrations is:"

echo "e1a e1b e1c e2a e2b e2c e2d e2e e2f" \|awk '{print ((4+5+6+7+8+9)/6.0-(1+2+3)/3.0)}'

echo "The zero-point renormalization of the band gap (in eV) is:"

echo "e1a e1b e1c e2a e2b e2c e2d e2e e2f h_ref l_ref" \|awk '{print ((4+5+6+7+8+9)/6.0-(1+2+3)/3.0)-(11-10)}'

预期输出示例

3×3×3超胞:
The band gap (in eV) without zero-point vibrations is:

4.0729

The band gap (in eV) including zero-point vibrations is:

3.81437

The zero-point renormalization of the band gap (in eV) is:

-0.258533

4×4×4超胞:
The band gap (in eV) without zero-point vibrations is:

4.4049

The band gap (in eV) including zero-point vibrations is:

4.05102

The zero-point renormalization of the band gap (in eV) is:

-0.353883

5×5×5超胞结果(更精确):
The band gap (in eV) without zero-point vibrations is:

4.1421

The band gap (in eV) including zero-point vibrations is:

3.83717

The zero-point renormalization of the band gap (in eV) is:

-0.304933

温度依赖计算
在INCAR.init中加入PHON_TLIST = 0.0 100.0 200.0 300.0 400.0 500.0 600.0 700.0

general:

System = cd-C

PREC = Accurate

ALGO = FAST

ISMEAR = 0; SIGMA = 0.1;

IBRION = 6

PHON_LMC = .TRUE.

PHON_NSTRUCT = 0

PHON_TLIST = 0.0 100.0 200.0 300.0 400.0 500.0 600.0 700.0

然后执行VASP计算,可获得0-700K内不同温度下的位移POSCAR,分别为

POSCAR.T=0. POSCAR.T=100. POSCAR.T=200. POSCAR.T=300. POSCAR.T=400. POSCAR.T=500. POSCAR.T=600. POSCAR.T=700.

分别将每个POSCAR进行VASP自洽计算并获得OUTCAR,并重命名为

OUTCAR.T=0

OUTCAR.T=100

OUTCAR.T=200

OUTCAR.T=300

OUTCAR.T=400

OUTCAR.T=500

OUTCAR.T=600

OUTCAR.T=700

再通过extract_temp.sh提取计算每个温度下的带隙(相对0K的偏移)输出到 gap_vs_temp.dat

bash ./extract_temp.sh
#!/bin/bash

if [ -f gap_vs_temp.dat ]

then

rm gap_vs_temp.dat

fi

touch gap_vs_temp.dat

counter=0

for temp in 0 100 200 300 400 500 600 700

do

i="OUTCAR.T=$temp"

homo1=`awk '/NELECT/ {print 3/2}' i`

homo2=`awk '/NELECT/ {print 3/2-1}' i`

homo3=`awk '/NELECT/ {print 3/2-2}' i`

lumo1=`awk '/NELECT/ {print 3/2+var+1}' i`

lumo2=`awk '/NELECT/ {print 3/2+var+2}' i`

lumo3=`awk '/NELECT/ {print 3/2+var+3}' i`

lumo4=`awk '/NELECT/ {print 3/2+var+4}' i`

lumo5=`awk '/NELECT/ {print 3/2+var+5}' i`

lumo6=`awk '/NELECT/ {print 3/2+var+6}' i`

e1a=`grep "^ homo1 " i | head -nkpt \| sort -n -k 2 \| tail -1 \| awk '{print 2}'`

e1b=`grep "^ homo2 " i | head -nkpt \| sort -n -k 2 \| tail -1 \| awk '{print 2}'`

e1c=`grep "^ homo3 " i | head -nkpt \| sort -n -k 2 \| tail -1 \| awk '{print 2}'`

e2a=`grep "^ lumo1 " i | head -nkpt \| sort -n -k 2 \| head -1 \| awk '{print 2}'`

e2b=`grep "^ lumo2 " i | head -nkpt \| sort -n -k 2 \| head -1 \| awk '{print 2}'`

e2c=`grep "^ lumo3 " i | head -nkpt \| sort -n -k 2 \| head -1 \| awk '{print 2}'`

e2d=`grep "^ lumo4 " i | head -nkpt \| sort -n -k 2 \| head -1 \| awk '{print 2}'`

e2e=`grep "^ lumo5 " i | head -nkpt \| sort -n -k 2 \| head -1 \| awk '{print 2}'`

e2f=`grep "^ lumo6 " i | head -nkpt \| sort -n -k 2 \| head -1 \| awk '{print 2}'`

if [ $temp -eq "0" ]

then

ref=`echo "e1a e1b e1c e2a e2b e2c e2d e2e e2f" \|awk '{print ((4+5+6+7+8+9)/6.0-(1+2+3)/3.0)}'`

fi

echo "e1a e1b e1c e2a e2b e2c e2d e2e e2f temp ref" \|awk '{print 10,((4+5+6+7+8+9)/6.0-(1+2+3)/3.0)-11}' >> gap_vs_temp.dat

done

使用gnuplot绘制温度下的带隙偏移

gnuplot -e "set terminal pngcairo size 800,600; set xlabel 'T (K)'; set ylabel 'Band gap (eV)'; set style data lines; plot 'gap_vs_temp.dat' title 'Calculated', 'C_exp_points_offset0.dat' w circles title 'Exp. data', 'C_exp_fit_offset0.dat' title 'Exp. fit'" > gap_vs_temp.png

3×3×3超胞:

与实验值对比

4×4×4超胞

考虑体积效应的温度依赖性

通过运行quasi_harm_4x4x4_diamond_create_pos_and_run_vasp.sh脚本在平衡体积±2%范围内生成15个不同体积的POSCAR,并计算每个体积的动力学矩阵。

quasi_harm_4x4x4_diamond_create_pos_and_run_vasp.sh

vasp_exec=./vasp_gam

#please enter the number of processors used for VASP here

np=8

cp INCAR.qh INCAR

for i in 6.13521592 6.27789536 6.4205748 6.56325424 6.70593368 6.84861312 6.99129256 7.133972 7.27665144 7.41933088 7.56201032 7.70468976 7.8473692 7.99004864 8.13272808

do

sed "s/7.13397200/{i}/g" POSCAR.4x4x4 \> POSCAR_i

cp POSCAR_$i POSCAR

mpirun -np np vasp_exec

mv OUTCAR OUTCAR_$i

done

计算所使用的INCAR.qh
general:

System = cd-C

PREC = Accurate

ALGO = FAST

ISMEAR = 0; SIGMA = 0.1;

IBRION = 6

可通过for循环更改缩放系数生成更大更密集的不同体积POSCAR模型,可参考QHA文章
for i in $(seq 0.950.0051.05

)#对i赋值0.95到1.05之间,每隔0.005取值。

do

mkdir $i

cp POSCAR INCAR KPOINTS POTCAR ./$i

cd ./$

ised '2c '$i'' POSCAR > POS

mv POS POSCAR#修改POSCAR中的缩放系数,并覆盖POSCAR

pwd

对所有体积的POSCAR完成计算后,提取能量和体积的数据

bash quasi_harm_4x4x4_diamond_make_energy_vs_volume_plots.sh

生成每个温度下的自由能-体积曲线(OUTTEMP_*)
#!/bin/bash

bandshift=0

gwrun=-1

dgbd=-1

val=-1

con=-1

gwldadiff=-1

test=-1

while [[ $# -gt 0 ]]

do

key="$1"

case $key in

esac

shift

done

if [ -f "helpscript.perl" ]; then

rm helpscript.perl

fi

cat > helpscript.perl <<EOF

#!/bin/perl

use strict;

use warnings;

my \$zahler=0;

my @entropy=0;

my \$ezp=0;

my \$fhelmholtz=0;

my \$uenergy;

my \$kboltzmann=8.6173303*10**(-5.0);

my \$ntemp=8;

my \$tmax=700;

my \$tmin=0;

my \$tstep=100;

for (my \itemp=1;\\itemp<=\ntemp;\\itemp++)

{

\entropy\[\\itemp]=0;

}

while (<>)

{

chomp;

\$_=~s/^/ /;

my @help=split(/[\t,\s]+/);

\zahler=\\zahler+1;

if (\zahler == 1) {\\uenergy=\$help[1];}

else

{

my \homega=\\help[2]/1000;

\ezp=\\ezp+\$homega*0.5;

for (my \itemp=1;\\itemp<=\ntemp;\\itemp++)

{

my \temp=(\\itemp-1)*\tstep+\\tmin;

my \kbt=\\kboltzmann*\$temp;

if (\$temp < 0.0000001)

{

}

else

{

\entropy\[\\itemp]=\entropy\[\\itemp]-\kboltzmann\*log(1-exp(-\\homega/\$kbt));

\entropy\[\\itemp]=\entropy\[\\itemp]+\kboltzmann\*\\homega/\kbt\*(1/(exp(\\homega/\$kbt)-1));

}

}

}

last if eof;

}

\ezp=\\ezp; #/ \$zahler;

for (my \itemp=1;\\itemp<=\ntemp;\\itemp++)

{

my \temp=(\\itemp-1)*\tstep+\\tmin;

\entropy\[\\itemp]=\entropy\[\\itemp]; # / \$zahler;

\fhelmholtz=\\uenergy+\ezp-\\temp*\entropy\[\\itemp];

printf ("%15.8e %15.8e\n",\temp,\\fhelmholtz);

}

printf ("#NOTEMP %15.8e\n",\$uenergy);

EOF

rm OUTTEMP*

first=0

for i in OUTCAR_*; do

echo "Starting $i"

v2=${i##OUTCAR_}

if [ -f "helpfile.help" ]; then

rm helpfile.help

fi

touch helpfile.help

cp OUTCAR_$v2 OUTCAR

awk '/free energy/' OUTCAR | tail -n 1| awk '{print $5}' >> helpfile.help

awk '/[0-9]* f .* THz/ {print 1,10}' OUTCAR >> helpfile.help

awk '/[0-9]* f.i.*THz/ {print 1,9}' OUTCAR >> helpfile.help

volume=`awk '/volume of cell/ {print $5}' OUTCAR | tail -n 1`

perl helpscript.perl helpfile.help > hhhhelp.txt

runcount=0

while read line; do

runcount=$((runcount+1))

if [[ $first -eq 0 ]]; then

echo line \| awk -v var="volume" '{print var,2,1}' > OUTTEMP_$runcount

else

echo line \| awk -v var="volume" '{print var,2}' \>\> OUTTEMP_runcount

fi

done < ./hhhhelp.txt

first=1

done

for i in OUTTEMP_*; do

v2=${i##OUTTEMP_}

mv OUTTEMP_$v2 OUTHELP

sort -n -k 1 OUTHELP > OUTTEMP_$v2

done

rm helpfile.help

rm helpscript.perl

rm hhhhelp.txt

rm OUTHELP

运行 quasi_harm_4x4x4_diamond_obtain_fitting.sh用Birch-Murnaghan状态方程拟合输出每个温度下的平衡晶格常数

bash quasi_harm_4x4x4_diamond_obtain_fitting.sh
#!/bin/bash

for i in OUTTEMP_*

do

cp $i OUTTEMP.current

#extract temperature

temp=`head -n 1 OUTTEMP.current|awk '{print $3}'`

#do fitting

gnuplot -e "E(V)=E0+9.0/8.0*B0*V0*((V0/V)**(2.0/3.0)-1)**2 + 9.0/16.0*B0*\

(B0P-4)*V0*((V0/V)**(2.0/3.0)-1.0)**3.0 + R*((V0/V)**(2.0/3.0)-1.0)**4.0;\

B0P = 1;B0 = 1;V0 = 720;E0 = -1150;R = -1.0;fit E(x) 'OUTTEMP.current' u 1:2 via B0P,B0,V0,E0,R" &> suppress_output

#extract volume from fit

a=`grep "V0" fit.log|grep "=" |tail -n 1|awk '{print ($3/2.0)**(1.0/3.0)}'`

#print temperature and volume to

echo "temperature: temp, a_latt: a"

done

rm suppress_output

rm OUTTEMP.current

复制代码
$ sh quasi_harm_4x4x4_diamond_obtain_fitting.shtemperature: 0.00000000e+00, a_latt: 7.18018temperature: 1.00000000e+02, a_latt: 7.18021temperature: 2.00000000e+02, a_latt: 7.18072temperature: 3.00000000e+02, a_latt: 7.18276temperature: 4.00000000e+02, a_latt: 7.18623temperature: 5.00000000e+02, a_latt: 7.19049temperature: 6.00000000e+02, a_latt: 7.19507temperature: 7.00000000e+02, a_latt: 7.19976temperature: #NOTEMP, a_latt: 7.15218

用新的晶格常数更新各POSCAR.T=*文件,重新运行温度依赖计算,体积效应会使带隙随温度下降更快,更接近实验值