Two-Level: Collision of Two 2π Pulses

[1]:
import numpy as np

SECH_FWHM_CONV = 1.0 / 2.6339157938
t_width_1 = 2.0 * SECH_FWHM_CONV  # [τ]
print("t_width", t_width_1)
# n = 2.0 # For a pulse area of nπ
# ampl_1 = n/t_width_1/(2*np.pi) # Pulse amplitude [2π Γ]
# print('ampl_1', ampl_1)

t_width_2 = 1.0 * SECH_FWHM_CONV  # [τ]
# ampl_2 = n/t_width_2/(2*np.pi)
# print('t_width_2', t_width_2)
# print('ampl_2', ampl_2)
t_width 0.7593257175145156
[2]:
mb_solve_json = """
{
  "atom": {
    "fields": [
      {
        "coupled_levels": [[0, 1]]
      }
    ],
    "num_states": 2
  },
  "t_min": -5.0,
  "t_max": 25.0,
  "t_steps": 240,
  "z_min": -0.5,
  "z_max": 1.5,
  "z_steps": 200,
  "interaction_strengths": [
    10.0
  ],
  "savefile": "mbs-two-sech-2pi-collision"
}
"""
[3]:
from maxwellbloch import mb_solve

mbs = mb_solve.MBSolve().from_json_str(mb_solve_json)
[4]:
from maxwellbloch import t_funcs

probe_field = mbs.atom.fields[0]
two_pulse_t_func = lambda t, args: t_funcs.sech(1)(t, args) + t_funcs.sech(2)(t, args)
probe_field.rabi_freq_t_func = two_pulse_t_func
probe_field.rabi_freq_t_args = {
    "n_pi_2": 2.0,
    "centre_2": 5.0,
    "width_2": t_width_2,
    "n_pi_1": 2.0,
    "centre_1": 0.0,
    "width_1": t_width_1,
}

mbs.atom.build_H_Omega()  # We have to rebuild H_Omega
mbs.init_Omegas_zt();

We’ll just check that the pulse area is what we want. Should be 4π

[5]:
print(
    "The input pulse area is {0:.4f}π".format(
        np.trapezoid(mbs.Omegas_zt[0, 0, :].real, mbs.tlist) / np.pi
    )
)
The input pulse area is 3.9982π
[6]:
import matplotlib.pyplot as plt

%matplotlib inline
import seaborn as sns

sns.set_style("darkgrid")

plt.plot(mbs.tlist, np.abs(mbs.Omegas_zt[0, 0, :]));
../_images/examples_mbs-two-sech-2pi-collision_7_0.png

Solve the Problem

[7]:
Omegas_zt, states_zt = mbs.mbsolve(recalc=False)
/home/docs/checkouts/readthedocs.org/user_builds/maxwellbloch/envs/v0.8.1/lib/python3.11/site-packages/qutip/fileio.py:253: VisibleDeprecationWarning: dtype(): align should be passed as Python or NumPy boolean but got `align=0`. Did you mean to pass a tuple to create a subarray type? (Deprecated NumPy 2.4)
  out = pickle.load(fileObject, encoding='latin1')

Plot Output

[8]:
import matplotlib.pyplot as plt

%matplotlib inline
import numpy as np
import seaborn as sns

sns.set_style("darkgrid")
fig = plt.figure(1, figsize=(16, 6))
ax = fig.add_subplot(111)
cmap_range = np.linspace(0.0, 1.0, 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$)")
for y in [0.0, 1.0]:
    ax.axhline(y, c="grey", lw=1.0, ls="dotted")
plt.colorbar(cf);
../_images/examples_mbs-two-sech-2pi-collision_11_0.png

Pulse area

[9]:
fig, ax = plt.subplots(figsize=(16, 4))
ax.plot(mbs.zlist, mbs.fields_area()[0] / np.pi, clip_on=False)
# ax.set_ylim([0.0, 4.0])
ax.set_xlabel("Distance ($L$)")
ax.set_ylabel(r"Pulse Area ($\pi$)");
../_images/examples_mbs-two-sech-2pi-collision_13_0.png

Movie

[10]:
# C = 0.1 # speed of light
# Y_MIN = 0.0 # Y-axis min
# Y_MAX = 4.0 # y-axis max
# ZOOM = 2 # level of linear interpolation
# FPS = 60 # frames per second
# ATOMS_ALPHA = 0.2 # Atom indicator transparency
[11]:
# FNAME = "images/mb-solve-two-sech-2pi-collision"
# FNAME_JSON = FNAME + '.json'
# with open(FNAME_JSON, "w") as f:
#     f.write(mb_solve_json)
[12]:
# !make-mp4-fixed-frame.py -f $FNAME_JSON -c $C --fps $FPS --y-min $Y_MIN --y-max $Y_MAX \
#     --zoom $ZOOM --atoms-alpha $ATOMS_ALPHA #--peak-line --c-line
[13]:
# FNAME_MP4 = FNAME + '.mp4'
# !make-gif-ffmpeg.sh -f $FNAME_MP4 --in-fps $FPS
[14]:
# from IPython.display import Image
# Image(url=FNAME_MP4 +'.gif', format='gif')