模型和能带, 学术

Haldane模型哈密顿量与能带图(附Python代码)

Haldane(霍尔丹)模型PRL原文:Model for a Quantum Hall Effect without Landau Levels: Condensed-Matter Realization of the "Parity Anomaly"

量子霍尔效应在某种意义上是拓扑绝缘体(陈数不为零;体态绝缘,边态导电),但是需要外加强磁场。而Haldane模型是第一个在理论上提出不需要磁场的拓扑绝缘体。

Haldane哈密顿量:

在以上表达式中,用到了以下公式:

  • exp(ix)+exp(-ix)=2cos(x)
  • cos(x+y)= cos(x)cos(y)-sin(x)sin(y)
  • cos(x-y) = cos(x)cos(y)+sin(x)sin(y)

如果只考虑最近邻跃迁 t1,那么跟最简单的石墨烯模型是一样的。在这个哈密顿量中加上了次近邻 t2,而且次近邻是带有相位phi的(有一个方向为正)。引入带相位的次近邻,打破了时间反演对称性,让陈拓扑绝缘体成为了可能(可证明具有时间反演对称的体系,陈数为零)。

模型图为:

这里的模型图来源于这篇文献:Numerical study of disorder on the orbital magnetization in two dimensions

下面是Python代码,用于画出二维Haldane模型的能带:

"""
This code is supported by the website: https://www.guanjihuan.com
The newest version of this code is on the web page: https://www.guanjihuan.com/archives/410
"""

import numpy as np
import matplotlib.pyplot as plt
from math import * 
import cmath 
import functools


def hamiltonian(k1, k2, M, t1, t2, phi, a=1/sqrt(3)):  # Haldane哈密顿量(a为原子间距,不赋值的话默认为1/sqrt(3))
    # 初始化为零矩阵
    h0 = np.zeros((2, 2), dtype=complex)
    h1 = np.zeros((2, 2), dtype=complex)
    h2 = np.zeros((2, 2), dtype=complex)

    # 质量项(mass term),用于打开带隙
    h0[0, 0] = M
    h0[1, 1] = -M

    # 最近邻项
    h1[1, 0] = t1*(cmath.exp(1j*k2*a)+cmath.exp(1j*sqrt(3)/2*k1*a-1j/2*k2*a)+cmath.exp(-1j*sqrt(3)/2*k1*a-1j/2*k2*a))
    h1[0, 1] = h1[1, 0].conj()

    # 最近邻项也可写成这种形式
    # h1[1, 0] = t1+t1*cmath.exp(1j*sqrt(3)/2*k1*a-1j*3/2*k2*a)+t1*cmath.exp(-1j*sqrt(3)/2*k1*a-1j*3/2*k2*a)
    # h1[0, 1] = h1[1, 0].conj()

    # 次近邻项
    h2[0, 0] = t2*cmath.exp(-1j*phi)*(cmath.exp(1j*sqrt(3)*k1*a)+cmath.exp(-1j*sqrt(3)/2*k1*a+1j*3/2*k2*a)+cmath.exp(-1j*sqrt(3)/2*k1*a-1j*3/2*k2*a))
    h2[1, 1] = t2*cmath.exp(1j*phi)*(cmath.exp(1j*sqrt(3)*k1*a)+cmath.exp(-1j*sqrt(3)/2*k1*a+1j*3/2*k2*a)+cmath.exp(-1j*sqrt(3)/2*k1*a-1j*3/2*k2*a))

    matrix = h0 + h1 + h2 + h2.transpose().conj()
    return matrix


def main():
    hamiltonian0 = functools.partial(hamiltonian, M=2/3, t1=1, t2=1/3, phi=pi/4, a=1/sqrt(3))
    k1 = np.linspace(-2*pi, 2*pi, 500)
    k2 = np.linspace(-2*pi, 2*pi, 500)
    plot_bands_two_dimension(k1, k2, hamiltonian0)


def plot_bands_two_dimension(k1, k2, hamiltonian):
    from matplotlib import cm
    dim = hamiltonian(0, 0).shape[0]
    dim1 = k1.shape[0]
    dim2 = k2.shape[0]
    eigenvalue_k = np.zeros((dim2, dim1, dim))
    i0 = 0
    for k10 in k1:
        j0 = 0
        for k20 in k2:
            matrix0 = hamiltonian(k10, k20)
            eigenvalue, eigenvector = np.linalg.eig(matrix0)
            eigenvalue_k[j0, i0, :] = np.sort(np.real(eigenvalue[:]))
            j0 += 1
        i0 += 1
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    k1, k2 = np.meshgrid(k1, k2)
    for dim0 in range(dim):
        ax.plot_surface(k1, k2, eigenvalue_k[:, :, dim0], cmap=cm.coolwarm, linewidth=0, antialiased=False)
    plt.show()


if __name__ == '__main__':
    main()

画出的能带图为:

当参数设为M=0, t1=1, t2=0, phi=0,画出的是最简单的石墨烯模型能带。这里画出的Haldane能带图也只是看到是绝缘体,是看不出来拓扑的。是否拓扑要通过计算陈数来判断。关于Haldane模型陈数的计算,参考这一篇:Haldane模型中陈数的计算(附Python代码)

下面计算准一维(条带)的情况。在拓扑时,能带中会出现交叉的边缘态。准一维的情况可参考:准一维方格子能带图(附Python代码)石墨烯哈密顿量与能带图(附Python代码)

Python代码如下(这里只考虑Zigzag边的情形):

"""
This code is supported by the website: https://www.guanjihuan.com
The newest version of this code is on the web page: https://www.guanjihuan.com/archives/410
"""

import numpy as np
import matplotlib.pyplot as plt
from math import *
import cmath 
import functools


def hamiltonian(k, N, M, t1, t2, phi):  # Haldane哈密顿量(N是条带的宽度参数)
    # 初始化为零矩阵
    h00 = np.zeros((4*N, 4*N), dtype=complex)
    h01 = np.zeros((4*N, 4*N), dtype=complex)

    # 原胞内的跃迁h00
    for i in range(N):
        h00[i*4+0, i*4+0] = M
        h00[i*4+1, i*4+1] = -M
        h00[i*4+2, i*4+2] = M
        h00[i*4+3, i*4+3] = -M

        # 最近邻
        h00[i*4+0, i*4+1] = t1
        h00[i*4+1, i*4+0] = t1
        h00[i*4+1, i*4+2] = t1
        h00[i*4+2, i*4+1] = t1
        h00[i*4+2, i*4+3] = t1
        h00[i*4+3, i*4+2] = t1

        # 次近邻
        h00[i*4+0, i*4+2] = t2*cmath.exp(-1j*phi)
        h00[i*4+2, i*4+0] = h00[i*4+0, i*4+2].conj()
        h00[i*4+1, i*4+3] = t2*cmath.exp(-1j*phi)
        h00[i*4+3, i*4+1] = h00[i*4+1, i*4+3].conj()
    for i in range(N-1):
        # 最近邻
        h00[i*4+3, (i+1)*4+0] = t1
        h00[(i+1)*4+0, i*4+3] = t1

        # 次近邻
        h00[i*4+2, (i+1)*4+0] = t2*cmath.exp(1j*phi)
        h00[(i+1)*4+0, i*4+2] = h00[i*4+2, (i+1)*4+0].conj()
        h00[i*4+3, (i+1)*4+1] = t2*cmath.exp(1j*phi)
        h00[(i+1)*4+1, i*4+3] = h00[i*4+3, (i+1)*4+1].conj()

    # 原胞间的跃迁h01
    for i in range(N):
        # 最近邻
        h01[i*4+1, i*4+0] = t1
        h01[i*4+2, i*4+3] = t1

        # 次近邻
        h01[i*4+0, i*4+0] = t2*cmath.exp(1j*phi)
        h01[i*4+1, i*4+1] = t2*cmath.exp(-1j*phi)
        h01[i*4+2, i*4+2] = t2*cmath.exp(1j*phi)
        h01[i*4+3, i*4+3] = t2*cmath.exp(-1j*phi)

        h01[i*4+1, i*4+3] = t2*cmath.exp(1j*phi)
        h01[i*4+2, i*4+0] = t2*cmath.exp(-1j*phi)
        if i != 0:
            h01[i*4+1, (i-1)*4+3] = t2*cmath.exp(1j*phi)
    for i in range(N-1):
        h01[i*4+2, (i+1)*4+0] = t2*cmath.exp(-1j*phi)

    matrix = h00 + h01*cmath.exp(1j*k) + h01.transpose().conj()*cmath.exp(-1j*k)
    return matrix


def main():
    hamiltonian0 = functools.partial(hamiltonian, N=40, M=2/3, t1=1, t2=1/3, phi=pi/4)
    k = np.linspace(-pi, pi, 300)
    plot_bands_one_dimension(k, hamiltonian0)


def plot_bands_one_dimension(k, hamiltonian):
    dim = hamiltonian(0).shape[0]
    dim_k = k.shape[0]
    eigenvalue_k = np.zeros((dim_k, dim))
    i0 = 0
    for k0 in k:
        matrix0 = hamiltonian(k0)
        eigenvalue, eigenvector = np.linalg.eig(matrix0)
        eigenvalue_k[i0, :] = np.sort(np.real(eigenvalue[:]))
        i0 += 1
    for dim0 in range(dim):
        plt.plot(k, eigenvalue_k[:, dim0], '-k')
    plt.show()


if __name__ == '__main__':
    main()

画出的能带图为:

这里模型参数来源于这篇文献: Insulator/Chern-insulator transition in the Haldane model

可以明显看到交叉的两条线,为拓扑边缘态。这个边缘态也叫做Chiral edge states,是受到拓扑保护的。一个直观的理解是:拓扑绝缘体的外面是真空,属于平庸的绝缘态。从拓扑态到平庸态,能带要发生反转。边缘态就是这个能带反转的过渡区域,具有交叉状的能带。

此外,用上“Kane-Mele模型的哈密顿量和能带图”博文中的模型参数(N=40, M=0, t1=1, t2=0.03, phi=pi/2),结果为:

24,466 次浏览

【说明:本站主要是个人的一些笔记和代码分享,内容可能会不定期修改。为了使全网显示的始终是最新版本,这里的文章未经同意请勿转载。引用请注明出处:https://www.guanjihuan.com

33 thoughts on “Haldane模型哈密顿量与能带图(附Python代码)”

  1. 关老师我想问一下,两个加正负磁场的Haldane模型组成的边界态,边界处是不是只有最近邻耦合,没有次近邻耦合。

  2. 关老师您好,有个疑惑就是为啥霍尔丹模型打破了时间反演对称性后边界态是那种交叉的呢(如您这篇文章中所示)?但是我看有的文献TIs打破了时间反演对称性边界态能带反而是那种单向的,如https://doi.org/10.1021/acs.chemrev.2c00800 Fig. 6 (a)-(b)所说。(b)图又说反而是保证了TRS的TIs才有那种交叉的边界态能带。

  3. 前辈,请问画蜂窝晶格或者Haldane模型的边缘态的时候,怎么在程序中体现出左边缘和右边缘

  4. 关老师,能问你个问题吗?有两条隙内边缘态,是怎么判断能带交叉后发生了翻转呢(因为在此,隙内的边缘态并未区分)

    1. 这里的能带反转指的是二维体带,不包括边缘态。如果连续改变模型的参数,拓扑转变的过程中,体带的能带是会发生闭合再打开的。当然,能带反转不是拓扑相变的充分条件或者必要条件,只是一个比较有用的指标,具体还是需要算拓扑不变量来确定。

      1. 关老师,那如果只想看其中一条边缘能带的趋势/在改变参数的时候是否反转,在代码中怎么实现呢?

  5. 关老师,我们都知道如果改变Haldane模型的一组次近邻耦合方向会产生反手性的边界态,同时耦合方向的改变会使系统的磁通为0,那么系统的磁通为0是不是一个系统产生反手性边界态的一个很重要的条件。(表述不太专业,望关老师见谅)

    1. 可能是吧,这样可以保持整个体系是半金属。但我不确定是不是一个必要条件,可能也有其他特殊的情况。

  6. 关博士您好,看您的矩阵形式貌似和prb74.235111就是你标注的那篇文献的规范选择并非完全一致的

      1. 是考虑了带有相位的t2才是相当于加了磁通,可以参考Haldane的那篇文章

  7. 关博士您好,我想请教一下边缘态只有准一维情况下才会出现吗?还有Edge spectrum和边缘态又是什么关系呢?

    1. 不一定,在量子点的情况下也会出现,只要有边缘就有边缘态。如果是二维拓扑材料,在二维的情况就没有边缘态,因为没有边缘。Edge spectrum应该就指的是能带中是边缘态的部分,是一回事。

    1. 从图中可以看出:A到A的次近邻跃迁应该要有六项。而在代码中,h2只写出了其中三项,另外三项用h2的厄密共轭来表示,即h2.transpose().conj()

  8. 博主您好,我画了一下armchair型石墨烯的能带图,发现也有这种交叉的X型边缘态,可是其中没有加质量项也没有磁通,仅考虑了最近邻hopping。我想知道这种X型边缘态和haldane model里的这种X型边缘态有什么区别吗?它和拓扑又有什么关系吗?

    1. 交叉的能带应该是石墨烯狄拉克锥在一维条带中的结果。体系为狄拉克半金属,不是绝缘体,更不是拓扑绝缘体。你说的这个交叉的带应该是属于体态的性质,并且对条带宽度比较敏感,具体我也没算过。建议可以看下相关的综述文献。

  9. 你好,请问有没有用实际原子坐标表示时的哈密顿量? 我自己写了一个,跟用原胞坐标画出来的能带结构不一样。不知道哪里错了。。。

    1. 其实两个方法是一样的。要把矩阵元每一项都写对,可以参考本文中代码赋值的情况,就大概知道有哪些项。还有次近邻跃迁相位的正负也要写对。

  10. 您好,请问求解边界态的那个哈密顿量与第一个kx,ky皆作傅里叶变换相比,区别仅仅是在ky做傅里叶变换,kx方向取有限个吗?

    1. 如果是周期性边界条件,是相当于k取有限个。如果是开放边界条件会出现边缘态,就不完全是对应的。

    1. 选取个t1值,计算体系本征值E(离散的N个点)。当t1选取为一个区间时,对应的就是N条曲线,即E和t1的关系图。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

Captcha Code