CODE: make other parameters scale with Ω and add real RWA and add sweep

This commit is contained in:
Valentin Boettcher 2024-05-24 21:26:28 -04:00
parent ec636c1c57
commit b0c77dab5a
4 changed files with 107 additions and 43 deletions

View file

@ -1 +0,0 @@
hiro@Lobsang.149236:1716554985

View file

@ -11,33 +11,43 @@ def transient_rabi():
params = Params(
η=0.7,
Ω=13.07,
δ=13.07 / 4,
d=13.07 / 4 * 1,
laser_detuning=0.1,
Δ=13.07 / 4 * 0.01,
Ω=13,
δ=1 / 4,
d=0.02,
laser_detuning=0,
Δ=0,
N=3,
measurement_detuning=1,
rwa=False,
)
params.laser_off_time = params.lifetimes(10)
params.laser_off_time = params.lifetimes(15)
t = time_axis(params, 50, 0.1)
solution = solve(t, params)
signal = output_signal(t, solution.y, params)
f, (_, ax) = plot_simulation_result(
make_figure(), t, signal, params, window=(params.lifetimes(10), t[-1])
make_figure(), t, signal, params, window=(params.lifetimes(15), t[-1])
)
plot_sidebands(ax, params)
# ax.set_xlim(0.73, 0.77)
f.suptitle("Transient Rabi oscillation")
def steady_rabi():
"""A steady state rabi oscillation without noise."""
params = Params(η=0.001, d=0.1, laser_detuning=0, Δ=0.05)
t = time_axis(params, lifetimes=10, resolution=1)
params = Params(
η=0.7,
Ω=13,
δ=1 / 4,
d=0.02,
laser_detuning=0,
Δ=0,
N=3,
measurement_detuning=1,
rwa=False,
)
t = time_axis(params, lifetimes=20, resolution=0.01)
solution = solve(t, params)
signal = output_signal(t, solution.y, params)
@ -53,15 +63,31 @@ def steady_rabi():
def noisy_transient_rabi():
"""A transient rabi oscillation with noise."""
params = Params(η=0.001, d=0.1, laser_detuning=0, Δ=0.05)
t = time_axis(params, 2, 1)
params = Params(
η=0.7,
Ω=13,
δ=1 / 4,
d=0.02,
laser_detuning=0,
Δ=0,
N=3,
measurement_detuning=1,
rwa=False,
)
t = time_axis(params, 20, 0.01)
params.laser_off_time = params.lifetimes(5)
solution = solve(t, params)
signal = output_signal(t, solution.y, params)
noise_strength = 0.1
noise_strength = 5
signal = add_noise(signal, noise_strength)
f, (_, ax) = plot_simulation_result(make_figure(), t, signal, params)
f, (_, ax) = plot_simulation_result(
make_figure(), t, signal, params, window=(params.laser_off_time, t[-1])
)
plot_sidebands(ax, params)
f.suptitle(f"Transient Rabi oscillation with noise strength {noise_strength}.")
@ -69,14 +95,25 @@ def noisy_transient_rabi():
def ringdown_after_rabi():
"""Demonstrates the nonstationary ringdown of the resonator after turning off the EOM and laser drive."""
off_lifetime = 4
off_lifetime = 5
laser_detuning = 0.1
params = Params(η=0.0001, d=0.01, laser_detuning=laser_detuning, Δ=0.00, N=2)
params = Params(
η=0.7,
Ω=13,
δ=1 / 4,
d=0.02,
laser_detuning=laser_detuning,
Δ=0,
N=3,
measurement_detuning=-2,
rwa=False,
)
params.laser_off_time = params.lifetimes(off_lifetime)
params.drive_off_time = params.lifetimes(off_lifetime)
t = time_axis(params, lifetimes=5, resolution=1)
t = time_axis(params, lifetimes=20, resolution=0.01)
solution = solve(t, params)
signal = output_signal(t, solution.y, params)
@ -94,11 +131,21 @@ def ringdown_after_rabi():
def sweep():
"""A transient rabi oscillation without noise."""
"""A sweep of the laser over the spectrum."""
params = Params(η=1, δ=1 / 4, d=0.0, laser_detuning=100, N=1)
t = time_axis(params, 1000, 0.001)
params.dynamic_detunting = -100, t[-1]
params = Params(
η=1,
Ω=1,
δ=1 / 4,
d=0.0,
laser_detuning=-2,
Δ=0,
N=3,
measurement_detuning=0,
rwa=False,
)
t = time_axis(params, params.lifetimes(2000), 0.1)
params.dynamic_detunting = (2 * params.δ + params.N) * params.Ω, t[-1]
solution = solve(t, params)
signal = output_signal(t, solution.y, params)

View file

@ -46,7 +46,7 @@ def plot_simulation_result(
ax3.plot(
freq,
np.unwrap(np.angle(fft) + np.pi, 2 * np.pi),
np.angle(fft),
linestyle="--",
color="C2",
alpha=0.5,
@ -63,7 +63,7 @@ def plot_sidebands(ax, params: Params):
:param ax: axis to plot on
:param params: system parameters
"""
energy = params.rabi_splitting / (2 * np.pi)
energy = params.rabi_splitting
first_sidebands = np.abs(
-(params.laser_detuning + params.measurement_detuning)
@ -71,8 +71,7 @@ def plot_sidebands(ax, params: Params):
+ params.Δ / 2
)
second_sidebands = (
params.Ω
- params.δ
params.Ω * (1 - params.δ)
- (params.laser_detuning + params.measurement_detuning)
+ np.array([1, -1]) * energy / 2
- params.Δ / 2

View file

@ -12,24 +12,26 @@ class Params:
"""Number of bath modes."""
Ω: float = 1
"""Free spectral range of the system."""
η: float = 0.1
"""Decay rate of the system."""
d: float = 0.01
"""Drive amplitude."""
Δ: float = 0.0
"""Detuning of the EOM drive."""
"""Free spectral range of the system in *frequency units*."""
δ: float = 1 / 4
"""Mode splitting."""
"""Mode splitting in units of :any:`Ω`."""
η: float = 0.1
"""Decay rate :math:`\eta/2` of the system in frequency units (no
:math:`2 \pi`)."""
d: float = 0.01
"""Drive amplitude in units of :any:`Ω`."""
Δ: float = 0.0
"""Detuning of the EOM drive in *frequency units*."""
laser_detuning: float = 0.0
"""Detuning of the laser relative to the _A_ mode."""
measurement_detuning: float = 0.0
"""Additional detuning of the measurement laser signal relative to the _A_ mode."""
laser_off_time: float | None = None
"""Time at which the laser is turned off."""
@ -41,28 +43,42 @@ class Params:
"""Whether to use the rotating wave approximation."""
dynamic_detunting: tuple[float, float] = 0, 0
"""
A tuple of the total amount and the timescale (``1/speed``) of the
detuning of the laser.
"""
def periods(self, n: float):
"""
Returns the number of periods of the system that correspond to
`n` cycles.
"""
return n / self.Ω
def lifetimes(self, n: float):
"""
Returns the number of lifetimes of the system that correspond to
`n` cycles.
"""
return n / self.η
@property
def rabi_splitting(self):
return np.sqrt(self.d**2 + self.Δ**2)
"""The Rabi splitting of the system in *frequency units*."""
return np.sqrt((self.Ω * self.d) ** 2 + self.Δ**2)
@property
def ω_eom(self):
return 2 * np.pi * (self.Ω - self.δ - self.Δ)
"""The frequency of the EOM drive as *angular frequency*."""
return 2 * np.pi * (self.Ω * (1 - self.δ) - self.Δ)
class RuntimeParams:
"""Secondary Parameters that are required to run the simulation."""
def __init__(self, params: Params):
Ωs = 2 * np.pi * np.concatenate(
[[-1 * params.δ, params.δ], np.arange(1, params.N + 1) * params.Ω]
Ωs = 2 * np.pi * params.Ω * np.concatenate(
[[-1 * params.δ, params.δ], np.arange(1, params.N + 1)]
) - 1j * np.repeat(params.η / 2, params.N + 2)
self.Ωs = Ωs
@ -103,7 +119,8 @@ def eom_drive(t, x, d, ω):
def laser_frequency(params: Params, t: np.ndarray):
base = 2 * np.pi * (params.laser_detuning + params.δ)
"""The frequency of the laser light as a function of time."""
base = 2 * np.pi * (params.laser_detuning + params.Ω * params.δ)
if params.dynamic_detunting[1] == 0:
return base
@ -123,7 +140,9 @@ def make_righthand_side(runtime_params: RuntimeParams, params: Params):
x[3:] = 0
if (params.drive_off_time is None) or (t < params.drive_off_time):
differential += eom_drive(t, x, params.d, params.ω_eom)
differential += eom_drive(
t, x, 2 * np.pi * params.Ω * params.d, params.ω_eom
)
if (params.laser_off_time is None) or (t < params.laser_off_time):
laser = np.exp(-1j * laser_frequency(params, t) * t)