read_result() returns cases/provenance for the old bare-list receipts and
the new schema-2 object, and rejects unknown schemas. Existing evidence
(e.g. 70f6617) and its digest scripts stay valid for schema 1; queue and
digest scripts must use read_result(...)['cases'] for new receipts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
55 lines
3.1 KiB
Markdown
55 lines
3.1 KiB
Markdown
# DFG 2D-1 (Re 20) against the official reference intervals
|
|
|
|
`tests/validation/run_dfg_re20.py` runs the steady DFG 2D-1 case on the refined
|
|
channel root (D40 root, D80 wide fine patch) and on the uniform D80 grid. Geometry,
|
|
inflow, initial state, layout and observation are those of the pinned Re100 runner
|
|
(`run_refined_dfg.py`, `re100_helpers.py`, both unchanged); only the lattice
|
|
viscosity is set for Re 20 (root tau 0.56, fine 0.62, uniform 0.62, lattice speed 0.01).
|
|
|
|
Label: "compared against the official reference bands", not a full benchmark
|
|
certification: the outlet is pressure-NEQ (`neq_extrap`), not do-nothing, and the
|
|
inlet is local Zou-He.
|
|
|
|
## Quantities
|
|
|
|
- Cd = 2 Fx / (rho U^2 D), Cl = 2 Fy / (rho U^2 D), interval means over each sample.
|
|
- p_diff = p(0.15, 0.2) - p(0.25, 0.2), linear extrapolation to the exact surface
|
|
points (`re100_helpers.pressure_probes`). The helper returns dp / (rho U^2) in
|
|
scaled units; p_diff = dp * 0.04 for U = 0.2 m/s, rho = 1. Both are reported.
|
|
- Official intervals (Schaefer & Turek 1996): Cd [5.57, 5.59], Cl [0.0104, 0.0110],
|
|
p_diff [0.1172, 0.1176].
|
|
|
|
## Bounds and steady rule (frozen before any run)
|
|
|
|
- End time t* = 60 (30 s physical): 240,000 refined root steps, 480,000 uniform steps.
|
|
- One sample every t* = 0.5 (0.25 s) at the end of a synchronized root step; Cd and
|
|
Cl are interval means. Trailing window t* 50..60 inclusive (21 samples).
|
|
- Steady rule (our engineering choice, not official): in the window, for each of Cd,
|
|
Cl, p_diff, max - min <= 10 % and |least-squares slope x window| <= 2 % of its
|
|
official interval width (range 2e-3 / 6e-5 / 4e-5; slope 4e-4 / 1.2e-5 / 8e-6).
|
|
Absolute limits, so the small Cl is never a divisor. Never relaxed after a run.
|
|
- The verdict uses the window mean; the distance to the nearest interval edge is
|
|
reported for each quantity (negative outside).
|
|
- Force sign: fluid on cylinder, x along the inflow, y up from the bottom wall; Cd > 0
|
|
and the official Cl > 0 (`cd_positive` is reported).
|
|
- Not steady at t* = 60: status `NOT_STEADY`, no interval verdict. Health limits
|
|
(Mach <= 0.2, rho in [0.5, 1.5]) stop the run with `UNHEALTHY`.
|
|
- Steady: `WITHIN_INTERVALS` or `OUTSIDE_INTERVALS`, with the per-quantity verdict.
|
|
|
|
## Run
|
|
|
|
```
|
|
python tests/validation/run_dfg_re20.py --output <new-dir> --plan
|
|
CUDA_VISIBLE_DEVICES=<n> python tests/validation/run_dfg_re20.py --case both \
|
|
--collision SRT --output <new-dir> --max-wall-seconds <cap>
|
|
```
|
|
|
|
The uniform D80 control separates method error from refinement error. `--plan` writes `plan.json` only. A GPU run writes `plan.json` and `result.json`
|
|
(per case: lattice parameters, every sample, window ranges, status, verdict).
|
|
Receipts: `plan.json` and `result.json` carry `schema` 2 and `provenance` (HEAD, src tree,
|
|
runner hash; clean checkout required, refused if it changes during the run). Receipts
|
|
written before this (schema 1, e.g. evidence 70f6617) are a bare list of cases. Read both
|
|
with `run_dfg_re20.read_result(path)` (`["cases"][0]` replaces the old `[0]`); existing
|
|
evidence scripts stay valid for schema-1 receipts and need this reader for new ones.
|
|
Host contract tests: `tests/unit/test_dfg_re20.py`.
|