SinkFiller: Permanently fill pits in a topography

Created on Mon Oct 19.

@author: dejh

class SinkFiller(*args, **kwds)[source]

Bases: landlab.core.model_component.Component

This component identifies depressions in a topographic surface, then fills them in in the topography. No attempt is made to conserve sediment mass. User may specify whether the holes should be filled to flat, or with a gradient downwards towards the depression outlet. The gradient can be spatially variable, and is chosen to not reverse any drainage directions at the perimeter of each lake.

The primary method of this class is ‘run_one_step’. ‘fill_pits’ is a synonym.

Constructor assigns a copy of the grid, and calls the initialize method.


SinkFiller(grid, routing='D8', apply_slope=False, fill_slope=1.e-5):

grid : ModelGrid

A landlab grid.

routing : {‘D8’, ‘D4’} (optional)

If grid is a raster type, controls whether fill connectivity can occur on diagonals (‘D8’, default), or only orthogonally (‘D4’). Has no effect if grid is not a raster.

apply_slope : bool

If False (default), leave the top of the filled sink flat. If True, apply the slope fill_slope to the top surface to allow subsequent flow routing. A test is performed to ensure applying this slope will not alter the drainage structure at the edge of the filled region (i.e., that we are not accidentally reversing the flow direction far from the outlet.)

fill_slope : float (m/m)

The slope added to the top surface of filled pits to allow flow routing across them, if apply_slope.


>>> from landlab import RasterModelGrid
>>> from landlab import BAD_INDEX_VALUE as XX
>>> from landlab.components import FlowRouter, SinkFiller
>>> import numpy as np
>>> lake1 = np.array([34, 35, 36, 44, 45, 46, 54, 55, 56, 65, 74])
>>> lake2 = np.array([78, 87, 88])
>>> guard_nodes = np.array([23, 33, 53, 63, 73, 83])
>>> lake = np.concatenate((lake1, lake2))
>>> mg = RasterModelGrid((10, 10), 1.)
>>> z = np.ones(100, dtype=float)
>>> z += mg.node_x  # add a slope
>>> z[guard_nodes] += 0.001  # forces the flow out of a particular node
>>> z[lake] = 0.
>>> field = mg.add_field('node', 'topographic__elevation', z,
...                      units='-', copy=True)
>>> fr = FlowRouter(mg)
>>> fr.run_one_step()
>>> mg.at_node['flow__sink_flag'][mg.core_nodes].sum()
>>> hf = SinkFiller(mg, apply_slope=False)
>>> hf.run_one_step()
>>> np.allclose(mg.at_node['topographic__elevation'][lake1], 4.)
>>> np.allclose(mg.at_node['topographic__elevation'][lake2], 7.)

Now reset and demonstrate the adding of an inclined surface:

>>> field[:] = z
>>> hf = SinkFiller(mg, apply_slope=True)
>>> hf.run_one_step()
>>> hole1 = np.array([4.00007692, 4.00015385, 4.00023077, 4.00030769,
...                   4.00038462, 4.00046154, 4.00053846, 4.00061538,
...                   4.00069231, 4.00076923, 4.00084615])
>>> hole2 = np.array([7.4, 7.2, 7.6])
>>> np.allclose(mg.at_node['topographic__elevation'][lake1], hole1)
>>> np.allclose(mg.at_node['topographic__elevation'][lake2], hole2)
>>> fr.run_one_step()
>>> mg.at_node['flow__sink_flag'][mg.core_nodes].sum()
drainage_directions_change(lake_nodes, old_elevs, new_elevs)[source]

True if the drainage structure at lake margin changes, False otherwise.


This is a synonym for the main method run_one_step().


The BMI-style initialize method takes an optional input_stream parameter, which may be either a ModelParameterDictionary object or an input stream from which a ModelParameterDictionary can read values.


This is the main method. Call it to fill depressions in a starting topography.