.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/plot_chern.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 or to run this example in your browser via Binder .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_plot_chern.py: Topological invariants =================================== Calculation of Berry phase and Chern number for a magneto-optical photonic crystal. .. GENERATED FROM PYTHON SOURCE LINES 15-32 .. code-block:: Python import time import matplotlib.pyplot as plt import protis as pt pt.set_backend("autograd") # pt.set_backend("torch") bk = pt.backend pi = bk.pi plt.ion() plt.close("all") .. GENERATED FROM PYTHON SOURCE LINES 33-35 Reference results are taken from :cite:p:`blancodepaz2020`. .. GENERATED FROM PYTHON SOURCE LINES 35-41 .. code-block:: Python a = 1 lattice = pt.Lattice([[a, 0], [0, a]], discretization=2**9) .. GENERATED FROM PYTHON SOURCE LINES 42-43 Define the permittivity .. GENERATED FROM PYTHON SOURCE LINES 43-55 .. code-block:: Python rod = lattice.circle(center=(0.5, 0.5), radius=0.11) epsilon = lattice.ones() epsilon[rod] = 15 mu = lattice.ones() one = lattice.ones() zero = lattice.zeros() mu = pt.block_z_anisotropic(one, zero, zero, one, one) mu[0, 0, rod] = mu[1, 1, rod] = 14 mu[0, 1, rod] = 12.4j mu[1, 0, rod] = -12.4j .. GENERATED FROM PYTHON SOURCE LINES 56-57 We define here the wavevector path: .. GENERATED FROM PYTHON SOURCE LINES 57-65 .. code-block:: Python Gamma = (0, 0) X = (pi / a, 0) M = (pi / a, pi / a) sym_points = [Gamma, X, M, Gamma] Nb = 31 kpath = pt.init_bands(sym_points, Nb) .. GENERATED FROM PYTHON SOURCE LINES 66-67 Calculate the band diagram: .. GENERATED FROM PYTHON SOURCE LINES 67-88 .. code-block:: Python polarization = "TM" nh = 200 def compute_bands(epsilon, mu): sim = pt.Simulation(lattice, epsilon=epsilon, mu=mu, nh=nh) ev_band = [] for kx, ky in kpath: sim.k = kx, ky sim.solve(polarization, vectors=False) ev_norma = sim.eigenvalues * a / (2 * pi) ev_band.append(ev_norma.real) return ev_band ev_band0 = compute_bands(epsilon, mu=1) ev_band = compute_bands(epsilon, mu) .. GENERATED FROM PYTHON SOURCE LINES 89-90 Plot the bands (without magnetic field): .. GENERATED FROM PYTHON SOURCE LINES 90-101 .. code-block:: Python labels = ["$\Gamma$", "$X$", "$M$", "$\Gamma$"] plt.figure() pt.plot_bands(sym_points, Nb, ev_band0, color="#8041b0", xtickslabels=labels) plt.ylim(0, 1.2) plt.ylabel(r"Frequency $\omega a/2\pi c$") plt.title("without magnetic field") plt.tight_layout() .. image-sg:: /examples/images/sphx_glr_plot_chern_001.png :alt: without magnetic field :srcset: /examples/images/sphx_glr_plot_chern_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none /builds/protis/protis.gitlab.io/protis/examples/plot_chern.py:99: UserWarning: Glyph 64257 (\N{LATIN SMALL LIGATURE FI}) missing from current font. plt.tight_layout() .. GENERATED FROM PYTHON SOURCE LINES 102-103 Plot the bands (with magnetic field): .. GENERATED FROM PYTHON SOURCE LINES 103-111 .. code-block:: Python plt.figure() pt.plot_bands(sym_points, Nb, ev_band, color="#8041b0", xtickslabels=labels) plt.ylim(0, 1.2) plt.ylabel(r"Frequency $\omega a/2\pi c$") plt.title("with applied magnetic field") plt.tight_layout() .. image-sg:: /examples/images/sphx_glr_plot_chern_002.png :alt: with applied magnetic field :srcset: /examples/images/sphx_glr_plot_chern_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none /builds/protis/protis.gitlab.io/protis/examples/plot_chern.py:109: UserWarning: Glyph 64257 (\N{LATIN SMALL LIGATURE FI}) missing from current font. plt.tight_layout() .. GENERATED FROM PYTHON SOURCE LINES 112-113 Compute modes in the first Brillouin zone: .. GENERATED FROM PYTHON SOURCE LINES 113-144 .. code-block:: Python sim = pt.Simulation(lattice, epsilon=epsilon, mu=mu, nh=nh) t = -time.time() method = "fourier" n_eig = 3 nk = 31 kx = ky = bk.linspace(0, 2 * pi / a, nk) Kx, Ky = bk.meshgrid(kx, ky) if method == "fourier": eigenmodes = bk.empty((nk, nk, sim.nh, n_eig), dtype=bk.complex128) else: eigenmodes = bk.empty((nk, nk, *lattice.discretization, n_eig), dtype=bk.complex128) for i in range(nk): _mode = [] for j in range(nk): k = kx[i], ky[j] sim.k = k eigs, modes = sim.solve(polarization) if method == "fourier": eigenmodes[i, j] = modes[:, :n_eig] else: eigenmodes[i, j] = sim.get_modes(range(n_eig)) .. GENERATED FROM PYTHON SOURCE LINES 145-146 Compute Berry curvature and Chern number .. GENERATED FROM PYTHON SOURCE LINES 146-172 .. code-block:: Python for imode in range(n_eig): mode = ( eigenmodes[:, :, :, imode] if method == "fourier" else eigenmodes[:, :, :, :, imode] ) phi = sim.get_berry_curvature(kx, ky, mode, method=method) C = sim.get_chern_number(kx, ky, phi) print(f"Mode {imode+1}: Chern number = {C}") plt.figure() plt.pcolormesh(kx, ky, phi) plt.axis("scaled") plt.xticks([0, pi / a, 2 * pi / a], ["0", r"$\pi/a$", r"$2\pi/a$"]) plt.yticks([0, pi / a, 2 * pi / a], ["0", r"$\pi/a$", r"$2\pi/a$"]) plt.title(f"Berry curvature, mode {imode+1}, C={C:.0f}") plt.colorbar() plt.tight_layout() plt.pause(0.001) t += time.time() print(f"Elapsed time: {t:.1f}s") .. rst-class:: sphx-glr-horizontal * .. image-sg:: /examples/images/sphx_glr_plot_chern_003.png :alt: Berry curvature, mode 1, C=-0 :srcset: /examples/images/sphx_glr_plot_chern_003.png :class: sphx-glr-multi-img * .. image-sg:: /examples/images/sphx_glr_plot_chern_004.png :alt: Berry curvature, mode 2, C=-1 :srcset: /examples/images/sphx_glr_plot_chern_004.png :class: sphx-glr-multi-img * .. image-sg:: /examples/images/sphx_glr_plot_chern_005.png :alt: Berry curvature, mode 3, C=2 :srcset: /examples/images/sphx_glr_plot_chern_005.png :class: sphx-glr-multi-img .. rst-class:: sphx-glr-script-out .. code-block:: none Mode 1: Chern number = -0.00026902036635345996 Mode 2: Chern number = -0.9996736875242193 Mode 3: Chern number = 1.9738567117040693 Elapsed time: 67.0s .. GENERATED FROM PYTHON SOURCE LINES 173-174 Same but with reduced Bloch mode expansion .. GENERATED FROM PYTHON SOURCE LINES 174-221 .. code-block:: Python t = -time.time() U = (0, 2 * pi / a) V = (2 * pi / a, 0) W = (2 * pi / a, 2 * pi / a) Y = (0, pi / a) Z = (2 * pi / a, pi / a) Q = (pi / a, 2 * pi / a) RBME_points = [Gamma, X, M, Y] # ,U, V, W, Z, Q] N_RBME = 8 R = sim.get_rbme_matrix(N_RBME, RBME_points, polarization) Nred = N_RBME * len(RBME_points) eigenmodes_rbme = bk.empty((nk, nk, Nred, n_eig), dtype=bk.complex128) for i in range(nk): _mode = [] for j in range(nk): k = kx[i], ky[j] sim.k = k eigs, modes = sim.solve(polarization, rbme=R, reduced=True) eigenmodes_rbme[i, j] = modes[:, :n_eig] for imode in range(n_eig): phi = sim.get_berry_curvature( kx, ky, eigenmodes_rbme[:, :, :, imode], method="rbme" ) C = sim.get_chern_number(kx, ky, phi) print(f"Mode {imode+1}: Chern number = {C}") plt.figure() plt.pcolormesh(kx, ky, phi) plt.axis("scaled") plt.xticks([0, pi / a, 2 * pi / a], ["0", r"$\pi/a$", r"$2\pi/a$"]) plt.yticks([0, pi / a, 2 * pi / a], ["0", r"$\pi/a$", r"$2\pi/a$"]) plt.title(f"Berry curvature, mode {imode+1}, C={C:.0f}") plt.colorbar() plt.tight_layout() plt.pause(0.001) t += time.time() print(f"Elapsed time RBME: {t:.1f}s") .. rst-class:: sphx-glr-horizontal * .. image-sg:: /examples/images/sphx_glr_plot_chern_006.png :alt: Berry curvature, mode 1, C=-0 :srcset: /examples/images/sphx_glr_plot_chern_006.png :class: sphx-glr-multi-img * .. image-sg:: /examples/images/sphx_glr_plot_chern_007.png :alt: Berry curvature, mode 2, C=-1 :srcset: /examples/images/sphx_glr_plot_chern_007.png :class: sphx-glr-multi-img * .. image-sg:: /examples/images/sphx_glr_plot_chern_008.png :alt: Berry curvature, mode 3, C=2 :srcset: /examples/images/sphx_glr_plot_chern_008.png :class: sphx-glr-multi-img .. rst-class:: sphx-glr-script-out .. code-block:: none Mode 1: Chern number = -0.00025461078356810477 Mode 2: Chern number = -0.9989436451252299 Mode 3: Chern number = 1.9665374534479194 Elapsed time RBME: 26.3s .. rst-class:: sphx-glr-timing **Total running time of the script:** (1 minutes 43.132 seconds) **Estimated memory usage:** 104 MB .. _sphx_glr_download_examples_plot_chern.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/protis/protis.gitlab.io/doc?filepath=notebooks/examples/plot_chern.ipynb :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_chern.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_chern.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_