Z2PackDev / Z2Pack

A tool for calculating topological invariants.
https://z2pack.greschd.ch
GNU General Public License v3.0
81 stars 51 forks source link

The Chern number of the Haldane model #206

Open xlhuang-phy opened 6 months ago

xlhuang-phy commented 6 months ago

Dear developer,

I calculated the Chern number of the Haldane model using software and found it to be incorrect. I am using the Haldane model provided in the book "Topological Insulators - Dirac Equation in Condensed Matters", which is not in Bloch form. However, I believe that the Chern number is not related to the gauge. I don't know where the reason lies or what parameters should be set. Here is my code and results.

import z2pack
import numpy as np

identity=np.identity(2,dtype=complex)
pauli_x=np.array([[0,1],[1,0]],dtype=complex)
pauli_y=np.array([[0,-1j],[1j,0]],dtype=complex)
pauli_z=np.array([[1,0],[0,-1]],dtype=complex)

def Hamilton(k,M,t1,t2,phi):
    a=1
    a1=np.array([0,1]);a2=np.array([-np.sqrt(3)*a/2,-a/2]);a3=np.array([np.sqrt(3)*a/2,-a/2]);
    b1=a2-a3;b2=a3-a1;b3=a1-a2;
    epsilon=2*t2*np.cos(phi)*(np.cos(np.dot(k,b1))+np.cos(np.dot(k,b2))+np.cos(np.dot(k,b3)))
    dx=t1*(np.cos(np.dot(k,a1))+np.cos(np.dot(k,a2))+np.cos(np.dot(k,a3)))
    dy=t1*(np.sin(np.dot(k,a1))+np.sin(np.dot(k,a2))+np.sin(np.dot(k,a3)))
    dz=M-2*t2*np.sin(phi)*(np.sin(np.dot(k,b1))+np.sin(np.dot(k,b2))+np.sin(np.dot(k,b3)))
    H=epsilon*identity+dx*pauli_x+dy*pauli_y+dz*pauli_z 
    return H

system=z2pack.hm.System(
    lambda k:Hamilton(k,0.1,1,0.2,0.2*np.pi),
    #lambda k:Hamilton(k,0.5,1.,1./3,0.5*np.pi),
    #lambda k:Hamilton(k,0.5,1.,1./3,-0.5*np.pi),
    bands=1,
    dim=2
)

result=z2pack.surface.run(
    system=system,
    surface=lambda s,t:[t,s],
    min_neighbour_dist=1e-5
)

print('Chern number:',z2pack.invariant.chern(result))

Chern number: 0.000314335120135396

greschd commented 6 months ago

It seems like there's a $2 \pi$ missing somewhere; the Z2Pack example uses the convention that the Hamiltonian is periodic w.r.t. $[0, 1]$, whereas the one defined here is periodic w.r.t. $[0, 2\pi]$ as far as I can tell.

So, either the Hamiltonian should include a factor $2\pi$ to get a period of $1$, or lambda s, t: [t, s] should be changed to lambda s, t: [2 * pi * t,2 * pi * s], adapting how reciprocal space is defined.

xlhuang-phy commented 6 months ago

Hello!

I changed the code and ran it according to your reply, but the program encountered an error:

Value Error: Start and end points of the line buffer by [6.28318531 0.], Which is not an inverse lattice vector

May I ask if your system can run successfully? The Hamiltonian remains unchanged, and my modified code is

def get_chern(m, t1, t2, phi):
    system = z2pack.hm.System(
        lambda k: Hamilton(k, m, t1, t2, phi), dim=2, bands=1
    )

    result = z2pack.surface.run(
        system=system, surface=lambda s, t: [2*np.pi*t, 2*np.pi*s], min_neighbour_dist=1e-5
    )
    return z2pack.invariant.chern(result)

if __name__ == "__main__":
    print(get_chern(0.5, 1., 1. / 3., 0.5 * np.pi))
    print(get_chern(0.5, 1., 1. / 3., -0.5 * np.pi))
    print(get_chern(0.1, 1., 0.2, 0.2*np.pi))

The norm of the second nearest neighbor in the hexagonal lattice used for my Hamiltonian is sqrt(3), and even after dividing it by sqrt(3), I still haven't obtained the correct result. I'm not sure if the Hamiltonian should change.

greschd commented 6 months ago

Value Error: Start and end points of the line buffer by [6.28318531 0.], Which is not an inverse lattice vector

Ah, I hadn't remembered this check.

In that case, the Hamiltonian needs to be adapted s.t. it's expressed with respect to the reduced inverse lattice vector. In other words, it needs to be periodic when adding $[0, 1]$ or $[1, 0]$.