Add Manning normal-depth + rainfall-driven HAND flood (2/2)#16
Merged
Conversation
Second of two routing PRs. Closes the hydraulic side of the rainfall-> flood pipeline by computing per-stream-cell water levels via Manning's normal-depth equation, then broadcasting those water levels upstream along the flow direction grid to drive HAND-based inundation. Combined with PR1's runoff accumulation + peak discharge, the project now turns synthetic uniform rainfall (or any future PrecipGrid) into a full rainfall-driven flood depth raster with no remaining gaps. Module additions (floodpath/routing/): - utils.py: pixel_sizes_m() factored out of cell_areas_m2 for reuse; slope_along_flow(flow_grid, dem) computes per-cell slope (m/m) along the downstream D8 direction with a min_slope floor for numerical safety in Manning's sqrt(S). - manning.py: leopold_maddock_width(Q, a=2.5, b=0.5) for global natural-channel width-discharge relation; manning_normal_depth(Q, w, S, n) returns the closed-form wide-channel solution h = ((Q*n)/(w*sqrt(S)))^(3/5); compute_water_level() is the high-level convenience producing a WaterLevelGrid with h at stream cells and NaN elsewhere. - flood.py: compute_rainfall_inundation(water_level, hand, flow_grid, streams) uses pyflwdir.basins(idxs=stream_indices) to label every cell with its drainage stream index, then applies depth = max(W - HAND, 0) to every cell. Out-of-basin cells (square-cropped bbox ridges that flow off the edge) stay dry. New dataclasses: WaterLevelGrid (h at stream cells, m) and RainfallInundationDepth (per-cell flood depth driven by per-stream water levels) — the latter has flooded_fraction(), stats(), and the full provenance chain (precip_source, duration_s, method). Tests: 29 new — pixel_sizes_m at equator vs 60 deg N, slope_along_flow on flat / inclined / Robit Bata DEMs, Leopold-Maddock at canonical Q, Manning at hand-computed (Q=10,w=10,S=0.001,n=0.04) -> h=1.150 m, plus end-to-end pinned values on the Robit Bata fixtures (outlet h ~ 10.07 m, flooded fraction ~ 9.5% under 100 mm/6 hr storm). Shape-mismatch errors checked. Smoke test gains stage 16 (rainfall-driven flood map): hillshade + log-scale flood depth + stream overlay. The pipeline is now end-to-end physical: rain -> CN -> SCS -> accumulation -> discharge -> Manning -> water level -> HAND -> flood.
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 2 of 2 for the routing milestone. Closes the hydraulic half — turns the per-cell peak discharge from PR1 into per-stream-cell water levels via Manning's wide-channel normal-depth equation, then broadcasts those upstream along the flow direction grid to drive HAND-based inundation. Combined with PR1, the project now produces a true rainfall-driven flood depth raster from synthetic uniform rainfall (or any future `PrecipGrid`).
Pipeline closed
```
rainfall (uniform or any source)
↓ SCS-CN equation
runoff Q (mm)
↓ accumulate_runoff (PR1)
V_acc (m³)
↓ peak_discharge (PR1)
Q_peak (m³/s)
↓ compute_water_level — NEW
h at stream cells (m)
↓ compute_rainfall_inundation — NEW
flood depth (m) per cell
```
Module surface
Test plan
Notes