The Zak Phase: Where the SSH Chain’s Electrons Sit#

J. Zak showed in 1989 that the Berry phase acquired by a Bloch state carried once across the Brillouin zone,

\[\gamma = \oint \mathbf{A}\cdot d\mathbf{k}\, ,\qquad \mathbf{A} = i\langle u_k|\partial_k u_k\rangle\, ,\]

is a property of the whole band – the Zak phase – and that \(\gamma/2\pi\) is the centre of the band’s Wannier functions in units of the lattice constant: the electronic polarization. With inversion symmetry it is quantized to 0 or \(\pi\).

In the SSH chain (sites at \(x = 0\) and \(x = 1/2\), intracell hopping \(v\), intercell \(w\)), the occupied band’s Wannier function sits on the stronger bond: at the intracell bond centre \(x = 1/4\) when \(v > w\), at the intercell one \(x = 3/4\) when \(w > v\). The two phases differ by \(\pi\) – half an electron per cell moved by half a cell – and the jump is what leaves the end charges and zero modes of an open topological chain. berry_phase() and wannier_centers() compute both, from the gauge-invariant discrete Wilson loop.

import numpy as np
import matplotlib.pyplot as plt

from tbkit.lattice import Lattice
from tbkit.bridges import finite_system
from tbkit.kspace import KSpace
from tbkit.plot import Plot


def ssh(v, w):
    lat = Lattice(unit_cell=[{'tag': 'a', 'r0': (0., 0.)}, {'tag': 'b', 'r0': (0.5, 0.)}],
                         prim_vec=[(1., 0.)])
    chain = KSpace(lat)
    chain.set_hopping([{'i': 0, 'j': 1, 'R': (0,), 't': v},
                                {'i': 1, 'j': 0, 'R': (1,), 't': w}])
    return chain

The lattice#

Eight cells of the SSH chain (finite_system()), orbitals a and b in two colours, bond widths proportional to the hoppings: \(v\) inside each cell, \(w\) between cells, for \(v > w\) (top) and \(v < w\) (bottom).

fig_lat, axes_lat = plt.subplots(2, 1, figsize=(7, 2.2))
Plot(finite_system(ssh(1., 0.4), 8)).lattice(plt_hop=True, ms=7, c=4., ax=axes_lat[0])
Plot(finite_system(ssh(0.4, 1.), 8)).lattice(plt_hop=True, ms=7, c=4., ax=axes_lat[1])
plot zak phase
<Figure size 700x220 with 2 Axes>

The Wannier centre sits on the strong bond#

for v, w, centre in [(1., 0.4, 0.25), (0.4, 1., 0.75)]:
    x = ssh(v, w).wannier_centers(0, nk=200)[0]
    print('v = {}, w = {}: Wannier centre x = {:.6f}'.format(v, w, x))
    assert np.isclose(x, centre, atol=1e-8)
v = 1.0, w = 0.4: Wannier centre x = 0.250000
v = 0.4, w = 1.0: Wannier centre x = 0.750000

Across the transition: a jump of pi#

The Zak phase is pinned while the gap stays open, and jumps by \(\pi\) where it closes, at \(v = w\).

ratios = np.linspace(0.2, 2., 37)
zak = np.array([ssh(r, 1.).berry_phase(0, nk=200) for r in ratios])
centres = (zak / (2*np.pi)) % 1.
topo = ratios < 1.
assert np.allclose(centres[topo], 0.75, atol=1e-8)
assert np.allclose(centres[~topo & ~np.isclose(ratios, 1.)], 0.25, atol=1e-8)
print('Wannier centre 3/4 for v < w, 1/4 for v > w: a jump of half a cell (Zak phase pi).')

fig, ax = plt.subplots(figsize=(6, 3.6))
ax.plot(ratios, centres, 'o-b')
ax.axvline(1., color='k', ls='--', lw=1)
ax.set_xlabel('$v/w$')
ax.set_ylabel(r'Wannier centre $\gamma/2\pi$')
ax.set_title('Zak phase of the SSH chain')
fig.set_layout_engine('tight')
Zak phase of the SSH chain
Wannier centre 3/4 for v < w, 1/4 for v > w: a jump of half a cell (Zak phase pi).

The polarization is a property of the band, not of the gauge#

Placing both orbitals on the cell origin (positions=False) shifts each phase, but not the quantized difference between the two phases.

diff = (ssh(0.4, 1.).berry_phase(0, positions=False)
            - ssh(1., 0.4).berry_phase(0, positions=False)) % (2*np.pi)
assert np.isclose(diff, np.pi)
print('Zak-phase difference in the periodic gauge: {:.6f} = pi.'.format(diff))
Zak-phase difference in the periodic gauge: 3.141593 = pi.

Total running time of the script: (0 minutes 0.077 seconds)

Gallery generated by Sphinx-Gallery