.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/tight_binding/plot_graphene_bands.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_tight_binding_plot_graphene_bands.py: Graphene: Real-Space Flake and Reciprocal-Space Bands ========================================================== A from-scratch walkthrough of tbkit's two complementary ways of looking at a Tight-Binding model: * :mod:`tbkit.lattice` / :mod:`tbkit.system` -- build a finite flake in real space and diagonalize it directly. * :mod:`tbkit.kspace` -- build the Bloch Hamiltonian :math:`H(\mathbf{k})` of the infinite periodic lattice and compute a band structure along a k-path. Graphene's honeycomb lattice is the running example throughout tbkit's :doc:`/history` -- its two bands touch linearly at the Brillouin zone corners, the massless-Dirac-fermion dispersion P. R. Wallace predicted in 1947, fifty-seven years before the material itself was isolated. .. GENERATED FROM PYTHON SOURCE LINES 19-28 .. code-block:: Python import numpy as np import matplotlib.pyplot as plt from tbkit.lattice import Lattice from tbkit.system import System from tbkit.plot import Plot from tbkit.kspace import KSpace, reciprocal_vectors .. GENERATED FROM PYTHON SOURCE LINES 29-33 Shared lattice geometry ------------------------------ A two-atom hexagonal unit cell (sublattices ``a``, ``b``) with a single nearest-neighbor hopping ``t``. .. GENERATED FROM PYTHON SOURCE LINES 33-39 .. code-block:: Python DX, DY = 0.5 * 3 ** 0.5, 0.5 unit_cell = [{'tag': 'a', 'r0': (0., 0.)}, {'tag': 'b', 'r0': (DX, DY)}] prim_vec = [(2 * DX, 0.), (DX, 1.5)] t = 1. .. GENERATED FROM PYTHON SOURCE LINES 40-45 Real space: a finite flake, diagonalized directly -------------------------------------------------------- :meth:`~tbkit.lattice.Lattice.get_lattice` tiles the unit cell into an 8x8-cell flake; :class:`~tbkit.system.System` then builds and diagonalizes its real-space Hamiltonian. .. GENERATED FROM PYTHON SOURCE LINES 45-55 .. code-block:: Python # The honeycomb lattice this builds: two orbitals ('a' and 'b', drawn in # different colours) per unit cell, each with three nearest neighbors on # the other sublattice. lat_small = Lattice(unit_cell=unit_cell, prim_vec=prim_vec) lat_small.get_lattice(n1=5, n2=4) vis = System(lat_small) vis.set_hopping([{'n': 1, 't': t}]) fig_lat = Plot(vis).lattice(plt_hop=True, ms=12, figsize=(5.5, 4.5)) .. image-sg:: /api/gallery/tight_binding/images/sphx_glr_plot_graphene_bands_001.png :alt: plot graphene bands :srcset: /api/gallery/tight_binding/images/sphx_glr_plot_graphene_bands_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 56-57 The flake actually diagonalized: .. GENERATED FROM PYTHON SOURCE LINES 57-74 .. code-block:: Python lat = Lattice(unit_cell=unit_cell, prim_vec=prim_vec) lat.get_lattice(n1=8, n2=8) sys = System(lat) sys.set_hopping([{'n': 1, 't': t}]) sys.set_onsite({'a': 0., 'b': 0.}) sys.get_ham() sys.get_eig() fig, ax = plt.subplots() ax.plot(sys.en.real, 'o') ax.set_xlabel('state index $n$') ax.set_ylabel('$E_n$') ax.set_title('Graphene flake: real-space spectrum') print('Real-space flake: {} sites.'.format(sys.lat.sites)) .. image-sg:: /api/gallery/tight_binding/images/sphx_glr_plot_graphene_bands_002.png :alt: Graphene flake: real-space spectrum :srcset: /api/gallery/tight_binding/images/sphx_glr_plot_graphene_bands_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none Real-space flake: 128 sites. .. GENERATED FROM PYTHON SOURCE LINES 75-81 Reciprocal space: the Bloch Hamiltonian H(k) and its band structure -------------------------------------------------------------------------- :class:`~tbkit.kspace.KSpace` Bloch-sums the same nearest-neighbor hopping into :math:`H(\mathbf{k})`, and :meth:`~tbkit.kspace.KSpace.k_path` / :meth:`~tbkit.kspace.KSpace.plot_bands` diagonalize it along a path through the high-symmetry points :math:`\Gamma`, K, M. .. GENERATED FROM PYTHON SOURCE LINES 81-99 .. code-block:: Python kag = KSpace(lat) kag.set_hopping([{'i': 0, 'j': 1, 'R': (0, 0), 't': t}, {'i': 0, 'j': 1, 'R': (-1, 0), 't': t}, {'i': 0, 'j': 1, 'R': (0, -1), 't': t}]) b1, b2 = (np.array(v) for v in reciprocal_vectors(prim_vec)) Gamma = np.zeros(2) K = (b1 - b2) / 3 M = b1 / 2 kag.k_path([Gamma, K, M, Gamma], nk=60) fig2 = kag.plot_bands(node_labels=[r'$\Gamma$', 'K', 'M', r'$\Gamma$']) # Sanity check: the two bands must touch exactly at the Dirac point K. en_K = np.linalg.eigvalsh(kag.get_ham(K)) print('Energies at K: {} (should be ~0, ~0 -- the Dirac point)'.format(en_K)) .. image-sg:: /api/gallery/tight_binding/images/sphx_glr_plot_graphene_bands_003.png :alt: plot graphene bands :srcset: /api/gallery/tight_binding/images/sphx_glr_plot_graphene_bands_003.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none Energies at K: [-1.11022302e-16 1.11022302e-16] (should be ~0, ~0 -- the Dirac point) .. GENERATED FROM PYTHON SOURCE LINES 100-107 Wallace's 1947 linear dispersion near K -------------------------------------------- The historically defining result: near K the dispersion isn't just gapless, it is *linear* (massless Dirac fermions), :math:`E(\mathbf{K}+\mathbf{q}) \approx \pm\frac{3}{2}ta|\mathbf{q}|`, with :math:`a` the nearest-neighbor distance. See :doc:`/history` for the historical context. .. GENERATED FROM PYTHON SOURCE LINES 107-116 .. code-block:: Python a = 1. for q in (0.001, 0.01, 0.05): en_q = np.linalg.eigvalsh(kag.get_ham(K + np.array([q, 0.]))) predicted = 1.5 * t * a * q print('|q|={:.3f}: E(K+q)={:.6f}, Wallace linear estimate={:.6f}' .format(q, en_q[1], predicted)) assert np.isclose(en_q[1], predicted, rtol=0.02) print('Linear (Dirac) dispersion near K confirmed to within 2% for |q|<=0.05.') .. rst-class:: sphx-glr-script-out .. code-block:: none |q|=0.001: E(K+q)=0.001500, Wallace linear estimate=0.001500 |q|=0.010: E(K+q)=0.015037, Wallace linear estimate=0.015000 |q|=0.050: E(K+q)=0.075914, Wallace linear estimate=0.075000 Linear (Dirac) dispersion near K confirmed to within 2% for |q|<=0.05. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.068 seconds) .. _sphx_glr_download_api_gallery_tight_binding_plot_graphene_bands.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_graphene_bands.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_graphene_bands.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_graphene_bands.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_