2D Turbulence (SciPy + CuPy)
Project description
2D Turbulence Simulation (SciPy / CuPy)
Source code: https://github.com/mannetroll/cupystorm
A Direct Numerical Simulation (DNS) code for 2D homogeneous incompressible turbulence
It supports:
- SciPy / NumPy for CPU runs
- CuPy (optional) for GPU acceleration on CUDA devices (e.g. RTX 3090)
one-liner CPU/SciPy
$ curl -LsSf https://astral.sh/uv/install.sh | sh
$ uv cache clean mannetroll-cupystorm
$ uv run --python 3.13 --with "mannetroll-cupystorm==0.1.2" turbulence
one-liner GPU/CuPy
$ uv run --python 3.13 --with "mannetroll-cupystorm[cuda]==0.1.2" turbulence
DNS solver
The solver includes:
- PAO-style random-field initialization
- 3/2 de-aliasing in spectral space
- Crank–Nicolson time integration
- CFL-based adaptive time stepping (Δt updated from the current flow state)
cupystorm GUI (PySide6)
Run an cupystorm window that:
- Displays the flow field as a live image (fast Indexed8 palette rendering)
- Lets you switch displayed variable:
- U, V (velocity components)
- K (kinetic energy)
- Ω (vorticity)
- φ (stream function)
- Lets you switch colormap (several built-in palettes)
- Lets you change simulation parameters on the fly:
- Grid size N
- Reynolds number Re
- Initial spectrum peak K0
- CFL number CFL
- Max steps / auto-reset limit
- GUI update interval (how often to refresh the display)
- Includes force/initialization modes:
- Navier-Stokes: PAO spectrum init
- High-k + Ekman/Rayleigh: High-k spectral forcing + Ekman/Rayleigh large-scale drag
- Rain: random “kick” forcing events
- Circle: a forcing point moves on a circular trajectory (continuous forcing)
- Mouse: apply forcing by click/drag in the image
Keyboard shortcuts
Single-key shortcuts (application-wide) for fast control:
- V: cycle variable
- C: cycle colormap
- N: cycle grid size
- R: cycle Reynolds number
- K: cycle K0
- L: cycle CFL
- S: cycle max steps
- U: cycle update interval
Saving / exporting
From the GUI you can:
- Save the current frame as a PNG image
- Dump full-resolution fields to a folder as PGM images:
- u-velocity, v-velocity, kinetic energy, vorticity
Display scaling
To keep the GUI responsive for large grids, the displayed image is automatically upscaled/downscaled depending on N. The window is resized accordingly when you change N.
Installation
Using uv
From the project root:
uv sync
uv run turbulence
High-k spectral forcing + Ekman/Rayleigh large-scale drag
The flow remains fully turbulent after 1,000,000 iterations (256 x 256) CuPy
Rain (256 x 256) SciPy
Circle (256 x 256) SciPy
Mouse (256 x 256) SciPy
Full CLI
$ python -m cupystorm.turbo_simulator N Re K0 STEPS CFL BACKEND [MODE]
Where:
- N — grid size
- Re — Reynolds number
- K0 — peak wavenumber of the energy spectrum
- STEPS — number of time steps
- CFL — target CFL number
- BACKEND — "cpu", "gpu", or "auto"
- MODE — "pao" | "highh" | "rain" | "circle" | "mouse"
Examples:
# CPU run (SciPy with 4 workers)
$ python -m cupystorm.turbo_simulator 256 10000 10 1001 0.75 cpu
# Auto-select backend (GPU if CuPy + CUDA are available)
$ python -m cupystorm.turbo_simulator 256 10000 10 1001 0.75 auto
Enabling GPU with CuPy (CUDA 13)
On a CUDA machine (e.g. RTX 5090):
Download: https://developer.nvidia.com/cuda-downloads
-
Check that the driver/CUDA are available:
$ nvidia-smi -
Install CuPy into the uv environment:
$ uv sync --extra cuda $ uv run turbulence -
Verify that CuPy sees the GPU:
$ uv run python -c "import cupy as cp; x = cp.arange(5); print(x, x.device)" -
Run in GPU mode:
$ uv run python -m cupystorm.turbo_simulator 256 10000 10 1001 0.75 gpu
Or let the backend auto-detect:
$ uv run python -m cupystorm.turbo_simulator 256 10000 10 1001 0.75 auto
The DNS with CuPy (7776 x 7776) Navier-Stokes
Profiling
cProfile (CPU)
$ python -m cProfile -o turbo_simulator.prof -m cupystorm.turbo_simulator
Inspect the results:
$ python -m pstats turbo_simulator.prof
# inside pstats:
turbo_simulator.prof% sort time
turbo_simulator.prof% stats 20
GUI profiling with SnakeViz
Install SnakeViz:
$ uv pip install snakeviz
Visualize the profile:
$ snakeviz turbo_simulator.prof
Memory & CPU profiling with Scalene (GUI)
Install Scalene:
$ uv pip install "scalene==1.5.55"
Run with a GUI report:
$ scalene -m cupystorm.turbo_simulator 256 10000 10 201 0.75 cpu
Memory & CPU profiling with Scalene (CLI only)
For a terminal-only summary:
$ scalene --cli --cpu -m cupystorm.turbo_simulator 256 10000 10 201 0.75 cpu
License
Copyright © 2026 Mannetroll
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mannetroll_cupystorm-0.1.2.tar.gz.
File metadata
- Download URL: mannetroll_cupystorm-0.1.2.tar.gz
- Upload date:
- Size: 163.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
edd4725071a3cd50092165cd19ea88a5374085d465a15863f9eee2407681e4bd
|
|
| MD5 |
2dcd7de84e3a750b4c5da3940a577f84
|
|
| BLAKE2b-256 |
82b49dfa27b89620ee13a426af0b557369a75acd708a248dbc0958480f968d97
|
File details
Details for the file mannetroll_cupystorm-0.1.2-py3-none-any.whl.
File metadata
- Download URL: mannetroll_cupystorm-0.1.2-py3-none-any.whl
- Upload date:
- Size: 161.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e722f9b169e6c80e06e5ee803fdd0a4827afc1ed13da52681fa2e01132a8289e
|
|
| MD5 |
30e13e8c4a15df23ab4f36ad57c670f6
|
|
| BLAKE2b-256 |
27e246b56a373d8afba147cb3c927a5a7a738c2b4fd736f8c7ba8586da338285
|