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

View file

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

View file

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