A deterministic Python 3 grid fluid. Each step lays two soft ink strokes — a figure-8 ribbon and a slower orbit — then stirs them with a central vortex. Old ink fades so the paper stays clear instead of filling with fog. The seed kernel diffuses, advects, and projects the field with nested loops and Gauss-Seidel. There is no NumPy, FFT, tiling, or parallelism. That leaves a clear optimization opportunity while the correctness tests protect the density field.
Colour mapping is display-only. Discovery should maximize simulation_fps without changing those densities or weakening the tests.
- Python 3.10 or newer
- Tkinter and a graphical display for the (default-on) visualization pass; see below for headless behavior
Compile:
python3 -m compileall src testsTest:
python3 -m unittest discover -s testsBenchmark:
python3 main.py --no-visualizeThe benchmark measures 20 steps on a 128×128 grid after three warmup steps and writes simulation_fps to artemis_results.json. That is the same field as the visualization, but headless: no window, no colour mapping, no Tk. Artemis tracks this number, not the FPS shown in the visualization.
The measured benchmark is always followed by a visual pass on the same 128×128 field, bilinearly upsampled to fill most of the screen and colour-mapped as ink on paper. Press 1 / 2 / 3 (or click) to switch Paper, Night, and Aurora. The window starts playing from the first step. The on-screen FPS includes display overhead and is not the Artemis metric. The window stays open until you close it:
python3 main.pyPass --no-visualize to skip the window entirely, e.g. for a faster local loop or an Artemis runner:
python3 main.py --no-visualizeThe visualization is never part of the timed section, so it cannot affect simulation_fps. On a runner with no graphical display, the visualization pass prints a warning to stderr instead of failing the whole command. The measured artemis_results.json from the timed section is written first and is unaffected either way.
Licensed under the Apache License 2.0.