Synthetic field values#

synthetic.py provides functions to add synthetic values to a model grid.

Values can be added to any valid grid element (e.g. link or node). If no field exists, a field of float zeros will be initialized.

All functions add values to the field—this means that multiple functions can be chained together.

All functions support adding values to only portions of the grid, based on the status_at_link and status_at_node attributes.

For example, if one wanted to construct an initial topographic elevation represented by a tetrahedron and add normally distributed noise only to core nodes, this could be acomplished as follows:

Examples

>>> import numpy as np
>>> from landlab import NodeStatus, RasterModelGrid
>>> from landlab.values import random, plane
>>> np.random.seed(42)

Create the grid.

>>> mg = RasterModelGrid((7, 7))

Create a tetrahedron by adding planes selectively using where.

>>> southwest = plane(
...     mg,
...     "topographic__elevation",
...     where=((mg.x_of_node <= 3) & (mg.y_of_node <= 3)),
...     point=(0, 0, 0),
...     normal=(-1, -1, 1),
... )
>>> southeast = plane(
...     mg,
...     "topographic__elevation",
...     where=((mg.x_of_node > 3) & (mg.y_of_node <= 3)),
...     point=(6, 0, 0),
...     normal=(1, -1, 1),
... )
>>> northeast = plane(
...     mg,
...     "topographic__elevation",
...     where=((mg.x_of_node > 3) & (mg.y_of_node > 3)),
...     point=(6, 6, 0),
...     normal=(1, 1, 1),
... )
>>> northwest = plane(
...     mg,
...     "topographic__elevation",
...     where=((mg.x_of_node <= 3) & (mg.y_of_node > 3)),
...     point=(0, 6, 0),
...     normal=(-1, 1, 1),
... )
>>> mg.at_node["topographic__elevation"]
array([ 0.,  1.,  2.,  3.,  2.,  1.,  0.,
        1.,  2.,  3.,  4.,  3.,  2.,  1.,
        2.,  3.,  4.,  5.,  4.,  3.,  2.,
        3.,  4.,  5.,  6.,  5.,  4.,  3.,
        2.,  3.,  4.,  5.,  4.,  3.,  2.,
        1.,  2.,  3.,  4., 3.,   2.,  1.,
        0.,  1.,  2.,  3.,  2.,  1.,  0.])

Next add uniformly distributed noise.

>>> noise = random(
...     mg, "topographic__elevation", where=NodeStatus.CORE, distribution="uniform"
... )
>>> np.round(mg.at_node["topographic__elevation"], decimals=3)
array([ 0.   ,  1.   ,  2.   ,  3.   ,  2.   ,  1.   ,  0.   ,
        1.   ,  2.375,  3.951,  4.732,  3.599,  2.156,  1.   ,
        2.   ,  3.156,  4.058,  5.866,  4.601,  3.708,  2.   ,
        3.   ,  4.021,  5.97 ,  6.832,  5.212,  4.182,  3.   ,
        2.   ,  3.183,  4.304,  5.525,  4.432,  3.291,  2.   ,
        1.   ,  2.612,  3.139,  4.292,  3.366,  2.456,  1.   ,
        0.   ,  1.   ,  2.   ,  3.   ,  2.   ,  1.   ,  0.   ])

At present only a small selection of possible synthetic functions exist. If your research requires additional functions, consider contributing one back to the main landlab repository. If you have questions on how to proceed, please create a GitHub issue.

All public functions from this submodule should have a common format. They take as the first two arguments a model grid, and the name of the field. They all take two keyword arguments: at, which specifies which grid element values are placed, and where, which indicates where the values are placed. Additional keyword arguments are required as needed by each function.

constant(grid, name, at='node', where=None, value=0.0, dtype=None)[source]#

Add a constant to a grid.

Parameters:
  • grid (ModelGrid) –

  • name (str) – Name of the field.

  • at (str, optional) – Grid location to store values. If not given, values are assumed to be on node.

  • where (optional) – The keyword where indicates where synthetic values should be placed. It is either (1) a single value or list of values indicating a grid-element status (e.g. NodeStatus.CORE), or (2) a (number-of-grid-element,) sized boolean array.

  • value (float, optional) – Constant value to add to the grid. Default is 0.

  • dtype (str, optional) – The type of the newly created field. If not provided, the type will be determined based on the type of value.

Returns:

values – Array of the values added to the field.

Return type:

array

Examples

>>> from landlab import RasterModelGrid
>>> from landlab.values import constant
>>> mg = RasterModelGrid((4, 4))
>>> values = constant(mg, "some_flux", "link", where="ACTIVE_LINK", value=10.0)
>>> mg.at_link["some_flux"]
array([  0.,   0.,   0.,   0.,  10.,  10.,   0.,  10.,  10.,  10.,   0.,
        10.,  10.,   0.,  10.,  10.,  10.,   0.,  10.,  10.,   0.,   0.,
         0.,   0.])
plane(grid, name, at='node', where=None, point=(0.0, 0.0, 0), normal=(0.0, 0.0, 1.0))[source]#

Add a single plane defined by a point and a normal to a grid.

Parameters:
  • grid (ModelGrid) –

  • name (str) – Name of the field.

  • at (str, optional) – Grid location to store values. If not given, values are assumed to be on node.

  • where (optional) – The keyword where indicates where synthetic values should be placed. It is either (1) a single value or list of values indicating a grid-element status (e.g. NodeStatus.CORE), or (2) a (number-of-grid-element,) sized boolean array.

  • point (tuple, optional) – A tuple defining a point the plane goes through in the format (x, y, z). Default is (0., 0., 0.)

  • normal (tuple, optional) – A tuple defining the normal to the plane in the format (dx, dy, dz). Must not be verticaly oriented. Default is a horizontal plane (0., 0., 1.).

Returns:

values – Array of the values added to the field.

Return type:

array

Examples

>>> from landlab import RasterModelGrid
>>> from landlab.values import plane
>>> mg = RasterModelGrid((4, 4))
>>> values = plane(
...     mg, "soil__depth", "node", point=(0.0, 0.0, 0.0), normal=(-1.0, -1.0, 1.0)
... )
>>> mg.at_node["soil__depth"]
array([ 0.,  1.,  2.,  3.,
        1.,  2.,  3.,  4.,
        2.,  3.,  4.,  5.,
        3.,  4.,  5.,  6.])
random(grid, name, at='node', where=None, distribution='uniform', **kwargs)[source]#

Add random values to a grid.

This function supports all distributions provided in the numpy.random submodule.

Parameters:
  • grid (ModelGrid) –

  • name (str) – Name of the field.

  • at (str, optional) – Grid location to store values. If not given, values are assumed to be on node.

  • where (optional) – The keyword where indicates where synthetic values should be placed. It is either (1) a single value or list of values indicating a grid-element status (e.g. NodeStatus.CORE), or (2) a (number-of-grid-element,) sized boolean array.

  • distribution (str, optional) – Name of the distribution provided by the np.random submodule.

  • kwargs (dict) – Keyword arguments to pass to the np.random distribution function.

Returns:

values – Array of the values added to the field.

Return type:

array

Examples

>>> import numpy as np
>>> from landlab import RasterModelGrid
>>> from landlab.values import random
>>> np.random.seed(42)
>>> mg = RasterModelGrid((4, 4))
>>> values = random(
...     mg,
...     "soil__depth",
...     "node",
...     where="CORE_NODE",
...     distribution="uniform",
...     high=3.0,
...     low=2.0,
... )
>>> mg.at_node["soil__depth"]
array([ 0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  2.37454012,  2.95071431,  0.        ,
        0.        ,  2.73199394,  2.59865848,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ])
sine(grid, name, at='node', where=None, amplitude=1.0, wavelength=1.0, a=1.0, b=1.0, point=(0.0, 0.0))[source]#

Add a sin wave to a grid.

Add a sine wave \(z\) defined as:

\[\begin{split}z = A * sin ( \\frac{2\pi v}{\lambda} ) v = a(x-x_0) + b(y-y_0)\end{split}\]

where \(A\) is the amplitude and \(\lambda\) is the wavelength. The values \(a\), \(b\), and the point \((x_0, y_0)\) permit the sin wave to be oriented arbitrarily in the x-y plane.

Parameters:
  • grid (ModelGrid) –

  • name (str) – Name of the field.

  • at (str, optional) – Grid location to store values. If not given, values are assumed to be on node.

  • where (optional) – The keyword where indicates where synthetic values should be placed. It is either (1) a single value or list of values indicating a grid-element status (e.g. NodeStatus.CORE), or (2) a (number-of-grid-element,) sized boolean array.

  • amplitude (p) –

  • wavelength

  • a

  • b

  • point

Returns:

values – Array of the values added to the field.

Return type:

array

Examples

>>> from numpy.testing import assert_array_almost_equal
>>> from landlab import RasterModelGrid
>>> from landlab.values import sine
>>> mg = RasterModelGrid((5, 5))
>>> values = sine(mg, "topographic__elevation", amplitude=2, wavelength=4, a=1, b=0)
>>> new_field = mg.at_node["topographic__elevation"].reshape(mg.shape)
>>> truth = np.array(
...     [
...         [0.0, 2.0, 0.0, -2.0, -0.0],
...         [0.0, 2.0, 0.0, -2.0, -0.0],
...         [0.0, 2.0, 0.0, -2.0, -0.0],
...         [0.0, 2.0, 0.0, -2.0, -0.0],
...         [0.0, 2.0, 0.0, -2.0, -0.0],
...     ]
... )
>>> assert_array_almost_equal(new_field, truth)
units(grid, name, at='node', units=None)[source]#

Add units to a field.