feat(ccd): light reorganization — results/ dir, PIPELINE.md, numbered figures
- Add PIPELINE.md as primary entry (pipeline overview, conventions, results index, new training integration guide) - Create results/ directory with numbered symlinks to all 16 core figures - Copy final CCD JSON into results/ccd/ - Rewrite README.md to point to PIPELINE.md Design follows SR_analysis lightweight pattern: clear structure, small number of entry files, results/ as canonical output directory. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
# CCD Analysis Pipeline
|
||||
|
||||
> Correction-field CCD analysis for fluidic pinball DRL control.
|
||||
> Core question: does `dq_ctl` (what the controller adds) match `dq_tar` (what the target requires)?
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
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)
|
||||
```
|
||||
|
||||
## 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 object**
|
||||
- **`dq_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_fact` during 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:
|
||||
1. **Cylinder order**: add order is front→TOP(+y)→BOTTOM(−y); reversed caused wrong bias mapping
|
||||
2. **Obs swap**: used `[sensors/force_norm, forces/sens_norm]` instead of force-first `[forces/force_norm, sensors/sens_norm]`
|
||||
3. **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):
|
||||
|
||||
1. **Collect fields**: Run the appropriate `scripts/collect_*.py` with the new model path
|
||||
2. **Phase alignment**: `detect_period.py` → `replay_fields.py` (for periodic scenes)
|
||||
3. **Correction fields**: Already handled by `compute_correction_fields.py` — just ensure the scene name is registered in `configs.py` `_SCENE_MAP`
|
||||
4. **Regenerate figures**: `compare_dqctl_scenes.py` and `diagnose_corrections.py`
|
||||
5. **Regenerate CCD**: `decompose_corrections.py`
|
||||
6. **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-smi` before collection)
|
||||
- **CPU-only steps**: POD, CCD, analysis scripts
|
||||
Reference in New Issue
Block a user