WhereTheWaterFlows.jl
WhereTheWaterFlows routes water on gridded topography (or hydraulic potential) with a D8 algorithm combined with a breach algorithm for depression filling. It supports deterministic flow routing, DEM filling, catchment analysis, coupled feedbacks, subglacial routing physics, and uncertainty propagation.
The package currently has three modules:
WhereTheWaterFlows: core deterministic routing and post-processing (WWF)WhereTheWaterFlows.Subglacially: subglacial hydraulic-potential routing (WWFS)WhereTheWaterFlows.Randomly: Monte Carlo wrappers for uncertainty studies (WWFR)
Installation
using Pkg
Pkg.add("WhereTheWaterFlows")Plotting functions are provided through a Makie extension. Load any Makie backend alongside the package to enable them:
using WhereTheWaterFlows, GLMakie # or CairoMakie, WGLMakie, …Submodules are bundled in the same package and are typically used like so:
using WhereTheWaterFlows
const WWF = WhereTheWaterFlows
const WWFS = WhereTheWaterFlows.Subglacially
const WWFR = WhereTheWaterFlows.RandomlyQuick start
using WhereTheWaterFlows
# build a small synthetic DEM
x = y = range(-π, π, length=200)
dem = sin.(x) .* cos.(y')
out = waterflows(dem)
maximum(out.area), length(out.sinks)See the Tutorial for a full walkthrough of the core API.
Algorithm
The core routing uses the D8 algorithm: each cell drains to whichever of its eight neighbours has the steepest downward gradient. Local minima (pits) are handled by default via a breach-type algorithm that finds the lowest spillway for each pit and reverses flow along that path, so the input DEM does not need to be pre-filled (or pre-processed in any other way). Both algorithms are described by O’Callaghan & Mark (1984).
The flow is accumulated by recursively traversing the drainage tree, the algorithm has O(n) complexity where n is the number of cells (Braun & Willett, 2013). On large DEMs the recursion depth can exceed the default Julia call-stack size and cause a StackOverflowError.