Chirality of a Weyl point (tight-binding)

In this example, the chirality of a Weyl point is calculated for a tight-binding model of WTe2. This is done by calculating the Chern number on a sphere surrounding the Weyl point.

The Chern number is a measure for the flux of Berry curvature, thus it can be used to determine if the Weyl point is a source or sink of Berry curvature (i.e., determine its chirality).

#!/usr/bin/env python3

from contextlib import suppress
import lzma
import os
import pickle

import matplotlib.pyplot as plt
from tbmodels import Model
import z2pack

MODEL_NAME = "wte2_soc"
MODEL_SOURCE = os.path.join("data", MODEL_NAME + ".json")
MODEL_PATH = os.path.join("data", MODEL_NAME + ".p")

# creating the necessary subfolders
subfolders = ["results", "plots"]
for s in subfolders:
    with suppress(FileExistsError):
        os.mkdir(s)


def calculate_chirality(tag, center, radius, overwrite=False, **kwargs):
    # converting the Model to the pickle format (which is quicker to load)
    # Note that keeping only the pickle format is dangerous, because it
    # may become unreadable -- use the JSON format for long-term saving.
    try:
        with open(MODEL_PATH, "rb") as f:
            model = pickle.load(f)
    except OSError:
        # The .xz compression is used to avoid the GitHub file size limit
        with lzma.open(MODEL_SOURCE + ".xz") as fin, open(MODEL_SOURCE, "wb") as fout:
            fout.write(fin.read())

        model = Model.from_json_file(MODEL_SOURCE)
        with open(MODEL_PATH, "wb") as f:
            pickle.dump(model, f, protocol=pickle.HIGHEST_PROTOCOL)

    system = z2pack.tb.System(model)
    full_name = MODEL_NAME + "_" + tag
    res = z2pack.surface.run(
        system=system,
        surface=z2pack.shape.Sphere(center, radius),
        save_file=os.path.join("results", full_name + ".p"),
        load=not overwrite,
        **kwargs,
    )
    # Again, the pickle format is used because it is faster than JSON
    # or msgpack. If you wish to permanently store the result, use
    # z2pack.io.save(res, os.path.join('results', full_name + '.json'))
    print("Chern number:", z2pack.invariant.chern(res))


def plot_chirality(tag, ax):
    full_name = MODEL_NAME + "_" + tag
    res = z2pack.io.load(os.path.join("results", full_name + ".p"))
    z2pack.plot.chern(res, axis=ax)


if __name__ == "__main__":
    # calculate
    calculate_chirality("0", [0.1203, 0.05232, 0.0], 0.005)
    calculate_chirality("1", [0.1211, 0.02887, 0.0], 0.005, iterator=range(10, 33, 2))

    # plot
    fig, ax = plt.subplots(1, 2, figsize=[4, 2], sharey=True, gridspec_kw=dict(wspace=0.3))
    ax[0].set_xticks([0, 1])
    ax[1].set_xticks([0, 1])
    ax[0].set_xticklabels([r"$-\pi$", r"$0$"])
    ax[1].set_xticklabels([r"$-\pi$", r"$0$"])
    ax[0].set_yticks([0, 1])
    ax[1].set_yticks([0, 1])
    ax[1].set_yticklabels([r"$0$", r"$2\pi$"])
    ax[0].set_xlabel(r"$\theta$")
    ax[1].set_xlabel(r"$\theta$")
    ax[0].set_ylabel(r"$\bar{\varphi}$", rotation="horizontal")
    ax[0].text(-0.2, 1.05, r"(a)", ha="right")
    ax[1].text(-0.05, 1.05, r"(b)", ha="right")
    plot_chirality("0", ax[0])
    plot_chirality("1", ax[1])
    plt.savefig("plots/WTe2_chirality.pdf", bbox_inches="tight", rasterized=True)