landlab.components.flow_director.flow_director_dinf

flow_director_dinf.py: provides the component FlowDirectorDINF.

Directs flow on raster grids only using the Dinfinity algorithm of Tarboton 1997.

class FlowDirectorDINF[source]

Bases: _FlowDirectorToMany

Flow direction on a raster grid by the D infinity method.

Directs flow by the D infinity method (Tarboton, 1997). Each node is assigned two flow directions, toward the two neighboring nodes that are on the steepest subtriangle. Partitioning of flow is done based on the aspect of the subtriangle.

Specifically, it stores as ModelGrid fields:

  • Node array of receivers (nodes that receive flow), or ITS OWN ID if there is no receiver: ‘flow__receiver_node’. This array is 2D, and is of dimension (number of nodes x max number of receivers).

  • Node array of flow proportions: ‘flow__receiver_proportions’. This array is 2D, and is of dimension (number of nodes x max number of receivers).

  • Node array of links carrying flow: ‘flow__link_to_receiver_node’. This array is 2D, and is of dimension (number of nodes x max number of receivers).

  • Node array of downhill slopes corresponding to each receiver.: ‘topographic__steepest_slope’ This array is 2D, and is of dimension (number of nodes x max number of receivers). If the slope is uphill or flat, the value is assigned zero.

  • Boolean node array of all local lows: ‘flow__sink_flag’

  • Link array identifing if flow goes with (1) or against (-1) the link direction: ‘flow__link_direction’

The primary method of this class is run_one_step.

Examples

This method works for both raster and irregular grids. First we will look at a raster example, and then an irregular example.

>>> import numpy as numpy
>>> from landlab import RasterModelGrid
>>> from landlab.components import FlowDirectorDINF
>>> mg = RasterModelGrid((4, 4), xy_spacing=(1, 1))
>>> mg.set_closed_boundaries_at_grid_edges(True, True, True, False)
>>> _ = mg.add_field(
...     "topographic__elevation",
...     mg.node_x**2 + mg.node_y**2,
...     at="node",
... )

The DINF flow director can be uses for raster grids only.

>>> fd = FlowDirectorDINF(mg, "topographic__elevation")
>>> fd.surface_values.reshape(mg.shape)
array([[ 0.,  1.,   4.,  9.],
       [ 1.,  2.,   5., 10.],
       [ 4.,  5.,   8., 13.],
       [ 9., 10., 13., 18.]])
>>> fd.run_one_step()

Unlike flow directors that only direct flow to one node or to all downstream nodes, FlowDirectorDINF directs flow two nodes only. It stores the receiver information is a (number of nodes x 2) shape field at nodes.

>>> mg.at_node["flow__receiver_node"]
array([[ 0, -1],
       [ 1, -1],
       [ 2, -1],
       [ 3, -1],
       [ 4, -1],
       [ 0,  -1],
       [ 5,  1],
       [ 7, -1],
       [ 8, -1],
       [ 5, -1],
       [ 5, -1],
       [11, -1],
       [12, -1],
       [13, -1],
       [14, -1],
       [15, -1]])

It also stores the proportions of flow going to each receiver, the link on which the flow moves in at node arrays, and the slope of each link.

>>> mg.at_node["flow__receiver_proportions"]
array([[1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [0.59033447, 0.40966553],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ]])
>>> mg.at_node["flow__link_to_receiver_node"]
array([[-1, -1],
       [-1, -1],
       [-1, -1],
       [-1, -1],
       [ 3, 25],
       [24,  4],
       [ 8, 26],
       [ 9, 28],
       [14, 31],
       [11, 33],
       [32, 12],
       [16, 34],
       [21, 37],
       [18, 39],
       [19, 38],
       [20, 40]])
>>> mg.at_node["topographic__steepest_slope"]
array([[-1.00000000e+00, -1.41421356e+00],
       [ 1.00000000e+00, -7.12763635e+02],
       [ 3.00000000e+00,  1.41421356e+00],
       [ 5.00000000e+00,  2.82842712e+00],
       [ 1.00900000e+03,  7.12763635e+02],
       [ 1.41421356e+00,  1.00000000e+00],
       [ 3.00000000e+00,  2.82842712e+00],
       [ 1.00400000e+03,  7.10642315e+02],
       [ 1.00400000e+03,  7.12056529e+02],
       [ 3.00000000e+00,  0.00000000e+00],
       [ 4.24264069e+00,  3.00000000e+00],
       [ 1.00100000e+03,  7.09935208e+02],
       [-0.00000000e+00,  7.09935208e+02],
       [ 1.00400000e+03,  7.07813888e+02],
       [ 1.00100000e+03,  7.09935208e+02],
       [ 0.00000000e+00,  7.07813888e+02]])

Finally, FlowDirectorDINF identifies sinks, or local lows.

>>> mg.at_node["flow__sink_flag"].astype(int)
array([1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1])

The flow directors also have the ability to return the flow receiver nodes through a function called direct_flow()

>>> fd = FlowDirectorDINF(mg, "topographic__elevation")
>>> fd.run_one_step()
>>> receivers, proportions = fd.direct_flow()
>>> receivers
array([[ 0, -1],
       [ 1, -1],
       [ 2, -1],
       [ 3, -1],
       [ 4, -1],
       [ 0, -1],
       [ 5,  1],
       [ 7, -1],
       [ 8, -1],
       [ 5, -1],
       [ 5, -1],
       [11, -1],
       [12, -1],
       [13, -1],
       [14, -1],
       [15, -1]])
>>> proportions
array([[1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [0.59033447, 0.40966553],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ],
       [1.        , 0.        ]])

For each donor node (represented by each row) the proportions should sum to one.

>>> proportions.sum(axis=1)
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])

References

Required Software Citation(s) Specific to this Component

None Listed

Additional References

Tarboton, D. (1997). A new method for the determination of flow directions and upslope areas in grid digital elevation models. Water Resources Research 33(2), 309-319. https://dx.doi.org/10.1029/96wr03137

Parameters:
  • grid (ModelGrid) – A grid.

  • surface (field name at node or array of length node, optional) – The surface to direct flow across, default is field at node: topographic__elevation.

  • partition_method (string, optional) – Method for partitioning flow. Options include ‘slope’ (default) and ‘square_root_of_slope’.

__init__(grid, surface='topographic__elevation')[source]
Parameters:
  • grid (ModelGrid) – A grid.

  • surface (field name at node or array of length node, optional) – The surface to direct flow across, default is field at node: topographic__elevation.

  • partition_method (string, optional) – Method for partitioning flow. Options include ‘slope’ (default) and ‘square_root_of_slope’.

static __new__(cls, *args, **kwds)
cite_as = ''
property coords

Return the coordinates of nodes on grid attached to the component.

property current_time

Current time.

Some components may keep track of the current time. In this case, the current_time attribute is incremented. Otherwise it is set to None.

Return type:

current_time

definitions = (('flow__link_to_receiver_node', 'ID of link downstream of each node, which carries the discharge'), ('flow__receiver_node', 'Node array of receivers (node that receives flow from current node)'), ('flow__receiver_proportions', 'Node array of proportion of flow sent to each receiver.'), ('flow__sink_flag', 'Boolean array, True at local lows'), ('topographic__elevation', 'Land surface topographic elevation'), ('topographic__steepest_slope', 'The steepest *downhill* slope'))
direct_flow()[source]

Find flow directions, save to the model grid, and return receivers.

direct_flow() checks for updated boundary conditions, calculates slopes on links, finds basself._surface_valuesel nodes based on the status at node, calculates flow directions, saves results to the grid, and returns a at-node array of receiver nodes. This array is stored in the grid at: grid[‘node’][‘flow__receiver_nodes’]

An alternative to direct_flow() is run_one_step() which does the same things but also returns a at-node array of receiver nodes. This array is stored in the grid at: grid[‘node’][‘flow__receiver_nodes’]

classmethod from_path(grid, path)

Create a component from an input file.

Parameters:
  • grid (ModelGrid) – A landlab grid.

  • path (str or file_like) – Path to a parameter file, contents of a parameter file, or a file-like object.

Returns:

A newly-created component.

Return type:

Component

property grid

Return the grid attached to the component.

initialize_optional_output_fields()

Create fields for a component based on its optional field outputs, if declared in _optional_var_names.

This method will create new fields (without overwrite) for any fields output by the component as optional. New fields are initialized to zero. New fields are created as arrays of floats, unless the component also contains the specifying property _var_type.

initialize_output_fields(values_per_element=None)

Create fields for a component based on its input and output var names.

This method will create new fields (without overwrite) for any fields output by, but not supplied to, the component. New fields are initialized to zero. Ignores optional fields. New fields are created as arrays of floats, unless the component specifies the variable type.

Parameters:

values_per_element (int (optional)) – On occasion, it is necessary to create a field that is of size (n_grid_elements, values_per_element) instead of the default size (n_grid_elements,). Use this keyword argument to acomplish this task.

input_var_names = ()

Return the link id along the link transporting flow.

name = 'FlowDirectorDINF'
property node_receiving_flow

Return the node ids of the nodes receiving flow.

property node_steepest_slope

Return the steepest link slope at a node.

optional_var_names = ('topographic__elevation',)
output_var_names = ('flow__link_to_receiver_node', 'flow__receiver_node', 'flow__receiver_proportions', 'flow__sink_flag', 'topographic__steepest_slope')
property proportions_of_flow

Return the proportions of flow going to recievers.

run_one_step()[source]

Find flow directions and save to the model grid.

run_one_step() checks for updated boundary conditions, calculates slopes on links, finds basself._surface_valuesel nodes based on the status at node, calculates flow directions, and saves results to the grid.

An alternative to direct_flow() is direct_flow() which does the same things but also returns the receiver nodes not return values.

property shape

Return the grid shape attached to the component, if defined.

property sink_flag

Return the array with sink flags.

property surface_values

Values of the surface over which flow is directed.

unit_agnostic = True
units = (('flow__link_to_receiver_node', '-'), ('flow__receiver_node', '-'), ('flow__receiver_proportions', '-'), ('flow__sink_flag', '-'), ('topographic__elevation', 'm'), ('topographic__steepest_slope', '-'))
updated_boundary_conditions()[source]

Method to update FlowDirectorDINF when boundary conditions change.

Call this if boundary conditions on the grid are updated after the component is instantiated.

classmethod var_definition(name)

Get a description of a particular field.

Parameters:

name (str) – A field name.

Returns:

A description of each field.

Return type:

tuple of (name, *description*)

classmethod var_help(name)

Print a help message for a particular field.

Parameters:

name (str) – A field name.

classmethod var_loc(name)

Location where a particular variable is defined.

Parameters:

name (str) – A field name.

Returns:

The location (‘node’, ‘link’, etc.) where a variable is defined.

Return type:

str

var_mapping = (('flow__link_to_receiver_node', 'node'), ('flow__receiver_node', 'node'), ('flow__receiver_proportions', 'node'), ('flow__sink_flag', 'node'), ('topographic__elevation', 'node'), ('topographic__steepest_slope', 'node'))
classmethod var_type(name)

Returns the dtype of a field (float, int, bool, str…).

Parameters:

name (str) – A field name.

Returns:

The dtype of the field.

Return type:

dtype

classmethod var_units(name)

Get the units of a particular field.

Parameters:

name (str) – A field name.

Returns:

Units for the given field.

Return type:

str