Add routing module: steady-state runoff accumulation + peak discharge (1/2)#15
Merged
Conversation
floodpath.routing closes the rainfall-runoff loop's hydrologic-routing half. Per-cell SCS-CN runoff (mm) is reprojected onto the DEM-derived flow direction grid, converted to volume (m^3) using lat-aware cell areas, and accumulated downstream via pyflwdir's accuflux. Dividing the accumulated volume by an event duration yields per-cell peak discharge (m^3/s). PR1 of a planned two-PR routing sequence; the follow-up adds Manning normal-depth at stream cells to close the hydraulic side. - floodpath/routing/utils.py: cell_areas_m2(transform, shape, crs) handles WGS84 cos(lat) longitude convergence for geographic CRSes and falls back to abs(a*e) for projected CRSes. - floodpath/routing/accumulate.py: accumulate_runoff(runoff, flow_grid) -> AccumulatedRunoffGrid. Reprojects Q via Resampling.average (correct for area-weighted depth aggregation), zero-fills NaN before accuflux so the SCS-CN nodata patch doesn't poison downstream cells. - floodpath/routing/discharge.py: peak_discharge(accumulated, duration_s) -> DischargeGrid with Q_peak = V_acc / T per cell. - AccumulatedRunoffGrid carries total_volume_m3() (=outlet, NOT sum of cells which would double-count); DischargeGrid carries outlet_peak(). - Tests: 30 new — cell_areas_m2 sanity at equator vs 60 deg N (verifies cos(lat) shrinkage), peak-discharge V/T arithmetic with NRCS-default 6-hour duration, robust pinned values against the existing Robit Bata fixtures: outlet V_acc = 1.43 Mm^3, peak Q at outlet = 66.2 m^3/s for 100 mm uniform rain over 6-hour event. Smoke test gains stage 15 (two-panel: log-scale V_acc + Q_peak with stream overlay) and a new --event-duration-h CLI flag (default 6.0).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR 1 of 2 for the routing milestone. Closes the hydrologic half of routing — turns SCS-CN per-cell runoff (mm) into accumulated upstream volume (m³) and peak discharge (m³/s) along the flow direction grid. The follow-up PR adds Manning normal-depth at stream cells to close the hydraulic half (discharge → water level → HAND-driven inundation).
Module surface
Why steady-state, why two PRs
Resolution alignment
`accumulate_runoff` reprojects the runoff raster (WorldCover 10 m grid) onto the DEM 30 m grid using `Resampling.average` — the area-weighted mean is the correct aggregation for a depth quantity. Each coarse cell's volume is then `mean_depth × cell_area`, where cell area handles WGS84 longitude convergence.
Test plan
Notes