The sample programs included in the book Berry Phases in Electronic Structure Theory: Electric Polarization, Orbital Magnetization and Topological Insulators (David Vanderbilt, Cambridge University Press, 2018), together with their printed and plotted outputs, can be downloaded here:
Alternatively, the sample programs and outputs can be browsed or downloaded individually below.
Note that the outputs archived here are the result of running PythTB 1.8.0 under Python 3. In a few cases, the original program sources, as posted at the time of publication of the book in 2018, have been modified slightly for compatibility with PythTB 1.8.0. The original source files and outputs can be found HERE.
The links in the first column of the table will take you to the corresponding entry in the long listing below.
Note that PDF plots are embedded as PNGs below.
#!/usr/bin/env python from __future__ import print_function # python3 style print # ---------------------------------------------------------- # Tight-binding model for H2O molecule # ---------------------------------------------------------- # import the pythtb module from pythtb import * import numpy as np # geometry: bond length and half bond-angle b=1.0; angle=54.0*np.pi/180 # site energies [O(s), O(p), H(s)] eos=-1.5; eop=-1.2; eh=-1.0 # hoppings [O(s)-H(s), O(p)-H(s)] ts=-0.4; tp=-0.3 # define frame for defining vectors: 3D Cartesian lat=[[1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0]] # define coordinates of orbitals: O(s,px,py,pz) ; H(s) ; H(s) orb=[ [0.,0.,0.], [0.,0.,0.], [0.,0.,0.], [0.,0.,0.], [b*np.cos(angle), b*np.sin(angle),0.], [b*np.cos(angle),-b*np.sin(angle),0.] ] # define model my_model=tb_model(0,3,lat,orb) my_model.set_onsite([eos,eop,eop,eop,eh,eh]) my_model.set_hop(ts,0,4) my_model.set_hop(ts,0,5) my_model.set_hop(tp*np.cos(angle),1,4) my_model.set_hop(tp*np.cos(angle),1,5) my_model.set_hop(tp*np.sin(angle),2,4) my_model.set_hop(-tp*np.sin(angle),2,5) # print model my_model.display() # solve model (eval,evec)=my_model.solve_all(eig_vectors=True) # the model is real, so OK to discard imaginary parts of eigenvectors evec=evec.real # optional: choose overall sign of evec according to some specified rule # (here, we make the average oxygen p component positive) for i in range(len(eval)): if sum(evec[i,1:4]) < 0: evec[i,:]=-evec[i,:] # print results, setting numpy to format floats as xx.xxx np.set_printoptions(formatter={'float': '{: 6.3f}'.format}) # print eigenvalues and real parts of eigenvectors, one to a line print(" n eigval eigvec") for n in range(6): print(" %2i %7.3f " % (n,eval[n]), evec[n,:])
--------------------------------------- report of tight-binding model --------------------------------------- k-space dimension = 0 r-space dimension = 3 number of spin components = 1 periodic directions = [] number of orbitals = 6 number of electronic states = 6 lattice vectors: # 0 ===> [ 1.0 , 0.0 , 0.0 ] # 1 ===> [ 0.0 , 1.0 , 0.0 ] # 2 ===> [ 0.0 , 0.0 , 1.0 ] positions of orbitals: # 0 ===> [ 0.0 , 0.0 , 0.0 ] # 1 ===> [ 0.0 , 0.0 , 0.0 ] # 2 ===> [ 0.0 , 0.0 , 0.0 ] # 3 ===> [ 0.0 , 0.0 , 0.0 ] # 4 ===> [ 0.5878 , 0.809 , 0.0 ] # 5 ===> [ 0.5878 , -0.809 , 0.0 ] site energies: # 0 ===> -1.5 # 1 ===> -1.2 # 2 ===> -1.2 # 3 ===> -1.2 # 4 ===> -1.0 # 5 ===> -1.0 hoppings: < 0 | H | 4 > ===> -0.4 + 0.0 i < 0 | H | 5 > ===> -0.4 + 0.0 i < 1 | H | 4 > ===> -0.1763 + 0.0 i < 1 | H | 5 > ===> -0.1763 + 0.0 i < 2 | H | 4 > ===> -0.2427 + 0.0 i < 2 | H | 5 > ===> 0.2427 + 0.0 i hopping distances: | pos( 0 ) - pos( 4 ) | = 1.0 | pos( 0 ) - pos( 5 ) | = 1.0 | pos( 1 ) - pos( 4 ) | = 1.0 | pos( 1 ) - pos( 5 ) | = 1.0 | pos( 2 ) - pos( 4 ) | = 1.0 | pos( 2 ) - pos( 5 ) | = 1.0 n eigval eigvec 0 -1.896 [ 0.802 0.201 0.000 -0.000 0.398 0.398] 1 -1.458 [-0.000 0.000 0.800 0.000 0.424 -0.424] 2 -1.242 [-0.342 0.927 -0.000 -0.000 0.110 0.110] 3 -1.200 [ 0.000 -0.000 -0.000 1.000 -0.000 0.000] 4 -0.742 [ 0.000 -0.000 0.600 -0.000 -0.566 0.566] 5 -0.562 [ 0.490 0.317 -0.000 -0.000 -0.574 -0.574]
#!/usr/bin/env python from __future__ import print_function # python3 style print # ---------------------------------------------------------- # Tight-binding model for p_z states of benzene molecule # ---------------------------------------------------------- from pythtb import * # set up molecular geometry lat=[[1.0,0.0],[0.0,1.0]] # define coordinate frame: 2D Cartesian r=1.2 # distance of atoms from center orb=np.zeros((6,2),dtype=float) # initialize array for orbital positions for i in range(6): # define coordinates of orbitals angle=i*np.pi/3.0 orb[i,:]= [r*np.cos(angle), r*np.sin(angle)] # set site energy and hopping amplitude, respectively ep=-0.4 t=-0.25 # define model my_model=tb_model(0,2,lat,orb) my_model.set_onsite([ep,ep,ep,ep,ep,ep]) my_model.set_hop(t,0,1) my_model.set_hop(t,1,2) my_model.set_hop(t,2,3) my_model.set_hop(t,3,4) my_model.set_hop(t,4,5) my_model.set_hop(t,5,0) # print model my_model.display() # solve model and print results (eval,evec)=my_model.solve_all(eig_vectors=True) # print results, setting numpy to format floats as xx.xxx np.set_printoptions(formatter={'float': '{: 6.3f}'.format}) # Print eigenvalues and real parts of eigenvectors, one to a line print(" n eigval eigvec") for n in range(6): print(" %2i %7.3f " % (n,eval[n]), evec[n,:].real)
--------------------------------------- report of tight-binding model --------------------------------------- k-space dimension = 0 r-space dimension = 2 number of spin components = 1 periodic directions = [] number of orbitals = 6 number of electronic states = 6 lattice vectors: # 0 ===> [ 1.0 , 0.0 ] # 1 ===> [ 0.0 , 1.0 ] positions of orbitals: # 0 ===> [ 1.2 , 0.0 ] # 1 ===> [ 0.6 , 1.0392 ] # 2 ===> [ -0.6 , 1.0392 ] # 3 ===> [ -1.2 , 0.0 ] # 4 ===> [ -0.6 , -1.0392 ] # 5 ===> [ 0.6 , -1.0392 ] site energies: # 0 ===> -0.4 # 1 ===> -0.4 # 2 ===> -0.4 # 3 ===> -0.4 # 4 ===> -0.4 # 5 ===> -0.4 hoppings: < 0 | H | 1 > ===> -0.25 + 0.0 i < 1 | H | 2 > ===> -0.25 + 0.0 i < 2 | H | 3 > ===> -0.25 + 0.0 i < 3 | H | 4 > ===> -0.25 + 0.0 i < 4 | H | 5 > ===> -0.25 + 0.0 i < 5 | H | 0 > ===> -0.25 + 0.0 i hopping distances: | pos( 0 ) - pos( 1 ) | = 1.2 | pos( 1 ) - pos( 2 ) | = 1.2 | pos( 2 ) - pos( 3 ) | = 1.2 | pos( 3 ) - pos( 4 ) | = 1.2 | pos( 4 ) - pos( 5 ) | = 1.2 | pos( 5 ) - pos( 0 ) | = 1.2 n eigval eigvec 0 -0.900 [-0.408 -0.408 -0.408 -0.408 -0.408 -0.408] 1 -0.650 [-0.577 -0.262 0.314 0.577 0.262 -0.314] 2 -0.650 [ 0.030 0.514 0.484 -0.030 -0.514 -0.484] 3 -0.150 [ 0.179 0.386 -0.565 0.179 0.386 -0.565] 4 -0.150 [ 0.549 -0.429 -0.120 0.549 -0.429 -0.120] 5 0.100 [ 0.408 -0.408 0.408 -0.408 0.408 -0.408]
#!/usr/bin/env python from __future__ import print_function # python3 style print # 3D model of Li on bcc lattice, with s orbitals only from pythtb import * # import TB model class import matplotlib.pyplot as plt # define lattice vectors lat=[[-0.5, 0.5, 0.5],[ 0.5,-0.5, 0.5],[ 0.5, 0.5,-0.5]] # define coordinates of orbitals orb=[[0.0,0.0,0.0]] # make 3D model my_model=tb_model(3,3,lat,orb) # set model parameters # lattice parameter implicitly set to a=1 Es= 4.5 # site energy t =-1.4 # hopping parameter # set on-site energy my_model.set_onsite([Es]) # set hoppings along four unique bonds # note that neighboring cell must be specified in lattice coordinates # (the corresponding Cartesian coords are given for reference) my_model.set_hop(t, 0, 0, [1,0,0]) # [-0.5, 0.5, 0.5] cartesian my_model.set_hop(t, 0, 0, [0,1,0]) # [ 0.5,-0.5, 0.5] cartesian my_model.set_hop(t, 0, 0, [0,0,1]) # [ 0.5, 0.5,-0.5] cartesian my_model.set_hop(t, 0, 0, [1,1,1]) # [ 0.5, 0.5, 0.5] cartesian # print tight-binding model my_model.display() # generate k-point path and labels # again, specified in reciprocal lattice coordinates k_P = [0.25,0.25,0.25] # [ 0.5, 0.5, 0.5] cartesian k_Gamma = [ 0.0, 0.0, 0.0] # [ 0.0, 0.0, 0.0] cartesian k_H = [-0.5, 0.5, 0.5] # [ 1.0, 0.0, 0.0] cartesian path=[k_P,k_Gamma,k_H] label=(r'$P$',r'$\Gamma $',r'$H$') (k_vec,k_dist,k_node)=my_model.k_path(path,101) print('---------------------------------------') print('starting calculation') print('---------------------------------------') print('Calculating bands...') # solve for eigenenergies of hamiltonian on # the set of k-points from above evals=my_model.solve_all(k_vec) # plotting of band structure print('Plotting band structure...') # First make a figure object fig, ax = plt.subplots(figsize=(4.,3.)) # specify horizontal axis details ax.set_xlim([0,k_node[-1]]) ax.set_xticks(k_node) ax.set_xticklabels(label) for n in range(len(k_node)): ax.axvline(x=k_node[n], linewidth=0.5, color='k') # plot bands ax.plot(k_dist,evals[0],color='k') # put title ax.set_xlabel("Path in k-space") ax.set_ylabel("Band energy") # make a PDF figure of a plot fig.tight_layout() fig.savefig("li_bsr.pdf") print('Done.\n')
--------------------------------------- report of tight-binding model --------------------------------------- k-space dimension = 3 r-space dimension = 3 number of spin components = 1 periodic directions = [0, 1, 2] number of orbitals = 1 number of electronic states = 1 lattice vectors: # 0 ===> [ -0.5 , 0.5 , 0.5 ] # 1 ===> [ 0.5 , -0.5 , 0.5 ] # 2 ===> [ 0.5 , 0.5 , -0.5 ] positions of orbitals: # 0 ===> [ 0.0 , 0.0 , 0.0 ] site energies: # 0 ===> 4.5 hoppings: < 0 | H | 0 + [ 1 , 0 , 0 ] > ===> -1.4 + 0.0 i < 0 | H | 0 + [ 0 , 1 , 0 ] > ===> -1.4 + 0.0 i < 0 | H | 0 + [ 0 , 0 , 1 ] > ===> -1.4 + 0.0 i < 0 | H | 0 + [ 1 , 1 , 1 ] > ===> -1.4 + 0.0 i hopping distances: | pos( 0 ) - pos( 0 + [ 1 , 0 , 0 ] ) | = 0.866 | pos( 0 ) - pos( 0 + [ 0 , 1 , 0 ] ) | = 0.866 | pos( 0 ) - pos( 0 + [ 0 , 0 , 1 ] ) | = 0.866 | pos( 0 ) - pos( 0 + [ 1 , 1 , 1 ] ) | = 0.866 ----- k_path report begin ---------- real-space lattice vectors [[-0.5 0.5 0.5] [ 0.5 -0.5 0.5] [ 0.5 0.5 -0.5]] k-space metric tensor [[2. 1. 1.] [1. 2. 1.] [1. 1. 2.]] internal coordinates of nodes [[ 0.25 0.25 0.25] [ 0. 0. 0. ] [-0.5 0.5 0.5 ]] reciprocal-space lattice vectors [[-0. 1. 1.] [ 1. 0. 1.] [ 1. 1. 0.]] cartesian coordinates of nodes [[0.5 0.5 0.5] [0. 0. 0. ] [1. 0. 0. ]] list of segments: length = 0.86603 from [0.25 0.25 0.25] to [0. 0. 0.] length = 1.0 from [0. 0. 0.] to [-0.5 0.5 0.5] node distance list: [0. 0.86603 1.86603] node index list: [ 0 46 100] ----- k_path report end ------------ --------------------------------------- starting calculation --------------------------------------- Calculating bands... Plotting band structure... Done.
#!/usr/bin/env python from __future__ import print_function # python3 style print # Chain with alternating site energies and hoppings from pythtb import * import matplotlib.pyplot as plt # define function to set up model for a given paramter set def set_model(t,del_t,Delta): # 1D model with two orbitals per cell lat=[[1.0]] orb=[[0.0],[0.5]] my_model=tb_model(1,1,lat,orb) # alternating site energies (let average be zero) my_model.set_onsite([Delta,-Delta]) # alternating hopping strengths my_model.set_hop(t+del_t, 0, 1, [0]) my_model.set_hop(t-del_t, 1, 0, [1]) return my_model # set reference hopping strength to unity to set energy scale t=-1.0 # set alternation strengths del_t=-0.3 # bond strength alternation Delta= 0.4 # site energy alternation # set up the model my_model=set_model(t,del_t,Delta) # construct the k-path (k_vec,k_dist,k_node)=my_model.k_path('full',121) k_lab=(r'0',r'$\pi$',r'$2\pi$') # solve for eigenvalues at each point on the path evals=my_model.solve_all(k_vec) # set up the figure and specify details fig, ax = plt.subplots(figsize=(4.,3.)) ax.set_xlim([0,k_node[-1]]) ax.set_xticks(k_node) ax.set_xticklabels(k_lab) ax.axvline(x=k_node[1],linewidth=0.5, color='k') ax.set_xlabel("k") ax.set_ylabel("Band energy") # plot first and second bands ax.plot(k_dist,evals[0],color='k') ax.plot(k_dist,evals[1],color='k') # save figure as a PDF fig.tight_layout() fig.savefig("chain_alt.pdf")
Path in 1D BZ defined by nodes at [0. 0.5 1. ]
#!/usr/bin/env python from __future__ import print_function # python3 style print # Simple model of pi manifold of graphene from pythtb import * # import TB model class import matplotlib.pyplot as plt # define lattice vectors lat=[[1.0,0.0],[0.5,np.sqrt(3.0)/2.0]] # define coordinates of orbitals orb=[[1./3.,1./3.],[2./3.,2./3.]] # make 2D tight-binding graphene model my_model=tb_model(2,2,lat,orb) # set model parameters delta=0.0 t=-1.0 my_model.set_onsite([-delta,delta]) my_model.set_hop(t, 0, 1, [ 0, 0]) my_model.set_hop(t, 1, 0, [ 1, 0]) my_model.set_hop(t, 1, 0, [ 0, 1]) # print out model details my_model.display() # list of k-point nodes and their labels defining the path for the # band structure plot path=[[0.,0.],[2./3.,1./3.],[.5,.5],[0.,0.]] label=(r'$\Gamma $',r'$K$', r'$M$', r'$\Gamma $') # construct the k-path nk=121 (k_vec,k_dist,k_node)=my_model.k_path(path,nk) # solve for eigenvalues at each point on the path evals=my_model.solve_all(k_vec) # generate band structure plot fig, ax = plt.subplots(figsize=(4.,3.)) # specify horizontal axis details ax.set_xlim([0,k_node[-1]]) ax.set_ylim([-3.4,3.4]) ax.set_xticks(k_node) ax.set_xticklabels(label) # add vertical lines at node positions for n in range(len(k_node)): ax.axvline(x=k_node[n],linewidth=0.5, color='k') # put titles ax.set_xlabel("Path in k-space") ax.set_ylabel("Band energy") # plot first and second bands ax.plot(k_dist,evals[0],color='k') ax.plot(k_dist,evals[1],color='k') # save figure as a PDF fig.tight_layout() fig.savefig("graphene.pdf")
--------------------------------------- report of tight-binding model --------------------------------------- k-space dimension = 2 r-space dimension = 2 number of spin components = 1 periodic directions = [0, 1] number of orbitals = 2 number of electronic states = 2 lattice vectors: # 0 ===> [ 1.0 , 0.0 ] # 1 ===> [ 0.5 , 0.866 ] positions of orbitals: # 0 ===> [ 0.3333 , 0.3333 ] # 1 ===> [ 0.6667 , 0.6667 ] site energies: # 0 ===> -0.0 # 1 ===> 0.0 hoppings: < 0 | H | 1 + [ 0 , 0 ] > ===> -1.0 + 0.0 i < 1 | H | 0 + [ 1 , 0 ] > ===> -1.0 + 0.0 i < 1 | H | 0 + [ 0 , 1 ] > ===> -1.0 + 0.0 i hopping distances: | pos( 0 ) - pos( 1 + [ 0 , 0 ] ) | = 0.5774 | pos( 1 ) - pos( 0 + [ 1 , 0 ] ) | = 0.5774 | pos( 1 ) - pos( 0 + [ 0 , 1 ] ) | = 0.5774 ----- k_path report begin ---------- real-space lattice vectors [[1. 0. ] [0.5 0.86603]] k-space metric tensor [[ 1.33333 -0.66667] [-0.66667 1.33333]] internal coordinates of nodes [[0. 0. ] [0.66667 0.33333] [0.5 0.5 ] [0. 0. ]] reciprocal-space lattice vectors [[ 1. -0.57735] [ 0. 1.1547 ]] cartesian coordinates of nodes [[0.00000e+00 0.00000e+00] [6.66667e-01 1.56412e-17] [5.00000e-01 2.88675e-01] [0.00000e+00 0.00000e+00]] list of segments: length = 0.66667 from [0. 0.] to [0.66667 0.33333] length = 0.33333 from [0.66667 0.33333] to [0.5 0.5] length = 0.57735 from [0.5 0.5] to [0. 0.] node distance list: [0. 0.66667 1. 1.57735] node index list: [ 0 51 76 120] ----- k_path report end ------------
#!/usr/bin/env python from __future__ import print_function # python3 style print # Tight-binding model for trimer with magnetic flux from pythtb import * import matplotlib.pyplot as plt # ------------------------------------------------------------ # define function to set up model for given (t0,s,phi,alpha) # ------------------------------------------------------------ def set_model(t0,s,phi,alpha): # coordinate space is 2D lat=[[1.0,0.0],[0.0,1.0]] # Finite model with three orbitals forming a triangle at unit # distance from the origin sqr32=np.sqrt(3.)/2. orb=np.zeros((3,2),dtype=float) orb[0,:]=[0.,1.] # orbital at top vertex orb[1,:]=[-sqr32,-0.5] # orbital at lower left orb[2,:]=[ sqr32,-0.5] # orbital at lower right # compute hoppings [t_01, t_12, t_20] # s is distortion amplitude; phi is "pseudorotation angle" tpio3=2.0*np.pi/3.0 t=[ t0+s*np.cos(phi), t0+s*np.cos(phi-tpio3), t0+s*np.cos(phi-2.0*tpio3) ] # alpha is fraction of flux quantum passing through the triangle # magnetic flux correction, attached to third bond t[2]=t[2]*np.exp((1.j)*alpha) # set up model (leave site energies at zero) my_model=tb_model(0,2,lat,orb) my_model.set_hop(t[0],0,1) my_model.set_hop(t[1],1,2) my_model.set_hop(t[2],2,0) return(my_model) # ------------------------------------------------------------ # define function to return eigenvectors for given (t0,s,phi,alpha) # ------------------------------------------------------------ def get_evecs(t0,s,phi,alpha): my_model=set_model(t0,s,phi,alpha) (eval,evec)=my_model.solve_all(eig_vectors=True) return(evec) # evec[bands,orbitals] # ------------------------------------------------------------ # begin regular execution # ------------------------------------------------------------ # for the purposes of this problem we keep t0 and s fixed t0 =-1.0 s =-0.4 ref_model=set_model(t0,s,0.,1.) # reference with phi=alpha=0 ref_model.display() # define two pi twopi=2.*np.pi # ------------------------------------------------------------ # compute Berry phase for phi loop explicitly at alpha=pi/3 # ------------------------------------------------------------ alpha=np.pi/3. n_phi=60 psi=np.zeros((n_phi,3),dtype=complex) # initialize wavefunction array for i in range(n_phi): phi=float(i)*twopi/float(n_phi) # 60 equal intervals psi[i]=get_evecs(t0,s,phi,alpha)[0] # psi[i] is short for psi[i,:] prod=1.+0.j # final [0] picks out band 0 for i in range(1,n_phi): prod=prod*np.vdot(psi[i-1],psi[i]) # <psi_0|psi_1>...<psi_58|psi_59> prod=prod*np.vdot(psi[-1],psi[0]) # include <psi_59|psi_0> berry=-np.angle(prod) # compute Berry phase print("Explcitly computed phi Berry phase at alpha=pi/3 is %6.3f"% berry) # ------------------------------------------------------------ # compute Berry phases for phi loops for several alpha values # using pythtb wf_array() method # ------------------------------------------------------------ alphas=np.linspace(0.,twopi,13) # 0 to 2pi in 12 increments berry_phi=np.zeros_like(alphas) # same shape and type array (empty) print("\nBerry phases for phi loops versus alpha") for j,alpha in enumerate(alphas): # let phi range from 0 to 2pi in equally spaced steps n_phi=61 phit=np.linspace(0.,twopi,n_phi) # set up empty wavefunction array object using pythtb wf_array() # creates 1D array of length [n_phi], with hidden [nbands,norbs] evec_array=wf_array(ref_model,[n_phi]) # run over values of phi and fill the array for k,phi in enumerate(phit[0:-1]): # skip last point of loop evec_array[k]=get_evecs(t0,s,phi,alpha) evec_array[-1]=evec_array[0] # copy first point to last point of loop # now compute and store the Berry phase berry_phi[j]=evec_array.berry_phase([0]) # [0] specifices lowest band print("%3d %7.3f %7.3f"% (j, alpha, berry_phi[j])) # ------------------------------------------------------------ # compute Berry phases for alpha loops for several phi values # using pythtb wf_array() method # ------------------------------------------------------------ phis=np.linspace(0.,twopi,13) # 0 to 2pi in 12 increments berry_alpha=np.zeros_like(phis) print("\nBerry phases for alpha loops versus phi") for j,phi in enumerate(phis): n_alpha=61 alphat=np.linspace(0.,twopi,n_alpha) evec_array=wf_array(ref_model,[n_alpha]) for k,alpha in enumerate(alphat[0:-1]): evec_array[k]=get_evecs(t0,s,phi,alpha) evec_array[-1]=evec_array[0] berry_alpha[j]=evec_array.berry_phase([0]) print("%3d %7.3f %7.3f"% (j, phi, berry_alpha[j])) # ------------------------------------------------------------ # now illustrate use of wf_array() to set up 2D array # recompute Berry phases and compute Berry curvature # ------------------------------------------------------------ n_phi=61 n_alp=61 n_cells=(n_phi-1)*(n_alp-1) phi=np.linspace(0.,twopi,n_phi) alp=np.linspace(0.,twopi,n_alp) evec_array=wf_array(ref_model,[n_phi,n_alp]) # empty 2D wavefunction array for i in range(n_phi): for j in range(n_alp): evec_array[i,j]=get_evecs(t0,s,phi[i],alp[j]) evec_array.impose_loop(0) # copy first to last points in each dimension evec_array.impose_loop(1) bp_of_alp=evec_array.berry_phase([0],0) # compute phi Berry phases vs. alpha bp_of_phi=evec_array.berry_phase([0],1) # compute alpha Berry phases vs. phi # compute 2D array of Berry fluxes for band 0 flux=evec_array.berry_flux([0]) print("\nFlux = %7.3f = 2pi * %7.3f"% (flux, flux/twopi)) curvature=evec_array.berry_flux([0],individual_phases=True)*float(n_cells) # ------------------------------------------------------------ # plots # ------------------------------------------------------------ fig,ax=plt.subplots(1,3,figsize=(10,4),gridspec_kw={'width_ratios':[1,1,2]}) (ax0,ax1,ax2)=ax ax0.set_xlim(0.,1.) ax0.set_ylim(-6.5,6.5) ax0.set_xlabel(r"$\alpha/2\pi$") ax0.set_ylabel(r"Berry phase $\phi(\alpha)$ for $\varphi$ loops") ax0.set_title("Berry phase") for shift in (-twopi,0.,twopi): ax0.plot(alp/twopi,bp_of_alp+shift,color='k') ax0.scatter(alphas/twopi,berry_phi,color='k') ax1.set_xlim(0.,1.) ax1.set_ylim(-6.5,6.5) ax1.set_xlabel(r"$\varphi/2\pi$") ax1.set_ylabel(r"Berry phase $\phi(\varphi)$ for $\alpha$ loops") ax1.set_title("Berry phase") for shift in (-twopi,0.,twopi): ax1.plot(phi/twopi,bp_of_phi+shift,color='k') ax1.scatter(phis/twopi,berry_alpha,color='k') X=alp[0:-1]/twopi + 0.5/float(n_alp-1) Y=phi[0:-1]/twopi + 0.5/float(n_phi-1) cs=ax2.contour(X,Y,curvature,colors='k') ax2.clabel(cs, inline=1, fontsize=10) ax2.set_title("Berry curvature") ax2.set_xlabel(r"$\alpha/2\pi$") ax2.set_xlim(0.,1.) ax2.set_ylim(0.,1.) ax2.set_ylabel(r"$\varphi/2\pi$") fig.tight_layout() fig.savefig("trimer.pdf")
--------------------------------------- report of tight-binding model --------------------------------------- k-space dimension = 0 r-space dimension = 2 number of spin components = 1 periodic directions = [] number of orbitals = 3 number of electronic states = 3 lattice vectors: # 0 ===> [ 1.0 , 0.0 ] # 1 ===> [ 0.0 , 1.0 ] positions of orbitals: # 0 ===> [ 0.0 , 1.0 ] # 1 ===> [ -0.866 , -0.5 ] # 2 ===> [ 0.866 , -0.5 ] site energies: # 0 ===> 0.0 # 1 ===> 0.0 # 2 ===> 0.0 hoppings: < 0 | H | 1 > ===> -1.4 + 0.0 i < 1 | H | 2 > ===> -0.8 + 0.0 i < 2 | H | 0 > ===> -0.4322 - 0.6732 i hopping distances: | pos( 0 ) - pos( 1 ) | = 1.7321 | pos( 1 ) - pos( 2 ) | = 1.7321 | pos( 2 ) - pos( 0 ) | = 1.7321 Explcitly computed phi Berry phase at alpha=pi/3 is -0.116 Berry phases for phi loops versus alpha 0 0.000 -0.000 1 0.524 -0.049 2 1.047 -0.116 3 1.571 -0.237 4 2.094 -0.509 5 2.618 -1.263 6 3.142 -3.142 7 3.665 1.263 8 4.189 0.509 9 4.712 0.237 10 5.236 0.116 11 5.760 0.049 12 6.283 0.000 Berry phases for alpha loops versus phi 0 0.000 -0.518 1 0.524 -0.185 2 1.047 -0.000 3 1.571 0.185 4 2.094 0.518 5 2.618 1.039 6 3.142 1.671 7 3.665 2.374 8 4.189 3.142 9 4.712 -2.374 10 5.236 -1.671 11 5.760 -1.039 12 6.283 -0.518 Flux = 6.283 = 2pi * 1.000
#!/usr/bin/env python from __future__ import print_function # python3 style print # Chain with alternating site energies and hoppings from pythtb import * import matplotlib.pyplot as plt # define function to set up model for a given parameter set def set_model(t,del_t,Delta): lat=[[1.0]] orb=[[0.0],[0.5]] my_model=tb_model(1,1,lat,orb) my_model.set_onsite([Delta,-Delta]) my_model.set_hop(t+del_t, 0, 1, [0]) my_model.set_hop(t-del_t, 1, 0, [1]) return my_model # set parameters of model t=-1.0 # average hopping del_t=-0.3 # bond strength alternation Delta= 0.4 # site energy alternation my_model=set_model(t,del_t,Delta) my_model.display() # ----------------------------------- # explicit calculation of Berry phase # ----------------------------------- # set up and solve the model on a discretized k mesh nk=61 # 60 equal intervals around the unit circle (k_vec,k_dist,k_node)=my_model.k_path('full',nk,report=False) (eval,evec)=my_model.solve_all(k_vec,eig_vectors=True) evec=evec[0] # pick band=0 from evec[band,kpoint,orbital] # now just evec[kpoint,orbital] # k-points 0 and 60 refer to the same point on the unit circle # so we will work only with evec[0],...,evec[59] # compute Berry phase of lowest band prod=1.+0.j for i in range(1,nk-1): # <evec_0|evec_1>...<evec_58|evec_59> prod*=np.vdot(evec[i-1],evec[i]) # a*=b means a=a*b # now compute the phase factors needed for last inner product orb=np.array([0.0,0.5]) # relative coordinates of orbitals phase=np.exp((-2.j)*np.pi*orb) # construct phase factors evec_last=phase*evec[0] # evec[60] constructed from evec[0] prod*=np.vdot(evec[-2],evec_last) # include <evec_59|evec_last> print("Berry phase is %7.3f"% (-np.angle(prod))) # ----------------------------------- # Berry phase via the wf_array method # ----------------------------------- evec_array=wf_array(my_model,[61]) # set array dimension evec_array.solve_on_grid([0.]) # fill with eigensolutions berry_phase=evec_array.berry_phase([0]) # Berry phase of bottom band print("Berry phase is %7.3f"% berry_phase)
--------------------------------------- report of tight-binding model --------------------------------------- k-space dimension = 1 r-space dimension = 1 number of spin components = 1 periodic directions = [0] number of orbitals = 2 number of electronic states = 2 lattice vectors: # 0 ===> [ 1.0 ] positions of orbitals: # 0 ===> [ 0.0 ] # 1 ===> [ 0.5 ] site energies: # 0 ===> 0.4 # 1 ===> -0.4 hoppings: < 0 | H | 1 + [ 0 ] > ===> -1.3 + 0.0 i < 1 | H | 0 + [ 1 ] > ===> -0.7 + 0.0 i hopping distances: | pos( 0 ) - pos( 1 + [ 0 ] ) | = 0.5 | pos( 1 ) - pos( 0 + [ 1 ] ) | = 0.5 Berry phase is 2.217 Berry phase is 2.217
#!/usr/bin/env python from __future__ import print_function # python3 style print # Chain with three sites per cell from pythtb import * import matplotlib.pyplot as plt # define function to construct model def set_model(t,delta,lmbd): lat=[[1.0]] orb=[[0.0],[1.0/3.0],[2.0/3.0]] model=tb_model(1,1,lat,orb) model.set_hop(t, 0, 1, [0]) model.set_hop(t, 1, 2, [0]) model.set_hop(t, 2, 0, [1]) onsite_0=delta*(-1.0)*np.cos(2.0*np.pi*(lmbd-0.0/3.0)) onsite_1=delta*(-1.0)*np.cos(2.0*np.pi*(lmbd-1.0/3.0)) onsite_2=delta*(-1.0)*np.cos(2.0*np.pi*(lmbd-2.0/3.0)) model.set_onsite([onsite_0,onsite_1,onsite_2]) return(model) # construct the model t=-1.3 delta=2.0 lmbd=0.3 my_model=set_model(t,delta,lmbd) # compute the results on a uniform k-point grid evec_array=wf_array(my_model,[21]) # set array dimension evec_array.solve_on_grid([0.]) # fill with eigensolutions # obtain Berry phases and convert to Wannier center positions # constrained to the interval [0.,1.] wfc0=evec_array.berry_phase([0])/(2.*np.pi)%1. wfc1=evec_array.berry_phase([1])/(2.*np.pi)%1. x=evec_array.berry_phase([0,1],berry_evals=True)/(2.*np.pi)%1. gwfc0=x[0] gwfc1=x[1] print ("Wannier centers of bands 0 and 1:") print((" Individual"+" Wannier centers: "+2*"%7.4f") % (wfc0,wfc1)) print((" Multiband "+" Wannier centers: "+2*"%7.4f") % (gwfc1,gwfc0)) print() # construct and solve finite model by cutting 10 cells from infinite chain finite_model=my_model.cut_piece(10,0) (feval,fevec)=finite_model.solve_all(eig_vectors=True) print ("Finite-chain eigenenergies associated with") print(("Band 0:"+10*"%6.2f")% tuple(feval[0:10])) print(("Band 1:"+10*"%6.2f")% tuple(feval[10:20])) # find maxloc Wannier centers in each band subspace xbar0=finite_model.position_hwf(fevec[0:10,],0) xbar1=finite_model.position_hwf(fevec[10:20,],0) xbarb=finite_model.position_hwf(fevec[0:20,],0) print ("\nFinite-chain Wannier centers associated with band 0:") print((10*"%7.4f")% tuple(xbar0)) x=10*(wfc0,) print(("Compare with bulk:\n"+10*"%7.4f")% x) print ("\nFinite-chain Wannier centers associated with band 1:") print((10*"%7.4f")% tuple(xbar1)) x=10*(wfc1,) print(("Compare with bulk:\n"+10*"%7.4f")% x) print ("\nFirst 10 finite-chain Wannier centers associated with bands 0 and 1:") print((10*"%7.4f")% tuple(xbarb[0:10])) x=5*(gwfc0,gwfc1) print(("Compare with bulk:\n"+10*"%7.4f")% x)
Wannier centers of bands 0 and 1: Individual Wannier centers: 0.3188 0.9092 Multiband Wannier centers: 0.3419 0.8860 Finite-chain eigenenergies associated with Band 0: -3.15 -3.12 -3.08 -3.02 -2.96 -2.88 -2.81 -2.75 -2.69 -2.66 Band 1: -0.32 -0.25 -0.14 0.01 0.17 0.34 0.51 0.66 0.77 1.16 Finite-chain Wannier centers associated with band 0: 0.3329 1.3193 2.3188 3.3188 4.3188 5.3188 6.3188 7.3188 8.3184 9.3073 Compare with bulk: 0.3188 0.3188 0.3188 0.3188 0.3188 0.3188 0.3188 0.3188 0.3188 0.3188 Finite-chain Wannier centers associated with band 1: 0.0697 0.9225 1.9106 2.9093 3.9092 4.9092 5.9093 6.9100 7.9155 8.9548 Compare with bulk: 0.9092 0.9092 0.9092 0.9092 0.9092 0.9092 0.9092 0.9092 0.9092 0.9092 First 10 finite-chain Wannier centers associated with bands 0 and 1: 0.0195 0.3627 0.8962 1.3436 1.8871 2.3421 2.8861 3.3419 3.8860 4.3419 Compare with bulk: 0.8860 0.3419 0.8860 0.3419 0.8860 0.3419 0.8860 0.3419 0.8860 0.3419
#!/usr/bin/env python from __future__ import print_function # python3 style print # Chain with three sites per cell - cyclic variation from pythtb import * import matplotlib.pyplot as plt # define function to construct model def set_model(t,delta,lmbd): lat=[[1.0]] orb=[[0.0],[1.0/3.0],[2.0/3.0]] model=tb_model(1,1,lat,orb) model.set_hop(t, 0, 1, [0]) model.set_hop(t, 1, 2, [0]) model.set_hop(t, 2, 0, [1]) onsite_0=delta*(-1.0)*np.cos(lmbd) onsite_1=delta*(-1.0)*np.cos(lmbd-2.0*np.pi/3.0) onsite_2=delta*(-1.0)*np.cos(lmbd-4.0*np.pi/3.0) model.set_onsite([onsite_0,onsite_1,onsite_2]) return(model) def get_xbar(band,model): evec_array=wf_array(model,[21]) # set array dimension evec_array.solve_on_grid([0.]) # fill with eigensolutions wfc=evec_array.berry_phase([band])/(2.*np.pi) # Wannier centers return(wfc) # set fixed parameters t=-1.3 delta=2.0 # obtain results for an array of lambda values lmbd=np.linspace(0.,2.*np.pi,61) xbar=np.zeros_like(lmbd) for j,lam in enumerate(lmbd): my_model=set_model(t,delta,lam) xbar[j]=get_xbar(0,my_model) # Wannier center of bottom band # enforce smooth evolution of xbar for j in range(1,61): delt=xbar[j]-xbar[j-1] delt=-0.5+(delt+0.5)%1. # add integer to enforce |delt| < 0.5 xbar[j]=xbar[j-1]+delt # set up the figure fig, ax = plt.subplots(figsize=(5.,3.)) ax.set_xlim([0.,2.*np.pi]) ax.set_ylim([-0.6,1.1]) ax.set_xlabel(r"Parameter $\lambda$") ax.set_ylabel(r"Wannier center position") xlab=[r"0",r"$\pi/3$",r"$2\pi/3$",r"$\pi$",r"$4\pi/3$",r"$5\pi/3$",r"$2\pi$"] ax.set_xticks(np.linspace(0.,2.*np.pi,num=7)) ax.set_xticklabels(xlab) ax.plot(lmbd,xbar,'k') # plot Wannier center and some periodic images ax.plot(lmbd,xbar-1.,'k') ax.plot(lmbd,xbar+1.,'k') ax.axhline(y=1.,color='k',linestyle='dashed') # horizontal reference lines ax.axhline(y=0.,color='k',linestyle='dashed') fig.tight_layout() fig.savefig("chain_3_cycle.pdf")
#!/usr/bin/env python from __future__ import print_function # python3 style print # Chain with alternating site energies and hoppings # Study surface properties of finite chain from pythtb import * import matplotlib as mpl import matplotlib.pyplot as plt # to set up model for given surface energy shift and lambda def set_model(n_cell,en_shift,lmbd): # set parameters of model t=-1.0 # average hopping Delta=-0.4*np.cos(lmbd) # site energy alternation del_t=-0.3*np.sin(lmbd) # bond strength alternation # construct bulk model lat=[[1.0]] orb=[[0.0],[0.5]] bulk_model=tb_model(1,1,lat,orb) bulk_model.set_onsite([Delta,-Delta]) bulk_model.set_hop(t+del_t, 0, 1, [0]) bulk_model.set_hop(t-del_t, 1, 0, [1]) # cut chain of length n_cell and shift energy on last site finite_model=bulk_model.cut_piece(n_cell,0) finite_model.set_onsite(en_shift,ind_i=2*n_cell-1,mode='add') return finite_model # set Fermi energy and number of cells Ef=0.18 n_cell=20 n_orb=2*n_cell # set number of parameter values to run over n_param=101 # initialize arrays params=np.linspace(0.,1.,n_param) eig_sav=np.zeros((n_orb,n_param),dtype=float) xbar_sav=np.zeros((n_orb,n_param),dtype=float) nocc_sav=np.zeros((n_param),dtype=int) surf_sav=np.zeros((n_param),dtype=float) count=np.zeros((n_orb),dtype=float) # initialize plots mpl.rc('font',size=10) # set global font size fig,ax=plt.subplots(3,2,figsize=(7.,6.), gridspec_kw={'height_ratios':[2,1,1]},sharex="col") # loop over two cases: vary surface site energy, or vary lambda for mycase in ['surface energy','lambda']: if mycase == 'surface energy': (ax0,ax1,ax2)=ax[:,0] # axes for plots in left panels ax0.text(-0.30,0.90,'(a)',size=22.,transform=ax0.transAxes) lmbd=0.15*np.pi*np.ones((n_param),dtype=float) en_shift=-3.0+6.0*params abscissa=en_shift elif mycase == 'lambda': (ax0,ax1,ax2)=ax[:,1] # axes for plots in right panels ax0.text(-0.30,0.90,'(b)',size=22.,transform=ax0.transAxes) lmbd=params*2.*np.pi en_shift=0.2*np.ones((n_param),dtype=float) abscissa=params # loop over parameter values for j in range(n_param): # set up and solve model; store eigenvalues my_model=set_model(n_cell,en_shift[j],lmbd[j]) (eval,evec)=my_model.solve_all(eig_vectors=True) # find occupied states nocc=(eval<Ef).sum() ovec=evec[0:nocc,:] # get Wannier centers xbar_sav[0:nocc,j]=my_model.position_hwf(ovec,0) # get electron count on each site # convert to charge (2 for spin; unit nuclear charge per site) # compute surface charge down to depth of 1/3 of chain for i in range(n_orb): count[i]=np.real(np.vdot(evec[:nocc,i],evec[:nocc,i])) charge=-2.*count+1. n_cut=int(0.67*n_orb) surf_sav[j]=0.5*charge[n_cut-1]+charge[n_cut:].sum() # save information for plots nocc_sav[j]=nocc eig_sav[:,j]=eval ax0.set_xlim(0.,1.) ax0.set_ylim(-2.8,2.8) ax0.set_ylabel(r"Band energy") ax0.axhline(y=Ef,color='k',linewidth=0.5) for n in range(n_orb): ax0.plot(abscissa,eig_sav[n,:],color='k') ax1.set_xlim(0.,1.) ax1.set_ylim(n_cell-4.6,n_cell+0.4) ax1.set_yticks(np.linspace(n_cell-4,n_cell,5)) #ax1.set_ylabel(r"$\bar{x}$") ax1.set_ylabel(r"Wannier centers") for j in range(n_param): nocc=nocc_sav[j] ax1.scatter([abscissa[j]]*nocc,xbar_sav[:nocc,j],color='k', s=3.,marker='o',edgecolors='none') ax2.set_ylim(-2.2,2.2) ax2.set_yticks([-2.,-1.,0.,1.,2.]) ax2.set_ylabel(r"Surface charge") if mycase == 'surface energy': ax2.set_xlabel(r"Surface site energy") elif mycase == 'lambda': ax2.set_xlabel(r"$\lambda/2\pi$") ax2.set_xlim(abscissa[0],abscissa[-1]) ax2.scatter(abscissa,surf_sav,color='k',s=3.,marker='o',edgecolors='none') # vertical lines denote surface state at right end crossing the Fermi energy for j in range(1,n_param): if nocc_sav[j] != nocc_sav[j-1]: n=min(nocc_sav[j],nocc_sav[j-1]) frac=(Ef-eig_sav[n,j-1])/(eig_sav[n,j]-eig_sav[n,j-1]) a_jump=(1-frac)*abscissa[j-1]+frac*abscissa[j] if mycase == 'surface energy' or nocc_sav[j] < nocc_sav[j-1]: ax0.axvline(x=a_jump,color='k',linewidth=0.5) ax1.axvline(x=a_jump,color='k',linewidth=0.5) ax2.axvline(x=a_jump,color='k',linewidth=0.5) fig.tight_layout() plt.subplots_adjust(left=0.12,wspace=0.4) fig.savefig("chain_alt_surf.pdf")
#!/usr/bin/env python from __future__ import print_function # python3 style print # Band structure of Haldane model from pythtb import * # import TB model class import matplotlib.pyplot as plt # set model parameters delta=0.7 # site energy shift t=-1.0 # real first-neighbor hopping t2=0.15 # imaginary second-neighbor hopping def set_model(delta,t,t2): lat=[[1.0,0.0],[0.5,np.sqrt(3.0)/2.0]] orb=[[1./3.,1./3.],[2./3.,2./3.]] model=tb_model(2,2,lat,orb) model.set_onsite([-delta,delta]) for lvec in ([ 0, 0], [-1, 0], [ 0,-1]): model.set_hop(t, 0, 1, lvec) for lvec in ([ 1, 0], [-1, 1], [ 0,-1]): model.set_hop(t2*1.j, 0, 0, lvec) for lvec in ([-1, 0], [ 1,-1], [ 0, 1]): model.set_hop(t2*1.j, 1, 1, lvec) return model # construct path in k-space and solve model path=[[0.,0.],[2./3.,1./3.],[.5,.5],[1./3.,2./3.], [0.,0.]] label=(r'$\Gamma $',r'$K$', r'$M$', r'$K^\prime$', r'$\Gamma $') (k_vec,k_dist,k_node)=set_model(delta,t,t2).k_path(path,101) # set up band structure plots fig, ax = plt.subplots(2,2,figsize=(8.,6.),sharex=True,sharey=True) ax=ax.flatten() t2_values=[0.,-0.06,-0.1347,-0.24] labs=['(a)','(b)','(c)','(d)'] for j in range(4): my_model=set_model(delta,t,t2_values[j]) evals=my_model.solve_all(k_vec) ax[j].set_xlim([0,k_node[-1]]) ax[j].set_xticks(k_node) ax[j].set_xticklabels(label) for n in range(len(k_node)): ax[j].axvline(x=k_node[n],linewidth=0.5, color='k') ax[j].set_ylabel("Energy") ax[j].set_ylim(-3.8,3.8) for n in range(2): ax[j].plot(k_dist,evals[n],color='k') # filled or open dots at K and K' following band inversion for m in [1,3]: kk=k_node[m] (en,ev)=my_model.solve_one(path[m],eig_vectors=True) if np.abs(ev[0,0]) > np.abs(ev[0,1]): #ev[band,orb] en=[en[1],en[0]] ax[j].scatter(kk,en[0],s=40.,marker='o',edgecolors='k',facecolors='w',zorder=4) ax[j].scatter(kk,en[1],s=40.,marker='o',color='k',zorder=6) ax[j].text(0.20,3.1,labs[j],size=18.) # save figure as a PDF fig.tight_layout() fig.savefig("haldane_bsr.pdf")
----- k_path report begin ---------- real-space lattice vectors [[1. 0. ] [0.5 0.86603]] k-space metric tensor [[ 1.33333 -0.66667] [-0.66667 1.33333]] internal coordinates of nodes [[0. 0. ] [0.66667 0.33333] [0.5 0.5 ] [0.33333 0.66667] [0. 0. ]] reciprocal-space lattice vectors [[ 1. -0.57735] [ 0. 1.1547 ]] cartesian coordinates of nodes [[0.00000e+00 0.00000e+00] [6.66667e-01 1.56412e-17] [5.00000e-01 2.88675e-01] [3.33333e-01 5.77350e-01] [0.00000e+00 0.00000e+00]] list of segments: length = 0.66667 from [0. 0.] to [0.66667 0.33333] length = 0.33333 from [0.66667 0.33333] to [0.5 0.5] length = 0.33333 from [0.5 0.5] to [0.33333 0.66667] length = 0.66667 from [0.33333 0.66667] to [0. 0.] node distance list: [0. 0.66667 1. 1.33333 2. ] node index list: [ 0 33 50 67 100] ----- k_path report end ------------
#!/usr/bin/env python from __future__ import print_function # python3 style print # Berry curvature of Haldane model from pythtb import * # import TB model class import matplotlib.pyplot as plt # define setup of Haldane model def set_model(delta,t,t2): lat=[[1.0,0.0],[0.5,np.sqrt(3.0)/2.0]] orb=[[1./3.,1./3.],[2./3.,2./3.]] model=tb_model(2,2,lat,orb) model.set_onsite([-delta,delta]) for lvec in ([ 0, 0], [-1, 0], [ 0,-1]): model.set_hop(t, 0, 1, lvec) for lvec in ([ 1, 0], [-1, 1], [ 0,-1]): model.set_hop(t2*1.j, 0, 0, lvec) for lvec in ([-1, 0], [ 1,-1], [ 0, 1]): model.set_hop(t2*1.j, 1, 1, lvec) return model # miscellaneous setup delta=0.7 # site energy shift t=-1.0 # real first-neighbor hopping nk=61 dk=2.*np.pi/(nk-1) k0=(np.arange(nk-1)+0.5)/(nk-1) kx=np.zeros((nk-1,nk-1),dtype=float) ky=np.zeros((nk-1,nk-1),dtype=float) sq3o2=np.sqrt(3.)/2. for i in range(nk-1): for j in range(nk-1): kx[i,j]=sq3o2*k0[i] ky[i,j]= -0.5*k0[i]+k0[j] fig,ax=plt.subplots(1,3,figsize=(11,4)) labs=['(a)','(b)','(c)'] # compute Berry curvature and Chern number for three values of t2 for j,t2 in enumerate([0.,-0.06,-0.24]): my_model=set_model(delta,t,t2) my_array=wf_array(my_model,[nk,nk]) my_array.solve_on_grid([0.,0.]) bcurv=my_array.berry_flux([0],individual_phases=True)/(dk*dk) chern=my_array.berry_flux([0])/(2.*np.pi) print('Chern number =',"%8.5f"%chern) # make contour plot of Berry curvature pos_lvls= 0.02*np.power(2.,np.linspace(0,8,9)) neg_lvls=-0.02*np.power(2.,np.linspace(8,0,9)) ax[j].contour(kx,ky,bcurv,levels=pos_lvls,colors='k') ax[j].contour(kx,ky,bcurv,levels=neg_lvls,colors='k',linewidths=1.4) # remove rectangular box and draw parallelogram, etc. ax[j].xaxis.set_visible(False) ax[j].yaxis.set_visible(False) for loc in ["top","bottom","left","right"]: ax[j].spines[loc].set_visible(False) ax[j].set(aspect=1.) ax[j].plot([0,sq3o2,sq3o2,0,0],[0,-0.5,0.5,1,0],color='k',linewidth=1.4) ax[j].set_xlim(-0.05,sq3o2+0.05) ax[j].text(-.35,0.88,labs[j],size=24.) fig.savefig("haldane_bcurv.pdf")
Chern number = -0.00000 Chern number = 0.00000 Chern number = 1.00000
#!/usr/bin/env python from __future__ import print_function # python3 style print # Band structure of Haldane model from pythtb import * # import TB model class import matplotlib.pyplot as plt # define setup of Haldane model def set_model(delta,t,t2): lat=[[1.0,0.0],[0.5,np.sqrt(3.0)/2.0]] orb=[[1./3.,1./3.],[2./3.,2./3.]] model=tb_model(2,2,lat,orb) model.set_onsite([-delta,delta]) for lvec in ([ 0, 0], [-1, 0], [ 0,-1]): model.set_hop(t, 0, 1, lvec) for lvec in ([ 1, 0], [-1, 1], [ 0,-1]): model.set_hop(t2*1.j, 0, 0, lvec) for lvec in ([-1, 0], [ 1,-1], [ 0, 1]): model.set_hop(t2*1.j, 1, 1, lvec) return model # set model parameters and construct bulk model delta=0.7 # site energy shift t=-1.0 # real first-neighbor hopping nk=51 # For the purposes of plot labels: # Real space is (r1,r2) in reduced coordinates # Reciprocal space is (k1,k2) in reduced coordinates # Below, following Python, these are (r0,r1) and (k0,k1) # set up figures fig,ax=plt.subplots(2,2,figsize=(7,6)) # run over two choices of t2 for j2,t2 in enumerate([-0.06,-0.24]): # solve bulk model on grid and get hybrid Wannier centers along r1 # as a function of k0 my_model=set_model(delta,t,t2) my_array=wf_array(my_model,[nk,nk]) my_array.solve_on_grid([0.,0.]) rbar_1 = my_array.berry_phase([0],1,contin=True)/(2.*np.pi) # set up and solve ribbon model that is finite along direction 1 width=20 nkr=81 ribbon_model=my_model.cut_piece(width,fin_dir=1,glue_edgs=False) (k_vec,k_dist,k_node)=ribbon_model.k_path('full',nkr,report=False) (rib_eval,rib_evec)=ribbon_model.solve_all(k_vec,eig_vectors=True) nbands=rib_eval.shape[0] (ax0,ax1)=ax[j2,:] # hybrid Wannier center flow k0=np.linspace(0.,1.,nk) ax0.set_xlim(0.,1.) ax0.set_ylim(-1.3,1.3) ax0.set_xlabel(r"$\kappa_1/2\pi$") ax0.set_ylabel(r"HWF centers") for shift in (-2.,-1.,0.,1.): ax0.plot(k0,rbar_1+shift,color='k') # edge band structure k0=np.linspace(0.,1.,nkr) ax1.set_xlim(0.,1.) ax1.set_ylim(-2.5,2.5) ax1.set_xlabel(r"$\kappa_1/2\pi$") ax1.set_ylabel(r"Edge band structure") for (i,kv) in enumerate(k0): # find expectation value <r1> at i'th k-point along direction k0 pos_exp=ribbon_model.position_expectation(rib_evec[:,i],dir=1) # assign weight in [0,1] to be 1 except for edge states near bottom weight=3.0*pos_exp/width for j in range(nbands): weight[j]=min(weight[j],1.) # scatterplot with symbol size proportional to assigned weight s=ax1.scatter([k_vec[i]]*nbands, rib_eval[:,i], s=0.6+2.5*weight, c='k', marker='o', edgecolors='none') # save figure as a PDF aa=ax.flatten() for i,lab in enumerate(['(a)','(b)','(c)','(d)']): aa[i].text(-0.45,0.92,lab,size=18.,transform=aa[i].transAxes) fig.tight_layout() plt.subplots_adjust(left=0.15,wspace=0.6) fig.savefig("haldane_topo.pdf")
#!/usr/bin/env python from __future__ import print_function # python3 style print # Entanglement spectrum of Haldane model from pythtb import * # import TB model class import matplotlib.pyplot as plt # define setup of Haldane model def set_model(delta,t,t2): lat=[[1.0,0.0],[0.5,np.sqrt(3.0)/2.0]] orb=[[1./3.,1./3.],[2./3.,2./3.]] model=tb_model(2,2,lat,orb) model.set_onsite([-delta,delta]) for lvec in ([ 0, 0], [-1, 0], [ 0,-1]): model.set_hop(t, 0, 1, lvec) for lvec in ([ 1, 0], [-1, 1], [ 0,-1]): model.set_hop(t2*1.j, 0, 0, lvec) for lvec in ([-1, 0], [ 1,-1], [ 0, 1]): model.set_hop(t2*1.j, 1, 1, lvec) return model # set model parameters and construct bulk model delta=0.7 # site energy shift t=-1.0 # real first-neighbor hopping # set up figures fig,ax=plt.subplots(1,2,figsize=(7,3)) # run over two choices of t2 for j2,t2 in enumerate([-0.10,-0.24]): my_model=set_model(delta,t,t2) # set up and solve ribbon model that is finite along direction 1 width=20 nkr=81 ribbon_model=my_model.cut_piece(width,fin_dir=1,glue_edgs=False) (k_vec,k_dist,k_node)=ribbon_model.k_path('full',nkr,report=False) (rib_eval,rib_evec)=ribbon_model.solve_all(k_vec,eig_vectors=True) nbands=rib_eval.shape[0] ax1=ax[j2] # entanglement spectrum k0=np.linspace(0.,1.,nkr) ax1.set_xlim(0.,1.) ax1.set_ylim(0.,1) ax1.set_xlabel(r"$\kappa_1/2\pi$") ax1.set_ylabel(r"eigenvalues of $\rho_A$") (nband,nk,norb)=rib_evec.shape ncut=norb//2 nocc=nband//2 # the '//' is needed in python3 so that int is returned for (i,kv) in enumerate(k0): # construct reduced density matrix for half of the chain dens_mat=np.zeros((ncut,ncut),dtype=complex) for nb in range(nocc): for j1 in range(ncut): for j2 in range(ncut): dens_mat[j1,j2] += np.conj(rib_evec[nb,i,j1])*rib_evec[nb,i,j2] # diagonalize spect=np.real(np.linalg.eigvals(dens_mat)) # scatterplot s=ax1.scatter([k_vec[i]]*nocc, spect, s=4, c='k', marker='o', edgecolors='none') # save figure as a PDF aa=ax.flatten() for i,lab in enumerate(['(a)','(b)']): aa[i].text(-0.45,0.92,lab,size=18.,transform=aa[i].transAxes) fig.tight_layout() plt.subplots_adjust(left=0.15,wspace=0.6) fig.savefig("haldane_entang.pdf")
#!/usr/bin/env python from __future__ import print_function # python3 style print from pythtb import * # import TB model class import matplotlib.pyplot as plt # set geometry lat=[[1.0,0.0],[0.0,1.0]] orb=[[0.0,0.0],[0.5,0.5]] my_model=tb_model(2,2,lat,orb) # set model Delta = 5.0 t_0 = 1.0 tprime = 0.4 my_model.set_onsite([-Delta,Delta]) my_model.set_hop(-t_0, 0, 0, [ 1, 0]) my_model.set_hop(-t_0, 0, 0, [ 0, 1]) my_model.set_hop( t_0, 1, 1, [ 1, 0]) my_model.set_hop( t_0, 1, 1, [ 0, 1]) my_model.set_hop( tprime , 1, 0, [ 1, 1]) my_model.set_hop( tprime*1j, 1, 0, [ 0, 1]) my_model.set_hop(-tprime , 1, 0, [ 0, 0]) my_model.set_hop(-tprime*1j, 1, 0, [ 1, 0]) my_model.display() # generate k-point path and labels and solve Hamiltonian path=[[0.0,0.0],[0.0,0.5],[0.5,0.5],[0.0,0.0]] k_lab=(r'$\Gamma $',r'$X$', r'$M$', r'$\Gamma $') (k_vec,k_dist,k_node)=my_model.k_path(path,121) evals=my_model.solve_all(k_vec) # plot band structure fig, ax = plt.subplots(figsize=(4.,3.)) ax.set_xlim([0,k_node[-1]]) ax.set_xticks(k_node) ax.set_xticklabels(k_lab) for n in range(len(k_node)): ax.axvline(x=k_node[n], linewidth=0.5, color='k') ax.plot(k_dist,evals[0],color='k') ax.plot(k_dist,evals[1],color='k') fig.savefig("checkerboard_bsr.pdf")
--------------------------------------- report of tight-binding model --------------------------------------- k-space dimension = 2 r-space dimension = 2 number of spin components = 1 periodic directions = [0, 1] number of orbitals = 2 number of electronic states = 2 lattice vectors: # 0 ===> [ 1.0 , 0.0 ] # 1 ===> [ 0.0 , 1.0 ] positions of orbitals: # 0 ===> [ 0.0 , 0.0 ] # 1 ===> [ 0.5 , 0.5 ] site energies: # 0 ===> -5.0 # 1 ===> 5.0 hoppings: < 0 | H | 0 + [ 1 , 0 ] > ===> -1.0 + 0.0 i < 0 | H | 0 + [ 0 , 1 ] > ===> -1.0 + 0.0 i < 1 | H | 1 + [ 1 , 0 ] > ===> 1.0 + 0.0 i < 1 | H | 1 + [ 0 , 1 ] > ===> 1.0 + 0.0 i < 1 | H | 0 + [ 1 , 1 ] > ===> 0.4 + 0.0 i < 1 | H | 0 + [ 0 , 1 ] > ===> 0.0 + 0.4 i < 1 | H | 0 + [ 0 , 0 ] > ===> -0.4 + 0.0 i < 1 | H | 0 + [ 1 , 0 ] > ===> -0.0 - 0.4 i hopping distances: | pos( 0 ) - pos( 0 + [ 1 , 0 ] ) | = 1.0 | pos( 0 ) - pos( 0 + [ 0 , 1 ] ) | = 1.0 | pos( 1 ) - pos( 1 + [ 1 , 0 ] ) | = 1.0 | pos( 1 ) - pos( 1 + [ 0 , 1 ] ) | = 1.0 | pos( 1 ) - pos( 0 + [ 1 , 1 ] ) | = 0.7071 | pos( 1 ) - pos( 0 + [ 0 , 1 ] ) | = 0.7071 | pos( 1 ) - pos( 0 + [ 0 , 0 ] ) | = 0.7071 | pos( 1 ) - pos( 0 + [ 1 , 0 ] ) | = 0.7071 ----- k_path report begin ---------- real-space lattice vectors [[1. 0.] [0. 1.]] k-space metric tensor [[1. 0.] [0. 1.]] internal coordinates of nodes [[0. 0. ] [0. 0.5] [0.5 0.5] [0. 0. ]] reciprocal-space lattice vectors [[1. 0.] [0. 1.]] cartesian coordinates of nodes [[0. 0. ] [0. 0.5] [0.5 0.5] [0. 0. ]] list of segments: length = 0.5 from [0. 0.] to [0. 0.5] length = 0.5 from [0. 0.5] to [0.5 0.5] length = 0.70711 from [0.5 0.5] to [0. 0.] node distance list: [0. 0.5 1. 1.70711] node index list: [ 0 35 70 120] ----- k_path report end ------------
#!/usr/bin/env python from __future__ import print_function # python3 style print # Tight-binding 2D Kane-Mele model # C.L. Kane and E.J. Mele, PRL 95, 146802 (2005) from pythtb import * # import TB model class import matplotlib.pyplot as plt # set model parameters delta=0.7 # site energy t=-1.0 # spin-independent first-neighbor hop rashba=0.05 # spin-flip first-neighbor hop soc_list=[-0.06,-0.24] # spin-dependent second-neighbor hop def set_model(t,soc,rashba,delta): # set up Kane-Mele model lat=[[1.0,0.0],[0.5,np.sqrt(3.0)/2.0]] orb=[[1./3.,1./3.],[2./3.,2./3.]] model=tb_model(2,2,lat,orb,nspin=2) model.set_onsite([delta,-delta]) # definitions of Pauli matrices sigma_x=np.array([0.,1.,0.,0]) sigma_y=np.array([0.,0.,1.,0]) sigma_z=np.array([0.,0.,0.,1]) r3h =np.sqrt(3.0)/2.0 sigma_a= 0.5*sigma_x-r3h*sigma_y sigma_b= 0.5*sigma_x+r3h*sigma_y sigma_c=-1.0*sigma_x # spin-independent first-neighbor hops for lvec in ([ 0, 0], [-1, 0], [ 0,-1]): model.set_hop(t, 0, 1, lvec) # spin-dependent second-neighbor hops for lvec in ([ 1, 0], [-1, 1], [ 0,-1]): model.set_hop(soc*1.j*sigma_z, 0, 0, lvec) for lvec in ([-1, 0], [ 1,-1], [ 0, 1]): model.set_hop(soc*1.j*sigma_z, 1, 1, lvec) # spin-flip first-neighbor hops model.set_hop(1.j*rashba*sigma_a, 0, 1, [ 0, 0], mode="add") model.set_hop(1.j*rashba*sigma_b, 0, 1, [-1, 0], mode="add") model.set_hop(1.j*rashba*sigma_c, 0, 1, [ 0,-1], mode="add") return model # construct path in k-space and solve model path=[[0.,0.],[2./3.,1./3.],[.5,.5],[1./3.,2./3.], [0.,0.]] label=(r'$\Gamma $',r'$K$', r'$M$', r'$K^\prime$', r'$\Gamma $') (k_vec,k_dist,k_node)=set_model(t,0.,rashba,delta).k_path(path,101) # set up band structure plots fig, ax = plt.subplots(1,2,figsize=(8.,3.)) labs=['(a)','(b)'] for j in range(2): my_model=set_model(t,soc_list[j],rashba,delta) evals=my_model.solve_all(k_vec) ax[j].set_xlim([0,k_node[-1]]) ax[j].set_xticks(k_node) ax[j].set_xticklabels(label) for n in range(len(k_node)): ax[j].axvline(x=k_node[n],linewidth=0.5, color='k') ax[j].set_ylabel("Energy") ax[j].set_ylim(-3.8,3.8) for n in range(4): ax[j].plot(k_dist,evals[n],color='k') for m in [1,3]: kk=k_node[m] en=my_model.solve_one(path[m]) en=en[1:3] # pick out second and third bands if j==1: # exchange them in second plot en=[en[1],en[0]] ax[j].scatter(kk,en[0],s=40.,marker='o',color='k',zorder=6) ax[j].scatter(kk,en[1],s=40.,marker='o',edgecolors='k',facecolors='w',zorder=4) ax[j].text(-0.45,3.5,labs[j],size=18.) # save figure as a PDF fig.tight_layout() plt.subplots_adjust(wspace=0.35) fig.savefig("kanemele_bsr.pdf")
----- k_path report begin ---------- real-space lattice vectors [[1. 0. ] [0.5 0.86603]] k-space metric tensor [[ 1.33333 -0.66667] [-0.66667 1.33333]] internal coordinates of nodes [[0. 0. ] [0.66667 0.33333] [0.5 0.5 ] [0.33333 0.66667] [0. 0. ]] reciprocal-space lattice vectors [[ 1. -0.57735] [ 0. 1.1547 ]] cartesian coordinates of nodes [[0.00000e+00 0.00000e+00] [6.66667e-01 1.56412e-17] [5.00000e-01 2.88675e-01] [3.33333e-01 5.77350e-01] [0.00000e+00 0.00000e+00]] list of segments: length = 0.66667 from [0. 0.] to [0.66667 0.33333] length = 0.33333 from [0.66667 0.33333] to [0.5 0.5] length = 0.33333 from [0.5 0.5] to [0.33333 0.66667] length = 0.66667 from [0.33333 0.66667] to [0. 0.] node distance list: [0. 0.66667 1. 1.33333 2. ] node index list: [ 0 33 50 67 100] ----- k_path report end ------------
#!/usr/bin/env python from __future__ import print_function # python3 style print # Tight-binding 2D Kane-Mele model # C.L. Kane and E.J. Mele, PRL 95, 146802 (2005) from pythtb import * # import TB model class import matplotlib.pyplot as plt # set model parameters delta=0.7 # site energy t=-1.0 # spin-independent first-neighbor hop soc=0.06 # spin-dependent second-neighbor hop rashba=0.05 # spin-flip first-neighbor hop soc_list=[-0.06,-0.24] # spin-dependent second-neighbor hop def set_model(t,soc,rashba,delta): # set up Kane-Mele model lat=[[1.0,0.0],[0.5,np.sqrt(3.0)/2.0]] orb=[[1./3.,1./3.],[2./3.,2./3.]] model=tb_model(2,2,lat,orb,nspin=2) model.set_onsite([delta,-delta]) # definitions of Pauli matrices sigma_x=np.array([0.,1.,0.,0]) sigma_y=np.array([0.,0.,1.,0]) sigma_z=np.array([0.,0.,0.,1]) r3h =np.sqrt(3.0)/2.0 sigma_a= 0.5*sigma_x-r3h*sigma_y sigma_b= 0.5*sigma_x+r3h*sigma_y sigma_c=-1.0*sigma_x # spin-independent first-neighbor hops for lvec in ([ 0, 0], [-1, 0], [ 0,-1]): model.set_hop(t, 0, 1, lvec) # spin-dependent second-neighbor hops for lvec in ([ 1, 0], [-1, 1], [ 0,-1]): model.set_hop(soc*1.j*sigma_z, 0, 0, lvec) for lvec in ([-1, 0], [ 1,-1], [ 0, 1]): model.set_hop(soc*1.j*sigma_z, 1, 1, lvec) # spin-flip first-neighbor hops model.set_hop(1.j*rashba*sigma_a, 0, 1, [ 0, 0], mode="add") model.set_hop(1.j*rashba*sigma_b, 0, 1, [-1, 0], mode="add") model.set_hop(1.j*rashba*sigma_c, 0, 1, [ 0,-1], mode="add") return model # For the purposes of plot labels: # Real space is (r1,r2) in reduced coordinates # Reciprocal space is (k1,k2) in reduced coordinates # Below, following Python, these are (r0,r1) and (k0,k1) # set up figures fig,ax=plt.subplots(2,2,figsize=(7,6)) nk=51 # run over two choices of t2 for je,soc in enumerate(soc_list): # solve bulk model on grid and get hybrid Wannier centers along r1 # as a function of k0 my_model=set_model(t,soc,rashba,delta) my_array=wf_array(my_model,[nk,nk]) my_array.solve_on_grid([0.,0.]) rbar = my_array.berry_phase([0,1],1,berry_evals=True,contin=True)/(2.*np.pi) # set up and solve ribbon model that is finite along direction 1 width=20 nkr=81 ribbon_model=my_model.cut_piece(width,fin_dir=1,glue_edgs=False) (k_vec,k_dist,k_node)=ribbon_model.k_path('full',nkr,report=False) (rib_eval,rib_evec)=ribbon_model.solve_all(k_vec,eig_vectors=True) nbands=rib_eval.shape[0] (ax0,ax1)=ax[je,:] # hybrid Wannier center flow k0=np.linspace(0.,1.,nk) ax0.set_xlim(0.,1.) ax0.set_ylim(-1.3,1.3) ax0.set_xlabel(r"$\kappa_1/2\pi$") ax0.set_ylabel(r"HWF centers") ax0.axvline(x=0.5,linewidth=0.5, color='k') for shift in (-1.,0.,1.,2.): ax0.plot(k0,rbar[:,0]+shift,color='k') ax0.plot(k0,rbar[:,1]+shift,color='k') # edge band structure k0=np.linspace(0.,1.,nkr) ax1.set_xlim(0.,1.) ax1.set_ylim(-2.5,2.5) ax1.set_xlabel(r"$\kappa_1/2\pi$") ax1.set_ylabel(r"Edge band structure") for (i,kv) in enumerate(k0): # find expectation value <r1> at i'th k-point along direction k0 pos_exp=ribbon_model.position_expectation(rib_evec[:,i],dir=1) # assign weight in [0,1] to be 1 except for edge states near bottom weight=3.0*pos_exp/width for j in range(nbands): weight[j]=min(weight[j],1.) # scatterplot with symbol size proportional to assigned weight s=ax1.scatter([k_vec[i]]*nbands, rib_eval[:,i], s=0.6+2.5*weight, c='k', marker='o', edgecolors='none') # ax0.text(-0.45,0.92,'(a)',size=18.,transform=ax0.transAxes) # ax1.text(-0.45,0.92,'(b)',size=18.,transform=ax1.transAxes) # save figure as a PDF aa=ax.flatten() for i,lab in enumerate(['(a)','(b)','(c)','(d)']): aa[i].text(-0.45,0.92,lab,size=18.,transform=aa[i].transAxes) fig.tight_layout() plt.subplots_adjust(left=0.15,wspace=0.6) fig.savefig("kanemele_topo.pdf")
#!/usr/bin/env python from __future__ import print_function # python3 style print # Three-dimensional Fu-Kane-Mele model # Fu, Kane and Mele, PRL 98, 106803 (2007) from pythtb import * # import TB model class import matplotlib.pyplot as plt # set model parameters t=1.0 # spin-independent first-neighbor hop dt=0.4 # modification to t for (111) bond soc=0.125 # spin-dependent second-neighbor hop def set_model(t,dt,soc): # set up Fu-Kane-Mele model lat=[[.0,.5,.5],[.5,.0,.5],[.5,.5,.0]] orb=[[0.,0.,0.],[.25,.25,.25]] model=tb_model(3,3,lat,orb,nspin=2) # spin-independent first-neighbor hops for lvec in ([0,0,0],[-1,0,0],[0,-1,0],[0,0,-1]): model.set_hop(t,0,1,lvec) model.set_hop(dt,0,1,[0,0,0],mode="add") # spin-dependent second-neighbor hops lvec_list=([1,0,0],[0,1,0],[0,0,1],[-1,1,0],[0,-1,1],[1,0,-1]) dir_list=([0,1,-1],[-1,0,1],[1,-1,0],[1,1,0],[0,1,1],[1,0,1]) for j in range(6): spin=np.array([0.]+dir_list[j]) model.set_hop( 1.j*soc*spin,0,0,lvec_list[j]) model.set_hop(-1.j*soc*spin,1,1,lvec_list[j]) return model my_model=set_model(t,dt,soc) my_model.display() # first plot: compute band structure # --------------------------------- # construct path in k-space and solve model path=[[0.,0.,0.],[0.,.5,.5],[0.25,.625,.625], [.5,.5,.5],[.75,.375,.375],[.5,0.,0.]] label=(r'$\Gamma$',r'$X$',r'$U$',r'$L$',r'$K$',r'$L^\prime$') (k_vec,k_dist,k_node)=my_model.k_path(path,101) evals=my_model.solve_all(k_vec) # band structure plot fig, ax = plt.subplots(1,1,figsize=(4.,3.)) ax.set_xlim([0,k_node[-1]]) ax.set_xticks(k_node) ax.set_xticklabels(label) for n in range(len(k_node)): ax.axvline(x=k_node[n],linewidth=0.5, color='k') ax.set_ylabel("Energy") ax.set_ylim(-4.9,4.9) for n in range(4): ax.plot(k_dist,evals[n],color='k') fig.tight_layout() fig.savefig("fkm_bsr.pdf") # second plot: compute Wannier flow # --------------------------------- # initialize plot fig, ax = plt.subplots(1,2,figsize=(5.4,2.6),sharey=True) # Obtain eigenvectors on 2D grid on slices at fixed kappa_3 # Note physical (kappa_1,kappa_2,kappa_3) have python indices (0,1,2) kappa2_values=[0.,0.5] labs=[r'$\kappa_3$=0',r'$\kappa_3$=$\pi$'] nk=41 dk=1./float(nk-1) wf=wf_array(my_model,[nk,nk]) #loop over slices for j in range(2): for k0 in range(nk): for k1 in range(nk): kvec=[k0*dk,k1*dk,kappa2_values[j]] (eval,evec)=my_model.solve_one(kvec,eig_vectors=True) wf[k0,k1]=evec wf.impose_pbc(mesh_dir=0,k_dir=0) wf.impose_pbc(mesh_dir=1,k_dir=1) hwfc=wf.berry_phase([0,1],dir=1,contin=True,berry_evals=True)/(2.*np.pi) ax[j].set_xlim([0.,1.]) ax[j].set_xticks([0.,0.5,1.]) ax[j].set_xlabel(r"$\kappa_1/2\pi$") ax[j].set_ylim(-0.5,1.5) for n in range(2): for shift in [-1.,0.,1.]: ax[j].plot(np.linspace(0.,1.,nk),hwfc[:,n]+shift,color='k') ax[j].text(0.08,1.20,labs[j],size=12.,bbox=dict(facecolor='w',edgecolor='k')) ax[0].set_ylabel(r"HWF center $\bar{s}_2$") fig.tight_layout() plt.subplots_adjust(left=0.15,wspace=0.2) fig.savefig("fkm_topo.pdf")
--------------------------------------- report of tight-binding model --------------------------------------- k-space dimension = 3 r-space dimension = 3 number of spin components = 2 periodic directions = [0, 1, 2] number of orbitals = 2 number of electronic states = 4 lattice vectors: # 0 ===> [ 0.0 , 0.5 , 0.5 ] # 1 ===> [ 0.5 , 0.0 , 0.5 ] # 2 ===> [ 0.5 , 0.5 , 0.0 ] positions of orbitals: # 0 ===> [ 0.0 , 0.0 , 0.0 ] # 1 ===> [ 0.25 , 0.25 , 0.25 ] site energies: # 0 ===> [[0.+0.j 0.+0.j] [0.+0.j 0.+0.j]] # 1 ===> [[0.+0.j 0.+0.j] [0.+0.j 0.+0.j]] hoppings: < 0 | H | 1 + [ 0 , 0 , 0 ] > ===> [[1.4+0.j 0. +0.j] [0. +0.j 1.4+0.j]] < 0 | H | 1 + [ -1 , 0 , 0 ] > ===> [[1.+0.j 0.+0.j] [0.+0.j 1.+0.j]] < 0 | H | 1 + [ 0 , -1 , 0 ] > ===> [[1.+0.j 0.+0.j] [0.+0.j 1.+0.j]] < 0 | H | 1 + [ 0 , 0 , -1 ] > ===> [[1.+0.j 0.+0.j] [0.+0.j 1.+0.j]] < 0 | H | 0 + [ 1 , 0 , 0 ] > ===> [[ 0. -0.125j 0.125+0.j ] [-0.125+0.j 0. +0.125j]] < 1 | H | 1 + [ 1 , 0 , 0 ] > ===> [[ 0. +0.125j -0.125+0.j ] [ 0.125+0.j 0. -0.125j]] < 0 | H | 0 + [ 0 , 1 , 0 ] > ===> [[0.+0.125j 0.-0.125j] [0.-0.125j 0.-0.125j]] < 1 | H | 1 + [ 0 , 1 , 0 ] > ===> [[0.-0.125j 0.+0.125j] [0.+0.125j 0.+0.125j]] < 0 | H | 0 + [ 0 , 0 , 1 ] > ===> [[ 0. +0.j -0.125+0.125j] [ 0.125+0.125j 0. +0.j ]] < 1 | H | 1 + [ 0 , 0 , 1 ] > ===> [[ 0. +0.j 0.125-0.125j] [-0.125-0.125j 0. +0.j ]] < 0 | H | 0 + [ -1 , 1 , 0 ] > ===> [[ 0. +0.j 0.125+0.125j] [-0.125+0.125j 0. +0.j ]] < 1 | H | 1 + [ -1 , 1 , 0 ] > ===> [[ 0. +0.j -0.125-0.125j] [ 0.125-0.125j 0. +0.j ]] < 0 | H | 0 + [ 0 , -1 , 1 ] > ===> [[ 0. +0.125j 0.125+0.j ] [-0.125+0.j 0. -0.125j]] < 1 | H | 1 + [ 0 , -1 , 1 ] > ===> [[ 0. -0.125j -0.125+0.j ] [ 0.125+0.j 0. +0.125j]] < 0 | H | 0 + [ 1 , 0 , -1 ] > ===> [[0.+0.125j 0.+0.125j] [0.+0.125j 0.-0.125j]] < 1 | H | 1 + [ 1 , 0 , -1 ] > ===> [[0.-0.125j 0.-0.125j] [0.-0.125j 0.+0.125j]] hopping distances: | pos( 0 ) - pos( 1 + [ 0 , 0 , 0 ] ) | = 0.433 | pos( 0 ) - pos( 1 + [ -1 , 0 , 0 ] ) | = 0.433 | pos( 0 ) - pos( 1 + [ 0 , -1 , 0 ] ) | = 0.433 | pos( 0 ) - pos( 1 + [ 0 , 0 , -1 ] ) | = 0.433 | pos( 0 ) - pos( 0 + [ 1 , 0 , 0 ] ) | = 0.7071 | pos( 1 ) - pos( 1 + [ 1 , 0 , 0 ] ) | = 0.7071 | pos( 0 ) - pos( 0 + [ 0 , 1 , 0 ] ) | = 0.7071 | pos( 1 ) - pos( 1 + [ 0 , 1 , 0 ] ) | = 0.7071 | pos( 0 ) - pos( 0 + [ 0 , 0 , 1 ] ) | = 0.7071 | pos( 1 ) - pos( 1 + [ 0 , 0 , 1 ] ) | = 0.7071 | pos( 0 ) - pos( 0 + [ -1 , 1 , 0 ] ) | = 0.7071 | pos( 1 ) - pos( 1 + [ -1 , 1 , 0 ] ) | = 0.7071 | pos( 0 ) - pos( 0 + [ 0 , -1 , 1 ] ) | = 0.7071 | pos( 1 ) - pos( 1 + [ 0 , -1 , 1 ] ) | = 0.7071 | pos( 0 ) - pos( 0 + [ 1 , 0 , -1 ] ) | = 0.7071 | pos( 1 ) - pos( 1 + [ 1 , 0 , -1 ] ) | = 0.7071 ----- k_path report begin ---------- real-space lattice vectors [[0. 0.5 0.5] [0.5 0. 0.5] [0.5 0.5 0. ]] k-space metric tensor [[ 3. -1. -1.] [-1. 3. -1.] [-1. -1. 3.]] internal coordinates of nodes [[0. 0. 0. ] [0. 0.5 0.5 ] [0.25 0.625 0.625] [0.5 0.5 0.5 ] [0.75 0.375 0.375] [0.5 0. 0. ]] reciprocal-space lattice vectors [[-1. 1. 1.] [ 1. -1. 1.] [ 1. 1. -1.]] cartesian coordinates of nodes [[ 0. 0. 0. ] [ 1. 0. 0. ] [ 1. 0.25 0.25] [ 0.5 0.5 0.5 ] [ 0. 0.75 0.75] [-0.5 0.5 0.5 ]] list of segments: length = 1.0 from [0. 0. 0.] to [0. 0.5 0.5] length = 0.35355 from [0. 0.5 0.5] to [0.25 0.625 0.625] length = 0.61237 from [0.25 0.625 0.625] to [0.5 0.5 0.5] length = 0.61237 from [0.5 0.5 0.5] to [0.75 0.375 0.375] length = 0.61237 from [0.75 0.375 0.375] to [0.5 0. 0. ] node distance list: [0. 1. 1.35355 1.96593 2.5783 3.19067] node index list: [ 0 31 42 62 81 100] ----- k_path report end ------------