The BravaisLattice and TightBinding classes: definitions and example

The following example is aimed at demonstrating the use of TRIQS Lattice tools.

BravaisLattice

A BravaisLattice is constructed as BravaisLattice(units, orbital_positions ) where

  • units is the list the coordinates (given as triplets) of the basis vectors \(\lbrace \mathbf{e}_i \rbrace _{i=1\dots d}\) (\(d\) is the dimension)

  • orbital_positions is a dictionary of the atoms forming the basis of the Bravais Lattice: the key is the name of the atom/orbital, the value is the triplet of its coordinates.

TightBinding

A tight-binding lattice is defined by the relation:

\[\mathbf{t}_k = \sum_{\mathbf{R}\in \mathrm{BL}} e^{i \mathbf{k}\cdot \mathbf{R}} \mathbf{t}_\mathbf{R}\]

where \(\mathbf{t}_i\) is the matrix of the hoppings from a documentation/manual/triqs unit cell (\(\mathbf{R}=O\)) to a unit cell indexed by \(\mathbf{R}\). \((\mathbf{t}_\mathbf{R})_{n,m}\) is the tight-binding integral between atom \(n\) of site \(O\) and atom \(m\) of site \(\mathbf{R}\), ie

\[(\mathbf{t}_\mathbf{R})_{n,m} \equiv \int d^3\mathbf{r} \phi_n(\mathbf{r})^{*} V(\mathbf{r}) \phi_m(\mathbf{r}-\mathbf{R})\]

where \(\phi_n(\mathbf{r}-\mathbf{R})\) is the Wannier orbital of atom \(n\) centered at site \(\mathbf{R}\). The corresponding class in Lattice Tools is the TightBinding class. Its instances are constructed as follows:

TightBinding ( bravais_lattice, hopping_dictionary) where

  • bravais_lattice is an instance of BravaisLattice

  • hopping_dictionary is a dictionary of the hoppings \(\mathbf{t}_\mathbf{R}\), where the keys correspond to the coordinates of \(\mathbf{R}\) in the unitary basis \(\lbrace \mathbf{e}_i \rbrace _{i=1\dots d}\), and the values to the corresponding matrix: \((\mathbf{t}_\mathbf{R})_{n,m}\)

energies_on_bz_path

The function energies_on_bz_path (TB, start, end, n_pts) returns a \(n_{at} \times n_{pts}\) matrix \(E\) such that

E[n,k]\(= \epsilon_n(\mathbf{k})\)

where k indexes the n_pts \(\mathbf{k}\)-points of the line joining start and end, and \(\epsilon_n(k)\) is the \(n\)th eigenvector of \(t_\mathbf{k}\).

Example

The following example illustrates the usage of the above tools for the case of a two-dimensional, square lattice with various unit cells. We successively construct three Bravais lattices BL_1, BL_2 and BL_4 with, respectively, 1, 2 and 4 atoms per unit cell, as well as three tight-binding models with hopping dictionaries hop_1, hop_2 and hop_4

from numpy import array, zeros
import math 
from triqs.lattice.tight_binding import *

# Define the Bravais Lattice : a square lattice in 2d
BL_1 = BravaisLattice(units = [(1,0,0), (0,1,0) ], orbital_positions= [(0,0,0)] )
BL_2 = BravaisLattice(units = [(1,1,0) , (-1,1,0) ], orbital_positions= [ (0,0,0),(.5,.5,0)] )
BL_4 = BravaisLattice(units = [(2,0,0) , (0,2,0) ], orbital_positions= [(0,0,0),(0,.5,0), (.5,0,0), (.5,.5,0)] )

# Hopping dictionaries
t = .25; tp = -.1;

hop_1= {  (1,0)  :  [[ t]],      (-1,0) :  [[ t]],     (0,1)  :  [[ t]],   (0,-1) :  [[ t]],
        (1,1)  :  [[ tp]],      (-1,-1):  [[ tp]],        (1,-1) :  [[ tp]],     (-1,1) :  [[ tp]]
        }

hop_2= {  (0,0) :[[0.,t],
                  [t,0.]],
        (1,0)  :  [[ tp, 0],
                   [ t ,tp]],
        (-1,0) :  [[ tp, t],
                   [ 0 ,tp]],
        (0,1)  :[[ tp, 0],
                 [ t, tp]],
        (0,-1) :[[ tp, t],
                 [ 0 ,tp]],
        (1,1)  :  [[ 0, 0],
                   [ t,0]],
        (-1,-1) :[[ 0, t],
                  [ 0,0]],
        (-1,1) :  [[ 0, 0],
                   [ 0,0]],
        (1,-1)  : [[ 0, 0],
                   [ 0,0]]
        }

hop_4= {  (0,0) :[[0.,t, tp,t],
                  [t,0., t,tp],
                  [tp,t,0,t],
                  [t,tp,t,0]],
    
        (1,0)  :  [[0.,0, 0,0],
                   [t,0.,0,tp],
                   [tp,0,0,t],
                   [0,0,0,0]],
    
        (-1,0) :  [[0.,t, tp,0],
                   [0,0.,0,0],
                   [0,0,0,0],
                   [0,tp,t,0]], 
    
        (0,1)  : [[0.,0, 0,0],
                  [0,0.,0,0],
                  [tp,t,0,0],
                  [t,tp,0,0]],   
    
        (0,-1) :[[0.,0, tp,t],
                 [0,0.,t,tp],
                 [0,0,0,0],
                 [0,0,0,0]],
    
         (1,1)  :  [[0.,0, 0,0],
                   [0,0.,0,0],
                   [tp,0,0,0],
                   [0,0,0,0]],
     
        (-1,-1) :  [[0.,0, tp,0],
                   [0,0.,0,0],
                   [0,0,0,0],
                   [0,0,0,0]], 
    
        (-1,1)  : [[0.,0, 0,0],
                  [0,0.,0,0],
                  [0,0,0,0],
                  [0,tp,0,0]],  
    
        (1,-1) :[[0.,0, 0,0],
                 [0,0.,0,tp],
                 [0,0,0,0],
                 [0,0,0,0]],
    
        }

TB_1 = TightBinding(BL_1, hop_1)
TB_2 = TightBinding(BL_2, hop_2)
TB_4 = TightBinding(BL_4, hop_4)

# High-symmetry points
Gamma     = array([0.        ,0.       ]);
PiPi      = array([math.pi   ,math.pi  ])*1/(2*math.pi);
Pi0       = array([math.pi   ,0        ])*1/(2*math.pi);
PihPih    = array([math.pi/2 ,math.pi/2])*1/(2*math.pi)
TwoPi0    = array([2*math.pi ,0        ])*1/(2*math.pi);
TwoPiTwoPi= array([math.pi*2 ,math.pi*2])*1/(2*math.pi)

n_pts=50

# Paths along high-symmetry directions
path_1=[Gamma,Pi0,PiPi,Gamma]
path_2=[Gamma,PiPi,TwoPi0,Gamma] #equivalent to path_1 in coordinates of 2at/ucell basis
path_4=[Gamma,TwoPi0,TwoPiTwoPi,Gamma] #equivalent to path_1 in coordinates of 4at/ucell basis

def energies_on_path(path, TB, n_pts, n_orb=1):
    E=zeros((n_orb,n_pts*(len(path)-1)))
    for i in range(len(path)-1,0,-1):
        energies = energies_on_bz_path (TB, path[i-1], path[i], n_pts)
        for orb in range(n_orb):     E[orb,(i-1)*n_pts:(i)*n_pts]=energies[orb,:]
        print("index of point #"+str(i-1)+" = "+str((i-1)*n_pts))
    
    return E
E_1= energies_on_path(path_1,TB_1,n_pts,1)
E_2= energies_on_path(path_2,TB_2,n_pts,2)
E_4= energies_on_path(path_4,TB_4,n_pts,4)

from matplotlib import pylab as plt
plt.plot(E_1[0], '--k', linewidth=4, label = "1 at/unit cell")
plt.plot(E_2[0],'-.g', linewidth=4, label = "2 ats/unit cell")
plt.plot(E_2[1],'-.g', linewidth=4)
plt.plot(E_4[0],'-r', label = "4 ats/unit cell")
plt.plot(E_4[1],'-r')
plt.plot(E_4[2],'-r')
plt.plot(E_4[3],'-r')
plt.grid()
plt.legend()
plt.axes().set_xticks([0,50,100,150])
plt.axes().set_xticklabels([r'$\Gamma_1$',r'$M_1$',r'$X_1$',r'$\Gamma_1$'])
plt.ylabel(r"$\epsilon$")