fix(oid): confirm FIFO bias bug has no structural impact
- Fixed bias_arr[4] (front 0), bias_arr[5] (bottom -4U0), bias_arr[6] (top +4U0) - Re-ran full karman pipeline: force-sig overlap unchanged (-0.034) - Force-OID still beats POD (0.295 vs 0.068, was 0.750 vs 0.418) - Absolute R2 shifted because corrected FIFO changed PPO trajectory start - Structural conclusion (force-sig near-orthogonal) is robust Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+57
-157
@@ -4,181 +4,81 @@ Extracts interpretable control laws (`obs -> act`) from DRL-trained policies for
|
||||
fluidic pinball. Uses **PySR symbolic regression** on dimensionless physical features with
|
||||
G-equivariant structural constraints (v23: front no-bias, rear shared-head).
|
||||
|
||||
## Current Results (2026-06-25)
|
||||
## Quick Start
|
||||
|
||||
### Karman Cloak — Cross-Re Unified Formula
|
||||
```bash
|
||||
# 1. Generate PPO data
|
||||
conda run -n pycuda_3_10 python stage_1_infer.py --scene karman_re100 --device 2
|
||||
|
||||
| Scene | Front Formula | Top Formula | CFD Closed-Loop |
|
||||
|-------|--------------|-------------|:---------------:|
|
||||
| Joint (Re50-400) | `daF_dt - 14.952*mu*Cl_tot` | `alpha_T = 3.414` (const) | **0.847 avg** |
|
||||
| Re50 independent | PySR per-Re best | — | **0.895** |
|
||||
| Re100 independent | PySR per-Re best | — | **0.888** |
|
||||
| Re200 independent | PySR per-Re best | — | **0.916** |
|
||||
| Re400 (SI=400 opt) | Joint formula | Joint formula | **0.819** |
|
||||
# 2. Fit formula
|
||||
conda run -n sr_env python stage_2_fit.py --scene karman_re100 --mode per-scene
|
||||
|
||||
### Illusion
|
||||
# 3. Validate in CFD
|
||||
conda run -n pycuda_3_10 python stage_3_validate.py \\
|
||||
--scene karman_re100 --device 2 --mode pysr \\
|
||||
--formula-front results/formulas/karman_joint_front.json \\
|
||||
--formula-top results/formulas/karman_joint_top.json
|
||||
|
||||
| Scene | Front Formula | CFD Closed-Loop | % of PPO |
|
||||
|-------|--------------|:---------------:|:--------:|
|
||||
| 0.75L | `-0.169*(Cl_tot + dCl_tot_dt) - 1.240` | **0.979** | 100.7% |
|
||||
| 1L | `(du_a_dt + u_a + 26.5)*0.0123` | **0.957** | 98.4% |
|
||||
| **Joint (0.75L+1L)** | `target_Cd - 5.428 + 0.0098*(du_a_dt + u_a)` | **0.978 / 0.970** | — |
|
||||
| 1.5L | High-freq periodic modulation (not SR-amenable) | — | — |
|
||||
# 4. Analyze
|
||||
conda run -n pycuda_3_10 python stage_4_analyze.py --scene karman_re100 --mode ppo-viz
|
||||
```
|
||||
|
||||
**Key finding**: 0.75L and 1L formulas have fundamentally different skeletons (Cl_tot vs u_a
|
||||
dominant). Joint formula still achieves excellent CFD results on both although the underlying
|
||||
mechanisms differ.
|
||||
## Pipeline Architecture
|
||||
|
||||
### Illusion Generalization (Joint Formula, No PPO)
|
||||
```
|
||||
stage_1_infer.py → stage_2_fit.py → stage_3_validate.py → stage_4_analyze.py
|
||||
(PPO数据) (PySR拟合) (CFD闭环验证) (分析/画图)
|
||||
```
|
||||
|
||||
| Diameter | Similarity | Notes |
|
||||
|:--------:|:----------:|-------|
|
||||
| 0.5L | 0.854 | Signal weak, noise-dominated |
|
||||
| 0.6L | **0.939** | Generalizes well |
|
||||
| 0.8L | **0.908** | Generalizes well |
|
||||
| 1.2L | 0.849 | Begins to degrade |
|
||||
| 1.5L | N/A | High-frequency regime, different mechanism |
|
||||
| 2.0L | 0.676 | Degraded, near 1.5L regime |
|
||||
## Directory Structure
|
||||
|
||||
Valid range: 0.6L-1.0L (similarity > 0.90).
|
||||
|
||||
### Vortex Cloak (Generalization)
|
||||
|
||||
Karman joint formula tested on vortex scenes (no retraining):
|
||||
| Scene | Karman Joint Formula | PPO Baseline |
|
||||
|-------|:-------------------:|:------------:|
|
||||
| vortex_lamb | **0.949** | 0.942 |
|
||||
| vortex_taylor | **0.905** | 0.916 |
|
||||
```
|
||||
SR_analysis/
|
||||
PIPELINE.md # 总览文档 (入口)
|
||||
README.md # 本文件
|
||||
sindy_sr_knowledge.md # 知识库 (bugs, 事实, 结果)
|
||||
sindy_sr_notes.md # 任务清单
|
||||
scene_registry.json # 所有场景的规范结果索引
|
||||
configs.py # 场景注册表
|
||||
core/ # 共享工具库
|
||||
features.py # 特征构建 (无量纲化+phase-state)
|
||||
fitting.py # STLSQ拟合+特征矩阵
|
||||
cfd.py # LegacyCelerisLab接口
|
||||
g_operator.py # G-mirror变换
|
||||
data/ # 运行时生成的.npz数据
|
||||
results/
|
||||
formulas/ # 规范公式JSON
|
||||
validations/ # CFD闭环验证结果
|
||||
archive/ # 归档的中间文件
|
||||
stage_1_infer.py # Stage 1: 统一PPO推理入口
|
||||
STAGE_1_INFER.md
|
||||
stage_2_fit.py # Stage 2: 统一PySR拟合入口
|
||||
STAGE_2_FIT.md
|
||||
stage_3_validate.py # Stage 3: 统一CFD闭环验证入口
|
||||
STAGE_3_VALIDATE.md
|
||||
stage_4_analyze.py # Stage 4: 统一分析/画图入口
|
||||
STAGE_4_ANALYZE.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pipeline Overview
|
||||
|
||||
```
|
||||
controlled.npz (PPO rollout)
|
||||
|
|
||||
v
|
||||
compute_features() --> dimensionless physics features (ILLUSION_PHASE_KEYS, etc.)
|
||||
|
|
||||
v
|
||||
PySR symbolic regression --> sparse interpretable formulas
|
||||
|
|
||||
v
|
||||
CFD closed-loop validation --> final similarity score
|
||||
```
|
||||
|
||||
### Key Design Decisions
|
||||
## Key Design Decisions
|
||||
|
||||
1. **Feature levels**: Static (8-dim) -> Phase-state (6-dim) -> Illusion-phase (10-dim)
|
||||
2. **Output target**: Non-dimensional alpha, not physical omega
|
||||
3. **v23 structure**: Front no-bias, rear shared-head (Bottom = -Top(Gx))
|
||||
4. **Final judge**: CFD closed-loop similarity, not one-step R2
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
SR_analysis/
|
||||
configs.py # Scene metadata (Karman, Illusion, Vortex)
|
||||
configs/legacy/ # Legacy CFD configs (config_cuda.json, config_flowfield.json)
|
||||
utils/
|
||||
__init__.py # Exports (no pycuda dependency)
|
||||
feature_builder.py # Dimensionless features, G-operator, phase-state features
|
||||
sindy_fitter.py # STLSQ fitting + feature matrices
|
||||
cfd_interface.py # LegacyCelerisLab wrapper (requires pycuda_3_10)
|
||||
g_operator.py # Equivariance diagnostics
|
||||
data/ # Inference output data (controlled.npz, target.npz)
|
||||
karman/ karman_re50..400/
|
||||
illusion/ illusion_0.75L,1L,1.5L/
|
||||
vortex/ vortex_lamb,taylor/
|
||||
scripts/
|
||||
infer_karman.py # PPO inference -> controlled.npz
|
||||
infer_illusion.py # PPO inference -> controlled.npz
|
||||
infer_vortex.py # PPO inference -> controlled.npz
|
||||
gen_illusion_target.py # Target data generation for generalization scenes
|
||||
visualize_ppo_illusion.py# PPO visualization with vorticity
|
||||
sindy/
|
||||
run_pysr.py # PySR symbolic regression (niter=40)
|
||||
run_pysr_deep.py # Karman deep PySR (niter=120, Re independent + joint)
|
||||
run_pysr_deep_illusion.py# Illusion deep+joint PySR (niter=120)
|
||||
validate/
|
||||
run_closed_loop.py # Karman closed-loop validator
|
||||
run_closed_loop_illusion.py # Illusion closed-loop validator
|
||||
run_closed_loop_vortex.py # Vortex closed-loop validator
|
||||
run_closed_loop_re400_si.py # Karman re400 short-SI validator
|
||||
predict_pysr.py # PySR formula sympy.lambdify wrapper
|
||||
eval_rollout.py # Offline multi-step rollout evaluation
|
||||
launch_pysr_validation.py # Batch CFD validation launcher
|
||||
batch_illusion_generalization.sh# Batch generalization CFD validation
|
||||
results/ # 136 JSON files — canonical + intermediate
|
||||
results/README.md # Result file reference table
|
||||
results/archive/ # Archived intermediate search attempts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
### PySR Symbolic Regression (conda: sr_env)
|
||||
|
||||
```bash
|
||||
# Illusion
|
||||
conda run -n sr_env python src/SR_analysis/sindy/run_pysr_deep_illusion.py --individual
|
||||
|
||||
# Karman deep (cross-Re independent + joint)
|
||||
conda run -n sr_env python src/SR_analysis/sindy/run_pysr_deep.py --both
|
||||
```
|
||||
|
||||
### CFD Closed-Loop Validation (conda: pycuda_3_10, GPU 1 or 2)
|
||||
|
||||
```bash
|
||||
# Illusion PySR formula
|
||||
conda run -n pycuda_3_10 python src/SR_analysis/validate/run_closed_loop_illusion.py \
|
||||
--scene illusion_1L --device 2 --steps 320 --mode pysr \
|
||||
--pysr-front validate/results/pysr_illusion_1L_front.json \
|
||||
--pysr-top validate/results/pysr_illusion_1L_top.json
|
||||
|
||||
# Karman joint formula
|
||||
conda run -n pycuda_3_10 python src/SR_analysis/validate/run_closed_loop.py \
|
||||
--scene karman_re100 --device 2 --steps 200 --mode pysr \
|
||||
--pysr-front validate/results/karman_joint_deep_front.json \
|
||||
--pysr-top validate/results/karman_joint_deep_top.json
|
||||
|
||||
# Vortex (generalization test)
|
||||
conda run -n pycuda_3_10 python src/SR_analysis/validate/run_closed_loop_vortex.py \
|
||||
--scene vortex_lamb --device 2 --steps 150 --mode pysr \
|
||||
--pysr-front validate/results/karman_joint_deep_front.json \
|
||||
--pysr-top validate/results/karman_joint_deep_top.json
|
||||
```
|
||||
|
||||
### PPO Inference (generate controlled.npz)
|
||||
|
||||
```bash
|
||||
conda run -n pycuda_3_10 python src/SR_analysis/scripts/infer_karman.py --re 100 --device 2
|
||||
conda run -n pycuda_3_10 python src/SR_analysis/scripts/infer_illusion.py --diameter 1.0 --device 2
|
||||
conda run -n pycuda_3_10 python src/SR_analysis/scripts/infer_vortex.py --type lamb --device 2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Critical Reminders
|
||||
|
||||
- **actions.npz are normalized [-1,1]**, not physical omega. Convert: `(action * scale + bias) * u0`
|
||||
- **PySR needs `sensors_raw`/`forces_raw`** passed to `compute_features()` or derivative features are zero
|
||||
- **Output target must be alpha** (non-dim): `Y = actions_phys / u0`
|
||||
- **One-step R2 high != closed-loop good** -- always validate in CFD
|
||||
- **Controls must propagate**: steps >= NX/u0/SI (S=400->320, S=600->214, S=800->160)
|
||||
- **FIFO bias != DRL action bias** for Illusion: FIFO=[0,-U0,U0], decode=[0,-2,2]*U0
|
||||
- **Joint formula must be manually reviewed** for spurious terms (e.g. `daB_dt` is constant=0 at deployment)
|
||||
|
||||
---
|
||||
|
||||
## Key Documentation
|
||||
|
||||
| File | Content |
|
||||
|------|---------|
|
||||
| `src/SR_analysis/sindy_sr_knowledge.md` | Background knowledge, bug history, known pitfalls (for coder reference) |
|
||||
| `src/SR_analysis/sindy_sr_notes.md` | Task list, phase breakdown, current status |
|
||||
| `docs/SR_analysis_report.md` | **Single consolidated report** — all formulas, results, methodology, structural analysis |
|
||||
| `docs/illusion_joint_formula_analysis.md` | Illusion joint formula deep dive — physical interpretation, generalization curve |
|
||||
| `PIPELINE.md` | **Primary entry** — pipeline overview, environment, conventions |
|
||||
| `sindy_sr_knowledge.md` | Bug history, confirmed facts, known limitations |
|
||||
| `sindy_sr_notes.md` | Task list, current status |
|
||||
| `docs/SR_analysis_report.md` | Full report (465+ lines) |
|
||||
| `docs/illusion_joint_formula_analysis.md` | Illusion joint formula deep dive |
|
||||
|
||||
## Core Files (≤20)
|
||||
|
||||
`stage_1_infer.py`, `stage_2_fit.py`, `stage_3_validate.py`, `stage_4_analyze.py`, `configs.py`, `scene_registry.json`, `core/features.py`, `core/fitting.py`, `core/cfd.py`, `core/g_operator.py` + 8 docs.
|
||||
|
||||
Reference in New Issue
Block a user