# Lattice specification and bands¶

## Checkerboard¶

Source code

"""Two dimensional checkerboard lattice with real hoppings"""
import pybinding as pb
import matplotlib.pyplot as plt
from math import pi

pb.pltutils.use_style()

def checkerboard(d=0.2, delta=1.1, t=0.6):
lat = pb.Lattice(a1=[d, 0], a2=[0, d])
('A', [0, 0], -delta),
('B', [d/2, d/2], delta)
)
([ 0,  0], 'A', 'B', t),
([ 0, -1], 'A', 'B', t),
([-1,  0], 'A', 'B', t),
([-1, -1], 'A', 'B', t)
)
return lat

lattice = checkerboard()
lattice.plot()
plt.show()

lattice.plot_brillouin_zone()
plt.show()

model = pb.Model(checkerboard(), pb.translational_symmetry())
solver = pb.solver.lapack(model)

bands = solver.calc_bands([0, 0], [0, 5*pi], [5*pi, 5*pi], [0, 0])
bands.plot()
plt.show()


## Trestle¶

Source code

"""One dimensional lattice with complex hoppings"""
import pybinding as pb
import matplotlib.pyplot as plt

pb.pltutils.use_style()

def trestle(d=0.2, t1=0.8 + 0.6j, t2=2):
lat = pb.Lattice(a1=1.3*d)
('A', [0,   0], 0),
('B', [d/2, d], 0)
)
(0, 'A', 'B', t1),
(1, 'A', 'B', t1),
(1, 'A', 'A', t2),
(1, 'B', 'B', t2)
)
return lat

lattice = trestle()
lattice.plot()
plt.show()

lattice.plot_brillouin_zone()
plt.show()

model = pb.Model(trestle(), pb.translational_symmetry())
solver = pb.solver.lapack(model)

start, end = lattice.brillouin_zone()
bands = solver.calc_bands(start, end)
bands.plot()
plt.show()


## Monolayer graphene¶

Source code

"""Create and plot a monolayer graphene lattice, its Brillouin zone and band structure"""
import pybinding as pb
import matplotlib.pyplot as plt
from math import sqrt, pi

pb.pltutils.use_style()

def monolayer_graphene():
"""Return the lattice specification for monolayer graphene"""
a = 0.24595   # [nm] unit cell length
a_cc = 0.142  # [nm] carbon-carbon distance
t = -2.8      # [eV] nearest neighbour hopping

# create a lattice with 2 primitive vectors
lat = pb.Lattice(
a1=[a, 0],
a2=[a/2, a/2 * sqrt(3)]
)

# name and position
('A', [0, -a_cc/2]),
('B', [0,  a_cc/2])
)

# inside the main cell
([0,  0], 'A', 'B', t),
# between neighboring cells
([1, -1], 'A', 'B', t),
([0, -1], 'A', 'B', t)
)

return lat

lattice = monolayer_graphene()
lattice.plot()
plt.show()

lattice.plot_brillouin_zone()
plt.show()

model = pb.Model(monolayer_graphene(), pb.translational_symmetry())
solver = pb.solver.lapack(model)

a_cc = 0.142
Gamma = [0, 0]
K1 = [-4*pi / (3*sqrt(3)*a_cc), 0]
M = [0, 2*pi / (3*a_cc)]
K2 = [2*pi / (3*sqrt(3)*a_cc), 2*pi / (3*a_cc)]

bands = solver.calc_bands(K1, Gamma, M, K2)
bands.plot(point_labels=['K', r'$\Gamma$', 'M', 'K'])
plt.show()

model.lattice.plot_brillouin_zone(decorate=False)
bands.plot_kpath(point_labels=['K', r'$\Gamma$', 'M', 'K'])


## Monolayer graphene NN¶

Source code

"""Monolayer graphene with next-nearest hoppings"""
import pybinding as pb
import matplotlib.pyplot as plt
from math import sqrt, pi

pb.pltutils.use_style()

def monolayer_graphene_nn():
a = 0.24595   # [nm] unit cell length
a_cc = 0.142  # [nm] carbon-carbon distance
t = -2.8      # [eV] nearest neighbour hopping
t_nn = 0.25   # [eV] next-nearest neighbour hopping

lat = pb.Lattice(
a1=[a, 0],
a2=[a/2, a/2 * sqrt(3)]
)
('A', [0, -a_cc/2]),
('B', [0,  a_cc/2])
)
# between A and B inside the main cell
([0,  0], 'A', 'B', t),
# between neighboring cells
([1, -1], 'A', 'B', t),
([0, -1], 'A', 'B', t),
# next-nearest
([1,  0], 'A', 'A', t_nn),
([1,  0], 'B', 'B', t_nn),
([0,  1], 'A', 'A', t_nn),
([0,  1], 'B', 'B', t_nn),
([1, -1], 'A', 'A', t_nn),
([1, -1], 'B', 'B', t_nn)
)
return lat

lattice = monolayer_graphene_nn()
lattice.plot()
plt.show()

lattice.plot_brillouin_zone()
plt.show()

model = pb.Model(monolayer_graphene_nn(), pb.translational_symmetry())
solver = pb.solver.lapack(model)

a_cc = 0.142
Gamma = [0, 0]
K1 = [-4*pi / (3*sqrt(3)*a_cc), 0]
M = [0, 2*pi / (3*a_cc)]
K2 = [2*pi / (3*sqrt(3)*a_cc), 2*pi / (3*a_cc)]

# Note the elector-hole asymmetry in the band structure (due to t_nn).
bands = solver.calc_bands(K1, Gamma, M, K2)
bands.plot(point_labels=['K', r'$\Gamma$', 'M', 'K'])
plt.show()


## Bilayer graphene¶

Source code

"""Build the simplest model of bilayer graphene and compute its band structure"""
import pybinding as pb
import matplotlib.pyplot as plt
from math import sqrt, pi

pb.pltutils.use_style()

def bilayer_graphene():
"""Bilayer lattice in the AB-stacked form (Bernal-stacked)

This is the simplest model with just a single intralayer and a single interlayer hopping.
"""
a = 0.24595   # [nm] unit cell length
a_cc = 0.142  # [nm] carbon-carbon distance
c0 = 0.335    # [nm] interlayer spacing

lat = pb.Lattice(a1=[a/2, a/2 * sqrt(3)], a2=[a/2, -a/2 * sqrt(3)])

('A1', [0,  -a_cc/2,   0]),
('B1', [0,   a_cc/2,   0]),
('A2', [0,   a_cc/2, -c0]),
('B2', [0, 3*a_cc/2, -c0])
)

lat.register_hopping_energies({
'gamma0': -2.8,  # [eV] intralayer
'gamma1': -0.4,  # [eV] interlayer
})

# layer 1
([ 0, 0], 'A1', 'B1', 'gamma0'),
([ 0, 1], 'A1', 'B1', 'gamma0'),
([-1, 0], 'A1', 'B1', 'gamma0'),
# layer 2
([ 0, 0], 'A2', 'B2', 'gamma0'),
([ 0, 1], 'A2', 'B2', 'gamma0'),
([-1, 0], 'A2', 'B2', 'gamma0'),
# interlayer
([ 0,  0], 'B1', 'A2', 'gamma1')
)

return lat

lattice = bilayer_graphene()
lattice.plot()
plt.show()

lattice.plot_brillouin_zone()
plt.show()

model = pb.Model(bilayer_graphene(), pb.translational_symmetry())
solver = pb.solver.lapack(model)

a_cc = 0.142
Gamma = [0, 0]
K1 = [-4*pi / (3*sqrt(3)*a_cc), 0]
M = [0, 2*pi / (3*a_cc)]
K2 = [2*pi / (3*sqrt(3)*a_cc), 2*pi / (3*a_cc)]

bands = solver.calc_bands(K1, Gamma, M, K2)
bands.plot(point_labels=['K', r'$\Gamma$', 'M', 'K'])
plt.show()


## Phosphorene¶

Source code

"""Create and plot a phosphorene lattice, its Brillouin zone and band structure"""
import pybinding as pb
import matplotlib.pyplot as plt
from math import pi, sin, cos

pb.pltutils.use_style()

def phosphorene_4band():
"""Monolayer phosphorene lattice using the four-band model"""
a = 0.222
ax = 0.438
ay = 0.332
theta = 96.79 * (pi / 180)
phi = 103.69 * (pi / 180)

lat = pb.Lattice(a1=[ax, 0], a2=[0, ay])

h = a * sin(phi - pi / 2)
s = 0.5 * ax - a * cos(theta / 2)
('A', [-s/2,        -ay/2, h], 0),
('B', [ s/2,        -ay/2, 0], 0),
('C', [-s/2 + ax/2,     0, 0], 0),
('D', [ s/2 + ax/2,     0, h], 0)
)

lat.register_hopping_energies({
't1': -1.22,
't2': 3.665,
't3': -0.205,
't4': -0.105,
't5': -0.055
})

# t1
([-1,  0], 'A', 'D', 't1'),
([-1, -1], 'A', 'D', 't1'),
([ 0,  0], 'B', 'C', 't1'),
([ 0, -1], 'B', 'C', 't1'),
# t2
([ 0,  0], 'A', 'B', 't2'),
([ 0,  0], 'C', 'D', 't2'),
# t3
([ 0,  0], 'A', 'D', 't3'),
([ 0, -1], 'A', 'D', 't3'),
([ 1,  1], 'C', 'B', 't3'),
([ 1,  0], 'C', 'B', 't3'),
# t4
([ 0,  0], 'A', 'C', 't4'),
([ 0, -1], 'A', 'C', 't4'),
([-1,  0], 'A', 'C', 't4'),
([-1, -1], 'A', 'C', 't4'),
([ 0,  0], 'B', 'D', 't4'),
([ 0, -1], 'B', 'D', 't4'),
([-1,  0], 'B', 'D', 't4'),
([-1, -1], 'B', 'D', 't4'),
# t5
([-1,  0], 'A', 'B', 't5'),
([-1,  0], 'C', 'D', 't5')
)

return lat

plt.figure(figsize=(6, 6))
lattice = phosphorene_4band()
lattice.plot()
plt.show()

lattice.plot_brillouin_zone()
plt.show()

model = pb.Model(phosphorene_4band(), pb.translational_symmetry())
solver = pb.solver.lapack(model)

ax = 0.438
ay = 0.332
kx = pi / ax
ky = pi / ay
bands = solver.calc_bands([kx, ky], [kx, 0], [0, 0], [0, ky], [kx, ky])
bands.plot(point_labels=["S", "Y", r"$\Gamma$", "X", "S"])
plt.show()

model.lattice.plot_brillouin_zone(decorate=False)
bands.plot_kpath(point_labels=["S", "Y", r"$\Gamma$", "X", "S"])
plt.show()