GRASS logo

NAME

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).

KEYWORDS

raster, hydrology, temporal, RRI

SYNOPSIS

r.hydro.rri
r.hydro.rri --help
r.hydro.rri [-er] elevation=name [drainage=name] [accumulation=name] [watershed_threshold=integer] [riv_thresh=float] [width_param_c=float] [width_param_s=float] [depth_param_c=float] [depth_param_s=float] [height_param=float] [height_limit_param=float] [ns_river=float] [ns_slope=float[,float,...]] [soildepth=float[,float,...]] [gammaa=float[,float,...]] [ksv=float[,float,...]] [faif=float[,float,...]] [ka=float[,float,...]] [gammam=float[,float,...]] [beta=float[,float,...]] [landuse=name] [utm=integer] [rain=name] [rain_strds=name] [rain_units=string] [lasth=float] [dt=float] [dt_riv=float] [hs_output=name] [hs_interval=integer] [hydrograph_table=string] [--overwrite] [--help] [--verbose] [--quiet] [--ui]

Flags:

-e
8-direction hillslope routing (default: 4-direction)
-r
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.
utm=integer
0 = lat/lon (geodesic dx/dy via Hubeny's formula), 1 = projected/UTM
Options: 0, 1
Default: 0
rain=name
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.

Table of contents

DESCRIPTION

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.

Satellite/reanalysis forcing

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.

RRI-side simplifications

NOTES

Flow direction convention

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 negative drainage 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.

Outlet/hydrograph station

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.

Rain/PET file format

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.

KNOWN GAPS

EXAMPLES

Prepare RRI inputs from a DEM and an ERA5 precipitation STRDS, without running the model:
t.in.era5 variables=precipitation start=2026-01-01 end=2026-01-10 \
  output_prefix=era5
r.hydro.rri elevation=dem rain_strds=era5_precipitation \
  project_dir=/data/rri_project lasth=240
Also run the model (OpenMP/CPU backend) and import the outlet hydrograph:
r.hydro.rri elevation=dem rain_strds=era5_precipitation \
  project_dir=/data/rri_project lasth=240 -r
With PET forcing and the GPU/OpenCL backend:
t.in.era5 variables=precipitation,potential_evaporation \
  start=2026-01-01 end=2026-01-10 output_prefix=era5
r.hydro.rri elevation=dem rain_strds=era5_precipitation \
  pet_strds=era5_potential_evaporation \
  project_dir=/data/rri_project lasth=240 -r -g

SEE ALSO

i.evapo.mh, i.evapo.pm, i.evapo.pt, r.hydro.hbv, r.hydro.hbv.basins, r.hydro.hbv.forcing, r.in.landsat, r.in.modis, r.in.sentinel, r.watershed, t.in.era5, t.rast.list

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).

AUTHORS

Yann Chemin

SOURCE CODE

Available at: r.hydro.rri source code (history)

Accessed: Sunday Sep 13 08:29:02 2026


Main index | Raster index | Topics index | Keywords index | Graphical index | Full index

© 2003-2026 GRASS Development Team, GRASS 8.5.1dev Reference Manual