landlab

Gradient calculators

Calculate gradients of quantities over links.

Gradient calculation functions

calc_grad_at_active_link(\*args, \*\*kwargs) Calculate gradients of node values over active links.
calc_grad_at_link(grid, vals, \*args, \*\*kwds) Calculate gradients of node values at links.
calculate_gradients_at_faces(\*args, \*\*kwargs) Calculate gradients of node values over faces.
calculate_diff_at_links(\*args, \*\*kwargs) Calculate differences of node values over links.
calculate_diff_at_active_links(\*args, \*\*kwargs) Calculate differences of node values over active links.
calc_aspect_at_node(grid, slope_component_tuple=None, elevs='topographic__elevation', unit='degrees', ignore_closed_nodes=True)[source]

Get array of aspect of a surface.

Calculates at returns the aspect of a surface. Aspect is returned as radians clockwise of north, unless input parameter units is set to ‘degrees’.

If slope_component_tuple is provided, i.e., (slope_x, slope_y), the aspect will be calculated from these data.

If it is not, it will be derived from elevation data at the nodes, which can either be a string referring to a grid field (default: ‘topographic__elevation’), or an nnodes-long numpy array of the values themselves.

If ignore_closed_nodes is False, all proximal elevation values will be used in the calculation. If True, only unclosed nodes are used.

Parameters:

grid : ModelGrid

A ModelGrid.

slope_component_tuple : (slope_x_array, slope_y_array) (optional)

Tuple of components of slope in the x and y directions, defined on nodes, if already known. If not, provide elevs.

elevs : str or array (optional)

Node field name or node array of elevations. If slope_component_tuple is not provided, must be set, but unused otherwise.

unit : {‘degrees’, ‘radians’}

Controls the unit that the aspect is returned as.

ignore_closed_nodes : bool

If True, do not incorporate values at closed nodes into the calc.

Examples

>>> from landlab import RasterModelGrid
>>> mg = RasterModelGrid((4, 4))
>>> z = mg.node_x ** 2 + mg.node_y ** 2
>>> mg.calc_aspect_at_node(elevs=z)
array([ 225.        ,  240.16585039,  255.2796318 ,  258.69006753,
        209.83414961,  225.        ,  243.54632481,  248.77808974,
        194.7203682 ,  206.45367519,  225.        ,  231.94498651,
        191.30993247,  201.22191026,  218.05501349,  225.        ])
>>> z = z.max() - z
>>> mg.calc_aspect_at_node(elevs=z)
array([ 45.        ,  60.16585039,  75.2796318 ,  78.69006753,
        29.83414961,  45.        ,  63.54632481,  68.77808974,
        14.7203682 ,  26.45367519,  45.        ,  51.94498651,
        11.30993247,  21.22191026,  38.05501349,  45.        ])
>>> mg = RasterModelGrid((4, 4), (2., 3.))
>>> z = mg.node_x ** 2 + mg.node_y ** 2
>>> mg.calc_aspect_at_node(elevs=z)
array([ 236.30993247,  247.52001262,  259.97326008,  262.40535663,
        220.75264634,  234.41577266,  251.13402374,  255.29210302,
        201.54258265,  215.47930877,  235.73541937,  242.24162456,
        196.69924423,  209.43534223,  229.19345757,  236.30993247])

Note that a small amount of asymmetry arises at the grid edges due to the “missing” nodes beyond the edge of the grid.

LLCATS: NINF SURF

Calculate differences of node values over links.

Calculates the difference in quantity node_values at each link in the grid.

Construction:

calc_diff_at_link(grid, node_values, out=None)
Parameters:

grid : ModelGrid

A ModelGrid.

node_values : ndarray or field name

Values at grid nodes.

out : ndarray, optional

Buffer to hold the result.

Returns:

ndarray

Differences across links.

Examples

>>> import numpy as np
>>> from landlab import RasterModelGrid
>>> rmg = RasterModelGrid((3, 3))
>>> z = np.zeros(9)
>>> z[4] = 1.
>>> rmg.calc_diff_at_link(z)
array([ 0.,  0.,  0.,  1.,  0.,  1., -1.,  0., -1.,  0.,  0.,  0.])

LLCATS: LINF GRAD

Calculate gradients of node values over active links.

Note

This method is deprecated as of Landlab version 1.0beta.

Use calc_grad_at_link() instead.

Calculates the gradient in quantity node values at each active link in the grid.

Construction:

calc_grad_at_active_link(grid, node_values, out=None)
Parameters:

grid : ModelGrid

A ModelGrid.

node_values : ndarray or field name

Values at grid nodes.

out : ndarray, optional

Buffer to hold the result.

Returns:

ndarray

Gradients across active links.

LLCATS: DEPR LINF GRAD

Calculate gradients of node values at links.

Calculates the gradient in node_values at each link in the grid, returning an array of length number_of_links.

Construction:

calc_grad_at_link(grid, node_values, out=None)
Parameters:

grid : ModelGrid

A ModelGrid.

node_values : ndarray or field name (x number of nodes)

Values at grid nodes.

out : ndarray, optional (x number of links)

Buffer to hold the result.

Returns:

ndarray

Gradients across active links.

Examples

>>> from landlab import RasterModelGrid
>>> rg = RasterModelGrid(3, 4, 10.0)
>>> z = rg.add_zeros('node', 'topographic__elevation')
>>> z[5] = 50.0
>>> z[6] = 36.0
>>> calc_grad_at_link(rg, z)  # there are 17 links
array([ 0. ,  0. ,  0. ,  0. ,  5. ,  3.6,  0. ,  5. , -1.4, -3.6,  0. ,
       -5. , -3.6,  0. ,  0. ,  0. ,  0. ])
>>> from landlab import HexModelGrid
>>> hg = HexModelGrid(3, 3, 10.0)
>>> z = hg.add_zeros('node', 'topographic__elevation', noclobber=False)
>>> z[4] = 50.0
>>> z[5] = 36.0
>>> calc_grad_at_link(hg, z)  # there are 11 faces
array([ 0. ,  0. ,  0. ,  5. ,  5. ,  3.6,  3.6,  0. ,  5. , -1.4, -3.6,
        0. , -5. , -5. , -3.6, -3.6,  0. ,  0. ,  0. ])

LLCATS: LINF GRAD

calc_grad_at_patch(grid, elevs='topographic__elevation', ignore_closed_nodes=True, unit_normal=None, slope_magnitude=None)[source]

Calculate the components of the gradient at each patch.

If ignore_closed_nodes is True, closed nodes do not affect gradient calculations. If a closed node is present in a patch, the patch gradient is set to zero in both x and y directions.

Parameters:

grid : ModelGrid

A ModelGrid.

elevs : str or ndarray, optional

Field name or array of node values.

ignore_closed_nodes : bool

If True, do not incorporate values at closed nodes into the calc.

unit_normal : array with shape (num_patches, 3) (optional)

The unit normal vector to each patch, if already known.

slope_magnitude : array with size num_patches (optional)

The slope of each patch, if already known.

Returns:

gradient_tuple : (x_component_at_patch, y_component_at_patch)

Len-2 tuple of arrays giving components of gradient in the x and y directions, in the units of units.

Examples

>>> import numpy as np
>>> from landlab import RasterModelGrid
>>> mg = RasterModelGrid((4, 5))
>>> z = mg.node_y
>>> (x_grad, y_grad) = mg.calc_grad_at_patch(elevs=z)
>>> np.allclose(y_grad, np.pi / 4.)
True
>>> np.allclose(x_grad, 0.)
True

LLCATS: PINF GRAD

Calculate gradients at active links.

Note

This method is deprecated as of Landlab version 1.0beta.

Use calc_grad_at_link() instead.

Examples

>>> import numpy as np
>>> from landlab import RasterModelGrid
>>> grid = RasterModelGrid((3, 4))
>>> z = np.array([0., 0., 0., 0.,
...               1., 1., 1., 1.,
...               3., 3., 3., 3.])
>>> grid.calc_grad_of_active_link(z)
array([ 1.,  1.,  0.,  0.,  0.,  2.,  2.])

This method is deprecated. Instead, use calc_grad_at_link.

>>> vals = grid.calc_grad_at_link(z)
>>> vals[grid.active_links]
array([ 1.,  1.,  0.,  0.,  0.,  2.,  2.])

LLCATS: DEPR

calc_slope_at_node(grid, elevs='topographic__elevation', method='patch_mean', ignore_closed_nodes=True, return_components=False, **kwds)[source]

Array of slopes at nodes, averaged over neighboring patches.

Produces a value for node slope (i.e., mean gradient magnitude) at each node in a manner analogous to a GIS-style slope map. It averages the gradient on each of the patches surrounding the node, creating a value for node slope that better incorporates nonlocal elevation information. Directional information can still be returned through use of the return_components keyword.

Note that under these definitions, it is not always true that:

mag, cmp = mg.calc_slope_at_node(z)
mag ** 2 == cmp[0] ** 2 + cmp[1] ** 2  # not always true

If ignore_closed_nodes is False, all proximal elevation values will be used in the calculation. If True, only unclosed nodes are used.

Parameters:

grid : ModelGrid

A ModelGrid.

elevs : str or ndarray, optional

Field name or array of node values.

method : {‘patch_mean’, ‘Horn’}

By equivalence to the raster version, ‘patch_mean’ returns a scalar mean on the patches; ‘Horn’ returns a vector mean on the patches.

ignore_closed_nodes : bool

If True, do not incorporate values at closed nodes into the calc.

return_components : bool

If True, return a tuple, (array_of_magnitude, (array_of_slope_x_radians, array_of_slope_y_radians)). If false, return an array of floats of the slope magnitude.

Returns:

float array or length-2 tuple of float arrays

If return_components, returns (array_of_magnitude, (array_of_slope_x_radians, array_of_slope_y_radians)). If not return_components, returns an array of slope magnitudes.

Examples

>>> import numpy as np
>>> from landlab import RadialModelGrid, RasterModelGrid
>>> mg = RasterModelGrid((4, 5), 1.)
>>> z = mg.node_x
>>> slopes = mg.calc_slope_at_node(elevs=z)
>>> np.allclose(slopes, 45. / 180. * np.pi)
True
>>> mg = RasterModelGrid((4, 5), 1.)
>>> z = - mg.node_y
>>> slope_mag, cmp = mg.calc_slope_at_node(elevs=z,
...                                        return_components=True)
>>> np.allclose(slope_mag, np.pi / 4.)
True
>>> np.allclose(cmp[0], 0.)
True
>>> np.allclose(cmp[1], - np.pi / 4.)
True
>>> mg = RadialModelGrid(num_shells=9)
>>> z = mg.radius_at_node
>>> slopes = mg.calc_slope_at_node(elevs=z)
>>> mean_ring_slope = []
>>> for i in range(10):
...     mean_ring_slope.append(
...         slopes[np.isclose(mg.radius_at_node, i)].mean())

Notice the small amounts of numerical error here:

>>> target_mean_ring_slope = [0.85707194785013108, 0.79363155567711452,
...                           0.77922185867135429, 0.78359813570962411,
...                           0.78433070957439543, 0.78452745144699965,
...                           0.78477643475446901, 0.78506472422668094,
...                           0.78505793680521629, 0.78661256633611021]
>>> np.allclose(mean_ring_slope, target_mean_ring_slope)
True

LLCATS: NINF GRAD SURF

calc_slope_at_patch(grid, elevs='topographic__elevation', ignore_closed_nodes=True, unit_normal=None)[source]

Calculate the slope (positive magnitude of gradient) at patches.

If ignore_closed_nodes is True, closed nodes do not affect slope calculations. If a closed node is present in a patch, the patch slope is set to zero.

Parameters:

grid : ModelGrid

A ModelGrid.

elevs : str or ndarray, optional

Field name or array of node values.

ignore_closed_nodes : bool

If True, do not incorporate values at closed nodes into the calc.

unit_normal : array with shape (num_patches, 3) (optional)

The unit normal vector to each patch, if already known.

Returns:

slopes_at_patch : n_patches-long array

The slope (positive gradient magnitude) of each patch.

Examples

>>> import numpy as np
>>> from landlab import RasterModelGrid
>>> mg = RasterModelGrid((4, 5))
>>> z = mg.node_x
>>> S = mg.calc_slope_at_patch(elevs=z)
>>> S.size == mg.number_of_patches
True
>>> np.allclose(S, np.pi / 4.)
True

LLCATS: PINF GRAD

calc_unit_normal_at_patch(grid, elevs='topographic__elevation')[source]

Calculate and return the unit normal vector <a, b, c> to a patch.

Parameters:

grid : ModelGrid

A ModelGrid.

elevs : str or ndarray, optional

Field name or array of node values.

Returns:

nhat : num-patches x length-3 array

The unit normal vector <a, b, c> to each patch.

Examples

>>> from landlab import HexModelGrid
>>> mg = HexModelGrid(3, 3)
>>> z = mg.node_x * 3. / 4.
>>> mg.calc_unit_normal_at_patch(z)
array([[-0.6,  0. ,  0.8],
       [-0.6,  0. ,  0.8],
       [-0.6,  0. ,  0.8],
       [-0.6,  0. ,  0.8],
       [-0.6,  0. ,  0.8],
       [-0.6,  0. ,  0.8],
       [-0.6,  0. ,  0.8],
       [-0.6,  0. ,  0.8],
       [-0.6,  0. ,  0.8],
       [-0.6,  0. ,  0.8]])

LLCATS: PINF GRAD

Calculate differences of node values over active links.

Note

This method is deprecated as of Landlab version 1.0beta.

Use calc_diff_at_link() instead.

Calculates the difference in quantity node_values at each active link in the grid.

Construction:

calculate_diff_at_active_links(grid, node_values, out=None)
Parameters:

grid : ModelGrid

A ModelGrid.

node_values : ndarray or field name

Values at grid nodes.

out : ndarray, optional

Buffer to hold the result.

Returns:

ndarray

Differences across active links.

LLCATS: DEPR LINF GRAD

Calculate differences of node values over links.

Note

This method is deprecated as of Landlab version 1.0beta.

Use calc_diff_at_link() instead.

Examples

>>> import numpy as np
>>> from landlab import RasterModelGrid
>>> grid = RasterModelGrid((3, 3))
>>> z = np.zeros(9)
>>> z[4] = 1.
>>> grid.calculate_diff_at_links(z)
array([ 0.,  0.,  0.,  1.,  0.,  1., -1.,  0., -1.,  0.,  0.,  0.])
>>> grid.calc_diff_at_link(z)
array([ 0.,  0.,  0.,  1.,  0.,  1., -1.,  0., -1.,  0.,  0.,  0.])

LLCATS: DEPR LINF GRAD

calculate_gradients_at_faces(*args, **kwargs)[source]

Calculate gradients of node values over faces.

Note

This method is deprecated as of Landlab version 1.0beta.

Use calc_grad_at_link() instead.

Calculate and return gradient in node_values at each face in the grid. Gradients are calculated from the nodes at either end of the link that crosses each face.

Construction:

calculate_gradients_at_faces(grid, node_values, out=None)
Parameters:

grid : ModelGrid

A ModelGrid.

node_values : ndarray or field name

Values at grid nodes.

out : ndarray, optional

Buffer to hold the result.

Returns:

ndarray (x number of faces)

Gradients across faces.

Examples

>>> from landlab import RasterModelGrid
>>> rg = RasterModelGrid(3, 4, 10.0)
>>> z = rg.add_zeros('node', 'topographic__elevation')
>>> z[5] = 50.0
>>> z[6] = 36.0
>>> calculate_gradients_at_faces(rg, z)  # there are 7 faces
array([ 5. ,  3.6,  5. , -1.4, -3.6, -5. , -3.6])
>>> from landlab import HexModelGrid
>>> hg = HexModelGrid(3, 3, 10.0)
>>> z = hg.add_zeros('node', 'topographic__elevation', noclobber=False)
>>> z[4] = 50.0
>>> z[5] = 36.0
>>> calculate_gradients_at_faces(hg, z)  # there are 11 faces
array([ 5. ,  5. ,  3.6,  3.6,  5. , -1.4, -3.6, -5. , -5. , -3.6, -3.6])

LLCATS: DEPR GRAD