landlab.utils.distance_to_divide module#

Functions to calculate flow distance from divide.

calculate_distance_to_divide(grid, longest_path=True, add_to_grid=False, clobber=False)[source]#

Calculate the along flow distance from drainage divide to point.

This utility calculates the along flow distance based on the results of running flow accumulation on the grid. It will use the connectivity used by the FlowAccumulator (e.g. D4, D8, Dinf).

Parameters:
  • grid (ModelGrid) –

  • longest_path (bool, optional) – Take the longest (or shortest) path to a drainage divide. Default is true.

  • add_to_grid (boolean, optional) – Flag to indicate if the stream length field should be added to the grid. Default is False. The field name used is distance_to_divide.

  • clobber (boolean, optional) – Flag to indicate if adding the field to the grid should not clobber an existing field with the same name. Default is False.

Returns:

distance_to_divide – The distance that has to be covered from an imaginary flow, located in each node of the grid, to reach the watershed’s outlet.

Return type:

float ndarray

Examples

>>> import numpy as np
>>> from landlab import RasterModelGrid
>>> from landlab.components import FlowAccumulator
>>> from landlab.utils.distance_to_divide import calculate_distance_to_divide
>>> mg = RasterModelGrid((5, 4))
>>> mg.at_node["topographic__elevation"] = [
...     [0.0, 0.0, 0.0, 0.0],
...     [0.0, 10.0, 10.0, 0.0],
...     [0.0, 20.0, 20.0, 0.0],
...     [0.0, 30.0, 30.0, 0.0],
...     [0.0, 0.0, 0.0, 0.0],
... ]
>>> mg.set_closed_boundaries_at_grid_edges(
...     bottom_is_closed=False,
...     left_is_closed=True,
...     right_is_closed=True,
...     top_is_closed=True,
... )
>>> fr = FlowAccumulator(mg, flow_director="D8")
>>> fr.run_one_step()
>>> distance_to_divide = calculate_distance_to_divide(
...     mg,
...     add_to_grid=True,
...     clobber=True,
... )
>>> mg.at_node["distance_to_divide"]
array([ 0.,  3.,  3.,  0.,
        0.,  2.,  2.,  0.,
        0.,  1.,  1.,  0.,
        0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.])

Now, let’s change to MFD the flow_director method, which routes flow to multiple nodes.

>>> from landlab import RasterModelGrid
>>> from landlab.components import FlowAccumulator
>>> from landlab.utils.distance_to_divide import calculate_distance_to_divide
>>> mg = RasterModelGrid((5, 4), xy_spacing=(1, 1))
>>> mg.at_node["topographic__elevation"] = [
...     [0.0, 0.0, 0.0, 0.0],
...     [0.0, 10.0, 10.0, 0.0],
...     [0.0, 20.0, 20.0, 0.0],
...     [0.0, 30.0, 30.0, 0.0],
...     [0.0, 0.0, 0.0, 0.0],
... ]
>>> mg.set_closed_boundaries_at_grid_edges(
...     bottom_is_closed=False,
...     left_is_closed=True,
...     right_is_closed=True,
...     top_is_closed=True,
... )
>>> fr = FlowAccumulator(mg, flow_director="MFD")
>>> fr.run_one_step()
>>> distance_to_divide = calculate_distance_to_divide(
...     mg,
...     add_to_grid=True,
...     clobber=True,
... )
>>> mg.at_node["distance_to_divide"]
array([ 0.,  3.,  3.,  0.,
        0.,  2.,  2.,  0.,
        0.,  1.,  1.,  0.,
        0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.])

The distance_to_divide utility can also work on irregular grids. For the example we will use a Hexagonal Model Grid, a special type of Voroni Grid that has regularly spaced hexagonal cells.

>>> from landlab import HexModelGrid
>>> from landlab.components import FlowAccumulator
>>> from landlab.utils.distance_to_divide import calculate_distance_to_divide
>>> dx = 1
>>> hmg = HexModelGrid((5, 3), dx)
>>> _ = hmg.add_field(
...     "topographic__elevation",
...     hmg.node_x + np.round(hmg.node_y),
...     at="node",
... )
>>> hmg.status_at_node[hmg.boundary_nodes] = hmg.BC_NODE_IS_CLOSED
>>> hmg.status_at_node[0] = hmg.BC_NODE_IS_FIXED_VALUE
>>> fr = FlowAccumulator(hmg, flow_director="D4")
>>> fr.run_one_step()
>>> distance_to_divide = calculate_distance_to_divide(
...     hmg,
...     add_to_grid=True,
...     clobber=True,
... )
>>> hmg.at_node["distance_to_divide"]
array([ 3.,  0.,  0.,
     0.,  2.,  1.,  0.,
   0.,  1.,  1.,  0.,  0.,
     0.,   0.,  0.,  0.,
        0.,  0.,  0.])