Topological characterization#
The library provides different quantities to determine the topological behaviour of materials. The main one is based on the calculation of Wilson loops, from which we obtain the Wannier charge centers. From their evolution one can determine both the \(\mathbb{Z}_2\) invariant or the Chern number \(C\). Alternatively, the library also allows to computer the Chern marker, from which one can also extract the Chern number. The spatial entanglement spectrum can be also computed as it may provide information about the topology of the system.
Calculation of Wannier charge centers#
The simplest way to determine if a crystalline system is topological or not is to extract the corresponding topological invariant from the
evolution of the Wannier charge centers. This can be done with the methods defined inside the module tightbinder.topology, specifically
via tightbinder.topology.calculate_wannier_centre_flow()
from tightbinder.fileparse import parse_config_file
from tightbinder.models import SlaterKoster
from tightbinder.topology import calculate_wannier_centre_flow
file = open("./examples/hBN.txt", "r")
config = parse_config_file(file)
model = SlaterKoster(config).reduce(n1=5, n2=5)
model.initialize_hamiltonian()
nk = 20
wcc = calculate_wannier_centre_flow(model, nk)
Note
The calculation of the evolution of the WCC can be relatively complex in some systems, meaning that it might be difficult to
assert the topological invariant just from looking at the evolution if the mesh used is not dense enough. To compensante this, the method
tightbinder.topology.calculate_wannier_centre_flow() incorporates an algorithm to iteratively refine the mesh until the desired
accuracy, making it easier to track the evolution of the centers. We refer to the documentation of the method for more information
on the different parameters it can take.
Z2 invariant#
Once we have the Wannier charge centers, we can plot their evolution to see if there is charge pumping or not. In a time-reversal topological
insulator, one has to inspect the evolution over half BZ (in 2D), since the other half is the same because of time-reveral symmetry. With
tightbinder.topology.calculate_z2_invariant() we extract the invariant from the WCCs, whereas tightbinder.topology.plot_wannier_centre_flow() allows
us to examine the evolution to ensure the invariant is correct.
from tightbinder.fileparse import parse_config_file
from tightbinder.models import SlaterKoster
from tightbinder.topology import calculate_wannier_centre_flow, plot_wannier_centre_flow, calculate_z2_invariant
file = open("./examples/hBN.txt", "r")
config = parse_config_file(file)
model = SlaterKoster(config).reduce(n1=5, n2=5)
model.initialize_hamiltonian()
nk = 20
wcc = calculate_wannier_centre_flow(model, nk)
z2 = calculate_z2_invariant(wcc)
plot_wannier_centre_flow(wcc)
Chern number#
Alternatively, we might want to determine the Chern number of a Chern insulator (i.e. topological insulator without time-reveral symmetry). The procedure
is analogue to that of the \(\mathbb{Z}_2\) invariant, although in this case we have to look at the evolution of the WCC along the whole BZ for 2D materials, which
can be done with the option full_BZ=True in tightbinder.topology.calculate_wannier_centre_flow().
Then, inspecting their evolution we can determine the Chern number.
from tightbinder.models import HaldaneModel
from tightbinder.topology import calculate_wannier_centre_flow, plot_wannier_centre_flow
model = HaldaneModel()
model.initialize_hamiltonian()
nk = 20
wcc = calculate_wannier_centre_flow(model, nk, full_BZ=True)
plot_wannier_centre_flow(wcc, full_BZ=True)
Chern marker#
For finite systems we can not compute the Chern number from the evolution of the WCC, since this is done in reciprocal space. Instead, we can compute the Chern marker which is evaluated over each spatial position. From its value at the bulk of the finite system, one can also estimate the value of the Chern number, which is particularly useful for non-crystalline systems.
from tightbinder.models import AgarwalaModel
from tightbinder.topology import chern_marker
model = AgarwalaModel().reduce(n1=4, n2=4)
model.initialize_hamiltonian()
results = model.solve()
marker = chern_marker(model, results)
Entanglement spectrum#
Another quantity that was shown to be related to the topological behaviour of the system is its entanglement spectrum. Namely, the spectrum of the reduced density matrix restricted to one partition of the system reflects whether the system is topological or not. To compute it, first we need to specify a partition of our system, usually via a plane that divides the material into two halves. Then, the entanglement spectrum can be built.
from tightbinder.models import AgarwalaModel
from tightbinder.topology import specify_partition_plane, entanglement_spectrum
import numpy as np
model = AgarwalaModel().reduce(n1=4, n2=4)
model.initialize_hamiltonian()
plane = specify_partition_plane([0., 1., 0., -np.max(model.motif[:, 1]])
entanglement = entanglement_spectrum(model, plane)
Note
The entanglement spectrum can also be evaluated as a function of \(k\). The current implementation only allows computing the entanglement spectrum as a function of \(k\) for 1D systems such as ribbons; for 2D or higher results might be incorrect.