This commit is contained in:
2023-07-26 00:46:01 +08:00
parent c7cbcd09af
commit 822fa7e626
212 changed files with 5687 additions and 5687 deletions

View File

@@ -0,0 +1,50 @@
% 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/3932
%
clear;clc;
n=100; %
delta=1e-9; %
C=0;
for kx=-pi:(1/n):pi
for ky=-pi:(1/n):pi
VV=get_vector(HH(kx,ky));
Vkx=get_vector(HH(kx+delta,ky)); % kx
Vky=get_vector(HH(kx,ky+delta)); % ky
Vkxky=get_vector(HH(kx+delta,ky+delta)); % kxky
if sum((abs(Vkx-VV)))>0.01 %
Vkx=-Vkx;
end
if sum((abs(Vky-VV)))>0.01
Vky=-Vky;
end
if sum(abs(Vkxky-VV))>0.01
Vkxky=-Vkxky;
end
% berry connection
Ax=VV'*(Vkx-VV)/delta; % Berry connection Ax
Ay=VV'*(Vky-VV)/delta; % Berry connection Ay
Ax_delta_ky=Vky'*(Vkxky-Vky)/delta; % kyberry connection Ax
Ay_delta_kx=Vkx'*(Vkxky-Vkx)/delta; % kxberry connection Ay
% berry curvature
F=((Ay_delta_kx-Ay)-(Ax_delta_ky-Ax))/delta;
% chern number
C=C+F*(1/n)^2;
end
end
C=C/(2*pi*1i)
function vector_new = get_vector(H)
[vector,eigenvalue] = eig(H);
[eigenvalue, index]=sort(diag(eigenvalue), 'descend');
vector_new = vector(:, index(2));
end
function H=HH(kx,ky)
H(1,2)=2*cos(kx)-1i*2*cos(ky);
H(2,1)=2*cos(kx)+1i*2*cos(ky);
H(1,1)=-1+2*0.5*sin(kx)+2*0.5*sin(ky)+2*cos(kx+ky);
H(2,2)=-(-1+2*0.5*sin(kx)+2*0.5*sin(ky)+2*cos(kx+ky));
end

View File

@@ -0,0 +1,69 @@
"""
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/3932
"""
import numpy as np
from math import *
import time
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 = 100 # 积分密度
delta = 1e-9 # 求导的偏离量
chern_number = 0 # 陈数初始化
for kx in np.arange(-pi, pi, 2*pi/n):
for ky in np.arange(-pi, pi, 2*pi/n):
H = hamiltonian(kx, ky)
eigenvalue, eigenvector = np.linalg.eig(H)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 价带波函数
# print(np.argsort(np.real(eigenvalue))[0]) # 排序索引(从小到大)
# print(eigenvalue) # 排序前的本征值
# print(np.sort(np.real(eigenvalue))) # 排序后的本征值(从小到大)
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的波函数
# 价带的波函数的贝里联络(berry connection) # 求导后内积
A_x = np.dot(vector.transpose().conj(), (vector_delta_kx-vector)/delta) # 贝里联络Axx分量
A_y = np.dot(vector.transpose().conj(), (vector_delta_ky-vector)/delta) # 贝里联络Ayy分量
A_x_delta_ky = np.dot(vector_delta_ky.transpose().conj(), (vector_delta_kx_ky-vector_delta_ky)/delta) # 略偏离ky的贝里联络Ax
A_y_delta_kx = np.dot(vector_delta_kx.transpose().conj(), (vector_delta_kx_ky-vector_delta_kx)/delta) # 略偏离kx的贝里联络Ay
# 贝里曲率(berry curvature)
F = (A_y_delta_kx-A_y)/delta-(A_x_delta_ky-A_x)/delta
# 陈数(chern number)
chern_number = chern_number + F*(2*pi/n)**2
chern_number = chern_number/(2*pi*1j)
print('Chern number = ', chern_number)
end_time = time.time()
print('运行时间(min)=', (end_time-start_time)/60)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,107 @@
"""
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/3932
"""
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 = 20 # 积分密度
delta = 1e-9 # 求导的偏离量
chern_number = 0 # 陈数初始化
for kx in np.arange(-pi, pi, 2*pi/n):
for ky in np.arange(-pi, pi, 2*pi/n):
H = hamiltonian(kx, ky)
eigenvalue, eigenvector = np.linalg.eig(H)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 价带波函数
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的波函数
vector_delta_kx = find_vector_with_the_same_gauge(vector_delta_kx, vector)
vector_delta_ky = find_vector_with_the_same_gauge(vector_delta_ky, vector)
vector_delta_kx_ky = find_vector_with_the_same_gauge(vector_delta_kx_ky, vector)
# 价带的波函数的贝里联络(berry connection) # 求导后内积
A_x = np.dot(vector.transpose().conj(), (vector_delta_kx-vector)/delta) # 贝里联络Axx分量
A_y = np.dot(vector.transpose().conj(), (vector_delta_ky-vector)/delta) # 贝里联络Ayy分量
A_x_delta_ky = np.dot(vector_delta_ky.transpose().conj(), (vector_delta_kx_ky-vector_delta_ky)/delta) # 略偏离ky的贝里联络Ax
A_y_delta_kx = np.dot(vector_delta_kx.transpose().conj(), (vector_delta_kx_ky-vector_delta_kx)/delta) # 略偏离kx的贝里联络Ay
# 贝里曲率(berry curvature)
F = (A_y_delta_kx-A_y)/delta-(A_x_delta_ky-A_x)/delta
# 陈数(chern number)
chern_number = chern_number + F*(2*pi/n)**2
chern_number = chern_number/(2*pi*1j)
print('Chern number = ', chern_number)
end_time = time.time()
print('运行时间(min)=', (end_time-start_time)/60)
def find_vector_with_the_same_gauge(vector_1, vector_0):
# 寻找近似的同一的规范
phase_1_pre = 0
phase_2_pre = pi
n_test = 10001
for i0 in range(n_test):
test_1 = np.sum(np.abs(vector_1*cmath.exp(1j*phase_1_pre) - vector_0))
test_2 = np.sum(np.abs(vector_1*cmath.exp(1j*phase_2_pre) - vector_0))
if test_1 < 1e-8:
phase = phase_1_pre
# print('Done with i0=', i0)
break
if i0 == n_test-1:
phase = phase_1_pre
print('Gauge Not Found with i0=', i0)
if test_1 < test_2:
if i0 == 0:
phase_1 = phase_1_pre-(phase_2_pre-phase_1_pre)/2
phase_2 = phase_1_pre+(phase_2_pre-phase_1_pre)/2
else:
phase_1 = phase_1_pre
phase_2 = phase_1_pre+(phase_2_pre-phase_1_pre)/2
else:
if i0 == 0:
phase_1 = phase_2_pre-(phase_2_pre-phase_1_pre)/2
phase_2 = phase_2_pre+(phase_2_pre-phase_1_pre)/2
else:
phase_1 = phase_2_pre-(phase_2_pre-phase_1_pre)/2
phase_2 = phase_2_pre
phase_1_pre = phase_1
phase_2_pre = phase_2
vector_1 = vector_1*cmath.exp(1j*phase)
# print('二分查找找到的规范=', phase)
return vector_1
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,90 @@
"""
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/3932
"""
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 = 20 # 积分密度
delta = 1e-9 # 求导的偏离量
chern_number = 0 # 陈数初始化
for kx in np.arange(-pi, pi, 2*pi/n):
for ky in np.arange(-pi, pi, 2*pi/n):
H = hamiltonian(kx, ky)
eigenvalue, eigenvector = np.linalg.eig(H)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 价带波函数
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的波函数
index = np.argmax(np.abs(vector))
precision = 0.0001
vector = find_vector_with_fixed_gauge_by_making_one_component_real(vector, precision=precision, index=index)
vector_delta_kx = find_vector_with_fixed_gauge_by_making_one_component_real(vector_delta_kx, precision=precision, index=index)
vector_delta_ky = find_vector_with_fixed_gauge_by_making_one_component_real(vector_delta_ky, precision=precision, index=index)
vector_delta_kx_ky = find_vector_with_fixed_gauge_by_making_one_component_real(vector_delta_kx_ky, precision=precision, index=index)
# 价带的波函数的贝里联络(berry connection) # 求导后内积
A_x = np.dot(vector.transpose().conj(), (vector_delta_kx-vector)/delta) # 贝里联络Axx分量
A_y = np.dot(vector.transpose().conj(), (vector_delta_ky-vector)/delta) # 贝里联络Ayy分量
A_x_delta_ky = np.dot(vector_delta_ky.transpose().conj(), (vector_delta_kx_ky-vector_delta_ky)/delta) # 略偏离ky的贝里联络Ax
A_y_delta_kx = np.dot(vector_delta_kx.transpose().conj(), (vector_delta_kx_ky-vector_delta_kx)/delta) # 略偏离kx的贝里联络Ay
# 贝里曲率(berry curvature)
F = (A_y_delta_kx-A_y)/delta-(A_x_delta_ky-A_x)/delta
# 陈数(chern number)
chern_number = chern_number + F*(2*pi/n)**2
chern_number = chern_number/(2*pi*1j)
print('Chern number = ', chern_number)
end_time = time.time()
print('运行时间(min)=', (end_time-start_time)/60)
def find_vector_with_fixed_gauge_by_making_one_component_real(vector, precision=0.005, index=None):
vector = np.array(vector)
if index == None:
index = np.argmax(np.abs(vector))
sign_pre = np.sign(np.imag(vector[index]))
for phase in np.arange(0, 2*np.pi, precision):
sign = np.sign(np.imag(vector[index]*cmath.exp(1j*phase)))
if np.abs(np.imag(vector[index]*cmath.exp(1j*phase))) < 1e-9 or sign == -sign_pre:
break
sign_pre = sign
vector = vector*cmath.exp(1j*phase)
if np.real(vector[index]) < 0:
vector = -vector
return vector
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,40 @@
% 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/4179
%
clear;clc;
n=1000 %
delta=2*pi/n;
C=0;
for kx=-pi:(2*pi/n):pi
for ky=-pi:(2*pi/n):pi
VV=get_vector(HH(kx,ky));
Vkx=get_vector(HH(kx+delta,ky)); % kx
Vky=get_vector(HH(kx,ky+delta)); % ky
Vkxky=get_vector(HH(kx+delta,ky+delta)); % kxky
Ux = VV'*Vkx/abs(VV'*Vkx);
Uy = VV'*Vky/abs(VV'*Vky);
Ux_y = Vky'*Vkxky/abs(Vky'*Vkxky);
Uy_x = Vkx'*Vkxky/abs(Vkx'*Vkxky);
% berry curvature
F=log(Ux*Uy_x*(1/Ux_y)*(1/Uy));
% chern number
C=C+F;
end
end
C=C/(2*pi*1i)
function vector_new = get_vector(H)
[vector,eigenvalue] = eig(H);
[eigenvalue, index]=sort(diag(eigenvalue), 'descend');
vector_new = vector(:, index(2));
end
function H=HH(kx,ky)
H(1,2)=2*cos(kx)-1i*2*cos(ky);
H(2,1)=2*cos(kx)+1i*2*cos(ky);
H(1,1)=-1+2*0.5*sin(kx)+2*0.5*sin(ky)+2*cos(kx+ky);
H(2,2)=-(-1+2*0.5*sin(kx)+2*0.5*sin(ky)+2*cos(kx+ky));
end

View File

@@ -0,0 +1,65 @@
"""
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/4179
"""
import numpy as np
import matplotlib.pyplot as plt
from math import * # 引入pi, cos等
import cmath
import time
def hamiltonian(kx, ky): # 量子反常霍尔QAH模型该参数对应的陈数为2
t1 = 1.0
t2 = 1.0
t3 = 0.5
m = -1.0
matrix = np.zeros((2, 2))*(1+0j)
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 = 100
delta = 2*pi/n
chern_number = 0 # 陈数初始化
for kx in np.arange(-pi, pi, 2*pi/n):
for ky in np.arange(-pi, pi, 2*pi/n):
H = hamiltonian(kx, ky)
eigenvalue, eigenvector = np.linalg.eig(H)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 价带波函数
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的波函数
Ux = np.dot(np.conj(vector), vector_delta_kx)/abs(np.dot(np.conj(vector), vector_delta_kx))
Uy = np.dot(np.conj(vector), vector_delta_ky)/abs(np.dot(np.conj(vector), vector_delta_ky))
Ux_y = np.dot(np.conj(vector_delta_ky), vector_delta_kx_ky)/abs(np.dot(np.conj(vector_delta_ky), vector_delta_kx_ky))
Uy_x = np.dot(np.conj(vector_delta_kx), vector_delta_kx_ky)/abs(np.dot(np.conj(vector_delta_kx), vector_delta_kx_ky))
F = cmath.log(Ux*Uy_x*(1/Ux_y)*(1/Uy))
# 陈数(chern number)
chern_number = chern_number + F
chern_number = chern_number/(2*pi*1j)
print('Chern number = ', chern_number)
end_time = time.time()
print('运行时间(min)=', (end_time-start_time)/60)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,94 @@
"""
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/5133
"""
import numpy as np
from math import * # 引入pi, cos等
import cmath
import time
import functools # 使用偏函数functools.partial()
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()
#次近邻项 # 对应陈数为-1
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))
# # 次近邻项 # 对应陈数为1
# 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():
start_clock = time.perf_counter()
delta = 0.005
chern_number = 0 # 陈数初始化
# 几个坐标中常出现的项
a = 1/sqrt(3)
aa1 = 4*sqrt(3)*pi/9/a
aa2 = 2*sqrt(3)*pi/9/a
bb1 = 2*pi/3/a
hamiltonian0 = functools.partial(hamiltonian, M=2/3, t1=1, t2=1/3, phi=pi/4, a=a) # 使用偏函数,固定一些参数
for kx in np.arange(-aa1, aa1, delta):
print(kx)
for ky in np.arange(-bb1, bb1, delta):
if (-aa2<=kx<=aa2) or (kx>aa2 and -(aa1-kx)*tan(pi/3)<=ky<=(aa1-kx)*tan(pi/3)) or (kx<-aa2 and -(kx-(-aa1))*tan(pi/3)<=ky<=(kx-(-aa1))*tan(pi/3)): # 限制在六角格子布里渊区内
H = hamiltonian0(kx, ky)
eigenvalue, eigenvector = np.linalg.eig(H)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 价带波函数
H_delta_kx = hamiltonian0(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 = hamiltonian0(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 = hamiltonian0(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的波函数
Ux = np.dot(np.conj(vector), vector_delta_kx)/abs(np.dot(np.conj(vector), vector_delta_kx))
Uy = np.dot(np.conj(vector), vector_delta_ky)/abs(np.dot(np.conj(vector), vector_delta_ky))
Ux_y = np.dot(np.conj(vector_delta_ky), vector_delta_kx_ky)/abs(np.dot(np.conj(vector_delta_ky), vector_delta_kx_ky))
Uy_x = np.dot(np.conj(vector_delta_kx), vector_delta_kx_ky)/abs(np.dot(np.conj(vector_delta_kx), vector_delta_kx_ky))
F = cmath.log(Ux*Uy_x*(1/Ux_y)*(1/Uy))
# 陈数(chern number)
chern_number = chern_number + F
chern_number = chern_number/(2*pi*1j)
print('Chern number = ', chern_number)
end_clock = time.perf_counter()
print('CPU执行时间(min)=', (end_clock-start_clock)/60)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,91 @@
"""
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/5133
"""
import numpy as np
import matplotlib.pyplot as plt
from math import * # 引入pi, cos等
import cmath
import time
import functools # 使用偏函数functools.partial()
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()
#次近邻项 # 对应陈数为-1
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))
# # 次近邻项 # 对应陈数为1
# 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():
start_clock = time.perf_counter()
delta = 0.005
chern_number = 0 # 陈数初始化
# 常出现的项
a = 1/sqrt(3)
bb1 = 2*sqrt(3)*pi/3/a
bb2 = 2*pi/3/a
hamiltonian0 = functools.partial(hamiltonian, M=2/3, t1=1, t2=1/3, phi=pi/4, a=a) # 使用偏函数,固定一些参数
for kx in np.arange(0 , bb1, delta):
print(kx)
for ky in np.arange(0, 2*bb2, delta):
H = hamiltonian0(kx, ky)
eigenvalue, eigenvector = np.linalg.eig(H)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 价带波函数
H_delta_kx = hamiltonian0(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 = hamiltonian0(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 = hamiltonian0(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的波函数
Ux = np.dot(np.conj(vector), vector_delta_kx)/abs(np.dot(np.conj(vector), vector_delta_kx))
Uy = np.dot(np.conj(vector), vector_delta_ky)/abs(np.dot(np.conj(vector), vector_delta_ky))
Ux_y = np.dot(np.conj(vector_delta_ky), vector_delta_kx_ky)/abs(np.dot(np.conj(vector_delta_ky), vector_delta_kx_ky))
Uy_x = np.dot(np.conj(vector_delta_kx), vector_delta_kx_ky)/abs(np.dot(np.conj(vector_delta_kx), vector_delta_kx_ky))
F = cmath.log(Ux*Uy_x*(1/Ux_y)*(1/Uy))
# 陈数(chern number)
chern_number = chern_number + F
chern_number = chern_number/(2*pi*1j)
print('Chern number = ', chern_number)
end_clock = time.perf_counter()
print('CPU执行时间(min)=', (end_clock-start_clock)/60)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,99 @@
"""
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/5133
"""
import numpy as np
import matplotlib.pyplot as plt
from math import * # 引入pi, cos等
import cmath
import time
import functools # 使用偏函数functools.partial()
def hamiltonian(k1, k2, M, t1, t2, phi, a=1/sqrt(3)): # Haldane哈密顿量# 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()
#次近邻项 # 对应陈数为-1
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))
# # 次近邻项 # 对应陈数为1
# 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():
start_clock = time.perf_counter()
delta = 0.005
chern_number = 0 # 陈数初始化
# 常出现的项
a = 1/sqrt(3)
bb1 = 2*sqrt(3)*pi/3/a
bb2 = 2*pi/3/a
hamiltonian0 = functools.partial(hamiltonian, M=2/3, t1=1, t2=1/3, phi=pi/4, a=a) # 使用偏函数,固定一些参数
for k1 in np.arange(0 , 1, delta):
print(k1)
for k2 in np.arange(0, 1, delta):
# 坐标变换
kx = (k1-k2)*bb1
ky = (k1+k2)*bb2
# 这里乘2或除以2是为了保证“步长与积分个数的乘积刚好为布里渊区面积”
delta_x = delta*bb1*2
delta_y = delta*bb2*2/2
H = hamiltonian0(kx, ky)
eigenvalue, eigenvector = np.linalg.eig(H)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 价带波函数
H_delta_kx = hamiltonian0(kx+delta_x, ky)
eigenvalue, eigenvector = np.linalg.eig(H_delta_kx)
vector_delta_kx = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 略偏离kx的波函数
H_delta_ky = hamiltonian0(kx, ky+delta_y)
eigenvalue, eigenvector = np.linalg.eig(H_delta_ky)
vector_delta_ky = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 略偏离ky的波函数
H_delta_kx_ky = hamiltonian0(kx+delta_x, ky+delta_y)
eigenvalue, eigenvector = np.linalg.eig(H_delta_kx_ky)
vector_delta_kx_ky = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 略偏离kx和ky的波函数
Ux = np.dot(np.conj(vector), vector_delta_kx)/abs(np.dot(np.conj(vector), vector_delta_kx))
Uy = np.dot(np.conj(vector), vector_delta_ky)/abs(np.dot(np.conj(vector), vector_delta_ky))
Ux_y = np.dot(np.conj(vector_delta_ky), vector_delta_kx_ky)/abs(np.dot(np.conj(vector_delta_ky), vector_delta_kx_ky))
Uy_x = np.dot(np.conj(vector_delta_kx), vector_delta_kx_ky)/abs(np.dot(np.conj(vector_delta_kx), vector_delta_kx_ky))
F = cmath.log(Ux*Uy_x*(1/Ux_y)*(1/Uy))
# 陈数(chern number)
chern_number = chern_number + F
chern_number = chern_number/(2*pi*1j)
print('Chern number = ', chern_number)
end_clock = time.perf_counter()
print('CPU执行时间(min)=', (end_clock-start_clock)/60)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,41 @@
"""
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/5025
"""
import numpy as np
import matplotlib.pyplot as plt
from math import *
import cmath
import time
def hamiltonian(k): # SSH模型
v=0.6
w=1
matrix = np.zeros((2, 2), dtype=complex)
matrix[0,1] = v+w*cmath.exp(-1j*k)
matrix[1,0] = v+w*cmath.exp(1j*k)
return matrix
def main():
start_clock = time.perf_counter()
delta_1 = 1e-9 # 求导的步长(求导的步长可以尽可能短)
delta_2 = 1e-5 # 积分的步长(积分步长和计算时间相关,因此取一个合理值即可)
W = 0 # Winding number初始化
for k in np.arange(-pi, pi, delta_2):
H = hamiltonian(k)
log0 = cmath.log(H[0, 1])
H_delta = hamiltonian(k+delta_1)
log1 = cmath.log(H_delta[0, 1])
W = W + (log1-log0)/delta_1*delta_2 # Winding number
print('Winding number = ', W/2/pi/1j)
end_clock = time.perf_counter()
print('CPU执行时间(min)=', (end_clock-start_clock)/60)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,42 @@
"""
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/5025
"""
import numpy as np
import matplotlib.pyplot as plt
from math import *
import cmath
def hamiltonian(k): # SSH模型
v=0.6
w=1
matrix = np.zeros((2, 2), dtype=complex)
matrix[0,1] = v+w*cmath.exp(-1j*k)
matrix[1,0] = v+w*cmath.exp(1j*k)
return matrix
def main():
k = np.linspace(-pi, pi, 100)
plot_bands_one_dimension(k, hamiltonian)
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()

View File

@@ -0,0 +1,68 @@
% 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/5778
clear;clc;
delta=0.1;
Z2=0;
for kx=-pi:0.1:0
for ky=-pi:0.1:pi
[V1,V2]=get_vector(Hamiltonian(kx,ky));
[Vkx1,Vkx2]=get_vector(Hamiltonian(kx+delta,ky)); % kx
[Vky1,Vky2]=get_vector(Hamiltonian(kx,ky+delta)); % ky
[Vkxky1,Vkxky2]=get_vector(Hamiltonian(kx+delta,ky+delta)); % kxky
Ux = dot_and_det(V1, Vkx1, V2, Vkx2);
Uy = dot_and_det(V1, Vky1, V2, Vky2);
Ux_y = dot_and_det(Vky1, Vkxky1, Vky2, Vkxky2);
Uy_x = dot_and_det(Vkx1, Vkxky1, Vkx2, Vkxky2);
F=imag(log(Ux*Uy_x*(conj(Ux_y))*(conj(Uy))));
A=imag(log(Ux))+imag(log(Uy_x))+imag(log(conj(Ux_y)))+imag(log(conj(Uy)));
Z2 = Z2+(A-F)/(2*pi);
end
end
Z2= mod(Z2, 2)
function dd = dot_and_det(a1,b1,a2,b2) %
x1=a1'*b1;
x2=a2'*b2;
x3=a1'*b2;
x4=a2'*b1;
dd =x1*x2-x3*x4;
end
function [vector_new_1, vector_new_2] = get_vector(H)
[vector,eigenvalue] = eig(H);
[eigenvalue, index]=sort(diag(eigenvalue), 'ascend');
vector_new_2 = vector(:, index(2));
vector_new_1 = vector(:, index(1));
end
function H=Hamiltonian(kx,ky) % BHZ
A=0.3645/5;
B=-0.686/25;
C=0;
D=-0.512/25;
M=-0.01;
H=zeros(4,4);
varepsilon = C-2*D*(2-cos(kx)-cos(ky));
d3 = -2*B*(2-(M/2/B)-cos(kx)-cos(ky));
d1_d2 = A*(sin(kx)+1j*sin(ky));
H(1, 1) = varepsilon+d3;
H(2, 2) = varepsilon-d3;
H(1, 2) = conj(d1_d2);
H(2, 1) = d1_d2 ;
varepsilon = C-2*D*(2-cos(-kx)-cos(-ky));
d3 = -2*B*(2-(M/2/B)-cos(-kx)-cos(-ky));
d1_d2 = A*(sin(-kx)+1j*sin(-ky));
H(3, 3) = varepsilon+d3;
H(4, 4) = varepsilon-d3;
H(3, 4) = d1_d2 ;
H(4, 3) = conj(d1_d2);
end

View File

@@ -0,0 +1,88 @@
"""
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/5778
"""
import numpy as np
import matplotlib.pyplot as plt
from math import * # 引入pi, cos等
import cmath
import time
def hamiltonian(kx, ky): # BHZ模型
A=0.3645/5
B=-0.686/25
C=0
D=-0.512/25
M=-0.01
matrix = np.zeros((4, 4))*(1+0j)
varepsilon = C-2*D*(2-cos(kx)-cos(ky))
d3 = -2*B*(2-(M/2/B)-cos(kx)-cos(ky))
d1_d2 = A*(sin(kx)+1j*sin(ky))
matrix[0, 0] = varepsilon+d3
matrix[1, 1] = varepsilon-d3
matrix[0, 1] = np.conj(d1_d2)
matrix[1, 0] = d1_d2
varepsilon = C-2*D*(2-cos(-kx)-cos(-ky))
d3 = -2*B*(2-(M/2/B)-cos(-kx)-cos(-ky))
d1_d2 = A*(sin(-kx)+1j*sin(-ky))
matrix[2, 2] = varepsilon+d3
matrix[3, 3] = varepsilon-d3
matrix[2, 3] = d1_d2
matrix[3, 2] = np.conj(d1_d2)
return matrix
def main():
start_clock = time.perf_counter()
delta = 0.1
Z2 = 0 # Z2数
for kx in np.arange(-pi, 0, delta):
print(kx)
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]] # 价带波函数1
vector2 = eigenvector[:, np.argsort(np.real(eigenvalue))[1]] # 价带波函数2
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的波函数1
vector_delta_kx2 = eigenvector[:, np.argsort(np.real(eigenvalue))[1]] # 略偏离kx的波函数2
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的波函数1
vector_delta_ky2 = eigenvector[:, np.argsort(np.real(eigenvalue))[1]] # 略偏离ky的波函数2
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的波函数1
vector_delta_kx_ky2 = eigenvector[:, np.argsort(np.real(eigenvalue))[1]] # 略偏离kx和ky的波函数2
Ux = dot_and_det(vector, vector_delta_kx, vector2, vector_delta_kx2)
Uy = dot_and_det(vector, vector_delta_ky, vector2, vector_delta_ky2)
Ux_y = dot_and_det(vector_delta_ky, vector_delta_kx_ky, vector_delta_ky2, vector_delta_kx_ky2)
Uy_x = dot_and_det(vector_delta_kx, vector_delta_kx_ky, vector_delta_kx2, vector_delta_kx_ky2)
F = np.imag(cmath.log(Ux*Uy_x*np.conj(Ux_y)*np.conj(Uy)))
A = np.imag(cmath.log(Ux))+np.imag(cmath.log(Uy_x))+np.imag(cmath.log(np.conj(Ux_y)))+np.imag(cmath.log(np.conj(Uy)))
Z2 = Z2 + (A-F)/(2*pi)
print('Z2 = ', Z2) # Z2数
end_clock = time.perf_counter()
print('CPU执行时间(min)=', (end_clock-start_clock)/60)
def dot_and_det(a1, b1, a2, b2): # 内积组成的矩阵对应的行列式
x1 = np.dot(np.conj(a1), b1)
x2 = np.dot(np.conj(a2), b2)
x3 = np.dot(np.conj(a1), b2)
x4 = np.dot(np.conj(a2), b1)
return x1*x2-x3*x4
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,98 @@
"""
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/5778
"""
import numpy as np
import matplotlib.pyplot as plt
from math import * # 引入pi, cos等
import cmath
import time
def hamiltonian1(kx, ky): # Half BHZ for spin up
A=0.3645/5
B=-0.686/25
C=0
D=-0.512/25
M=-0.01
matrix = np.zeros((2, 2))*(1+0j)
varepsilon = C-2*D*(2-cos(kx)-cos(ky))
d3 = -2*B*(2-(M/2/B)-cos(kx)-cos(ky))
d1_d2 = A*(sin(kx)+1j*sin(ky))
matrix[0, 0] = varepsilon+d3
matrix[1, 1] = varepsilon-d3
matrix[0, 1] = np.conj(d1_d2)
matrix[1, 0] = d1_d2
return matrix
def hamiltonian2(kx, ky): # Half BHZ for spin down
A=0.3645/5
B=-0.686/25
C=0
D=-0.512/25
M=-0.01
matrix = np.zeros((2, 2))*(1+0j)
varepsilon = C-2*D*(2-cos(-kx)-cos(-ky))
d3 = -2*B*(2-(M/2/B)-cos(-kx)-cos(-ky))
d1_d2 = A*(sin(-kx)+1j*sin(-ky))
matrix[0, 0] = varepsilon+d3
matrix[1, 1] = varepsilon-d3
matrix[0, 1] = d1_d2
matrix[1, 0] = np.conj(d1_d2)
return matrix
def main():
start_clock = time.perf_counter()
delta = 0.1
for i0 in range(2):
if i0 == 0:
hamiltonian = hamiltonian1
else:
hamiltonian = hamiltonian2
chern_number = 0 # 陈数初始化
for kx in np.arange(-pi, pi, delta):
print(kx)
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]] # 价带波函数
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的波函数
Ux = np.dot(np.conj(vector), vector_delta_kx)/abs(np.dot(np.conj(vector), vector_delta_kx))
Uy = np.dot(np.conj(vector), vector_delta_ky)/abs(np.dot(np.conj(vector), vector_delta_ky))
Ux_y = np.dot(np.conj(vector_delta_ky), vector_delta_kx_ky)/abs(np.dot(np.conj(vector_delta_ky), vector_delta_kx_ky))
Uy_x = np.dot(np.conj(vector_delta_kx), vector_delta_kx_ky)/abs(np.dot(np.conj(vector_delta_kx), vector_delta_kx_ky))
F = cmath.log(Ux*Uy_x*(1/Ux_y)*(1/Uy))
# 陈数(chern number)
chern_number = chern_number + F
chern_number = chern_number/(2*pi*1j)
if i0 == 0:
chern_number_up = chern_number
else:
chern_number_down = chern_number
spin_chern_number = (chern_number_up-chern_number_down)/2
print('Chern number for spin up = ', chern_number_up)
print('Chern number for spin down = ', chern_number_down)
print('Spin chern number = ', spin_chern_number)
end_clock = time.perf_counter()
print('CPU执行时间(min)=', (end_clock-start_clock)/60)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,83 @@
"""
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/6896
"""
import numpy as np
from math import *
import matplotlib.pyplot as plt
import time
import cmath
def hamiltonian(kx,ky,kz): # Weyl semimetal
A = 1
M0 = 1
M1 = 1
H = A*(sin(kx)*sigma_x()+sin(ky)*sigma_y())+(M0-M1*(2*(1-cos(kx))+2*(1-cos(ky))+2*(1-cos(kz))))*sigma_z()
return H
def sigma_x():
return np.array([[0, 1],[1, 0]])
def sigma_y():
return np.array([[0, -1j],[1j, 0]])
def sigma_z():
return np.array([[1, 0],[0, -1]])
def main():
start_time = time.time()
n = 50
delta = 2*pi/n
kz_array = np.arange(-pi, pi, 0.1)
chern_number_array = np.zeros(kz_array.shape[0])
i0 = 0
for kz in kz_array:
print('kz=', kz)
chern_number = 0 # 陈数初始化
for kx in np.arange(-pi, pi, 2*pi/n):
for ky in np.arange(-pi, pi, 2*pi/n):
H = hamiltonian(kx, ky, kz)
eigenvalue, eigenvector = np.linalg.eig(H)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 价带波函数
H_delta_kx = hamiltonian(kx+delta, ky, kz)
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, kz)
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, kz)
eigenvalue, eigenvector = np.linalg.eig(H_delta_kx_ky)
vector_delta_kx_ky = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 略偏离kx和ky的波函数
Ux = np.dot(np.conj(vector), vector_delta_kx)/abs(np.dot(np.conj(vector), vector_delta_kx))
Uy = np.dot(np.conj(vector), vector_delta_ky)/abs(np.dot(np.conj(vector), vector_delta_ky))
Ux_y = np.dot(np.conj(vector_delta_ky), vector_delta_kx_ky)/abs(np.dot(np.conj(vector_delta_ky), vector_delta_kx_ky))
Uy_x = np.dot(np.conj(vector_delta_kx), vector_delta_kx_ky)/abs(np.dot(np.conj(vector_delta_kx), vector_delta_kx_ky))
F = cmath.log(Ux*Uy_x*(1/Ux_y)*(1/Uy))
# 陈数(chern number)
chern_number = chern_number + F
chern_number = chern_number/(2*pi*1j)
print('Chern number = ', chern_number, '\n')
chern_number_array[i0] = np.real(chern_number)
i0 += 1
end_time = time.time()
print('运行时间(min)=', (end_time-start_time)/60)
plt.plot(kz_array, chern_number_array, 'o-')
plt.xlabel('kz')
plt.ylabel('Chern number')
plt.show()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,30 @@
"""
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/6896
"""
import numpy as np
import guan
import functools
def main():
kz_array = np.arange(-np.pi, np.pi, 0.1)
chern_number_array = []
for kz in kz_array:
print(kz)
hamiltonian_function = functools.partial(hamiltonian, kz=kz)
chern_number = guan.calculate_chern_number_for_square_lattice_with_efficient_method(hamiltonian_function)
chern_number_array.append(chern_number)
guan.plot(kz_array, chern_number_array, style='-o')
def hamiltonian(kx,ky,kz): # Weyl semimetal
A = 1
M0 = 1
M1 = 1
H = A*(np.sin(kx)*guan.sigma_x()+np.sin(ky)*guan.sigma_y())+(M0-M1*(2*(1-np.cos(kx))+2*(1-np.cos(ky))+2*(1-np.cos(kz))))*guan.sigma_z()
return H
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,66 @@
"""
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/6896
"""
import numpy as np
from math import *
import matplotlib.pyplot as plt
def main():
k1 = np.arange(-pi, pi, 0.05)
k2 = np.arange(-pi, pi, 0.05)
plot_bands_two_dimension(k1, k2, hamiltonian)
def hamiltonian(kx,kz,ky=0): # Weyl semimetal
A = 1
M0 = 1
M1 = 1
H = A*(sin(kx)*sigma_x()+sin(ky)*sigma_y())+(M0-M1*(2*(1-cos(kx))+2*(1-cos(ky))+2*(1-cos(kz))))*sigma_z()
return H
def sigma_x():
return np.array([[0, 1],[1, 0]])
def sigma_y():
return np.array([[0, -1j],[1j, 0]])
def sigma_z():
return np.array([[1, 0],[0, -1]])
def plot_bands_two_dimension(k1, k2, hamiltonian):
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
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.xlabel('kx')
plt.ylabel('kz')
ax.set_zlabel('E')
plt.show()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,113 @@
"""
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/7516
"""
import numpy as np
from math import * # 引入pi, cos等
import cmath
import time
def hamiltonian(kx, ky): # 量子反常霍尔QAH模型该参数对应的陈数为2
t1 = 1.0
t2 = 1.0
t3 = 0.5
m = -1.0
matrix = np.zeros((2, 2))*(1+0j)
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 = 100 # 积分密度
delta = 1e-9 # 求导的偏离量
chern_number = 0 # 陈数初始化
for kx in np.arange(-pi, pi, 2*pi/n):
for ky in np.arange(-pi, pi, 2*pi/n):
H = hamiltonian(kx, ky)
eigenvalue, eigenvector = np.linalg.eig(H)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 价带波函数
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的波函数
# vector = vector*cmath.exp(-1j*1)
# vector_delta_kx = vector_delta_kx*cmath.exp(-1j*1)
# vector_delta_ky = vector_delta_ky*cmath.exp(-1j*1)
# vector_delta_kx_ky = vector_delta_kx_ky*cmath.exp(-1j*(1+1e-8))
rand = np.random.uniform(-pi, pi)
vector_delta_kx_ky = vector_delta_kx_ky*cmath.exp(-1j*rand)
# 寻找近似的同一的规范
phase_1_pre = 0
phase_2_pre = pi
n_test = 10001
for i0 in range(n_test):
test_1 = np.sum(np.abs(vector_delta_kx_ky*cmath.exp(1j*phase_1_pre) - vector))
test_2 = np.sum(np.abs(vector_delta_kx_ky*cmath.exp(1j*phase_2_pre) - vector))
if test_1 < 1e-6:
phase = phase_1_pre
print('Done with i0=', i0)
break
if i0 == n_test-1:
phase = phase_1_pre
print('Not Found with i0=', i0)
if test_1 < test_2:
if i0 == 0:
phase_1 = phase_1_pre-(phase_2_pre-phase_1_pre)/2
phase_2 = phase_1_pre+(phase_2_pre-phase_1_pre)/2
else:
phase_1 = phase_1_pre
phase_2 = phase_1_pre+(phase_2_pre-phase_1_pre)/2
else:
if i0 == 0:
phase_1 = phase_2_pre-(phase_2_pre-phase_1_pre)/2
phase_2 = phase_2_pre+(phase_2_pre-phase_1_pre)/2
else:
phase_1 = phase_2_pre-(phase_2_pre-phase_1_pre)/2
phase_2 = phase_2_pre
phase_1_pre = phase_1
phase_2_pre = phase_2
vector_delta_kx_ky = vector_delta_kx_ky*cmath.exp(1j*phase)
print('随机的规范=', rand) # 可注释掉
print('二分查找找到的规范=', phase) # 可注释掉
print() # 可注释掉
# 价带的波函数的贝里联络(berry connection) # 求导后内积
A_x = np.dot(vector.transpose().conj(), (vector_delta_kx-vector)/delta) # 贝里联络Axx分量
A_y = np.dot(vector.transpose().conj(), (vector_delta_ky-vector)/delta) # 贝里联络Ayy分量
A_x_delta_ky = np.dot(vector_delta_ky.transpose().conj(), (vector_delta_kx_ky-vector_delta_ky)/delta) # 略偏离ky的贝里联络Ax
A_y_delta_kx = np.dot(vector_delta_kx.transpose().conj(), (vector_delta_kx_ky-vector_delta_kx)/delta) # 略偏离kx的贝里联络Ay
# 贝里曲率(berry curvature)
F = (A_y_delta_kx-A_y)/delta-(A_x_delta_ky-A_x)/delta
# 陈数(chern number)
chern_number = chern_number + F*(2*pi/n)**2
chern_number = chern_number/(2*pi*1j)
print('Chern number = ', chern_number)
end_time = time.time()
print('运行时间(min)=', (end_time-start_time)/60)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,78 @@
"""
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/7516
"""
import numpy as np
from math import *
import cmath
import time
import guan
def hamiltonian(kx, ky): # 量子反常霍尔QAH模型该参数对应的陈数为2
t1 = 1.0
t2 = 1.0
t3 = 0.5
m = -1.0
matrix = np.zeros((2, 2))*(1+0j)
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 = 100 # 积分密度
delta = 1e-9 # 求导的偏离量
chern_number = 0 # 陈数初始化
for kx in np.arange(-pi, pi, 2*pi/n):
for ky in np.arange(-pi, pi, 2*pi/n):
H = hamiltonian(kx, ky)
eigenvalue, eigenvector = np.linalg.eig(H)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[0]] # 价带波函数
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的波函数
# vector = vector*cmath.exp(-1j*1)
# vector_delta_kx = vector_delta_kx*cmath.exp(-1j*1)
# vector_delta_ky = vector_delta_ky*cmath.exp(-1j*1)
# vector_delta_kx_ky = vector_delta_kx_ky*cmath.exp(-1j*(1+1e-8))
rand = np.random.uniform(-pi, pi)
vector_delta_kx_ky = vector_delta_kx_ky*cmath.exp(-1j*rand)
vector_delta_kx_ky = guan.find_vector_with_the_same_gauge_with_binary_search(vector_delta_kx_ky, vector)
# 价带的波函数的贝里联络(berry connection) # 求导后内积
A_x = np.dot(vector.transpose().conj(), (vector_delta_kx-vector)/delta) # 贝里联络Axx分量
A_y = np.dot(vector.transpose().conj(), (vector_delta_ky-vector)/delta) # 贝里联络Ayy分量
A_x_delta_ky = np.dot(vector_delta_ky.transpose().conj(), (vector_delta_kx_ky-vector_delta_ky)/delta) # 略偏离ky的贝里联络Ax
A_y_delta_kx = np.dot(vector_delta_kx.transpose().conj(), (vector_delta_kx_ky-vector_delta_kx)/delta) # 略偏离kx的贝里联络Ay
# 贝里曲率(berry curvature)
F = (A_y_delta_kx-A_y)/delta-(A_x_delta_ky-A_x)/delta
# 陈数(chern number)
chern_number = chern_number + F*(2*pi/n)**2
chern_number = chern_number/(2*pi*1j)
print('Chern number = ', chern_number)
end_time = time.time()
print('运行时间(min)=', (end_time-start_time)/60)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,159 @@
"""
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/8536
"""
import numpy as np
import matplotlib.pyplot as plt
from math import *
import cmath
import time
def hamiltonian(k1, k2, t1=2.82, a=1/sqrt(3)): # 石墨烯哈密顿量a为原子间距不赋值的话默认为1/sqrt(3)
h = np.zeros((2, 2), dtype=complex)
h[0, 0] = 0.28/2
h[1, 1] = -0.28/2
h[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))
h[0, 1] = h[1, 0].conj()
return h
def main():
start_time = time.time()
n = 400 # 取点密度
delta = 1e-10 # 求导的偏离量
kx_array = np.linspace(-2*pi, 2*pi, n)
ky_array = np.linspace(-2*pi, 2*pi, n)
for band in range(2):
F_all = np.zeros((ky_array.shape[0], ky_array.shape[0])) # 贝里曲率
j0 = 0
for kx in kx_array:
print(kx)
i0 = 0
for ky in ky_array:
H = hamiltonian(kx, ky)
eigenvalue, eigenvector = np.linalg.eig(H)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[band]] # 价带波函数
# print(np.argsort(np.real(eigenvalue))[0]) # 排序索引(从小到大)
# print(eigenvalue) # 排序前的本征值
# print(np.sort(np.real(eigenvalue))) # 排序后的本征值(从小到大)
H_delta_kx = hamiltonian(kx+delta, ky)
eigenvalue, eigenvector = np.linalg.eig(H_delta_kx)
vector_delta_kx = eigenvector[:, np.argsort(np.real(eigenvalue))[band]] # 略偏离kx的波函数
# vector_delta_kx = find_vector_with_the_same_gauge(vector_delta_kx, vector) # 如果波函数不连续需要使用这个
H_delta_ky = hamiltonian(kx, ky+delta)
eigenvalue, eigenvector = np.linalg.eig(H_delta_ky)
vector_delta_ky = eigenvector[:, np.argsort(np.real(eigenvalue))[band]] # 略偏离ky的波函数
# vector_delta_ky = find_vector_with_the_same_gauge(vector_delta_ky, vector) # 如果波函数不连续需要使用这个
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))[band]] # 略偏离kx和ky的波函数
# vector_delta_kx_ky = find_vector_with_the_same_gauge(vector_delta_kx_ky, vector) # 如果波函数不连续需要使用这个
# 价带的波函数的贝里联络(berry connection) # 求导后内积
A_x = np.dot(vector.transpose().conj(), (vector_delta_kx-vector)/delta) # 贝里联络Axx分量
A_y = np.dot(vector.transpose().conj(), (vector_delta_ky-vector)/delta) # 贝里联络Ayy分量
A_x_delta_ky = np.dot(vector_delta_ky.transpose().conj(), (vector_delta_kx_ky-vector_delta_ky)/delta) # 略偏离ky的贝里联络Ax
A_y_delta_kx = np.dot(vector_delta_kx.transpose().conj(), (vector_delta_kx_ky-vector_delta_kx)/delta) # 略偏离kx的贝里联络Ay
# 贝里曲率(berry curvature)
F = ((A_y_delta_kx-A_y)/delta-(A_x_delta_ky-A_x)/delta)*1j
# print(F)
F_all[i0, j0] = np.real(F)
i0 += 1
j0 += 1
if band==0:
plot_3d_surface(kx_array/pi, ky_array/pi, F_all, xlabel='k_x (pi)', ylabel='k_y (pi)', zlabel='Berry curvature', title='Valence Band', rcount=300, ccount=300)
else:
plot_3d_surface(kx_array/pi, ky_array/pi, F_all, xlabel='k_x (pi)', ylabel='k_y (pi)', zlabel='Berry curvature', title='Conductance Band', rcount=300, ccount=300)
# import guan
# if band==0:
# guan.plot_3d_surface(kx_array/pi, ky_array/pi, F_all, xlabel='kx', ylabel='ky', zlabel='Berry curvature', title='Valence Band', rcount=300, ccount=300)
# else:
# guan.plot_3d_surface(kx_array/pi, ky_array/pi, F_all, xlabel='kx', ylabel='ky', zlabel='Berry curvature', title='Conductance Band', rcount=300, ccount=300)
end_time = time.time()
print('运行时间(min)=', (end_time-start_time)/60)
def find_vector_with_the_same_gauge(vector_1, vector_0):
# 寻找近似的同一的规范
phase_1_pre = 0
phase_2_pre = pi
n_test = 10001
for i0 in range(n_test):
test_1 = np.sum(np.abs(vector_1*cmath.exp(1j*phase_1_pre) - vector_0))
test_2 = np.sum(np.abs(vector_1*cmath.exp(1j*phase_2_pre) - vector_0))
if test_1 < 1e-9:
phase = phase_1_pre
# print('Done with i0=', i0)
break
if i0 == n_test-1:
phase = phase_1_pre
print('Gauge Not Found with i0=', i0)
if test_1 < test_2:
if i0 == 0:
phase_1 = phase_1_pre-(phase_2_pre-phase_1_pre)/2
phase_2 = phase_1_pre+(phase_2_pre-phase_1_pre)/2
else:
phase_1 = phase_1_pre
phase_2 = phase_1_pre+(phase_2_pre-phase_1_pre)/2
else:
if i0 == 0:
phase_1 = phase_2_pre-(phase_2_pre-phase_1_pre)/2
phase_2 = phase_2_pre+(phase_2_pre-phase_1_pre)/2
else:
phase_1 = phase_2_pre-(phase_2_pre-phase_1_pre)/2
phase_2 = phase_2_pre
phase_1_pre = phase_1
phase_2_pre = phase_2
vector_1 = vector_1*cmath.exp(1j*phase)
# print('二分查找找到的规范=', phase)
return vector_1
def plot_3d_surface(x_array, y_array, matrix, xlabel='x', ylabel='y', zlabel='z', title='', fontsize=20, labelsize=15, show=1, save=0, filename='a', file_format='.jpg', dpi=300, z_min=None, z_max=None, rcount=100, ccount=100):
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator
matrix = np.array(matrix)
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
plt.subplots_adjust(bottom=0.1, right=0.65)
x_array, y_array = np.meshgrid(x_array, y_array)
if len(matrix.shape) == 2:
surf = ax.plot_surface(x_array, y_array, matrix, rcount=rcount, ccount=ccount, cmap=cm.coolwarm, linewidth=0, antialiased=False)
elif len(matrix.shape) == 3:
for i0 in range(matrix.shape[2]):
surf = ax.plot_surface(x_array, y_array, matrix[:,:,i0], rcount=rcount, ccount=ccount, cmap=cm.coolwarm, linewidth=0, antialiased=False)
ax.set_title(title, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_xlabel(xlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_ylabel(ylabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_zlabel(zlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.zaxis.set_major_locator(LinearLocator(5))
ax.zaxis.set_major_formatter('{x:.2f}')
if z_min!=None or z_max!=None:
if z_min==None:
z_min=matrix.min()
if z_max==None:
z_max=matrix.max()
ax.set_zlim(z_min, z_max)
ax.tick_params(labelsize=labelsize)
labels = ax.get_xticklabels() + ax.get_yticklabels() + ax.get_zticklabels()
[label.set_fontname('Times New Roman') for label in labels]
cax = plt.axes([0.8, 0.1, 0.05, 0.8])
cbar = fig.colorbar(surf, cax=cax)
cbar.ax.tick_params(labelsize=labelsize)
for l in cbar.ax.yaxis.get_ticklabels():
l.set_family('Times New Roman')
if save == 1:
plt.savefig(filename+file_format, dpi=dpi)
if show == 1:
plt.show()
plt.close('all')
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,110 @@
"""
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/8536
"""
import numpy as np
import matplotlib.pyplot as plt
from math import *
import cmath
import time
def hamiltonian(k1, k2, t1=2.82, a=1/sqrt(3)): # 石墨烯哈密顿量a为原子间距不赋值的话默认为1/sqrt(3)
h = np.zeros((2, 2), dtype=complex)
h[0, 0] = 0.28/2
h[1, 1] = -0.28/2
h[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))
h[0, 1] = h[1, 0].conj()
return h
def main():
start_time = time.time()
n = 2000 # 取点密度
delta = 1e-9 # 求导的偏离量
for band in range(2):
F_all = [] # 贝里曲率
for kx in np.linspace(-2*pi, 2*pi, n):
for ky in [0]: # 这里只考虑ky=0对称轴上的情况 # np.linspace(-pi, pi, n):
H = hamiltonian(kx, ky)
eigenvalue, eigenvector = np.linalg.eig(H)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[band]] # 价带波函数
# print(np.argsort(np.real(eigenvalue))[0]) # 排序索引(从小到大)
# print(eigenvalue) # 排序前的本征值
# print(np.sort(np.real(eigenvalue))) # 排序后的本征值(从小到大)
H_delta_kx = hamiltonian(kx+delta, ky)
eigenvalue, eigenvector = np.linalg.eig(H_delta_kx)
vector_delta_kx = eigenvector[:, np.argsort(np.real(eigenvalue))[band]] # 略偏离kx的波函数
# vector_delta_kx = find_vector_with_the_same_gauge(vector_delta_kx, vector) # 如果波函数不连续需要使用这个
H_delta_ky = hamiltonian(kx, ky+delta)
eigenvalue, eigenvector = np.linalg.eig(H_delta_ky)
vector_delta_ky = eigenvector[:, np.argsort(np.real(eigenvalue))[band]] # 略偏离ky的波函数
# vector_delta_ky = find_vector_with_the_same_gauge(vector_delta_ky, vector) # 如果波函数不连续需要使用这个
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))[band]] # 略偏离kx和ky的波函数
# vector_delta_kx_ky = find_vector_with_the_same_gauge(vector_delta_kx_ky, vector) # 如果波函数不连续需要使用这个
# 价带的波函数的贝里联络(berry connection) # 求导后内积
A_x = np.dot(vector.transpose().conj(), (vector_delta_kx-vector)/delta) # 贝里联络Axx分量
A_y = np.dot(vector.transpose().conj(), (vector_delta_ky-vector)/delta) # 贝里联络Ayy分量
A_x_delta_ky = np.dot(vector_delta_ky.transpose().conj(), (vector_delta_kx_ky-vector_delta_ky)/delta) # 略偏离ky的贝里联络Ax
A_y_delta_kx = np.dot(vector_delta_kx.transpose().conj(), (vector_delta_kx_ky-vector_delta_kx)/delta) # 略偏离kx的贝里联络Ay
# 贝里曲率(berry curvature)
F = ((A_y_delta_kx-A_y)/delta-(A_x_delta_ky-A_x)/delta)*1j
# print(F)
F_all = np.append(F_all,[F], axis=0)
plt.plot(np.linspace(-2*pi, 2*pi, n)/pi, np.real(F_all))
plt.xlabel('k_x (pi)')
plt.ylabel('Berry curvature')
if band==0:
plt.title('Valence Band')
else:
plt.title('Conductance Band')
plt.show()
end_time = time.time()
print('运行时间(min)=', (end_time-start_time)/60)
def find_vector_with_the_same_gauge(vector_1, vector_0):
# 寻找近似的同一的规范
phase_1_pre = 0
phase_2_pre = pi
n_test = 10001
for i0 in range(n_test):
test_1 = np.sum(np.abs(vector_1*cmath.exp(1j*phase_1_pre) - vector_0))
test_2 = np.sum(np.abs(vector_1*cmath.exp(1j*phase_2_pre) - vector_0))
if test_1 < 1e-9:
phase = phase_1_pre
# print('Done with i0=', i0)
break
if i0 == n_test-1:
phase = phase_1_pre
print('Gauge Not Found with i0=', i0)
if test_1 < test_2:
if i0 == 0:
phase_1 = phase_1_pre-(phase_2_pre-phase_1_pre)/2
phase_2 = phase_1_pre+(phase_2_pre-phase_1_pre)/2
else:
phase_1 = phase_1_pre
phase_2 = phase_1_pre+(phase_2_pre-phase_1_pre)/2
else:
if i0 == 0:
phase_1 = phase_2_pre-(phase_2_pre-phase_1_pre)/2
phase_2 = phase_2_pre+(phase_2_pre-phase_1_pre)/2
else:
phase_1 = phase_2_pre-(phase_2_pre-phase_1_pre)/2
phase_2 = phase_2_pre
phase_1_pre = phase_1
phase_2_pre = phase_2
vector_1 = vector_1*cmath.exp(1j*phase)
# print('二分查找找到的规范=', phase)
return vector_1
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,77 @@
"""
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/10064
"""
import numpy as np
import cmath
from math import *
def hamiltonian(k): # SSH模型哈密顿量
gamma = 0.5
lambda0 = 1
h = np.zeros((2, 2), dtype=complex)
h[0,0] = 0
h[1,1] = 0
h[0,1] = gamma+lambda0*cmath.exp(-1j*k)
h[1,0] = gamma+lambda0*cmath.exp(1j*k)
return h
def main():
Num_k = 100
k_array = np.linspace(-pi, pi, Num_k)
vector_array = []
for k in k_array:
vector = get_occupied_bands_vectors(k, hamiltonian)
vector_array.append(vector)
# vector_array.append(vector*cmath.exp(1j*np.random.uniform(0, pi))) # 随机相位测试
# 波函数固定一个规范
vector_sum = 0
for i0 in range(Num_k):
vector_sum += np.abs(vector_array[i0])
index = np.argmax(np.abs(vector_sum))
for i0 in range(Num_k):
vector_array[i0] = find_vector_with_fixed_gauge_by_making_one_component_real(vector_array[i0], index=index)
# # 波函数固定一个规范
# import guan
# vector_array = guan.find_vector_array_with_fixed_gauge_by_making_one_component_real(vector_array, precision=0.005)
# 计算Wilson loop
W_k = 1
for i0 in range(Num_k-1):
F = np.dot(vector_array[i0+1].transpose().conj(), vector_array[i0])
W_k = np.dot(F, W_k)
nu = np.log(W_k)/2/pi/1j
# if np.real(nu) < 0:
# nu += 1
print('p=', nu, '\n')
def get_occupied_bands_vectors(x, matrix):
matrix0 = matrix(x)
eigenvalue, eigenvector = np.linalg.eig(matrix0)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[0]]
return vector
def find_vector_with_fixed_gauge_by_making_one_component_real(vector, precision=0.005, index=None):
if index == None:
index = np.argmax(np.abs(vector))
sign_pre = np.sign(np.imag(vector[index]))
for phase in np.arange(0, 2*np.pi, precision):
sign = np.sign(np.imag(vector[index]*cmath.exp(1j*phase)))
if np.abs(np.imag(vector[index]*cmath.exp(1j*phase))) < 1e-9 or sign == -sign_pre:
break
sign_pre = sign
vector = vector*cmath.exp(1j*phase)
if np.real(vector[index]) < 0:
vector = -vector
return vector
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,53 @@
"""
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/10064
"""
import numpy as np
import cmath
from math import *
def hamiltonian(k):
gamma = 0.5
lambda0 = 1
delta = 0
h = np.zeros((2, 2), dtype=complex)
h[0,0] = delta
h[1,1] = -delta
h[0,1] = gamma+lambda0*cmath.exp(-1j*k)
h[1,0] = gamma+lambda0*cmath.exp(1j*k)
return h
def main():
Num_k = 100
k_array = np.linspace(-pi, pi, Num_k)
vector_array = []
for k in k_array:
vector = get_occupied_bands_vectors(k, hamiltonian)
if k != pi:
vector_array.append(vector)
else:
vector_array.append(vector_array[0])
# 计算Wilson loop
W_k = 1
for i0 in range(Num_k-1):
F = np.dot(vector_array[i0+1].transpose().conj(), vector_array[i0])
W_k = np.dot(F, W_k)
nu = np.log(W_k)/2/pi/1j
# if np.real(nu) < 0:
# nu += 1
print('p=', nu, '\n')
def get_occupied_bands_vectors(x, matrix):
matrix0 = matrix(x)
eigenvalue, eigenvector = np.linalg.eig(matrix0)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[0]]
return vector
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,50 @@
"""
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/16148
"""
import numpy as np
from math import *
import time
def hamiltonian(kx, ky): # one QAH model with Chern number = 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 # integration
delta = 1e-6 # derivation
chern_number = 0
for kx in np.arange(-pi, pi, 2*pi/n):
for ky in np.arange(-pi, pi,2*pi/n):
H = hamiltonian(kx, ky)
eigenvalue, eigenvector = np.linalg.eig(H)
vector_0 = eigenvector[:, np.argsort(np.real(eigenvalue))[0]]
vector_1 = eigenvector[:, np.argsort(np.real(eigenvalue))[1]]
eigenvalue = np.sort(np.real(eigenvalue))
H_delta_kx = hamiltonian(kx+delta, ky)-hamiltonian(kx, ky)
H_delta_ky = hamiltonian(kx, ky+delta)-hamiltonian(kx, ky)
berry_curvature = 1j*(np.dot(np.dot(np.dot(np.dot(np.dot(vector_0.transpose().conj(), H_delta_kx/delta), vector_1), vector_1.transpose().conj()), H_delta_ky/delta), vector_0)- np.dot(np.dot(np.dot(np.dot(np.dot(vector_0.transpose().conj(), H_delta_ky/delta), vector_1), vector_1.transpose().conj()), H_delta_kx/delta), vector_0))/(eigenvalue[0]-eigenvalue[1])**2
chern_number = chern_number + berry_curvature*(2*pi/n)**2
chern_number = chern_number/(2*pi)
print('Chern number = ', chern_number)
end_time = time.time()
print('运行时间(min)=', (end_time-start_time)/60)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,92 @@
"""
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/17984
"""
import numpy as np
import cmath
from math import *
def hamiltonian(kx, ky): # BBH model
# label of atoms in a unit cell
# (2) —— (0)
# | |
# (1) —— (3)
gamma_x = 0.5 # hopping inside one unit cell
lambda_x = 1 # hopping between unit cells
gamma_y = gamma_x
lambda_y = lambda_x
h = np.zeros((4, 4), dtype=complex)
h[0, 2] = gamma_x+lambda_x*cmath.exp(1j*kx)
h[1, 3] = gamma_x+lambda_x*cmath.exp(-1j*kx)
h[0, 3] = gamma_y+lambda_y*cmath.exp(1j*ky)
h[1, 2] = -gamma_y-lambda_y*cmath.exp(-1j*ky)
h[2, 0] = np.conj(h[0, 2])
h[3, 1] = np.conj(h[1, 3])
h[3, 0] = np.conj(h[0, 3])
h[2, 1] = np.conj(h[1, 2])
return h
def main():
Num_kx = 100
Num_ky = 100
kx_array = np.linspace(-pi, pi, Num_kx)
ky_array = np.linspace(-pi, pi, Num_ky)
nu_x_array = []
for ky in ky_array:
vector1_array = []
vector2_array = []
for kx in kx_array:
eigenvalue, eigenvector = np.linalg.eigh(hamiltonian(kx, ky))
if kx != pi:
vector1_array.append(eigenvector[:, 0])
vector2_array.append(eigenvector[:, 1])
else:
# 这里是为了-pi和pi有相同的波函数使得Wilson loop的值与波函数规范无关。
vector1_array.append(vector1_array[0])
vector2_array.append(vector2_array[0])
W_x_k = np.eye(2, dtype=complex)
for i0 in range(Num_kx-1):
F = np.zeros((2, 2), dtype=complex)
F[0, 0] = np.dot(vector1_array[i0+1].transpose().conj(), vector1_array[i0])
F[1, 1] = np.dot(vector2_array[i0+1].transpose().conj(), vector2_array[i0])
F[0, 1] = np.dot(vector1_array[i0+1].transpose().conj(), vector2_array[i0])
F[1, 0] = np.dot(vector2_array[i0+1].transpose().conj(), vector1_array[i0])
W_x_k = np.dot(F, W_x_k)
eigenvalue, eigenvector = np.linalg.eig(W_x_k)
nu_x = np.log(eigenvalue)/2/pi/1j
for i0 in range(2):
if np.real(nu_x[i0]) < 0:
nu_x[i0] += 1
nu_x = np.sort(nu_x)
nu_x_array.append(nu_x.real)
plot(ky_array, nu_x_array, xlabel='ky', ylabel='nu_x', style='-', y_min=0, y_max=1)
# import guan
# guan.plot(ky_array, nu_x_array, xlabel='ky', ylabel='nu_x', style='-', y_min=0, y_max=1)
def plot(x_array, y_array, xlabel='x', ylabel='y', title='', fontsize=20, labelsize=20, show=1, save=0, filename='a', file_format='.jpg', dpi=300, style='', y_min=None, y_max=None, linewidth=None, markersize=None, adjust_bottom=0.2, adjust_left=0.2):
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=adjust_bottom, left=adjust_left)
ax.plot(x_array, y_array, style, linewidth=linewidth, markersize=markersize)
ax.grid()
ax.set_title(title, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_xlabel(xlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_ylabel(ylabel, fontsize=fontsize, fontfamily='Times New Roman')
if y_min!=None or y_max!=None:
if y_min==None:
y_min=min(y_array)
if y_max==None:
y_max=max(y_array)
ax.set_ylim(y_min, y_max)
ax.tick_params(labelsize=labelsize)
labels = ax.get_xticklabels() + ax.get_yticklabels()
[label.set_fontname('Times New Roman') for label in labels]
if save == 1:
plt.savefig(filename+file_format, dpi=dpi)
if show == 1:
plt.show()
plt.close('all')
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,163 @@
"""
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/17984
"""
import numpy as np
import cmath
from math import *
import functools
def hamiltonian(kx, ky): # BBH model
# label of atoms in a unit cell
# (2) —— (0)
# | |
# (1) —— (3)
gamma_x = 0.5 # hopping inside one unit cell
lambda_x = 1 # hopping between unit cells
gamma_y = gamma_x
lambda_y = lambda_x
h = np.zeros((4, 4), dtype=complex)
h[0, 2] = gamma_x+lambda_x*cmath.exp(1j*kx)
h[1, 3] = gamma_x+lambda_x*cmath.exp(-1j*kx)
h[0, 3] = gamma_y+lambda_y*cmath.exp(1j*ky)
h[1, 2] = -gamma_y-lambda_y*cmath.exp(-1j*ky)
h[2, 0] = np.conj(h[0, 2])
h[3, 1] = np.conj(h[1, 3])
h[3, 0] = np.conj(h[0, 3])
h[2, 1] = np.conj(h[1, 2])
return h
def main():
kx = np.arange(-pi, pi, 0.05)
ky = np.arange(-pi, pi, 0.05)
eigenvalue_array = calculate_eigenvalue_with_two_parameters(kx, ky, hamiltonian)
plot_3d_surface(kx, ky, eigenvalue_array, xlabel='kx', ylabel='ky', zlabel='E', title='BBH bands')
hamiltonian0 = functools.partial(hamiltonian, ky=0)
eigenvalue_array = calculate_eigenvalue_with_one_parameter(kx, hamiltonian0)
plot(kx, eigenvalue_array, xlabel='kx', ylabel='E', title='BBH bands ky=0')
# import guan
# eigenvalue_array = guan.calculate_eigenvalue_with_two_parameters(kx, ky, hamiltonian)
# guan.plot_3d_surface(kx, ky, eigenvalue_array, xlabel='kx', ylabel='ky', zlabel='E', title='BBH bands')
# hamiltonian0 = functools.partial(hamiltonian, ky=0)
# eigenvalue_array = guan.calculate_eigenvalue_with_one_parameter(kx, hamiltonian0)
# guan.plot(kx, eigenvalue_array, xlabel='kx', ylabel='E', title='BBH bands ky=0')
def calculate_eigenvalue_with_one_parameter(x_array, hamiltonian_function, print_show=0):
dim_x = np.array(x_array).shape[0]
i0 = 0
if np.array(hamiltonian_function(0)).shape==():
eigenvalue_array = np.zeros((dim_x, 1))
for x0 in x_array:
hamiltonian = hamiltonian_function(x0)
eigenvalue_array[i0, 0] = np.real(hamiltonian)
i0 += 1
else:
dim = np.array(hamiltonian_function(0)).shape[0]
eigenvalue_array = np.zeros((dim_x, dim))
for x0 in x_array:
if print_show==1:
print(x0)
hamiltonian = hamiltonian_function(x0)
eigenvalue, eigenvector = np.linalg.eigh(hamiltonian)
eigenvalue_array[i0, :] = eigenvalue
i0 += 1
return eigenvalue_array
def calculate_eigenvalue_with_two_parameters(x_array, y_array, hamiltonian_function, print_show=0, print_show_more=0):
dim_x = np.array(x_array).shape[0]
dim_y = np.array(y_array).shape[0]
if np.array(hamiltonian_function(0,0)).shape==():
eigenvalue_array = np.zeros((dim_y, dim_x, 1))
i0 = 0
for y0 in y_array:
j0 = 0
for x0 in x_array:
hamiltonian = hamiltonian_function(x0, y0)
eigenvalue_array[i0, j0, 0] = np.real(hamiltonian)
j0 += 1
i0 += 1
else:
dim = np.array(hamiltonian_function(0, 0)).shape[0]
eigenvalue_array = np.zeros((dim_y, dim_x, dim))
i0 = 0
for y0 in y_array:
j0 = 0
if print_show==1:
print(y0)
for x0 in x_array:
if print_show_more==1:
print(x0)
hamiltonian = hamiltonian_function(x0, y0)
eigenvalue, eigenvector = np.linalg.eigh(hamiltonian)
eigenvalue_array[i0, j0, :] = eigenvalue
j0 += 1
i0 += 1
return eigenvalue_array
def plot(x_array, y_array, xlabel='x', ylabel='y', title='', fontsize=20, labelsize=20, show=1, save=0, filename='a', file_format='.jpg', dpi=300, style='', y_min=None, y_max=None, linewidth=None, markersize=None, adjust_bottom=0.2, adjust_left=0.2):
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=adjust_bottom, left=adjust_left)
ax.plot(x_array, y_array, style, linewidth=linewidth, markersize=markersize)
ax.grid()
ax.set_title(title, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_xlabel(xlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_ylabel(ylabel, fontsize=fontsize, fontfamily='Times New Roman')
if y_min!=None or y_max!=None:
if y_min==None:
y_min=min(y_array)
if y_max==None:
y_max=max(y_array)
ax.set_ylim(y_min, y_max)
ax.tick_params(labelsize=labelsize)
labels = ax.get_xticklabels() + ax.get_yticklabels()
[label.set_fontname('Times New Roman') for label in labels]
if save == 1:
plt.savefig(filename+file_format, dpi=dpi)
if show == 1:
plt.show()
plt.close('all')
def plot_3d_surface(x_array, y_array, matrix, xlabel='x', ylabel='y', zlabel='z', title='', fontsize=20, labelsize=15, show=1, save=0, filename='a', file_format='.jpg', dpi=300, z_min=None, z_max=None, rcount=100, ccount=100):
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator
matrix = np.array(matrix)
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
plt.subplots_adjust(bottom=0.1, right=0.65)
x_array, y_array = np.meshgrid(x_array, y_array)
if len(matrix.shape) == 2:
surf = ax.plot_surface(x_array, y_array, matrix, rcount=rcount, ccount=ccount, cmap=cm.coolwarm, linewidth=0, antialiased=False)
elif len(matrix.shape) == 3:
for i0 in range(matrix.shape[2]):
surf = ax.plot_surface(x_array, y_array, matrix[:,:,i0], rcount=rcount, ccount=ccount, cmap=cm.coolwarm, linewidth=0, antialiased=False)
ax.set_title(title, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_xlabel(xlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_ylabel(ylabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_zlabel(zlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.zaxis.set_major_locator(LinearLocator(5))
ax.zaxis.set_major_formatter('{x:.2f}')
if z_min!=None or z_max!=None:
if z_min==None:
z_min=matrix.min()
if z_max==None:
z_max=matrix.max()
ax.set_zlim(z_min, z_max)
ax.tick_params(labelsize=labelsize)
labels = ax.get_xticklabels() + ax.get_yticklabels() + ax.get_zticklabels()
[label.set_fontname('Times New Roman') for label in labels]
cax = plt.axes([0.8, 0.1, 0.05, 0.8])
cbar = fig.colorbar(surf, cax=cax)
cbar.ax.tick_params(labelsize=labelsize)
for l in cbar.ax.yaxis.get_ticklabels():
l.set_family('Times New Roman')
if save == 1:
plt.savefig(filename+file_format, dpi=dpi)
if show == 1:
plt.show()
plt.close('all')
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,202 @@
"""
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/17984
"""
import numpy as np
import cmath
from math import *
def hamiltonian(kx, ky): # BBH model
# label of atoms in a unit cell
# (2) —— (0)
# | |
# (1) —— (3)
gamma_x = 0.5 # hopping inside one unit cell
lambda_x = 1 # hopping between unit cells
gamma_y = gamma_x
lambda_y = lambda_x
x_symmetry_breaking_1 = 0.000000000000 # default (not breaking): zero
x_symmetry_breaking_2 = 1.0000000000001 # default (not breaking): unity
y_symmetry_breaking_1 = 0.000000000000 # default (not breaking): zero
y_symmetry_breaking_2 = 1.000000000000 # default (not breaking): unity
h = np.zeros((4, 4), dtype=complex)
h[0, 0] = x_symmetry_breaking_1
h[1, 1] = y_symmetry_breaking_1
h[2, 2] = y_symmetry_breaking_1
h[3, 3] = x_symmetry_breaking_1
h[0, 2] = (gamma_x+lambda_x*cmath.exp(1j*kx))*y_symmetry_breaking_2
h[1, 3] = gamma_x+lambda_x*cmath.exp(-1j*kx)
h[0, 3] = gamma_y+lambda_y*cmath.exp(1j*ky)
h[1, 2] = (-gamma_y-lambda_y*cmath.exp(-1j*ky))*x_symmetry_breaking_2
h[2, 0] = np.conj(h[0, 2])
h[3, 1] = np.conj(h[1, 3])
h[3, 0] = np.conj(h[0, 3])
h[2, 1] = np.conj(h[1, 2])
return h
def main():
Num_kx = 30 # for wilson loop and nested wilson loop
Num_ky = 30 # for wilson loop and nested wilson loop
Num_kx2 = 20 # plot precision
Num_ky2 = 20 # plot precision
kx_array = np.linspace(-pi, pi, Num_kx)
ky_array = np.linspace(-pi, pi, Num_ky)
kx2_array = np.linspace(-pi, pi, Num_kx2)
ky2_array = np.linspace(-pi, pi, Num_ky2)
# Part I: calculate p_y_for_nu_x
p_y_for_nu_x_array = []
for kx in kx2_array:
print('kx=', kx)
w_vector_for_nu1_array = []
vector1_array = []
vector2_array = []
i0 = -1
for ky in ky_array:
eigenvalue, eigenvector = np.linalg.eigh(hamiltonian(kx, ky))
if ky != pi:
vector1_array.append(eigenvector[:, 0])
vector2_array.append(eigenvector[:, 1])
else:
vector1_array.append(vector1_array[0])
vector2_array.append(vector2_array[0])
i0=0
for ky in ky_array:
if ky != pi:
nu_x_vector_1, nu_x_vector_2 = get_nu_x_vector(kx_array, ky)
# the Wannier band subspaces
w_vector_for_nu1 = vector1_array[i0]*nu_x_vector_1[0]+vector2_array[i0]*nu_x_vector_1[1]
w_vector_for_nu1_array.append(w_vector_for_nu1)
else:
w_vector_for_nu1_array.append(w_vector_for_nu1_array[0])
i0 +=1
W_y_k_for_nu_x = 1
for i0 in range(Num_ky-1):
F_for_nu_x = np.dot(w_vector_for_nu1_array[i0+1].transpose().conj(), w_vector_for_nu1_array[i0])
W_y_k_for_nu_x = F_for_nu_x*W_y_k_for_nu_x
p_y_for_nu_x = np.log(W_y_k_for_nu_x)/2/pi/1j
if np.real(p_y_for_nu_x) < 0:
p_y_for_nu_x += 1
p_y_for_nu_x_array.append(p_y_for_nu_x.real)
print('p_y_for_nu_x=', p_y_for_nu_x)
plot(kx2_array, p_y_for_nu_x_array, xlabel='kx', ylabel='p_y_for_nu_x', style='-o', y_min=0, y_max=1)
# import guan
# guan.plot(kx2_array, p_y_for_nu_x_array, xlabel='kx', ylabel='p_y_for_nu_x', style='-o', y_min=0, y_max=1)
# Part II: calculate p_x_for_nu_y
p_x_for_nu_y_array = []
for ky in ky2_array:
w_vector_for_nu1_array = []
vector1_array = []
vector2_array = []
for kx in kx_array:
eigenvalue, eigenvector = np.linalg.eigh(hamiltonian(kx, ky))
if kx != pi:
vector1_array.append(eigenvector[:, 0])
vector2_array.append(eigenvector[:, 1])
else:
vector1_array.append(vector1_array[0])
vector2_array.append(vector2_array[0])
i0 = 0
for kx in kx_array:
if kx != pi:
nu_y_vector_1, nu_y_vector_2 = get_nu_y_vector(kx, ky_array)
# the Wannier band subspaces
w_vector_for_nu1 = vector1_array[i0]*nu_y_vector_1[0]+vector2_array[i0]*nu_y_vector_1[1]
w_vector_for_nu1_array.append(w_vector_for_nu1)
else:
w_vector_for_nu1_array.append(w_vector_for_nu1_array[0])
i0 += 1
W_x_k_for_nu_y = 1
for i0 in range(Num_ky-1):
F_for_nu_y = np.dot(w_vector_for_nu1_array[i0+1].transpose().conj(), w_vector_for_nu1_array[i0])
W_x_k_for_nu_y = F_for_nu_y*W_x_k_for_nu_y
p_x_for_nu_y = np.log(W_x_k_for_nu_y)/2/pi/1j
if np.real(p_x_for_nu_y) < 0:
p_x_for_nu_y += 1
p_x_for_nu_y_array.append(p_x_for_nu_y.real)
print('p_x_for_nu_y=', p_x_for_nu_y)
# print(sum(p_x_for_nu_y_array)/len(p_x_for_nu_y_array))
plot(ky2_array, p_x_for_nu_y_array, xlabel='ky', ylabel='p_x_for_nu_y', style='-o', y_min=0, y_max=1)
# import guan
# guan.plot(ky2_array, p_x_for_nu_y_array, xlabel='ky', ylabel='p_x_for_nu_y', style='-o', y_min=0, y_max=1)
def get_nu_x_vector(kx_array, ky):
Num_kx = len(kx_array)
vector1_array = []
vector2_array = []
for kx in kx_array:
eigenvalue, eigenvector = np.linalg.eigh(hamiltonian(kx, ky))
if kx != pi:
vector1_array.append(eigenvector[:, 0])
vector2_array.append(eigenvector[:, 1])
else:
vector1_array.append(vector1_array[0])
vector2_array.append(vector2_array[0])
W_x_k = np.eye(2, dtype=complex)
for i0 in range(Num_kx-1):
F = np.zeros((2, 2), dtype=complex)
F[0, 0] = np.dot(vector1_array[i0+1].transpose().conj(), vector1_array[i0])
F[1, 1] = np.dot(vector2_array[i0+1].transpose().conj(), vector2_array[i0])
F[0, 1] = np.dot(vector1_array[i0+1].transpose().conj(), vector2_array[i0])
F[1, 0] = np.dot(vector2_array[i0+1].transpose().conj(), vector1_array[i0])
W_x_k = np.dot(F, W_x_k)
eigenvalue, eigenvector = np.linalg.eig(W_x_k)
nu_x = np.log(eigenvalue)/2/pi/1j
nu_x_vector_1 = eigenvector[:, np.argsort(np.real(nu_x))[0]]
nu_x_vector_2 = eigenvector[:, np.argsort(np.real(nu_x))[1]]
return nu_x_vector_1, nu_x_vector_2
def get_nu_y_vector(kx, ky_array):
Num_ky = len(ky_array)
vector1_array = []
vector2_array = []
for ky in ky_array:
eigenvalue, eigenvector = np.linalg.eigh(hamiltonian(kx, ky))
if ky != pi:
vector1_array.append(eigenvector[:, 0])
vector2_array.append(eigenvector[:, 1])
else:
vector1_array.append(vector1_array[0])
vector2_array.append(vector2_array[0])
W_y_k = np.eye(2, dtype=complex)
for i0 in range(Num_ky-1):
F = np.zeros((2, 2), dtype=complex)
F[0, 0] = np.dot(vector1_array[i0+1].transpose().conj(), vector1_array[i0])
F[1, 1] = np.dot(vector2_array[i0+1].transpose().conj(), vector2_array[i0])
F[0, 1] = np.dot(vector1_array[i0+1].transpose().conj(), vector2_array[i0])
F[1, 0] = np.dot(vector2_array[i0+1].transpose().conj(), vector1_array[i0])
W_y_k = np.dot(F, W_y_k)
eigenvalue, eigenvector = np.linalg.eig(W_y_k)
nu_y = np.log(eigenvalue)/2/pi/1j
nu_y_vector_1 = eigenvector[:, np.argsort(np.real(nu_y))[0]]
nu_y_vector_2 = eigenvector[:, np.argsort(np.real(nu_y))[1]]
return nu_y_vector_1, nu_y_vector_2
def plot(x_array, y_array, xlabel='x', ylabel='y', title='', fontsize=20, labelsize=20, show=1, save=0, filename='a', file_format='.jpg', dpi=300, style='', y_min=None, y_max=None, linewidth=None, markersize=None, adjust_bottom=0.2, adjust_left=0.2):
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=adjust_bottom, left=adjust_left)
ax.plot(x_array, y_array, style, linewidth=linewidth, markersize=markersize)
ax.grid()
ax.set_title(title, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_xlabel(xlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_ylabel(ylabel, fontsize=fontsize, fontfamily='Times New Roman')
if y_min!=None or y_max!=None:
if y_min==None:
y_min=min(y_array)
if y_max==None:
y_max=max(y_array)
ax.set_ylim(y_min, y_max)
ax.tick_params(labelsize=labelsize)
labels = ax.get_xticklabels() + ax.get_yticklabels()
[label.set_fontname('Times New Roman') for label in labels]
if save == 1:
plt.savefig(filename+file_format, dpi=dpi)
if show == 1:
plt.show()
plt.close('all')
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,15 @@
if kx == -pi:
vector1_array.append(eigenvector[:, 0])
vector2_array.append(eigenvector[:, 1])
elif kx != pi:
# 这里的判断是为了处理能带简并时最简单情况,只做个对调。
if np.abs(np.dot(vector1_array[-1].transpose().conj(), eigenvector[:, 0]))>0.5:
vector1_array.append(eigenvector[:, 0])
vector2_array.append(eigenvector[:, 1])
else:
vector1_array.append(eigenvector[:, 1])
vector2_array.append(eigenvector[:, 0])
else:
# 这里是为了-pi和pi有相同的波函数使得Wilson loop的值与波函数规范无关。
vector1_array.append(vector1_array[0])
vector2_array.append(vector2_array[0])

View File

@@ -0,0 +1,42 @@
"""
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/18306
"""
import numpy as np
from math import *
import cmath
import functools
import guan
def hamiltonian(kx, ky, Ny, B):
h00 = np.zeros((Ny, Ny), dtype=complex)
h01 = np.zeros((Ny, Ny), dtype=complex)
t = 1
for iy in range(Ny-1):
h00[iy, iy+1] = t
h00[iy+1, iy] = t
h00[Ny-1, 0] = t*cmath.exp(1j*ky)
h00[0, Ny-1] = t*cmath.exp(-1j*ky)
for iy in range(Ny):
h01[iy, iy] = t*cmath.exp(-2*np.pi*1j*B*iy)
matrix = h00 + h01*cmath.exp(1j*kx) + h01.transpose().conj()*cmath.exp(-1j*kx)
return matrix
def main():
Ny = 21
k_array = np.linspace(-pi, pi, 100)
H_k = functools.partial(hamiltonian, ky=0, Ny=Ny, B=1/Ny)
eigenvalue_array = guan.calculate_eigenvalue_with_one_parameter(k_array, H_k)
guan.plot(k_array, eigenvalue_array, xlabel='kx', ylabel='E', style='k')
H_k = functools.partial(hamiltonian, Ny=Ny, B=1/Ny)
chern_number = guan.calculate_chern_number_for_square_lattice_with_efficient_method(H_k, precision=100)
print(chern_number)
print(sum(chern_number))
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,114 @@
"""
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/18306
"""
import numpy as np
import time
import cmath
import guan
def get_lead_h00(width):
h00 = np.zeros((width, width))
for i0 in range(width-1):
h00[i0, i0+1] = 1
h00[i0+1, i0] = 1
return h00
def get_lead_h01(width):
h01 = np.identity(width)
return h01
def get_center_hamiltonian(Nx, Ny, B):
h = np.zeros((Nx*Ny, Nx*Ny), dtype=complex)
for x0 in range(Nx-1):
for y0 in range(Ny):
h[x0*Ny+y0, (x0+1)*Ny+y0] = 1*cmath.exp(-2*np.pi*1j*B*y0) # x方向的跃迁
h[(x0+1)*Ny+y0, x0*Ny+y0] = 1*cmath.exp(2*np.pi*1j*B*y0)
for x0 in range(Nx):
for y0 in range(Ny-1):
h[x0*Ny+y0, x0*Ny+y0+1] = 1 # y方向的跃迁
h[x0*Ny+y0+1, x0*Ny+y0] = 1
return h
def main():
start_time = time.time()
width = 21
length = 72
fermi_energy_array = np.arange(-4, 4, .05)
# 中心区的哈密顿量
H_cetner = get_center_hamiltonian(Nx=length, Ny=width, B=1/width)
# 电极的h00和h01
lead_h00 = get_lead_h00(width)
lead_h01 = get_lead_h01(width)
transmission_12_array = []
transmission_13_array = []
transmission_14_array = []
transmission_15_array = []
transmission_16_array = []
transmission_1_all_array = []
for fermi_energy in fermi_energy_array:
print(fermi_energy)
# 几何形状如下所示:
# lead2 lead3
# lead1(L) lead4(R)
# lead6 lead5
# 电极到中心区的跃迁矩阵
h_lead1_to_center = np.zeros((width, width*length), dtype=complex)
h_lead2_to_center = np.zeros((width, width*length), dtype=complex)
h_lead3_to_center = np.zeros((width, width*length), dtype=complex)
h_lead4_to_center = np.zeros((width, width*length), dtype=complex)
h_lead5_to_center = np.zeros((width, width*length), dtype=complex)
h_lead6_to_center = np.zeros((width, width*length), dtype=complex)
move = 10 # the step of leads 2,3,6,5 moving to center
for i0 in range(width):
h_lead1_to_center[i0, i0] = 1
h_lead2_to_center[i0, width*(move+i0)+(width-1)] = 1
h_lead3_to_center[i0, width*(length-move-1-i0)+(width-1)] = 1
h_lead4_to_center[i0, width*(length-1)+i0] = 1
h_lead5_to_center[i0, width*(length-move-1-i0)+0] = 1
h_lead6_to_center[i0, width*(i0+move)+0] = 1
# 自能
self_energy1, gamma1 = guan.self_energy_of_lead_with_h_lead_to_center(fermi_energy, lead_h00, lead_h01, h_lead1_to_center)
self_energy2, gamma2 = guan.self_energy_of_lead_with_h_lead_to_center(fermi_energy, lead_h00, lead_h01, h_lead2_to_center)
self_energy3, gamma3 = guan.self_energy_of_lead_with_h_lead_to_center(fermi_energy, lead_h00, lead_h01, h_lead3_to_center)
self_energy4, gamma4 = guan.self_energy_of_lead_with_h_lead_to_center(fermi_energy, lead_h00, lead_h01, h_lead4_to_center)
self_energy5, gamma5 = guan.self_energy_of_lead_with_h_lead_to_center(fermi_energy, lead_h00, lead_h01, h_lead5_to_center)
self_energy6, gamma6 = guan.self_energy_of_lead_with_h_lead_to_center(fermi_energy, lead_h00, lead_h01, h_lead6_to_center)
# 整体格林函数
green = np.linalg.inv(fermi_energy*np.eye(width*length)-H_cetner-self_energy1-self_energy2-self_energy3-self_energy4-self_energy5-self_energy6)
# Transmission
transmission_12 = np.trace(np.dot(np.dot(np.dot(gamma1, green), gamma2), green.transpose().conj()))
transmission_13 = np.trace(np.dot(np.dot(np.dot(gamma1, green), gamma3), green.transpose().conj()))
transmission_14 = np.trace(np.dot(np.dot(np.dot(gamma1, green), gamma4), green.transpose().conj()))
transmission_15 = np.trace(np.dot(np.dot(np.dot(gamma1, green), gamma5), green.transpose().conj()))
transmission_16 = np.trace(np.dot(np.dot(np.dot(gamma1, green), gamma6), green.transpose().conj()))
transmission_12_array.append(np.real(transmission_12))
transmission_13_array.append(np.real(transmission_13))
transmission_14_array.append(np.real(transmission_14))
transmission_15_array.append(np.real(transmission_15))
transmission_16_array.append(np.real(transmission_16))
transmission_1_all_array.append(np.real(transmission_12+transmission_13+transmission_14+transmission_15+transmission_16))
guan.plot(fermi_energy_array, transmission_12_array, xlabel='Fermi energy', ylabel='Transmission_12')
guan.plot(fermi_energy_array, transmission_13_array, xlabel='Fermi energy', ylabel='Transmission_13')
guan.plot(fermi_energy_array, transmission_14_array, xlabel='Fermi energy', ylabel='Transmission_14')
guan.plot(fermi_energy_array, transmission_15_array, xlabel='Fermi energy', ylabel='Transmission_15')
guan.plot(fermi_energy_array, transmission_16_array, xlabel='Fermi energy', ylabel='Transmission_16')
guan.plot(fermi_energy_array, transmission_1_all_array, xlabel='Fermi energy', ylabel='Transmission_1_all')
end_time = time.time()
print('运行时间=', end_time-start_time)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,72 @@
"""
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()

View File

@@ -0,0 +1,67 @@
"""
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()

View File

@@ -0,0 +1,55 @@
"""
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/20869
"""
import numpy as np
import matplotlib.pyplot as plt
from math import *
import cmath
def hamiltonian(k1, k2, t1=2.82, a=1/sqrt(3)): # 石墨烯哈密顿量a为原子间距不赋值的话默认为1/sqrt(3)
h = np.zeros((2, 2), dtype=complex)
h[0, 0] = 0.28/2
h[1, 1] = -0.28/2
h[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))
h[0, 1] = h[1, 0].conj()
return h
def main():
n = 2000 # 取点密度
delta = 1e-9 # 求导的偏离量
for band in range(2):
F_all = [] # 贝里曲率
for kx in np.linspace(-2*pi, 2*pi, n):
for ky in [0]: # 这里只考虑ky=0对称轴上的情况
H = hamiltonian(kx, ky)
eigenvalue, eigenvector = np.linalg.eig(H)
if band==0:
vector_0 = eigenvector[:, np.argsort(np.real(eigenvalue))[0]]
vector_1 = eigenvector[:, np.argsort(np.real(eigenvalue))[1]]
elif band==1:
vector_0 = eigenvector[:, np.argsort(np.real(eigenvalue))[1]]
vector_1 = eigenvector[:, np.argsort(np.real(eigenvalue))[0]]
eigenvalue = np.sort(np.real(eigenvalue))
H_delta_kx = hamiltonian(kx+delta, ky)-hamiltonian(kx, ky)
H_delta_ky = hamiltonian(kx, ky+delta)-hamiltonian(kx, ky)
berry_curvature = 1j*(np.dot(np.dot(np.dot(np.dot(np.dot(vector_0.transpose().conj(), H_delta_kx/delta), vector_1), vector_1.transpose().conj()), H_delta_ky/delta), vector_0)- np.dot(np.dot(np.dot(np.dot(np.dot(vector_0.transpose().conj(), H_delta_ky/delta), vector_1), vector_1.transpose().conj()), H_delta_kx/delta), vector_0))/(eigenvalue[0]-eigenvalue[1])**2
F_all = np.append(F_all,[berry_curvature], axis=0)
plt.plot(np.linspace(-2*pi, 2*pi, n)/pi, np.real(F_all))
plt.xlabel('k_x (pi)')
plt.ylabel('Berry curvature')
if band==0:
plt.title('Valence Band')
else:
plt.title('Conductance Band')
plt.show()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,72 @@
"""
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/20869
"""
import numpy as np
import matplotlib.pyplot as plt
from math import *
import cmath
def hamiltonian(k1, k2, t1=2.82, a=1/sqrt(3)): # 石墨烯哈密顿量a为原子间距不赋值的话默认为1/sqrt(3)
h = np.zeros((2, 2), dtype=complex)
h[0, 0] = 0.28/2
h[1, 1] = -0.28/2
h[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))
h[0, 1] = h[1, 0].conj()
return h
def main():
n1 = 1000 # small plaquettes精度
n2 = 10 # Wilson loop精度
delta = 2*pi/n1
for band in range(2):
F_all = [] # 贝里曲率
for kx in np.linspace(-2*pi, 2*pi, n1):
for ky in [0]: # 这里只考虑ky=0对称轴上的情况
vector_array = []
# line_1
for i2 in range(n2+1):
H_delta = hamiltonian(kx+delta/n2*i2, ky)
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))[band]]
vector_array.append(vector_delta)
# line_2
for i2 in range(n2):
H_delta = hamiltonian(kx+delta, ky+delta/n2*(i2+1))
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))[band]]
vector_array.append(vector_delta)
# line_3
for i2 in range(n2):
H_delta = hamiltonian(kx+delta-delta/n2*(i2+1), ky+delta)
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))[band]]
vector_array.append(vector_delta)
# line_4
for i2 in range(n2-1):
H_delta = hamiltonian(kx, ky+delta-delta/n2*(i2+1))
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))[band]]
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)/delta/delta*1j
F_all = np.append(F_all,[arg], axis=0)
plt.plot(np.linspace(-2*pi, 2*pi, n1)/pi, np.real(F_all))
plt.xlabel('k_x (pi)')
plt.ylabel('Berry curvature')
if band==0:
plt.title('Valence Band')
else:
plt.title('Conductance Band')
plt.show()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,63 @@
"""
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/20869
"""
import numpy as np
import matplotlib.pyplot as plt
from math import *
import cmath
def hamiltonian(k1, k2, t1=2.82, a=1/sqrt(3)): # 石墨烯哈密顿量a为原子间距不赋值的话默认为1/sqrt(3)
h = np.zeros((2, 2), dtype=complex)
h[0, 0] = 0.28/2
h[1, 1] = -0.28/2
h[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))
h[0, 1] = h[1, 0].conj()
return h
def main():
n = 2000 # 取点密度
delta = 4*pi/n # 求导的偏离量
for band in range(2):
F_all = [] # 贝里曲率
for kx in np.linspace(-2*pi, 2*pi, n):
for ky in [0]: # 这里只考虑ky=0对称轴上的情况
H = hamiltonian(kx, ky)
eigenvalue, eigenvector = np.linalg.eig(H)
vector = eigenvector[:, np.argsort(np.real(eigenvalue))[band]] # 价带波函数
H_delta_kx = hamiltonian(kx+delta, ky)
eigenvalue, eigenvector = np.linalg.eig(H_delta_kx)
vector_delta_kx = eigenvector[:, np.argsort(np.real(eigenvalue))[band]] # 略偏离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))[band]] # 略偏离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))[band]] # 略偏离kx和ky的波函数
Ux = np.dot(np.conj(vector), vector_delta_kx)/abs(np.dot(np.conj(vector), vector_delta_kx))
Uy = np.dot(np.conj(vector), vector_delta_ky)/abs(np.dot(np.conj(vector), vector_delta_ky))
Ux_y = np.dot(np.conj(vector_delta_ky), vector_delta_kx_ky)/abs(np.dot(np.conj(vector_delta_ky), vector_delta_kx_ky))
Uy_x = np.dot(np.conj(vector_delta_kx), vector_delta_kx_ky)/abs(np.dot(np.conj(vector_delta_kx), vector_delta_kx_ky))
F = cmath.log(Ux*Uy_x*(1/Ux_y)*(1/Uy))/delta/delta*1j
F_all = np.append(F_all,[F], axis=0)
plt.plot(np.linspace(-2*pi, 2*pi, n)/pi, np.real(F_all))
plt.xlabel('k_x (pi)')
plt.ylabel('Berry curvature')
if band==0:
plt.title('Valence Band')
else:
plt.title('Conductance Band')
plt.show()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,48 @@
"""
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/22604
"""
import numpy as np
import cmath
def find_vector_with_fixed_gauge_by_making_one_component_real(vector, precision=0.005, index=None):
vector = np.array(vector)
if index == None:
index = np.argmax(np.abs(vector))
sign_pre = np.sign(np.imag(vector[index]))
for phase in np.arange(0, 2*np.pi, precision):
sign = np.sign(np.imag(vector[index]*cmath.exp(1j*phase)))
if np.abs(np.imag(vector[index]*cmath.exp(1j*phase))) < 1e-9 or sign == -sign_pre:
break
sign_pre = sign
vector = vector*cmath.exp(1j*phase)
if np.real(vector[index]) < 0:
vector = -vector
return vector
vector_1 = np.array([np.sqrt(0.5), np.sqrt(0.5)])*cmath.exp(np.random.uniform(0, 1)*1j)
vector_2 = np.array([1, 0])*cmath.exp(np.random.uniform(0, 1)*1j)
print('\n随机规范的原向量:', vector_1)
vector_1 = find_vector_with_fixed_gauge_by_making_one_component_real(vector_1, precision=0.001)
print('固定规范后的向量:', vector_1)
print('\n随机规范的原向量:', vector_2)
vector_2 = find_vector_with_fixed_gauge_by_making_one_component_real(vector_2, precision=0.001)
print('固定规范后的向量:', vector_2)
# # 可直接使用Guan软件包来调用以上函数https://py.guanjihuan.com。
# # 安装命令pip install --upgrade guan。
# import guan
# print('\n随机规范的原向量', vector_1)
# vector_1 = guan.find_vector_with_fixed_gauge_by_making_one_component_real(vector_1, precision=0.001)
# print('固定规范后的向量:', vector_1)
# print('\n随机规范的原向量', vector_2)
# vector_2 = guan.find_vector_with_fixed_gauge_by_making_one_component_real(vector_2, precision=0.001)
# print('固定规范后的向量:', vector_2)

View File

@@ -0,0 +1,78 @@
"""
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/22604
"""
import numpy as np
import math
import cmath
# from numba import jit
# @jit
def rotation_of_degenerate_vectors(vector1, vector2, index1=None, index2=None, precision=0.01, criterion=0.01, show_theta=0):
vector1 = np.array(vector1)
vector2 = np.array(vector2)
if index1 == None:
index1 = np.argmax(np.abs(vector1))
if index2 == None:
index2 = np.argmax(np.abs(vector2))
if np.abs(vector1[index2])>criterion or np.abs(vector2[index1])>criterion:
for theta in np.arange(0, 2*math.pi, precision):
if show_theta==1:
print(theta)
for phi1 in np.arange(0, 2*math.pi, precision):
for phi2 in np.arange(0, 2*math.pi, precision):
vector1_test = cmath.exp(1j*phi1)*vector1*math.cos(theta)+cmath.exp(1j*phi2)*vector2*math.sin(theta)
vector2_test = -cmath.exp(-1j*phi2)*vector1*math.sin(theta)+cmath.exp(-1j*phi1)*vector2*math.cos(theta)
if np.abs(vector1_test[index2])<criterion and np.abs(vector2_test[index1])<criterion:
vector1 = vector1_test
vector2 = vector2_test
break
if np.abs(vector1_test[index2])<criterion and np.abs(vector2_test[index1])<criterion:
break
if np.abs(vector1_test[index2])<criterion and np.abs(vector2_test[index1])<criterion:
break
return vector1, vector2
def hamiltonian_of_bbh_model(kx, ky, gamma_x=0.5, gamma_y=0.5, lambda_x=1, lambda_y=1):
# label of atoms in a unit cell
# (2) —— (0)
# | |
# (1) —— (3)
hamiltonian = np.zeros((4, 4), dtype=complex)
hamiltonian[0, 2] = gamma_x+lambda_x*cmath.exp(1j*kx)
hamiltonian[1, 3] = gamma_x+lambda_x*cmath.exp(-1j*kx)
hamiltonian[0, 3] = gamma_y+lambda_y*cmath.exp(1j*ky)
hamiltonian[1, 2] = -gamma_y-lambda_y*cmath.exp(-1j*ky)
hamiltonian[2, 0] = np.conj(hamiltonian[0, 2])
hamiltonian[3, 1] = np.conj(hamiltonian[1, 3])
hamiltonian[3, 0] = np.conj(hamiltonian[0, 3])
hamiltonian[2, 1] = np.conj(hamiltonian[1, 2])
return hamiltonian
# For kx=0
print('\nFor kx=0:\n')
eigenvalue, eigenvector = np.linalg.eigh(hamiltonian_of_bbh_model(kx=0, ky=0))
print(eigenvalue, '\n')
print(eigenvector[:, 0])
print(eigenvector[:, 1], '\n')
# For kx=0.005
print('\nFor kx=0.005:\n')
eigenvalue, eigenvector = np.linalg.eigh(hamiltonian_of_bbh_model(kx=0.005, ky=0))
print(eigenvalue, '\n')
print(eigenvector[:, 0])
print(eigenvector[:, 1], '\n\n')
# Rotaion
vector1, vector2 = rotation_of_degenerate_vectors(eigenvector[:, 0], eigenvector[:, 1], precision=0.01, criterion=0.01, show_theta=1)
print()
print(vector1)
print(vector2, '\n')
# # 可直接使用Guan软件包来调用以上函数https://py.guanjihuan.com。
# # 安装命令pip install --upgrade guan。
# import guan
# vector1, vector2 = guan.rotation_of_degenerate_vectors(vector1, vector2, index1=None, index2=None, precision=0.01, criterion=0.01, show_theta=0)
# hamiltonian = guan.hamiltonian_of_bbh_model(kx, ky, gamma_x=0.5, gamma_y=0.5, lambda_x=1, lambda_y=1)

View File

@@ -0,0 +1,110 @@
"""
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/23989
"""
import numpy as np
import math
from math import *
import cmath
import functools
def hamiltonian(kx, ky, Ny, B):
h00 = np.zeros((Ny, Ny), dtype=complex)
h01 = np.zeros((Ny, Ny), dtype=complex)
t = 1
for iy in range(Ny-1):
h00[iy, iy+1] = t
h00[iy+1, iy] = t
h00[Ny-1, 0] = t*cmath.exp(1j*ky)
h00[0, Ny-1] = t*cmath.exp(-1j*ky)
for iy in range(Ny):
h01[iy, iy] = t*cmath.exp(-2*np.pi*1j*B*iy)
matrix = h00 + h01*cmath.exp(1j*kx) + h01.transpose().conj()*cmath.exp(-1j*kx)
return matrix
def main():
Ny = 20
H_k = functools.partial(hamiltonian, Ny=Ny, B=1/Ny)
chern_number = calculate_chern_number_for_square_lattice_with_wilson_loop_for_degenerate_case(H_k, index_of_bands=range(int(Ny/2)-1), precision_of_wilson_loop=5)
print('价带:', chern_number)
print()
chern_number = calculate_chern_number_for_square_lattice_with_wilson_loop_for_degenerate_case(H_k, index_of_bands=range(int(Ny/2)+2), precision_of_wilson_loop=5)
print('价带(包含两个交叉能带):', chern_number)
print()
chern_number = calculate_chern_number_for_square_lattice_with_wilson_loop_for_degenerate_case(H_k, index_of_bands=range(Ny), precision_of_wilson_loop=5)
print('所有能带:', chern_number)
# # 函数可通过Guan软件包调用。安装方法pip install --upgrade guan
# import guan
# chern_number = guan.calculate_chern_number_for_square_lattice_with_wilson_loop_for_degenerate_case(hamiltonian_function, index_of_bands=[0, 1], precision_of_plaquettes=20, precision_of_wilson_loop=5, print_show=0)
def calculate_chern_number_for_square_lattice_with_wilson_loop_for_degenerate_case(hamiltonian_function, index_of_bands=[0, 1], precision_of_plaquettes=20, precision_of_wilson_loop=5, print_show=0):
delta = 2*math.pi/precision_of_plaquettes
chern_number = 0
for kx in np.arange(-math.pi, math.pi, delta):
if print_show == 1:
print(kx)
for ky in np.arange(-math.pi, math.pi, delta):
vector_array = []
# line_1
for i0 in range(precision_of_wilson_loop):
H_delta = hamiltonian_function(kx+delta/precision_of_wilson_loop*i0, ky)
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))]
vector_array.append(vector_delta)
# line_2
for i0 in range(precision_of_wilson_loop):
H_delta = hamiltonian_function(kx+delta, ky+delta/precision_of_wilson_loop*i0)
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))]
vector_array.append(vector_delta)
# line_3
for i0 in range(precision_of_wilson_loop):
H_delta = hamiltonian_function(kx+delta-delta/precision_of_wilson_loop*i0, ky+delta)
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))]
vector_array.append(vector_delta)
# line_4
for i0 in range(precision_of_wilson_loop):
H_delta = hamiltonian_function(kx, ky+delta-delta/precision_of_wilson_loop*i0)
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))]
vector_array.append(vector_delta)
wilson_loop = 1
dim = len(index_of_bands)
for i0 in range(len(vector_array)-1):
dot_matrix = np.zeros((dim , dim), dtype=complex)
i01 = 0
for dim1 in index_of_bands:
i02 = 0
for dim2 in index_of_bands:
dot_matrix[i01, i02] = np.dot(vector_array[i0][:, dim1].transpose().conj(), vector_array[i0+1][:, dim2])
i02 += 1
i01 += 1
det_value = np.linalg.det(dot_matrix)
wilson_loop = wilson_loop*det_value
dot_matrix_plus = np.zeros((dim , dim), dtype=complex)
i01 = 0
for dim1 in index_of_bands:
i02 = 0
for dim2 in index_of_bands:
dot_matrix_plus[i01, i02] = np.dot(vector_array[len(vector_array)-1][:, dim1].transpose().conj(), vector_array[0][:, dim2])
i02 += 1
i01 += 1
det_value = np.linalg.det(dot_matrix_plus)
wilson_loop = wilson_loop*det_value
arg = np.log(wilson_loop)/1j
chern_number = chern_number + arg
chern_number = chern_number/(2*math.pi)
return chern_number
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,154 @@
"""
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/24059
"""
import numpy as np
from math import *
import cmath
import math
def hamiltonian(k1, k2, t1=2.82, a=1/sqrt(3)): # 石墨烯哈密顿量a为原子间距不赋值的话默认为1/sqrt(3)
h = np.zeros((2, 2), dtype=complex)
h[0, 0] = 0.28/2
h[1, 1] = -0.28/2
h[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))
h[0, 1] = h[1, 0].conj()
return h
def main():
k_array, berry_curvature_array = calculate_berry_curvature_with_wilson_loop(hamiltonian_function=hamiltonian, k_min=-2*math.pi, k_max=2*math.pi, precision_of_plaquettes=500, precision_of_wilson_loop=1)
plot_3d_surface(k_array, k_array, np.real(berry_curvature_array[:, :, 0]), title='Valence Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
plot_3d_surface(k_array, k_array, np.real(berry_curvature_array[:, :, 1]), title='Conductance Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
dim = berry_curvature_array.shape
plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :, 0]), title='Valence Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :, 1]), title='Conductance Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
# import guan
# k_array, berry_curvature_array = guan.calculate_berry_curvature_with_wilson_loop(hamiltonian_function=hamiltonian, k_min=-2*math.pi, k_max=2*math.pi, precision_of_plaquettes=500, precision_of_wilson_loop=1)
# guan.plot_3d_surface(k_array, k_array, np.real(berry_curvature_array[:, :, 0]), title='Valence Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
# guan.plot_3d_surface(k_array, k_array, np.real(berry_curvature_array[:, :, 1]), title='Conductance Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
# dim = berry_curvature_array.shape
# guan.plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :, 0]), title='Valence Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
# guan.plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :, 1]), title='Conductance Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
def calculate_berry_curvature_with_wilson_loop(hamiltonian_function, k_min=-math.pi, k_max=math.pi, precision_of_plaquettes=20, precision_of_wilson_loop=5, print_show=0):
if np.array(hamiltonian_function(0, 0)).shape==():
dim = 1
else:
dim = np.array(hamiltonian_function(0, 0)).shape[0]
delta = (k_max-k_min)/precision_of_plaquettes
k_array = np.arange(k_min, k_max, delta)
berry_curvature_array = np.zeros((k_array.shape[0], k_array.shape[0], dim), dtype=complex)
i00 = 0
for kx in k_array:
if print_show == 1:
print(kx)
j00 = 0
for ky in k_array:
vector_array = []
# line_1
for i0 in range(precision_of_wilson_loop):
H_delta = hamiltonian_function(kx+delta/precision_of_wilson_loop*i0, ky)
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))]
vector_array.append(vector_delta)
# line_2
for i0 in range(precision_of_wilson_loop):
H_delta = hamiltonian_function(kx+delta, ky+delta/precision_of_wilson_loop*i0)
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))]
vector_array.append(vector_delta)
# line_3
for i0 in range(precision_of_wilson_loop):
H_delta = hamiltonian_function(kx+delta-delta/precision_of_wilson_loop*i0, ky+delta)
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))]
vector_array.append(vector_delta)
# line_4
for i0 in range(precision_of_wilson_loop):
H_delta = hamiltonian_function(kx, ky+delta-delta/precision_of_wilson_loop*i0)
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))]
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])
berry_curvature = np.log(np.diagonal(wilson_loop))/delta/delta*1j
berry_curvature_array[j00, i00, :]=berry_curvature
j00 += 1
i00 += 1
return k_array, berry_curvature_array
def plot_3d_surface(x_array, y_array, matrix, xlabel='x', ylabel='y', zlabel='z', title='', fontsize=20, labelsize=15, show=1, save=0, filename='a', file_format='.jpg', dpi=300, z_min=None, z_max=None, rcount=100, ccount=100):
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator
matrix = np.array(matrix)
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
plt.subplots_adjust(bottom=0.1, right=0.65)
x_array, y_array = np.meshgrid(x_array, y_array)
if len(matrix.shape) == 2:
surf = ax.plot_surface(x_array, y_array, matrix, rcount=rcount, ccount=ccount, cmap=cm.coolwarm, linewidth=0, antialiased=False)
elif len(matrix.shape) == 3:
for i0 in range(matrix.shape[2]):
surf = ax.plot_surface(x_array, y_array, matrix[:,:,i0], rcount=rcount, ccount=ccount, cmap=cm.coolwarm, linewidth=0, antialiased=False)
ax.set_title(title, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_xlabel(xlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_ylabel(ylabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_zlabel(zlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.zaxis.set_major_locator(LinearLocator(5))
ax.zaxis.set_major_formatter('{x:.2f}')
if z_min!=None or z_max!=None:
if z_min==None:
z_min=matrix.min()
if z_max==None:
z_max=matrix.max()
ax.set_zlim(z_min, z_max)
ax.tick_params(labelsize=labelsize)
labels = ax.get_xticklabels() + ax.get_yticklabels() + ax.get_zticklabels()
[label.set_fontname('Times New Roman') for label in labels]
cax = plt.axes([0.8, 0.1, 0.05, 0.8])
cbar = fig.colorbar(surf, cax=cax)
cbar.ax.tick_params(labelsize=labelsize)
for l in cbar.ax.yaxis.get_ticklabels():
l.set_family('Times New Roman')
if save == 1:
plt.savefig(filename+file_format, dpi=dpi)
if show == 1:
plt.show()
plt.close('all')
def plot(x_array, y_array, xlabel='x', ylabel='y', title='', fontsize=20, labelsize=20, show=1, save=0, filename='a', file_format='.jpg', dpi=300, style='', y_min=None, y_max=None, linewidth=None, markersize=None, adjust_bottom=0.2, adjust_left=0.2):
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=adjust_bottom, left=adjust_left)
ax.grid()
ax.tick_params(labelsize=labelsize)
labels = ax.get_xticklabels() + ax.get_yticklabels()
[label.set_fontname('Times New Roman') for label in labels]
ax.plot(x_array, y_array, style, linewidth=linewidth, markersize=markersize)
ax.set_title(title, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_xlabel(xlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_ylabel(ylabel, fontsize=fontsize, fontfamily='Times New Roman')
if y_min!=None or y_max!=None:
if y_min==None:
y_min=min(y_array)
if y_max==None:
y_max=max(y_array)
ax.set_ylim(y_min, y_max)
if save == 1:
plt.savefig(filename+file_format, dpi=dpi)
if show == 1:
plt.show()
plt.close('all')
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,177 @@
"""
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/24059
"""
import numpy as np
from math import *
import cmath
import math
def hamiltonian(k1, k2, t1=2.82, a=1/sqrt(3)): # 石墨烯哈密顿量a为原子间距不赋值的话默认为1/sqrt(3)
h = np.zeros((2, 2), dtype=complex)
h[0, 0] = 0.28/2
h[1, 1] = -0.28/2
h[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))
h[0, 1] = h[1, 0].conj()
return h
def main():
k_array, berry_curvature_array = calculate_berry_curvature_with_wilson_loop_for_degenerate_case(hamiltonian_function=hamiltonian, index_of_bands=[0], k_min=-2*math.pi, k_max=2*math.pi, precision_of_plaquettes=500, precision_of_wilson_loop=1)
dim = berry_curvature_array.shape
plot_3d_surface(k_array, k_array, np.real(berry_curvature_array), title='Valence Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :]), title='Valence Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
k_array, berry_curvature_array = calculate_berry_curvature_with_wilson_loop_for_degenerate_case(hamiltonian_function=hamiltonian, index_of_bands=[0, 1], k_min=-2*math.pi, k_max=2*math.pi, precision_of_plaquettes=500, precision_of_wilson_loop=1)
dim = berry_curvature_array.shape
plot_3d_surface(k_array, k_array, np.real(berry_curvature_array), title='All Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :]), title='All Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
# import guan
# k_array, berry_curvature_array = guan.calculate_berry_curvature_with_wilson_loop_for_degenerate_case(hamiltonian_function=hamiltonian, index_of_bands=[0], k_min=-2*math.pi, k_max=2*math.pi, precision_of_plaquettes=500, precision_of_wilson_loop=1)
# dim = berry_curvature_array.shape
# guan.plot_3d_surface(k_array, k_array, np.real(berry_curvature_array), title='Valence Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
# guan.plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :]), title='Valence Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
# k_array, berry_curvature_array = guan.calculate_berry_curvature_with_wilson_loop_for_degenerate_case(hamiltonian_function=hamiltonian, index_of_bands=[0, 1], k_min=-2*math.pi, k_max=2*math.pi, precision_of_plaquettes=500, precision_of_wilson_loop=1)
# dim = berry_curvature_array.shape
# guan.plot_3d_surface(k_array, k_array, np.real(berry_curvature_array), title='All Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
# guan.plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :]), title='All Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
def calculate_berry_curvature_with_wilson_loop_for_degenerate_case(hamiltonian_function, index_of_bands=[0, 1], k_min=-math.pi, k_max=math.pi, precision_of_plaquettes=20, precision_of_wilson_loop=5, print_show=0):
delta = (k_max-k_min)/precision_of_plaquettes
k_array = np.arange(k_min, k_max, delta)
berry_curvature_array = np.zeros((k_array.shape[0], k_array.shape[0]), dtype=complex)
i000 = 0
for kx in k_array:
if print_show == 1:
print(kx)
j000 = 0
for ky in k_array:
vector_array = []
# line_1
for i0 in range(precision_of_wilson_loop):
H_delta = hamiltonian_function(kx+delta/precision_of_wilson_loop*i0, ky)
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))]
vector_array.append(vector_delta)
# line_2
for i0 in range(precision_of_wilson_loop):
H_delta = hamiltonian_function(kx+delta, ky+delta/precision_of_wilson_loop*i0)
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))]
vector_array.append(vector_delta)
# line_3
for i0 in range(precision_of_wilson_loop):
H_delta = hamiltonian_function(kx+delta-delta/precision_of_wilson_loop*i0, ky+delta)
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))]
vector_array.append(vector_delta)
# line_4
for i0 in range(precision_of_wilson_loop):
H_delta = hamiltonian_function(kx, ky+delta-delta/precision_of_wilson_loop*i0)
eigenvalue, eigenvector = np.linalg.eig(H_delta)
vector_delta = eigenvector[:, np.argsort(np.real(eigenvalue))]
vector_array.append(vector_delta)
wilson_loop = 1
dim = len(index_of_bands)
for i0 in range(len(vector_array)-1):
dot_matrix = np.zeros((dim , dim), dtype=complex)
i01 = 0
for dim1 in index_of_bands:
i02 = 0
for dim2 in index_of_bands:
dot_matrix[i01, i02] = np.dot(vector_array[i0][:, dim1].transpose().conj(), vector_array[i0+1][:, dim2])
i02 += 1
i01 += 1
det_value = np.linalg.det(dot_matrix)
wilson_loop = wilson_loop*det_value
dot_matrix_plus = np.zeros((dim , dim), dtype=complex)
i01 = 0
for dim1 in index_of_bands:
i02 = 0
for dim2 in index_of_bands:
dot_matrix_plus[i01, i02] = np.dot(vector_array[len(vector_array)-1][:, dim1].transpose().conj(), vector_array[0][:, dim2])
i02 += 1
i01 += 1
det_value = np.linalg.det(dot_matrix_plus)
wilson_loop = wilson_loop*det_value
berry_curvature = np.log(wilson_loop)/delta/delta*1j
berry_curvature_array[j000, i000]=berry_curvature
j000 += 1
i000 += 1
return k_array, berry_curvature_array
def plot_3d_surface(x_array, y_array, matrix, xlabel='x', ylabel='y', zlabel='z', title='', fontsize=20, labelsize=15, show=1, save=0, filename='a', file_format='.jpg', dpi=300, z_min=None, z_max=None, rcount=100, ccount=100):
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator
matrix = np.array(matrix)
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
plt.subplots_adjust(bottom=0.1, right=0.65)
x_array, y_array = np.meshgrid(x_array, y_array)
if len(matrix.shape) == 2:
surf = ax.plot_surface(x_array, y_array, matrix, rcount=rcount, ccount=ccount, cmap=cm.coolwarm, linewidth=0, antialiased=False)
elif len(matrix.shape) == 3:
for i0 in range(matrix.shape[2]):
surf = ax.plot_surface(x_array, y_array, matrix[:,:,i0], rcount=rcount, ccount=ccount, cmap=cm.coolwarm, linewidth=0, antialiased=False)
ax.set_title(title, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_xlabel(xlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_ylabel(ylabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_zlabel(zlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.zaxis.set_major_locator(LinearLocator(5))
ax.zaxis.set_major_formatter('{x:.2f}')
if z_min!=None or z_max!=None:
if z_min==None:
z_min=matrix.min()
if z_max==None:
z_max=matrix.max()
ax.set_zlim(z_min, z_max)
ax.tick_params(labelsize=labelsize)
labels = ax.get_xticklabels() + ax.get_yticklabels() + ax.get_zticklabels()
[label.set_fontname('Times New Roman') for label in labels]
cax = plt.axes([0.8, 0.1, 0.05, 0.8])
cbar = fig.colorbar(surf, cax=cax)
cbar.ax.tick_params(labelsize=labelsize)
for l in cbar.ax.yaxis.get_ticklabels():
l.set_family('Times New Roman')
if save == 1:
plt.savefig(filename+file_format, dpi=dpi)
if show == 1:
plt.show()
plt.close('all')
def plot(x_array, y_array, xlabel='x', ylabel='y', title='', fontsize=20, labelsize=20, show=1, save=0, filename='a', file_format='.jpg', dpi=300, style='', y_min=None, y_max=None, linewidth=None, markersize=None, adjust_bottom=0.2, adjust_left=0.2):
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=adjust_bottom, left=adjust_left)
ax.grid()
ax.tick_params(labelsize=labelsize)
labels = ax.get_xticklabels() + ax.get_yticklabels()
[label.set_fontname('Times New Roman') for label in labels]
ax.plot(x_array, y_array, style, linewidth=linewidth, markersize=markersize)
ax.set_title(title, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_xlabel(xlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_ylabel(ylabel, fontsize=fontsize, fontfamily='Times New Roman')
if y_min!=None or y_max!=None:
if y_min==None:
y_min=min(y_array)
if y_max==None:
y_max=max(y_array)
ax.set_ylim(y_min, y_max)
if save == 1:
plt.savefig(filename+file_format, dpi=dpi)
if show == 1:
plt.show()
plt.close('all')
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,141 @@
"""
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/24059
"""
import numpy as np
from math import *
import cmath
import math
def hamiltonian(k1, k2, t1=2.82, a=1/sqrt(3)): # 石墨烯哈密顿量a为原子间距不赋值的话默认为1/sqrt(3)
h = np.zeros((2, 2), dtype=complex)
h[0, 0] = 0.28/2
h[1, 1] = -0.28/2
h[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))
h[0, 1] = h[1, 0].conj()
return h
def main():
k_array, berry_curvature_array = calculate_berry_curvature_with_efficient_method(hamiltonian_function=hamiltonian, k_min=-2*math.pi, k_max=2*math.pi, precision=500, print_show=0)
plot_3d_surface(k_array, k_array, np.real(berry_curvature_array[:, :, 0]), title='Valence Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
plot_3d_surface(k_array, k_array, np.real(berry_curvature_array[:, :, 1]), title='Conductance Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
dim = berry_curvature_array.shape
plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :, 0]), title='Valence Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :, 1]), title='Conductance Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
# import guan
# k_array, berry_curvature_array = guan.calculate_berry_curvature_with_efficient_method(hamiltonian_function=hamiltonian, k_min=-2*math.pi, k_max=2*math.pi, precision=500, print_show=0)
# guan.plot_3d_surface(k_array, k_array, np.real(berry_curvature_array[:, :, 0]), title='Valence Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
# guan.plot_3d_surface(k_array, k_array, np.real(berry_curvature_array[:, :, 1]), title='Conductance Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
# dim = berry_curvature_array.shape
# guan.plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :, 0]), title='Valence Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
# guan.plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :, 1]), title='Conductance Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
def calculate_berry_curvature_with_efficient_method(hamiltonian_function, k_min=-math.pi, k_max=math.pi, precision=100, print_show=0):
if np.array(hamiltonian_function(0, 0)).shape==():
dim = 1
else:
dim = np.array(hamiltonian_function(0, 0)).shape[0]
delta = (k_max-k_min)/precision
k_array = np.arange(k_min, k_max, delta)
berry_curvature_array = np.zeros((k_array.shape[0], k_array.shape[0], dim), dtype=complex)
i0 = 0
for kx in k_array:
if print_show == 1:
print(kx)
j0 = 0
for ky in k_array:
H = hamiltonian_function(kx, ky)
eigenvalue, vector = np.linalg.eigh(H)
H_delta_kx = hamiltonian_function(kx+delta, ky)
eigenvalue, vector_delta_kx = np.linalg.eigh(H_delta_kx)
H_delta_ky = hamiltonian_function(kx, ky+delta)
eigenvalue, vector_delta_ky = np.linalg.eigh(H_delta_ky)
H_delta_kx_ky = hamiltonian_function(kx+delta, ky+delta)
eigenvalue, vector_delta_kx_ky = np.linalg.eigh(H_delta_kx_ky)
for i in range(dim):
vector_i = vector[:, i]
vector_delta_kx_i = vector_delta_kx[:, i]
vector_delta_ky_i = vector_delta_ky[:, i]
vector_delta_kx_ky_i = vector_delta_kx_ky[:, i]
Ux = np.dot(np.conj(vector_i), vector_delta_kx_i)/abs(np.dot(np.conj(vector_i), vector_delta_kx_i))
Uy = np.dot(np.conj(vector_i), vector_delta_ky_i)/abs(np.dot(np.conj(vector_i), vector_delta_ky_i))
Ux_y = np.dot(np.conj(vector_delta_ky_i), vector_delta_kx_ky_i)/abs(np.dot(np.conj(vector_delta_ky_i), vector_delta_kx_ky_i))
Uy_x = np.dot(np.conj(vector_delta_kx_i), vector_delta_kx_ky_i)/abs(np.dot(np.conj(vector_delta_kx_i), vector_delta_kx_ky_i))
berry_curvature = cmath.log(Ux*Uy_x*(1/Ux_y)*(1/Uy))/delta/delta*1j
berry_curvature_array[j0, i0, i] = berry_curvature
j0 += 1
i0 += 1
return k_array, berry_curvature_array
def plot_3d_surface(x_array, y_array, matrix, xlabel='x', ylabel='y', zlabel='z', title='', fontsize=20, labelsize=15, show=1, save=0, filename='a', file_format='.jpg', dpi=300, z_min=None, z_max=None, rcount=100, ccount=100):
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator
matrix = np.array(matrix)
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
plt.subplots_adjust(bottom=0.1, right=0.65)
x_array, y_array = np.meshgrid(x_array, y_array)
if len(matrix.shape) == 2:
surf = ax.plot_surface(x_array, y_array, matrix, rcount=rcount, ccount=ccount, cmap=cm.coolwarm, linewidth=0, antialiased=False)
elif len(matrix.shape) == 3:
for i0 in range(matrix.shape[2]):
surf = ax.plot_surface(x_array, y_array, matrix[:,:,i0], rcount=rcount, ccount=ccount, cmap=cm.coolwarm, linewidth=0, antialiased=False)
ax.set_title(title, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_xlabel(xlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_ylabel(ylabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_zlabel(zlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.zaxis.set_major_locator(LinearLocator(5))
ax.zaxis.set_major_formatter('{x:.2f}')
if z_min!=None or z_max!=None:
if z_min==None:
z_min=matrix.min()
if z_max==None:
z_max=matrix.max()
ax.set_zlim(z_min, z_max)
ax.tick_params(labelsize=labelsize)
labels = ax.get_xticklabels() + ax.get_yticklabels() + ax.get_zticklabels()
[label.set_fontname('Times New Roman') for label in labels]
cax = plt.axes([0.8, 0.1, 0.05, 0.8])
cbar = fig.colorbar(surf, cax=cax)
cbar.ax.tick_params(labelsize=labelsize)
for l in cbar.ax.yaxis.get_ticklabels():
l.set_family('Times New Roman')
if save == 1:
plt.savefig(filename+file_format, dpi=dpi)
if show == 1:
plt.show()
plt.close('all')
def plot(x_array, y_array, xlabel='x', ylabel='y', title='', fontsize=20, labelsize=20, show=1, save=0, filename='a', file_format='.jpg', dpi=300, style='', y_min=None, y_max=None, linewidth=None, markersize=None, adjust_bottom=0.2, adjust_left=0.2):
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=adjust_bottom, left=adjust_left)
ax.grid()
ax.tick_params(labelsize=labelsize)
labels = ax.get_xticklabels() + ax.get_yticklabels()
[label.set_fontname('Times New Roman') for label in labels]
ax.plot(x_array, y_array, style, linewidth=linewidth, markersize=markersize)
ax.set_title(title, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_xlabel(xlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_ylabel(ylabel, fontsize=fontsize, fontfamily='Times New Roman')
if y_min!=None or y_max!=None:
if y_min==None:
y_min=min(y_array)
if y_max==None:
y_max=max(y_array)
ax.set_ylim(y_min, y_max)
if save == 1:
plt.savefig(filename+file_format, dpi=dpi)
if show == 1:
plt.show()
plt.close('all')
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,183 @@
"""
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/24059
"""
import numpy as np
from math import *
import cmath
import math
def hamiltonian(k1, k2, t1=2.82, a=1/sqrt(3)): # 石墨烯哈密顿量a为原子间距不赋值的话默认为1/sqrt(3)
h = np.zeros((2, 2), dtype=complex)
h[0, 0] = 0.28/2
h[1, 1] = -0.28/2
h[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))
h[0, 1] = h[1, 0].conj()
return h
def main():
k_array, berry_curvature_array = calculate_berry_curvature_with_efficient_method_for_degenerate_case(hamiltonian_function=hamiltonian, index_of_bands=[0], k_min=-2*math.pi, k_max=2*math.pi, precision=500)
dim = berry_curvature_array.shape
plot_3d_surface(k_array, k_array, np.real(berry_curvature_array), title='Valence Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :]), title='Valence Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
k_array, berry_curvature_array = calculate_berry_curvature_with_efficient_method_for_degenerate_case(hamiltonian_function=hamiltonian, index_of_bands=[0, 1], k_min=-2*math.pi, k_max=2*math.pi, precision=500)
dim = berry_curvature_array.shape
plot_3d_surface(k_array, k_array, np.real(berry_curvature_array), title='All Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :]), title='All Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
# import guan
# k_array, berry_curvature_array = guan.calculate_berry_curvature_with_efficient_method_for_degenerate_case(hamiltonian_function=hamiltonian, index_of_bands=[0], k_min=-2*math.pi, k_max=2*math.pi, precision=500)
# dim = berry_curvature_array.shape
# guan.plot_3d_surface(k_array, k_array, np.real(berry_curvature_array), title='Valence Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
# guan.plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :]), title='Valence Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
# k_array, berry_curvature_array = guan.calculate_berry_curvature_with_efficient_method_for_degenerate_case(hamiltonian_function=hamiltonian, index_of_bands=[0, 1], k_min=-2*math.pi, k_max=2*math.pi, precision=500)
# dim = berry_curvature_array.shape
# guan.plot_3d_surface(k_array, k_array, np.real(berry_curvature_array), title='All Band', xlabel='kx', ylabel='ky', zlabel='Berry curvature')
# guan.plot(k_array, np.real(berry_curvature_array[int(dim[0]/2), :]), title='All Band ky=0', xlabel='kx', ylabel='Berry curvature') # ky=0
def calculate_berry_curvature_with_efficient_method_for_degenerate_case(hamiltonian_function, index_of_bands=[0, 1], k_min=-math.pi, k_max=math.pi, precision=100, print_show=0):
delta = (k_max-k_min)/precision
k_array = np.arange(k_min, k_max, delta)
berry_curvature_array = np.zeros((k_array.shape[0], k_array.shape[0]), dtype=complex)
i00 = 0
for kx in np.arange(k_min, k_max, delta):
if print_show == 1:
print(kx)
j00 = 0
for ky in np.arange(k_min, k_max, delta):
H = hamiltonian_function(kx, ky)
eigenvalue, vector = np.linalg.eigh(H)
H_delta_kx = hamiltonian_function(kx+delta, ky)
eigenvalue, vector_delta_kx = np.linalg.eigh(H_delta_kx)
H_delta_ky = hamiltonian_function(kx, ky+delta)
eigenvalue, vector_delta_ky = np.linalg.eigh(H_delta_ky)
H_delta_kx_ky = hamiltonian_function(kx+delta, ky+delta)
eigenvalue, vector_delta_kx_ky = np.linalg.eigh(H_delta_kx_ky)
dim = len(index_of_bands)
det_value = 1
# first dot product
dot_matrix = np.zeros((dim , dim), dtype=complex)
i0 = 0
for dim1 in index_of_bands:
j0 = 0
for dim2 in index_of_bands:
dot_matrix[i0, j0] = np.dot(np.conj(vector[:, dim1]), vector_delta_kx[:, dim2])
j0 += 1
i0 += 1
dot_matrix = np.linalg.det(dot_matrix)/abs(np.linalg.det(dot_matrix))
det_value = det_value*dot_matrix
# second dot product
dot_matrix = np.zeros((dim , dim), dtype=complex)
i0 = 0
for dim1 in index_of_bands:
j0 = 0
for dim2 in index_of_bands:
dot_matrix[i0, j0] = np.dot(np.conj(vector_delta_kx[:, dim1]), vector_delta_kx_ky[:, dim2])
j0 += 1
i0 += 1
dot_matrix = np.linalg.det(dot_matrix)/abs(np.linalg.det(dot_matrix))
det_value = det_value*dot_matrix
# third dot product
dot_matrix = np.zeros((dim , dim), dtype=complex)
i0 = 0
for dim1 in index_of_bands:
j0 = 0
for dim2 in index_of_bands:
dot_matrix[i0, j0] = np.dot(np.conj(vector_delta_kx_ky[:, dim1]), vector_delta_ky[:, dim2])
j0 += 1
i0 += 1
dot_matrix = np.linalg.det(dot_matrix)/abs(np.linalg.det(dot_matrix))
det_value = det_value*dot_matrix
# four dot product
dot_matrix = np.zeros((dim , dim), dtype=complex)
i0 = 0
for dim1 in index_of_bands:
j0 = 0
for dim2 in index_of_bands:
dot_matrix[i0, j0] = np.dot(np.conj(vector_delta_ky[:, dim1]), vector[:, dim2])
j0 += 1
i0 += 1
dot_matrix = np.linalg.det(dot_matrix)/abs(np.linalg.det(dot_matrix))
det_value= det_value*dot_matrix
berry_curvature = cmath.log(det_value)/delta/delta*1j
berry_curvature_array[j00, i00] = berry_curvature
j00 += 1
i00 += 1
return k_array, berry_curvature_array
def plot_3d_surface(x_array, y_array, matrix, xlabel='x', ylabel='y', zlabel='z', title='', fontsize=20, labelsize=15, show=1, save=0, filename='a', file_format='.jpg', dpi=300, z_min=None, z_max=None, rcount=100, ccount=100):
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator
matrix = np.array(matrix)
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
plt.subplots_adjust(bottom=0.1, right=0.65)
x_array, y_array = np.meshgrid(x_array, y_array)
if len(matrix.shape) == 2:
surf = ax.plot_surface(x_array, y_array, matrix, rcount=rcount, ccount=ccount, cmap=cm.coolwarm, linewidth=0, antialiased=False)
elif len(matrix.shape) == 3:
for i0 in range(matrix.shape[2]):
surf = ax.plot_surface(x_array, y_array, matrix[:,:,i0], rcount=rcount, ccount=ccount, cmap=cm.coolwarm, linewidth=0, antialiased=False)
ax.set_title(title, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_xlabel(xlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_ylabel(ylabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_zlabel(zlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.zaxis.set_major_locator(LinearLocator(5))
ax.zaxis.set_major_formatter('{x:.2f}')
if z_min!=None or z_max!=None:
if z_min==None:
z_min=matrix.min()
if z_max==None:
z_max=matrix.max()
ax.set_zlim(z_min, z_max)
ax.tick_params(labelsize=labelsize)
labels = ax.get_xticklabels() + ax.get_yticklabels() + ax.get_zticklabels()
[label.set_fontname('Times New Roman') for label in labels]
cax = plt.axes([0.8, 0.1, 0.05, 0.8])
cbar = fig.colorbar(surf, cax=cax)
cbar.ax.tick_params(labelsize=labelsize)
for l in cbar.ax.yaxis.get_ticklabels():
l.set_family('Times New Roman')
if save == 1:
plt.savefig(filename+file_format, dpi=dpi)
if show == 1:
plt.show()
plt.close('all')
def plot(x_array, y_array, xlabel='x', ylabel='y', title='', fontsize=20, labelsize=20, show=1, save=0, filename='a', file_format='.jpg', dpi=300, style='', y_min=None, y_max=None, linewidth=None, markersize=None, adjust_bottom=0.2, adjust_left=0.2):
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=adjust_bottom, left=adjust_left)
ax.grid()
ax.tick_params(labelsize=labelsize)
labels = ax.get_xticklabels() + ax.get_yticklabels()
[label.set_fontname('Times New Roman') for label in labels]
ax.plot(x_array, y_array, style, linewidth=linewidth, markersize=markersize)
ax.set_title(title, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_xlabel(xlabel, fontsize=fontsize, fontfamily='Times New Roman')
ax.set_ylabel(ylabel, fontsize=fontsize, fontfamily='Times New Roman')
if y_min!=None or y_max!=None:
if y_min==None:
y_min=min(y_array)
if y_max==None:
y_max=max(y_array)
ax.set_ylim(y_min, y_max)
if save == 1:
plt.savefig(filename+file_format, dpi=dpi)
if show == 1:
plt.show()
plt.close('all')
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,116 @@
"""
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/25107
"""
import numpy as np
import math
from math import *
import cmath
import functools
def hamiltonian(kx, ky, Ny, B):
h00 = np.zeros((Ny, Ny), dtype=complex)
h01 = np.zeros((Ny, Ny), dtype=complex)
t = 1
for iy in range(Ny-1):
h00[iy, iy+1] = t
h00[iy+1, iy] = t
h00[Ny-1, 0] = t*cmath.exp(1j*ky)
h00[0, Ny-1] = t*cmath.exp(-1j*ky)
for iy in range(Ny):
h01[iy, iy] = t*cmath.exp(-2*np.pi*1j*B*iy)
matrix = h00 + h01*cmath.exp(1j*kx) + h01.transpose().conj()*cmath.exp(-1j*kx)
return matrix
def main():
Ny = 20
H_k = functools.partial(hamiltonian, Ny=Ny, B=1/Ny)
chern_number = calculate_chern_number_for_square_lattice_with_efficient_method_for_degenerate_case(H_k, index_of_bands=range(int(Ny/2)-1))
print('价带:', chern_number)
print()
chern_number = calculate_chern_number_for_square_lattice_with_efficient_method_for_degenerate_case(H_k, index_of_bands=range(int(Ny/2)+2))
print('价带(包含两个交叉能带):', chern_number)
print()
chern_number = calculate_chern_number_for_square_lattice_with_efficient_method_for_degenerate_case(H_k, index_of_bands=range(Ny))
print('所有能带:', chern_number)
# 函数可通过Guan软件包调用。安装方法pip install --upgrade guan
# import guan
# chern_number = guan.calculate_chern_number_for_square_lattice_with_efficient_method_for_degenerate_case(hamiltonian_function, index_of_bands=[0, 1], precision=100, print_show=0)
def calculate_chern_number_for_square_lattice_with_efficient_method_for_degenerate_case(hamiltonian_function, index_of_bands=[0, 1], precision=100, print_show=0):
delta = 2*math.pi/precision
chern_number = 0
for kx in np.arange(-math.pi, math.pi, delta):
if print_show == 1:
print(kx)
for ky in np.arange(-math.pi, math.pi, delta):
H = hamiltonian_function(kx, ky)
eigenvalue, vector = np.linalg.eigh(H)
H_delta_kx = hamiltonian_function(kx+delta, ky)
eigenvalue, vector_delta_kx = np.linalg.eigh(H_delta_kx)
H_delta_ky = hamiltonian_function(kx, ky+delta)
eigenvalue, vector_delta_ky = np.linalg.eigh(H_delta_ky)
H_delta_kx_ky = hamiltonian_function(kx+delta, ky+delta)
eigenvalue, vector_delta_kx_ky = np.linalg.eigh(H_delta_kx_ky)
dim = len(index_of_bands)
det_value = 1
# first dot product
dot_matrix = np.zeros((dim , dim), dtype=complex)
i0 = 0
for dim1 in index_of_bands:
j0 = 0
for dim2 in index_of_bands:
dot_matrix[i0, j0] = np.dot(np.conj(vector[:, dim1]), vector_delta_kx[:, dim2])
j0 += 1
i0 += 1
dot_matrix = np.linalg.det(dot_matrix)/abs(np.linalg.det(dot_matrix))
det_value = det_value*dot_matrix
# second dot product
dot_matrix = np.zeros((dim , dim), dtype=complex)
i0 = 0
for dim1 in index_of_bands:
j0 = 0
for dim2 in index_of_bands:
dot_matrix[i0, j0] = np.dot(np.conj(vector_delta_kx[:, dim1]), vector_delta_kx_ky[:, dim2])
j0 += 1
i0 += 1
dot_matrix = np.linalg.det(dot_matrix)/abs(np.linalg.det(dot_matrix))
det_value = det_value*dot_matrix
# third dot product
dot_matrix = np.zeros((dim , dim), dtype=complex)
i0 = 0
for dim1 in index_of_bands:
j0 = 0
for dim2 in index_of_bands:
dot_matrix[i0, j0] = np.dot(np.conj(vector_delta_kx_ky[:, dim1]), vector_delta_ky[:, dim2])
j0 += 1
i0 += 1
dot_matrix = np.linalg.det(dot_matrix)/abs(np.linalg.det(dot_matrix))
det_value = det_value*dot_matrix
# fourth dot product
dot_matrix = np.zeros((dim , dim), dtype=complex)
i0 = 0
for dim1 in index_of_bands:
j0 = 0
for dim2 in index_of_bands:
dot_matrix[i0, j0] = np.dot(np.conj(vector_delta_ky[:, dim1]), vector[:, dim2])
j0 += 1
i0 += 1
dot_matrix = np.linalg.det(dot_matrix)/abs(np.linalg.det(dot_matrix))
det_value= det_value*dot_matrix
chern_number += cmath.log(det_value)
chern_number = chern_number/(2*math.pi*1j)
return chern_number
if __name__ == '__main__':
main()