学术, 朗道能级

六角格子/石墨烯紧束缚模型的朗道能级(附Python代码)

这是之前的一篇:方格子紧束缚模型中朗道能级的陈数/霍尔电导(附Python代码)。本篇计算六角格子的朗道能级,代码主要参考和修改自这篇:六角格子的佩尔斯替换和石墨烯条带的Hofstadter蝴蝶(附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/23834
"""

import numpy as np
from math import *  
import cmath  
import functools 


def hamiltonian(kx, ky, B, N, M, t1, a):  # 在磁场下的二维石墨烯,取磁元胞
    h00 = np.zeros((4*N, 4*N), dtype=complex)
    h01 = np.zeros((4*N, 4*N), dtype=complex)
    # 原胞内的跃迁h00
    for i in range(N):
        h00[i*4+0, i*4+0] = M
        h00[i*4+1, i*4+1] = -M
        h00[i*4+2, i*4+2] = M
        h00[i*4+3, i*4+3] = -M
        # 最近邻
        h00[i*4+0, i*4+1] = t1*cmath.exp(-2*pi*1j*B*(3*a*i+1/4*a)*(np.sqrt(3)/2*a))
        h00[i*4+1, i*4+0] = np.conj(h00[i*4+0, i*4+1])
        h00[i*4+1, i*4+2] = t1
        h00[i*4+2, i*4+1] = np.conj(h00[i*4+1, i*4+2])
        h00[i*4+2, i*4+3] = t1*cmath.exp(2*pi*1j*B*(3*a*i+7/4*a)*(np.sqrt(3)/2)*a)
        h00[i*4+3, i*4+2] = np.conj(h00[i*4+2, i*4+3])
    for i in range(N-1):
        # 最近邻
        h00[i*4+3, (i+1)*4+0] = t1
        h00[(i+1)*4+0, i*4+3] = t1
    h00[4*(N-1)+3, 0] = t1*cmath.exp(1j*ky)
    h00[0, 4*(N-1)+3] = t1*cmath.exp(-1j*ky)
    # 原胞间的跃迁h01
    for i in range(N):
        # 最近邻
        h01[i*4+1, i*4+0] = t1*cmath.exp(-2*pi*1j*B*(3*a*i+1/4*a)*(np.sqrt(3)/2*a))
        h01[i*4+2, i*4+3] = t1*cmath.exp(-2*pi*1j*B*(3*a*i+7/4*a)*(np.sqrt(3)/2*a))
    matrix = h00 + h01*cmath.exp(1j*kx) + h01.transpose().conj()*cmath.exp(-1j*kx)
    return matrix


def main():
    N = 300
    a = 1
    hamiltonian_function = functools.partial(hamiltonian, ky=0, B=1/(3*np.sqrt(3)/2*a*a*N), N=N, M=0, t1=1, a=a)


    # 查看能带图
    k_array = np.linspace(-pi, pi, 10)
    eigenvalue_array = calculate_eigenvalue_with_one_parameter(k_array, hamiltonian_function)
    plot(k_array, eigenvalue_array, xlabel='kx', ylabel='E', title='ky=0    N=%i    Φ/Φ_0=1/(3*np.sqrt(3)/2*a*a*N)'%N, style='k-', y_max=1, y_min=-1)

    # import guan
    # k_array = np.linspace(-pi, pi, 10)
    # eigenvalue_array = guan.calculate_eigenvalue_with_one_parameter(k_array, hamiltonian_function)
    # guan.plot(k_array, eigenvalue_array, xlabel='kx', ylabel='E', title='ky=0    N=%i    Φ/Φ_0=1/(3*np.sqrt(3)/2*a*a*N)'%N, style='k-', y_max=1, y_min=-1)


    # 查看关系
    eigenvalue, eigenvector = np.linalg.eigh(hamiltonian_function(0))
    print('本征值个数:', eigenvalue.shape)
    new_eigenvalue = []
    for eigen in eigenvalue:
        if -0.1<eigen<0.8:  # 找某个范围内的本征值
            if new_eigenvalue == []:
                new_eigenvalue.append(eigen)
            else:
                if np.abs(eigen-new_eigenvalue[-1])>0.001:  # 去除简并
                    new_eigenvalue.append(eigen)
    print('大于等于0的本征值个数:', len(new_eigenvalue), '\n')
    print(new_eigenvalue)
    plot(range(len(new_eigenvalue)), np.square(np.real(new_eigenvalue)), xlabel='n', ylabel='E^2', style='o-')


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 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()

运行结果:

结论:六角格子/石墨烯紧束缚模型的朗道能级在费米能为零附近接近于根号N的分布。

参考资料:

[1] Yan-Yang Zhang et alThree-dimensional topological insulator in a magnetic field: chiral side surface states and quantized Hall conductance, J. Phys.: Condens. Matter 24 015004 (2012).

2,626 次浏览

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

5 thoughts on “六角格子/石墨烯紧束缚模型的朗道能级(附Python代码)”

  1. 感觉确实是周期性边界条件导致了其振荡,我将尺度取到很大后就可以看到基本不振荡了。

  2. 您好,我想请问一下,这里的六角格子算出来的LLs都是平的,并且不同的k对应相同的E,我的问题是你这里写的程序应该是周期性条件下的,对吧,不是开边界的条件;还有就是我也看了您写的方格子的LLs,为什么方格子的LLs在E=0附近就是低能部分是关于cos振荡的,而不是想六角格子一样都是平。

    1. 挺好的一个问题,我之前也发现了这个现象,其实也不是完全懂,但大概率就是由于晶格离散化所导致的,因为二维电子气的朗道能级不存在震荡的现象,参考:二维电子气的朗道能级

      以下是我个人的理解,不一定对,供参考。
      (1)二维电子气晶格化后k^2对应的是cos的形式,这个近似应该是在k=0附近才比较成立,然而方格子的k=0时不是最低能量,因此当费米能E=0时,晶格化后的朗道能级和二维电子气的朗道能级会呈现出一些偏差。至于震荡的来源,应该是由于晶格周期性和有限尺寸的影响。
      (2)对于六角格子,它的低能部分E=0附近刚好是线性的,满足狄拉克费米子的性质,参考:狄拉克电子朗道能级的根号N分布,因此在晶格中朗道能级的数值计算的结果和理论值比较吻合。

发表评论

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

Captcha Code