1D and 2D Flow Routing on a Terrain
Abstract.
An important problem in terrain analysis is modeling how water flows across a terrain creating floods by forming channels and filling depressions. In this paper we study a number of flow-query related problems: Given a terrain , represented as a triangulated -monotone surface with vertices, a rain distribution which may vary over time, determine how much water is flowing over a given edge as a function of time. We develop internal-memory as well as I/O-efficient algorithms for flow queries.
This paper contains four main results:
(i) We present an internal-memory algorithm that preprocesses into a linear-size data structure in time that for a (possibly time varying) rain distribution can return the flow-rate functions of all edges of in time, where is the number of sinks in , is the number of times the rain distribution changes, and is the total complexity of the flow-rate functions that have non-zero values; in the worst case, where is the height of the merge tree of and is the number of times the rain distribution changes, but is much smaller in practice.
(ii) We also present an I/O-efficient algorithm for preprocessing into a linear-size data structure using I/Os and internal computation time, so that for a rain distribution , it can compute the flow-rate function of all edges using I/Os and internal computation time.
(iii) can be preprocessed in time, into a linear-size data structure so that for a given rain distribution , the flow-rate function of an edge under the single-flow direction (SFD) model can be computed in time, where is the number of vertices in on which nonzero rain falls, and is the number of tributaries of in which rain directly falls in.
(iv) We present an algorithm for computing the two-dimensional channel along which water flows using Manning’s equation; a widely used empirical equation that relates the flow-rate of water in an open channel to the geometry of the channel along with the height of water in the channel. Given the flow-rates along a path of edges, the algorithm computes the height of water and boundary along the channel in time, where is the number of wetted faces at least partially covered by water in the channel.
1. Introduction
An important problem in terrain analysis is modeling how water flows across a terrain and creates floods by forming channels and filling up depressions. The rate at which a depression fills up during a rainfall depends not only on the shape of the depression and the size of its watershed (i.e., the area of the terrain that contributes water to the depression) but also on other depressions that are filling up. Water falling on the watershed of a filled depression flows to a neighboring depression effectively making the watershed of the latter larger and filling it up faster. Modeling how depressions fill and how water spills into other depressions during a flash flood event is therefore an important computational problem.
Besides determining which areas of a terrain become flooded and when they become flooded, determining the 2D channels (rivers) along which water flows across the terrain is also important. The flow queries we ask can also be used to solve related flood-risk queries, and the algorithms developed will provide a simpler and faster algorithm for a previously studied flood-risk queries. We assume we are given a terrain , represented as a triangulated -monotone surface with vertices. As in earlier papers, (Rav et al., 2017; Lowe and Agarwal, 2019; Arge et al., 2010) we assume that water flows along the edges of . Two models of water flow along edges have been proposed: (i) a simple and more widely used model called the single flow-direction (SFD) model in which water from a vertex flows along one of its downward edges, and (ii) a more accurate but more complex model called the multi-flow-direction (MFD) model in which water at a vertex splits and flows along all of its downward edges. There is also some earlier work by Liu and Snoeyink (Liu and Snoeyink, 2005) which allows water to flow in the interior of edges. We consider both of these models.
We study the following three problems in this paper:
-
•
Terrain-flow query: given a rain distribution (possibly varying with time), compute as a function of time the flow rate (of water) for all edges of .
-
•
Edge-flow query: given a rain distribution and a query edge of , compute the flow rate of under the single flow-direction (SFD) model.
-
•
2D flow network: Given a 1D flow network, represented as a set of edges along with their flow values, compute 2D channels along which water flows.
Finally, as high-resolution terrain data sets are becoming easily available, their size easily exceeds the size of main memory of a standard computer, so movement of data between main memory and external memory (such as disk) becomes the bottleneck in computations.
We use the I/O-model with one disk by Aggarwal and Vitter (Aggarwal and Vitter, 1988), in which, the computer is equipped with a two-level memory hierarchy consisting of an internal memory, which is capable of holding data items, and an external memory of unlimited size. All computation happens on data in internal memory. Data is transferred between internal and external memory in blocks of consecutive data items. Such a transfer is referred to as an I/O-operation or an I/O. The cost of an algorithm is the number of I/Os it performs. The number of I/Os required to read items from disk is . The number of I/Os required to sort items is (Aggarwal and Vitter, 1988). For all realistic values of , , and we have .
Related work. Due to its importance, the problem of modeling how water flows on a terrain has been studied extensively, and many approaches have been taken to address this problem. One approach focuses on accurately simulating fluid dynamics using non-linear partial differential equations such as the Navier-Stokes equations. These equations have no closed form solutions and are usually solved using numerical methods. They often account for additional factors, such as the effects of different terrain types and drainage networks. While these models tend to be more accurate, they are computationally expensive and do not scale to large terrains. Bates and De Roo (Bates and De Roo, 2000) developed one such model for simulating flooding on digital elevation models (DEMs) using two flow models for different regions of the terrain: the first handles flow within rivers and the second models flow of water as it spreads over floodplains. While there has been some research into refining the representation of channels, such as Wood et al. (Wood et al., 2016), often the channel geometry is assumed to be a simple model (e.g. rectangular or trapezoidal.)
Water-flow modeling on a terrain also has been studied in the GIS community. These approaches use simpler models, which are computationally efficient and suitable for large datasets. Although some early work, e.g. (Liu and Snoeyink, 2005) allowed water to flow in the interior of faces, recent work assumes that water flows along the edges of the terrain and the SFD and MFD models described above are used to model the water flow locally at a vertex, see e.g. (Rav et al., 2017; Lowe and Agarwal, 2019; Arge et al., 2010) Arge et al. (Arge et al., 2000) described an I/O-efficient algorithm for the flow-accumulation problem in the SFD model, water falls uniformly on the terrain which asks how much water flows over each point in a terrain assuming the terrain has only one sink at infinity. Their algorithm performs a total of I/Os, where is the number of I/Os required to sort items. The flow accumulation model only provides rough solution to flow modeling, since it assumes that either the terrain does not have any local minima or that they have been filled in advance.
In order to accurately model flow it is necessary to compute times at which depressions fill and simulate how water spills from one depression into others. Arge et al. (Arge et al., 2010) proposed the first I/O-efficient algorithm that computes the fill times of all maximal depressions in I/Os, where is the number of depressions in the terrain and is the size of the internal memory. If , the algorithm can be simplified and requires only I/Os.
Arge et al. (Arge et al., 2017) described an I/O-efficient algorithm that computes which points on the terrain become flooded if a total volume of rain falls according to a distribution . It performs I/Os, where is the height of the merge tree of the terrain. In the worst case , but it can be bounded to under certain practical assumptions.
Lowe et al. (Lowe and Agarwal, 2019) presented efficient algorithms for several flood queries on a terrain under the multiflow direction (MFD) model. They presented a -time algorithm to answer terrain flood queries. They also showed that a terrain can be preprocessed in -time into a data structure that can answer point-flood queries: Given a rain distribution , a volume of rain , and a point , determine whether will be flooded. The query time is time, where is the number of maximal depressions that contain the query point ; in the worst case, but in practice it is much smaller. Finally, they presented a -time algorithm to determine when a query point gets flooded, where is the exponent of fast matrix multiplication. To our knowledge, no I/O-efficient algorithms are known for these flooding queries under the MFD model.
Our results. There are four main results in the paper.
(i) We present a time algorithm for preprocessing into a linear-size data structure for answering terrain-flow queries: for a rain distribution , it can compute the flow rate of all edges in time, where is total complexity of nonzero flow-rate functions, is the number of sinks in , and is the number of times the rain distribution changes. In the worst case , where , as above, is the height of the merge tree of , but is much smaller in practice. An immediate corollary of our result is that a flood-time query (i.e. given and a point , when will be flooded) can be answered in the same time, which is a significant improvement over the result in (Lowe and Agarwal, 2019).
(ii) We present two I/O-efficient algorithms for the terrain flow algorithm. We first preprocess the terrain using I/Os and internal computation time. The first algorithm that , where , and are as above, and considers a terrain-flow query in I/Os and internal computation time. The second algorithm assumes and answers a terrain-flow query in I/Os and internal computation time. We additionally note that since the terrain-flow query is a more general problem, these algorithms also yield I/O-efficient algorithms for the terrain-flood and flood-time queries under the MFD model studied in (Lowe and Agarwal, 2019).
(iii) The terrain-flow query algorithm naturally can also be used to perform edge-flow queries. Under SFD flow, we can build a linear sized data structure in time which given an edge and rain distribution computes in time, where is the complexity of the rain distribution, is the number of tributaries of in which rain is falling, and is the number of times the rain distribution changes.
(iv) We present an algorithm that given a 1D flow network, represented as a path of edges along with their flow values, identifies the depth and width of water along the 2D flow network in time, where is the number of “wetted” faces at least partially covered by the water in the channel. We do so by utilizing Manning’s equation (Manning et al., 1890), a widely used empirical formula relating flow-rate of water in an open channel to the geometry of the channel. The algorithm utilizes the key idea that while the profile of the channel changes continuously as we sweep along the 1D flow network, the combinatorial structure only changes at discrete events. By tracking when these events occur, the algorithm efficiently computes the depth of the river along the flow network. We note that previous work computing the 2D channel assumes the cross section of each channel has a simple geometry (e.g. rectangular or trapezoidal) (Bates and De Roo, 2000). In contrast, we do not make any such assumption.
We note that our terrain-flow query algorithm builds on some ideas in (Lowe and Agarwal, 2019) namely, it also performed a sweep in the -direction. However, our new algorithm is more general, simpler, faster, and several new ideas are needed. First note that the terrain-flood and flood-query problems studied in (Lowe and Agarwal, 2019) are special cases of the terrain-flow query problem. In the process of computing the flow rate of all edges, it computes the flood-time of all depressions of . In contrast, the algorithms in (Lowe and Agarwal, 2019) either compute which depression got flooded or the flood time of only one depression. Furthermore, computation of the latter required a complicated algorithm that relied on matrix multiplication and ran in time in the worst case, while our algorithm takes time in the worst case. Additionally, our algorithm can handle rain distributions that vary over time, and our algorithm is output-sensitive. Finally, we also present an I/O-efficient algorithm for answering terrain-flow queries.
2. Preliminaries & Models
In this section we give a number of preliminary definitions and describe the flooding model, most of the text here follows closely (Rav et al., 2017; Lowe and Agarwal, 2019).
2.1. Geometric Preliminaries
Terrains. Let be a triangulation of , and let be the set of vertices of ; set . We assume that contains a vertex at infinity, and that each edge is a ray emanating from ; the triangles in incident to are unbounded. Let be a height function. We assume that the restriction of to each triangle of is a linear map, that approaches at , and that the heights of all vertices are distinct. Given and , the graph of , called a terrain and denoted by , is an -monotone triangulated surface whose triangulation is induced by .
Critical vertices. There is a natural cyclic order on the neighbor vertices of a vertex of , and each such vertex is either an upslope or downslope neighbor. If has no downslope (resp. upslope) neighbor, then is a minimum (resp. maximum). We also refer to a minimum as a sink. If has four neighbors , , , in clockwise order such that then is a saddle vertex.
Level sets, contours, depressions. Given , the -sublevel set of is the set , and the -level set of is the set . Each connected component of is called a depression, and each connected component of is called a contour. Note that a depression is not necessarily simply connected, as a maximum can cause a hole to appear;
For a point , a depression of is said to be delimited by the point if lies on the boundary of , which implies that . A depression is maximal if every depression contains strictly more sinks than . A maximal depression that contains exactly one sink is called an elementary depression. Note that each maximal depression is delimited by a saddle, and a saddle that delimits more than one maximal depression is called a negative saddle. For a maximal depression , let denote the saddle delimiting , and let denote the set of sinks in . The volume of a depression of is
(1) |

Merge tree. The maximal depressions of a terrain form a hierarchy that is easily represented using a rooted tree, called the merge tree (Kreveld et al., 1997; Carr et al., 2003) and denoted by . Suppose we sweep a horizontal plane from to . As we vary , the depressions in vary continuously, but their structure changes only at sinks and negative saddles. If we increase , then a new depression appears at a sink, and two depressions merge at a negative saddle. The merge tree is a tree that tracks these changes. Its leaves are the sinks of the terrain, and its internal nodes are the negative saddles. The edges of , the merge tree, are in one-to-one correspondence with the maximal depressions of , that is, we associate each edge with the maximal depression delimited by and containing . See Figure 1 for an example. We assume that has an edge from the root of extending to , corresponding to the depression that extends to . For simplicity, we assume that is binary, that is, each negative saddle delimits exactly two depressions. Non-simple saddles can be unfolded into a number of simple saddles (Edelsbrunner et al., 2001).
can be computed in time (Carr et al., 2003), and it can be preprocessed in additional time so that for a point , , the volume of the depression delimited by can be computed in time (Carr et al., 2003). In the I/O model, can be constructed using I/Os and as shown in (Arge and Revsbæk, 2009), the volume and the smallest maximal depression containing can be computed for all vertices using I/Os.
2.2. Flooding Model
We now describe the flooding model, which is the same as in (Lowe and Agarwal, 2019), and define flow-rate functions.
Flow graph and flow functions. We transform into a directed acyclic graph , referred to as the flow graph, by directing each edge of from to if , and from to otherwise, i.e., each edge is directed in the downward direction. For each (directed) edge , we define the local flow to be the portion of water arriving at that flows along the edge to at time . By definition for any ,
The value of is, in general, based on relative heights of the downslope neighbors of . If is not a negative saddle vertex, then remains the same for all , so we will often drop and write to denote . If is a negative saddle, then changes when one of its depressions fills up as no water flows for to that saddle; see below for further discussion.
Rain distribution. Let denote a rain distribution, that is, for each vertex , indicates the rate at which the rain is falling on at time . We assume that for a each , is piecewise-constant function of time, with the function changing at discrete time values , and for all and , . For a depression , we define . For , let denote the number of vertices for which , and let . In practice .
Fill and spill rates. For a maximal depression , we define the fill rate as the rate at which water is arriving in the depression as a function of time. That is, the rate at which rain is falling directly in plus the rate at which other depressions are spilling water into . The fill rate is a monotonically nondecreasing piecewise-constant function. Similarly, we define the spill rate as the rate (as a function of time) at which water spills from through the saddle that delimits .
Flow rate. Next we define flow rates and for edges and vertices of , which is the amount of water flowing through and , respectively, at time . For an edge , is the fraction of water from that passes along as a function of time. That is,
(2) |
The flow-rate of a non-saddle vertex is the sum of the flow-rates along incoming edges to plus the rain on the vertex . That is,
(3) |
Letting be the time at which a vertex becomes flooded, and for any are undefined for . That is to say, when a vertex is flooded, the flow-rate function is undefined.
Let be a negative saddle delimiting depressions and . Until one of or is filled, is defined using equation 3. Without loss of generality assume that depression fills first, say at time , and water starts spilling from to through . The spill rate specifies the rate at which water spills from to . It is tempting to simply add to equation 3, but it double counts the amount of water that was flowing from to depression . For , is defined as in (3). For , is defined as follows,
(4) |
Finally for and for any ,
(5) |
3. Terrain-flow Query
In this section we describe an internal-memory algorithm that, given a terrain and rain distribution , computes the flow-rate functions for all edges .
Each function is piecewise constant and represented as a sequence of pairs , where represents the change in the function value at time . We denote to be the combinatorial complexity of , i.e., the number of pieces defining . Set . If the rain distribution changes at times, then , where is the height of the merge tree.
The preprocessing step builds, in time, the merge tree of , and labels each node in according to its in-order traversal as described in (Lowe and Agarwal, 2019). Furthermore, it computes for each vertex and augments each edge with the index of the smallest maximal depression containing .
We first present a simple algorithm and then describe how to adapt it to make it output-sensitive.
3.1. A simple algorithm
We first give an overview of the algorithm. We sweep through the vertices of in descending height order, maintaining the following values for each height :
-
(1)
the set of depressions in the sublevel set ;
-
(2)
for each , maintain the fill rate , and
-
(3)
for each and the set of edges with and , denoted by , maintain the flow-rate function .
Note that depends only on the sinks contained in , so we compute fill-rate functions of only maximal depressions. At each non-saddle vertex we compute and , for each edge , in a straightforward manner using (2) and (3). If is a negative saddle delimiting two depressions and , we must account for any rain spilling from one depression to the other. We do so by first partitioning the edges into two sets, and . Then given the flow-rates on the edges in each set, we compute the fill-rates and . Given these fill-rates, we then determine which depression (if any) fills first. If at least one depression becomes full, assume that fills first without loss of generality. Then we can compute the spill-rate function . Finally, we compute for each edge .
We will now describe the algorithm in detail. We begin by augmenting with additional information which will be used when computing the fill-rates.
Given a rain distribution , before performing the downward sweep, we first compute for each maximal depression as follows: first assign for each vertex with nonzero rainfall to the smallest maximal depression containing , and then perform an upward sweep on the merge-tree , maintaining the sum of rainfall functions at each saddle vertex.
As we sweep top-down, for each depression we store the flow-rates of the edges in in a data structure that supports the following three operations: (i) add to the data structure; (ii) remove from the data structure; (iii) and given a saddle vertex delimiting two depressions , partition the flow-rates into two sets and and return the sum of flow-rates in each set.
Noting there are values of at which the flow-rate functions can change (corresponding to the times at which changes and spill-times of tributaries of the depression in question) we build the data structure as follows. For each time at which the functions can change, maintain the values for the flow-rate of each edge sorted according to the label . Additionally maintain the prefix sum of the values for each . There will be values to consider at each edge, so we can insert and remove flow-rates of edges in -time.
To partition the edges into and , recall each vertex is labeled according to an in-order traversal of . Given two depressions and delimited by a saddle vertex with label , all vertices contained in will have a label less than , and all vertices contained in will have a label greater than . Thus, to partition the edges into the depressions they cross into we simply take the prefix of all edges with label less than to be one set, and the remaining suffix to be the other set. Then given the partition, we can use the prefix sums to determine the sum of flow-rate functions into and in time.
With this data structure at hand, we now describe how to process each vertex as we encounter it in our sweep.
Non-negative-saddle vertex. If is a non-negative-saddle vertex computing is easy using (3). Note that for all incoming edges to has been computed. Additionally, using , for the maximal depression containing , along with , we can determine if or when becomes flooded.
Negative saddles. If is a negative saddle delimiting two depressions and , we first determine whether either of or becomes full and, if so, which fills first. The fill rate of a depression is the sum of the rain falling directly on vertices in plus the flow-rates across all edges crossing into , that is
(6) |
The first sum has already been computed in the upward sweep of the merge tree. However, to compute for all values of we would need to know which depression fills first and when. So instead, we define the pseudo-flow-rate function, , in the same manner that flow-rate for non-saddle vertices is computed as in (3). Using this, we compute a modified pseudo-fill-rate function
(7) |
Before or become full (i.e. ) we have that , which in turn implies that (resp. ) before or becomes full. Given this, compute for all edges from the saddle and add these flow-rates to the data structure. We then use the data structure to partition the edges and compute the pseudo-fill-rates of the two depressions, from which we can determine which (if any) depression fills first.
If neither nor becomes full, we are done. If not, assume without loss of generality that becomes full first and spills into . Then given we compute and in turn compute for using (4) along with using (6).
Computing for all maximal depressions can be done in -time where is the number of sinks in the terrain and is the number of times the rain distribution changes. To compute the flow-rate functions of edges from all non-negative saddle vertices, along with the pseudo-fill-rate functions from negative saddles, we spend -time computing the flow-rate functions and adding them to the data structure. At a negative saddle delimiting two depressions , if we partition the edges by walking from the front and back of the sorted list of edges we spend -time, where is the number of vertices contained in . A simple recurrence shows that the total time spent partitioning edges at all negative saddles is . Finally computing the fill and spill rates at a negative saddle takes time proportional to their complexity, which is . Noting that , we get the following.
Theorem 3.1.
Given a triangulation of with vertices and a height function that is linear on each face of , a data structure of size can be constructed in time so that for a (time varying) rain distribution , a terrain-flow query can be answered in time, where is the number of sinks in , is the number of times at which the rain distribution changes.
In particular, if , we have that the terrain-flow query can be answered in time.
3.2. An Output-Sensitive Algorithm
We modify the above algorithm so that its running time becomes where is the total complexity of all non-zero flow-rate functions. If water flows across a small portion of then and the new algorithm will be faster. The key idea is we do not have to process vertices with zero flow-rate.
The algorithm begins in the same manner as the previous algorithm, computing for each maximal depression .
However rather than sweeping over all vertices of , we instead maintain a priority queue of vertices with nonzero flow-rate with their heights as their priority, i.e., the larger the height, the higher the priority. Every vertex with nonzero flow-rate will either have rain falling directly on it, or have a path in from a source vertex (i.e. either a vertex with rain falling directly on it, or a saddle from which water is spilling.) We initialize the priority queue with all vertices on which rain falls directly along with all negative saddles.
While the priority queue is not empty, we pop the highest priority vertex from the queue and compute the flow-rate function , as we have described in the previous algorithm. For each vertex adjacent to in with , add to the priority queue. For each edge, in addition to each value representing the change in the flow-rate function at time , we also store , the integral of the flow-rate function from to . These are also stored in sorted order, and we maintain the prefix sum of these values for each edge.
At negative saddles, to determine which depression fills first, when we partition the edges we also compute the sum of volumes at the last time step for the depressions and delimited by the saddle vertex. If both have filled by this time, consider the sum at and so on until we find the latest time at which only one depression is filled. This will be the depression which fills first, and ensures the number of time steps considered will be . Then we compute the fill and spill-rates as we did in the prior algorithm.
Since we compute the flow and spill-rates as before, it suffices to prove that we consider each negative saddle with positive spill-rate and each vertex with positive flow-rate. We begin with all negative saddles in the priority queue, so the former holds trivially. For the latter, given a vertex with positive flow-rate, either rain falls directly on it, in which case we added when initializing the priority queue, or water flows to it from some higher vertex . If is added to the priority queue, when it is processed will in turn be added and later processed. Since all non-source vertices with positive flow-rate have a path from source vertex, and all source vertices begin in the priority queue, we have that we will reach and process .
The time spent processing non-saddle vertices and edges will be and respectively. So the total time processing these will be . At negative saddle vertices when we partition the edges, if we perform the search by walking from the front and back of the list we will spend a total of time partitioning edges at all negative saddles. Finally, at each negative saddle which is a source we spend -time computing which depression fills first. Since , the total time processing saddle vertices is .
Theorem 3.2.
Given a triangulation of with vertices and a height function that is linear on each face of , a data structure of size can be constructed in time so that for a (time varying) rain distribution , a terrain-flow query can be answered in time, where is the number of sinks in , is the number of times at which the rain distribution changes, and is the total complexity of all non-zero flow-rate functions.
4. I/O-Efficient Algorithms
In this section we describe two I/O-efficient algorithms that given a terrain and a rain distribution determine the flow-rate for all edges . The algorithms use the same framework as described in Section 3. However, we cannot explicitly maintain the list of edges crossed by the sweep line in memory due to the bounded internal memory size. We instead store the merge tree in memory and rely on the time-forward processing technique, where the flow-rates computed at vertices are forwarded to downslope neighbors using an I/O-efficient priority queue (Chiang et al., 1995). The I/O-efficient priority queue supports insertions and deletions in I/Os and internal computation time (Sanders, 2001).
In the preprocessing step of both algorithms, we compute the merge tree of and label each node in according to its in-order traversal as described in (Lowe and Agarwal, 2019). Furthermore, we compute for each vertex and augment each edge with the index of the smallest maximal depression containing . This can be computed in I/Os using the algorithm described by Arge et al. (Arge and Revsbæk, 2009). Since both algorithms assume , we assume the is stored in internal memory.
4.1. Extending the Internal Memory Algorithm
We now describe our first I/O-efficient algorithm. In order to extend the internal terrain-flow query algorithm, we introduce the following notation: let be the set of edges such that, for each edge , is the smallest maximal depression containing .
As in the previous section, we proceed by performing an upward sweep on the terrain followed by a downward sweep.
Upward sweep. For the upward sweep of our algorithm, we compute for each maximal depression . Given a rain distribution , we start by computing the sum of rain falling directly in each maximal depression . We do this by assigning for each vertex with nonzero rainfall to the smallest maximal depression containing . This step can be implemented I/O-efficiently using a sort and a scan of the terrain and ; for each maximal depression store in memory. We then perform the upward sweep described in Section 3 in memory, maintaining the sum of rainfall functions at each saddle vertex. This upward sweep can be trivially implemented in I/Os and internal computation time.
Downward sweep. We sweep through vertices of in descending height order, maintaining the following values in memory for each height :
-
(1)
for each depression in the sublevel set , maintain the fill-rate , and
-
(2)
for each maintain the depression flow-rate sum
We cannot explicitly store the flow-rates for the set of edges crossing the sweep line in memory. Instead, we store each flow-rate in an I/O-efficient priority queue keyed on the height of vertex . Furthermore, we initialize by inserting the functions for each vertex with . Whenever we process a vertex , for all we propagate the flow-rate forward to using such that the function can be removed from whenever is processed. The values maintained for each depression in sublevel set can be maintained in memory since we assume .
We now describe how each step of the sweep is performed. Let be the current vertex. First we remove the function from . Furthermore, for each edge , we remove the flow-rate from . Since the algorithms visits vertices in descending order of height, the functions must have been inserted into at an earlier point and will be at the front of . Since each edge no longer crosses the sweep line, we update the depression flow-rate sums by subtracting from the flow-rate sum of the smallest maximal depression containing .
Let be the smallest maximal depression containing . If is a non-negative-saddle vertex, we compute and determine if or when becomes flooded, using and as described in Section 3.
If is a negative saddle delimiting two depressions and , we wish to compute whether or becomes full and, if so, which fills first. In order to compute the flood times of the two depressions, we recall that the fill-rate of a depression is equal to the sum of flow-rates across all the edges plus the amount of rain falling in . When we are processing the vertex we have that all edges crossing into and respectively are also crossing the sweep line. We therefore compute the fill-rate of ( resp.) by summing the depression flow-rate sums for all maximal depressions ( resp.):
(8) |
The flood times and the flow-rate is then computed from and as described in Section 3.
Finally, we can propagate the flow-rates on the outgoing edges by pushing to for all vertices where . Furthermore, we update the depression flow-rate sums with the flow-rates of the outgoing edges. Note that each flow-rate is added to only one flow-rate sum.
The flow-rate of each edge is forwarded only once using the priority queue. Thus, we spend a total of I/Os and internal computation time processing all vertices in the sweep excluding computation of the fill-rates at negative saddles. In order to efficiently compute the fill-rates in internal memory, we store the depression flow-rate sums in a sorted list ordered by the in-order traversal index of the depressions. We then partition the sums as in (Lowe and Agarwal, 2019) and compute the fill-rates using internal computation time in total. Since the initial sorting of vertices and edges can be performed in I/Os and internal computation time, the algorithm uses a total of I/Os and internal computation time.
Theorem 4.1.
Given a triangulation of with vertices, a height function which is linear on each face of and a rain distribution , a terrain-flow query can be answered in I/Os and internal computation time assuming , where is the total complexity of all flow-rate functions which we return, is the height of the merge tree, is the number of times at which the rain distribution changes, is the number of sinks in , and is the size of internal memory.
4.2. Assuming Smaller Internal Memory
We now extend the algorithm to relax the assumption on the size of the internal memory from to , at the cost of a greater number of I/Os.
We use the same framework as described previously, however, we avoid storing the depression flow-rate sums and fill-rates in memory for each depression in the sublevel set ; We instead the priority queue to forward fill-rates as well as the edge flow-rates used to compute fill-rates at negative saddle vertices.
Forwarding fill-rates. Let be non-negative-saddle vertex and let be the smallest maximal depression containing . Let be the vertex visited after in the downward sweep, where the smallest maximal depression containing is also . When performing the sweep, we forward from to using . We note that we can augment with the height of using I/Os in preprocessing, and thus we can forward to during the sweep. Furthermore, for each negative saddle vertex delimiting depressions and , we forward and to the first vertices visited in and , respectively.
Computing fill-rates at negative saddles. Let be a negative saddle vertex delimiting two depressions and . During execution of the sweep, we wish to compute the fill-rates of depressions and . We recall that the fill-rate of can be computed as follows:
(9) |
We note that the flow-rates required to compute this sum and can be propagated using . However, that would in the worst-case lead to forwarding functions in total. We recall that is forwarded to using . Furthermore, since , it suffices to compute either or , whichever requires the fewest flow-rates to be forwarded. The number of flow-rate functions that need to be forwarded in order to compute and , respectively, can be precomputed by counting the number of edges crossing the boundaries of and . This precomputation step can trivially be implemented by performing a scan of the vertices using I/Os and memory. We therefore preprocess for which depressions we compute fill-rates and forward only the flow-rates required for computing those.
We now bound the number of edges forwarded using a similar recurrence as (Lowe and Agarwal, 2019); Let denote the total number of edges with at least one vertex contained in the depression and note that . Letting be the total number of flow-rates summed to compute the fill-rates for all saddles contained in , we have that
(10) |
Noting that the set of edges crossing into the two maximal depressions and are disjoint, it follows that . Using this, the recurrence solves to , and we thus need to forward only a total of flow-rate functions. Since the complexity of each flow-rate function is bounded by , we spend a total of I/Os and internal computation forwarding edges and computing fill-rates.
Theorem 4.2.
Given a triangulation of with vertices, a height function which is linear on each face of and a rain distribution , a terrain-flow query can be answered in I/Os and internal computation time assuming , where is the height of the merge tree, is the number of times at which the rain distribution changes, is the number of sinks in , and is the size of internal memory.
5. Edge-Flow Query
The terrain-flow query can naturally be used to answer edge-flow queries by returning for a query edge . While in practice the query time can be improved, the worst case running time under the MFD model remains the same as the terrain-flow query. Under the SFD model, we can improve this running time significantly, building on the fast algorithm for the flood-time query under SFD given by Rav et al. (Rav et al., 2017), along with a linear-size data structure supporting constant time reachability queries in planar directed graphs given by Holm et al. (Holm et al., 2015).
The key idea of the algorithm is that under the SFD model when water falls on a vertex or spills from a negative saddle the water flows along a single path to some sink in the terrain. Thus if we can find which vertices and negative saddles from which water follows a path containing , will be the sum of water falling directly on or spilling from these sources. Before describing the algorithm, we begin with some definitions.
Let be a negative saddle, let and be two down edges in from , and let be the up edge from . We call the depression associated with (resp. with ) as the sibling (resp. parent) (depression) of that associated with . Any given point is contained in a sequence of maximal depressions . Each is delimited by a saddle and has a corresponding sibling depression . Note that these saddles form a path in from to the root. We refer to the maximal depressions as the tributaries of and denote them by .
For any point we define the tributary tree as follows. is a directed graph with nodes corresponding to the tributaries of plus . There is an edge in if water spills from the saddle to a sink in when becomes full. Water spills to exactly one sink under the SFD model, so will be a tree rooted at .
We present an -time algorithm for preprocessing into a linear-size data structure that can answer an edge-flow query for a given rain distribution and query edge . The query takes , where is the number of -tributaries with .
Given a query edge and a rain distribution , we begin by assuming that water flows from to . Since water only flows from each vertex to one neighbor in the SFD model, if this were not the case then we would immediately have that . Hence, . For simplicity, we will instead compute the equivalent point-flow query.
The algorithm begins by building . See Figure 2 for an example. As we have noted, water will reach in one of two cases: rain falls on a vertex of the terrain and follows a path which crosses , or water spills from a tributary of and reaches .
Consider first the case when rain falls only on a single point contained in some tributary . Take the path in from to the root , For each depression let denote the depression volume of and let be the fill-time of . The fill-time , when begins spilling into , will be when the volume of rain falling on equals . Moreover we have
That is to say, instead of computing the fill and spill rates for each tributary along the path, we can merge all the tributaries in this path and treat it as if it were a single depression. Then to answer the query, check whether there is a path from the saddle delimiting to the query vertex . If there is, we have , otherwise .
Now consider the general case where rain falls on many vertices. We will compute as a sum of the rainfall functions on vertices that directly reach , along with the spill-rates of parents of in that reach . We begin by computing the initial fill-rate of each tributary in which rain falls directly. For each vertex from which rain flows to a sink contained in , check whether the path the water takes crosses . If so add their rainfall to the sum. If rain falls in multiple tributaries that have disjoint paths in to (excluding the root ), we can simply perform the single-point rain algorithm multiple times for each path and add each spill-rates from depressions which reach to the sum. However it might be the case that two such paths intersect at a tributary before reaching (e.g. and in Figure 2.) Here, we can compute the spill-rates of the two parent tributaries of as we did in the single-point rain algorithm, and then recurse, treating as a single-point source of rain with fill-rate equal to the sum of spill-rates of its parent tributaries. Cases where more than two paths merge at a single vertex can be handled in a similar manner.
Now it remains to show how we can perform this algorithm efficiently. There are two main operations needed. First, we must compute the fill and spill-rates of the tributaries of . Then we must determine from which saddles and vertices water will reach .
To perform the first operation efficiently, build the linear-size fast data structure for flood-time queries as described in (Rav et al., 2017). With this data structure we can compute the spill-rates of parent tributaries of in time, where as defined above, is the numbe of -tributaries in which rain is falling directly.

To perform the second operation efficiently, we consider the subgraph of the flow graph taking only edges for which , i.e., when is the lowest neighbor of . Then on this directed planar graph, build the linear-size data structure reachability queries as described in (Holm et al., 2015). This data structure supports constant-time reachability queries. For a non-saddle vertex , water falling at reaches the query vertex if is reachable from . For water spilling from a negative-saddle towards a node we instead check whether is reachable from this vertex . Omitting all the details, we obtain the following:
Theorem 5.1.
Given a triangulation with vertices and a height function which is linear on each face of , a data structure of size can be constructed in time so that for a (time varying) rain distribution and an edge an edge-flow query can be answered in , where is the complexity of the rain distribution, is the number of tributaries in which rain is falling directly, and is the number of times at which the rain distribution changes.
6. Extracting 2D Flow Networks
So far we have assumed that water flows along the edges of , and computed the flow rate of water along these edges. But in reality the water is not constrained to edges and flows along 2D channels forming a 2D network of rivers. In this section we first describe a model for determining the 2D channels given a 1D flow network. We then present an efficient algorithm for computing these channels for a given path along the edges of .
6.1. Model for 2D Channels
We assume that we are given a path along the edges of . For each edge of , let be the flow value along . Unlike previous sections, we assume that does not vary with time. But may vary with edges. The goal is to compute a 2D channel along which water flows. 111One method of generating is computing the flow rate along all edges of as in Sections 3 and 4, fixing a time , choosing a threshold , extracting the edges with , post-processing these edges to construct a 1D flow network with some desired properties, and finally decomposing this flow network into a set of paths. These steps are beyond the scope of this paper and an interesting direction for future research. The channel is defined by its left and right banks and the height of water at every point on . More precisely, is parameterized as where is an interval. For every , we define as the left and right bank, respectively, of at , and The locus of points (resp. ), for , traces a curve (resp. ), which is the left (resp. right) bank of .
We overlay with and . is the portion of this overlay between and ; see Figure 3. The complexity of , denoted by , is the number of vertices in .
To estimate and , we use Manning’s equation (Manning et al., 1890), a widely used empirical formula relating the channel geometry and flow rate as follows.
Let be a point on an edge with flow value . Let be the line in the -plane passing through and normal to , and let be the vertical plane containing . Let be the cross-section of in , which we refer to as the profile of at . is a polygonal chain whose vertices (resp. edges) are the intersection points of edges (resp. faces) of with . See Figure 3. Let be the vertex on corresponding to the point , i.e. is vertically above .
We divide into two polygonal rays , at the vertex , with (resp. ) lying to the left (resp. right) of . For a height , let (resp. ) be the first point on (resp. ) at height as we walk along (resp. .) Let denote the area of the polygon formed by the segment and the portion of between and , and let denote the arc length of between and . If the water has height at , then Manning’s equation (Manning et al., 1890) states that the flow rate at is
(11) |
where is the slope in the -direction of the edge of corresponding to , and is Manning’s roughness coefficient. We assume that we are given the value of , which depends on the material of the terrain at (e.g. concrete, dirt, light brush, etc.) Manning’s equation is typically used to compute the flow rate of rivers given a measurement of the river depth and approximate channel geometry. Here instead we state an inverse problem: given the flow rate at , determine the depth and width of the river at . Let be the value of for which . We set and , i.e., the river bank points on corresponding to ; Let be the profile of the channel at . See Figure 3.
We first describe how we compute for a fixed and then describe how to track and as we vary . For simplicity, we make the following two assumptions:
-
(A1)
is unimodal for all .
-
(A2)
The point is the unique minimum of .
We discuss in Section 6.4 how to relax these assumptions.
6.2. Computing
Recall that we assume to be unimodal with as its unique minimum. Without loss of generality, assume that the edge containing is parallel to the -axis, so is parallel to the -plane. We raise the value of starting from and stopping at the height of vertices of until we find a vertex such that . We now know the edges of and that contain and . We then compute the points themselves.
We now describe the procedure in more detail. Let be the sequence of edges of , ordered from left to right, and let be the endpoints of ; . Recall that each edge is the intersection of a face of with the vertical plane , and each endpoint is for some edge of . For each edge , let be the semi-infinite trapezoid formed by the edge and the vertical rays in the -direction from the endpoints of . For a value , we define the trapezoid to be the intersection of with the halfspace ; may be empty, or it may be a triangle. We define to be the area of and to be the length of the bottom edge of , which is a portion of the edge . Let denote the coordinates of as a function of , and set and . Then can be written as
(12) |
Similarly can be expressed as
(13) |
We note that (resp. ) is a piecewise-linear (resp. piecewise-quadratic) function of for a fixed . We can define and for the edges of as well. We can now express and as:
(14) |
where the summation is taken over all edges of that contain a point of height at most . and are also piecewise-linear and piecewise-quadratic functions respectively.
Let be the heights of vertices of . . Assuming have been computed then , can be computed in time using (12)–(14).
Let be the first value for which . Since (resp. ) is a linear (resp. quadratic) function for , the value of can be computed in time by plugging these functional forms in (11). Let (resp. ) be the edge of (resp. ) at which the vertical sweep stopped. Then (resp. ) is the point on (resp. ) of height and can be computed in time. The total time spent by the procedure is . Hence, we obtain the following.
Lemma 6.1.
For a given point , , and can be computed in time.
6.3. Unimodal Channel Algorithm
We now describe an algorithm for compute the channel assuming (A1) and (A2) hold. Recall that for any , the vertices of are intersection points of the edges with the plane . Let denote the sequence of these edges, which implicitly define . We refer to as the combinatorial structure of . We compute by varying continuously from to and maintaining . As varies, changes continuously, i.e., each vertex of traces a curve, but the combinatorial structure changes only at discrete values of , called the events. The algorithm works by sweeping the line along , stopping at events as we traverse . As long as lies on the same edge of , simply translates. At vertices of , where the sweep line shifts from one edge to the next one in , the algorithm continues by rotating to make it normal to the next edge. We first describe how we sweep along an edge of and then describe how the sweep line rotates at a vertex of .
Edges. Fix an edge . Without loss of generality, assume that is parameterized as .

As we sweep along and vary , the left and right banks trace curves that lie inside fixed faces of and the remaining vertices of trace the corresponding edges of . The algorithm encounters the following two types of events at which changes:
-
(1)
the sweep line reaches an endpoint of an edge of which is a vertex of , or
-
(2)
or intersects an edge (bounding the face containing it) of .
The first event results in one or more edges in shrinking to the point , and one or more new edges starting at . The second event results in either the addition and/or removal of an extremal edge in (and thus insertion/deletion of an edge in ) depending on whether the height of the channel is increasing or decreasing.
The first type of events are easy to detect, as they correspond to the vertices of . The second type are more challenging, and we detect them as follows. By maintaining functions representing the area and wetted perimeter of as a bivariate function of and (using (12-14)) and using Manning’s equation we can express as a function of . We then compute when reaches the top or bottom boundary of the face containing (resp. ). These time instances correspond to the second type of event.
Process the events in order, by popping the first event from the priority queue . If it is the first type of event corresponding to a vertex of , we remove from the edges that end at and insert into the edges that start at . We add the other endpoints of the new edges to as new first type of events. We also remove from and the terms corresponding to the old edges and add terms corresponding to the new edges. If an edge of the face of containing or changes, we also update the second type of event in .
If the event corresponds to or reaching an edge of the terrain, either add the new face the it crosses into and/or remove the face it crosses out of. We update as well as . We also and accordingly.
and can be maintained using a height balanced tree so that its functional form can be updated in time per insertion/deletion of a term in and .
We continue this process until we reach the event corresponding to , when the endpoint of is reached. Let be the number of total faces contained in the channel from to . Between any two events, and intersect a face only a constant number of times. Therefore the total number of events is , giving a total running time to sweep an edge of .
Vertex. When transitioning from one edge to another along the path, we must join the two channels. We will assume the there are no sharp bends between two edges of , specifically the angle between the sweep line along the first and second channel is less than 90 degrees, Taking the two channels and we see that on one side of the two channels will intersect, while on the other they will be disjoint. Let (resp. ) be the sweep line perpendicular to (resp. ) at , and (resp. ) be the intersection point between with the riverbank of (resp. with the riverbank of .) Then let (resp. ) be the line parallel to at (resp. at ), and be the intersection point between and . Now rotating about from to will sweep the area where the two channels intersect. See Figure 4.
In a similar manner in which we swept along each edge, let be the profile of with a line at angle . As we rotate the sweep line, we assume the water is flowing at the intersection of with either or . We will similarly maintain the area function (resp. the wetted perimeter function ) as a sum of functions on each face in the channel. Additionally when computing Manning’s equation, as we rotate we will linearly interpolate between slope values as well as the roughness coefficients for the two edges. The main difference is now for each face , and are not linear functions in as it was when we swept along an edge. However, we can still computed analytically the events corresponding to the riverbank(s) crossing edges of faces.

Letting denote the total number of faces in the channel obtained by sweeping at . Then the total time spent is
Putting everything together we obtain the following:
Theorem 6.1.
Given a triangulation with vertices, a height function which is linear on each face of a path in , if the channel is unimodal for all along the path, we can compute the 2D flow network in time where is the total number of faces in the channel obtained by sweeping along the edges and vertices of .
6.4. General Channels
We will now show how to modify the algorithm when assumptions (A1) and (A2) do not hold. When (A2) does not hold, i.e. is not a local minima, the modification is straightforward. Simply walk down the edges of until finding a local minima and then run the algorithm using that vertex as the division point for the polygonal rays and . It may be the case that the edge containing ends and a new minima begins, but this can be handled like any other event in the algorithm. The only difference comes in the interpretation and runtime analysis. When (A1) does not hold, it may be the case that the water level in the 2D channel does reach an edge along which water was flowing according to the 1D flow network. However this is reasonable behavior, as the 1D flow network assumes water only flows along edges of the terrain whereas in reality water will also flow along the faces. For the runtime analysis, we now include the edges searched along from to to be included in the channel .
When (A1) does not hold, i.e. the channel is not unimodal, when or intersect an edge of bounding the face containing it, that edge may correspond to a local maximum in the profile. In this case, water flows over the ridge into a secondary channel. See Figure 5333Here contains all faces between the leftmost and rightmost river banks, i.e., all edges marked red.. We must now account for the decrease of the flow-rate in the primary channel as well as determining the height of water in the secondary channel.

Updating flow rates. Let be the first face containing a local maximum encountered when sweeping along an edge maintaining , and let be the edge of corresponding to the maximum. Using Manning’s equation, we compute the flow rate corresponding to when this unimodal channel becomes full . If a spill will occur, and the excess flow is sent to the local minimum in the secondary channel. To account for the water flowing out of the channel, consider the flow rate along as a function of , . Letting be the minimum edge in the secondary channel, we set . As we continue the sweep will be a non-increasing function, we set .
Secondary channel. When an overflow occurs we continue adding faces to the profile until finding the next local minima corresponding to edge . Then in this secondary channel if the excess flow exceeds our threshold for the 1D channel, i.e. , we repeat the unimodal channel algorithm in this channel using . It may be the case that is enough to fill the secondary channel above the height of a ridge. If it is the same ridge that spilled into the secondary channel we treat it as a single channel. If it is a ridge further out, we repeat the process in the tertiary channel.
7. Conclusion
In this paper we presented algorithms for a number of flow routing problems: First, we developed a fast internal-memory algorithm for the terrain-flow query problem which given a rain distribution, computes the flow rate for all edges . We also showed how the algorithm could be made I/O-efficient. Next, we presented a faster algorithm if one is interested in computing the flow rate of only one edge, after some preprocessing. Finally, given a flow path along the edges of , we proposed an algorithm to determine the 2D channel along which water flows; our algorithm does not make any assumption about the geometry of the channel.
We conclude by mentioning a few directions for future work. The model of extracting 2D channels leaves a number of open questions. For instance, if the 1D flow network is a forest then channels along different paths will interact which leaves the question of how we merge these channels to construct a 2D river network.
While we consider the flow rate as a function of time, it only changes when the rain distribution changes or a spill event occurs. That is, the effects of such events are propagated to all reachable vertices instantaneously. While this assumption is reasonable for local effects and for flash floods when a large volume of rain falls over a short duration, an interesting question is to make the model more general and account for the time it takes water to flow over the terrain.
References
- (1)
- Aggarwal and Vitter (1988) A Aggarwal and JS Vitter. 1988. The input/output complexity of sorting and related problems. Commun. ACM 31, 9 (1988), 1116–1127.
- Arge et al. (2017) L Arge, M Rav, S Raza, and M Revsbæk. 2017. I/O-Efficient Event Based Depression Flood Risk. In Proc. 19th Workshop on Algorithm Engineering and Experiments. 259–269.
- Arge and Revsbæk (2009) L Arge and M Revsbæk. 2009. I/O-efficient Contour Tree Simplification. In Intl. Sympos. on Algos. and Computation. 1155–1165.
- Arge et al. (2010) L Arge, M Revsbæk, and N Zeh. 2010. I/O-efficient computation of water flow across a terrain. In Proc. 26th Annu. Sympos. on Comp. Geom. 403–412.
- Arge et al. (2000) L Arge, L Toma, and J Vitter. 2000. I/O-Efficient Algorithms for Problems on Grid-Based Terrains. Journal of Experimental Algorithmics 6 (10 2000). https://doi.org/10.1145/945394.945395
- Bates and De Roo (2000) PD Bates and APJ De Roo. 2000. A simple raster-based model for flood inundation simulation. Journal of hydrology 236, 1-2 (2000), 54–77.
- Carr et al. (2003) H Carr, J Snoeyink, and U Axen. 2003. Computing contour trees in all dimensions. Comp. Geom. 24, 2 (2003), 75–94.
- Chiang et al. (1995) Y Chiang, MT Goodrich, EF Grove, R Tamassia, DE Vengroff, and JS Vitter. 1995. External-memory graph algorithms. In Proc. Sixth Annu. ACM-SIAM Sympos. on Discrete Algos. 139–149.
- Edelsbrunner et al. (2001) H Edelsbrunner, J Harer, and A Zomorodian. 2001. Hierarchical Morse complexes for piecewise linear 2-manifolds. In Proc. 17th Annu. Sympos. Comp. Geom. 70–79.
- Holm et al. (2015) J Holm, E Rotenberg, and M Thorup. 2015. Planar reachability in linear space and constant time. In 2015 IEEE 56th Annual Symposium on Foundations of Computer Science. IEEE, 370–389.
- Kreveld et al. (1997) M Kreveld, R Oostrum, C Bajaj, V Pascucci, and D Schikore. 1997. Contour trees and small seed sets for isosurface traversal. In Proc. 13th Annu. Sympos. on Comp. Geom. 212–220.
- Liu and Snoeyink (2005) Y Liu and J Snoeyink. 2005. Flooding triangulated terrain. In Proc. 11th Intl. Sympos. on Spatial Data Handling. 137–148.
- Lowe and Agarwal (2019) A Lowe and PK Agarwal. 2019. Flood-Risk Analysis on Terrains under the Multiflow-Direction Model. ACM Trans. Spatial Algorithms Syst. 5, 4, Article 26 (Sept. 2019), 27 pages. https://doi.org/10.1145/3340707
- Manning et al. (1890) R Manning, JP Griffith, TF Pigot, and LF Vernon-Harcourt. 1890. On the flow of water in open channels and pipes.
- Rav et al. (2017) M Rav, A Lowe, and PK Agarwal. 2017. Flood Risk Analysis on Terrains. In Proc. of the 25th ACM SIGSPATIAL Int. Conference on Advances in GIS. ACM, 36.
- Sanders (2001) Peter Sanders. 2001. Fast Priority Queues for Cached Memory. ACM J. Exp. Algorithmics 5 (Dec. 2001), 7–es. https://doi.org/10.1145/351827.384249
- Wood et al. (2016) M Wood, JC Neal, PD Bates, R Hostache, T Wagener, L Giustarini, M Chini, G Corato, and P Matgen. 2016. Calibration of channel depth and friction parameters in the LISFLOOD-FP hydraulic model using medium resolution SAR data and identifiability techniques. Hydrology and Earth System Sciences 20, 12 (2016), 4983–4997.