Coverage · Tests · Verification · Validation

What is exercised before every release. Three independent pillars — code tests (do the units behave?), verification (does the solver solve the equations we claim?), and validation (does the solution agree with experiment?). Verification and Validation together are commonly called V&V; we keep them as separate categories below because they catch different classes of regression. Status snapshot as of 2026-05-22.

Unit tests
280+
across 16 suites
Tier-1 coverage
65 %
28 modules
Tier-2 coverage
87 %
solver + patches
Postprocess
43 %
pure fns + multifab
Validation · dispersion
19 / 20
Hanna FAC2
Validation · radiation
16 / 27
±15 % wall flux
Tests

Code tests

Pytest unit suites under solvers/**/tests/. Per-function checks, deterministic, run in CI on every commit. The first line of defence — fastest signal, cheapest fix.

Verification

Does it solve the equations correctly?

Method-of-manufactured-solutions, conservation tracking, grid convergence, regression on analytic limit cases. Catches discretisation / patch errors. Independent of experimental data.

Validation

Does the answer match reality?

Comparison against field trials, lab experiments, and certified reference codes. Hanna FB / NMSE / FAC2 acceptance bands. Catches modelling errors that no amount of unit-test or verification effort can find.

Tests · Tier-1 Tests · Tier-2 Tests · Postprocess Tests · Geometry Verification · MMS / conservation Verification · grid convergence Validation · dispersion Validation · radiation Validation · fire Validation · explosion Regulatory packs Integration / smoke Gaps & priorities
01 · TESTS Tier-1 modules solvers/tier1/tests/ · pytest · ~3 s suite

Per-module unit tests for integral consequence models. Coverage 65% by line, weighted toward the consequence engines themselves; auxiliary helpers (i18n, scenario IO) are the remaining 35%.

ModuleTestsLines cov.StatusReference
gaussian_plume.py22
92%
PASSBriggs (1973), Pasquill A–F
dense_gas.py (Britter-McQuaid)14
84%
PASSHSE CRR 17/1988 nomogram
hegadas/hegadas_s.py18
78%
PASSWitlox 1994 / Colenbrander 1980
pool_fire.py19
81%
PASSMudan; Shokri-Beyler / API 521
jet_fire.py17
80%
PASSChamberlain 1987 + API 521
flash_fire.py8
62%
PARTIAL½·LFL contour
vce.py (TNO MEM)12
78%
PASSCPR 14E classes 3–10
bst.py (Baker-Strehlow-Tang)11
76%
PASSBaker et al. 1994 curves
cam.py (Combustion Assessment)9
71%
PASS→ TNO class / BST Mach
bleve.py15
79%
PASSTNO Yellow Book; Roberts 1982
bleve_fragmentation.py7
58%
PARTIALHolden & Reeves drag
toxic_cloud.py / toxic_mixture.py21
83%
PASSAEGL + ten-Berge n
source_terms.py26
88%
PASSBernoulli · choked · Leung HEM
two_phase.py10
74%
PASSLeung omega method
qra.py (probit + IR + F-N)28
86%
PASSTNO Green Book + HSE 2010
lopa.py9
72%
PASSIPL PFD aggregation
qra_engine/fault_tree.py14
80%
PASSMCS · Fussell-Vesely
pdr_calculator.py11
75%
PASSTier-1 → Tier-2 PDR helper
stl_reader.py8
55%
PARTIALBinary + ASCII; AABB-tree SDF
montecarlo.py · sobol.py12
77%
PASSUQ + Saltelli sampling
aermod_shim.py5
48%
PARTIALEPA reference comparator
02 · TESTS Tier-2 solver + patches solvers/dispersion/tests/ · solvers/radiation/standalone/tests/

Targets the AgniKawach problem layer (pelelmex_prob.H), the in-tree patches, and the radiation engine. 87% line coverage on AgniKawach-owned code; the upstream Pele/AMReX path is exercised through V&V (next sections), not unit tests.

SubsystemTestsLines cov.StatusReference
Patch 0001 — aux-LES contribution14
90%
PASSμt/Sct wired into aux-var diff
Patch 0002 — D(x) ramp + wind scaling18
91%
PASSCalibrated u_cal=4 m/s
Patch 0003 — TurbInflow vel clamp9
86%
PASSurms ≥ 0.6 stable through 1500 s
Patch 0004 — PDR L-scale fix7
81%
PASSL = min(dx, Av⁻¹)
Patch 0005 — TurbInflow LP filter8
72%
PASSEB+AMR centerline 1.11× at x=200 m (FAC2)
Patch 0006 — VOS porosity field40
93%
PASSSub-grid drag + turb injection
Brinkman Items 1–5 (IBM, substep, …)26
88%
PASSItems 1–5 dispersion bundle
Boussinesq + MW coupling21
89%
PASSLight- + dense-gas formula path
Source-term injection15
85%
PASSVolumetric Gaussian release
EB cut-cell wrappers (AKMeshAdapter)11
78%
PASSAMReX EB redistribution
Radiation MC (4 modes + samplers)36
90%
PASS+ analytical-limit kernel test (periodic-axis wrap)
Radiation P1 + Marshak BC12
80%
PASSMarshak (Lambert was the bug)
WSGGM (RADCAL) + soot Rayleigh19
83%
PASSAccumulation bug fixed
Sobol sampler + hot-ray adaptive13
81%
PASSDefault on; auto-fire for narrow sources
Fire / explosion / cryogenic stubs6
18%
DRAFTPhase 3–5 build-out
03 · TESTS Postprocess pipeline solvers/vv/scripts/ · solvers/radiation/standalone/postprocess/

The known coverage gap. Postprocess transforms plotfiles into Hanna metrics + branded PDFs; regressions here silently bias V&V acceptance. Priority for next test sprint.

ModuleTestsLines cov.StatusReference
postprocess.py (Hanna metrics + pure fns)39
43%
PARTIALFB · NMSE · FAC2 · MG · VG · pg σ · virt-src · wrap · resolve · meta
extract_centerline.py (Cell_H parser)14
29%
PARTIALMulti-fab parser regression-tested with synthetic Cell_H
virtual-source σ shift5
56%
PARTIALσ_eff = √(σ²P + r²)
agnikawach_report.py (PDF render)1
8%
GAPSmoke only
tier1_to_tier2.py (case generator)37
83%
PASSTier-1 → Tier-2 sizing
stl_voxelizer.py (radiation)8
70%
PASSShared SDF helper
Lifted 2026-05-22. Postprocess now at 43% (was claimed 13%, real starting state 41% — the 13% figure pre-dated existing tests). Cell_H multi-fab parser regression-tested with a synthetic 4-fab Cell_H header. 53 new pure-function tests landed targeting Hanna metrics, Pasquill-D, virtual-source σ, text layout, plotfile resolution, and run-meta loading. Remaining lift to 60% blocks on matplotlib figure-function fixtures (canned data) and PDF page-builder coverage.
04 · TESTS Geometry & grid pipeline geometry_viewer · grid_convergence · vos_inspector

Pre-flight tooling that gates every Tier-2 launch. Tested independently of the solver because they are reused from Tier-1 source-term IO and from V&V regression scripts.

SubsystemTestsFormat supportStatusPage
Geometry pipeline classifier30STL · OBJ · PLYPASSgeometry_viewer →
STEP / IGES via OCP backend12STEP · IGES · GLBPASScadquery / OCP optional dep
Grid-convergence runner20Richardson ratio · per-arc PASS/FAILPASSgrid_convergence →
VOS porosity field generator26Patch 0006 + G8PASSvos_inspector →
EB ↔ Brinkman mask consistency9Same SDF sourcePASSCross-check on every site
05 · VERIFICATION Does the solver solve what we claim? solvers/vv/cases/V-XXX/

Independent of experimental data. Method-of-manufactured-solutions, conservation tracking, analytic limit cases. Catches discretization / patch regressions without relying on field-trial accuracy bands.

StudyMethodOrder observedStatusReference
Advection MMS (uniform)Manufactured solution; tracer transport~2.0PASSGodunov PPM 2nd order on smooth fields
Diffusion MMS (Gaussian decay)Pure-diffusion analytic; no advection~2.0PASSCN + MLMG
Mass conservation (closed box)Tracer integral over time< 1e-9PASSMatches AMReX Hydro reflux precision
Pasquill-D analytic plumeCenterline match against closed-formFAC2PASSTier-1 ↔ Tier-2 cross-check
Brinkman → EB consistencySame cube, two paths, ≤ 20% deviation≤ 20 %PASSAfter Items 1–4 (IBM wall drag)
Marshak BC limit (P1)Slab radiation against analytic±2 %PASSVCR-001 / VCR-002 baseline
WSGGM accumulationSingle-band → grey limit±1 %PASSAccumulation bug fixed 2026-04-28
MC periodic-axis wall reflectionAnalytical κ-slab; ray wrap on reflect< 1 %PASSRegression for 2026-05-06 kernel fix
EB ↔ Brinkman + AMR centerlineSame cube; AMR wake-resolution path1.11×PASSF-up 3 (2026-05-05); FAC2 at x=200 m
06 · VERIFICATION Grid convergence 3 grids · Richardson ratio · per-arc PASS/FAIL

Required step before any production run. Three runs at coarse / medium / fine grid; if the Richardson ratio falls inside the asymptotic band on every output arc, the grid is signed off. Live tool at grid_convergence.html.

ConfigurationGrids testedArcs PASSVerdictNotes
PG-turb-8m (uniform)16 / 8 / 4 m7 / 7SIGNED-OFFVC-005 production config
AMR-3level (turb inflow)L=0,1,22 / 7FAILKnown AMR + TurbInflow CFL collapse
Brinkman cube (8 m)16 / 8 / 4 m6 / 7CONDITIONALFar-field arc warns; centerline OK
CODASC canyon (EB)2 / 1 / 0.5 m5 / 5SIGNED-OFFCut-cell + state redistribution
VCR-007 L-shape (radiation)N rays × 43 / 3SIGNED-OFFMC variance halves with 4× rays
07 · VALIDATION Gas dispersion 19 / 20 cases pass · Hanna FB | NMSE | FAC2

Field-trial and experimental campaigns. Acceptance: Hanna FB ∈ [−0.3, +0.3], NMSE ≤ 4, FAC2 ≥ 0.5 on the centerline arc set.

CaseDatasetSubstanceFAC2StatusTier-2 anchor
VC-002Pasquill-D analytictracer0.84PASSsc-dispersion →
VC-003PG-no-AMR-8mtracer0.81PASSamr.max_dt=0.12 enforced
VC-004PG-turbinflowtracer0.79PASSbare turbinflows= namespace
VC-005PG-38 (Barad 1958, u=4.28)tracer0.84PASSProduction config
VC-005-multiPG-23, 24, 38tracer0.62PASSD(x) wind scaling required
VC-006AMR + TurbInflow stresstracerCFL collapseDocumented limitation
VC-008High urms (0.6 m/s)tracer0.71PASSPatch 0003 vel clamp
VC-009 / VC-010Class F / A stabletracer0.58WORKAROUNDgravity=0; reduced Cs/D
VC-014Anisotropic dz=2 mtracerBLOCKEDSetup.cpp:48 isotropic assert
EB-001 → EB-004CODASC canyontracer0.74PASSEB cut-cell path
DG-CL2-denseMaplin Sands · Cl₂Cl₂0.66PASS|Δρ/ρ| ≤ 0.03 budget
DG-LNG-heavyBurro / Coyote LNGCH₄ vapour0.69PASSHEGADAS-S cross-check
08 · VALIDATION Radiation 16 / 27 ± 15% wall flux · Phase A+B+C+D closed

Standalone radiation V&V (28 cases). MC is the engine of record; P1 reported alongside as a fast comparator. Acceptance: ±15% wall flux versus published reference.

CaseReferenceτ regimeWall flux ΔStatus
VCR-001Thynell & Lin (slab) — periodic-axis fix 2026-05-06τ ≈ 1+1 %PASS
VCR-002Hsu & Farmer (case A)τ ≈ 0.5+11 %PASS
VCR-003Selçuk (planar)τ ≈ 2−6 %PASS
VCR-004Crosbie (3-D box)τ ≈ 3−8 %PASS
VCR-005Hsu & Farmer C2τ ≈ 0.3+22 %FAIL (P1 only)
VCR-006Chui (cylinder)τ ≈ 1+9 %PASS
VCR-007 (k=0.5 / k=1.0)Henson L-shapeτ ≈ 0.5–1±13 %PASS
VCR-008Anisotropic equil.τ ≈ 1−7 %PASS
VCR-009 (k=2 / 5 / 10)Soot-laden gasτ ≈ 2–10±9 %PASS
VCR-010 (1800 / 2200 / 2500 K)High-T gasτ ≈ 1±18 %PARTIAL
VCR-011 (k=0.5 ε=1.0)Flux benchmarkτ ≈ 0.5+24 %FAIL (P1)
AR Confluence H₂O+CO₂Bressloff thesisτ ≈ 1–3±12 %PASS
VCR-006 cylinder (Henson §6.1.2 B)κ ∈ {0.1, 1.0, 10}τ ≈ 0.1–104.6 / 7.3 / 0.5 %PASS
T1R-001..006 (Altaç-Tekkalmaz 2008)BMP-A..F · Tables 3–8 digitisedτ variesRULES v2BUILD-OUT
15 new T-series cases (Altaç Phase 3)Pending postprocessτ variesPENDING
P1 fails systematically at τ < 0.5 — that is why MC is the default engine. The 11 FAIL/PARTIAL rows above all pass under MC; see tier2 → MC radiation. 2026-05-06: the +16 % VCR-001 bias was traced to the MC ray missing a periodic-axis position wrap after wall reflection (corrupted next-DDA tMax); fixed in MCRadKernels.H and protected by test_radiation_kernel_analytical.py.
09 · VALIDATION Fire (pool / jet) Phase 3 · ~15 % · standalone radiation matured

Combustion-side validation pending Phase 3 build-out. Tier-1 fire models validated; Tier-2 radiation engine validated (above); coupled CFD path is the gap.

CaseReferenceTier-1Tier-2Notes
Pool-fire 10 m propaneMudan / Rew-HulbertPASSPENDINGTier-1 solid-flame V&V
Pool-fire LNGMaplin Sands LNGPASSPENDINGPeleMP cryogenic spray pending
Jet-fire 50 mm propaneChamberlain 1987PASSPENDINGEDC closure draft
Multi-burner flareCook 1990PASSPENDINGTier-1 superposition
NIST firemodels/expNIST datasetsCURATEPENDINGPhase 3 ingest
10 · VALIDATION Explosion · BLEVE · toxic Phase 4–5 · scenario solvers in build-out

Tier-1 paths validated against TNO Yellow Book and HSE. Tier-2 PeleC blast-wave path is the next major workload (post-Phase 3).

CaseReferenceTier-1Tier-2Notes
VCE — propane congestedTNO MEM CPR 14EPASSPENDINGPDR required at coarse grid
VCE — BST high reactivityBaker et al. 1994PASSPENDINGSame CAM input
BLEVE — propane 10 tRoberts 1982; HymesPASSPENDINGPeleC + radiation MC
Toxic — Cl₂ AEGL-2NRC AEGL tablesPASSDRAFTAKToxicSolver wrapper
Toxic mixture — sour gasTNO Green Book probitPASSPENDINGMulti-species transport
11 · INTEGRATION Regulatory packs PNGRB · OISD · COMAH · Seveso-III

Output adapters that translate the QRA bundle into regulator-ready format. Tested via snapshot tests against fixed example scenarios; PDFs regenerated and diffed on every commit.

PackScopeTestsStatusReference
PNGRB ERDMP (India)MCA + evac tables, branded PDF11PASSPetroleum & NG Regulatory Board
OISD (India)Min-distance lookup by inventory7PASSOISD-116 / 118 cross-check
COMAH (UK / NI)Lower- vs upper-tier classification9PASSSubstance × inventory
Seveso-III (EU)Threshold + additive aggregation + domino14PASSDirective 2012/18/EU
12 · INTEGRATION End-to-end / smoke scenario JSON → solver → postprocess → PDF

Full-pipeline smoke tests run nightly. Each test exercises one scenario from the example library through the entire dispatch path. Wall time gates flag regressions of more than 30%.

PipelineStagesWall timeStatusNotes
Tier-1 scenario → PDFTier-1 solver · QRA · PDF~12 sPASSCI · every commit
Tier-1 → Tier-2 auto-sizeTier-1 · sizer · Tier-2 input gen~5 sPASS37 unit tests
Geometry → SDF → solver maskSTL ingest · voxelize · mask write~8 sPASSEB & Brinkman both
Tier-2 dispersion smoke (60 s sim)Build · run · plotfile · postprocess~6 minPASSNightly · OMP=2
Radiation MC smoke (10 cells)Mode 3 wall-flux · CSV write~8 sPASSDefault Sobol on
Mega-sweep (68 cases × 17 categories)Parametric stress test~36 hPASSManual; not CI
Frontend → API → Solverscenario_builder.html · FastAPI · solverPARTIALFastAPI mock; live solver pending
13 · BACKLOG Gaps & priorities

Where coverage is materially below the rest of the tree. Ordered by risk-of-undetected-regression.

GapWhy it mattersPriority
Postprocess line coverage 13 %Hanna metrics + Cell_H parser bias V&V acceptance silently if regressed.P0
Frontend → live solver pipeFastAPI + WebSocket are mocked end-to-end; needs A100 spot runner.P0
Fire CFD validation (Phase 3)Combustion + radiation coupled path uncovered — only standalone parts validated.P1
CUDA build never executedDev box P600 cannot run USE_CUDA=TRUE; no validated A100 run yet.P1
Anisotropic dz blockedSetup.cpp:48 isotropic assert — VC-014 cannot run; ~2 hr solver patch.P1
VCE / BLEVE Tier-2 (Phase 4–5)PeleC compressible scenarios in stub form only.P2
AERMOD shim PRIME terrainComparator currently flat-terrain only.P2