[
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A1P-001_darcy_weisbach_single_pipe",
  "test_class": "verification_analytic",
  "title": "Darcy–Weisbach single pipe",
  "description": "Steady flow through a 1 km, 300 mm pipe at 1 m/s. The friction factor follows from Colebrook–White, so the exact head loss Δh = f (L/D) V²/(2g) = 3.09 m checks both the friction law a solver uses and how it applies it.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "pressurized",
   "governing_equations": [
    "darcy_weisbach",
    "continuity"
   ],
   "phenomena": [
    "pipe_friction",
    "steady_flow"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Darcy, H.",
      "Weisbach, J."
     ],
     "year": 1845,
     "title": "Classical Darcy–Weisbach pipe-friction relation (as used in EPANET hydraulics)",
     "report_number": "EPA/600/R-20/133 §3"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/params.json",
    "role": "case_parameters",
    "format": "json",
    "sha256": "60886c40a73717c5130318da3c03ef74bfb27102726d9ff8c4c73e55e13bb961"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.darcy_weisbach",
    "function": "head_loss",
    "parameters": {
     "L": 1000.0,
     "D": 0.3,
     "V": 1.0,
     "f": null,
     "roughness": 0.00015,
     "nu": 1e-06,
     "g": 9.81,
     "H0": 100.0
    }
   }
  },
  "simulation": {
   "t_end": 1.0,
   "output_interval": 1.0,
   "required_outputs": [
    "h",
    "Q"
   ],
   "steady": true
  },
  "scoring": {
   "criteria": [
    {
     "id": "head_loss",
     "metric": "relative_head_loss",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 1.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Exact Colebrook–White head loss within 1 %: the accuracy Swamee & Jain (1976) give for their explicit approximation over 5e3 < Re < 1e8, so a solver using any standard explicit friction formula passes and a wrong friction law or a units error fails."
    },
    {
     "id": "head_profile",
     "metric": "L2",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.05,
      "units": "m"
     },
     "gating": true,
     "rationale": "Heads along the pipe within 5 cm of the linear exact profile: catches a correct total loss distributed wrongly."
    }
   ],
   "convergence": {
    "not_applicable": "Steady closed-form pipe flow: a network solver has no grid to refine, so observed order of accuracy does not apply."
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A1P-010_todini_multiloop",
  "test_class": "verification_analytic",
  "title": "Todini multi-loop network",
  "description": "Steady two-loop gravity network (Alperovits & Shamir 1977 topology, fixed analysis diameters, Hazen–Williams). Reference heads and flows from a Todini–Pilati gradient solve converged to 1e-12 m, cross-checked against EPANET 2.2 (|ΔH| < 1 mm).",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "pressurized",
   "governing_equations": [
    "darcy_weisbach",
    "network_continuity"
   ],
   "phenomena": [
    "looped_network",
    "steady_hydraulics"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Todini, E.",
      "Pilati, S."
     ],
     "year": 1988,
     "title": "A gradient algorithm for the analysis of pipe networks",
     "isbn": "9780863800948"
    },
    {
     "authors": [
      "Alperovits, E.",
      "Shamir, U."
     ],
     "year": 1977,
     "title": "Design of optimal water distribution systems",
     "doi": "10.1029/WR013i006p00885"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/network.json",
    "role": "network",
    "format": "json",
    "sha256": "e93cd1cba8d75846db32789065c81026c11b0b3334f307fa3342a42d552410f8"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.todini",
    "function": "steady_network",
    "parameters": {
     "network_path": "inputs/network.json",
     "demand_scale": 1.0
    }
   }
  },
  "simulation": {
   "t_end": 1.0,
   "output_interval": 1.0,
   "required_outputs": [
    "h",
    "Q"
   ],
   "steady": true
  },
  "scoring": {
   "criteria": [
    {
     "id": "nodal_head",
     "metric": "Linf",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.05,
      "units": "m"
     },
     "gating": true,
     "rationale": "Worst junction head within 5 cm. The SI Hazen–Williams coefficients in use differ by up to 0.1 % (10.667 here, ≈10.67 from EPANET's US-unit 4.727), which moves heads by at most 0.03 m on this network's 26 m of loss; single-precision output adds about 2 mm at 200 m."
    },
    {
     "id": "link_flow",
     "metric": "L2",
     "variable": "Q",
     "threshold": {
      "op": "abs<=",
      "value": 0.1,
      "units": "%"
     },
     "gating": true,
     "rationale": "Pipe flows within 0.1 % (relative L2). Flows do not depend on the Hazen–Williams coefficient's absolute value, only on continuity and loop balance; 0.1 % is the default EPANET convergence criterion (sum of flow changes over total flow ≤ 0.001)."
    }
   ],
   "convergence": {
    "not_applicable": "Steady looped network with a closed-form-equivalent reference: there is no grid or time step to refine."
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "test_id": "A1P-020_joukowsky_instant_closure",
  "case_version": "3.0.0",
  "status": "candidate",
  "track": "A",
  "test_class": "verification_analytic",
  "title": "Joukowsky instant valve closure",
  "description": "Frictionless pipe after an instantaneous valve closure: the classic Joukowsky pressure rise ρaV₀ travels upstream as a sharp front until it reaches the reservoir. Because the front is a discontinuity carried by a linear wave equation, a first-order fixed-grid scheme converges in L1 only at order ½ (p/(p+1) for order p), which sets the convergence target; the storage balance checks mass exactly.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "pressurized",
   "governing_equations": [
    "water_hammer"
   ],
   "phenomena": [
    "water_hammer",
    "valve_closure",
    "pressure_wave"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Joukowsky, N."
     ],
     "year": 1900,
     "title": "Über den hydraulischen Stoss in Wasserleitungsröhren",
     "report_number": "Mem. Acad. Imp. Sci. St.-Petersbourg Ser.8 9(5)"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/params.json",
    "role": "case_parameters",
    "format": "json",
    "sha256": "1a1d580b46bca5b168619391e8a27147a04869f03c293f32ef85ac639eb201c5"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.joukowsky",
    "function": "pressure_wave",
    "parameters": {
     "L": 1000.0,
     "a": 1000.0,
     "V0": 1.0,
     "rho": 1000.0,
     "p0": 0.0
    }
   }
  },
  "simulation": {
   "t_end": 0.5,
   "output_interval": 0.05,
   "required_outputs": [
    "p",
    "u"
   ],
   "mesh_refinement": {
    "levels": [
     20,
     10,
     5,
     2.5
    ],
    "fixed_courant": 0.5
   }
  },
  "scoring": {
   "criteria": [
    {
     "id": "peak_pressure",
     "metric": "peak_error",
     "variable": "p",
     "threshold": {
      "op": "abs<=",
      "value": 2.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Peak pressure within ±2% of Joukowsky rise Δp = ρ a V0."
    },
    {
     "id": "storage_balance",
     "metric": "storage_balance_error",
     "variable": "p",
     "threshold": {
      "op": "abs<=",
      "value": 1.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Mass balance with no free parameter: until the first reflection the reservoir keeps delivering V0 while the valve is shut, and the pipe must store exactly that volume by compression, so ∫Δp dx = ρa²V0t. A conservative scheme meets it to round-off; 1 % allows non-conservative interpolation schemes that are otherwise accurate."
    }
   ],
   "convergence": {
    "norm": "L1",
    "variable": "p",
    "expected_order": 0.5,
    "min_observed_order": 0.4
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "0.1.0",
  "status": "draft",
  "track": "A",
  "test_id": "A1P-021_bergant_slow_closure_column_sep",
  "test_class": "validation_lab",
  "title": "Bergant slow valve closure with column separation",
  "description": "Laboratory water-hammer with slow valve closure producing column separation and cavity collapse; compare pressure traces to published gauge data.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "pressurized",
   "governing_equations": [
    "water_hammer",
    "column_separation"
   ],
   "phenomena": [
    "water_hammer",
    "column_separation",
    "valve_closure"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Bergant, A.",
      "Simpson, A. R."
     ],
     "year": 1999,
     "title": "Pipeline column separation flow regimes",
     "doi": "10.1061/(ASCE)0733-9429(1999)125:8(835)"
    }
   ],
   "license": "TBD-confirm",
   "adaptation_notes": "Draft: laboratory pressure traces to be vendored after license/source confirmation of raw data."
  },
  "inputs": [
   {
    "path": "inputs/rig.json",
    "role": "geometry",
    "format": "json",
    "pending": {
     "reason": "Pipeline rig geometry, valve closure law and pressure traces from Bergant & Simpson (1999); raw traces need permission from the authors.",
     "obtain_from": "University of Adelaide (Simpson) / Litostroj Power (Bergant)"
    }
   }
  ],
  "reference": {
   "kind": "measured",
   "data_path": "reference/measurements.parquet",
   "uncertainty": {
    "type": "relative",
    "value": 0.05,
    "units": "1",
    "notes": "Draft placeholder uncertainty; replace with published gauge error."
   },
   "include_measurement_uncertainty": true,
   "availability": "request_from_authors"
  },
  "simulation": {
   "t_end": 10.0,
   "output_interval": 0.01,
   "required_outputs": [
    "p",
    "u"
   ]
  },
  "scoring": {
   "criteria": [
    {
     "id": "peak_pressure",
     "metric": "peak_error",
     "variable": "p",
     "threshold": {
      "op": "abs<=",
      "value": 5.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Peak pressure within 5% of published Bergant & Simpson gauge peak."
    },
    {
     "id": "arrival",
     "metric": "arrival_time_error",
     "variable": "p",
     "threshold": {
      "op": "abs<=",
      "value": 0.05,
      "units": "s"
     },
     "gating": true,
     "rationale": "Cavity collapse / pressure recovery timing within 0.05 s."
    }
   ],
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A1P-030_advection_dispersion_tracer",
  "test_class": "verification_analytic",
  "title": "Advection–dispersion tracer (Ogata–Banks)",
  "description": "A tracer is released continuously at x = 0 into a uniform flow (u = 0.1 m/s, D = 0.01 m²/s); after one hour the front is 360 m downstream. Ogata & Banks (1961) give the exact profile, which tests both advection and dispersion and penalises numerical diffusion.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "pressurized",
   "governing_equations": [
    "advection_dispersion"
   ],
   "phenomena": [
    "tracer_transport",
    "dispersion"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Ogata, A.",
      "Banks, R. B."
     ],
     "year": 1961,
     "title": "A Solution of the Differential Equation of Longitudinal Dispersion in Porous Media",
     "report_number": "USGS Professional Paper 411-A"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/params.json",
    "role": "case_parameters",
    "format": "json",
    "sha256": "94ed2381312349f7e35df843a0c6c4926d529895c8f8ada75798895570564025"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.ogata_banks",
    "function": "concentration",
    "parameters": {
     "u": 0.1,
     "D": 0.01,
     "c0": 1.0
    }
   }
  },
  "simulation": {
   "t_end": 3600.0,
   "output_interval": 60.0,
   "required_outputs": [
    "c",
    "u"
   ],
   "mesh_refinement": {
    "levels": [
     4.0,
     2.0,
     1.0,
     0.5
    ],
    "fixed_courant": 0.5
   }
  },
  "scoring": {
   "criteria": [
    {
     "id": "concentration_L1",
     "metric": "L1",
     "variable": "c",
     "threshold": {
      "op": "abs<=",
      "value": 2.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Concentration L1 error within 2 % of the L1 norm of the Ogata–Banks profile on the finest grid. The front is 8.5 m wide (2√(Dt)) and moves 360 m, so a scheme with numerical diffusion comparable to D (first-order upwind at u·dx/2 = 0.025 m²/s, 2.5×D) visibly smears it and fails."
    },
    {
     "id": "mass",
     "metric": "global_mass_error",
     "variable": "c",
     "threshold": {
      "op": "abs<=",
      "value": 0.5,
      "units": "%"
     },
     "gating": true,
     "rationale": "Tracer mass in the domain within 0.5 % of the exact integral: a conservative scheme meets it to quadrature error."
    }
   ],
   "convergence": {
    "norm": "L1",
    "variable": "c",
    "expected_order": 2.0,
    "min_observed_order": 1.6
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A1D-001_circular_pipe_normal_depth",
  "test_class": "verification_analytic",
  "title": "Normal depth in partly full circular pipes",
  "description": "Three chains of ten 1 m circular pipes (n = 0.013, slope 0.002) carry 0.15, 0.5 and 1.0 m³/s to normal-depth outfalls, filling them to about a quarter, a half and three quarters. At steady state every interior manhole and every pipe runs at Manning normal depth in the exact circular section.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "free_surface",
   "governing_equations": [
    "manning",
    "network_continuity"
   ],
   "phenomena": [
    "partly_full_pipe",
    "steady_hydraulics",
    "uniform_flow"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Chow, V. T."
     ],
     "year": 1959,
     "title": "Open-Channel Hydraulics",
     "isbn": "9780070107762"
    },
    {
     "authors": [
      "Rossman, L. A."
     ],
     "year": 2017,
     "title": "Storm Water Management Model Reference Manual Volume II – Hydraulics (EPA/600/R-17/111)",
     "url": "https://www.epa.gov/water-research/storm-water-management-model-swmm"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/network.json",
    "role": "network",
    "format": "json",
    "sha256": "69bd619bc8fa036f71c64c7077037e1d13831721f4fcc866b6875b72650b3ae5"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.drainage",
    "function": "uniform_flow",
    "parameters": {
     "network_path": "inputs/network.json"
    }
   }
  },
  "simulation": {
   "t_end": 21600.0,
   "output_interval": 300.0,
   "required_outputs": [
    "h",
    "Q"
   ],
   "steady": true
  },
  "scoring": {
   "criteria": [
    {
     "id": "normal_depth",
     "metric": "Linf",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.01,
      "units": "m"
     },
     "gating": true,
     "rationale": "Worst node or pipe depth within 1 cm (1 % of the diameter). SWMM-family engines store circular-pipe area and hydraulic radius in 51-entry tables and interpolate between them; that alone moves a normal depth by a few millimetres."
    },
    {
     "id": "pipe_flow",
     "metric": "L2",
     "variable": "Q",
     "threshold": {
      "op": "abs<=",
      "value": 0.5,
      "units": "%"
     },
     "gating": true,
     "rationale": "Pipe flows within 0.5 %: at steady state every pipe carries its chain's inflow."
    }
   ],
   "convergence": {
    "not_applicable": "A link–node network with a closed-form (or 1e-11 integrated) reference at fixed elements: there is no grid to refine."
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A1D-002_surcharged_pipe_grade_line",
  "test_class": "verification_analytic",
  "title": "Surcharged pipes: hydraulic grade line",
  "description": "Five 0.6 m pipes (100 m, n = 0.013) carry 0.3 m³/s to an outfall held 1.5 m above its invert, so every pipe runs full. The hydraulic grade line falls by n²Q²L/(A²R^(4/3)) = 0.239 m along each pipe (1.19 m in all); manhole depths follow exactly.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "pressurized",
   "governing_equations": [
    "manning",
    "network_continuity"
   ],
   "phenomena": [
    "surcharge",
    "full_pipe",
    "steady_hydraulics"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Chow, V. T."
     ],
     "year": 1959,
     "title": "Open-Channel Hydraulics",
     "isbn": "9780070107762"
    },
    {
     "authors": [
      "Rossman, L. A."
     ],
     "year": 2017,
     "title": "Storm Water Management Model Reference Manual Volume II – Hydraulics (EPA/600/R-17/111)",
     "url": "https://www.epa.gov/water-research/storm-water-management-model-swmm"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/network.json",
    "role": "network",
    "format": "json",
    "sha256": "c228b0e9e815257b49b1c2b01f77646b63623ab1234489545e57832068690002"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.drainage",
    "function": "surcharged_pipe",
    "parameters": {
     "network_path": "inputs/network.json"
    }
   }
  },
  "simulation": {
   "t_end": 7200.0,
   "output_interval": 300.0,
   "required_outputs": [
    "h",
    "Q"
   ],
   "steady": true
  },
  "scoring": {
   "criteria": [
    {
     "id": "grade_line",
     "metric": "Linf",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.01,
      "units": "m"
     },
     "gating": true,
     "rationale": "Worst manhole head within 1 cm of the 1.19 m friction loss (0.8 %). Full-pipe friction is exact in every engine's geometry; the error is how surcharged heads are solved."
    },
    {
     "id": "pipe_flow",
     "metric": "L2",
     "variable": "Q",
     "threshold": {
      "op": "abs<=",
      "value": 0.5,
      "units": "%"
     },
     "gating": true,
     "rationale": "Pipe flows within 0.5 % of the inflow."
    }
   ],
   "convergence": {
    "not_applicable": "A link–node network with a closed-form (or 1e-11 integrated) reference at fixed elements: there is no grid to refine."
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A1D-003_storage_power_law_outlet",
  "test_class": "verification_analytic",
  "title": "Storage draining through a power-law outlet",
  "description": "A 100 m² storage, 2 m deep, empties through an outlet rated Q = 0.5 h^0.5 to a free outfall. Its depth follows h(t) = (√h0 − C t/(2A))² exactly: 0.441 m and 0.332 m³/s at 300 s.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "free_surface",
   "governing_equations": [
    "storage_continuity",
    "outlet_rating"
   ],
   "phenomena": [
    "storage",
    "unsteady",
    "drain_down"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Rossman, L. A."
     ],
     "year": 2017,
     "title": "Storm Water Management Model Reference Manual Volume II – Hydraulics (EPA/600/R-17/111)",
     "url": "https://www.epa.gov/water-research/storm-water-management-model-swmm"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/network.json",
    "role": "network",
    "format": "json",
    "sha256": "884ebb86b5520a35487369c2025958dbf9f29810a13c52e39237e0133ccf77d9"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.drainage",
    "function": "storage_drain",
    "parameters": {
     "network_path": "inputs/network.json"
    }
   }
  },
  "simulation": {
   "t_end": 300.0,
   "output_interval": 10.0,
   "required_outputs": [
    "h",
    "Q"
   ],
   "steady": false
  },
  "scoring": {
   "criteria": [
    {
     "id": "storage_depth",
     "metric": "Linf",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.005,
      "units": "m"
     },
     "gating": true,
     "rationale": "Storage depth within 5 mm (about 1 %) after 300 s. A first-order time integration with SWMM's default steps errs by well under a millimetre."
    },
    {
     "id": "outlet_flow",
     "metric": "Linf",
     "variable": "Q",
     "threshold": {
      "op": "abs<=",
      "value": 0.005,
      "units": "m³/s"
     },
     "gating": true,
     "rationale": "Outlet flow within 5 L/s (1.5 %), the rating applied to the depth."
    }
   ],
   "convergence": {
    "not_applicable": "One storage node and one outlet: there is no grid to refine; the time step is the engine's own."
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A1D-004_pump_on_its_curve",
  "test_class": "verification_analytic",
  "title": "Pump operating on its head–flow curve",
  "description": "A 20 m² wet well receives 0.1 m³/s and is emptied by a pump (head–flow curve 12 m/0, 10 m/0.08, 6 m/0.15 m³/s) against an outfall held at 10 m. At steady state the pump passes the inflow at a head rise of 8.857 m, so the wet well stands at 1.143 m.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "pressurized",
   "governing_equations": [
    "storage_continuity",
    "pump_curve"
   ],
   "phenomena": [
    "pump",
    "steady_hydraulics"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Rossman, L. A."
     ],
     "year": 2017,
     "title": "Storm Water Management Model Reference Manual Volume II – Hydraulics (EPA/600/R-17/111)",
     "url": "https://www.epa.gov/water-research/storm-water-management-model-swmm"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/network.json",
    "role": "network",
    "format": "json",
    "sha256": "2c974666927f0260d5f20132c754778ca8c7b0c49e18c00c8db11fbe207cbaaa"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.drainage",
    "function": "pump_curve",
    "parameters": {
     "network_path": "inputs/network.json"
    }
   }
  },
  "simulation": {
   "t_end": 21600.0,
   "output_interval": 300.0,
   "required_outputs": [
    "h",
    "Q"
   ],
   "steady": true
  },
  "scoring": {
   "criteria": [
    {
     "id": "wet_well_depth",
     "metric": "Linf",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.01,
      "units": "m"
     },
     "gating": true,
     "rationale": "Wet-well depth within 1 cm. The operating point is the curve read at the inflow; the curve is linear between its points in every engine that accepts this input."
    },
    {
     "id": "pump_flow",
     "metric": "Linf",
     "variable": "Q",
     "threshold": {
      "op": "abs<=",
      "value": 0.001,
      "units": "m³/s"
     },
     "gating": true,
     "rationale": "Pump flow within 1 L/s of the inflow (1 %)."
    }
   ],
   "convergence": {
    "not_applicable": "A link–node network with a closed-form (or 1e-11 integrated) reference at fixed elements: there is no grid to refine."
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A1D-005_backwater_through_manholes",
  "test_class": "verification_analytic",
  "title": "Backwater through a chain of manholes",
  "description": "Twenty 1.2 m pipes (50 m each, n = 0.013, slope 0.001) carry 0.6 m³/s from normal depth (0.59 m) down to an outfall held 1.0 m above its invert. The M1 backwater profile through the manholes is integrated from the outfall to 1e-11 (gradually varied flow in the exact circular section).",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "free_surface",
   "governing_equations": [
    "gradually_varied_flow",
    "manning"
   ],
   "phenomena": [
    "backwater",
    "partly_full_pipe",
    "steady_hydraulics"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Chow, V. T."
     ],
     "year": 1959,
     "title": "Open-Channel Hydraulics",
     "isbn": "9780070107762"
    },
    {
     "authors": [
      "Rossman, L. A."
     ],
     "year": 2017,
     "title": "Storm Water Management Model Reference Manual Volume II – Hydraulics (EPA/600/R-17/111)",
     "url": "https://www.epa.gov/water-research/storm-water-management-model-swmm"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/network.json",
    "role": "network",
    "format": "json",
    "sha256": "880838ccb4e0ce0cf3486440112e3163063ccff6265d79bf884dd1891c31e27a"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.drainage",
    "function": "backwater",
    "parameters": {
     "network_path": "inputs/network.json"
    }
   }
  },
  "simulation": {
   "t_end": 21600.0,
   "output_interval": 300.0,
   "required_outputs": [
    "h",
    "Q"
   ],
   "steady": true
  },
  "scoring": {
   "criteria": [
    {
     "id": "profile_depth",
     "metric": "Linf",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.02,
      "units": "m"
     },
     "gating": true,
     "rationale": "Worst manhole or pipe depth within 2 cm. A link–node model represents each 50 m pipe by its end heads and a mid-pipe depth, a second-order discretisation of the profile whose error here is a few millimetres; the rest is the section tables."
    },
    {
     "id": "pipe_flow",
     "metric": "L2",
     "variable": "Q",
     "threshold": {
      "op": "abs<=",
      "value": 0.5,
      "units": "%"
     },
     "gating": true,
     "rationale": "Pipe flows within 0.5 % of the inflow."
    }
   ],
   "convergence": {
    "not_applicable": "A link–node network with a closed-form (or 1e-11 integrated) reference at fixed elements: there is no grid to refine."
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "test_id": "A1F-001_macdonald_m1_backwater",
  "case_version": "1.1.0",
  "status": "candidate",
  "track": "A",
  "test_class": "verification_analytic",
  "title": "MacDonald M1 subcritical backwater",
  "description": "Steady 1D open-channel M1-like backwater with MacDonald manufactured bed so that a prescribed smooth depth profile is exact.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "free_surface",
   "governing_equations": [
    "saint_venant_steady"
   ],
   "phenomena": [
    "backwater",
    "subcritical",
    "friction"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "MacDonald, I.",
      "Baines, M. J.",
      "Nichols, N. K.",
      "Samuels, P. G."
     ],
     "year": 1997,
     "title": "Analytic benchmark solutions for open-channel flows",
     "doi": "10.1061/(ASCE)0733-9429(1997)123:11(1041)"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/params.json",
    "role": "case_parameters",
    "format": "json",
    "sha256": "01a75f47e13d1ffdc4395d1840cd709d33bb84c6b0c5955da9cd7b15baf47f70"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.macdonald",
    "function": "depth_profile",
    "parameters": {
     "case": "m1",
     "g": 9.81
    }
   }
  },
  "simulation": {
   "t_end": 3600,
   "output_interval": 60,
   "required_outputs": [
    "h",
    "u",
    "Q"
   ],
   "mesh_refinement": {
    "levels": [
     40,
     20,
     10,
     5
    ],
    "fixed_courant": 0.5
   }
  },
  "scoring": {
   "criteria": [
    {
     "id": "L1_h",
     "metric": "L1",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.01,
      "units": "m"
     },
     "gating": true,
     "rationale": "Steady depth L1 error on finest mesh against MacDonald M1 profile."
    },
    {
     "id": "mass",
     "metric": "global_mass_error",
     "variable": "volume",
     "threshold": {
      "op": "abs<=",
      "value": 0.1,
      "units": "%"
     },
     "gating": true,
     "rationale": "Conservation property at steady state."
    }
   ],
   "convergence": {
    "norm": "L1",
    "variable": "h",
    "expected_order": 1.0,
    "min_observed_order": 0.8
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "test_id": "A1F-010_ritter_dry_bed_dambreak",
  "case_version": "3.0.0",
  "status": "candidate",
  "track": "A",
  "test_class": "verification_analytic",
  "title": "Ritter dry-bed dam break",
  "description": "1D inviscid Saint-Venant dam break onto a dry bed with exact Ritter (1892) solution.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "free_surface",
   "governing_equations": [
    "saint_venant_dynamic"
   ],
   "phenomena": [
    "dam_break",
    "dry_bed",
    "wet_dry_front"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Ritter, A."
     ],
     "year": 1892,
     "title": "Die Fortpflanzung der Wasserwellen",
     "report_number": "ZdVDI 36(33)"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/params.json",
    "role": "case_parameters",
    "format": "json",
    "sha256": "ec594fd897382ccebf4e11ecad5eb85342cc81f9bdf3ca85040616e7ec818a2c"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.ritter",
    "function": "depth_velocity",
    "parameters": {
     "h0": 1.0,
     "x0": 1000.0,
     "g": 9.81
    }
   }
  },
  "simulation": {
   "t_end": 60,
   "output_interval": 5,
   "required_outputs": [
    "h",
    "u",
    "Q"
   ],
   "mesh_refinement": {
    "levels": [
     10,
     5,
     2.5,
     1.25
    ],
    "fixed_courant": 0.5
   }
  },
  "scoring": {
   "criteria": [
    {
     "id": "volume_front",
     "metric": "volume_front_error",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 9.8,
      "units": "m"
     },
     "gating": true,
     "rationale": "5 × the error of the suite's first-order reference scheme (demo 1D, Godunov/HLL: 1.95 m on the finest grid), scoring method 2, rule R7; since v3.0.0 (v2: two finest cells, 2.5 m). 9.8 m is 2.6 % of the 376 m the front travels in 60 s, about 1.6 s of arrival time. The front is the abscissa beyond which lies the last 5 % of the water downstream of the dam (exact: x0 + 2c0·t·(1 − 0.05^(1/3)) = 1237.4 m at 60 s). An integral of depth is well conditioned on the thin tip, where a depth contour is not; it is computed against the solver's own downstream volume, so mass errors do not leak into it."
    },
    {
     "id": "front_position",
     "metric": "front_position_error",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 2.5,
      "units": "m"
     },
     "gating": false,
     "rationale": "Reported, not gating (since v2.0.0). Exact iso-contour at h=0.001·h0 (~1358 m). On the thin tip a 1 mm depth error moves this contour about 10 m, and production codes treat depths under ~1 mm as dry, so it measures thin-film handling more than the front; the volume front gates instead."
    },
    {
     "id": "mass",
     "metric": "global_mass_error",
     "variable": "volume",
     "threshold": {
      "op": "abs<=",
      "value": 0.1,
      "units": "%"
     },
     "gating": true,
     "rationale": "Conservation property of continuous equations."
    }
   ],
   "convergence": {
    "norm": "L1",
    "variable": "h",
    "expected_order": 1.0,
    "min_observed_order": 0.8
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "test_id": "A1F-011_stoker_wet_bed_dambreak",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_class": "verification_analytic",
  "title": "Stoker wet-bed dam break",
  "description": "1D inviscid Saint-Venant dam break onto a wet bed (hl=1, hr=0.1) with exact Stoker (1957) Riemann solution.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "free_surface",
   "governing_equations": [
    "saint_venant_dynamic"
   ],
   "phenomena": [
    "dam_break",
    "wet_bed",
    "shock",
    "rarefaction"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Stoker, J. J."
     ],
     "year": 1957,
     "title": "Water Waves: The Mathematical Theory with Applications",
     "isbn": "9780471570349"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/params.json",
    "role": "case_parameters",
    "format": "json",
    "sha256": "11c492bdd3a55a0ce95b6b20ac4979772eed50032ee49830affa8fc008c33770"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.stoker",
    "function": "depth_velocity",
    "parameters": {
     "hl": 1.0,
     "hr": 0.1,
     "x0": 0.0,
     "g": 9.81
    }
   }
  },
  "simulation": {
   "t_end": 30,
   "output_interval": 5,
   "required_outputs": [
    "h",
    "u",
    "Q"
   ],
   "mesh_refinement": {
    "levels": [
     10,
     5,
     2.5,
     1.25
    ],
    "fixed_courant": 0.5
   }
  },
  "scoring": {
   "criteria": [
    {
     "id": "L1_h",
     "metric": "L1",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.05,
      "units": "m"
     },
     "gating": true,
     "rationale": "L1 depth error on finest mesh; shock and rarefaction capture."
    },
    {
     "id": "mass",
     "metric": "global_mass_error",
     "variable": "volume",
     "threshold": {
      "op": "abs<=",
      "value": 0.1,
      "units": "%"
     },
     "gating": true,
     "rationale": "Conservation property of continuous equations."
    }
   ],
   "convergence": {
    "norm": "L1",
    "variable": "h",
    "expected_order": 1.0,
    "min_observed_order": 0.8
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A1F-020_hydraulic_jump_belanger",
  "test_class": "verification_analytic",
  "title": "Bélanger hydraulic jump",
  "description": "A stationary hydraulic jump on a horizontal frictionless bed: supercritical inflow (h1 = 0.2 m, Fr1 = 2.5) meets the Bélanger sequent depth h2 = 0.61 m held downstream. The exact solution is a step that stays at x = 50 m; the case checks that a solver captures the jump with the right conjugate depths and does not let it drift.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "free_surface",
   "governing_equations": [
    "saint_venant_dynamic"
   ],
   "phenomena": [
    "hydraulic_jump",
    "shock"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Bélanger, J. B."
     ],
     "year": 1828,
     "title": "Essai sur la solution numérique de quelques problèmes relatifs au mouvement permanent des eaux courantes (Bélanger sequent-depth relation)",
     "report_number": "Belanger-1828"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/params.json",
    "role": "case_parameters",
    "format": "json",
    "sha256": "e9ccb8d3d60b7cdcadc73a71d048f8b393ecab3be9f290ae45295dc96bce72fb"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.belanger",
    "function": "sequent_depths",
    "parameters": {
     "Fr1": 2.5,
     "h1": 0.2,
     "g": 9.81,
     "L": 100.0,
     "x_jump": 50.0
    }
   }
  },
  "simulation": {
   "t_end": 200.0,
   "output_interval": 10.0,
   "required_outputs": [
    "h",
    "u",
    "Q"
   ],
   "mesh_refinement": {
    "levels": [
     2.0,
     1.0,
     0.5,
     0.25
    ],
    "fixed_courant": 0.45
   }
  },
  "scoring": {
   "criteria": [
    {
     "id": "jump_profile",
     "metric": "L1",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 1.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Depth profile within 1 % (relative L1) of the stationary Bélanger step at x = 50 m on the finest grid. A captured jump smeared over two cells contributes Δh·2dx/L ≈ 0.5 % at dx = 0.25 m; a drifting jump or wrong sequent depth exceeds it."
    },
    {
     "id": "jump_stays_put",
     "metric": "global_mass_error",
     "variable": "volume",
     "threshold": {
      "op": "abs<=",
      "value": 0.1,
      "units": "%"
     },
     "gating": true,
     "rationale": "Stored volume within 0.1 % of the exact step: a jump that drifts by half a cell (0.125 m) on the finest grid changes the volume by 0.13 %, so this fails any solver that cannot hold the Rankine–Hugoniot balance."
    }
   ],
   "convergence": {
    "norm": "L1",
    "variable": "h",
    "expected_order": 1.0,
    "min_observed_order": 0.8
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "0.1.0",
  "status": "draft",
  "track": "A",
  "test_id": "A1F-030_weber_90deg_junction",
  "test_class": "validation_lab",
  "title": "Weber 90° open-channel junction",
  "description": "Laboratory combining junction at 90°; compare depths and velocities to Weber, Schumate & Mawer (2001) measurements.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "free_surface",
   "governing_equations": [
    "saint_venant_dynamic"
   ],
   "phenomena": [
    "junction",
    "combining_flow"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Weber, L. J.",
      "Schumate, E. D.",
      "Mawer, N."
     ],
     "year": 2001,
     "title": "Experiments on flow at a 90° open-channel junction",
     "doi": "10.1061/(ASCE)0733-9429(2001)127:5(340)"
    }
   ],
   "license": "TBD-confirm",
   "adaptation_notes": "Draft: digitize published gauge profiles once redistribution terms allow."
  },
  "inputs": [
   {
    "path": "inputs/flume.json",
    "role": "geometry",
    "format": "json",
    "pending": {
     "reason": "Flume geometry and inflows from Weber, Schumate & Mawer (2001); measured depth/velocity fields need redistribution terms from the authors / IIHR.",
     "obtain_from": "IIHR – Hydroscience & Engineering, University of Iowa (authors of Weber et al. 2001)"
    }
   }
  ],
  "reference": {
   "kind": "measured",
   "data_path": "reference/measurements.parquet",
   "uncertainty": {
    "type": "relative",
    "value": 0.03,
    "units": "1",
    "notes": "Draft placeholder uncertainty; replace with published gauge error."
   },
   "include_measurement_uncertainty": true,
   "availability": "request_from_authors"
  },
  "simulation": {
   "t_end": 600.0,
   "output_interval": 5.0,
   "required_outputs": [
    "h",
    "u",
    "Q"
   ]
  },
  "scoring": {
   "criteria": [
    {
     "id": "depth_NSE",
     "metric": "NSE",
     "variable": "h",
     "threshold": {
      "op": ">=",
      "value": 0.7,
      "units": "1"
     },
     "gating": true,
     "rationale": "NSE on junction depths ≥ 0.7 within measurement uncertainty."
    },
    {
     "id": "peak_depth",
     "metric": "peak_error",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 5.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Peak depth within 5% of laboratory peak."
    }
   ],
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A1F-040_swashes_bump_subcritical",
  "test_class": "verification_analytic",
  "title": "Subcritical flow over a bump (SWASHES)",
  "description": "Steady frictionless flow of q = 4.42 m²/s over a 0.2 m parabolic bump in a 25 m channel, held at 2 m downstream. The flow stays subcritical; the depth follows from constant discharge and Bernoulli head (a cubic at every point), dipping to 1.71 m over the crest.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "free_surface",
   "governing_equations": [
    "saint_venant_dynamic"
   ],
   "phenomena": [
    "steady_hydraulics",
    "bed_slope"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Delestre, O.",
      "Lucas, C.",
      "Ksinant, P.-A.",
      "Darboux, F.",
      "Laguerre, C.",
      "Vo, T. N. T.",
      "James, F.",
      "Cordier, S."
     ],
     "year": 2013,
     "title": "SWASHES: a compilation of shallow water analytic solutions for hydraulic and environmental studies",
     "doi": "10.1002/fld.3741"
    },
    {
     "authors": [
      "Goutal, N.",
      "Maurel, F."
     ],
     "year": 1997,
     "title": "Proceedings of the 2nd workshop on dam-break wave simulation (EDF HE-43/97/016/B)",
     "url": "https://www.irit.fr/swashes"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/params.json",
    "role": "parameters",
    "format": "json",
    "sha256": "29539a58888411623b9ae0395e1c7f5709c8b7bab8f0b87b12d89930fefbfeae"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.swashes",
    "function": "steady_bump",
    "parameters": {
     "case": "subcritical",
     "g": 9.81
    }
   }
  },
  "simulation": {
   "t_end": 300.0,
   "output_interval": 300.0,
   "required_outputs": [
    "h",
    "u",
    "Q"
   ],
   "mesh_refinement": {
    "levels": [
     0.2,
     0.1,
     0.05
    ],
    "fixed_courant": 0.5
   },
   "steady": true
  },
  "scoring": {
   "criteria": [
    {
     "id": "L1_h",
     "metric": "L1",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.005,
      "units": "m"
     },
     "gating": true,
     "rationale": "Average depth error under 5 mm (0.25 % of the depth) once steady."
    },
    {
     "id": "L1_Q",
     "metric": "L1",
     "variable": "Q",
     "threshold": {
      "op": "abs<=",
      "value": 0.044,
      "units": "m²/s"
     },
     "gating": true,
     "rationale": "Discharge within 1 % of q everywhere on average: a steady state must carry the inflow along the whole channel."
    }
   ],
   "convergence": {
    "norm": "L1",
    "variable": "h",
    "expected_order": 2.0,
    "min_observed_order": 0.8
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A1F-041_swashes_bump_transcritical",
  "test_class": "verification_analytic",
  "title": "Transcritical flow over a bump, no shock (SWASHES)",
  "description": "Steady frictionless flow of q = 1.53 m²/s over the 0.2 m bump, with 0.66 m held downstream only while the outflow is subcritical (as in SWASHES). The flow passes through critical depth at the crest, subcritical upstream and supercritical downstream, with no jump: the depth falls from 1.01 m to 0.41 m.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "free_surface",
   "governing_equations": [
    "saint_venant_dynamic"
   ],
   "phenomena": [
    "steady_hydraulics",
    "bed_slope",
    "critical_flow"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Delestre, O.",
      "Lucas, C.",
      "Ksinant, P.-A.",
      "Darboux, F.",
      "Laguerre, C.",
      "Vo, T. N. T.",
      "James, F.",
      "Cordier, S."
     ],
     "year": 2013,
     "title": "SWASHES: a compilation of shallow water analytic solutions for hydraulic and environmental studies",
     "doi": "10.1002/fld.3741"
    },
    {
     "authors": [
      "Goutal, N.",
      "Maurel, F."
     ],
     "year": 1997,
     "title": "Proceedings of the 2nd workshop on dam-break wave simulation (EDF HE-43/97/016/B)",
     "url": "https://www.irit.fr/swashes"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/params.json",
    "role": "parameters",
    "format": "json",
    "sha256": "7b858a1d063d962a9e5c7c4e5eedfa33ac7fd9d2d9f9a223447d5828ab6cfafa"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.swashes",
    "function": "steady_bump",
    "parameters": {
     "case": "transcritical",
     "g": 9.81
    }
   }
  },
  "simulation": {
   "t_end": 300.0,
   "output_interval": 300.0,
   "required_outputs": [
    "h",
    "u",
    "Q"
   ],
   "mesh_refinement": {
    "levels": [
     0.2,
     0.1,
     0.05
    ],
    "fixed_courant": 0.5
   },
   "steady": true
  },
  "scoring": {
   "criteria": [
    {
     "id": "L1_h",
     "metric": "L1",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.005,
      "units": "m"
     },
     "gating": true,
     "rationale": "Average depth error under 5 mm (1 % of the downstream depth) once steady; the critical point at the crest is where schemes struggle."
    },
    {
     "id": "L1_Q",
     "metric": "L1",
     "variable": "Q",
     "threshold": {
      "op": "abs<=",
      "value": 0.0153,
      "units": "m²/s"
     },
     "gating": true,
     "rationale": "Discharge within 1 % of q on average."
    }
   ],
   "convergence": {
    "norm": "L1",
    "variable": "h",
    "expected_order": 1.0,
    "min_observed_order": 0.8
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A1F-042_swashes_bump_shock",
  "test_class": "verification_analytic",
  "title": "Transcritical flow over a bump with a hydraulic jump (SWASHES)",
  "description": "Steady frictionless flow of q = 0.18 m²/s over the 0.2 m bump, held at 0.33 m downstream. The flow goes critical at the crest, accelerates down the bump and jumps back to subcritical at x = 11.666 m, where the Rankine–Hugoniot condition holds.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "free_surface",
   "governing_equations": [
    "saint_venant_dynamic"
   ],
   "phenomena": [
    "steady_hydraulics",
    "bed_slope",
    "hydraulic_jump"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Delestre, O.",
      "Lucas, C.",
      "Ksinant, P.-A.",
      "Darboux, F.",
      "Laguerre, C.",
      "Vo, T. N. T.",
      "James, F.",
      "Cordier, S."
     ],
     "year": 2013,
     "title": "SWASHES: a compilation of shallow water analytic solutions for hydraulic and environmental studies",
     "doi": "10.1002/fld.3741"
    },
    {
     "authors": [
      "Goutal, N.",
      "Maurel, F."
     ],
     "year": 1997,
     "title": "Proceedings of the 2nd workshop on dam-break wave simulation (EDF HE-43/97/016/B)",
     "url": "https://www.irit.fr/swashes"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/params.json",
    "role": "parameters",
    "format": "json",
    "sha256": "60030aae58473d9853e18773692e659a3cdba77d73bfb7480a4912b4bb4445d4"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.swashes",
    "function": "steady_bump",
    "parameters": {
     "case": "shock",
     "g": 9.81
    }
   }
  },
  "simulation": {
   "t_end": 300.0,
   "output_interval": 300.0,
   "required_outputs": [
    "h",
    "u",
    "Q"
   ],
   "mesh_refinement": {
    "levels": [
     0.2,
     0.1,
     0.05
    ],
    "fixed_courant": 0.5
   },
   "steady": true
  },
  "scoring": {
   "criteria": [
    {
     "id": "L1_h",
     "metric": "L1",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.005,
      "units": "m"
     },
     "gating": true,
     "rationale": "Average depth error under 5 mm (1.5 % of the downstream depth) once steady; a jump one cell out of place costs about 0.2 m over one cell, about 1 mm of average error on the finest grid."
    },
    {
     "id": "L1_Q",
     "metric": "L1",
     "variable": "Q",
     "threshold": {
      "op": "abs<=",
      "value": 0.0018,
      "units": "m²/s"
     },
     "gating": true,
     "rationale": "Discharge within 1 % of q on average."
    }
   ],
   "convergence": {
    "norm": "L1",
    "variable": "h",
    "expected_order": 1.0,
    "min_observed_order": 0.8
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A1F-043_swashes_lake_at_rest_emerged_bump",
  "test_class": "verification_analytic",
  "title": "Lake at rest with an emerged bump (SWASHES)",
  "description": "Still water at level 0.1 m over the 0.2 m bump, whose top stands out of the water between x = 8.59 and 11.41 m. Nothing should move: the depth stays max(0.1 − z, 0) and the velocity zero. A scheme that does not balance the bed slope against the pressure gradient, or mishandles the dry shoreline on a slope, sets the lake in motion.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "free_surface",
   "governing_equations": [
    "saint_venant_dynamic"
   ],
   "phenomena": [
    "well_balancing",
    "wetting_drying"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Delestre, O.",
      "Lucas, C.",
      "Ksinant, P.-A.",
      "Darboux, F.",
      "Laguerre, C.",
      "Vo, T. N. T.",
      "James, F.",
      "Cordier, S."
     ],
     "year": 2013,
     "title": "SWASHES: a compilation of shallow water analytic solutions for hydraulic and environmental studies",
     "doi": "10.1002/fld.3741"
    },
    {
     "authors": [
      "Goutal, N.",
      "Maurel, F."
     ],
     "year": 1997,
     "title": "Proceedings of the 2nd workshop on dam-break wave simulation (EDF HE-43/97/016/B)",
     "url": "https://www.irit.fr/swashes"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/params.json",
    "role": "parameters",
    "format": "json",
    "sha256": "eb5589de2de47b1f659d521f126599519c7ae5b0e4a687010dc9ea91838a0343"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.swashes",
    "function": "lake_at_rest",
    "parameters": {
     "level": 0.1
    }
   }
  },
  "simulation": {
   "t_end": 100.0,
   "output_interval": 100.0,
   "required_outputs": [
    "h",
    "u",
    "Q"
   ],
   "mesh_refinement": {
    "levels": [
     0.2,
     0.1,
     0.05
    ],
    "fixed_courant": 0.5
   },
   "steady": false
  },
  "scoring": {
   "criteria": [
    {
     "id": "Linf_u",
     "metric": "Linf",
     "variable": "u",
     "threshold": {
      "op": "abs<=",
      "value": 0.001,
      "units": "m/s"
     },
     "gating": true,
     "rationale": "Nothing may move: worst velocity under 1 mm/s after 100 s. A scheme that does not balance the bed slope against the pressure gradient, or leaks at the dry shoreline on the bump, sets up currents of centimetres per second."
    },
    {
     "id": "L1_h",
     "metric": "L1",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.0005,
      "units": "m"
     },
     "gating": true,
     "rationale": "Average depth change under 0.5 mm: the lake must keep its water where it was."
    },
    {
     "id": "Linf_h",
     "metric": "Linf",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.001,
      "units": "m"
     },
     "gating": false,
     "rationale": "Informational: the worst depth difference sits in the cells cut by the shoreline, where a cell-mean depth over a sloping bed differs from the exact depth at the cell centre by up to a few millimetres on these grids even when nothing moves."
    }
   ],
   "convergence": {
    "not_applicable": "The exact state is the initial state; a well-balanced scheme keeps it to rounding error on any grid, so there is no error to converge."
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "test_id": "A1F-100_bellinge_urban_drainage",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_class": "validation_field",
  "title": "Bellinge combined sewer system (Odense, Denmark) — field validation",
  "description": "1.7 km² mainly combined urban drainage system in Bellinge, Odense, with a published EPA SWMM model and years of level-meter records. A candidate runs the published model, unchanged except for its run dates, on eight storms (2011-2019) and is judged against the measured water levels at seven level meters.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "mixed",
   "governing_equations": [
    "saint_venant_dynamic",
    "rainfall_runoff"
   ],
   "phenomena": [
    "surcharge",
    "pump",
    "combined_sewer_overflow",
    "network_routing"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Pedersen, A. N.",
      "Pedersen, J. W.",
      "Vigueras-Rodriguez, A.",
      "Brink-Kjær, A.",
      "Borup, M.",
      "Mikkelsen, P. S."
     ],
     "year": 2021,
     "title": "The Bellinge data set: open data and models for community-wide urban drainage systems research",
     "doi": "10.5194/essd-13-4779-2021"
    },
    {
     "authors": [
      "Pedersen, A. N.",
      "Pedersen, J. W.",
      "Vigueras-Rodriguez, A.",
      "Brink-Kjær, A.",
      "Borup, M.",
      "Mikkelsen, P. S."
     ],
     "year": 2021,
     "title": "Dataset for Bellinge: An urban drainage case study",
     "doi": "10.11583/DTU.c.5029124"
    }
   ],
   "license": "CC-BY-4.0",
   "source_dataset_doi": "10.11583/DTU.c.5029124",
   "adaptation_notes": "Uses only CC BY 4.0 items: 7 – Models (SWMM; its rain-gauge file drives the runs) and 2 – Sensor data. Item 3a (rain gauges) is CC BY-NC 4.0 and is not used; the radar (3b) is not needed. The published SWMM model is uncalibrated (ESSD paper §4), so this case judges the model and the engine together. Storms: the eight most intense in the model's rain-gauge series after the level meters start (Aug 2010), including the model's own 29 June 2012 event."
  },
  "inputs": [
   {
    "path": "inputs/7_SWMM.zip",
    "role": "network",
    "format": "zip",
    "committed": false,
    "source": {
     "url": "https://ndownloader.figshare.com/files/30592830",
     "md5": "fea9026c5d98b29645eb7fad69c4675d",
     "doi": "10.11583/DTU.12513428.v2"
    },
    "sha256": "fe07d487925cef647d1657def9c6316f952c9ae75304d28f2e1798d5dd8a646b"
   },
   {
    "path": "inputs/2_cleaned_data.zip",
    "role": "observations",
    "format": "zip",
    "committed": false,
    "source": {
     "url": "https://ndownloader.figshare.com/files/30592524",
     "doi": "10.11583/DTU.12509249"
    },
    "sha256": "0801435a0077d9db18e3f07fd8671160004f7b44d460229c0be1674972c26279"
   }
  ],
  "reference": {
   "kind": "measured",
   "data_path": "reference/levels.parquet",
   "availability": "available",
   "uncertainty": {
    "type": "absolute",
    "value": 0.02,
    "units": "m",
    "notes": "Provisional level-meter accuracy. Each meter reads no lower than its own floor (the lowest level it recorded in any of the storms); the scorer reads the model the same way."
   },
   "include_measurement_uncertainty": true,
   "probe_map": {}
  },
  "simulation": {
   "t_end": 172800,
   "output_interval": 60,
   "required_outputs": [
    "h",
    "z"
   ],
   "epoch": "2010-01-01T00:00:00",
   "events": [
    {
     "id": "2012-06-29",
     "start": "2012-06-28T12:00:00",
     "score_from": "2012-06-29T00:00:00",
     "end": "2012-07-01T00:00:00"
    },
    {
     "id": "2011-06-30",
     "start": "2011-06-29T12:00:00",
     "score_from": "2011-06-30T00:00:00",
     "end": "2011-07-02T00:00:00"
    },
    {
     "id": "2011-08-26",
     "start": "2011-08-25T12:00:00",
     "score_from": "2011-08-26T00:00:00",
     "end": "2011-08-28T00:00:00"
    },
    {
     "id": "2013-08-12",
     "start": "2013-08-11T12:00:00",
     "score_from": "2013-08-12T00:00:00",
     "end": "2013-08-14T00:00:00"
    },
    {
     "id": "2014-06-24",
     "start": "2014-06-23T12:00:00",
     "score_from": "2014-06-24T00:00:00",
     "end": "2014-06-26T00:00:00"
    },
    {
     "id": "2014-08-17",
     "start": "2014-08-16T12:00:00",
     "score_from": "2014-08-17T00:00:00",
     "end": "2014-08-19T00:00:00"
    },
    {
     "id": "2015-07-25",
     "start": "2015-07-24T12:00:00",
     "score_from": "2015-07-25T00:00:00",
     "end": "2015-07-27T00:00:00"
    },
    {
     "id": "2019-10-11",
     "start": "2019-10-10T12:00:00",
     "score_from": "2019-10-11T00:00:00",
     "end": "2019-10-13T00:00:00"
    }
   ],
   "probes": [
    {
     "id": "G71F04R_Level2",
     "element": "G71F04R"
    },
    {
     "id": "G71F05R_LevelBasin",
     "element": "G71F05R"
    },
    {
     "id": "G71F05R_LevelInlet",
     "element": "G71F05R_skyl"
    },
    {
     "id": "G71F06R_LevelInlet",
     "element": "G71F06R"
    },
    {
     "id": "G71F68Y_LevelPS",
     "element": "G71F68Y"
    },
    {
     "id": "G73F010",
     "element": "G73F010"
    },
    {
     "id": "G80F13P_LevelPS",
     "element": "G80F13P"
    }
   ]
  },
  "scoring": {
   "pass_rule": "all_gating",
   "criteria": [
    {
     "id": "level_nse",
     "metric": "NSE",
     "variable": "wse",
     "aggregate": "median",
     "threshold": {
      "op": ">=",
      "value": 0.5,
      "units": "1"
     },
     "gating": true,
     "rationale": "Set before any run: Moriasi et al. (2007) 'satisfactory' band, NSE ≥ 0.5, for the median gauge record (a meter on one storm). A record where the meter moved less than three times its accuracy is not scored for NSE."
    },
    {
     "id": "peak_level",
     "metric": "peak_error",
     "variable": "wse",
     "aggregate": "median",
     "threshold": {
      "op": "abs<=",
      "value": 0.1,
      "units": "m"
     },
     "gating": true,
     "rationale": "Set before any run: the ±0.1 m depth criterion for verifying sewer models against measurements (WaPUG 2002; CIWEM UDG 2017 Code of Practice), for the median gauge record."
    }
   ]
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "2.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A2A-001_thacker_parabolic_bowl",
  "test_class": "verification_analytic",
  "title": "Thacker parabolic bowl",
  "description": "2D shallow-water planar free-surface oscillation in a parabolic bowl (Thacker 1981) with a moving wet/dry shoreline. Reference: zs = (η h0/L²)(2x cos ωt − η cos² ωt), u = −η ω sin ωt, ω = √(2 g h0)/L. Case v2.0.0 replaces a v1 reference that satisfied momentum but violated mass conservation (wrong ω and a missing cos² term).",
  "physics": {
   "dimensionality": "2D",
   "flow_type": "free_surface",
   "governing_equations": [
    "shallow_water_2d"
   ],
   "phenomena": [
    "wet_dry",
    "oscillation",
    "parabolic_bowl"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Thacker, W. C."
     ],
     "year": 1981,
     "title": "Some exact solutions to the nonlinear shallow-water wave equations",
     "doi": "10.1017/S0022112081001882"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/params.json",
    "role": "parameters",
    "format": "json",
    "sha256": "c9abbf61996257072e21811e6efe20aabb3e2ebab6a1d44fb377ef8ef076fc53"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.thacker",
    "function": "depth_velocity",
    "parameters": {
     "h0": 0.1,
     "L": 1.0,
     "eta": 0.05,
     "g": 9.81
    }
   }
  },
  "simulation": {
   "t_end": 1.0,
   "output_interval": 0.25,
   "required_outputs": [
    "h",
    "u",
    "v"
   ],
   "mesh_refinement": {
    "levels": [
     0.1,
     0.05,
     0.025,
     0.0125
    ],
    "fixed_courant": 0.5
   }
  },
  "scoring": {
   "criteria": [
    {
     "id": "depth_L1",
     "metric": "L1",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.02,
      "units": "m"
     },
     "gating": true,
     "rationale": "L1 depth error within 0.02 m of Thacker exact solution on the finest mesh."
    },
    {
     "id": "mass",
     "metric": "global_mass_error",
     "variable": "volume",
     "threshold": {
      "op": "abs<=",
      "value": 0.1,
      "units": "%"
     },
     "gating": true,
     "rationale": "Global volume conserved within 0.1% versus analytic wet mass."
    }
   ],
   "convergence": {
    "norm": "L1",
    "variable": "h",
    "expected_order": 1.0,
    "min_observed_order": 0.8
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.0.0",
  "case_version": "2.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A2A-010_macdonald_2d",
  "test_class": "verification_analytic",
  "title": "MacDonald 2D manufactured channel",
  "description": "Steady subcritical flow with Manning friction in a 1 km × 100 m channel whose bed is built (MacDonald's method) so that a known smooth depth profile is the exact solution. It is A1F-001's profile on a 2D grid: the solver has to balance pressure, bed slope and friction in two dimensions, starting from a uniform depth.",
  "physics": {
   "dimensionality": "2D",
   "flow_type": "free_surface",
   "governing_equations": [
    "shallow_water_2d"
   ],
   "phenomena": [
    "backwater",
    "manufactured",
    "topography"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "MacDonald, I.",
      "Baines, M. J.",
      "Nichols, N. K.",
      "Samuels, P. G."
     ],
     "year": 1997,
     "title": "Analytic benchmark solutions for open-channel flows",
     "doi": "10.1061/(ASCE)0733-9429(1997)123:11(1041)"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/params.json",
    "role": "parameters",
    "format": "json",
    "sha256": "71aba8ea945683cf5e16283f05fdd79146ed3feaae6342bc0657d28ed57ae52d"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.macdonald_2d",
    "function": "depth_velocity",
    "parameters": {
     "L": 1000.0,
     "W": 100.0,
     "q": 0.2,
     "n_manning": 0.03,
     "g": 9.81
    }
   }
  },
  "simulation": {
   "t_end": 3600.0,
   "output_interval": 3600.0,
   "required_outputs": [
    "h",
    "u",
    "v",
    "z"
   ],
   "mesh_refinement": {
    "levels": [
     50.0,
     25.0,
     12.5,
     6.25
    ],
    "fixed_courant": 0.45
   }
  },
  "scoring": {
   "criteria": [
    {
     "id": "depth_L1",
     "metric": "L1",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.01,
      "units": "m"
     },
     "gating": true,
     "rationale": "Mean depth error below 1 cm on the finest grid (1.3 % of the 0.74 m outlet depth); a scheme that is not well balanced over the sloping bed, or that mis-applies friction, settles to a visibly different profile."
    },
    {
     "id": "mass",
     "metric": "global_mass_error",
     "variable": "volume",
     "threshold": {
      "op": "abs<=",
      "value": 0.5,
      "units": "%"
     },
     "gating": true,
     "rationale": "Water stored in the channel within 0.5 % of the exact profile: confirms the run has reached the steady state rather than a different equilibrium."
    }
   ],
   "convergence": {
    "norm": "L1",
    "variable": "h",
    "expected_order": 1.0,
    "min_observed_order": 0.8
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.0.0",
  "case_version": "2.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A2A-020_oblique_hydraulic_jump",
  "test_class": "verification_analytic",
  "title": "Oblique hydraulic jump",
  "description": "Supercritical flow (Fr₁ = 2.5) meets a straight wall at 15° and is turned through an oblique hydraulic jump. The exact solution has two uniform states separated by a straight jump at 39.58° to the incoming flow, with depth ratio 1.81. It tests shock capturing in 2D and directional accuracy on a Cartesian grid.",
  "physics": {
   "dimensionality": "2D",
   "flow_type": "free_surface",
   "governing_equations": [
    "shallow_water_2d"
   ],
   "phenomena": [
    "oblique_jump",
    "supercritical",
    "shock"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Ippen, A. T."
     ],
     "year": 1951,
     "title": "Mechanics of supercritical flow",
     "report_number": "ASCE Trans. 116:268-295"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/params.json",
    "role": "parameters",
    "format": "json",
    "sha256": "371f5f6bef6c7b1c2b017930dac620783ddedfd687b90519df82dbc6a20ac221"
   }
  ],
  "reference": {
   "kind": "analytic",
   "generator": {
    "module": "references.oblique_jump",
    "function": "depth_velocity",
    "parameters": {
     "Fr1": 2.5,
     "theta_deg": 15.0,
     "h1": 1.0,
     "g": 9.81
    }
   }
  },
  "simulation": {
   "t_end": 50.0,
   "output_interval": 2.0,
   "required_outputs": [
    "h",
    "u",
    "v"
   ],
   "mesh_refinement": {
    "levels": [
     2.0,
     1.0,
     0.5,
     0.25
    ],
    "fixed_courant": 0.45
   }
  },
  "scoring": {
   "criteria": [
    {
     "id": "depth_L1",
     "metric": "L1",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.05,
      "units": "m"
     },
     "gating": true,
     "rationale": "Mean depth error within 5 cm of the exact two-state field on the finest grid (6 % of the 0.81 m depth jump); a jump at the wrong angle or with the wrong conjugate depth fails."
    },
    {
     "id": "mass",
     "metric": "global_mass_error",
     "variable": "volume",
     "threshold": {
      "op": "abs<=",
      "value": 0.1,
      "units": "%"
     },
     "gating": true,
     "rationale": "Stored volume within 0.1 % of the exact field: the jump sits where the jump conditions put it."
    }
   ],
   "convergence": {
    "norm": "L1",
    "variable": "h",
    "expected_order": 1.0,
    "min_observed_order": 0.8
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "test_id": "A2C-EA1_disconnected_water_body",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_class": "intercomparison",
  "title": "EA Test 1 — flooding a disconnected water body",
  "description": "700 m × 100 m sloping strip with a depression behind a 10.25 m sill. A water-level boundary rises from 9.7 m to 10.35 m, holds, then falls back; the pond must fill, become horizontal, and settle at the sill crest. Tests wetting/drying and disconnected water bodies.",
  "physics": {
   "dimensionality": "2D",
   "flow_type": "free_surface",
   "governing_equations": [
    "shallow_water_2d"
   ],
   "phenomena": [
    "wet_dry",
    "disconnected_water_body",
    "inundation"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Néelz, S.",
      "Pender, G."
     ],
     "year": 2013,
     "title": "Benchmarking the Latest Generation of 2D Hydraulic Modelling Packages",
     "report_number": "SC120002",
     "isbn": "978-1-84911-306-9",
     "url": "https://www.gov.uk/flood-and-coastal-erosion-risk-management-research-reports/2d-benchmarking-evaluating-the-latest-generation-of-the-hydraulic-models-for-fcrm"
    },
    {
     "authors": [
      "Néelz, S.",
      "Pender, G."
     ],
     "year": 2010,
     "title": "Benchmarking of 2D Hydraulic Modelling Packages",
     "report_number": "SC080035/SR2",
     "url": "https://assets.publishing.service.gov.uk/media/5a75765c40f0b6360e4744dd/scho0510bsno-e-e.pdf"
    }
   ],
   "license": "OGL-UK-3.0",
   "adaptation_notes": "Inputs come from the GOV.UK 'Benchmarking model data' archive, published under the Open Government Licence v3.0 (the page licence; the archive carries no other terms). Attribution: Environment Agency, SC120002 (2013), test specifications May 2010. Committed: boundary table, output points, case.json. DEM fetched by hash."
  },
  "inputs": [
   {
    "path": "inputs/terrain.asc",
    "role": "terrain",
    "format": "esri_ascii_grid",
    "sha256": "96dc6541a3e53f6fcae5d1984452a87b3892a9f5f097bb2b86e9fa614104616a",
    "committed": false,
    "source": {
     "url": "https://assets.publishing.service.gov.uk/media/6033a9bbd3bf7f72182e99ca/Benchmarking_Model_Data.zip",
     "archive_sha256": "388c2789570e5975fe909033e34bedbe5d7bde5e6d7f9b7d7c1eaf04e58bc732",
     "members": [
      "Test1_dataset_2010.zip",
      "Test1 dataset 2010/test1DEM.asc"
     ]
    },
    "crs": "local"
   },
   {
    "path": "inputs/boundary_level.csv",
    "sha256": "c0a001dd8971b25b7f1ee87b491aa92b8ae20d39d74e82db9b67a7c4cc50fd93",
    "role": "boundary_condition",
    "format": "csv"
   },
   {
    "path": "inputs/output_points.csv",
    "sha256": "6b89f16db52d41d135979c93418c0c56a21a39f426993cbba70ed5fc619318f5",
    "role": "probes",
    "format": "csv"
   },
   {
    "path": "inputs/case.json",
    "sha256": "70b96e6d913a91197161d63eabc5ec2fb2135abc80cc9fbd4cda9ea263154ccf",
    "role": "case_parameters",
    "format": "json"
   }
  ],
  "reference": {
   "kind": "intercomparison",
   "expected_states": [
    {
     "id": "pond_final_level_p1",
     "variable": "h+z",
     "where": "P1",
     "time": 72000,
     "value": 10.25,
     "units": "m",
     "derivation": "Specification §2: after the boundary falls the pond becomes horizontal at the sill elevation, 10.25 m (sill crest at x = 300 m in the DEM)."
    },
    {
     "id": "pond_final_level_p2",
     "variable": "h+z",
     "where": "P2",
     "time": 72000,
     "value": 10.25,
     "units": "m",
     "derivation": "As P1; both points lie in the same pond."
    },
    {
     "id": "peak_level",
     "variable": "h+z",
     "where": "P1,P2",
     "value": 10.35,
     "units": "m",
     "derivation": "Boundary holds 10.35 m for 10 h (60–660 min), long enough for the whole domain to become horizontal (specification §2)."
    },
    {
     "id": "final_stored_volume",
     "variable": "volume",
     "time": 72000,
     "value": 9954.1,
     "units": "m3",
     "derivation": "Pond below 10.25 m (9887.3 m³) plus water below 9.7 m elsewhere (66.9 m³), integrated on the 2 m EA DEM. Solvers on a 10 m grid sample the DEM differently, so this check does not gate."
    }
   ],
   "ensemble": {
    "source": "SC120002 report, Test 1 figures",
    "availability": "permission_required",
    "notes": "Published package results exist only as figures in the SC120002 report, whose text is 'All rights reserved … reproduced with prior permission of the Environment Agency'. They are shown for context once digitised with EA permission and never gate."
   }
  },
  "simulation": {
   "t_end": 72000.0,
   "output_interval": 60.0,
   "required_outputs": [
    "h",
    "u",
    "v"
   ],
   "probes": [
    {
     "id": "P1",
     "x": 400.0,
     "y": 50.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P2",
     "x": 600.0,
     "y": 50.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    }
   ]
  },
  "scoring": {
   "pass_rule": "all_gating",
   "criteria": [
    {
     "id": "final_level_p1",
     "metric": "expected_state_error",
     "against": "pond_final_level_p1",
     "variable": "h",
     "where": "P1",
     "threshold": {
      "op": "abs<=",
      "value": 0.02,
      "units": "m"
     },
     "gating": true,
     "rationale": "A solver that conserves mass and handles the sill must leave the pond at the crest level; 2 cm allows for slow drainage over the sill by t = 20 h."
    },
    {
     "id": "final_level_p2",
     "metric": "expected_state_error",
     "against": "pond_final_level_p2",
     "variable": "h",
     "where": "P2",
     "threshold": {
      "op": "abs<=",
      "value": 0.02,
      "units": "m"
     },
     "gating": true,
     "rationale": "Same pond as P1, so it must settle at the same 10.25 m crest level; a second point catches a solver that leaves the pond tilted or partly drained."
    },
    {
     "id": "peak_level",
     "metric": "expected_state_error",
     "against": "peak_level",
     "variable": "h",
     "where": "P1,P2",
     "threshold": {
      "op": "abs<=",
      "value": 0.02,
      "units": "m"
     },
     "gating": true,
     "rationale": "Hydrostatic plateau level during the 10 h hold."
    },
    {
     "id": "final_volume",
     "metric": "expected_state_error",
     "against": "final_stored_volume",
     "variable": "volume",
     "threshold": {
      "op": "abs<=",
      "value": 2.0,
      "units": "%"
     },
     "gating": false,
     "rationale": "Informational: depends on how the solver samples the 2 m DEM onto its own grid."
    }
   ]
  }
 },
 {
  "schema_version": "1.1.0",
  "test_id": "A2C-EA2_floodplain_depressions",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_class": "intercomparison",
  "title": "EA Test 2 — filling of floodplain depressions",
  "description": "2 km × 2 km floodplain with a 4 × 4 grid of ~0.5 m deep depressions; a 20 m³/s, ~85 min hydrograph enters along 100 m of the north-west edge and the run continues to 48 h. Tests low-momentum filling and final inundation extent.",
  "physics": {
   "dimensionality": "2D",
   "flow_type": "free_surface",
   "governing_equations": [
    "shallow_water_2d"
   ],
   "phenomena": [
    "wet_dry",
    "storage",
    "low_momentum_flow",
    "inundation"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Néelz, S.",
      "Pender, G."
     ],
     "year": 2013,
     "title": "Benchmarking the Latest Generation of 2D Hydraulic Modelling Packages",
     "report_number": "SC120002",
     "isbn": "978-1-84911-306-9",
     "url": "https://www.gov.uk/flood-and-coastal-erosion-risk-management-research-reports/2d-benchmarking-evaluating-the-latest-generation-of-the-hydraulic-models-for-fcrm"
    },
    {
     "authors": [
      "Néelz, S.",
      "Pender, G."
     ],
     "year": 2010,
     "title": "Benchmarking of 2D Hydraulic Modelling Packages",
     "report_number": "SC080035/SR2",
     "url": "https://assets.publishing.service.gov.uk/media/5a75765c40f0b6360e4744dd/scho0510bsno-e-e.pdf"
    }
   ],
   "license": "OGL-UK-3.0",
   "adaptation_notes": "Inputs come from the GOV.UK 'Benchmarking model data' archive, published under the Open Government Licence v3.0 (the page licence; the archive carries no other terms). Attribution: Environment Agency, SC120002 (2013), test specifications May 2010. Committed: inflow table, output points, active-area polygon, case.json. DEM fetched by hash."
  },
  "inputs": [
   {
    "path": "inputs/terrain.asc",
    "role": "terrain",
    "format": "esri_ascii_grid",
    "sha256": "92d85335a20c1b0dfeccc92d49df1bded32e5244be10a4a81a353d42d255f473",
    "committed": false,
    "source": {
     "url": "https://assets.publishing.service.gov.uk/media/6033a9bbd3bf7f72182e99ca/Benchmarking_Model_Data.zip",
     "archive_sha256": "388c2789570e5975fe909033e34bedbe5d7bde5e6d7f9b7d7c1eaf04e58bc732",
     "members": [
      "Test2_dataset_2010.zip",
      "Test2 dataset 2010/test2DEM.asc"
     ]
    },
    "crs": "local"
   },
   {
    "path": "inputs/active_area.shp",
    "sha256": "427f2f26033aa07b39f62278c69c903d19308588bd4fc0781d108069d5d633a3",
    "role": "active_area",
    "format": "shp"
   },
   {
    "path": "inputs/inflow.csv",
    "sha256": "533033b11da4356efbf94c4518667a9e2fa9ce80f6f6142b64f4d230908b4b44",
    "role": "boundary_condition",
    "format": "csv"
   },
   {
    "path": "inputs/output_points.csv",
    "sha256": "8ead735333d9e563851b4f669ff1afd43770ff206aeff1a6ea75032939ea5861",
    "role": "probes",
    "format": "csv"
   },
   {
    "path": "inputs/case.json",
    "sha256": "f8c74353d71563b0e64016320cf386d18fb621f6b961a082832f3294a37e2751",
    "role": "case_parameters",
    "format": "json"
   }
  ],
  "reference": {
   "kind": "intercomparison",
   "expected_states": [
    {
     "id": "final_stored_volume",
     "variable": "volume",
     "time": 172800.0,
     "value": 97200.0,
     "units": "m3",
     "derivation": "Closed boundaries and a dry initial bed: stored volume at the end of the run equals the linearly interpolated inflow hydrograph integrated to t_end."
    }
   ],
   "ensemble": {
    "source": "SC120002 report, Test 2 figures",
    "availability": "permission_required",
    "notes": "Published package results exist only as figures in the SC120002 report, whose text is 'All rights reserved … reproduced with prior permission of the Environment Agency'. They are shown for context once digitised with EA permission and never gate."
   }
  },
  "simulation": {
   "t_end": 172800.0,
   "output_interval": 300.0,
   "required_outputs": [
    "h",
    "u",
    "v"
   ],
   "probes": [
    {
     "id": "P1",
     "x": 250.0,
     "y": 250.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P2",
     "x": 250.0,
     "y": 750.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P3",
     "x": 250.0,
     "y": 1250.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P4",
     "x": 250.0,
     "y": 1750.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P5",
     "x": 750.0,
     "y": 250.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P6",
     "x": 750.0,
     "y": 750.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P7",
     "x": 750.0,
     "y": 1250.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P8",
     "x": 750.0,
     "y": 1750.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P9",
     "x": 1250.0,
     "y": 250.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P10",
     "x": 1250.0,
     "y": 750.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P11",
     "x": 1250.0,
     "y": 1250.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P12",
     "x": 1250.0,
     "y": 1750.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P13",
     "x": 1750.0,
     "y": 250.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P14",
     "x": 1750.0,
     "y": 750.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P15",
     "x": 1750.0,
     "y": 1250.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P16",
     "x": 1750.0,
     "y": 1750.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    }
   ]
  },
  "scoring": {
   "pass_rule": "all_gating",
   "criteria": [
    {
     "id": "mass_conservation",
     "metric": "expected_state_error",
     "against": "final_stored_volume",
     "variable": "volume",
     "threshold": {
      "op": "abs<=",
      "value": 0.1,
      "units": "%"
     },
     "gating": true,
     "rationale": "The only exact statement the test admits: nothing leaves a closed domain, so any difference is mass created or lost by the scheme (suite target < 0.1 %)."
    }
   ]
  }
 },
 {
  "schema_version": "1.1.0",
  "test_id": "A2C-EA4_flood_propagation_speed",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_class": "intercomparison",
  "title": "EA Test 4 — speed of flood propagation over an extended floodplain",
  "description": "Flat, horizontal 1000 m × 2000 m floodplain at 0 m; a breach hydrograph peaking at 20 m³/s enters along a 20 m line mid-way along the west edge. Tests front celerity and transient depths and velocities at the leading edge.",
  "physics": {
   "dimensionality": "2D",
   "flow_type": "free_surface",
   "governing_equations": [
    "shallow_water_2d"
   ],
   "phenomena": [
    "wet_dry",
    "front_propagation",
    "inundation"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Néelz, S.",
      "Pender, G."
     ],
     "year": 2013,
     "title": "Benchmarking the Latest Generation of 2D Hydraulic Modelling Packages",
     "report_number": "SC120002",
     "isbn": "978-1-84911-306-9",
     "url": "https://www.gov.uk/flood-and-coastal-erosion-risk-management-research-reports/2d-benchmarking-evaluating-the-latest-generation-of-the-hydraulic-models-for-fcrm"
    },
    {
     "authors": [
      "Néelz, S.",
      "Pender, G."
     ],
     "year": 2010,
     "title": "Benchmarking of 2D Hydraulic Modelling Packages",
     "report_number": "SC080035/SR2",
     "url": "https://assets.publishing.service.gov.uk/media/5a75765c40f0b6360e4744dd/scho0510bsno-e-e.pdf"
    }
   ],
   "license": "OGL-UK-3.0",
   "adaptation_notes": "Inputs come from the GOV.UK 'Benchmarking model data' archive, published under the Open Government Licence v3.0 (the page licence; the archive carries no other terms). Attribution: Environment Agency, SC120002 (2013), test specifications May 2010. Committed: inflow table, output points, active-area polygon, case.json. No DEM: the bed is flat at 0 m (specification §6)."
  },
  "inputs": [
   {
    "path": "inputs/inflow.csv",
    "sha256": "c640e05f6bf9c2d1a9c3ce85ca4e10f72a3559ea2c818b7e106ba69bd07cc4a1",
    "role": "boundary_condition",
    "format": "csv"
   },
   {
    "path": "inputs/output_points.csv",
    "sha256": "77fb98ecea8712f3d2d2aad76f0fd522c94077c8d5a0492255fdbb8dd960b327",
    "role": "probes",
    "format": "csv"
   },
   {
    "path": "inputs/case.json",
    "sha256": "be39d8144b77957e39111b47c6f4a06f78283c2c3bef7c77eba1adc3e2886adf",
    "role": "case_parameters",
    "format": "json"
   }
  ],
  "reference": {
   "kind": "intercomparison",
   "expected_states": [
    {
     "id": "final_stored_volume",
     "variable": "volume",
     "time": 18000.0,
     "value": 285000.0,
     "units": "m3",
     "derivation": "Closed boundaries and a dry initial bed: stored volume at the end of the run equals the linearly interpolated inflow hydrograph integrated to t_end."
    }
   ],
   "ensemble": {
    "source": "SC120002 report, Test 4 figures",
    "availability": "permission_required",
    "notes": "Published package results exist only as figures in the SC120002 report, whose text is 'All rights reserved … reproduced with prior permission of the Environment Agency'. They are shown for context once digitised with EA permission and never gate."
   }
  },
  "simulation": {
   "t_end": 18000.0,
   "output_interval": 20.0,
   "required_outputs": [
    "h",
    "u",
    "v"
   ],
   "probes": [
    {
     "id": "P1",
     "x": 50.0,
     "y": 1000.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P2",
     "x": 100.0,
     "y": 1000.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P3",
     "x": 200.0,
     "y": 1000.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P4",
     "x": 300.0,
     "y": 1000.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P5",
     "x": 400.0,
     "y": 1000.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P6",
     "x": 300.0,
     "y": 1300.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    }
   ]
  },
  "scoring": {
   "pass_rule": "all_gating",
   "criteria": [
    {
     "id": "mass_conservation",
     "metric": "expected_state_error",
     "against": "final_stored_volume",
     "variable": "volume",
     "threshold": {
      "op": "abs<=",
      "value": 0.1,
      "units": "%"
     },
     "gating": true,
     "rationale": "The only exact statement the test admits: nothing leaves a closed domain, so any difference is mass created or lost by the scheme (suite target < 0.1 %)."
    }
   ]
  }
 },
 {
  "schema_version": "1.1.0",
  "test_id": "A2C-EA5_valley_flooding",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_class": "intercomparison",
  "title": "EA Test 5 — valley flooding",
  "description": "Dam-failure hydrograph (peak 3000 m³/s) released down a ~17 km valley whose slope eases from ~0.01 to ~0.001, producing both super- and subcritical flow, run to 30 h. Tests peak levels, velocities and travel times.",
  "physics": {
   "dimensionality": "2D",
   "flow_type": "free_surface",
   "governing_equations": [
    "shallow_water_2d"
   ],
   "phenomena": [
    "wet_dry",
    "transcritical",
    "dam_break",
    "inundation"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Néelz, S.",
      "Pender, G."
     ],
     "year": 2013,
     "title": "Benchmarking the Latest Generation of 2D Hydraulic Modelling Packages",
     "report_number": "SC120002",
     "isbn": "978-1-84911-306-9",
     "url": "https://www.gov.uk/flood-and-coastal-erosion-risk-management-research-reports/2d-benchmarking-evaluating-the-latest-generation-of-the-hydraulic-models-for-fcrm"
    },
    {
     "authors": [
      "Néelz, S.",
      "Pender, G."
     ],
     "year": 2010,
     "title": "Benchmarking of 2D Hydraulic Modelling Packages",
     "report_number": "SC080035/SR2",
     "url": "https://assets.publishing.service.gov.uk/media/5a75765c40f0b6360e4744dd/scho0510bsno-e-e.pdf"
    }
   ],
   "license": "OGL-UK-3.0",
   "adaptation_notes": "Inputs come from the GOV.UK 'Benchmarking model data' archive, published under the Open Government Licence v3.0 (the page licence; the archive carries no other terms). Attribution: Environment Agency, SC120002 (2013), test specifications May 2010. Committed: inflow table, output points, active-area polygon, case.json. DEM fetched by hash."
  },
  "inputs": [
   {
    "path": "inputs/terrain.asc",
    "role": "terrain",
    "format": "esri_ascii_grid",
    "sha256": "bab3711e9fdcfa4b3599c91894d9dff216eca252f4deafb25e9923c39309c488",
    "committed": false,
    "source": {
     "url": "https://assets.publishing.service.gov.uk/media/6033a9bbd3bf7f72182e99ca/Benchmarking_Model_Data.zip",
     "archive_sha256": "388c2789570e5975fe909033e34bedbe5d7bde5e6d7f9b7d7c1eaf04e58bc732",
     "members": [
      "Test5_dataset_2010.zip",
      "Test5 dataset 2010/Test5DEM.asc"
     ]
    },
    "crs": "EPSG:27700"
   },
   {
    "path": "inputs/active_area.shp",
    "sha256": "cb3af8927f6203b459bd24e59f73c084bf3a8a72d055eefd875ff2bbc843c09a",
    "role": "active_area",
    "format": "shp"
   },
   {
    "path": "inputs/inflow.csv",
    "sha256": "bd464cffa339c0612478d6315f4d2915b86511d15d59f0dd6df3445726bc2bfb",
    "role": "boundary_condition",
    "format": "csv"
   },
   {
    "path": "inputs/output_points.csv",
    "sha256": "e8c8eccab28f5581441cd0d6dcc92eb4151f4f2e1322e4c52246aa20510f0fac",
    "role": "probes",
    "format": "csv"
   },
   {
    "path": "inputs/case.json",
    "sha256": "ef24fd3ad639208d98a750dcc8ec8a4eb5013de7f5f0a92fab171ac307e2ce07",
    "role": "case_parameters",
    "format": "json"
   }
  ],
  "reference": {
   "kind": "intercomparison",
   "expected_states": [
    {
     "id": "final_stored_volume",
     "variable": "volume",
     "time": 108000.0,
     "value": 9450000.0,
     "units": "m3",
     "derivation": "Closed boundaries and a dry initial bed: stored volume at the end of the run equals the linearly interpolated inflow hydrograph integrated to t_end."
    }
   ],
   "ensemble": {
    "source": "SC120002 report, Test 5 figures",
    "availability": "permission_required",
    "notes": "Published package results exist only as figures in the SC120002 report, whose text is 'All rights reserved … reproduced with prior permission of the Environment Agency'. They are shown for context once digitised with EA permission and never gate."
   }
  },
  "simulation": {
   "t_end": 108000.0,
   "output_interval": 60.0,
   "required_outputs": [
    "h",
    "u",
    "v"
   ],
   "probes": [
    {
     "id": "P1",
     "x": 235200.0,
     "y": 832400.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P2",
     "x": 236700.0,
     "y": 833800.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P3",
     "x": 237800.0,
     "y": 835200.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P4",
     "x": 239400.0,
     "y": 838000.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P5",
     "x": 243300.0,
     "y": 840300.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P6",
     "x": 235700.0,
     "y": 832500.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "P7",
     "x": 237700.0,
     "y": 835500.0,
     "variables": [
      "h",
      "u",
      "v"
     ]
    }
   ]
  },
  "scoring": {
   "pass_rule": "all_gating",
   "criteria": [
    {
     "id": "mass_conservation",
     "metric": "expected_state_error",
     "against": "final_stored_volume",
     "variable": "volume",
     "threshold": {
      "op": "abs<=",
      "value": 0.1,
      "units": "%"
     },
     "gating": true,
     "rationale": "The only exact statement the test admits: nothing leaves a closed domain, so any difference is mass created or lost by the scheme (suite target < 0.1 %)."
    }
   ]
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "0.1.0",
  "status": "draft",
  "track": "A",
  "test_id": "A2L-010_idealised_city_dambreak",
  "test_class": "validation_lab",
  "title": "Idealised city dam-break",
  "description": "Dam-break flow through an idealised urban district (Soares-Frazão & Zech 2008).",
  "physics": {
   "dimensionality": "2D",
   "flow_type": "free_surface",
   "governing_equations": [
    "shallow_water_2d"
   ],
   "phenomena": [
    "dam_break",
    "urban",
    "wet_dry"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Soares-Frazão, S.",
      "Zech, Y."
     ],
     "year": 2008,
     "title": "Dam-break flow through an idealised city",
     "doi": "10.3826/jhr.2008.3164"
    }
   ],
   "license": "TBD-confirm",
   "adaptation_notes": "CADAM/IMPACT laboratory data blocked pending license confirmation."
  },
  "inputs": [
   {
    "path": "inputs/bathymetry.tif",
    "role": "terrain",
    "format": "tif",
    "pending": {
     "reason": "UCLouvain idealised-city flume geometry (Soares-Frazão & Zech 2008); terms not confirmed.",
     "obtain_from": "Université catholique de Louvain (Soares-Frazão)"
    }
   }
  ],
  "reference": {
   "kind": "measured",
   "data_path": "reference/measurements.parquet",
   "uncertainty": {
    "type": "relative",
    "value": 0.05,
    "units": "1",
    "notes": "Draft placeholder uncertainty; replace with published gauge error."
   },
   "include_measurement_uncertainty": true,
   "availability": "pending_license"
  },
  "simulation": {
   "t_end": 30.0,
   "output_interval": 0.5,
   "required_outputs": [
    "h",
    "u",
    "v"
   ]
  },
  "scoring": {
   "criteria": [
    {
     "id": "gauge_NSE",
     "metric": "NSE",
     "variable": "h",
     "threshold": {
      "op": ">=",
      "value": 0.6,
      "units": "1"
     },
     "gating": true,
     "rationale": "NSE vs laboratory gauges ≥ 0.6 within measurement uncertainty."
    },
    {
     "id": "front",
     "metric": "front_position_error",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.1,
      "units": "m"
     },
     "gating": true,
     "rationale": "Wet/dry front position within 0.1 m of lab imagery / gauges."
    }
   ],
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "0.1.0",
  "status": "draft",
  "track": "A",
  "test_id": "A2L-011_toce_urban_district",
  "test_class": "validation_lab",
  "title": "Toce urban district",
  "description": "Flash-flood experiment in a simplified urban district (CADAM / IMPACT).",
  "physics": {
   "dimensionality": "2D",
   "flow_type": "free_surface",
   "governing_equations": [
    "shallow_water_2d"
   ],
   "phenomena": [
    "dam_break",
    "urban",
    "wet_dry"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Testa, G.",
      "Zuccalà, D.",
      "Alcrudo, F.",
      "Mulet, J.",
      "Soares-Frazão, S."
     ],
     "year": 2007,
     "title": "Flash flood flow experiment in a simplified urban district",
     "doi": "10.1080/00221686.2007.9521831"
    }
   ],
   "license": "TBD-confirm",
   "adaptation_notes": "CADAM/IMPACT laboratory data blocked pending license confirmation."
  },
  "inputs": [
   {
    "path": "inputs/bathymetry.tif",
    "role": "terrain",
    "format": "tif",
    "pending": {
     "reason": "Toce urban-district model geometry (CADAM / IMPACT, ENEL-CRIS); terms not confirmed.",
     "obtain_from": "ENEL-CRIS / IMPACT project partners"
    }
   }
  ],
  "reference": {
   "kind": "measured",
   "data_path": "reference/measurements.parquet",
   "uncertainty": {
    "type": "relative",
    "value": 0.05,
    "units": "1",
    "notes": "Draft placeholder uncertainty; replace with published gauge error."
   },
   "include_measurement_uncertainty": true,
   "availability": "pending_license"
  },
  "simulation": {
   "t_end": 30.0,
   "output_interval": 0.5,
   "required_outputs": [
    "h",
    "u",
    "v"
   ]
  },
  "scoring": {
   "criteria": [
    {
     "id": "gauge_NSE",
     "metric": "NSE",
     "variable": "h",
     "threshold": {
      "op": ">=",
      "value": 0.6,
      "units": "1"
     },
     "gating": true,
     "rationale": "NSE vs laboratory gauges ≥ 0.6 within measurement uncertainty."
    },
    {
     "id": "front",
     "metric": "front_position_error",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.1,
      "units": "m"
     },
     "gating": true,
     "rationale": "Wet/dry front position within 0.1 m of lab imagery / gauges."
    }
   ],
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "0.1.0",
  "status": "draft",
  "track": "A",
  "test_id": "A2L-020_triangular_sill_wetdry",
  "test_class": "validation_lab",
  "title": "Triangular sill wet/dry",
  "description": "Dam-break wave over a triangular bottom sill with wetting and drying.",
  "physics": {
   "dimensionality": "2D",
   "flow_type": "free_surface",
   "governing_equations": [
    "shallow_water_2d"
   ],
   "phenomena": [
    "dam_break",
    "urban",
    "wet_dry"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Soares-Frazão, S."
     ],
     "year": 2007,
     "title": "Experiments of dam-break wave over a triangular bottom sill",
     "doi": "10.1080/00221686.2007.9521829"
    }
   ],
   "license": "TBD-confirm",
   "adaptation_notes": "CADAM/IMPACT laboratory data blocked pending license confirmation."
  },
  "inputs": [
   {
    "path": "inputs/bathymetry.tif",
    "role": "terrain",
    "format": "tif",
    "pending": {
     "reason": "Triangular-sill flume geometry (Soares-Frazão 2007, CADAM); terms not confirmed.",
     "obtain_from": "Université catholique de Louvain (Soares-Frazão)"
    }
   }
  ],
  "reference": {
   "kind": "measured",
   "data_path": "reference/measurements.parquet",
   "uncertainty": {
    "type": "relative",
    "value": 0.05,
    "units": "1",
    "notes": "Draft placeholder uncertainty; replace with published gauge error."
   },
   "include_measurement_uncertainty": true,
   "availability": "pending_license"
  },
  "simulation": {
   "t_end": 30.0,
   "output_interval": 0.5,
   "required_outputs": [
    "h",
    "u",
    "v"
   ]
  },
  "scoring": {
   "criteria": [
    {
     "id": "gauge_NSE",
     "metric": "NSE",
     "variable": "h",
     "threshold": {
      "op": ">=",
      "value": 0.6,
      "units": "1"
     },
     "gating": true,
     "rationale": "NSE vs laboratory gauges ≥ 0.6 within measurement uncertainty."
    },
    {
     "id": "front",
     "metric": "front_position_error",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 0.1,
      "units": "m"
     },
     "gating": true,
     "rationale": "Wet/dry front position within 0.1 m of lab imagery / gauges."
    }
   ],
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "test_id": "A2L-EA6A_dambreak_isolated_building",
  "case_version": "1.0.0",
  "status": "draft",
  "track": "A",
  "test_class": "validation_lab",
  "title": "EA Test 6A — dam break past an isolated building (laboratory scale)",
  "description": "UCL laboratory dam break through a 1 m gate against a single idealised building (Soares-Frazão & Zech 2002, IMPACT), as adopted by the Environment Agency. Tests hydraulic jumps and the wake behind an obstacle against gauge measurements.",
  "physics": {
   "dimensionality": "2D",
   "flow_type": "free_surface",
   "governing_equations": [
    "shallow_water_2d"
   ],
   "phenomena": [
    "dam_break",
    "hydraulic_jump",
    "obstacle_wake",
    "wet_dry"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Soares-Frazão, S.",
      "Zech, Y."
     ],
     "year": 2007,
     "title": "Experimental study of dam-break flow against an isolated obstacle",
     "doi": "10.1080/00221686.2007.9521830"
    },
    {
     "authors": [
      "Néelz, S.",
      "Pender, G."
     ],
     "year": 2013,
     "title": "Benchmarking the Latest Generation of 2D Hydraulic Modelling Packages",
     "report_number": "SC120002",
     "isbn": "978-1-84911-306-9",
     "url": "https://www.gov.uk/flood-and-coastal-erosion-risk-management-research-reports/2d-benchmarking-evaluating-the-latest-generation-of-the-hydraulic-models-for-fcrm"
    }
   ],
   "license": "OGL-UK-3.0",
   "adaptation_notes": "Inputs come from the GOV.UK 'Benchmarking model data' archive, published under the Open Government Licence v3.0 (the page licence; the archive carries no other terms). Attribution: Environment Agency, SC120002 (2013), test specifications May 2010. Gauge measurements (G1–G6) are not in the EA archive; they come from the IMPACT programme / Soares-Frazão & Zech (2007) and need redistribution terms before the case can leave draft."
  },
  "inputs": [
   {
    "path": "inputs/terrain.asc",
    "role": "terrain",
    "format": "esri_ascii_grid",
    "sha256": "69a0722f0620663423cf8ff52c4c48779d697b9a7a48929cee99fa7fcf4ad864",
    "committed": false,
    "source": {
     "url": "https://assets.publishing.service.gov.uk/media/6033a9bbd3bf7f72182e99ca/Benchmarking_Model_Data.zip",
     "archive_sha256": "388c2789570e5975fe909033e34bedbe5d7bde5e6d7f9b7d7c1eaf04e58bc732",
     "members": [
      "Test6_dataset_2010.zip",
      "Test6 dataset 2010/Test6ADEM.asc"
     ]
    },
    "crs": "local"
   },
   {
    "path": "inputs/output_points.csv",
    "sha256": "78123efa0ea4aee66c8469a6e02bb8546175fa5c02b498de1b98bf35d4c5498b",
    "role": "probes",
    "format": "csv"
   },
   {
    "path": "inputs/case.json",
    "sha256": "e2ae35f95ec878fa30ec74cd5cef2434eed8ec6c0ea53899a62eb4fbed271693",
    "role": "case_parameters",
    "format": "json"
   }
  ],
  "reference": {
   "kind": "measured",
   "data_path": "reference/gauges.parquet",
   "availability": "request_from_authors",
   "uncertainty": {
    "type": "absolute",
    "value": 0.005,
    "units": "m",
    "notes": "Provisional: replace with the gauge accuracy stated by Soares-Frazão & Zech (2007)."
   },
   "include_measurement_uncertainty": true
  },
  "simulation": {
   "t_end": 120.0,
   "output_interval": 0.1,
   "required_outputs": [
    "h",
    "u",
    "v"
   ],
   "probes": [
    {
     "id": "G1",
     "x": 2.65,
     "y": 1.15,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "G2",
     "x": 2.65,
     "y": -0.6,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "G3",
     "x": 4.0,
     "y": 1.15,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "G4",
     "x": 4.0,
     "y": -0.8,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "G5",
     "x": 5.2,
     "y": 0.3,
     "variables": [
      "h",
      "u",
      "v"
     ]
    },
    {
     "id": "G6",
     "x": -1.87,
     "y": 1.1,
     "variables": [
      "h",
      "u",
      "v"
     ]
    }
   ]
  },
  "scoring": {
   "pass_rule": "all_gating",
   "criteria": [
    {
     "id": "gauge_nse",
     "metric": "NSE",
     "variable": "h",
     "where": "G1-G5",
     "threshold": {
      "op": ">=",
      "value": 0.7,
      "units": "1"
     },
     "gating": true,
     "rationale": "Provisional; set from measurement uncertainty once gauge data are obtained."
    },
    {
     "id": "front_arrival",
     "metric": "arrival_time_error",
     "variable": "h",
     "where": "G1-G5",
     "threshold": {
      "op": "abs<=",
      "value": 0.5,
      "units": "s"
     },
     "gating": true,
     "rationale": "Provisional; five output steps at the specified 0.1 s frequency."
    }
   ]
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "0.1.0",
  "status": "draft",
  "track": "A",
  "test_id": "A2F-001_malpasset_1959",
  "test_class": "validation_field",
  "title": "Malpasset 1959 dam failure",
  "description": "Historical Malpasset dam-break (1959, France); 2D shallow-water field validation against surveyed high-water marks (CADAM).",
  "physics": {
   "dimensionality": "2D",
   "flow_type": "free_surface",
   "governing_equations": [
    "shallow_water_2d"
   ],
   "phenomena": [
    "dam_break",
    "field_inundation",
    "high_water_marks"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Hervouet, J.-M.",
      "Petitjean, A."
     ],
     "year": 1999,
     "title": "Malpasset dam-break revisited with two-dimensional computations",
     "doi": "10.1080/00221689909498511"
    }
   ],
   "license": "TBD-confirm",
   "adaptation_notes": "Terrain and high-water marks blocked pending license confirmation (Goutal 1999 CADAM definition)."
  },
  "inputs": [
   {
    "path": "inputs/terrain.tif",
    "role": "terrain",
    "format": "tif",
    "pending": {
     "reason": "CADAM/EDF Malpasset topography; redistribution terms not confirmed.",
     "obtain_from": "EDF R&D / CADAM partners; USACE LifeSim derivative"
    }
   }
  ],
  "reference": {
   "kind": "measured",
   "data_path": "reference/high_water_marks.csv",
   "uncertainty": {
    "type": "relative",
    "value": 0.1,
    "units": "1",
    "notes": "Draft placeholder uncertainty; replace with published gauge error."
   },
   "include_measurement_uncertainty": true,
   "availability": "pending_license"
  },
  "simulation": {
   "t_end": 4000.0,
   "output_interval": 10.0,
   "required_outputs": [
    "h",
    "u",
    "v"
   ]
  },
  "scoring": {
   "criteria": [
    {
     "id": "hwm",
     "metric": "L2",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 15.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "High-water mark elevations within 15% / stated survey uncertainty."
    },
    {
     "id": "arrival",
     "metric": "arrival_time_error",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 120.0,
      "units": "s"
     },
     "gating": true,
     "rationale": "Arrival at key valley gauges within 2 minutes of reconstruction."
    }
   ],
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "0.1.0",
  "status": "draft",
  "track": "A",
  "test_id": "A12-001_rubinato_manhole_exchange",
  "test_class": "validation_coupled",
  "title": "Rubinato manhole exchange",
  "description": "Laboratory sewer/surface exchange through a manhole; validate 1D–2D coupling exchange equations (Rubinato et al. 2017).",
  "physics": {
   "dimensionality": "1D2D",
   "flow_type": "mixed",
   "governing_equations": [
    "saint_venant_dynamic",
    "shallow_water_2d",
    "manhole_exchange"
   ],
   "phenomena": [
    "sewer_surface_exchange",
    "manhole",
    "urban_flood"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Rubinato, M.",
      "Martins, R.",
      "Kesserwani, G.",
      "Leandro, J.",
      "Djordjević, S.",
      "Shucksmith, J."
     ],
     "year": 2017,
     "title": "Experimental calibration and validation of sewer/surface flow exchange equations in steady and unsteady flow conditions",
     "doi": "10.1016/j.jhydrol.2017.06.024"
    }
   ],
   "license": "TBD-confirm",
   "adaptation_notes": "Draft: exchange hydrographs to be digitized from publication / obtained from authors."
  },
  "inputs": [
   {
    "path": "inputs/coupling.json",
    "role": "coupling",
    "format": "json",
    "pending": {
     "reason": "Manhole/surface exchange rig geometry and measured exchange flows from Rubinato et al. (2017); request data from the University of Sheffield authors.",
     "obtain_from": "University of Sheffield (Shucksmith group)"
    }
   }
  ],
  "reference": {
   "kind": "measured",
   "data_path": "reference/measurements.parquet",
   "uncertainty": {
    "type": "relative",
    "value": 0.05,
    "units": "1",
    "notes": "Draft placeholder uncertainty; replace with published gauge error."
   },
   "include_measurement_uncertainty": true,
   "availability": "request_from_authors"
  },
  "simulation": {
   "t_end": 300.0,
   "output_interval": 1.0,
   "required_outputs": [
    "h",
    "Q"
   ]
  },
  "scoring": {
   "criteria": [
    {
     "id": "exchange_Q",
     "metric": "NSE",
     "variable": "Q",
     "threshold": {
      "op": ">=",
      "value": 0.7,
      "units": "1"
     },
     "gating": true,
     "rationale": "NSE on manhole exchange discharge ≥ 0.7 vs laboratory."
    },
    {
     "id": "surface_h",
     "metric": "peak_error",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 5.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Surface depth peak within 5% of lab gauges."
    }
   ],
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A12-010_manhole_surcharge_onto_street",
  "test_class": "verification_analytic",
  "title": "Manhole surcharge onto a sloping street",
  "description": "A 0.6 m pipe delivers 0.5 m³/s to a manhole with no outlet, which surcharges onto a 10 m wide street sloping at 0.005 (Manning n = 0.02). At steady state the manhole passes the whole inflow onto the street, and downstream the street carries it as uniform sheet flow at the exact normal depth (n q / √S)^(3/5) = 77.7 mm.",
  "physics": {
   "dimensionality": "1D2D",
   "flow_type": "mixed",
   "governing_equations": [
    "saint_venant_dynamic",
    "shallow_water_2d",
    "manhole_exchange"
   ],
   "phenomena": [
    "sewer_surface_exchange",
    "manhole",
    "volume_balance"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Chen, A. S.",
      "Djordjević, S.",
      "Leandro, J.",
      "Savić, D. A."
     ],
     "year": 2007,
     "title": "The urban inundated area: a coupled 1D/2D model for the interaction between sewer and surface",
     "url": "https://www.researchgate.net/publication/257306339"
    },
    {
     "authors": [
      "Rubinato, M.",
      "Martins, R.",
      "Kesserwani, G.",
      "Leandro, J.",
      "Djordjević, S.",
      "Shucksmith, J."
     ],
     "year": 2017,
     "title": "Experimental calibration and validation of sewer/surface flow exchange equations in steady and unsteady flow conditions",
     "doi": "10.1016/j.jhydrol.2017.06.024"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/coupling.json",
    "role": "coupling",
    "format": "json",
    "sha256": "cd6872b93d6f5544888199b8f1c006592556058b5f7e5303829857effe0b08ac"
   }
  ],
  "reference": {
   "kind": "exact_states",
   "expected_states": [
    {
     "id": "steady_exchange",
     "variable": "Q",
     "element": "M1",
     "value": 0.5,
     "units": "m3/s",
     "derivation": "At steady state the manhole has no outlet but the street, so it must pass the full pipe inflow (continuity)."
    },
    {
     "id": "normal_depth",
     "variable": "h",
     "where": "P1,P2",
     "time": 1800,
     "value": 0.07768,
     "units": "m",
     "derivation": "Uniform sheet flow of q = Q/B = 0.05 m²/s on slope 0.005 with Manning n = 0.02 (hydraulic radius = depth in 2D shallow-water models): h = (n q / √S)^(3/5)."
    }
   ]
  },
  "simulation": {
   "t_end": 1800.0,
   "output_interval": 30.0,
   "required_outputs": [
    "h",
    "Q",
    "V"
   ],
   "probes": [
    {
     "id": "P1",
     "x": 100.5,
     "y": 5.0,
     "variables": [
      "h"
     ]
    },
    {
     "id": "P2",
     "x": 150.5,
     "y": 5.0,
     "variables": [
      "h"
     ]
    }
   ]
  },
  "scoring": {
   "criteria": [
    {
     "id": "exchange_flow",
     "metric": "expected_state_error",
     "threshold": {
      "op": "abs<=",
      "value": 1.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Steady manhole outflow within 1 % of the inflow.",
     "against": "steady_exchange",
     "variable": "Q"
    },
    {
     "id": "street_depth",
     "metric": "expected_state_error",
     "threshold": {
      "op": "abs<=",
      "value": 0.003,
      "units": "m"
     },
     "gating": true,
     "rationale": "Street depth 75–125 m below the manhole within 3 mm (4 %) of normal depth: the sheet must carry exactly what the manhole released.",
     "against": "normal_depth",
     "variable": "h",
     "where": "P1,P2"
    },
    {
     "id": "water_balance",
     "metric": "continuity_error",
     "threshold": {
      "op": "abs<=",
      "value": 0.5,
      "units": "%"
     },
     "gating": true,
     "rationale": "By the end of the run, the water stored on the surface and in the pipes has changed by exactly what came in minus what went out. A coupling that moves water between the two models must not make or lose any; each engine's own continuity error is allowed within this limit.",
     "variable": "volume"
    }
   ],
   "convergence": {
    "not_applicable": "Scored on exact states that follow from conservation (exchanged and discharged volumes, settled levels): they do not depend on the grid."
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A12-011_flood_draining_into_pipe",
  "test_class": "verification_analytic",
  "title": "Flood draining into a pipe",
  "description": "A 30 × 30 m walled yard holds 0.3 m of water (270 m³). It drains through a gully whose crest stands 5 cm above the yard floor into a 0.3 m pipe to a free outfall. The water above the crest leaves through the pipe; the 5 cm below it cannot. After two hours the yard is ponded at the crest level (45 m³ stays), and 225 m³ has left by the outfall.",
  "physics": {
   "dimensionality": "1D2D",
   "flow_type": "mixed",
   "governing_equations": [
    "saint_venant_dynamic",
    "shallow_water_2d",
    "manhole_exchange"
   ],
   "phenomena": [
    "sewer_surface_exchange",
    "manhole",
    "volume_balance"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Chen, A. S.",
      "Djordjević, S.",
      "Leandro, J.",
      "Savić, D. A."
     ],
     "year": 2007,
     "title": "The urban inundated area: a coupled 1D/2D model for the interaction between sewer and surface",
     "url": "https://www.researchgate.net/publication/257306339"
    },
    {
     "authors": [
      "Rubinato, M.",
      "Martins, R.",
      "Kesserwani, G.",
      "Leandro, J.",
      "Djordjević, S.",
      "Shucksmith, J."
     ],
     "year": 2017,
     "title": "Experimental calibration and validation of sewer/surface flow exchange equations in steady and unsteady flow conditions",
     "doi": "10.1016/j.jhydrol.2017.06.024"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/coupling.json",
    "role": "coupling",
    "format": "json",
    "sha256": "a94ee75f36fa520bc1a140e9d2ef23cde3391f2626f7e205dc37bb22dccc29d6"
   }
  ],
  "reference": {
   "kind": "exact_states",
   "expected_states": [
    {
     "id": "final_level",
     "variable": "h",
     "where": "P1,P2",
     "time": 7200,
     "value": 0.05,
     "units": "m",
     "derivation": "Water drains until the yard level reaches the gully crest, 0.05 m above the flat floor; nothing below the crest can enter."
    },
    {
     "id": "discharged_volume",
     "variable": "V",
     "element": "outflow",
     "time": 7200,
     "value": 225.0,
     "units": "m3",
     "derivation": "Initial 270 m³ (900 m² × 0.3 m) less the 45 m³ held below the crest (900 m² × 0.05 m); the pipe drains freely, so it holds none at the end."
    }
   ]
  },
  "simulation": {
   "t_end": 7200.0,
   "output_interval": 60.0,
   "required_outputs": [
    "h",
    "Q",
    "V"
   ],
   "probes": [
    {
     "id": "P1",
     "x": 5.0,
     "y": 5.0,
     "variables": [
      "h"
     ]
    },
    {
     "id": "P2",
     "x": 25.0,
     "y": 25.0,
     "variables": [
      "h"
     ]
    }
   ]
  },
  "scoring": {
   "criteria": [
    {
     "id": "final_level",
     "metric": "expected_state_error",
     "threshold": {
      "op": "abs<=",
      "value": 0.01,
      "units": "m"
     },
     "gating": true,
     "rationale": "Yard level within 1 cm of the crest after two hours: the last of the water over a crest drains slowly (as a weir it slows with the head to the 3/2), so a coupling with any reasonable exchange law is within a few millimetres.",
     "against": "final_level",
     "variable": "h",
     "where": "P1,P2"
    },
    {
     "id": "discharged_volume",
     "metric": "expected_state_error",
     "threshold": {
      "op": "abs<=",
      "value": 2.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Outfall volume within 2 % of 225 m³: the water above the crest has gone through the pipe.",
     "against": "discharged_volume",
     "variable": "V"
    },
    {
     "id": "water_balance",
     "metric": "continuity_error",
     "threshold": {
      "op": "abs<=",
      "value": 0.5,
      "units": "%"
     },
     "gating": true,
     "rationale": "By the end of the run, the water stored on the surface and in the pipes has changed by exactly what came in minus what went out. A coupling that moves water between the two models must not make or lose any; each engine's own continuity error is allowed within this limit.",
     "variable": "volume"
    }
   ],
   "convergence": {
    "not_applicable": "Scored on exact states that follow from conservation (exchanged and discharged volumes, settled levels): they do not depend on the grid."
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "A",
  "test_id": "A12-012_surcharge_and_return",
  "test_class": "verification_analytic",
  "title": "Surcharge onto the surface and back",
  "description": "A storm hydrograph (peak 0.3 m³/s at 10 min, 180 m³ in all) enters a sewer whose outgoing pipe carries only about 0.06 m³/s. The manhole surcharges onto a 20 × 20 m walled hollow that falls 1 % towards it; when the storm passes, the water returns down the manhole. After three hours every drop has left by the outfall.",
  "physics": {
   "dimensionality": "1D2D",
   "flow_type": "mixed",
   "governing_equations": [
    "saint_venant_dynamic",
    "shallow_water_2d",
    "manhole_exchange"
   ],
   "phenomena": [
    "sewer_surface_exchange",
    "manhole",
    "volume_balance"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Chen, A. S.",
      "Djordjević, S.",
      "Leandro, J.",
      "Savić, D. A."
     ],
     "year": 2007,
     "title": "The urban inundated area: a coupled 1D/2D model for the interaction between sewer and surface",
     "url": "https://www.researchgate.net/publication/257306339"
    },
    {
     "authors": [
      "Rubinato, M.",
      "Martins, R.",
      "Kesserwani, G.",
      "Leandro, J.",
      "Djordjević, S.",
      "Shucksmith, J."
     ],
     "year": 2017,
     "title": "Experimental calibration and validation of sewer/surface flow exchange equations in steady and unsteady flow conditions",
     "doi": "10.1016/j.jhydrol.2017.06.024"
    }
   ],
   "license": "analytic-public"
  },
  "inputs": [
   {
    "path": "inputs/coupling.json",
    "role": "coupling",
    "format": "json",
    "sha256": "bd25d0da008dcfdce9ff64e823a7eedf626c67100c802c1dde7eedcf2444e69f"
   }
  ],
  "reference": {
   "kind": "exact_states",
   "expected_states": [
    {
     "id": "discharged_volume",
     "variable": "V",
     "element": "outflow",
     "time": 10800,
     "value": 180.0,
     "units": "m3",
     "derivation": "Everything that enters (the hydrograph's 180 m³) must leave by the outfall: the hollow drains to the manhole and the pipes drain freely."
    },
    {
     "id": "surface_empty",
     "variable": "V",
     "element": "surface",
     "time": 10800,
     "value": 0.0,
     "units": "m3",
     "derivation": "The hollow slopes to the manhole, whose crest is at its lowest point, so no water can stay on the surface."
    }
   ]
  },
  "simulation": {
   "t_end": 10800.0,
   "output_interval": 60.0,
   "required_outputs": [
    "h",
    "Q",
    "V"
   ],
   "probes": [
    {
     "id": "P1",
     "x": 10.0,
     "y": 10.0,
     "variables": [
      "h"
     ]
    }
   ]
  },
  "scoring": {
   "criteria": [
    {
     "id": "discharged_volume",
     "metric": "expected_state_error",
     "threshold": {
      "op": "abs<=",
      "value": 2.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Outfall volume within 2 % of the 180 m³ that came in.",
     "against": "discharged_volume",
     "variable": "V"
    },
    {
     "id": "surface_empty",
     "metric": "expected_state_error",
     "threshold": {
      "op": "abs<=",
      "value": 1.8,
      "units": "m3"
     },
     "gating": true,
     "rationale": "At most 1.8 m³ (1 % of the storm) left on the surface: a thin film on the 1 % slope drains slowly.",
     "against": "surface_empty",
     "variable": "V"
    },
    {
     "id": "water_balance",
     "metric": "continuity_error",
     "threshold": {
      "op": "abs<=",
      "value": 0.5,
      "units": "%"
     },
     "gating": true,
     "rationale": "By the end of the run, the water stored on the surface and in the pipes has changed by exactly what came in minus what went out. A coupling that moves water between the two models must not make or lose any; each engine's own continuity error is allowed within this limit.",
     "variable": "volume"
    }
   ],
   "convergence": {
    "not_applicable": "Scored on exact states that follow from conservation (exchanged and discharged volumes, settled levels): they do not depend on the grid."
   },
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "test_id": "B-EPANET-001_net1_parity",
  "case_version": "1.0.0",
  "status": "candidate",
  "track": "B",
  "test_class": "parity",
  "title": "EPANET Net1 parity against EPANET 2.2",
  "description": "EPANET Example Network 1 (9 junctions, 1 reservoir, 1 tank, 12 pipes, 1 pump; 24 h extended period). Candidate nodal pressures and link flows are compared element by element with EPANET 2.2.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "pressurized",
   "governing_equations": [
    "steady_network_hydraulics",
    "extended_period_simulation"
   ],
   "phenomena": [
    "looped_network",
    "pump",
    "tank_filling"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Rossman, L. A.",
      "Woo, H.",
      "Tryby, M.",
      "Shang, F.",
      "Janke, R.",
      "Haxton, T."
     ],
     "year": 2020,
     "title": "EPANET 2.2 User Manual",
     "report_number": "EPA/600/R-20/133"
    }
   ],
   "license": "public-domain-EPA",
   "adaptation_notes": "Net1.inp is the example network distributed with EPA EPANET (public domain); copied unmodified from the WNTR 1.5.0 network library."
  },
  "inputs": [
   {
    "path": "inputs/network.inp",
    "role": "network",
    "format": "inp",
    "sha256": "607510a01287d60d27b280a39df31a001363175a438a5de1b39e749cec6ddbc8"
   }
  ],
  "reference": {
   "kind": "pinned_engine",
   "engine": "EPANET",
   "version": "2.2",
   "binary_sha256": "3a49fa2eb1aecdf4d7a83c9a26667bacc418d285ed1d3a45becec52e7556d73f",
   "results_path": "reference/epanet-2.2.parquet",
   "build": "wntr 1.5.0 (EPANET 2.2 library libepanet22)"
  },
  "simulation": {
   "t_end": 86400,
   "output_interval": 3600,
   "required_outputs": [
    "p",
    "Q"
   ]
  },
  "scoring": {
   "pass_rule": "all_gating",
   "criteria": [
    {
     "id": "peak_pressure",
     "metric": "relative_peak",
     "variable": "p",
     "threshold": {
      "op": "abs<=",
      "value": 1.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Nodal peak pressure within 1 % of EPANET 2.2 at every node."
    },
    {
     "id": "link_volume",
     "metric": "relative_volume",
     "variable": "Q",
     "threshold": {
      "op": "abs<=",
      "value": 1.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "24 h conveyed volume within 1 % of EPANET 2.2 in every pipe and pump."
    },
    {
     "id": "peak_timing",
     "metric": "timing_error",
     "variable": "Q",
     "threshold": {
      "op": "abs<=",
      "value": 3600,
      "units": "s"
     },
     "gating": false,
     "rationale": "Informational: one reporting step."
    }
   ]
  }
 },
 {
  "schema_version": "1.1.0",
  "test_id": "B-EXTRAN-001_extran_parity",
  "case_version": "2.0.0",
  "status": "candidate",
  "track": "B",
  "test_class": "parity",
  "title": "EXTRAN Manual Example 1: parity against SWMM 5.2.4",
  "description": "EXTRAN Manual Example 1 (Roesner et al. 1988) as distributed with the OWA/EPA SWMM 5 regression set: a dendritic sewer network with surcharge and three hydrograph inflows, 8 h dynamic-wave routing. Candidate depths and flows are compared with EPA SWMM 5.2.4 at every node and link. Case v2.0.0 replaces a 2-conduit synthetic fixture that v1 presented as this example.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "mixed",
   "governing_equations": [
    "saint_venant_dynamic",
    "pressurized_pipe"
   ],
   "phenomena": [
    "surcharge",
    "backwater",
    "network_routing"
   ]
  },
  "provenance": {
   "citations": [
    {
     "authors": [
      "Roesner, L. A.",
      "Aldrich, J. A.",
      "Dickinson, R. E."
     ],
     "year": 1988,
     "title": "Storm Water Management Model User's Manual, Version 4: EXTRAN Addendum",
     "report_number": "EPA/600/3-88/001b"
    },
    {
     "title": "openswmm.engine.benchmarks corpus: owa-extran/extran1",
     "authors": [
      "HydroCouple"
     ],
     "year": 2026,
     "url": "https://raw.githubusercontent.com/HydroCouple/openswmm.engine.benchmarks/63eb8bc5b4e741c82195ed65c4d7d146b86da1cc/corpus/owa-extran/extran1/model.inp"
    }
   ],
   "license": "Unlicense",
   "adaptation_notes": "Unmodified model from HydroCouple openswmm.engine.benchmarks at commit 63eb8bc5b4e741c82195ed65c4d7d146b86da1cc (public-domain dedication)."
  },
  "inputs": [
   {
    "path": "inputs/network.inp",
    "role": "network",
    "format": "inp",
    "sha256": "739391331b141c142b40e29f16289a3d56cd54315e748a3ca076a522b63c08be",
    "source": {
     "url": "https://raw.githubusercontent.com/HydroCouple/openswmm.engine.benchmarks/63eb8bc5b4e741c82195ed65c4d7d146b86da1cc/corpus/owa-extran/extran1/model.inp"
    }
   }
  ],
  "reference": {
   "kind": "pinned_engine",
   "engine": "SWMM",
   "version": "5.2.4",
   "binary_sha256": "7bac9983ec031415f04e8e6bdafc4878fd17cb7c3460d3323f41cad78f4a7a92",
   "results_path": "reference/swmm-5.2.4.parquet",
   "build": "swmm-toolkit 0.17.0 (EPA SWMM 5.2.4 engine)"
  },
  "simulation": {
   "t_end": 28800,
   "output_interval": 900,
   "required_outputs": [
    "h",
    "Q"
   ]
  },
  "scoring": {
   "criteria": [
    {
     "id": "peak_depth",
     "metric": "relative_peak",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 1.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Peak depth within ±1 % of SWMM 5.2.4 at every node."
    },
    {
     "id": "volume",
     "metric": "relative_volume",
     "variable": "Q",
     "threshold": {
      "op": "abs<=",
      "value": 1.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Conveyed volume within ±1 % of SWMM 5.2.4 in every link."
    }
   ],
   "pass_rule": "all_gating"
  }
 },
 {
  "schema_version": "1.1.0",
  "test_id": "B-RTC-001_pump_station_rules",
  "case_version": "2.0.0",
  "status": "candidate",
  "track": "B",
  "test_class": "parity",
  "title": "Control-rule parity: pump stations switched by wet-well level",
  "description": "A 90-node sanitary network (SI units) with two pump stations whose pumps are switched ON and OFF by IF/THEN rules on wet-well depth (e.g. pump U433_Psan_1_ou_2 switches 74 times in 36 h). Tests that a candidate evaluates control rules at the same moments as SWMM 5.2.4. Case v2.0.0 replaces EXTRAN Example 1 with a rule whose condition never changed, so v1 never exercised a switch.",
  "physics": {
   "dimensionality": "1D",
   "flow_type": "mixed",
   "governing_equations": [
    "saint_venant_dynamic"
   ],
   "phenomena": [
    "real_time_control",
    "pump",
    "wet_well",
    "network_routing"
   ]
  },
  "provenance": {
   "citations": [
    {
     "title": "openswmm.engine.benchmarks corpus: epa/221-h-h-si-units-elements",
     "authors": [
      "HydroCouple"
     ],
     "year": 2026,
     "url": "https://raw.githubusercontent.com/HydroCouple/openswmm.engine.benchmarks/63eb8bc5b4e741c82195ed65c4d7d146b86da1cc/corpus/epa/221-h-h-si-units-elements/model.inp"
    },
    {
     "authors": [
      "Rossman, L. A."
     ],
     "year": 2017,
     "title": "Storm Water Management Model Reference Manual, Volume II – Hydraulics",
     "report_number": "EPA/600/R-17/111"
    }
   ],
   "license": "Unlicense",
   "adaptation_notes": "Unmodified EPA example model from HydroCouple openswmm.engine.benchmarks at commit 63eb8bc5b4e741c82195ed65c4d7d146b86da1cc (public-domain dedication). Not committed (21,158 lines); fetched by hash."
  },
  "inputs": [
   {
    "path": "inputs/network.inp",
    "role": "network",
    "format": "inp",
    "sha256": "6756016d98e6d8f2f2db004ec61cb844e6c18210d7646e8fc783e9048945a589",
    "committed": false,
    "source": {
     "url": "https://raw.githubusercontent.com/HydroCouple/openswmm.engine.benchmarks/63eb8bc5b4e741c82195ed65c4d7d146b86da1cc/corpus/epa/221-h-h-si-units-elements/model.inp"
    }
   }
  ],
  "reference": {
   "kind": "pinned_engine",
   "engine": "SWMM",
   "version": "5.2.4",
   "binary_sha256": "7bac9983ec031415f04e8e6bdafc4878fd17cb7c3460d3323f41cad78f4a7a92",
   "results_path": "reference/swmm-5.2.4.parquet",
   "build": "swmm-toolkit 0.17.0 (EPA SWMM 5.2.4 engine)"
  },
  "simulation": {
   "t_end": 129600,
   "output_interval": 30,
   "required_outputs": [
    "h",
    "Q"
   ]
  },
  "scoring": {
   "pass_rule": "all_gating",
   "criteria": [
    {
     "id": "peak_depth",
     "metric": "relative_peak",
     "variable": "h",
     "threshold": {
      "op": "abs<=",
      "value": 2.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Architecture parity band (±2 % peak) at every node, wet wells included."
    },
    {
     "id": "link_volume",
     "metric": "relative_volume",
     "variable": "Q",
     "threshold": {
      "op": "abs<=",
      "value": 2.0,
      "units": "%"
     },
     "gating": true,
     "rationale": "Pumped and conveyed volume within ±2 % in every link: a rule that fires at the wrong level changes how much each pump moves."
    },
    {
     "id": "peak_timing",
     "metric": "timing_error",
     "variable": "Q",
     "threshold": {
      "op": "abs<=",
      "value": 120,
      "units": "s"
     },
     "gating": true,
     "rationale": "Four 30 s reporting steps; a rule evaluated at a different moment shifts pump-on times."
    }
   ]
  }
 }
]