Hyperfine Structure: Sech Pulse 2π, q=1 — Self-Induced Transparency

Author

Thomas Ogden

\(^{87}\mathrm{Rb}\) driven on the \(5S_{1/2} F=1 \rightarrow 5p_{1/2} F=1\) transition.

import numpy as np
from clerq import hyperfine

Rb87_5s12_F1 = hyperfine.LevelF(I=1.5, J=0.5, F=1)
Rb87_5s12_F2 = hyperfine.LevelF(I=1.5, J=0.5, F=2)  # Needed for decay

Rb87_5p12_F1 = hyperfine.LevelF(I=1.5, J=0.5, F=1)

atom1e = hyperfine.Atom1e(element="Rb", isotope="87")

atom1e.add_F_level(Rb87_5s12_F1)
atom1e.add_F_level(Rb87_5s12_F2)
atom1e.add_F_level(Rb87_5p12_F1)
NUM_STATES = atom1e.get_num_mF_levels()
print(NUM_STATES)
11
ENERGIES = atom1e.get_energies()
print(ENERGIES)
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
# Tune to be on resonance with the F1 -> F1 transition
DETUNING = 0
print(DETUNING)
0
FIELD_CHANNELS = atom1e.get_coupled_levels(F_level_idxs_a=(0,), F_level_idxs_b=(2,))
print(FIELD_CHANNELS)
[[0, 8], [0, 9], [0, 10], [1, 8], [1, 9], [1, 10], [2, 8], [2, 9], [2, 10]]
q = 1  # Field polarisation
FIELD_FACTORS = atom1e.get_clebsch_hf_factors(
    F_level_idxs_a=(0,), F_level_idxs_b=(2,), q=q
)
print(FIELD_FACTORS)
[ 0.          0.          0.          0.28867513 -0.         -0.
  0.          0.28867513  0.        ]
strength_factor = np.sum(FIELD_FACTORS**2)
print(strength_factor)
0.16666666666666657

1/6 is the strength factor S_11

hf_factor = np.max(FIELD_FACTORS)
print(hf_factor)
0.2886751345948128
DECAY_CHANNELS = atom1e.get_coupled_levels(F_level_idxs_a=(0, 1), F_level_idxs_b=(2,))
print(DECAY_CHANNELS)
[[0, 8], [0, 9], [0, 10], [1, 8], [1, 9], [1, 10], [2, 8], [2, 9], [2, 10], [3, 8], [3, 9], [3, 10], [4, 8], [4, 9], [4, 10], [5, 8], [5, 9], [5, 10], [6, 8], [6, 9], [6, 10], [7, 8], [7, 9], [7, 10]]
DECAY_FACTORS = atom1e.get_decay_factors(F_level_idxs_a=(0, 1), F_level_idxs_b=(2,))
print(DECAY_FACTORS)
[ 0.28867513 -0.28867513  0.          0.28867513 -0.         -0.28867513
  0.          0.28867513 -0.28867513  0.70710678  0.          0.
  0.5         0.5        -0.          0.28867513  0.57735027  0.28867513
 -0.          0.5         0.5         0.          0.          0.70710678]
INITIAL_STATE = (
    [1.0 / 3.0] * 3  # s12_F1
    + [0.0 / 5.0] * 5  # s12_F2
    + [0.0] * 3
)  # p12_F1
print(INITIAL_STATE)
[0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
sech_fwhm_conv = 1.0 / 2.6339157938
WIDTH = 1.0 * sech_fwhm_conv  # [τ]
print("WIDTH", WIDTH)

n = 2.0  # For a pulse area of nπ
AMPL = n / WIDTH / (2 * np.pi)  # Pulse amplitude [2π Γ]

AMPL *= 1 / hf_factor

print("ampl", AMPL)
WIDTH 0.3796628587572578
ampl 2.9043077704595337
mb_solve_json = """
{{
  "atom": {{
    "decays": [
      {{
        "channels": {decay_channels},
        "rate": 0.0,
        "factors": {decay_factors}
      }}
    ],
    "energies": {energies},
    "fields": [
      {{
        "coupled_levels": {field_channels},
        "factors": {field_factors},
        "detuning": {detuning},
        "detuning_positive": true,
        "label": "probe",
        "rabi_freq": 1.0,
        "rabi_freq_t_args": {{
          "ampl": {ampl},
          "centre": 0.0,
          "width": {width}
        }},
        "rabi_freq_t_func": "sech"
      }}
    ],
    "num_states": {num_states},
    "initial_state": {initial_state}
  }},
  "t_min": -2.0,
  "t_max": 10.0,
  "t_steps": 100,
  "z_min": -0.5,
  "z_max": 1.5,
  "z_steps": 100,
  "z_steps_inner": 1,
  "num_density_z_func": "square",
  "num_density_z_args": {{
    "on": 0.0,
    "off": 1.0,
    "ampl": 1.0
  }},
  "interaction_strengths": [
    5.0e2
  ],
  "velocity_classes": null,
  "method": "mesolve",
  "opts": {{
    "method": "bdf", 
    "atol": 1e-8, 
    "rtol": 1e-6,
    "nsteps": 1e2
  }},
  "savefile": "mbs-Rb87_5s12_5p12_F11_q1-sech-2pi"
}}
""".format(
    num_states=NUM_STATES,
    energies=ENERGIES,
    initial_state=INITIAL_STATE,
    detuning=DETUNING,
    field_channels=FIELD_CHANNELS,
    field_factors=FIELD_FACTORS.tolist(),
    decay_channels=DECAY_CHANNELS,
    decay_factors=DECAY_FACTORS.tolist(),
    ampl=float(AMPL),
    width=WIDTH,
)
from clerq import mb_solve

mbs = mb_solve.MBSolve().from_json_str(mb_solve_json)
Omegas_zt, states_zt = mbs.mbsolve(recalc=True)

  0%|          | 0/100 [00:00<?, ?z/s]
  1%|          | 1/100 [00:00<00:00, 672.81z/s, Ω_max=18.1]
  2%|▏         | 2/100 [00:00<00:01, 80.39z/s, Ω_max=18.1] 
  3%|▎         | 3/100 [00:00<00:01, 64.13z/s, Ω_max=18.1]
  4%|▍         | 4/100 [00:00<00:01, 58.41z/s, Ω_max=18.1]
  5%|▌         | 5/100 [00:00<00:01, 55.18z/s, Ω_max=18.1]
  6%|▌         | 6/100 [00:00<00:01, 53.29z/s, Ω_max=18.1]
  6%|▌         | 6/100 [00:00<00:01, 53.29z/s, Ω_max=18.1]
  7%|▋         | 7/100 [00:00<00:01, 53.29z/s, Ω_max=18.1]
  8%|▊         | 8/100 [00:00<00:01, 53.29z/s, Ω_max=18.1]
  9%|▉         | 9/100 [00:00<00:01, 53.29z/s, Ω_max=18.1]
 10%|█         | 10/100 [00:00<00:01, 53.29z/s, Ω_max=18.1]
 11%|█         | 11/100 [00:00<00:01, 53.29z/s, Ω_max=18.1]
 12%|█▏        | 12/100 [00:00<00:01, 45.64z/s, Ω_max=18.1]
 12%|█▏        | 12/100 [00:00<00:01, 45.64z/s, Ω_max=18.1]
 13%|█▎        | 13/100 [00:00<00:01, 45.64z/s, Ω_max=18.1]
 14%|█▍        | 14/100 [00:00<00:01, 45.64z/s, Ω_max=18.1]
 15%|█▌        | 15/100 [00:00<00:01, 45.64z/s, Ω_max=18.1]
 16%|█▌        | 16/100 [00:00<00:01, 45.64z/s, Ω_max=18.1]
 17%|█▋        | 17/100 [00:00<00:01, 45.57z/s, Ω_max=18.1]
 17%|█▋        | 17/100 [00:00<00:01, 45.57z/s, Ω_max=18.1]
 18%|█▊        | 18/100 [00:00<00:01, 45.57z/s, Ω_max=18.1]
 19%|█▉        | 19/100 [00:00<00:01, 45.57z/s, Ω_max=18.1]
 20%|██        | 20/100 [00:00<00:01, 45.57z/s, Ω_max=18.1]
 21%|██        | 21/100 [00:00<00:01, 45.57z/s, Ω_max=18.1]
 22%|██▏       | 22/100 [00:00<00:01, 45.60z/s, Ω_max=18.1]
 22%|██▏       | 22/100 [00:00<00:01, 45.60z/s, Ω_max=18.1]
 23%|██▎       | 23/100 [00:00<00:01, 45.60z/s, Ω_max=18.1]
 24%|██▍       | 24/100 [00:00<00:01, 45.60z/s, Ω_max=18.1]
 25%|██▌       | 25/100 [00:00<00:01, 45.60z/s, Ω_max=19.2]
 26%|██▌       | 26/100 [00:00<00:01, 45.60z/s, Ω_max=19.6]
 27%|██▋       | 27/100 [00:00<00:01, 44.02z/s, Ω_max=19.6]
 27%|██▋       | 27/100 [00:00<00:01, 44.02z/s, Ω_max=19.8]
 28%|██▊       | 28/100 [00:00<00:01, 44.02z/s, Ω_max=19.9]
 29%|██▉       | 29/100 [00:00<00:01, 44.02z/s, Ω_max=19.9]
 30%|███       | 30/100 [00:00<00:01, 44.02z/s, Ω_max=19.8]
 31%|███       | 31/100 [00:00<00:01, 44.02z/s, Ω_max=19.7]
 32%|███▏      | 32/100 [00:00<00:01, 42.17z/s, Ω_max=19.7]
 32%|███▏      | 32/100 [00:00<00:01, 42.17z/s, Ω_max=19.8]
 33%|███▎      | 33/100 [00:00<00:01, 42.17z/s, Ω_max=20]  
 34%|███▍      | 34/100 [00:00<00:01, 42.17z/s, Ω_max=20.2]
 35%|███▌      | 35/100 [00:00<00:01, 42.17z/s, Ω_max=20.3]
 36%|███▌      | 36/100 [00:00<00:01, 42.17z/s, Ω_max=20.4]
 37%|███▋      | 37/100 [00:00<00:01, 40.32z/s, Ω_max=20.4]
 37%|███▋      | 37/100 [00:00<00:01, 40.32z/s, Ω_max=20.5]
 38%|███▊      | 38/100 [00:00<00:01, 40.32z/s, Ω_max=20.6]
 39%|███▉      | 39/100 [00:00<00:01, 40.32z/s, Ω_max=20.6]
 40%|████      | 40/100 [00:00<00:01, 40.32z/s, Ω_max=20.6]
 41%|████      | 41/100 [00:00<00:01, 40.32z/s, Ω_max=20.7]
 42%|████▏     | 42/100 [00:01<00:01, 38.04z/s, Ω_max=20.7]
 42%|████▏     | 42/100 [00:01<00:01, 38.04z/s, Ω_max=20.7]
 43%|████▎     | 43/100 [00:01<00:01, 38.04z/s, Ω_max=20.8]
 44%|████▍     | 44/100 [00:01<00:01, 38.04z/s, Ω_max=20.9]
 45%|████▌     | 45/100 [00:01<00:01, 38.04z/s, Ω_max=21]  
 46%|████▌     | 46/100 [00:01<00:01, 37.15z/s, Ω_max=21]
 46%|████▌     | 46/100 [00:01<00:01, 37.15z/s, Ω_max=21]
 47%|████▋     | 47/100 [00:01<00:01, 37.15z/s, Ω_max=21.1]
 48%|████▊     | 48/100 [00:01<00:01, 37.15z/s, Ω_max=21.1]
 49%|████▉     | 49/100 [00:01<00:01, 37.15z/s, Ω_max=21.2]
 50%|█████     | 50/100 [00:01<00:01, 35.56z/s, Ω_max=21.2]
 50%|█████     | 50/100 [00:01<00:01, 35.56z/s, Ω_max=21.3]
 51%|█████     | 51/100 [00:01<00:01, 35.56z/s, Ω_max=21.4]
 52%|█████▏    | 52/100 [00:01<00:01, 35.56z/s, Ω_max=21.4]
 53%|█████▎    | 53/100 [00:01<00:01, 35.56z/s, Ω_max=21.5]
 54%|█████▍    | 54/100 [00:01<00:01, 35.00z/s, Ω_max=21.5]
 54%|█████▍    | 54/100 [00:01<00:01, 35.00z/s, Ω_max=21.6]
 55%|█████▌    | 55/100 [00:01<00:01, 35.00z/s, Ω_max=21.6]
 56%|█████▌    | 56/100 [00:01<00:01, 35.00z/s, Ω_max=21.6]
 57%|█████▋    | 57/100 [00:01<00:01, 35.00z/s, Ω_max=21.6]
 58%|█████▊    | 58/100 [00:01<00:01, 33.56z/s, Ω_max=21.6]
 58%|█████▊    | 58/100 [00:01<00:01, 33.56z/s, Ω_max=21.6]
 59%|█████▉    | 59/100 [00:01<00:01, 33.56z/s, Ω_max=21.6]
 60%|██████    | 60/100 [00:01<00:01, 33.56z/s, Ω_max=21.5]
 61%|██████    | 61/100 [00:01<00:01, 33.56z/s, Ω_max=21.6]
 62%|██████▏   | 62/100 [00:01<00:01, 33.42z/s, Ω_max=21.6]
 62%|██████▏   | 62/100 [00:01<00:01, 33.42z/s, Ω_max=21.8]
 63%|██████▎   | 63/100 [00:01<00:01, 33.42z/s, Ω_max=22]  
 64%|██████▍   | 64/100 [00:01<00:01, 33.42z/s, Ω_max=22.1]
 65%|██████▌   | 65/100 [00:01<00:01, 33.42z/s, Ω_max=22.2]
 66%|██████▌   | 66/100 [00:01<00:01, 33.31z/s, Ω_max=22.2]
 66%|██████▌   | 66/100 [00:01<00:01, 33.31z/s, Ω_max=22.2]
 67%|██████▋   | 67/100 [00:01<00:00, 33.31z/s, Ω_max=22.2]
 68%|██████▊   | 68/100 [00:01<00:00, 33.31z/s, Ω_max=22.1]
 69%|██████▉   | 69/100 [00:01<00:00, 33.31z/s, Ω_max=22]  
 70%|███████   | 70/100 [00:01<00:00, 32.68z/s, Ω_max=22]
 70%|███████   | 70/100 [00:01<00:00, 32.68z/s, Ω_max=22.2]
 71%|███████   | 71/100 [00:01<00:00, 32.68z/s, Ω_max=22.4]
 72%|███████▏  | 72/100 [00:01<00:00, 32.68z/s, Ω_max=22.5]
 73%|███████▎  | 73/100 [00:01<00:00, 32.68z/s, Ω_max=22.6]
 74%|███████▍  | 74/100 [00:01<00:00, 32.77z/s, Ω_max=22.6]
 74%|███████▍  | 74/100 [00:01<00:00, 32.77z/s, Ω_max=22.6]
 75%|███████▌  | 75/100 [00:02<00:00, 32.77z/s, Ω_max=22.5]
 76%|███████▌  | 76/100 [00:02<00:00, 32.77z/s, Ω_max=22.5]
 77%|███████▋  | 77/100 [00:02<00:00, 32.77z/s, Ω_max=22.5]
 78%|███████▊  | 78/100 [00:02<00:00, 32.05z/s, Ω_max=22.5]
 78%|███████▊  | 78/100 [00:02<00:00, 32.05z/s, Ω_max=22.5]
 79%|███████▉  | 79/100 [00:02<00:00, 32.05z/s, Ω_max=22.5]
 80%|████████  | 80/100 [00:02<00:00, 32.05z/s, Ω_max=22.5]
 81%|████████  | 81/100 [00:02<00:00, 32.05z/s, Ω_max=22.5]
 82%|████████▏ | 82/100 [00:02<00:00, 32.44z/s, Ω_max=22.5]
 82%|████████▏ | 82/100 [00:02<00:00, 32.44z/s, Ω_max=22.5]
 83%|████████▎ | 83/100 [00:02<00:00, 32.44z/s, Ω_max=22.5]
 84%|████████▍ | 84/100 [00:02<00:00, 32.44z/s, Ω_max=22.5]
 85%|████████▌ | 85/100 [00:02<00:00, 32.44z/s, Ω_max=22.5]
 86%|████████▌ | 86/100 [00:02<00:00, 31.87z/s, Ω_max=22.5]
 86%|████████▌ | 86/100 [00:02<00:00, 31.87z/s, Ω_max=22.5]
 87%|████████▋ | 87/100 [00:02<00:00, 31.87z/s, Ω_max=22.5]
 88%|████████▊ | 88/100 [00:02<00:00, 31.87z/s, Ω_max=22.5]
 89%|████████▉ | 89/100 [00:02<00:00, 31.87z/s, Ω_max=22.5]
 90%|█████████ | 90/100 [00:02<00:00, 32.39z/s, Ω_max=22.5]
 90%|█████████ | 90/100 [00:02<00:00, 32.39z/s, Ω_max=22.5]
 91%|█████████ | 91/100 [00:02<00:00, 32.39z/s, Ω_max=22.5]
 92%|█████████▏| 92/100 [00:02<00:00, 32.39z/s, Ω_max=22.5]
 93%|█████████▎| 93/100 [00:02<00:00, 32.39z/s, Ω_max=22.5]
 94%|█████████▍| 94/100 [00:02<00:00, 32.81z/s, Ω_max=22.5]
 94%|█████████▍| 94/100 [00:02<00:00, 32.81z/s, Ω_max=22.5]
 95%|█████████▌| 95/100 [00:02<00:00, 32.81z/s, Ω_max=22.5]
 96%|█████████▌| 96/100 [00:02<00:00, 32.81z/s, Ω_max=22.5]
 97%|█████████▋| 97/100 [00:02<00:00, 32.81z/s, Ω_max=22.5]
 98%|█████████▊| 98/100 [00:02<00:00, 32.28z/s, Ω_max=22.5]
 98%|█████████▊| 98/100 [00:02<00:00, 32.28z/s, Ω_max=22.5]
 99%|█████████▉| 99/100 [00:02<00:00, 32.28z/s, Ω_max=22.5]
100%|██████████| 100/100 [00:02<00:00, 32.28z/s, Ω_max=22.5]
100%|██████████| 100/100 [00:02<00:00, 35.73z/s, Ω_max=22.5]
Saving MBSolve to mbs-Rb87_5s12_5p12_F11_q1-sech-2pi.qu
import matplotlib.pyplot as plt

%matplotlib inline
import seaborn as sns

sns.set_style("darkgrid")

import numpy as np
fig = plt.figure(1, figsize=(16, 6))
ax = fig.add_subplot(111)
# cmap_range = np.linspace(0.0, 12, 11)
cf = ax.contourf(
    mbs.tlist,
    mbs.zlist,
    np.abs(mbs.Omegas_zt[0] / (2 * np.pi)),
    #                  cmap_range,
    cmap=plt.cm.Blues,
)
ax.set_title(r"Rabi Frequency ($\Gamma / 2\pi $)")
ax.set_xlabel(r"Time ($1/\Gamma$)")
ax.set_ylabel("Distance ($L$)")
ax.grid(alpha=0.5)
ax.set_axisbelow(False)
for y in [0.0, 1.0]:
    ax.axhline(y, c="grey", lw=1.0, ls="dotted")
plt.colorbar(cf);

fig = plt.figure(1, figsize=(16, 6))
ax = fig.add_subplot(111)
# cmap_range = np.linspace(0.0, 1.0e-3, 11)
cf = ax.contourf(
    mbs.tlist,
    mbs.zlist,
    np.abs(mbs.populations_field(0, upper=False)),
    #                  cmap_range,
    cmap=plt.cm.Reds,
)
ax.set_title(r"Rabi Frequency ($\Gamma / 2\pi $)")
ax.set_xlabel(r"Time ($1/\Gamma$)")
ax.set_ylabel("Distance ($L$)")
for y in [0.0, 1.0]:
    ax.axhline(y, c="grey", lw=1.0, ls="dotted")
plt.colorbar(cf);

fig = plt.figure(1, figsize=(16, 6))
ax = fig.add_subplot(111)
# cmap_range = np.linspace(0.0, 1.0e-3, 11)
cf = ax.contourf(
    mbs.tlist,
    mbs.zlist,
    np.imag(mbs.coherences_field(0)),
    #                  cmap_range,
    cmap=plt.cm.Greens,
)
ax.set_title(r"Rabi Frequency ($\Gamma / 2\pi $)")
ax.set_xlabel(r"Time ($1/\Gamma$)")
ax.set_ylabel("Distance ($L$)")
for y in [0.0, 1.0]:
    ax.axhline(y, c="grey", lw=1.0, ls="dotted")
plt.colorbar(cf);