.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/models/plot_maximally_localized_wannier_functions.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_models_plot_maximally_localized_wannier_functions.py: Maximally Localized Wannier Functions: Graphene from a Wannier90 File ======================================================================== Marzari and Vanderbilt (1997) showed how to choose the gauge of the Bloch states so that their Fourier transforms, the Wannier functions :math:`|m\mathbf{R}\rangle`, are as localized as possible. In that basis the first-principles Hamiltonian *is* a tight-binding model, :math:`H_{mn}(\mathbf{R}) = \langle m\mathbf{0}|H|n\mathbf{R}\rangle`, whose hoppings decay quickly with distance. The Wannier90 code writes it to ``seedname_hr.dat``, which :func:`tbkit.io.read_wannier90` turns into a :class:`~tbkit.kspace.KSpace`, ready for every band and topology tool: .. math:: H_{mn}(\mathbf{k}) = \sum_{\mathbf{R}} \frac{H_{mn}(\mathbf{R})}{N_{\mathbf{R}}}\, e^{i\mathbf{k}\cdot\mathbf{R}}\, , with :math:`N_{\mathbf{R}}` the degeneracy weights of the lattice vectors on the boundary of the Wigner-Seitz supercell. The files shipped with this example (``graphene_hr.dat``, ``graphene.win``, ``graphene_centres.xyz``) are a hand-written stand-in for a Wannier90 run on graphene's :math:`p_z` bands, in exactly the format Wannier90 writes: a :math:`6\times 6\times 1` k-mesh (43 lattice vectors, with degeneracy weights 1, 2 and 3), the Wannier centres on the carbon atoms, and hoppings for the first three neighbour shells close to those of the maximally-localized-Wannier-function fit of J. Jung and A. H. MacDonald, Phys. Rev. B 87, 195450 (2013). .. GENERATED FROM PYTHON SOURCE LINES 31-49 .. code-block:: Python import os import numpy as np import matplotlib.pyplot as plt from tbkit.bridges import finite_system from tbkit.io import read_wannier90, read_hr from tbkit.kspace import KSpace from tbkit.plot import Plot try: HERE = os.path.dirname(os.path.abspath(__file__)) except NameError: # run interactively HERE = os.getcwd() HR = os.path.join(HERE, 'graphene_hr.dat') WIN = os.path.join(HERE, 'graphene.win') CENTRES = os.path.join(HERE, 'graphene_centres.xyz') .. GENERATED FROM PYTHON SOURCE LINES 50-55 The raw file --------------- :func:`~tbkit.io.read_hr` returns the lattice vectors, their weights and the matrices :math:`H(\mathbf{R})`. The weights obey Wannier90's sum rule :math:`\sum_{\mathbf{R}} 1/N_{\mathbf{R}} = N_k` (36 k-points). .. GENERATED FROM PYTHON SOURCE LINES 55-61 .. code-block:: Python num_wann, R, ndegen, ham = read_hr(HR) print('num_wann = {}, nrpts = {}, weights = {}'.format(num_wann, len(R), sorted(set(ndegen.tolist())))) assert (num_wann, len(R)) == (2, 43) assert abs(np.sum(1. / ndegen) - 36) < 1e-12 .. rst-class:: sphx-glr-script-out .. code-block:: none num_wann = 2, nrpts = 43, weights = [1, 2, 3] .. GENERATED FROM PYTHON SOURCE LINES 62-67 Import as a KSpace model ------------------------------ ``dim=2`` keeps the layer: the lattice vectors come from the ``unit_cell_cart`` block of the ``.win`` file (in Angstrom), the orbital positions from the Wannier centres. .. GENERATED FROM PYTHON SOURCE LINES 67-73 .. code-block:: Python gra = read_wannier90(HR, win=WIN, centres=CENTRES, tags=['a', 'b'], dim=2) print('prim_vec:', gra.lat.prim_vec) print('Wannier centres:', gra.orbital_positions().round(4).tolist()) assert gra.is_hermitian() and gra.dim == 2 .. rst-class:: sphx-glr-script-out .. code-block:: none prim_vec: [(2.46, 0.0), (1.23, 2.13042249)] Wannier centres: [[0.0, 0.0], [1.23, 0.7101]] .. GENERATED FROM PYTHON SOURCE LINES 74-79 The imported model on a patch of :math:`5\times4` cells (:func:`~tbkit.bridges.finite_system`): the honeycomb lattice of the two Wannier centres ('a' and 'b', in two colours), and every hopping in the file, drawn with a width proportional to its amplitude -- the nearest-neighbour one dominates, the longer-range ones are much weaker. .. GENERATED FROM PYTHON SOURCE LINES 79-82 .. code-block:: Python fig_lat = Plot(finite_system(gra, (5, 4))).lattice(plt_hop=True, ms=12, figsize=(5.5, 4.5)) .. image-sg:: /api/gallery/models/images/sphx_glr_plot_maximally_localized_wannier_functions_001.png :alt: plot maximally localized wannier functions :srcset: /api/gallery/models/images/sphx_glr_plot_maximally_localized_wannier_functions_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 83-86 Localization: the hoppings of a maximally localized basis decay with the bond length :math:`|\mathbf{R} + \boldsymbol\tau_n - \boldsymbol\tau_m|`; in this file they stop after the third shell (2.84 Angstrom). .. GENERATED FROM PYTHON SOURCE LINES 86-94 .. code-block:: Python tau = gra.orbital_positions() d = np.array([np.linalg.norm(Rc + tau[j] - tau[i]) for i, j, Rc, _ in gra._hop]) t = np.array([abs(h[3]) for h in gra._hop]) shells = np.unique(d.round(4)) print('bond lengths (Angstrom):', shells) assert np.allclose(shells, [1.4203, 2.46, 2.8406], atol=1e-4) .. rst-class:: sphx-glr-script-out .. code-block:: none bond lengths (Angstrom): [1.4203 2.46 2.8406] .. GENERATED FROM PYTHON SOURCE LINES 95-99 The same model by neighbour order --------------------------------------- The file is graphene with three hopping shells: built by neighbour order on the lattice read from the file, it gives the same :math:`H(\mathbf{k})`. .. GENERATED FROM PYTHON SOURCE LINES 99-106 .. code-block:: Python t0, t1, t2 = -2.89, 0.24, -0.27 ref = KSpace(gra.lat) ref.set_hopping([{'n': 1, 't': t0}, {'n': 2, 't': t1}, {'n': 3, 't': t2}]) for k in np.random.default_rng(0).uniform(-3., 3., (30, 2)): assert np.allclose(gra.get_ham(k), ref.get_ham(k), atol=1e-12) .. GENERATED FROM PYTHON SOURCE LINES 107-110 Closed-form energies: at :math:`\Gamma`, :math:`E_\pm = 6t_1 \pm 3|t_0 + t_2|`; at K the first- and third-neighbour sums vanish, so the Dirac point survives, shifted to :math:`-3t_1`. .. GENERATED FROM PYTHON SOURCE LINES 110-118 .. code-block:: Python b1, b2 = np.array(gra.rec_vec) Gamma, K, M = np.zeros(2), (b1 - b2) / 3, b1 / 2 en_G, en_K = gra.get_bands(Gamma)[0], gra.get_bands(K)[0] print('E(Gamma) = {} eV, E(K) = {} eV'.format(en_G.round(4), en_K.round(4))) assert np.allclose(en_G, [6*t1 - 3*abs(t0 + t2), 6*t1 + 3*abs(t0 + t2)], atol=1e-12) assert np.allclose(en_K, -3*t1, atol=1e-12) .. rst-class:: sphx-glr-script-out .. code-block:: none E(Gamma) = [-8.04 10.92] eV, E(K) = [-0.72 -0.72] eV .. GENERATED FROM PYTHON SOURCE LINES 119-121 Bands and hopping decay ----------------------------- .. GENERATED FROM PYTHON SOURCE LINES 121-140 .. code-block:: Python dist, en = gra.k_path([Gamma, K, M, Gamma], nk=100) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(9, 4)) ax1.plot(dist, en, color='C0') for x in gra.nodes: ax1.axvline(x, color='k', lw=0.5) ax1.axhline(-3*t1, color='C3', ls='--', lw=1, label='Dirac point, $-3t_1$') ax1.set_xticks(gra.nodes) ax1.set_xticklabels([r'$\Gamma$', 'K', 'M', r'$\Gamma$']) ax1.set_xlim(dist[0], dist[-1]) ax1.set_ylabel('$E$ (eV)') ax1.set_title(r'Graphene $\pi$ bands from graphene_hr.dat') ax1.legend(fontsize=8) ax2.semilogy(d, t, 'o') ax2.set_xlabel(r'bond length ($\AA$)') ax2.set_ylabel('$|t|$ (eV)') ax2.set_title('Hoppings of the Wannier basis') fig.tight_layout() plt.show() .. image-sg:: /api/gallery/models/images/sphx_glr_plot_maximally_localized_wannier_functions_002.png :alt: Graphene $\pi$ bands from graphene_hr.dat, Hoppings of the Wannier basis :srcset: /api/gallery/models/images/sphx_glr_plot_maximally_localized_wannier_functions_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.108 seconds) .. _sphx_glr_download_api_gallery_models_plot_maximally_localized_wannier_functions.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_maximally_localized_wannier_functions.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_maximally_localized_wannier_functions.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_maximally_localized_wannier_functions.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_