Time-Varying Coupling¶
Comprehensive guide to dynamic coupling protocols using all available variant types.
Note
For theoretical background on time-varying coupling, see Time-Varying Coupling.
Overview¶
Cavity HOOMD provides a complete variant system for time-dependent coupling protocols, enabling sophisticated non-equilibrium experiments and realistic modeling of pump-probe dynamics.
Available Variant Types:
Basic Variants: ConstantVariant, StepVariant
Periodic Variants: PeriodicVariant, SquareWaveVariant
Decay Variants: ExponentialDecayVariant, DecayingSquareWaveVariant
Adaptive Variants: AdaptiveSquareWaveVariant, ExponentialWaveVariant
Scaling Variants: LambdaScaledVariant
Why Use Time-Varying Coupling?¶
Model pump-probe experiments
Study non-equilibrium relaxation dynamics
Investigate sudden coupling activation/deactivation
Analyze energy redistribution and thermalization
Simulate realistic experimental protocols
Control system temperature via coupling modulation
Basic Variants¶
ConstantVariant¶
Fixed coupling throughout simulation:
from cavitymd.variants import ConstantVariant
from cavitymd.forces import CavityForce
# Constant coupling
coupling = ConstantVariant(value=0.001)
cavity_force = CavityForce(
kvector=[0, 0, 1],
couplstr=coupling,
omegac=omega_c,
phmass=1.0
)
Use when: Standard equilibrium simulations with fixed coupling.
StepVariant¶
Instantaneous switch at specified time:
from cavitymd.variants import StepVariant
# Switch coupling at t = 10 ps
coupling = StepVariant(
target_value=0.001,
switch_time_ps=10.0,
time_tracker=time_tracker
)
Protocol:
Command-line usage:
python examples/05_advanced_run.py \
--coupling 1e-3 \
--switch-time 10.0 \
--runtime 500
Applications: - Pump-probe simulations - Sudden quench experiments - Coupling activation studies
Periodic Variants¶
PeriodicVariant¶
Sinusoidal modulation:
from cavitymd.variants import PeriodicVariant
# Sine wave modulation
coupling = PeriodicVariant(
amplitude=0.001,
frequency_hz=1e12, # 1 THz
phase=0.0, # Initial phase
offset=0.0005, # DC offset
time_tracker=time_tracker
)
Protocol:
Parameters:
- amplitude: Oscillation amplitude
- frequency_hz: Modulation frequency (Hz)
- phase: Initial phase (radians)
- offset: DC offset (mean coupling)
Applications: - AC-driven cavity coupling - Frequency response analysis - Floquet engineering
Example - Temperature control via modulation:
# Modulate coupling to control heating/cooling
coupling = PeriodicVariant(
amplitude=0.0005,
frequency_hz=5e11, # 0.5 THz
offset=0.001,
time_tracker=time_tracker
)
SquareWaveVariant¶
Square wave modulation with controllable duty cycle:
from cavitymd.variants import SquareWaveVariant
# Square wave coupling
coupling = SquareWaveVariant(
amplitude=0.001,
frequency_hz=1e12, # 1 THz period
duty_cycle=0.5, # 50% on, 50% off
phase_offset=0.0,
time_tracker=time_tracker
)
Protocol:
where \(T = 1/f\) and \(d\) is duty cycle.
Parameters:
- amplitude: Coupling when “on”
- frequency_hz: Switching frequency
- duty_cycle: Fraction of period with coupling ON (0-1)
- phase_offset: Phase shift
Applications: - Pulsed coupling experiments - Intermittent cavity exposure - Duty-cycle-dependent heating studies
Example - Pulsed protocol:
# 10% duty cycle: short pulses
coupling = SquareWaveVariant(
amplitude=0.01, # Strong when on
frequency_hz=1e12,
duty_cycle=0.1, # On 10% of time
time_tracker=time_tracker
)
Decay Variants¶
ExponentialDecayVariant¶
Exponential decay from initial to final value:
from cavitymd.variants import ExponentialDecayVariant
# Exponentially decaying coupling
coupling = ExponentialDecayVariant(
initial_value=0.01, # Strong initial coupling
final_value=0.001, # Weak final coupling
decay_constant_ps=20.0, # Time constant
start_time_ps=10.0, # Start decay
time_tracker=time_tracker
)
Protocol:
Parameters:
- initial_value: Starting coupling
- final_value: Asymptotic coupling
- decay_constant_ps: Time constant τ
- start_time_ps: When decay begins
Applications: - Gradual coupling reduction - Adiabatic switching - Cooling protocols
Example - Adiabatic turn-off:
# Slowly reduce coupling to final state
coupling = ExponentialDecayVariant(
initial_value=0.005,
final_value=0.0, # Turn off completely
decay_constant_ps=50.0, # Slow decay
start_time_ps=100.0,
time_tracker=time_tracker
)
DecayingSquareWaveVariant¶
Square wave with exponentially decaying amplitude:
from cavitymd.variants import DecayingSquareWaveVariant
# Decaying pulsed coupling
coupling = DecayingSquareWaveVariant(
initial_amplitude=0.01,
final_amplitude=0.001,
frequency_hz=1e12,
duty_cycle=0.5,
decay_constant_ps=30.0,
start_time_ps=10.0,
time_tracker=time_tracker
)
Protocol:
Applications: - Decaying pulse trains - Realistic laser pulse sequences - Progressive weakening of modulation
Adaptive Variants¶
AdaptiveSquareWaveVariant¶
Square wave with temperature-dependent amplitude:
from cavitymd.variants import AdaptiveSquareWaveVariant
# Temperature-adaptive coupling
coupling = AdaptiveSquareWaveVariant(
base_amplitude=0.001,
frequency_hz=1e12,
duty_cycle=0.5,
temperature_tracker=temp_tracker,
target_temperature=100.0,
adaptation_gain=0.1, # Feedback strength
time_tracker=time_tracker
)
Protocol:
Square wave amplitude adapts based on temperature error.
Parameters:
- base_amplitude: Nominal amplitude
- target_temperature: Desired temperature
- adaptation_gain: Feedback strength K
- temperature_tracker: Source of T(t)
Applications: - Automatic temperature control - Self-regulating systems - Adaptive heating/cooling
Example - Temperature stabilization:
# Coupling increases when cold, decreases when hot
coupling = AdaptiveSquareWaveVariant(
base_amplitude=0.001,
target_temperature=100.0,
adaptation_gain=0.2, # Strong feedback
temperature_tracker=temp_tracker,
time_tracker=time_tracker
)
ExponentialWaveVariant¶
Exponential modulation patterns:
from cavitymd.variants import ExponentialWaveVariant
# Exponentially modulated coupling
coupling = ExponentialWaveVariant(
amplitude=0.001,
growth_rate=0.1, # Growth/decay rate
frequency_hz=1e12,
time_tracker=time_tracker
)
Protocol:
Applications: - Growing/decaying oscillations - Chirped pulses - Exponentially ramped protocols
Scaling Variants¶
LambdaScaledVariant¶
Automatic scaling by cavity frequency for physical units:
from cavitymd.variants import LambdaScaledVariant
# Lambda coupling (dimensionless)
lambda_variant = StepVariant(target_value=0.05, switch_time_ps=10.0, time_tracker=time_tracker)
# Automatically scaled: epsilon = lambda * omega_c
coupling = LambdaScaledVariant(
lambda_variant=lambda_variant,
omega_c=omega_cavity # In atomic units
)
cavity_force = CavityForce(
kvector=[0, 0, 1],
couplstr=coupling, # Uses scaled value
omegac=omega_c,
phmass=1.0
)
Purpose: Maintain physical meaning when changing cavity frequency.
Relation:
where λ is dimensionless coupling strength.
Composite Variants¶
Combine Multiple Protocols¶
Sequential composition:
from cavitymd import CompositeVariant
from cavitymd.variants import StepVariant, ExponentialDecayVariant
# Phase 1: Step up
step_up = StepVariant(target_value=0.01, switch_time_ps=10.0, time_tracker=time_tracker)
# Phase 2: Decay down
decay = ExponentialDecayVariant(
initial_value=0.01,
final_value=0.001,
decay_constant_ps=20.0,
start_time_ps=50.0,
time_tracker=time_tracker
)
# Combine
coupling = CompositeVariant(
variants=[step_up, decay],
transition_times=[10.0, 50.0]
)
Weighted combination:
# Superpose two frequencies
coupling1 = PeriodicVariant(amplitude=0.0005, frequency_hz=1e12, time_tracker=time_tracker)
coupling2 = PeriodicVariant(amplitude=0.0003, frequency_hz=2e12, time_tracker=time_tracker)
coupling = CompositeVariant(
variants=[coupling1, coupling2],
weights=[1.0, 1.0], # Equal weight
operation='add'
)
Practical Examples¶
Example 1: Pump-Probe Simulation¶
Protocol: Strong pulse, then weak coupling
from cavitymd.variants import DecayingSquareWaveVariant
# Strong initial pulse train, decaying to weak coupling
coupling = DecayingSquareWaveVariant(
initial_amplitude=0.01, # Strong pump
final_amplitude=0.0005, # Weak probe
frequency_hz=5e11,
duty_cycle=0.3,
decay_constant_ps=10.0,
start_time_ps=5.0,
time_tracker=time_tracker
)
# Run simulation
sim.run(100000) # 100 ps
Example 2: Temperature Control¶
Protocol: Adaptive square wave maintains 100K
from cavitymd.variants import AdaptiveSquareWaveVariant
from cavitymd.analysis import TemperatureTracker
# Setup temperature tracking
temp_tracker = TemperatureTracker(sim, time_tracker)
# Adaptive coupling for temperature control
coupling = AdaptiveSquareWaveVariant(
base_amplitude=0.001,
target_temperature=100.0,
adaptation_gain=0.15,
frequency_hz=1e12,
duty_cycle=0.5,
temperature_tracker=temp_tracker,
time_tracker=time_tracker
)
# Coupling automatically adjusts to maintain T = 100K
sim.run(500000)
Example 3: Adiabatic Switching¶
Protocol: Slowly ramp coupling on, then off
from cavitymd.variants import ExponentialDecayVariant
from cavitymd import CompositeVariant
# Ramp up (inverse decay)
ramp_up = ExponentialDecayVariant(
initial_value=0.0,
final_value=0.005,
decay_constant_ps=30.0,
start_time_ps=10.0,
time_tracker=time_tracker
)
# Hold constant
constant = ConstantVariant(value=0.005)
# Ramp down
ramp_down = ExponentialDecayVariant(
initial_value=0.005,
final_value=0.0,
decay_constant_ps=30.0,
start_time_ps=200.0,
time_tracker=time_tracker
)
# Sequential protocol
coupling = CompositeVariant(
variants=[ramp_up, constant, ramp_down],
transition_times=[10.0, 100.0, 200.0]
)
Best Practices¶
Choosing the Right Variant¶
Decision tree:
Fixed coupling? → ConstantVariant
Sudden change? → StepVariant
Periodic? - Smooth: PeriodicVariant - Pulsed: SquareWaveVariant
Gradual change? → ExponentialDecayVariant
Need adaptation? → AdaptiveSquareWaveVariant
Complex protocol? → CompositeVariant
Time Scale Considerations¶
Match time scales to physics:
Step changes: Instantaneous compared to molecular timescales
Periodic modulation: Match molecular vibrational periods (0.01-1 ps)
Exponential decay: Choose τ >> molecular relaxation time for adiabatic
Adaptive feedback: Update interval ~ 0.1-1 ps
Example:
# For molecular vibration ~20 cm⁻¹ (~1.5 ps period)
# Too fast (non-adiabatic)
decay = ExponentialDecayVariant(..., decay_constant_ps=0.1)
# Good (adiabatic)
decay = ExponentialDecayVariant(..., decay_constant_ps=15.0)
Analysis and Visualization¶
Plot coupling vs time:
import matplotlib.pyplot as plt
# Extract coupling history
times = []
couplings = []
for timestep in range(sim.timestep, final_timestep):
t_ps = timestep * sim.dt * 0.001 # Convert to ps
g_t = coupling_variant.compute(t_ps)
times.append(t_ps)
couplings.append(g_t)
# Plot
plt.plot(times, couplings)
plt.xlabel('Time (ps)')
plt.ylabel('Coupling Strength (a.u.)')
plt.title('Time-Varying Coupling Protocol')
Monitor energy during protocol:
# Load energy tracker data
data = np.loadtxt('energy_tracker.txt')
time = data[:, 0]
total_energy = data[:, -1]
# Plot energy conservation
plt.plot(time, total_energy - total_energy[0])
plt.xlabel('Time (ps)')
plt.ylabel('$\\Delta E$ (a.u.)')
plt.axvline(x=10.0, color='r', linestyle='--', label='Switch')
Troubleshooting¶
Common Issues¶
1. Energy not conserved:
Check if thermostat is interfering
Verify timestep is small enough
Ensure variant is properly configured
2. Unphysical coupling values:
Check amplitude/target_value is reasonable
Verify units (atomic units for coupling)
Monitor for numerical overflow
3. Adaptive variant not converging:
Reduce adaptation_gain
Increase update_interval
Check temperature_tracker is working
4. Composite variant conflicts:
Verify transition times are ordered
Check variants don’t contradict
Test each variant individually first
Next Steps¶
Running Simulations for basic simulation setup
Analysis Tools for analyzing results
Time-Varying Coupling for theoretical background
Controllers for advanced control strategies
API Reference for complete API reference