WannierTools 计算表面态与边缘态

  • 1610
  • 11 min

WannierTools 的定位很清楚:它不负责从头做第一性原理自洽计算,而是在已经得到 Wannier 紧束缚模型之后,进一步计算能带、Wilson loop、表面谱函数、Fermi arc、边缘态等拓扑相关性质。一个典型流程是

text
DFT 计算 -> Wannier90 拟合 -> wannier90_hr.dat -> WannierTools -> 表面态/边缘态/拓扑指标

其中最关键的输入文件是 wannier90_hr.datwt.in。前者给出实空间紧束缚哈密顿量,后者告诉 WannierTools 要算什么以及怎样取表面。

WannierTools 编译安装

官方文档给出的必要依赖包括 Fortran 编译器、MPI、BLAS/LAPACK、ARPACK 等。Intel MKL 对大体系通常更方便;如果只想在个人电脑上快速测试,GCC + OpenMPI + OpenBLAS 也足够开始。

在 Arch Linux 上可以先准备:

bash
sudo pacman -S base-devel gcc-fortran openmpi openblas lapack arpack git gnuplot

在 Debian/Ubuntu 上可以先准备:

bash
sudo apt install build-essential gfortran openmpi-bin libopenmpi-dev \
  libopenblas-dev liblapack-dev libarpack2-dev git gnuplot

然后下载源码:

bash
git clone https://github.com/quanshengwu/wannier_tools.git
cd wannier_tools/src

WannierTools 主要通过 Makefile 编译。源码里通常会带几个示例 Makefile,例如串行 gfortran、串行 ifort/ifx、MPI + Intel 编译器等。实际编译前要检查三件事:

  1. Fortran 编译器是否正确,例如 gfortranifxmpiifx
  2. BLAS/LAPACK/ARPACK 链接参数是否对应当前机器。
  3. 如果启用 MPI,编译选项中是否包含 -DMPI,并且运行时使用对应的 mpirun

一个串行 GNU 环境的思路大致是:

makefile
FC = gfortran
FFLAGS = -O2
LIBS = -lopenblas -llapack -larpack

编译后通常会在 wannier_tools/bin/ 下得到 wt.x

bash
make
../bin/wt.x

为了以后方便调用,可以把路径加入 shell 配置:

bash
export PATH=/path/to/wannier_tools/bin:$PATH

如果使用 MPI 版本,运行方式类似:

bash
mpirun -np 4 wt.x

准备输入文件

计算目录里至少放两个文件:

text
wt.in
wannier90_hr.dat

其中 wannier90_hr.dat 通常来自 Wannier90。为了避免后续结果没有物理意义,建议先在 Wannier90 阶段检查两件事:

  • Wannier 插值能带是否能复现 DFT 目标能带。
  • E_FERMINumOccupied、SOC 设置是否与 DFT 和 Wannier90 阶段一致。

wt.in 的基本结构是 Fortran namelist 加若干卡片。一个极简框架如下:

text
&TB_FILE
Hrfile = 'wannier90_hr.dat'
Package = 'VASP'
/

&CONTROL
BulkBand_calc = T
SlabSS_calc   = T
SlabArc_calc  = F
/

&SYSTEM
SOC = 1
NumOccupied = 18
E_FERMI = 0.0
/

&PARAMETERS
Nk1 = 101
Nk2 = 101
OmegaMin = -1.0
OmegaMax =  1.0
OmegaNum = 401
Eta_Arc = 0.001
NP = 2
/

这里最容易出错的是 E_FERMINumOccupied。如果费米能级没有和 DFT 输出对齐,表面谱函数会整体错位;如果占据带数写错,Wilson loop 和拓扑指标会变得没有意义。

计算表面态

三维材料的表面态一般有两种常见算法:

  1. 构造有限厚度 slab,直接对 slab 哈密顿量对角化。
  2. 构造半无限体系,用迭代格林函数计算表面谱函数。

WannierTools 中 SlabBand_calc 对应第一种思路,SlabSS_calc 对应第二种思路。拓扑表面态和 Fermi arc 更常用 SlabSS_calc,因为它直接模拟半无限表面,避免 slab 两个表面之间发生有限厚度杂化。

表面方向由 SURFACEMILLER_INDICES 指定。官方教程里更推荐认真理解 SURFACE 卡片,因为它明确给出表面内两个方向和法向方向。例如下面这个写法可以理解为以第三个向量作为法向:

text
SURFACE
 1  0  0
 0  1  0
 0  0  1

然后指定二维表面 Brillouin 区中的路径:

text
KPATH_SLAB
2
K 0.333333 0.666667 G 0.0 0.0
G 0.0      0.0      M 0.5 0.5

计算沿路径的表面谱函数:

text
&CONTROL
SlabSS_calc = T
/

&PARAMETERS
OmegaMin = -0.6
OmegaMax =  0.5
OmegaNum = 401
Nk1 = 101
NP = 2
Eta_Arc = 0.001
/

NP 是 principal layer 的数目。它需要做收敛测试:从 NP=1NP=2NP=3 逐步比较谱函数是否稳定。Wannier 函数越弥散,通常需要更大的 NP,但计算量也会上升。

表面态计算结束后,常见输出包括

text
surfdos_l.dat
surfdos_r.dat
surfdos_l.gnu
surfdos_r.gnu

其中 _l_r 分别对应两个相反表面。可以直接用:

bash
gnuplot surfdos_l.gnu
gnuplot surfdos_r.gnu

如果左右表面谱完全不同,需要检查 SURFACE 的法向选择、原胞方向和 Wannier 中心是否符合预期。

如果要看固定能量切片,例如 Weyl 半金属的 Fermi arc,可以打开

text
SlabArc_calc = T

并设置:

text
E_arc = 0.0

KPLANE_SLAB
-0.1 -0.1
 0.2  0.0
 0.0  0.2

这里 KPLANE_SLAB 定义二维表面动量平面,E_arc 定义取哪一个能量截面。

计算边缘态

二维材料的边缘态可以看作“三维模型的侧表面态”。WannierTools 的 MoS2 教程就是按这个思路处理:把单层二维材料放在带真空层的三维晶胞中,然后选择侧向 SURFACEMILLER_INDICES 来计算边缘谱。

例如对一个二维材料,如果希望看 (100) 方向边缘,可以使用类似:

text
&CONTROL
SlabSS_calc = T
/

&SYSTEM
SOC = 1
NumOccupied = 36
E_FERMI = -3.9151
/

&PARAMETERS
OmegaMin = -0.8
OmegaMax =  0.4
OmegaNum = 401
Nk1 = 101
Nk2 = 101
NP = 2
Eta_Arc = 0.001
/

MILLER_INDICES
1 0 0

KPATH_SLAB
2
X 0.5 0.0 G 0.0 0.0
G 0.0 0.0 X 0.5 0.0

这个计算得到的是半无限边界的谱函数。如果想看有限宽度 ribbon 或 wire 的能带,可以改用 WireBand_calc,并通过 NSLAB1NSLAB2 控制有限方向上的层数。有限 ribbon 的好处是能直接看到上下边缘之间的杂化开隙;缺点是需要做宽度收敛。

边缘态计算最常见的几个问题是:

  • 体能带 Wannier 拟合不好,导致边缘态没有可信基础。
  • 费米能级没有对齐,边缘态看起来“消失”在错误的能量窗口。
  • 真空方向或表面方向选错,把本该看的边缘切到了别的方向。
  • NP 或 slab/ribbon 厚度太小,导致两个边界强烈杂化。
  • SOC 在 DFT、Wannier90、WannierTools 三个阶段设置不一致。

我的经验是:不要一上来就算表面态。先算 bulk band,确认 WannierTools 从 wannier90_hr.dat 得到的能带和 Wannier90/DFT 一致;再算 Wilson loop 或 Z2;最后再算表面态或边缘态。这样排错路径会清楚很多。

参考资料