.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/relativity/schwarzschild/plot_light_bending_and_shadow.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_relativity_schwarzschild_plot_light_bending_and_shadow.py: Light bending, the photon sphere, and the black hole shadow ================================================================== Starlight grazing the Sun is deflected by :math:`\delta\phi \approx 4M/b` -- twice the (wrong) Newtonian prediction -- confirmed by Eddington's 1919 solar eclipse expedition and the observation that made Einstein a household name overnight. Push the impact parameter down toward the critical value :math:`b_c = 3\sqrt{3}M` and deflection diverges: photons can orbit (unstably) forever at the photon sphere :math:`r=3M`, and anything with :math:`b < b_c` is captured. This example traces individual light rays at a range of impact parameters, then renders the full 2D shadow silhouette by ray-tracing an entire camera image -- the calculation behind the 2019 Event Horizon Telescope image of M87*. .. GENERATED FROM PYTHON SOURCE LINES 16-23 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from physicskit.relativity.chapters.schwarzschild import SchwarzschildBlackHole from physicskit.relativity.visualizers.shadow_render import plot_black_hole_shadow, render_black_hole_image .. GENERATED FROM PYTHON SOURCE LINES 24-26 Individual light rays at a range of impact parameters ------------------------------------------------------------ .. GENERATED FROM PYTHON SOURCE LINES 26-46 .. code-block:: Python bh = SchwarzschildBlackHole(M=1.0) fig, ax = plt.subplots(figsize=(6, 6)) for b in [4.0, 5.0, bh.critical_impact_parameter, 6.0, 10.0, 20.0]: y0 = bh.null_geodesic_initial_state(r0=200.0, impact_parameter=b, ingoing=True) traj = bh.integrate_geodesic(y0, dtau=0.05, n_steps=20000) x = traj["r"] * np.cos(traj["phi"]) y = traj["r"] * np.sin(traj["phi"]) label = f"b={b:.2f}M" + (" (critical)" if np.isclose(b, bh.critical_impact_parameter) else "") ax.plot(x, y, linewidth=1, label=label) circle = plt.Circle((0, 0), bh.horizon_radius, color="black", zorder=5) ax.add_patch(circle) ax.set_xlim(-25, 25) ax.set_ylim(-25, 25) ax.set_aspect("equal") ax.set_xlabel("x [M]") ax.set_ylabel("y [M]") ax.set_title("Photon trajectories near a Schwarzschild black hole") ax.legend(fontsize=8, loc="upper right") plt.tight_layout() .. image-sg:: /api/gallery/relativity/schwarzschild/images/sphx_glr_plot_light_bending_and_shadow_001.png :alt: Photon trajectories near a Schwarzschild black hole :srcset: /api/gallery/relativity/schwarzschild/images/sphx_glr_plot_light_bending_and_shadow_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 47-49 Light deflection versus the weak-field 4M/b formula ------------------------------------------------------------ .. GENERATED FROM PYTHON SOURCE LINES 49-65 .. code-block:: Python impact_params = np.linspace(10.0, 100.0, 12) measured = [] for b in impact_params: y0 = bh.null_geodesic_initial_state(r0=2.0e5, impact_parameter=b, ingoing=True) traj = bh.integrate_geodesic(y0, dtau=2.0, n_steps=300000) measured.append((traj["phi"][-1] - traj["phi"][0]) - np.pi) fig, ax = plt.subplots(figsize=(6, 4.5)) ax.plot(impact_params, measured, "o", label="exact (geodesic integration)") ax.plot(impact_params, bh.light_deflection_angle(impact_params), "--", label="weak field, $4M/b$") ax.set_xlabel("impact parameter b [M]") ax.set_ylabel("deflection angle [rad]") ax.set_title("Gravitational light deflection") ax.legend() plt.tight_layout() .. image-sg:: /api/gallery/relativity/schwarzschild/images/sphx_glr_plot_light_bending_and_shadow_002.png :alt: Gravitational light deflection :srcset: /api/gallery/relativity/schwarzschild/images/sphx_glr_plot_light_bending_and_shadow_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 66-68 The black hole shadow: ray-tracing a full camera image ------------------------------------------------------------ .. GENERATED FROM PYTHON SOURCE LINES 68-73 .. code-block:: Python result = render_black_hole_image(M=1.0, ny=250, nx=250, inclination=1.3) fig, ax = plt.subplots(figsize=(7, 7)) plot_black_hole_shadow(result, ax=ax) plt.tight_layout() plt.show() .. image-sg:: /api/gallery/relativity/schwarzschild/images/sphx_glr_plot_light_bending_and_shadow_003.png :alt: Black hole shadow and gravitationally lensed accretion disk :srcset: /api/gallery/relativity/schwarzschild/images/sphx_glr_plot_light_bending_and_shadow_003.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.573 seconds) .. _sphx_glr_download_api_gallery_relativity_schwarzschild_plot_light_bending_and_shadow.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_light_bending_and_shadow.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_light_bending_and_shadow.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_light_bending_and_shadow.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_