Files
rods/docs/engineering/validation.md
Conner Majic 725a72a773 Initial commit: establish deterministic rod-string solver stack.
Set up the C solver core, Node API orchestration, TS GUI workflow, and engineering documentation with cleaned repo hygiene for private Git hosting.

Made-with: Cursor
2026-04-16 21:59:42 -06:00

84 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Validation plan
Last Updated: 2026-04-16
## Determinism
- Same XML + same `solverModel` + `workflow` → identical `solver.card` arrays (bitwise for floats at printed precision in C stdout path).
- API responses include `runMetadata.generatedAt`**stripped** before golden hash in tests.
## Golden file
- File: `data/golden/default.solve.sha256`
- Content: SHA-256 of **canonical JSON** string from `GET /solve/default?solverModel=fdm` with `generatedAt` removed and stable key ordering (`stableStringify` in tests).
## Unit coverage
- XML parser: numeric + array + unit conversion.
- `cardQa.js`: min samples, cycle closure, spike rejection.
- C: `test_solver` — determinism, bounds, static equilibrium helper, undamped wave CFL identity, FDM vs FEA peak tolerance.
## Cross-model (FDM vs FEA)
- C unit gate (`solver-c/tests/test_solver.c`): `|maxPolishedLoad_FDM - maxPolishedLoad_FEA| < 7e5 N` on an SI-normalized fixture (interim; tighten when BC parity improves).
## Integration
- `solver-api/tests/api.test.js` — solve routes, diagnostic path, golden hash, `validate-card`, `both` comparison keys.
- `comparison` schema v2 includes:
- `peakLoadDeltas` for Pmax/Pmin and Dmax/Dmin
- `pointwiseResiduals.series[]` (position + polished/downhole residuals)
- `residualSummary` RMS
- `fourier` optional baseline block (`null` unless `options.enableFourierBaseline=true`)
## Extended physics validation
- `options.enableProfiles=true` must return `solver.profiles` with `nodeCount > 0` and finite trajectory/side-load/friction arrays.
- `options.enableDiagnosticsDetail=true` must return `solver.diagnostics` with valve-state booleans and finite chamber/gas series.
- `options.enableFourierBaseline=true` must return non-null `comparison.fourier` and finite residual RMS metrics.
## Priority validation roadmap (15)
### 1) Correctness gates (mandatory)
- Field sensitivity checks: each mapped physics input gets ±1% perturbation and expected directional assertions.
- Invariant checks:
- finite loads/stresses/profiles,
- gas fraction within bounds,
- consistent valve-state transitions,
- no malformed profile/diagnostic arrays.
- Deterministic checks on multi-case golden set.
### 2) Fidelity checks
- Equation-backed vs heuristic term audit must be explicit in docs.
- Stability checks under high-deviation/high-friction cases.
### 3) Cross-model checks
- Case matrix compares FDM vs FEA on:
- peak polished load,
- peak downhole load,
- net stroke,
- residual RMS.
### 4) Contract checks
- Default `/solve` and `/solve/default` responses remain backward compatible.
- Option-gated payload behavior is tested for on/off combinations.
### 5) CI checks
- C sanitizers (ASan/UBSan) lane.
- Performance budget lane (fixed representative cases).
- Artifact lane emits comparison/drift summaries.
## Analytical targets (C tests)
- **Static rod:** uniform bar vertical hang — numerical mean tension trend vs \(\sum \rho g A \Delta x\) (approximate check).
- **Wave CFL:** \(a \Delta t / \Delta x \le 1\) for explicit scheme after clamp.
## GUI
- Smoke: import `base-case.xml`, run solver — manual / Playwright future.