56 lines
2.9 KiB
Python
56 lines
2.9 KiB
Python
# Guan is an open-source python package developed and maintained by https://www.guanjihuan.com/about. The primary location of this package is on website https://py.guanjihuan.com.
|
|
|
|
# calculate topological invariant
|
|
|
|
import numpy as np
|
|
import cmath
|
|
from math import *
|
|
from .calculate_band_structures_and_wave_functions import *
|
|
|
|
def calculate_chern_number_for_square_lattice(hamiltonian_function, precision=100):
|
|
if np.array(hamiltonian_function(0, 0)).shape==():
|
|
dim = 1
|
|
else:
|
|
dim = np.array(hamiltonian_function(0, 0)).shape[0]
|
|
delta = 2*pi/precision
|
|
chern_number = np.zeros(dim, dtype=complex)
|
|
for kx in np.arange(-pi, pi, delta):
|
|
for ky in np.arange(-pi, pi, delta):
|
|
H = hamiltonian_function(kx, ky)
|
|
vector = calculate_eigenvector(H)
|
|
H_delta_kx = hamiltonian_function(kx+delta, ky)
|
|
vector_delta_kx = calculate_eigenvector(H_delta_kx)
|
|
H_delta_ky = hamiltonian_function(kx, ky+delta)
|
|
vector_delta_ky = calculate_eigenvector(H_delta_ky)
|
|
H_delta_kx_ky = hamiltonian_function(kx+delta, ky+delta)
|
|
vector_delta_kx_ky = calculate_eigenvector(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))
|
|
F = cmath.log(Ux*Uy_x*(1/Ux_y)*(1/Uy))
|
|
chern_number[i] = chern_number[i] + F
|
|
chern_number = chern_number/(2*pi*1j)
|
|
return chern_number
|
|
|
|
def calculate_wilson_loop(hamiltonian_function, k_min=-pi, k_max=pi, precision=100):
|
|
k_array = np.linspace(k_min, k_max, precision)
|
|
dim = np.array(hamiltonian_function(0)).shape[0]
|
|
wilson_loop_array = np.ones(dim, dtype=complex)
|
|
for i in range(dim):
|
|
eigenvector_array = []
|
|
for k in k_array:
|
|
eigenvector = calculate_eigenvector(hamiltonian_function(k))
|
|
if k != k_max:
|
|
eigenvector_array.append(eigenvector[:, i])
|
|
else:
|
|
eigenvector_array.append(eigenvector_array[0])
|
|
for i0 in range(precision-1):
|
|
F = np.dot(eigenvector_array[i0+1].transpose().conj(), eigenvector_array[i0])
|
|
wilson_loop_array[i] = np.dot(F, wilson_loop_array[i])
|
|
return wilson_loop_array |