{ "cells": [ { "cell_type": "markdown", "id": "intro", "metadata": {}, "source": [ "# Two-Level: Odd-π Sech Pulses — Area Theorem\n", "\n", "The McCall–Hahn area theorem governs how the pulse area\n", "$\\mathcal{A}(z) = \\int_{-\\infty}^{\\infty} \\Omega(z,t)\\,dt$\n", "evolves as a pulse propagates through a resonant two-level absorber.\n", "For a purely absorbing medium the area satisfies\n", "\n", "$$\n", "\\frac{d\\mathcal{A}}{dz} = -\\frac{\\alpha}{2}\\sin\\mathcal{A},\n", "$$\n", "\n", "where $\\alpha$ is the resonant absorption coefficient.\n", "The stable fixed points are even multiples of $\\pi$ (including zero);\n", "odd multiples of $\\pi$ are **unstable** saddle points.\n", "\n", "| Input area | Fate |\n", "|---|---|\n", "| $1\\pi$ | absorbed toward $0\\pi$ |\n", "| $3\\pi$ | breaks into one $2\\pi$ soliton (residual $1\\pi$ absorbed) |\n", "| $5\\pi$ | breaks into two $2\\pi$ solitons (residual $1\\pi$ absorbed) |\n", "\n", "This notebook demonstrates all three cases using identical sech-pulse\n", "envelopes that differ only in their initial area." ] }, { "cell_type": "markdown", "id": "setup", "metadata": {}, "source": [ "## Parameters\n", "\n", "The sech pulse $\\Omega(t) = \\Omega_0\\,\\text{sech}(t/t_w)$ has pulse area\n", "$\\mathcal{A} = \\pi\\,\\Omega_0\\,t_w$.\n", "Setting `n_pi` in the JSON config scales $\\Omega_0$ so that the area is\n", "exactly $n\\pi$ at $z = z_\\mathrm{min}$.\n", "\n", "The medium optical depth is set by `interaction_strengths`. Here we use\n", "$C = 10$ (optically thick) so that the soliton structure is pronounced." ] }, { "cell_type": "code", "execution_count": null, "id": "imports", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from maxwellbloch import mb_solve, plot\n", "\n", "SECH_FWHM_CONV = 1.0 / 2.6339157938\n", "t_width = 1.0 * SECH_FWHM_CONV # sech width in γ⁻¹\n", "print(f\"t_width = {t_width:.4f} γ⁻¹\")" ] }, { "cell_type": "markdown", "id": "solve-1pi", "metadata": {}, "source": [ "## 1π pulse — absorbed\n", "\n", "A pulse with area below $2\\pi$ cannot form a self-induced transparency\n", "soliton. The area decays monotonically to zero: the pulse is absorbed\n", "by the medium." ] }, { "cell_type": "code", "execution_count": null, "id": "json-1pi", "metadata": {}, "outputs": [], "source": [ "mb_solve_json_1pi = \"\"\"\n", "{\n", " \"atom\": {\n", " \"fields\": [\n", " {\n", " \"coupled_levels\": [[0, 1]],\n", " \"rabi_freq_t_args\": {\"n_pi\": 1.0, \"centre\": 0.0, \"width\": %f},\n", " \"rabi_freq_t_func\": \"sech\"\n", " }\n", " ],\n", " \"num_states\": 2\n", " },\n", " \"t_min\": -2.0,\n", " \"t_max\": 10.0,\n", " \"t_steps\": 240,\n", " \"z_min\": -0.5,\n", " \"z_max\": 1.5,\n", " \"z_steps\": 100,\n", " \"interaction_strengths\": [10.0],\n", " \"savefile\": \"mbs-two-sech-1pi\"\n", "}\n", "\"\"\" % t_width\n", "\n", "mbs_1pi = mb_solve.MBSolve().from_json_str(mb_solve_json_1pi)\n", "print(f\"Input area: {np.trapezoid(mbs_1pi.Omegas_zt[0, 0, :].real, mbs_1pi.tlist) / np.pi:.4f} π\")\n", "mbs_1pi.mbsolve(recalc=False);" ] }, { "cell_type": "code", "execution_count": null, "id": "plot-spacetime-1pi", "metadata": {}, "outputs": [], "source": [ "fig = plot.field_spacetime(mbs_1pi)\n", "fig.update_layout(title=\"|Ω(z, t)| — 1π sech pulse\")\n", "fig.show(renderer='notebook_connected')" ] }, { "cell_type": "code", "execution_count": null, "id": "plot-area-1pi", "metadata": {}, "outputs": [], "source": [ "fig = plot.pulse_area(mbs_1pi)\n", "fig.update_layout(title=\"Pulse area vs z — 1π sech (absorbed toward 0π)\")\n", "fig.show(renderer='notebook_connected')" ] }, { "cell_type": "markdown", "id": "solve-3pi", "metadata": {}, "source": [ "## 3π pulse — one 2π soliton emitted\n", "\n", "The $3\\pi$ input is an unstable fixed point of the area equation.\n", "Any perturbation (including numerical discretisation) tips it toward\n", "the nearest stable attractor. The lower $2\\pi$ attractor 'wins': the\n", "pulse emits a single SIT soliton and the residual $1\\pi$ component is\n", "absorbed." ] }, { "cell_type": "code", "execution_count": null, "id": "json-3pi", "metadata": {}, "outputs": [], "source": [ "mb_solve_json_3pi = \"\"\"\n", "{\n", " \"atom\": {\n", " \"fields\": [\n", " {\n", " \"coupled_levels\": [[0, 1]],\n", " \"rabi_freq_t_args\": {\"n_pi\": 3.0, \"centre\": 0.0, \"width\": %f},\n", " \"rabi_freq_t_func\": \"sech\"\n", " }\n", " ],\n", " \"num_states\": 2\n", " },\n", " \"t_min\": -2.0,\n", " \"t_max\": 10.0,\n", " \"t_steps\": 240,\n", " \"z_min\": -0.5,\n", " \"z_max\": 1.5,\n", " \"z_steps\": 100,\n", " \"interaction_strengths\": [10.0],\n", " \"savefile\": \"mbs-two-sech-3pi\"\n", "}\n", "\"\"\" % t_width\n", "\n", "mbs_3pi = mb_solve.MBSolve().from_json_str(mb_solve_json_3pi)\n", "print(f\"Input area: {np.trapezoid(mbs_3pi.Omegas_zt[0, 0, :].real, mbs_3pi.tlist) / np.pi:.4f} π\")\n", "mbs_3pi.mbsolve(recalc=False);" ] }, { "cell_type": "code", "execution_count": null, "id": "plot-spacetime-3pi", "metadata": {}, "outputs": [], "source": [ "fig = plot.field_spacetime(mbs_3pi)\n", "fig.update_layout(title=\"|Ω(z, t)| — 3π sech pulse\")\n", "fig.show(renderer='notebook_connected')" ] }, { "cell_type": "code", "execution_count": null, "id": "plot-area-3pi", "metadata": {}, "outputs": [], "source": [ "fig = plot.pulse_area(mbs_3pi)\n", "fig.update_layout(title=\"Pulse area vs z — 3π sech (emits one 2π soliton)\")\n", "fig.show(renderer='notebook_connected')" ] }, { "cell_type": "markdown", "id": "solve-5pi", "metadata": {}, "source": [ "## 5π pulse — two 2π solitons emitted\n", "\n", "The $5\\pi$ pulse breaks into **two** $2\\pi$ solitons. Each soliton has\n", "a different width (and therefore a different group velocity — solitons\n", "with larger area travel faster), so they separate as they propagate\n", "through the medium." ] }, { "cell_type": "code", "execution_count": null, "id": "json-5pi", "metadata": {}, "outputs": [], "source": [ "mb_solve_json_5pi = \"\"\"\n", "{\n", " \"atom\": {\n", " \"fields\": [\n", " {\n", " \"coupled_levels\": [[0, 1]],\n", " \"rabi_freq_t_args\": {\"n_pi\": 5.0, \"centre\": 0.0, \"width\": %f},\n", " \"rabi_freq_t_func\": \"sech\"\n", " }\n", " ],\n", " \"num_states\": 2\n", " },\n", " \"t_min\": -2.0,\n", " \"t_max\": 10.0,\n", " \"t_steps\": 240,\n", " \"z_min\": -0.5,\n", " \"z_max\": 1.5,\n", " \"z_steps\": 100,\n", " \"interaction_strengths\": [10.0],\n", " \"savefile\": \"mbs-two-sech-5pi\"\n", "}\n", "\"\"\" % t_width\n", "\n", "mbs_5pi = mb_solve.MBSolve().from_json_str(mb_solve_json_5pi)\n", "print(f\"Input area: {np.trapezoid(mbs_5pi.Omegas_zt[0, 0, :].real, mbs_5pi.tlist) / np.pi:.4f} π\")\n", "mbs_5pi.mbsolve(recalc=False);" ] }, { "cell_type": "code", "execution_count": null, "id": "plot-spacetime-5pi", "metadata": {}, "outputs": [], "source": [ "fig = plot.field_spacetime(mbs_5pi)\n", "fig.update_layout(title=\"|Ω(z, t)| — 5π sech pulse\")\n", "fig.show(renderer='notebook_connected')" ] }, { "cell_type": "code", "execution_count": null, "id": "plot-area-5pi", "metadata": {}, "outputs": [], "source": [ "fig = plot.pulse_area(mbs_5pi)\n", "fig.update_layout(title=\"Pulse area vs z — 5π sech (emits two 2π solitons)\")\n", "fig.show(renderer='notebook_connected')" ] }, { "cell_type": "markdown", "id": "summary", "metadata": {}, "source": [ "## Summary\n", "\n", "The area theorem is confirmed in all three cases:\n", "\n", "- **1π**: area decays monotonically to 0 — the pulse is absorbed.\n", "- **3π**: area first rises slightly as the soliton forms, then the soliton\n", " exits the medium at $2\\pi$ while the residual component is absorbed.\n", "- **5π**: two $2\\pi$ solitons are clearly visible in the space-time plot;\n", " the faster (narrower) soliton separates from the slower one, and the area\n", " converges to $4\\pi$ at the exit.\n", "\n", "The general rule: an $n\\pi$ pulse with $n$ odd exits with $(n-1)$ solitons,\n", "each carrying $2\\pi$ area.\n", "\n", "## References\n", "\n", "1. S. L. McCall and E. L. Hahn, *Self-Induced Transparency by Pulsed Coherent\n", " Light*, PRL **18**, 908 (1967). Original area theorem.\n", "2. S. L. McCall and E. L. Hahn, *Self-Induced Transparency*,\n", " Phys. Rev. **183**, 457 (1969). Full theory." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "name": "python", "version": "3.14.0" } }, "nbformat": 4, "nbformat_minor": 5 }