r.hydro.rri - Native GRASS driver for the RRI distributed rainfall-runoff-inundation model (static input + index setting only in this increment -- see NATIVE_GRASS_PLAN.md).
Actually run the adaptive RK45 time loop (requires lasth= and rain= or rain_strds=). Increment 4 (NATIVE_GRASS_PLAN.md 'Progress'): prints per-outer-timestep mass-balance diagnostics to stderr for cross-checking against RRI.opencl's ASCII-path storage.dat on the same domain -- does NOT yet write GRASS output (DB table / STRDS), that is the next increment.
--overwrite
Allow output files to overwrite existing files
--help
Print usage summary
--verbose
Verbose module output
--quiet
Quiet module output
--ui
Force launching GUI dialog
Parameters:
elevation=name[required]
Name of input elevation raster map
drainage=name
D8 flow direction, r.watershed/r.watershed.opencl 'drainage' convention (counter-clockwise from north-east=1, negative at domain edges). Omit to auto-derive via r.watershed.opencl (watershed_threshold= controls its threshold=; see that option's description) -- pass this explicitly instead when you already have one (e.g. from a prior r.watershed.opencl run reused across experiments, mirroring r.hydro.hbv.basins' drainage_input=-style passthrough pattern) to skip recomputing it, which can be the difference between minutes and over an hour on a basin-scale DEM.
accumulation=name
Flow accumulation (cell count), r.watershed/r.watershed.opencl convention. Magnitude only is used (sign, where present, is r.watershed's own per-cell reliability flag, not part of RRI's model -- see drainage_to_rri_dir's neighboring comment for the equivalent caveat on 'drainage'). Omit to auto-derive via r.watershed.opencl alongside drainage= -- see that option's description.
watershed_threshold=integer
r.watershed.opencl's own threshold= (minimum exterior basin size, cells), used only when auto-deriving drainage=/accumulation= (i.e. when at least one of them is omitted). This module never reads r.watershed.opencl's stream=/basin= outputs, so the default of 1 (finest-grained, no effect on drainage/accumulation themselves) is safe -- raise it only if you separately care about r.watershed.opencl's basin delineation on the SAME run for some other purpose.
Default: 1
riv_thresh=float
Minimum flow accumulation (cell count) for a cell to be treated as a river channel
Default: 100
width_param_c=float
River width power-law coefficient c: width = c * (drainage area km^2)^s
Default: 5.0
width_param_s=float
River width power-law exponent s
Default: 0.35
depth_param_c=float
River depth power-law coefficient c
Default: 0.95
depth_param_s=float
River depth power-law exponent s
Default: 0.2
height_param=float
Levee height above bank [m] for river cells above height_limit
Default: 0.0
height_limit_param=float
Minimum accumulation for height_param to apply
Default: 20
ns_river=float
River Manning's roughness coefficient
Default: 0.03
ns_slope=float[,float,...]
Hillslope Manning's roughness coefficient, one per landuse= class (or one value for all)
Default: 0.4
soildepth=float[,float,...]
Soil depth [m], one per landuse= class (or one value for all)
Default: 1.0
gammaa=float[,float,...]
Soil porosity [-], one per landuse= class (or one value for all)
Default: 0.475
ksv=float[,float,...]
Green-Ampt vertical saturated hydraulic conductivity [m/s] (0 disables), one per landuse= class (or one value for all)
Default: 0.0
faif=float[,float,...]
Green-Ampt wetting front suction head [m], one per landuse= class (or one value for all)
Default: 0.316
ka=float[,float,...]
Lateral subsurface (Darcy) conductivity [m/s] (0 disables; mutually exclusive with ksv), one per landuse= class (or one value for all)
Default: 0.0
gammam=float[,float,...]
Matrix-flow porosity [-], one per landuse= class (or one value for all)
Default: 0.0
beta=float[,float,...]
Hillslope subsurface flow power-law exponent, one per landuse= class (or one value for all)
Default: 8.0
landuse=name
Classified land-use/land-cover raster. The raster's CELL VALUES (integer categories, read via Rast_get_c_row) are what matters -- category LABEL text (r.category/r.support) is metadata the physics never reads. Categories must be 1..num_of_landuse (this module takes num_of_landuse = the raster's own max category value), each representing a distinct combination of ns_slope=/soildepth=/gammaa=/etc (a hydraulic-parameter class, not a semantic land-cover label GRASS has any opinion about). Omit for a single uniform class over the whole domain. See README for a worked r.reclass example building a 1..N raster from a real classified source (MODIS MCD12Q1, ESA WorldCover, ...). Time-varying land use (a landuse_strds= option) is not implemented -- see NATIVE_GRASS_PLAN.md.
Precipitation intensity, a SINGLE static raster applied as constant forcing for the whole run. Units per rain_units= (default mm_per_day, converted internally -- see rain_units' own description for why that default, not mm_per_hour, is the safe one).
rain_strds=name
Precipitation space-time raster dataset, e.g. t.in.era5's <prefix>_precipitation. Units per rain_units=. Resolves and iterates the series (see resolve_strds_steps), feeding the RK45 time loop with -r. Mutually exclusive with rain= in practice (rain_strds= takes priority if both given).
rain_units=string
Units of rain=/rain_strds='s raster cell values. Default mm_per_day matches t.in.era5's ONE AND ONLY output convention for precipitation/potential_evaporation (confirmed against t.in.era5.py directly: both are registered as daily sums in mm, 'Total precipitation, daily sum (mm/d)' -- t.in.era5 has no hourly-output mode, so a STRDS from it is always mm/day, never a maybe). mm_per_day is divided by 24 to a uniform hourly rate before reaching the physics kernels -- this is a real simplification (a daily total cannot recover sub-daily rainfall intensity variation, only its correct daily mean rate), not a unit-only conversion; document this when citing results from era5-driven runs. Defaulting to mm_per_hour instead would have been the wrong default for this module's primary intended forcing source and risks a silent 24x error for anyone who feeds t.in.era5 output through without noticing -- exactly the mixup this module's own test suite hit once already (see NATIVE_GRASS_PLAN.md).
Options: mm_per_day, mm_per_hour
Default: mm_per_day
lasth=float
Simulation length [hours]. Required together with -r to actually run the RK45 time loop -- without it, rain=/rain_strds= only run their own isolated read/index diagnostic (increments 2/3), same as if -r were omitted.
dt=float
Outer (slope) timestep [s]
Default: 600
dt_riv=float
Initial river RK45 sub-timestep [s]
Default: 60
hs_output=name
With -r: name for an output space-time raster dataset (STRDS) of hillslope water depth [m], one map per hs_interval outer timesteps. Omit to skip periodic state output entirely.
hs_interval=integer
Write an hs_output= snapshot every N outer timesteps (1 = every timestep)
Default: 1
hydrograph_table=string
With -r: name for an output DB table (time_s, discharge_cms) of discharge summed over the domain's outlet river cell(s). Omit to skip.
r.hydro.rri prepares model inputs for RRI (Rainfall-Runoff-Inundation),
a fully-distributed rainfall-runoff/flood-inundation model, from GRASS
rasters and space-time raster datasets (STRDS), and optionally runs the
model and imports its outlet hydrograph back into GRASS.
RRI itself is not a GRASS module -- it is a separate C engine
(RRI.opencl, at $HOME/dev/RRI.opencl, built from
RRI_1.4.2.7_Linux) with its own text-file/ESRI-ASCII-grid input
format (RRI_Input.txt/topo/*.txt/rain/rain.dat).
r.hydro.rri is a GIS data-preparation bridge: it exports
elevation, derives flow direction/accumulation (via
r.watershed) when not supplied, and converts a precipitation
(and optionally potential evapotranspiration) STRDS -- for
example, t.in.era5's <prefix>_precipitation --
into RRI's own per-timestep grid format. With the -r flag it also
invokes the compiled rri_cpu binary and imports the resulting
outlet hydrograph into a GRASS DB table.
rain_strds is expected to come from a reanalysis or
satellite-derived precipitation product already imported as a GRASS
STRDS -- t.in.era5's precipitation variable is the
primary target (its daily mm/d output matches rain_units=mm_per_day,
the default). Any other STRDS with the same interval-registered (start,
end) structure works too, including one built from
r.in.sentinel/r.in.modis/r.in.landsat derived
products or registered manually with t.register.
pet_strds follows the same pattern for potential
evapotranspiration, e.g. t.in.era5's potential_evaporation
output, or a series of i.evapo.pm/i.evapo.pt/
i.evapo.mh outputs registered into a STRDS.
Every map in a forcing STRDS must be registered as an interval (an
explicit start AND end time), not an instantaneous point -- RRI's
rain/PET file format is a step function of elapsed time and needs both.
A STRDS built by t.in.era5 already satisfies this.
Single land-use class only (num_of_landuse=1) -- the
landuse option, if given, is exported for RRI's own internal use,
but this module's ns_slope=/soildepth=/etc. options
apply the same scalar value to the whole domain rather than one
value per class. See "Known gaps" below.
River channel geometry (width/depth/height) is not exported; RRI's
own internal power-law estimate from flow accumulation is used instead
(rivfile_switch=0 in the generated RRI_Input.txt).
The model's own D8 flow-direction convention differs from
r.watershed's drainage output -- see NOTES.
r.watershed's drainage output numbers 8 directions
counter-clockwise from 1=north-east (r.watershed.md); RRI's own
dir grid instead uses an 8-bit D8 bitmask (east=1, doubling
clockwise: E=1, SE=2, S=4, SW=8, W=16, NW=32, N=64, NE=128 -- documented
in prose only in RRI_Break.f90's comment block).
r.hydro.rri reclasses one into the other. This mapping has been
smoke-tested (see tests/) but not cross-validated against a real
watershed with known flow paths -- treat it as a reasonable, documented
judgment call, not a verified-against-ground-truth conversion.
A cell whose flow leaves the computational region gets a negativedrainage value from r.watershed; such cells become RRI
outlet cells (dir=0). r.watershed's accumulation
output separately uses a negative sign to flag a per-cell reliability
caveat (not a direction) -- this module always exports
abs(accumulation), since RRI only ever compares accumulation's
magnitude against riv_thresh.
r.hydro.rri auto-places a single hydrograph station, named
outlet, at the accumulation raster's maximum-magnitude cell.
This is a reasonable default for a single-outlet watershed but is wrong
for a domain with more than one drainage outlet (e.g. a delta) -- not
handled by this module.
RRI's rain.dat/PET file is a sequence of timestep blocks: a
header line t nx ny (t = elapsed seconds since the
forcing series' own first map's start) followed by ny rows of
nx whitespace-separated values in mm/h, preceded by a
t=0 all-zero block (used only as the lower bound of RRI's own
internal time-interpolation search, never applied itself). Values are
converted from rain_units=/pet_units= to mm/h before
writing. The forcing grid's own georeference is written into
RRI_Input.txt's xllcorner_rain/etc. fields -- it does
not need to align with elevation's grid; RRI does its own
nearest-cell lookup at runtime.
Single land-use class only; multi-class per-cell parameterization is
not implemented.
River width/depth/height override rasters, dam operation, flow
diversion, and boundary-condition files (all separate RRI features) are
not exposed by this module.
final_storage (importing RRI's periodic per-cell output grids
back as a GRASS raster) is not yet implemented -- RRI's
out/hs_*/out/hr_* files are per-cell-index dumps in the
model's own compressed indexing, not directly re-importable as a full
grid; wiring this up needs a small reprojection step not built in this
pass.
Only the first hydrograph station's discharge column is imported
into the output DB table, even if location.txt ever listed more
than one (it currently never does -- see "Outlet/hydrograph station"
above).
RRI model: T. Sayama et al., "Rainfall-Runoff-Inundation (RRI) Model"
(https://github.com/YannChemin/RRI_1.4.2.7_Linux).
The C/OpenMP/OpenCL engine this module drives: $HOME/dev/RRI.opencl
(this user's own port, see its README for physics/validation details).