.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/dynamics/plot_wavepacket_interference.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_dynamics_plot_wavepacket_interference.py: Wave Propagation: Interference on a Ring and a Trapped Domain-Wall State =========================================================================== :class:`~tbkit.propagation.Propagation` evolves a state in time (Crank-Nicolson, :math:`\hbar = 1`). Two classic effects of lattice waves: * **Interference on a ring.** On a hexagonal ring, a particle started on one site reaches the opposite site along two paths. Flip the sign of one hopping -- a :math:`\pi` flux through the ring -- and the two paths cancel exactly: the opposite site is *never* reached (Aharonov-Bohm caging). * **A trapped state.** A dimerized chain with a domain wall (the strong and weak bonds swap) binds a zero mode at the wall. A particle started there mostly stays: its long-time return probability is the sum :math:`\sum_n|\langle n|\psi_0\rangle|^4` over the eigenstates, far larger than on a uniform chain, where it spreads away. (This script replaces the pre-0.2 notebook ``examples_propagation.ipynb``.) .. GENERATED FROM PYTHON SOURCE LINES 21-29 .. code-block:: Python import numpy as np import matplotlib.pyplot as plt from tbkit.lattice import Lattice from tbkit.plot import Plot from tbkit.propagation import Propagation from tbkit.system import System .. GENERATED FROM PYTHON SOURCE LINES 30-32 A hexagonal ring, with and without a pi flux ----------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 32-44 .. code-block:: Python angles = np.arange(6) * np.pi / 3 ring_cell = [{'tag': 'a', 'r0': (float(np.cos(a)), float(np.sin(a)))} for a in angles] # Six sites on a ring, each bond a hopping t = 1. A walker starting on the # left-most site reaches the right-most one along two paths, one per arm. ring = Lattice(unit_cell=ring_cell, prim_vec=[(10., 0.), (0., 10.)]) ring.get_lattice(n1=1, n2=1) vis = System(ring) vis.set_hopping([{'n': 1, 't': 1.}]) fig_ring = Plot(vis).lattice(plt_hop=True, ms=16, figsize=(3, 3)) .. image-sg:: /api/gallery/dynamics/images/sphx_glr_plot_wavepacket_interference_001.png :alt: plot wavepacket interference :srcset: /api/gallery/dynamics/images/sphx_glr_plot_wavepacket_interference_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 45-47 The weight on the opposite site, without and with a :math:`\pi` flux through the ring: .. GENERATED FROM PYTHON SOURCE LINES 47-77 .. code-block:: Python fig, axes = plt.subplots(1, 3, figsize=(13, 3.8)) far = {} for flux in (False, True): lat = Lattice(unit_cell=ring_cell, prim_vec=[(10., 0.), (0., 10.)]) lat.get_lattice(n1=1, n2=1) sys = System(lat) sys.set_hopping([{'n': 1, 't': 1.}]) start = int(np.argmin(lat.coor['x'])) opposite = int(np.argmax(lat.coor['x'])) if flux: i, j = int(sys.hop['i'][0]), int(sys.hop['j'][0]) sys.set_hopping_def({(i, j): -1.}) sys.get_ham() prop = Propagation(lat) psi = np.zeros(lat.sites, 'c16') psi[start] = 1. prop.get_propagation(sys.ham, psi, steps=400, dz=0.05) weight = np.abs(prop.prop[opposite]) ** 2 far[flux] = weight t = np.arange(prop.steps) * prop.dz axes[0].plot(t, weight, label=r'$\pi$ flux' if flux else 'no flux') assert far[False].max() > 0.3 and far[True].max() < 1e-12 print('largest weight on the opposite site: {:.3f} (no flux), {:.1e} (pi flux)'.format( far[False].max(), far[True].max())) axes[0].set_xlabel('time') axes[0].set_ylabel('weight on the opposite site') axes[0].set_title('hexagonal ring') axes[0].legend() .. image-sg:: /api/gallery/dynamics/images/sphx_glr_plot_wavepacket_interference_002.png :alt: hexagonal ring :srcset: /api/gallery/dynamics/images/sphx_glr_plot_wavepacket_interference_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none largest weight on the opposite site: 0.756 (no flux), 7.4e-32 (pi flux) .. GENERATED FROM PYTHON SOURCE LINES 79-81 A domain wall in a dimerized chain ------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 81-100 .. code-block:: Python def dimer_chain(wall): lat = Lattice(unit_cell=[{'tag': 'a', 'r0': (0., 0.)}, {'tag': 'b', 'r0': (1., 0.)}], prim_vec=[(2., 0.)]) lat.get_lattice(n1=20) lat.remove_sites([39]) sys = System(lat) sys.set_hopping([{'n': 1, 'tag': 'ab', 't': 2.}, {'n': 1, 'tag': 'ba', 't': 1.}]) if wall: # swap the strong and weak bonds right of x = 20: a wall at site 20 sys.change_hopping_square([{'n': 1, 'tag': 'ab', 't': 1.}, {'n': 1, 'tag': 'ba', 't': 2.}], xlims=[20., 40.]) else: sys.set_hopping([{'n': 1, 'tag': 'ab', 't': 1.5}, {'n': 1, 'tag': 'ba', 't': 1.5}]) sys.get_ham() return lat, sys .. GENERATED FROM PYTHON SOURCE LINES 101-104 The chain with its domain wall, bond widths proportional to the hopping: strong bonds start each dimer left of site 20 ('a' to 'b') and right of it ('b' to 'a'), so site 20 sits between two weak bonds. .. GENERATED FROM PYTHON SOURCE LINES 104-107 .. code-block:: Python fig_wall = Plot(dimer_chain(True)[1]).lattice(plt_hop=True, ms=6, c=2.5, figsize=(12, 1.2)) .. image-sg:: /api/gallery/dynamics/images/sphx_glr_plot_wavepacket_interference_003.png :alt: plot wavepacket interference :srcset: /api/gallery/dynamics/images/sphx_glr_plot_wavepacket_interference_003.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 108-109 The return probability of a walker started on site 20: .. GENERATED FROM PYTHON SOURCE LINES 109-134 .. code-block:: Python for ax, wall in zip(axes[1:], (True, False)): lat, sys = dimer_chain(wall) site = 20 prop = Propagation(lat) psi = np.zeros(lat.sites, 'c16') psi[site] = 1. prop.get_propagation(sys.ham, psi, steps=3000, dz=0.05) ret = np.abs(prop.prop[site]) ** 2 en, vec = np.linalg.eigh(sys.ham.toarray()) expected = np.sum(np.abs(vec[site]) ** 4) late = ret[1000:].mean() assert abs(late - expected) < 0.05 if wall: assert np.min(np.abs(en)) < 1e-6 and late > 0.3 else: assert late < 0.1 print('{}: long-time return probability {:.3f} (eigenstate sum {:.3f})'.format( 'domain wall' if wall else 'uniform chain', late, expected)) ax.imshow(np.abs(prop.prop[:, ::10]) ** 2, aspect='auto', origin='lower', cmap='magma', extent=[0, prop.steps * prop.dz, 0, lat.sites], vmax=0.3) ax.set_xlabel('time') ax.set_ylabel('site') ax.set_title('domain wall' if wall else 'uniform chain') fig.tight_layout() .. rst-class:: sphx-glr-script-out .. code-block:: none domain wall: long-time return probability 0.367 (eigenstate sum 0.366) uniform chain: long-time return probability 0.038 (eigenstate sum 0.038) .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.093 seconds) .. _sphx_glr_download_api_gallery_dynamics_plot_wavepacket_interference.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_wavepacket_interference.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_wavepacket_interference.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_wavepacket_interference.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_