7.0 KiB
CCD Analysis Pipeline
Correction-field CCD analysis for fluidic pinball DRL control. Core question: does
dq_ctl(what the controller adds) matchdq_tar(what the target requires)?
Quick Start
cd src/CCD_analysis
# Panorama comparison figure (primary output)
conda run -n pycuda_3_10 python3 correction_analysis/compare_dqctl_scenes.py
# CCD quantitative decomposition
conda run -n pycuda_3_10 python3 correction_analysis/decompose_corrections.py
# Single-scene zone diagnostics
conda run -n pycuda_3_10 python3 correction_analysis/diagnose_corrections.py
Pipeline Architecture
[Data Collection] [Phase Alignment] [Correction Fields] [Analysis]
scripts/collect_*.py → detect_period.py → compute_correction_ → compare_dqctl_scenes.py
(GPU, device 2) replay_fields.py fields.py decompose_corrections.py
(CPU/GPU) (CPU) diagnose_corrections.py
(CPU)
Dual-clock field sampling
Legacy DRL 的控制时钟与 DDF 保存时钟必须独立:模型仍只在固定控制周期边界读取完整 observation 和预测动作,DDF 可以在周期内任意 lattice step 读取。通用 API、OID 复用方式、输出时间轴合同和 GPU A/B 结果见 DUAL_CLOCK_SAMPLING.md。
Key Conventions
Geometry (unified 2026-06-25)
- All scenes: pinball center ≈ 613 px, sensors at 800 px (40×L0)
- Collected at source — no post-processing translation needed
Correction Fields
dq_blk = q_blk − q_in: pinball blockage (passive)dq_ctl = q_ctl − q_blk: control correction (active) — primary analysis objectdq_tar = q_tar − q_blk: target correction (theoretical)- Core question: O(dq_ctl, dq_tar) — how well does control match theory?
Observation Normalization
- Force-first:
obs = [forces/force_norm, sensors/sens_norm] - Each scene computes its own
force_norm_fact,sens_deviation,sens_norm_factduring collection - Same norm values MUST be used during inference
Reynolds Number
- Code Re uses reference length 2D = 40:
Re = U0×40/ν - Physical Re_D uses D = 20:
Re_D = Re/2 - Default: Re=100 → Re_D=50, nu=0.004
Inlet
- Parabolic velocity profile (not uniform)
- Top/bottom walls: no-slip bounce-back
- U0 = 0.01 (centerline, lattice units)
Vortex Bug History (2026-06-29)
Three bugs in collect_vortex.py caused incorrect Lamb data:
- Cylinder order: add order is front→TOP(+y)→BOTTOM(−y); reversed caused wrong bias mapping
- Obs swap: used
[sensors/force_norm, forces/sens_norm]instead of force-first[forces/force_norm, sensors/sens_norm] - Missing fade-in/out: 25-step transition from steady-cloak bias to PPO action required
See collect_vortex.py header and ccd_knowledge.md §12 for full details.
Results Index
All figures in results/figures/; CCD JSON in results/ccd/.
Panorama (main deliverable)
| # | Figure | Content |
|---|---|---|
| 01 | 01_panorama_all_scenes.png |
7 scenes × 4 quantities (ux_mean, uy_mean, RMS, vorticity) |
| 02 | 02_cloak_comparison.png |
4 cloak scenes (steady, karman, vortex_lamb, vortex_taylor) |
| 03 | 03_illusion_comparison.png |
3 illusion scenes (0.75L, 1.0L, 1.5L) |
Per-Scene dq_ctl vs dq_tar
| # | Figure | Scene |
|---|---|---|
| 04 | 04_steady_cloak_cancel.png |
Steady cloak cancellation test |
| 05 | 05_illusion_075L_ctl_vs_tar.png |
Illusion 0.75L |
| 06 | 06_illusion_10L_ctl_vs_tar.png |
Illusion 1.0L |
| 07 | 07_illusion_15L_ctl_vs_tar.png |
Illusion 1.5L |
| 08 | 08_karman_ctl_vs_tar.png |
Karman cloak re100 |
| 09 | 09_vortex_lamb_ctl_vs_tar.png |
Vortex Lamb |
| 10 | 10_vortex_taylor_ctl_vs_tar.png |
Vortex Taylor |
Vortex Diagnosis
| # | Figure | Content |
|---|---|---|
| 11 | 11_vortex_lamb_diagnosis.png |
Lamb sensor + action comparison |
| 12 | 12_vortex_taylor_diagnosis.png |
Taylor sensor + action comparison |
| 13 | 13_vortex_lamb_vorticity.png |
Lamb vorticity field evolution |
| 14 | 14_vortex_taylor_vorticity.png |
Taylor vorticity field evolution |
| 15 | 15_vortex_lamb_target_vorticity.png |
Lamb target (no pinball) reference |
| 16 | 16_vortex_taylor_target_vorticity.png |
Taylor target (no pinball) reference |
Key Numerical Results
Correction-field CCD (2026-06-28, unified geometry)
| Metric | 0.75L | 1.0L | 1.5L |
|---|---|---|---|
| O(dq_ctl, dq_tar) mode1 (r=6) | 0.383 | 0.926 | 0.922 |
| O(dq_ctl, dq_tar) mode1 (r=10) | 0.320 | 0.684 | 0.661 |
| Force-CCD m80 (r=6) | 2 | 2 | 1 |
| Action sigma1 (r=6) | 1.49 | 1.17 | 0.20 |
Cloak dq_ctl RMS (cropped x=[300,1100])
| Scene | RMS | Type |
|---|---|---|
| steady_cloak | 0.196 | Steady, open-loop |
| karman_re100 | 0.397 | Periodic, PPO closed-loop |
| vortex_lamb | 0.146 | Transient, PPO closed-loop |
| vortex_taylor | 0.188 | Transient, PPO closed-loop |
Key findings:
- Cloak mechanism is independent of upstream condition (steady/vortex street/transient vortex all share the same dq_ctl structure)
- Illusion 1.0L achieves near-perfect overlap (O=0.926) via "cloak physics + target frequency modulation"
- Illusion 1.5L uses a fundamentally different mechanism (high-freq modulation, action sigma1=0.20 vs 1.17-1.49)
- 0.75L overlap dropped from 0.564→0.383 after fixing geometry alignment — old number was inflated
CCD Quantitative (JSON)
| File | Content |
|---|---|
results/ccd/correction_ccd_results.json |
Force/Action-CCD per scene (r=6,8,10), O(dq_ctl,dq_tar) per mode |
results/ccd/zone_metrics.json |
Per-zone KE and enstrophy |
Full Documentation
| File | Content |
|---|---|
PIPELINE.md |
This file — pipeline overview, conventions, results index |
README.md |
Quick start |
ccd_knowledge.md |
Complete knowledge base (theory, methodology, detailed results, bug history) |
Lyu23.md |
CCD method paper (Lyu 2023) |
Adding New Training Results
When new DRL models are trained (e.g. on new CelerisLab solver):
- Collect fields: Run the appropriate
scripts/collect_*.pywith the new model path - Phase alignment:
detect_period.py→replay_fields.py(for periodic scenes) - Correction fields: Already handled by
compute_correction_fields.py— just ensure the scene name is registered inconfigs.py_SCENE_MAP - Regenerate figures:
compare_dqctl_scenes.pyanddiagnose_corrections.py - Regenerate CCD:
decompose_corrections.py - Symlink: Add new figures to
results/figures/
The configs.py SCENES dict is the single source of truth — add new scenes there and all analysis scripts automatically pick them up.
Environment
- Conda:
pycuda_3_10 - GPU: Device 2 (check with
nvidia-smibefore collection) - CPU-only steps: POD, CCD, analysis scripts