.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/models/plot_neighbour_hoppings.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_neighbour_hoppings.py: Hoppings by Neighbour Order in k-Space: Third-Nearest-Neighbour Graphene ========================================================================= Real-space models in tbkit address bonds by neighbour order: ``{'n': 1}`` for nearest neighbours, ``{'n': 2}`` for next-nearest ones, optionally narrowed by bond angle ``'ang'`` or sublattice pair ``'tag'``. :meth:`~tbkit.kspace.KSpace.set_hopping` (and :meth:`~tbkit.kspace.KSpace.set_overlap`) accept the same selectors: the bonds of the infinite lattice are found from the unit cell and the primitive vectors (:func:`tbkit.neighbours.neighbour_bonds`), and turned into the explicit ``{'i', 'j', 'R', 't'}`` list (:func:`tbkit.neighbours.neighbour_hoppings`). This makes a realistic model a three-line affair. The example builds the third-nearest-neighbour tight-binding fit of graphene's :math:`\pi` bands by S. Reich, J. Maultzsch, C. Thomsen and P. Ordejon, Phys. Rev. B 66, 035412 (2002), with its non-orthogonal overlaps, and checks it against the closed-form energies at the high-symmetry points. .. GENERATED FROM PYTHON SOURCE LINES 21-31 .. code-block:: Python import numpy as np import matplotlib.pyplot as plt from tbkit import lattices from tbkit.kspace import KSpace from tbkit.neighbours import neighbour_bonds, neighbour_hoppings from tbkit.plot import Plot from tbkit.system import System .. GENERATED FROM PYTHON SOURCE LINES 32-39 The neighbour shells of the honeycomb lattice --------------------------------------------------- :func:`~tbkit.neighbours.neighbour_bonds` lists every bond of the first shells once (oriented so that its angle lies in [0, 180), as in :class:`~tbkit.system.System`): 3, 6 and 3 neighbours per site at distances :math:`a`, :math:`\sqrt{3}a` and :math:`2a` -- the nearest and third neighbours on the other sublattice, the second on the same one. .. GENERATED FROM PYTHON SOURCE LINES 39-51 .. code-block:: Python lat = lattices.honeycomb() # nearest-neighbour distance a = 1 bonds = neighbour_bonds(lat, 3) per_cell = [int(np.sum(bonds['n'] == n)) for n in (1, 2, 3)] lengths = [float(bonds['dis'][bonds['n'] == n][0]) for n in (1, 2, 3)] print('bonds per unit cell in shells 1, 2, 3:', per_cell) print('shell distances:', np.round(lengths, 4)) # 2 sites per cell, each bond shared by 2 sites: neighbours per site = bonds per cell assert per_cell == [3, 6, 3] assert np.allclose(lengths, [1., np.sqrt(3.), 2.]) assert set(bonds['tag'][bonds['n'] == 2]) == {'aa', 'bb'} .. rst-class:: sphx-glr-script-out .. code-block:: none bonds per unit cell in shells 1, 2, 3: [3, 6, 3] shell distances: [1. 1.7321 2. ] .. GENERATED FROM PYTHON SOURCE LINES 52-56 The three shells on a patch of the lattice (sublattices 'a' and 'b' in two colours), drawn with decreasing widths: nearest neighbours (thickest), second neighbours within each sublattice, and third neighbours across the hexagons (thinnest). .. GENERATED FROM PYTHON SOURCE LINES 56-63 .. code-block:: Python patch = lattices.honeycomb() patch.get_lattice(n1=5, n2=4) vis = System(patch) vis.set_hopping([{'n': 1, 't': 1.}, {'n': 2, 't': 0.4}, {'n': 3, 't': 0.15}]) fig_lat = Plot(vis).lattice(plt_hop=True, ms=12, figsize=(5.5, 4.5)) .. image-sg:: /api/gallery/models/images/sphx_glr_plot_neighbour_hoppings_001.png :alt: plot neighbour hoppings :srcset: /api/gallery/models/images/sphx_glr_plot_neighbour_hoppings_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 64-68 Nearest neighbours: the same as the explicit list ---------------------------------------------------- ``{'n': 1, 't': t}`` generates exactly the three bonds one would write by hand. .. GENERATED FROM PYTHON SOURCE LINES 68-81 .. code-block:: Python g0 = -2.97 explicit = KSpace(lat) explicit.set_hopping([{'i': 0, 'j': 1, 'R': (0, 0), 't': g0}, {'i': 0, 'j': 1, 'R': (-1, 0), 't': g0}, {'i': 0, 'j': 1, 'R': (0, -1), 't': g0}]) nn = KSpace(lat) nn.set_hopping([{'n': 1, 't': g0}]) print(neighbour_hoppings(lat, [{'n': 1, 't': g0}])) rng = np.random.default_rng(0) for k in rng.uniform(-4., 4., (20, 2)): assert np.allclose(nn.get_ham(k), explicit.get_ham(k), atol=1e-14) .. rst-class:: sphx-glr-script-out .. code-block:: none [{'i': 0, 'j': 1, 'R': (-1, 0), 't': -2.97}, {'i': 0, 'j': 1, 'R': (0, 0), 't': -2.97}, {'i': 1, 'j': 0, 'R': (0, 1), 't': -2.97}] .. GENERATED FROM PYTHON SOURCE LINES 82-87 The third-nearest-neighbour fit of Reich et al. ---------------------------------------------------- Hoppings :math:`\gamma_0, \gamma_1, \gamma_2` and overlaps :math:`s_0, s_1, s_2` for the first three shells, and the on-site energy :math:`\epsilon_{2p}` (eV): .. GENERATED FROM PYTHON SOURCE LINES 87-95 .. code-block:: Python eps, (g1, g2) = -0.28, (-0.073, -0.33) s0, s1, s2 = 0.073, 0.018, 0.026 gra = KSpace(lat) gra.set_onsite({'a': eps, 'b': eps}) gra.set_hopping([{'n': 1, 't': g0}, {'n': 2, 't': g1}, {'n': 3, 't': g2}]) gra.set_overlap([{'n': 1, 't': s0}, {'n': 2, 't': s1}, {'n': 3, 't': s2}]) .. GENERATED FROM PYTHON SOURCE LINES 96-103 At :math:`\Gamma` every Bloch sum is the number of neighbours, so the generalized eigenproblem :math:`Hv = ESv` gives :math:`E_\pm = (\epsilon + 6\gamma_1 \pm 3(\gamma_0+\gamma_2)) / (1 + 6s_1 \pm 3(s_0+s_2))`. At K the first- and third-neighbour sums vanish (the Dirac point survives), and the six second neighbours add up to :math:`-3`: both bands meet at :math:`E_K = (\epsilon - 3\gamma_1)/(1 - 3s_1)`, which is no longer zero -- second neighbours break electron-hole symmetry. .. GENERATED FROM PYTHON SOURCE LINES 103-116 .. code-block:: Python b1, b2 = np.array(gra.rec_vec) Gamma, K, M = np.zeros(2), (b1 - b2) / 3, b1 / 2 E_gamma = np.sort([(eps + 6*g1 + s * 3*(g0 + g2)) / (1 + 6*s1 + s * 3*(s0 + s2)) for s in (1, -1)]) E_K = (eps - 3*g1) / (1 - 3*s1) en_gamma = gra.get_bands(Gamma)[0] en_K = gra.get_bands(K)[0] print('E(Gamma) = {} eV (closed form {})'.format(np.round(en_gamma, 4), np.round(E_gamma, 4))) print('E(K) = {} eV (closed form {:.4f})'.format(np.round(en_K, 4), E_K)) assert np.allclose(en_gamma, E_gamma, atol=1e-12) assert np.allclose(en_K, E_K, atol=1e-12) assert abs(E_K - (-0.0645)) < 1e-4 .. rst-class:: sphx-glr-script-out .. code-block:: none E(Gamma) = [-7.5573 11.3218] eV (closed form [-7.5573 11.3218]) E(K) = [-0.0645 -0.0645] eV (closed form -0.0645) .. GENERATED FROM PYTHON SOURCE LINES 117-122 Band structures --------------------- Nearest neighbours only (orthogonal, :math:`\pm 3|\gamma_0|` at :math:`\Gamma`) against the full fit: the :math:`\pi^*` band is pushed up and the :math:`\pi` band compressed by the overlaps. .. GENERATED FROM PYTHON SOURCE LINES 122-145 .. code-block:: Python points = [Gamma, K, M, Gamma] labels = [r'$\Gamma$', 'K', 'M', r'$\Gamma$'] dist, en_nn = nn.k_path(points, nk=80) _, en_3nn = gra.k_path(points, nk=80) assert np.allclose(en_nn[0], [3*g0, -3*g0]) # at Gamma: pi* above +3|g0|, pi above -3|g0| (a narrower valence band) assert en_3nn[0, 1] > -3*g0 and en_3nn[0, 0] > 3*g0 fig, ax = plt.subplots(figsize=(6, 4.5)) ax.plot(dist, en_nn, color='0.6', lw=1.5) ax.plot(dist, en_3nn, color='C3', lw=2) ax.plot([], [], color='0.6', label='nearest neighbours, orthogonal') ax.plot([], [], color='C3', label='3rd neighbours + overlaps (Reich et al.)') for x in gra.nodes: ax.axvline(x, color='k', lw=0.5) ax.set_xticks(gra.nodes) ax.set_xticklabels(labels) ax.set_xlim(dist[0], dist[-1]) ax.set_ylabel('$E$ (eV)') ax.set_title('Graphene by neighbour order in k-space') ax.legend(loc='lower right', fontsize=8) plt.show() .. image-sg:: /api/gallery/models/images/sphx_glr_plot_neighbour_hoppings_002.png :alt: Graphene by neighbour order in k-space :srcset: /api/gallery/models/images/sphx_glr_plot_neighbour_hoppings_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.067 seconds) .. _sphx_glr_download_api_gallery_models_plot_neighbour_hoppings.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_neighbour_hoppings.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_neighbour_hoppings.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_neighbour_hoppings.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_