CelerisLab/README.md

236 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CelerisLab
**GPU-Accelerated Lattice Boltzmann Method (LBM) CFD Solver**
CelerisLab is a high-performance computational fluid dynamics (CFD) solver based on the Lattice Boltzmann Method, leveraging NVIDIA CUDA for GPU acceleration. It provides a Python interface for easy integration into scientific workflows while maintaining high computational efficiency through CUDA kernels.
## Features
- **GPU Acceleration**: CUDA-based kernels for high-performance simulations
- **D2Q9 / D3Q19 Lattice**: 2D and 3D lattice implementations
- **Multiple Collision Models**: SRT, TRT, and MRT operators; Smagorinsky LES subgrid model
- **Dual Streaming Paths**: Standard double-buffer pull and memory-efficient esoteric-pull (EsoPull)
- **Immersed Boundary Method (IBM)**: Support for complex geometries (cylinders, arbitrary shapes)
- **Flexible Boundary Conditions**: NEQ-extrapolation pressure outlet, parabolic/uniform velocity inlet, half-way bounce-back walls
- **Layered Configuration**: Compile-time parameters organized into Global / Method / Case / Debug tiers
- **High-Re Validated**: Tested up to Re=5000 (2D cylinder); MRT+LES and SRT+LES stable; TRT+LES stable with tuned Lambda and WMAX
- **Python API**: High-level `Simulation` class for scripting and RL integration
## Installation
### Prerequisites
- Python 3.8 or higher
- NVIDIA GPU with CUDA Compute Capability 6.0 or higher
- CUDA Toolkit 11.0 or higher
- NVIDIA drivers
### Install from source
```bash
git clone <repository_url>
cd CelerisLab
pip install -e . # Installs from src/ directory
```
### Dependencies
- `pycuda>=2020.1`: CUDA Python bindings
- `numpy>=1.19.0`: Numerical computing
- `scipy>=1.5.0`: Scientific computing (special functions for vortex initialization)
## Quick Start
```python
from CelerisLab import Simulation
# Path is optional; see Configuration → paths. Example passes the usual relative name.
sim = Simulation("configs/config_lbm.json")
sim.add_cylinder(center=(50, 50), radius=10)
sim.initialize()
for step in range(10000):
sim.run(1)
macro = sim.get_macroscopic() # {"rho": ..., "ux": ..., "uy": ...}
sim.close()
```
Or as a context manager:
```python
with Simulation("configs/config_lbm.json") as sim:
sim.add_cylinder(center=(96, 64), radius=12)
sim.initialize()
sim.run(5000)
data = sim.get_macroscopic()
```
## Configuration
### Where `config_lbm.json` is loaded from
`load_lbm_config()` resolves `config_lbm.json` in this order: an explicit path argument to `Simulation(...)` / `load_lbm_config(path)`, then `$CELERISLAB_CONFIG_DIR/config_lbm.json`, then `./configs/config_lbm.json` under the current working directory, then the copy shipped inside the installed package at `CelerisLab/configs/config_lbm.json`. In a source checkout the same file lives at `src/CelerisLab/configs/config_lbm.json`. There is **no** top-level `configs/` directory at the repository root; from the clone root you can omit the path (`Simulation()`), set `CELERISLAB_CONFIG_DIR`, or create your own `./configs/config_lbm.json`.
### `config_lbm.json` shape
The on-disk schema matches `src/CelerisLab/configs/config_lbm.json` (nested sections). Example fragment:
```json
{
"grid": {
"lattice_model": "D2Q9",
"nx": 512,
"ny": 256,
"nz": 1
},
"physics": {
"data_type": "FP32",
"viscosity": 0.0035,
"velocity": 0.03,
"rho": 1.0
},
"method": {
"collision": "SRT",
"streaming": "double_buffer",
"store_precision": "FP32",
"ddf_shifting": false,
"les": { "enabled": false, "cs": 0.16, "closed_form": true },
"trt": { "magic_param": 0.1875 },
"inlet": { "profile": "parabolic", "trt_neq_damp": 0.5 },
"outlet": {
"mode": "neq_extrap",
"backflow_clamp": true,
"blend_alpha": 0.7,
"srt_neq_damp": 0.5
},
"omega_guard": { "min": 0.01, "max": 1.96 }
},
"cuda": {
"threads_per_block": 256,
"compute_capability": "auto"
}
}
```
Lattice size and model come from `grid`; viscosity and scales from `physics`; collision, LES, boundaries, and ω clamps from `method` (ω upper bound is `method.omega_guard.max`, not a top-level `omega_max`). For high-Re runs, keep `method.omega_guard.max` in the `1.90-1.96` window. See `src/CelerisLab/configs/CONFIG.md` for the full parameter tables.
### Parameter tiers
| Tier | Headers | Examples |
|---|---|---|
| Global/Grid | `config_grid.h` | `NX`, `NY`, `NZ`, `LATTICE_MODEL`; `DIM` / `NQ` are **derived** from `LATTICE_MODEL` when `cuda/compiler_v2.py` emits headers (they are not separate keys in JSON) |
| Global/Physics | `config_physics.h` | VIS, RHO, U0, flag constants |
| Method | `config_method.h` | COLLISION_MODEL, USE_LES, TRT_MAGIC_PARAM, OMEGA_COLLISION_MAX |
| Case | `config_objects.h`, `config_obs.h` | `N_OBJS`; packed obs macros `OBS_*` from `generate_config(cfg, n_objects=K)` (`max(N_OBJS,1)` × `DIM` per segment; no extra JSON keys) |
Headers are auto-generated by `cuda/compiler_v2.py` from `LBMConfig`; do not edit manually.
## API Reference
### `Simulation`
```python
sim = Simulation(lbm_config_path=None, body_config_path=None, device_id=0)
sim.add_cylinder(center, radius) -> int
sim.add_sensor(center, radius) -> int
sim.initialize() # recompiles with N_OBJS when bodies were added
sim.run(steps, checkpoint_interval=0) # wires bodies.action_gpu / bodies.obs_gpu
sim.step(n=1)
sim.bodies # ObjectManager: packed buffers + zero_force_segment_async, ...
sim.get_macroscopic() -> {"rho": ndarray, "ux": ndarray, "uy": ndarray}
sim.get_ddf() -> ndarray
sim.get_flags() -> ndarray
sim.update_runtime_params(omega=..., fx=..., fy=...)
sim.snapshot() / sim.restore()
sim.save_checkpoint(path=None) -> str # HDF5; default path if omitted
sim.load_checkpoint(path) # restores field, step count, bodies
sim.close()
```
### `LBMStepper` (advanced)
```python
stepper.step(n=1, *, action_gpu, obs_gpu, stream=None)
```
Curved BC / sensor lists live on `field.curved` and `field.sensors` (`CurvedLinkSoA` / `SensorSoA`), filled by `ObjectManager.sync_to_gpu(field)`.
### Vortex initialization
```python
from CelerisLab.lbm.initializers import add_vortex
# Superimpose a LambOseen vortex on an existing LBMField
add_vortex(sim.field, center=(50, 50), radius=10.0, strength=1.0, vortex_type="lamb")
```
## Collision & LES Recommendations
| Use case | Recommended config |
|---|---|
| Low Re (≤ 500) | SRT or TRT, LES off |
| Medium Re (5002000) | MRT or SRT+LES |
| High Re (20005000) | MRT+LES (most robust); SRT+LES; TRT+LES with `method.omega_guard.max` in `1.90-1.96` (default `1.96`) and tuned `method.trt.magic_param` (default `0.1875`) |
## Project Layout
```
src/CelerisLab/
simulation.py High-level API
config.py LBMConfig / BodyConfig dataclasses
cuda/
compiler_v2.py Config header generation + nvcc + PTX load
context.py CUDA context lifecycle
lbm/
field.py GPU memory + ``curved`` / ``sensors`` SoA handles
curved_links.py CurvedLinkSoA / SensorSoA
stepper.py Time-step driver (``action_gpu``, ``obs_gpu``)
initializers.py Vortex superposition
kernels/
kernel_v2.cu Kernel entry (thin wrapper)
config/ Auto-generated headers (``config_grid.h``, …, ``config_obs.h``)
core/ Descriptors, layout, flags, params
operators/ Collision, LES, forcing
boundary/ Inlet, outlet, wall, curved, IBM
streaming/ Double-buffer & esopull
step/ Step orchestration
body/
objects.py SimObject / Cylinder / Sensor
manager.py ObjectManager; packed ``obs_gpu`` / ``obs_pinned``, B3 helpers
common/
preprocess.py Geometry utilities
output/
CelerisLab_stage1_architecture.md Architecture specification (v3)
refactor_brief_stage1.md Refactoring brief
high_re_audit_round1.md 8-round audit log
legacy/ Superseded code (FlowField, compiler v1, macros.h)
```
## Performance
Tested on Tesla V100-SXM2-16GB (CUDA 12.4):
| Config | Grid | MLUPS |
|---|---|---|
| Re100 MRT noLES | 384×192 | ~4200 |
| Re100 EsoPull SRT | 384×192 | ~3900 |
| Re3000 MRT+LES | 384×192 | ~4360 |
## Citation
If you use CelerisLab in your research, please cite:
```bibtex
@software{celerislab2026,
author = {Frank14f},
title = {CelerisLab: GPU-Accelerated Lattice Boltzmann Method Solver},
year = {2026},
url = {https://github.com/frank14f/CelerisLab}
}
```
## License
MIT License — see LICENSE file for details.