重构:分级设计,EsoPull

This commit is contained in:
Frank14f committed 2026-04-17 21:50:38 +08:00
1 parent b339f302d3
commit 654e3290a4
40 files changed
+2767 -619

No files matched your search

+123 -144
View File
@@ -7,13 +7,14 @@ CelerisLab is a high-performance computational fluid dynamics (CFD) solver based
## Features
- **GPU Acceleration**: CUDA-based kernels for high-performance simulations
- **D2Q9 Lattice**: 2D nine-velocity lattice implementation
- **MRT Collision Model**: Multiple-Relaxation-Time collision operator for improved stability
- **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**: Periodic, velocity inlet, pressure outlet
- **Real-time Sensors**: Monitor flow properties at specific locations during simulation
- **Vortex Initialization**: Built-in support for Lamb, Oseen, and Taylor vortices
- **Dynamic Compilation**: Runtime CUDA kernel compilation with configurable parameters
- **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
@@ -40,162 +41,149 @@ pip install -e . # Installs from src/ directory
## Quick Start
### Basic Flow Simulation
```python
from CelerisLab import Simulation
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
from CelerisLab import FlowField, utils
# Load configurations
config_cuda = utils.load_cuda_config() # Uses default or CELERISLAB_CONFIG_DIR
config_field = utils.load_flow_field_config()
# Initialize flow field
flow = FlowField(
config_cuda=config_cuda,
config_field=config_field,
device_id=0
)
# Add a cylinder obstacle
flow.add_cylinder(
center=(50, 50, 0),
radius=10,
velocity=(0, 0, 0),
use_IBM=True
)
# Add sensors to monitor flow
flow.add_sensor(position=(70, 50, 0))
# Run simulation
for step in range(10000):
flow.run(1)
# Read sensor data every 100 steps
if step % 100 == 0:
sensor_data = flow.read_sensor()
print(f"Step {step}: Velocity = {sensor_data[0]}")
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
## Configuration
CelerisLab searches for configuration files in the following order:
### `configs/config_lbm.json`
1. **Explicit path**: Passed to `load_*_config(config_path)`
2. **Environment variable**: `CELERISLAB_CONFIG_DIR` environment variable
3. **Current directory**: `./configs/` in current working directory
4. **Package default**: Bundled `CelerisLab/configs/` directory
#### Configuration Files
**config_cuda.json**: CUDA execution parameters
```json
{
"multi_gpu": false,
"gpu_connection": "NVLINK",
"required_cuda_capability": "6.0",
"threads_per_block": 256,
"X_1U": 16,
"Y_1U": 16,
"Z_1U": 1
"dim": 2,
"nq": 9,
"nx": 384,
"ny": 192,
"nz": 1,
"viscosity": 0.0005,
"velocity": 0.04,
"rho": 1.0,
"collision": "MRT",
"streaming": "double_buffer",
"les_enabled": true,
"les_cs": 0.16,
"trt_magic_param": 0.001,
"omega_max": 1.90,
"inlet_profile": "parabolic",
"outlet_mode": "neq_extrap",
"compute_capability": "auto",
"threads_per_block": 256
}
```
**config_flowfield.json**: Flow physics parameters
```json
{
"data_type": "FP32",
"dimensionality": 2,
"lattice": 9,
"field_dim_in_U": [100, 100, 1],
"viscosity": 0.01,
"velocity": 0.1,
"boundary_conditions": {
"x": ["periodic", "periodic"],
"y": ["periodic", "periodic"],
"z": ["periodic", "periodic"]
}
}
```
### Parameter tiers
| Tier | Headers | Examples |
|---|---|---|
| Global/Grid | `config_grid.h` | DIM, NQ, NX, NY, NZ |
| 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` | N_OBJS |
Headers are auto-generated by the compiler from `LBMConfig`; do not edit manually.
## API Reference
### FlowField Class
Main interface for running LBM simulations.
#### Constructor
```python
FlowField(config_cuda, config_field, device_id=0)
```
#### Methods
- `add_cylinder(center, radius, velocity, use_IBM=False)`: Add cylindrical obstacle
- `add_sensor(position)`: Add flow monitoring sensor
- `add_vortex(center, circulation, core_radius, vortex_type='Lamb')`: Initialize vortex
- `run(n_steps)`: Execute simulation steps
- `read_sensor()`: Read current sensor values
- `get_ddf()`: Get distribution function data
- `apply_ddf(ddf)`: Set distribution function data
### Utility Functions
- `load_cuda_config(config_path=None)`: Load CUDA configuration
- `load_flow_field_config(config_path=None)`: Load flow field configuration
- `check_cuda_device_availability(device_id=0)`: Verify CUDA device
- `get_device_info(device_id=0)`: Query GPU properties
- `estimate_memory_consumption(config_field, num_objects, num_sensors)`: Calculate memory usage
## Advanced Usage
### Custom Geometry with IBM
### `Simulation`
```python
# IBM enables smooth treatment of curved boundaries
flow.add_cylinder(
center=(grid_x//2, grid_y//2, 0),
radius=20,
velocity=(0.0, 0.0, 0.0),
use_IBM=True # Enables immersed boundary method
)
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()
sim.run(steps)
sim.step(n=1)
sim.get_macroscopic() -> {"rho": ndarray, "ux": ndarray, "uy": ndarray}
sim.get_ddf() -> ndarray
sim.get_flags() -> ndarray
sim.update_runtime_params(omega=..., u_inlet=...)
sim.snapshot() / sim.restore()
sim.close()
```
### Multiple Sensors
### Vortex initialization
```python
# Add sensors in a line downstream of obstacle
for i in range(5):
flow.add_sensor(position=(100 + i*10, 50, 0))
from CelerisLab.lbm.initializers import add_vortex
# Read all sensors at once
sensor_data = flow.read_sensor() # Returns array of shape (n_sensors, 3)
# Superimpose a Lamb–Oseen vortex on an existing LBMField
add_vortex(sim.field, center=(50, 50), radius=10.0, strength=1.0, vortex_type="lamb")
```
### Vortex Initialization
## Collision & LES Recommendations
```python
# Initialize Lamb-Oseen vortex
flow.add_vortex(
center=(50, 50, 0),
circulation=1.0,
core_radius=10.0,
vortex_type='Lamb'
)
| Use case | Recommended config |
|---|---|
| Low Re (≤ 500) | SRT or TRT, LES off |
| Medium Re (500–2000) | MRT or SRT+LES |
| High Re (2000–5000) | MRT+LES (most robust); SRT+LES; TRT+LES with `omega_max=1.90`, `trt_magic_param=0.001` |
## 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 management
stepper.py Time-step driver
initializers.py Vortex superposition
kernels/
kernel_v2.cu Kernel entry (thin wrapper)
config/ Auto-generated config headers
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 + GPU sync
common/
preprocess.py Geometry utilities
tests/
test_stability_matrix.py 13-case stability matrix (Re × collision × LES × streaming)
test_high_re_validation.py High-Re directed validation (Re5000, 2D/3D, parameter sweep)
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)
```
## Environment Variables
## Performance
- `CELERISLAB_CONFIG_DIR`: Directory containing configuration JSON files
- `OMP_NUM_THREADS`: OpenMP thread count (recommend setting to 1 for GPU workflows)
- `MKL_NUM_THREADS`: Intel MKL thread count (recommend setting to 1)
Tested on Tesla V100-SXM2-16GB (CUDA 12.4):
## Performance Tips
1. **Grid Size**: Choose dimensions that are multiples of `unit_dimensions` in config_cuda.json
2. **Thread Block Size**: 256 threads/block works well for most GPUs
3. **Memory**: Estimate memory with `utils.estimate_memory_consumption()` before large runs
4. **Single-threaded Python**: Set `OMP_NUM_THREADS=1` to avoid CPU interference with GPU
| Config | Grid | MLUPS |
|---|---|---|
| Re100 MRT noLES | 384×192 | ~4200 |
| Re100 EsoPull SRT | 384×192 | ~3900 |
| Re3000 MRT+LES | 384×192 | ~4360 |
## Citation
@@ -212,13 +200,4 @@ If you use CelerisLab in your research, please cite:
## License
MIT License - see LICENSE file for details
## Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.
## Acknowledgments
- Built with PyCUDA by Andreas Klöckner
- Inspired by the palabos C++ LBM library
MIT License — see LICENSE file for details.