How to sweep one parameter with checkpoint restart¶
Use this when you want to sweep one parameter (e.g. rocking frequency
omega_b) across several values, chained via checkpoint restart so each
segment after the first starts from an already-developed flow instead of
cold. For why this is worth doing and how the restart ramp works, see
Checkpoint restart and warm-start chains.
Tip
To sweep multiple parameters at once, or write configs in JSON instead of YAML, use Sweep any parameter combination instead.
1. Write a chain config¶
Copy config/chain_config.yaml and edit:
# ── Fixed params (same for all segments) ────────────────────────────────────
fidelity: 7
geometry: {a: 0.20, b: 0.09, n: 2.0} # superellipse; n=2 → ellipse
fill_level: 0.4
# ── Timing ───────────────────────────────────────────────────────────────────
n_mix_cycles: 80 # rocking cycles before O₂ injection (segment 0)
n_transition_cycles: 10 # rocking cycles before O₂ re-injection (segments 1+)
t_buffer: 150 # non-dim kLa measurement window
# ── Sweep: one segment per value ─────────────────────────────────────────────
sweep:
parameter: omega_b
values: [3.14159, 6.28318] # 0.5 Hz, 1.0 Hz
# ── Base motion (non-swept params, fixed across all segments) ─────────────────
motion:
n_harmonics: 1
theta_max: [5.0, 0.0, 0.0]
phi_angular: [0.0, 0.0, 0.0] # index 0 must stay 0.0
omega_h: 6.28
amplitude_h: [0.02, 0.0, 0.0]
phi_horizontal: [0.3, 0.0, 0.0]
videos: false # set true to use BioReactor-video and render MP4s
submit: true
walltime: "04:00:00"
Supported sweep parameters:
| Name | Maps to |
|---|---|
omega_b |
rocking angular frequency (rad/s) |
omega_h |
horizontal translation frequency (rad/s) |
theta_max_0 / _1 / _2 |
theta_max[0..2] |
amplitude_h_0 / _1 / _2 |
amplitude_h[0..2] |
phi_angular_1 / _2 |
phi_angular[1..2] (index 0 is always 0) |
phi_horizontal_0 / _1 / _2 |
phi_horizontal[0..2] |
2. Smoke-test before submitting long jobs¶
uv run python scripts/chain.py config/chain_config_smoke.yaml
Then check (see Your first sweep for what this looks like in full):
runs/<seg1_id>/logstats.datstarts att > 0, nott=0runs/<seg1_id>/results.jsonhas finite kLa values
3. Submit for real¶
python scripts/chain.py config/chain_config.yaml
Prints one line per segment with run IDs and SLURM job IDs. SLURM
--dependency=afterok ensures each segment starts only after the previous
one succeeds.
4. Collect results¶
Each segment writes independently to runs/<run_id>/results.json — there's
no aggregation script for Workflow B specifically; collect manually or use
collect_results.py (see Scripts reference).