# CelerisLab 配置说明

**唯一配置入口：`config_lbm.json`**  
Python `config.py` 只负责读取和校验，不是配置位置。

---

## grid — 网格

| 字段 | 类型 | 默认 | 允许值 | 说明 |
|------|------|------|--------|------|
| `lattice_model` | string | `"D2Q9"` | `D2Q9`, `D3Q19` | 格子模型，决定维度和速度数量 |
| `nx` | int | 512 | >0 | x 方向格点数（流向），建议整除 `threads_per_block` 以减少尾块浪费 |
| `ny` | int | 256 | >0 | y 方向格点数 |
| `nz` | int | 1 | >0 | z 方向格点数，D2Q9 时必须为 1 |

## physics — 物理参数

| 字段 | 类型 | 默认 | 说明 |
|------|------|------|------|
| `data_type` | string | `"FP32"` | 计算精度：当前仅实现 **`FP32`**（CUDA 核与 `LBMField` 主机缓冲为 float32；`FP64` 会在校验阶段被拒绝） |
| `viscosity` | float | 0.0035 | 运动粘度（格子单位），ω = 1/(3ν + 0.5) |
| `velocity` | float | 0.03 | 入口速度（格子单位） |
| `rho` | float | 1.0 | 参考密度 |

## method — 算法

| 字段 | 类型 | 默认 | 允许值 | 说明 |
|------|------|------|--------|------|
| `collision` | string | `"SRT"` | `SRT`, `TRT`, `MRT` | 碰撞算子 |
| `streaming` | string | `"double_buffer"` | `double_buffer`, `esopull` | 流传输方式。运行时 body 拓扑同步 (``sync_bodies()``) 仅支持 ``double_buffer`` |
| `store_precision` | string | `"FP32"` | `FP32`, `FP16S`, `FP16C` | GPU 存储精度。当前运行时已实现 `FP32` 与 `FP16S`，`FP16C` 仍为保留选项 |
| `ddf_shifting` | bool | false | | 存储 f−w 而非 f，提升 FP16 精度 |
| `les.enabled` | bool | false | | LES Smagorinsky 子格模型 |
| `les.cs` | float | 0.16 | | Smagorinsky 常数 |
| `les.closed_form` | bool | true | | 闭合形式 τ_eff（vs 迭代） |
| `trt.magic_param` | float | 0.1875 | | TRT Λ 参数，高 Re 建议 0.001 |
| `inlet.profile` | string | `"parabolic"` | `uniform`, `parabolic` | 入口速度剖面（物理目标速度，与 scheme 独立） |
| `inlet.scheme` | string | `"zou_he_local"` | `zou_he_local`, `channel_stabilized`, `equilibrium`, `regularized` | 入口数值闭合。`zou_he_local` 为本地 Zou-He，适合研究或 MRT 路径；`channel_stabilized` 为 donor NEQ 稳定化入口，适合高阻塞或更保守的量产路径；`equilibrium` 直接写入 `feq` 源态，适合 ghost-source 架构下的稳健 SRT 基线；`regularized` 使用本地宏量加 incoming donor NEQ 阻尼，是介于 `equilibrium` 与 `channel_stabilized` 之间的实验入口 |
| `inlet.trt_neq_damp` | float | 0.5 | [0, 1] | 仅 `channel_stabilized`：TRT 入口 donor NEQ 阻尼；更小更平滑、精度略降 |
| `inlet.regularized_neq_damp` | float | 0.5 | [0, 1] | 仅 `regularized`：incoming 方向 donor NEQ 阻尼；0 退化到 unknown 方向仅平衡态，1 为 unknown 方向全 donor NEQ |
| `outlet.mode` | string | `"neq_extrap"` | `neq_extrap`, `zero_gradient`, `blended` | 出口条件 |
| `outlet.backflow_clamp` | bool | true | | 出口回流钳位 |
| `outlet.blend_alpha` | float | 0.7 | | `blended` 下对未知入域方向的混合系数（**所有碰撞模型**共用同一路径） |
| `outlet.srt_neq_damp` | float | 0.5 | [0, 1] | 仅当 `outlet.mode` 为 **`neq_extrap`** 且碰撞为 **SRT/TRT** 时：出口全分布 damped NEQ 的阻尼系数。`outlet.mode` 为 **`blended`** 时 SRT/TRT 走混合未知方向分支，不使用本键。MRT + `neq_extrap` 仍为少量方向的 NEQ 外推 |
| `y_wall_bc` | string | `"bounce_back"` | `bounce_back`, `free_slip` | y 向上下壁面边界条件（仅壁面相邻流体行生效） |
| `omega_guard.min` | float | 0.01 | | ω 下界（LES τ_eff 保护） |
| `omega_guard.max` | float | 1.99 | | ω 上界，高 Re 建议 1.90-1.99 |

## cuda — 编译

| 字段 | 类型 | 默认 | 说明 |
|------|------|------|------|
| `threads_per_block` | int | 256 | CUDA block 线程数，V100 最优 256 |
| `compute_capability` | string | `"auto"` | 目标 SM 架构，`auto` 自动检测 |

---

## 配置 → 代码映射

```
**`lbm/kernels/config/*.h` 由编译器根据 `LBMConfig` 自动生成，请勿手改。**

仓库中可能检入过历史版本的 `config/*.h`，与当前默认 JSON **不一定一致**；若以 Python 入口运行仿真，`Simulation` / `compiler_v2.generate_config` 会在编译前重写这些头文件。若只用 `nvcc` 单独编译 `kernel_v2.cu` 且跳过 `generate_config`，则可能读到陈旧宏，属不受支持用法。

config_lbm.json
  ↓  load_lbm_config()
config.py:LBMConfig       (读取 + 校验)
  ↓  to_macros()
cuda/compiler_v2.py       (生成 config/*.h)
  ↓
config_grid.h             → NX, NY, NZ, NT, LATTICE_MODEL；
                            DIM / NQ 由 LATTICE_MODEL 推导写入（与 grid.lattice_model 一致，非 JSON 顶层字段）
config_physics.h           → LBtype, VIS, RHO, U0
config_method.h            → COLLISION_MODEL, STORE_PRECISION, USE_LES, Y_WALL_BC, ...
config_objects.h           → N_OBJS
config_obs.h               → OBS_*（打包遥测：force/torque/sensor 三段的 offset/stride 宏；`OBS_N_SLOTS=max(N_OBJS,1)`；由 `generate_config(cfg, n_objects=K)` 写入；**无**单独 JSON 字段，DIM 仍由格子模型推导）
  ↓  #include
descriptors.cuh            → d_cx[], d_cy[], d_w[] (CUDA __constant__)
step/one_step_*.cu         → kernel 编排
```

### 旋转物体数据契约（Rotating body contract）

- 几何参数（如 `rx`, `ry`）在 `initialize()` 后应视为不变量；改变几何属于拓扑变更，需要重新构建物体并重新初始化。
- 转速 `omega` 属于运行时状态，可在步进期间更新；该更新不改变 `N_OBJS` 或 `OBS_*` 内存布局，因此**不需要**因 `omega` 变化触发重新编译。
- 力矩观测从 `obs` 的 torque segment 读取；force / torque / sensor 段统一由 `config_obs.h` 宏描述。

### 稳定性默认窗口（Stability defaults）

- 默认 `method.omega_guard = {min: 0.01, max: 1.99}`，用于约束碰撞频率与 LES 有效粘度路径。
- 高 Re 调参建议将 `omega_guard.max` 保持在 `1.90-1.99` 区间；过高上界会增大接近 `omega -> 2` 的不稳定风险。

### 运行时 body 拓扑同步

- 运行时增删 body（`add_body()` / `remove_body()` + `sync_bodies()`）仅支持 `streaming: "double_buffer"`。
- `esopull` 模式下调用 `sync_bodies()` 会抛出 `NotImplementedError`。

### 力区域标记（Force region flag）

D2Q9/D3Q19 的 flag 扩展位 `0x0800` 定义为 `FRC_REGION`，用于标记 force_region 类型物体的格子。
- ForceRegionKernel 不依赖 flag 位执行，flag 只用于后处理可视化。
- `merge_flag_masks` 会正确合并 force_region 的 `FLUID | FRC_REGION` 标记。