Time Variables
Time Options
Routing simulations have four different time steps, all given in seconds.
dt_runoff: Interval between runoff inputs. It is not a config: it is read from the time steps of each forcing file. Every river hands its discharge to the river downstream at the end of each runoff step, and records it there.dt_routing:'auto', the default, or the step in seconds every river computes in,dtin the Muskingum equation, a divisor ofdt_runoff. With'auto'each river computes in its own valid step, the fewest steps of each runoff step that keep its coefficients valid, whichuse_subcyclesgives it, anduse_subreachessplits the rivers too long for the runoff step into sub-reaches.'auto'requires both.dt_discharge: Channel routing only. Interval between the discharges written to disk, and, with no runoff, the step at which every river hands its discharge downstream. It defaults todt_routingwhen that is given in seconds.dt_total: Channel routing only. Total simulation duration, an integer multiple ofdt_discharge.
Routing with forcing routes every step of each forcing file and writes the discharge at the end of each, labeled with
the time the step begins, so dt_discharge and dt_total are refused with any forcing but channel.
How Each River Computes
Rivers are routed one at a time, upstream to downstream, each river's whole series before the next, so every river
computes in a plan of its own. Each runoff step of a river is taken in subcycles, steps of its own, with its upstream
inflow interpolated linearly across them and its runoff spread evenly over them. Each river's plan is settled in two
jobs: dt_routing sets its step, and use_subreaches and use_subcycles make every coefficient non-negative at it.
- With
dt_routing: auto, the default, each river's step is its own: the runoff step over the fewest subcycles that keep its coefficients non-negative, whichuse_subcyclesgives it.use_subreachesthen splits a river too long for the runoff step into the fewest sub-reaches in series that keep its coefficients non-negative.'auto'requires both, so that every river it routes is valid where it can be. - With
dt_routinggiven in seconds, every river's step is exactlydt_routing,dt_runoff / dt_routingsubcycles of each runoff step. Withuse_subreaches, a river too long for it is split into sub-reaches, and withuse_subcycles, a river too short for it takes the fewest subcycles ofdt_routingthat keep its coefficients non-negative. Without them, no river is split or given a shorter step, so a river too long or too short for it keeps a negative coefficient and is reported, asinvalid_coefficientssays. Settingdt_routingtodt_runoffwith both routes as'auto'does, and without them routes each river whole in one step of each runoff step.
With both, a river that neither equal sub-reaches nor subcycles make valid alone, which only a river with x above 1/3 can be, is split into sub-reaches of unequal travel times that each take subcycles of their own; see sub-reaches that take subcycles of their own.
The subcycles of each sub-reach are combined into one step of coefficients that give the discharge of taking them one at a time, so they cost one step, and the sub-reaches of a river hand their discharge to each other at the end of each runoff step, as rivers do.
The following rules apply:
dt_routing, when given in seconds, must be less than or equal todt_runoffand an integer divisor of it, because runoff is never resampled.- Every step of each forcing file is routed, and the discharge at the end of each is written. Recession routing is not available.
- Every step of a forcing file must be as long as its first, which is its
dt_runoff. Runoff is never resampled, so a file with irregular time steps is refused, and so is a file with a single time step, which has no step to read, or with dates that do not increase.
Router Defaults
- Channel-only routing (
forcing: channel): requiresdt_totalanddt_discharge, ordt_routingin seconds. With no runoff, rivers hand their discharge downstream everydt_discharge, which defaults todt_routingwhen it is given in seconds. - Routing with forcing (e.g.
forcing: catchment):dt_runoffis the time step of each forcing file.- Every step of each forcing file is routed and written;
dt_dischargeanddt_totalare refused. dt_routingis'auto', anduse_subreachesanduse_subcyclesareTrue, so each river takes the fewest steps of each runoff step and the sub-reaches that keep it valid.
Required Relationships
For routing with forcing (e.g. forcing: catchment):
dt_runoff >= dt_routing (when given)
dt_runoff % dt_routing == 0 (when given)
For channel-only routing (forcing: channel):
dt_total >= dt_discharge >= dt_routing (when given)
dt_total % dt_discharge == 0
dt_discharge % dt_routing == 0 (when given)
Practical Notes
- Leave
dt_routingat'auto'unless every river must take the same step. A step in seconds keeps every river valid only withuse_subreaches, which splits the rivers too long for it, anduse_subcycles, which subcycles the rivers too short for it. A step shorter than a river's travel time does not route it more accurately: it does not change how much the river delays or spreads a flood wave, and it puts more rivers below the lower bound2*k*x. - If you need a different runoff timestep, resample runoff before routing.
- To route longer than your runoff record, pad runoff with zeros upstream of routing.
- To route part of a forcing file, trim the file before routing. To write fewer time steps, save only the ones you need with a custom writer.
Left- vs right-aligned timestamps
Runoff timestamps can be given as interval starts (left-aligned) or interval ends (right-aligned).
Example: an hourly value labeled 17:00 may represent either the hour 17:00-18:00 or 16:00-17:00.
Keep this convention consistent to avoid off-by-one timing errors.