refactor(SR): freeze compact legacy evidence package
Archive excluded experiments and superseded outputs so the active tree exposes only the auditable Kármán and Illusion workflow while preserving scientific provenance. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+34
-234
@@ -1,254 +1,54 @@
|
||||
# SR analysis: agent entry point
|
||||
# SR analysis
|
||||
|
||||
This directory contains the active symbolic-regression analysis for extracting compact control laws from the legacy PPO policies of the fluidic pinball.
|
||||
## Authority and scope
|
||||
|
||||
**Start here, then read `PIPELINE.md`.** The active scientific workflow has exactly three entry points:
|
||||
This directory is the frozen symbolic-regression evidence package for the LegacyCelerisLab fluidic pinball. The active scientific scope is Kármán-cloak and Illusion PPO data collection, symbolic discovery/refit, closed-loop CFD validation, sampled duration/generalization extensions, term deletion/scaling, and canonical publication export. The disturbance-free `steady` scene remains only as the calibration used to interpret the Kármán rear constant.
|
||||
|
||||
1. `stage_1_infer.py` — collect run-scoped PPO trajectories.
|
||||
2. `stage_2_fit.py` — discover and refit symbolic structures.
|
||||
3. `stage_3_validate.py` — evaluate formulas in closed-loop CFD with the legacy DTW metric.
|
||||
The authoritative evidence index is `results/README.md`; execution details are in `PIPELINE.md`. Material under `archive/` is historical, excluded, or non-authoritative.
|
||||
|
||||
The current article evidence is indexed in `results/README.md`. The manuscript-ready SR section is `../../docs/JFM_WYQ/SR_Draft.md`.
|
||||
## Three-stage workflow
|
||||
|
||||
## Scientific question
|
||||
1. `stage_1_infer.py`: collect immutable, run-scoped Legacy PPO trajectories for trained Kármán and Illusion scenes.
|
||||
2. `stage_2_fit.py`: perform broad per-case discovery, within-objective joint discovery, and fixed-topology all-data coefficient refit.
|
||||
3. `stage_3_validate.py`: deploy PPO, symbolic, uncontrolled, or constant policies in serial Legacy CFD and evaluate the exact legacy DTW contract.
|
||||
|
||||
SR is not used to maximize imitation of PPO actions. It is used to determine whether successful PPO control contains a compact, symmetric and physically interpretable feedback structure that remains effective when deployed in CFD.
|
||||
The acceptance chain is data and wiring checks → offline discovery/Pareto diagnostics → frozen topology and coefficient refit → finite closed-loop CFD → 200-step acceptance → 400-step duration and sampled unseen-condition checks → term deletion/scaling. Offline R² helps discover structure; it does not accept a controller. Averages never override a non-finite or prematurely terminated case.
|
||||
|
||||
The selection chain is therefore:
|
||||
## Scientific contracts
|
||||
|
||||
```text
|
||||
PPO trajectories
|
||||
-> broad per-case variable/topology discovery using R² and Pareto fronts
|
||||
-> within-objective joint topology discovery
|
||||
-> fixed-topology coefficient refit using all accepted rows
|
||||
-> short and standard closed-loop CFD screening using legacy DTW
|
||||
-> term-deletion and coefficient-scaling tests
|
||||
-> physical interpretation and explicit limitations
|
||||
```
|
||||
- **Solver/model/norm:** Stage 1 and Stage 3 use LegacyCelerisLab and the frozen legacy PPO models. Runtime PPO observations use the scene's frozen `data/karman/**/norm.json` or `data/illusion/**/norm.json`; PPO inference defaults to CPU while PyCUDA owns the CFD GPU.
|
||||
- **Native order:** bodies/actions are `front, upper, lower`; forces are front, upper, lower with `(x,y)` components; sensors are upper, centre, lower with `(u_x,u_y)` components. `checks/order_contract.py` is the runtime gate.
|
||||
- **Causal alignment:** Stage 2 uses `causal_post_state_to_next_action`: recorded post-state `i` predicts action `i+1`. Warm-up and lag construction are trajectory-local and splits do not cross trajectories.
|
||||
- **Action units:** formulas output `alpha = omega/U0`. PPO normalized actions are decoded with the scene scale and bias before fitting; Stage 3 converts formula outputs back to `omega` for CFD.
|
||||
- **Mapped-shared deployment:** the canonical architecture is `alpha_F=(h_F(x)-h_F(Gx))/2`, `alpha_U=h_R(x)`, `alpha_L=-h_R(Gx)`. This imposes exact reflection symmetry; it is not a claim that PPO training was equivariant. Three independent heads are diagnostic only.
|
||||
- **Metric:** `legacy_dtw_v1_abs_n_unclipped`, reported as `legacy_reference_cycle_vs_last_recorded_cycle`, is the exact acceptance metric. Its fitted circular lag is part of the historical comparison algorithm, not a physical delay.
|
||||
- **Names:** Kármán scene `re_code` uses reference length `2D`, so `Re_D=re_code/2`. Illusion labels such as `1L` are historical: the stored `target_diameter` value is passed to `add_cylinder` as a radius and must not be silently relabelled as a physical diameter.
|
||||
|
||||
R² is a discovery diagnostic. It is not the acceptance criterion. Closed-loop stability and DTW decide whether a candidate is useful; deletion and scaling tests decide whether its terms are necessary.
|
||||
## Current claim and evidence chain
|
||||
|
||||
## Current article scope
|
||||
Accepted training data are `data/runs/article-joint-data-karman-20260718` (Re-code 50/100/200/400) and `data/runs/article-joint-data-illusion-20260718` (0.75L/1L/1.5L). Formula discovery, refits, accepted and rejected CFD, 400-step duration, sampled unseen points, deletion/scaling, steady calibration, and plotting are retained under `results/runs/article-*` and `results/runs/article2-*` because their manifests and parent paths are provenance dependencies.
|
||||
|
||||
Two objectives are fitted separately:
|
||||
The Kármán evidence supports a controller dominated by persistent rear counter-rotation, with secondary rear-lift feedback and weak tested front feedback. The steady sweep calibrates the rear constant's magnitude; it is not a third fitting objective. The Illusion result is a finite symmetric numerical family, but its terms are partly replaceable and it does not establish explicit target tracking. Neither result proves global symbolic optimality, causal flow mechanism, universal high-Re behavior, or distribution-wide generalization; Article2 supports only the explicitly sampled conditions.
|
||||
|
||||
- **Kármán cloaking:** `karman_re50`, `karman_re100`, `karman_re200`, `karman_re400`.
|
||||
- **Illusion:** `illusion_0.75L`, `illusion_1L`, `illusion_1.5L`.
|
||||
## Active package map
|
||||
|
||||
Kármán and Illusion are never pooled into one fit. The fitted evidence is limited to these seven training scenes. The coefficient-frozen 2026-07-20 extension tests additional Reynolds-number and target-size points, but those points did not participate in fitting or model selection. Vortex, V5 and historical figures remain outside the current article evidence.
|
||||
|
||||
Seven new 200-step PPO trajectories were collected in:
|
||||
|
||||
- `data/runs/article-joint-data-karman-20260718/`
|
||||
- `data/runs/article-joint-data-illusion-20260718/`
|
||||
|
||||
All seven passed exact recorded-state policy replay. The accepted data inventory is:
|
||||
|
||||
- `results/runs/article-joint-data-audit-20260718/data_inventory.json`
|
||||
|
||||
Historical and round-one assets are retained, but are not silently pooled with the article data. The old `round1-legacy-v2-20260716-*` formulas are diagnostic only because they predate the final force-order contract.
|
||||
|
||||
## Non-negotiable contracts
|
||||
|
||||
### Native order
|
||||
|
||||
The canonical body, force and action order is:
|
||||
|
||||
```text
|
||||
front, upper, lower
|
||||
```
|
||||
|
||||
Sensors are ordered upper, centre, lower. Verify runtime binding with `checks/order_contract.py` before collecting data after any CFD change.
|
||||
|
||||
### Alignment
|
||||
|
||||
The article workflow uses:
|
||||
|
||||
```text
|
||||
causal_post_state_to_next_action
|
||||
```
|
||||
|
||||
Recorded post-state `i` predicts action `i+1`. Each trajectory is built independently so lag features and contiguous splits never cross trajectory boundaries.
|
||||
|
||||
### Action definition
|
||||
|
||||
Formula outputs are dimensionless cylinder surface velocities:
|
||||
|
||||
\[
|
||||
\alpha_i = \omega_i/U_0.
|
||||
\]
|
||||
|
||||
Normalized PPO actions are decoded with the scene action scale and bias before fitting.
|
||||
|
||||
### Exact reflection symmetry
|
||||
|
||||
The article candidate uses mapped-shared deployment:
|
||||
|
||||
\[
|
||||
\alpha_F(x)=\frac{h_F(x)-h_F(Gx)}{2},\qquad
|
||||
\alpha_U(x)=h_R(x),\qquad
|
||||
\alpha_L(x)=-h_R(Gx).
|
||||
\]
|
||||
|
||||
The front projection is exactly odd. The lower action is generated from the shared upper law. Three-head-independent fitting exists only as a PPO-structure diagnostic and is not the final physical architecture.
|
||||
|
||||
Fit augmentation and deployment architecture are separate choices:
|
||||
|
||||
- `--fit-augmentation none|G`
|
||||
- `--deployment-architecture mapped_shared|three_head_independent`
|
||||
|
||||
Hard G symmetry is a deliberate physical symmetrization; it is not presented as a property that the legacy PPO was trained to satisfy.
|
||||
|
||||
### Metric
|
||||
|
||||
The closed-loop metric is:
|
||||
|
||||
```text
|
||||
legacy_dtw_v1_abs_n_unclipped
|
||||
```
|
||||
|
||||
Its exact window is named:
|
||||
|
||||
```text
|
||||
legacy_reference_cycle_vs_last_recorded_cycle
|
||||
```
|
||||
|
||||
There are not separate “full” and “tail” DTW algorithms. Lag is part of the legacy comparison procedure and is not interpreted as a physical observation/control delay.
|
||||
|
||||
## Physical labels and units
|
||||
|
||||
The Kármán scene names contain the historical code Reynolds label `re_code`, defined with reference length `2D`; the cylinder-diameter Reynolds number is therefore \(Re_D=\texttt{re\_code}/2\). The Illusion names `0.75L`, `1L` and `1.5L` are legacy target-size labels: the stored `target_diameter` value is passed to `LegacyCelerisLab.add_cylinder` as a radius. Paper text must not silently reinterpret these labels as physical diameters.
|
||||
|
||||
SR uses dimensionless velocities and force coefficients, not the clipped PPO observation. Rear symmetry coordinates are half-sums and half-differences, for example
|
||||
|
||||
\[
|
||||
C_{d,\mathrm{rear},s}=\frac{C_{d,U}+C_{d,L}}{2},\qquad
|
||||
C_{d,\mathrm{rear},a}=\frac{C_{d,U}-C_{d,L}}{2},
|
||||
\]
|
||||
|
||||
with the same convention for rear lift.
|
||||
|
||||
## Feature strategy
|
||||
|
||||
Broad discovery starts from complete, dimensionless variable representations:
|
||||
|
||||
- `raw_complete`: six velocity components and six cylinder-force components.
|
||||
- `symmetry`: symmetric/antisymmetric velocity and force coordinates.
|
||||
- `physics_reduced`: compact diagnostics only; it is not the starting point for article discovery.
|
||||
|
||||
Illusion comparisons use non-overlapping profiles:
|
||||
|
||||
- `actual_only`
|
||||
- `target_only`
|
||||
- `actual_plus_target`
|
||||
- `actual_plus_error`
|
||||
|
||||
Target/error derivatives or other temporal features are added only after static variables are shown insufficient. Cross-correlation is never used to select a lag.
|
||||
|
||||
## Current results
|
||||
|
||||
### Kármán joint candidate
|
||||
|
||||
\[
|
||||
\alpha_F=\operatorname{odd}\!\left[-0.381391\,C_{d,\mathrm{rear},a}\right],
|
||||
\]
|
||||
|
||||
\[
|
||||
\alpha_U=1.307782\,C_{l,\mathrm{rear},s}-3.431209,
|
||||
\qquad
|
||||
\alpha_L=-\alpha_U(Gx).
|
||||
\]
|
||||
|
||||
Standard 200-step legacy DTW:
|
||||
|
||||
- Re50: `0.9543`
|
||||
- Re100: `0.9427`
|
||||
- Re200: `0.8560`
|
||||
- Re400: `0.7827`
|
||||
|
||||
Deletion tests support the ordering:
|
||||
|
||||
```text
|
||||
rear constant > rear lift feedback > front drag-asymmetry feedback
|
||||
```
|
||||
|
||||
This is consistent with the physical hypothesis that persistent rear counter-rotation provides the principal downstream velocity-deficit compensation. The SR evidence ranks controller terms but does not establish the spatial momentum correction or causality; those claims require OID/CCD. The law is not uniformly strong at Re400 and must not be called universal.
|
||||
|
||||
### Illusion joint numerical candidate
|
||||
|
||||
\[
|
||||
\alpha_F=\operatorname{odd}\!\left[-1.826604\,C_{d,\mathrm{rear},a}+2.064493\,C_{l,F}\right],
|
||||
\]
|
||||
|
||||
\[
|
||||
\alpha_U=1.254440\,C_{d,\mathrm{rear},a}-1.528074\,C_{l,F},
|
||||
\qquad
|
||||
\alpha_L=-\alpha_U(Gx).
|
||||
\]
|
||||
|
||||
Standard 200-step legacy DTW:
|
||||
|
||||
- 0.75L: `0.8749`
|
||||
- 1.0L: `0.9217`
|
||||
- 1.5L: `0.8306`
|
||||
|
||||
Scaling tests show that the `Cl_F` terms dominate action magnitude; the `Cd_rear,a` terms are weaker and partly replaceable. Every one-term deletion remained stable, so the current expression is not a unique mechanism law. Target/error variables were available but were not selected stably by low-complexity static joint discovery. This is a numerical joint reference, not proof of explicit target tracking.
|
||||
|
||||
## What can and cannot be claimed
|
||||
|
||||
Supported:
|
||||
|
||||
- A complete, reproducible discovery-to-CFD-to-ablation workflow.
|
||||
- Strong Kármán evidence for dominant rear counter-rotation and secondary rear lift feedback.
|
||||
- A symmetric Illusion joint family that remains finite across all three trained target-size labels.
|
||||
- R² and formula appearance alone are insufficient predictors of closed-loop value.
|
||||
|
||||
Not supported:
|
||||
|
||||
- Global symbolic optimality or uniqueness.
|
||||
- A universal Kármán law at Re400.
|
||||
- An explicit target-tracking mechanism for Illusion.
|
||||
- Necessity of every Illusion term.
|
||||
- Physical delay inferred from DTW lag or cross-correlation.
|
||||
- Distribution-wide or universal generalization. The Article2 extension supports only finite pointwise deployment at its explicitly sampled unseen conditions.
|
||||
|
||||
## Directory map
|
||||
|
||||
```text
|
||||
SR_analysis/
|
||||
├── README.md # this agent entry point
|
||||
├── PIPELINE.md # exact method, commands and design decisions
|
||||
├── configs.py # scene and action contracts
|
||||
├── stage_1_infer.py # PPO data collection
|
||||
├── stage_2_fit.py # discovery and fixed-topology refit
|
||||
├── stage_3_validate.py # closed-loop CFD and legacy DTW
|
||||
├── checks/ # pre-fit physical/wiring gates
|
||||
├── diagnostics/ # diagnostic-only analyses
|
||||
├── utils/ # feature, G, formula, data and provenance contracts
|
||||
├── tests/ # SR CPU contract tests
|
||||
├── results/README.md # evidence index and result status
|
||||
├── tools/ # integrity audit; audit is not scientific promotion
|
||||
├── experiments/v5/ # excluded experimental pipeline
|
||||
└── archive/ # inactive Stage 4 and historical guides
|
||||
```
|
||||
|
||||
`old/`, `archive/`, `experiments/v5/`, historical formula directories and old reports are context only. They are not authoritative sources for article numbers.
|
||||
|
||||
## Environments and resource discipline
|
||||
|
||||
- Stage 1, policy replay and Stage 3: `pycuda_3_10`; PPO inference defaults to CPU so physical GPU 2 remains dedicated to the PyCUDA CFD context.
|
||||
- Stage 2/PySR and coefficient refit: `sr_env`.
|
||||
- CFD uses physical GPU 2 and is strictly serial.
|
||||
- When `CUDA_VISIBLE_DEVICES=2`, the process uses logical device `0`; provenance records both visibility and GPU UUID rather than mislabelling the physical ordinal.
|
||||
- Every run ID is immutable; failed telemetry is retained.
|
||||
- Root: `configs.py`, the three stages, this README, and `PIPELINE.md`.
|
||||
- `checks/`: order and policy-replay gates.
|
||||
- `utils/`: active data, feature, symmetry, metric, formula, CFD, and provenance contracts.
|
||||
- `tools/`: canonical plotting/export tools (`prepare_plotting_data.py`, `telemetry_to_csv.py`, both SR plotting modules, and `export_flow_comparison.py`).
|
||||
- `tests/`: CPU contract tests.
|
||||
- `data/`: frozen Kármán/Illusion norms, steady calibration data, and the two accepted article data runs.
|
||||
- `results/`: the evidence index and provenance-dependent `article-*`/`article2-*` families.
|
||||
- `archive/`: excluded experiments, diagnostics, old run families, superseded flat surfaces, and historical code/docs. Archive paths may be non-executable.
|
||||
|
||||
## Verification
|
||||
|
||||
At the 2026-07-21 plotting-package revision, the SR contract suite contains 88 passing tests. Run from the repository root:
|
||||
From the repository root:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src conda run -n sr_env python -m pytest \
|
||||
src/SR_analysis/tests tests/test_stage_3_validate.py -q
|
||||
PYTHONPATH=src conda run -n sr_env python -m pytest src/SR_analysis/tests -q
|
||||
python3 -m compileall -q src/SR_analysis/configs.py src/SR_analysis/stage_1_infer.py src/SR_analysis/stage_2_fit.py src/SR_analysis/stage_3_validate.py src/SR_analysis/utils src/SR_analysis/checks src/SR_analysis/tools
|
||||
git diff --check -- src/SR_analysis
|
||||
```
|
||||
|
||||
See `PIPELINE.md` for reproducible commands and `results/README.md` for the exact evidence chain.
|
||||
No GPU CFD is part of this verification.
|
||||
|
||||
Reference in New Issue
Block a user