category
This commit is contained in:
@@ -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)); % 略偏离kx,ky的波函数
|
||||
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; % 略偏离ky的berry connection Ax
|
||||
Ay_delta_kx=Vkx'*(Vkxky-Vkx)/delta; % 略偏离kx的berry 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
|
@@ -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) # 贝里联络Ax(x分量)
|
||||
A_y = np.dot(vector.transpose().conj(), (vector_delta_ky-vector)/delta) # 贝里联络Ay(y分量)
|
||||
|
||||
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()
|
@@ -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) # 贝里联络Ax(x分量)
|
||||
A_y = np.dot(vector.transpose().conj(), (vector_delta_ky-vector)/delta) # 贝里联络Ay(y分量)
|
||||
|
||||
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()
|
@@ -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) # 贝里联络Ax(x分量)
|
||||
A_y = np.dot(vector.transpose().conj(), (vector_delta_ky-vector)/delta) # 贝里联络Ay(y分量)
|
||||
|
||||
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()
|
@@ -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)); % 略偏离kx,ky的波函数
|
||||
|
||||
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
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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)); % 略偏离kx,ky的波函数
|
||||
|
||||
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
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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) # 贝里联络Ax(x分量)
|
||||
A_y = np.dot(vector.transpose().conj(), (vector_delta_ky-vector)/delta) # 贝里联络Ay(y分量)
|
||||
|
||||
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()
|
@@ -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) # 贝里联络Ax(x分量)
|
||||
A_y = np.dot(vector.transpose().conj(), (vector_delta_ky-vector)/delta) # 贝里联络Ay(y分量)
|
||||
|
||||
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()
|
@@ -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) # 贝里联络Ax(x分量)
|
||||
A_y = np.dot(vector.transpose().conj(), (vector_delta_ky-vector)/delta) # 贝里联络Ay(y分量)
|
||||
|
||||
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()
|
@@ -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) # 贝里联络Ax(x分量)
|
||||
A_y = np.dot(vector.transpose().conj(), (vector_delta_ky-vector)/delta) # 贝里联络Ay(y分量)
|
||||
|
||||
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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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])
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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)
|
@@ -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)
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
@@ -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()
|
Reference in New Issue
Block a user