Guide 03
Run the experiment
The current homepage run uses AMReX / incflo. Follow the fixed-refinement launch settings and native backend build instructions for that solver. The commands below remain the earlier PhiFlow workflow.
Reproducible commands for a smoke test, a full start-from-rest trajectory, the static core refinement, and site media.
Install
Use Python 3.11–3.13 and uv.
git clone https://github.com/cmccomb/navier-stokes-singularity-simulation.git
cd navier-stokes-singularity-simulation
uv sync --no-editable --extra dev
uv run ns-blowup --help
Smoke test
uv run ns-blowup \
--resolution 20 --t-end 0.85 --frames 16 \
--pressure-projection fft \
--output outputs/smoke
Full-domain start from rest
This is a candidate production command, not a convergence-certified configuration. The first full-interval timestep gate failed; complete the controlled checks in the accuracy budget before committing to a large campaign.
uv run ns-blowup \
--resolution 192 --mesh-preset full-domain \
--t-start 0 --t-end 0.985 \
--frames 81 --frame-spacing similarity \
--cfl 0.20 --max-dt 0.001 \
--forcing-phase-step 0.15 --derivative-epsilon 0.000001 \
--profile-interpolation cubic \
--capture-velocity-volumes --capture-force-volumes --volume-frames 12 \
--stream-volumes --preview-phase-step 0.3 --preview-resolution 32 \
--paper-time-cutoff 0.55 0.775 \
--pressure-projection fft \
--output outputs/n192-paper-rest-fine \
--save-final-state --no-animation --no-3d
Similarity-time spacing saves real solver checkpoints more densely near t = 1; the GIF renderer never blends temporally between checkpoints.
Run 128³ with the same options for the baseline. Use one production solver per 16 GB machine, with a new output directory for each configuration. Full-resolution float64 vector checkpoints stream to full-volumes/; denser float32 display frames stream to preview-volumes/. Both velocity and force are saved. Rendering a run directory selects the denser preview; pass its full-volumes directory to use sparse analysis checkpoints instead. Streams do not accumulate a full-volume history in RAM.
Check the forcing timestep first
uv run python -m scripts.check_forcing_timestep \
--resolution 32 --t-end 0.985 --profile-interpolation cubic \
--derivative-epsilon 0.000001 --output outputs/cubic-phase-pilot-n32
This integrates from rest three times, halving both the maximum step and forcing-phase bound while holding the force-difference half-window at 10−6. The summary records successive final-velocity and vorticity differences. A low-resolution temporal pilot is not spatial validation; repeat the comparison at production resolution before making accuracy claims.
Static core refinement
uv run ns-blowup \
--resolution 192 --mesh-preset core-refined \
--t-start 0 --t-end 0.99 \
--frames 121 --frame-spacing similarity \
--cfl 0.20 --max-dt 0.00065 \
--pressure-projection fft \
--output outputs/n192-core-refined \
--no-animation --no-3d
This smaller box is a cutoff-sensitivity experiment, not the preferred refinement. It changes both the spacing and the exterior forcing taper, so it is not a clean grid-convergence comparison. See the numerical review and mesh tradeoff.
Render direction-aware GIFs
uv run python -m scripts.render_flow_gifs \
--run outputs/n192-paper-rest-fine \
--output artifacts --stem best \
--frames 72 --fps 8
The renderer writes a similarity-core axial-outflow GIF and paired physical-plane GIFs for speed, signed vertical velocity, and plane-normal vorticity. It uses saved solver states only and a fixed color scale for each paired view.
Publish the complete saved history from rest
The home-page velocity and forcing GIFs and MP4s include every finalized snapshot in preview-volumes/, starting with the actual zero field at t = 0. No rolling window, frame thinning, or interpolated fluid states are used. This includes every saved snapshot, not every internal solver timestep.
uv run python -m scripts.stream_run \
--host local --once --no-push \
--run outputs/n192-paper-rest-fine \
--repo . --cache .publish-cache \
--deadline <future-ISO-time-with-timezone>
Run this bounded export on the archive machine. Native planes and browser samples are cached outside Git; encoding reads one derived frame at a time. The live controller transfers the seven fixed website outputs plus explicitly indexed 32³ frame chunks. It checks complete GIF and 3D time coverage, chunk checksums, shapes, and finite vectors before pushing to main.
Movie playback uses five saved snapshots per second, a one-second initial-rest hold, and a half-second final hold. Duration grows with the archive. Simulation-time spacing varies, and every frame displays its actual time and frame number.
Both interactive 3D explorers also include every saved frame from rest. The selected three-component float32 volume loads on demand into a three-frame cache; no time window or temporal thinning is applied. Magnitude and signed x/y/z views use fixed scales and preserve the camera. Playback waits for each saved frame without interpolation. The 32³ browser sampling does not replace the complete 192³ native archive.
Serve each 3D HTML file together with its stream-volumes/ directory over HTTPS or localhost. Plotly is bundled, but the history is not embedded in one large file. Content-addressed chunks remain available after updates, so already-open explorers keep working. A failed download pauses playback, retains the last frame's label, and offers a retry.
Animate three-dimensional histories
uv run python -m scripts.render_volume_media \
--run outputs/n192-paper-rest-fine \
--output artifacts --stem full --field force \
--component magnitude --camera orbit --format both
This writes a time-animated GIF, MP4, interactive explorer, and a JSON record of times and display settings. Use --component x, y, or z for signed components, --camera fixed for a stationary view, and --field velocity for captured fluid velocity. The explorer offers magnitude and all components with the same saved-time slider. All arrows include x, y, and z.
--capture-velocity-volumes preserves velocity history even with --no-3d. That option now defers both velocity and force rendering. Full volume histories require substantial RAM and disk; use the offline exporter to stream one archived source frame at a time into compact display samples. Sparse volume checkpoints cannot show every forcing oscillation; see the numerical review before planning a longer run.
uv run python -m scripts.export_volume_preview \
--run outputs/n192-paper-rest-fine --field force \
--max-resolution 64 --output artifacts/force-preview.npz
uv run python -m scripts.render_volume_media \
--preview artifacts/force-preview.npz --output artifacts --stem full
Output contract
run.json: exact configuration, solver description, timestamp, and scope warning.diagnostics.csv: complete physical and numerical time history.slices.npz: saved axial and equatorial solver slices.partial-checkpoint.npz: atomic resumable state, removed after completion.forces.npz: full 3D force vectors at the requested volume checkpoints, including both endpoints.volumes.npz: optional three-component velocity history at the volume checkpoints.final-state.npz: optional terminal 3D field for convergence comparisons.
Verify before publishing
uv run ruff check .
uv run pytest -q
A live partial trajectory must include its full saved history from t = 0 and remain labeled as running. Do not describe it as a completed or convergence-validated endpoint. Check geometric scale coverage and spectral tails before making resolution claims. Raw arrays, derived caches, and run directories remain outside Git.