拓扑不变量, 学术

非简并波函数和简并波函数的固定规范

一、非简并波函数的固定规范

在之前这篇文章“SSH模型中的Wilson loop(附Python代码)”中,用到了非简并波函数的固定规范方法。这里重新提下,并给出例子。

原理:循环规范的参数,当波函数的某个指定元素为实数时,停止循环,返回波函数。

补充:除了循环查找,也可以对某个指定元素乘一个相反的相位角,达到实数化的目的,这种运算效率更高,推荐使用这种方法。

Python代码:

"""
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('随机规范的原向量:', vector_1)
angle = cmath.phase(vector_1[0])
print('固定规范后的向量(方法1):', vector_1*cmath.exp(-1j*angle))
vector_1 = find_vector_with_fixed_gauge_by_making_one_component_real(vector_1, precision=0.001)
print('固定规范后的向量(方法2):', vector_1)

print('\n随机规范的原向量:', vector_2)
angle = cmath.phase(vector_2[0])
print('固定规范后的向量(方法1):', vector_2*cmath.exp(-1j*angle))
vector_2 = find_vector_with_fixed_gauge_by_making_one_component_real(vector_2, precision=0.001)
print('固定规范后的向量(方法2):', vector_2)

运行结果:

随机规范的原向量: [0.6050246+0.36598529j 0.6050246+0.36598529j]
固定规范后的向量(方法1): [0.70710678+0.j 0.70710678+0.j]
固定规范后的向量(方法2): [0.70710672+0.00030346j 0.70710672+0.00030346j]

随机规范的原向量: [0.97845851+0.20644355j 0.        +0.j        ]
固定规范后的向量(方法1): [1.+0.j 0.+0.j]
固定规范后的向量(方法2): [0.99999994+0.00034615j 0.        -0.j        ]

二、简并波函数的固定规范

需要说明的是:这个方法涉及到三重循环查找参数,因此效率不是特别高,暂不推荐使用,仅作参考。

此外,对关键的函数可以通过Numba加速,速度会快很多,但用上Numba后运行可能会出一些警告,需要对问题一个个排除。参考:Numba加速Python的时间测试

原理:对简并波函数进行一般性的幺正变换,当得到满足规定形式的规范时,停止参数的循环,返回波函数。

计算公式[1]:

Python代码(说明:如果需要在整个布里渊区都连续,那么需要全程固定一个indxe1和index2。这里只是作为例子,一个k值的波函数给出一个index1和index2):

"""
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')

运行结果:

For kx=0:

[-2.12132034 -2.12132034  2.12132034  2.12132034]

[ 0.        +0.j -0.70710678+0.j -0.5       +0.j  0.5       +0.j]
[-0.70710678+0.j  0.        +0.j  0.5       +0.j  0.5       +0.j]


For kx=0.005:

[-2.1213174 -2.1213174  2.1213174  2.1213174]

[-0.1795765 +0.j         -0.68392353+0.00094454j -0.35662876+0.00024463j
  0.61058577+0.00094413j]
[ 0.68392418+0.j         -0.17957633+0.00024801j -0.61058388+0.00178739j
 -0.35662876+0.0002479j ]


0.0
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.1
0.11
0.12
0.13
0.14
0.15
0.16
0.17
0.18
0.19
0.2
0.21
0.22
0.23
0.24
0.25

[-0.00478835+0.j         -0.70708989+0.00097654j -0.4966029 +0.00067923j
  0.50337277+0.00097611j]
[ 0.70709057+0.00000000e+00j -0.00478834+6.61300191e-06j
 -0.50337094+1.67129993e-03j -0.49660337+6.61013877e-06j]

参考资料:

[1] “An anomalous higher-order topological insulator” Supplemental material

1,007 次浏览

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

3 thoughts on “非简并波函数和简并波函数的固定规范”

  1. 博主你好,我想问下 ,为什么当波函数的某个指定元素为实数时,这样就固定了一个规范?我不是很理解

    1. 如果是非零元素,乘任意相位exp(1j*phase)都会导致该元素为非实数,所以当为实数时是一个特殊的相位。每个波函数都这么规定,那么波函数就具有连续性,求导就不容易发散。

发表评论

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

Captcha Code