陈数Chern number的计算(Wilson loop方法,附Python代码)

陈数Chern number的计算(Wilson loop方法,附Python代码)

这是之前关于陈数的计算:

陈数Chern number的计算(定义法,附Python/Matlab代码)

陈数Chern number的计算(高效法,附Python/Matlab代码)

陈数Chern number的计算(Kubo公式,附Python代码)

本篇计算方法见参考资料:https://topocondmat.org/w4_haldane/ComputingChern.html。该方法同样不需要对波函数取连续规范。

说明:本篇的代码不支持能带交叉或简并,多条能带同时计算的代码阅读这篇:陈数Chern number的计算(多条能带的Wilson loop方法,附Python代码)。

为了防止原链接失效后无法访问,这里截图如下:

下面仍然以这篇“陈数Chern number的计算(定义法,附Python/Matlab代码)”中的哈密顿量为例子,Python程序如下。

一、初始代码

首先给出一个初始代码,这里计算结果的实部是正确的,但虚部的值比较大,一个可能的原因是因为计算一个small plaquettes的Wilson loop时取点的个数太少,仅取了四个点。

补充说明:Wilson loop方法计算结果之所以存在虚部,根本原因是因为Wilson loop之后没有除以归一化系数。如果考虑了归一化系数,就没有虚部,参考这篇中的公式:陈数Chern number的计算(高效法,附Python/Matlab代码),感谢Song MR同学参与的讨论。另外,微信公众号的这篇文章也给出了原因:https://mp.weixin.qq.com/s/Ci8FCjtj7I93PE5aHmgrzA。如果考虑了归一化系数,这里的表达式和高效法的表达式是完全一致的。个人推荐加上这个归一化系数。

"""

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/18319

"""

"""

Notice that this code is not correct for calculating the Chern number because of the low precision in the calculation of Wilson loop!

"""

import numpy as np

from math import *

import time

import cmath

def hamiltonian(kx, ky): # 量子反常霍尔QAH模型(该参数对应的陈数为2)

t1 = 1.0

t2 = 1.0

t3 = 0.5

m = -1.0

matrix = np.zeros((2, 2), dtype=complex)

matrix[0, 1] = 2*t1*cos(kx)-1j*2*t1*cos(ky)

matrix[1, 0] = 2*t1*cos(kx)+1j*2*t1*cos(ky)

matrix[0, 0] = m+2*t3*sin(kx)+2*t3*sin(ky)+2*t2*cos(kx+ky)

matrix[1, 1] = -(m+2*t3*sin(kx)+2*t3*sin(ky)+2*t2*cos(kx+ky))

return matrix

def main():

start_time = time.time()

n = 200 # 积分密度

delta = 2*pi/n

chern_number = 0

for kx in np.arange(-pi, pi, delta):

for ky in np.arange(-pi, pi, delta):

H = hamiltonian(kx, ky)

eigenvalue, eigenvector = np.linalg.eig(H)

vector = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 价带波函数

# vector = eigenvector[:, np.argsort(np.real(eigenvalue))[0]]*cmath.exp(1j*np.random.uniform(0, pi)) # 验证规范不依赖性

H_delta_kx = hamiltonian(kx+delta, ky)

eigenvalue, eigenvector = np.linalg.eig(H_delta_kx)

vector_delta_kx = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 略偏离kx的波函数

H_delta_ky = hamiltonian(kx, ky+delta)

eigenvalue, eigenvector = np.linalg.eig(H_delta_ky)

vector_delta_ky = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 略偏离ky的波函数

H_delta_kx_ky = hamiltonian(kx+delta, ky+delta)

eigenvalue, eigenvector = np.linalg.eig(H_delta_kx_ky)

vector_delta_kx_ky = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 略偏离kx和ky的波函数

line_1 = np.dot(vector.transpose().conj(), vector_delta_kx)

line_2 = np.dot(vector_delta_kx.transpose().conj(), vector_delta_kx_ky)

line_3 = np.dot(vector_delta_kx_ky.transpose().conj(), vector_delta_ky)

line_4 = np.dot(vector_delta_ky.transpose().conj(), vector)

arg = np.log(np.dot(np.dot(np.dot(line_1, line_2), line_3), line_4))/1j

chern_number = chern_number + arg

chern_number = chern_number/(2*pi)

print('Chern number = ', chern_number)

end_time = time.time()

print('运行时间(秒)=', end_time-start_time)

if __name__ == '__main__':

main()

运行结果:

Chern number = (2.0000000000000013+2.6085429982998165j)

二、Wilson loop增加取点的代码

"""

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/18319

"""

import numpy as np

from math import *

import time

import cmath

def hamiltonian(kx, ky): # 量子反常霍尔QAH模型(该参数对应的陈数为2)

t1 = 1.0

t2 = 1.0

t3 = 0.5

m = -1.0

matrix = np.zeros((2, 2), dtype=complex)

matrix[0, 1] = 2*t1*cos(kx)-1j*2*t1*cos(ky)

matrix[1, 0] = 2*t1*cos(kx)+1j*2*t1*cos(ky)

matrix[0, 0] = m+2*t3*sin(kx)+2*t3*sin(ky)+2*t2*cos(kx+ky)

matrix[1, 1] = -(m+2*t3*sin(kx)+2*t3*sin(ky)+2*t2*cos(kx+ky))

return matrix

def main():

start_time = time.time()

n1 = 10 # small plaquettes精度

n2 = 800 # Wilson loop精度

delta = 2*pi/n1

chern_number = 0

for kx in np.arange(-pi, pi, delta):

for ky in np.arange(-pi, pi, delta):

vector_array = []

# line_1

for i2 in range(n2):

H_delta = hamiltonian(kx+delta/n2*i2, ky)

eigenvalue, eigenvector = np.linalg.eig(H_delta)

vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))[0]]

# vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))[0]]*cmath.exp(1j*np.random.uniform(0, pi)) # 验证规范不依赖性

vector_array.append(vector_delta)

# line_2

for i2 in range(n2):

H_delta = hamiltonian(kx+delta, ky+delta/n2*i2)

eigenvalue, eigenvector = np.linalg.eig(H_delta)

vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))[0]]

vector_array.append(vector_delta)

# line_3

for i2 in range(n2):

H_delta = hamiltonian(kx+delta-delta/n2*i2, ky+delta)

eigenvalue, eigenvector = np.linalg.eig(H_delta)

vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))[0]]

vector_array.append(vector_delta)

# line_4

for i2 in range(n2):

H_delta = hamiltonian(kx, ky+delta-delta/n2*i2)

eigenvalue, eigenvector = np.linalg.eig(H_delta)

vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))[0]]

vector_array.append(vector_delta)

Wilson_loop = 1

for i0 in range(len(vector_array)-1):

Wilson_loop = Wilson_loop*np.dot(vector_array[i0].transpose().conj(), vector_array[i0+1])

Wilson_loop = Wilson_loop*np.dot(vector_array[len(vector_array)-1].transpose().conj(), vector_array[0])

arg = np.log(Wilson_loop)/1j

chern_number = chern_number + arg

chern_number = chern_number/(2*pi)

print('Chern number = ', chern_number)

end_time = time.time()

print('运行时间(秒)=', end_time-start_time)

if __name__ == '__main__':

main()

运行结果:

Chern number = (1.9999999999999987+0.0032600066414606387j)

随着Wilson loop计算精度的提高,虚部将趋于0。

其他参考资料:

[1] 数学上陈数(Chern number)或 Berry Phase 有何意义?

[2] 贝里相位、贝里联络、贝里曲率和陈数

[3] B. Andrei Bernevig - Topological Insulators and Topological Superconductors 第30页

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

关键点

这是之前关于陈数的计算: 陈数Chern number的计算(定义法,附Python/Matlab代码) 陈数Chern number的计算(高效法,附Python/Matlab代码) 陈数Chern numbe

相关文章