Graphene band structure#

Graphene is a two-dimensional material with a honeycomb lattice structure. It has two atoms per unit cell, which we represent as two orbitals in our tight-binding model. We start by defining the lattice vectors and the coordinates of the orbitals in fractional units. These are passed to the Lattice class to create a lattice object, along with a list of periodic directions which will be treated with periodic boundary conditions.

Note

We specify that all the lattice directions are periodic by passing periodic_dirs=.... This is a convenient shorthand for specifying all directions as periodic. Alternatively, we could have passed periodic_dirs='all', or explicitly listed periodic_dirs=[0, 1].

from pythtb import TBModel, Lattice
import numpy as np
import matplotlib.pyplot as plt
# define lattice vectors
lat_vecs = [[1, 0], [1 / 2, np.sqrt(3) / 2]]
# define coordinates of orbitals
orb_vecs = [[1 / 3, 1 / 3], [2 / 3, 2 / 3]]
lat = Lattice(lat_vecs, orb_vecs, periodic_dirs=...)

# make two dimensional tight-binding graphene model
my_model = TBModel(lat)

# set model parameters
delta = 0.0
t = -1.0

# set on-site energies
my_model.set_onsite([-delta, delta])
# set hoppings (one for each connected pair of orbitals)
# (amplitude, i, j, [lattice vector to cell containing j])
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(my_model)
----------------------------------------
       Tight-binding model report       
----------------------------------------
r-space dimension           = 2
k-space dimension           = 2
periodic directions         = [0, 1]
spinful                     = False
number of spin components   = 1
number of electronic states = 2
number of orbitals          = 2

Lattice vectors (Cartesian):
  # 0 ===> [ 1.000,  0.000]
  # 1 ===> [ 0.500,  0.866]
Volume of unit cell (Cartesian) = 0.866 [A^d]

Reciprocal lattice vectors (Cartesian):
  # 0 ===> [ 6.283, -3.628]
  # 1 ===> [ 0.000,  7.255]
Volume of reciprocal unit cell = 45.586 [A^-d]

Orbital vectors (Cartesian):
  # 0 ===> [ 0.500,  0.289]
  # 1 ===> [ 1.000,  0.577]

Orbital vectors (fractional):
  # 0 ===> [ 0.333,  0.333]
  # 1 ===> [ 0.667,  0.667]
----------------------------------------
Site energies:
  < 0 | H | 0 > = -0.000 
  < 1 | H | 1 > =  0.000 
Hoppings:
  < 0 | H | 1  + [ 0.0 ,  0.0 ] > = -1.0000+0.0000j
  < 1 | H | 0  + [ 1.0 ,  0.0 ] > = -1.0000+0.0000j
  < 1 | H | 0  + [ 0.0 ,  1.0 ] > = -1.0000+0.0000j
Hopping distances:
  | pos( 0 ) - pos( 1 ) + [ 0.0 ,  0.0 ] | =   0.577
  | pos( 1 ) - pos( 0 ) + [ 1.0 ,  0.0 ] | =   0.577
  | pos( 1 ) - pos( 0 ) + [ 0.0 ,  1.0 ] | =   0.577

Path in Brillouin zone from TBModel#

We generate list of k-points following a segmented path in the BZ list of nodes (high-symmetry points) using TBModel.k_path. These high-symmetry points are specified in reduced coordinates: each entry is a list of fractional coordinates with respect to the reciprocal lattice vectors. We choose the nodes:

  • \(\Gamma\) = [0, 0]

  • \(K\) = [2/3, 1/3]

  • \(M\) = [1/2, 1/2]

  • \(\Gamma\) = [0, 0]

Outputs:

  • k_path: list of interpolated k-points

  • k_dist: horizontal axis position of each k-point in the list

  • k_node_dist: horizontal axis position of each original node

k_nodes = [[0, 0], [2 / 3, 1 / 3], [1 / 2, 1 / 2], [0, 0]]
k_node_labels = (r"$\Gamma $", r"$K$", r"$M$", r"$\Gamma $")
nk = 121

k_path, k_dist, k_node_dist = my_model.k_path(k_nodes, nk)

Band structure#

Graphene has a characteristic linear band crossing at the K point in the Brillouin zone, known as a Dirac cone. This results in unique electronic properties, such as high electron mobility and massless charge carriers. The band structure can be calculated using the tight-binding model and visualized along high-symmetry paths in the Brillouin zone.

We diagonalize the Hamiltonian at each k-point to obtain the energy eigenvalues, which represent the allowed energy levels for electrons in the material. Plotting these energy levels against the k-points gives us the band structure of graphene, revealing its electronic properties.

evals = my_model.solve_ham(k_path)
fig, ax = plt.subplots()

ax.set_xlim(k_node_dist[0], k_node_dist[-1])
ax.set_xticks(k_node_dist)
ax.set_xticklabels(k_node_labels)

for n in range(len(k_node_dist)):
    ax.axvline(x=k_node_dist[n], linewidth=0.5, color="k")

ax.set_title("Graphene band structure")
ax.set_xlabel("Path in k-space")
ax.set_ylabel("Band energy")

# plot bands
ax.plot(k_dist, evals, c="b")
plt.show()
../_images/9e963795011ad55740ac6821ce0f71cb8c56cb37bee9bc5cdfd51768af9b0190.png

Alternatively, we can use the TBModel.band_structure method to compute the band structure directly along the specified path without having to generate the k-points separately or specify the matplotlib details. This method takes care of computing the k-points, solving the Hamiltonian, and plotting the results in one step.

my_model.plot_bands(k_nodes, k_node_labels)
plt.show()
../_images/5575ad9f318905f8692fb7480f9cdede7b92581c51078bec6c22285a215dd913.png