landlab.components.concentration_tracker.concentration_tracker_for_diffusion

Created on Wed May 31 11:41:20 2023

@author: LaurentRoberge

class ConcentrationTrackerForDiffusion[source]

Bases: Component

Track the concentration of any user-defined property.

This component tracks the concentration of any user-defined property of sediment using a mass balance approach in which the concentration \(C\) is calculated as:

\[∂CH / ∂t = [-(∂q_x C_x) / ∂x - (∂q_y C_y) / ∂y] + C_br * H_brw\]

where \(H\) is sediment depth, \(q_x\) and \(q_y\) are sediment fluxed in the x and y directions, \(C_br\) is concentration in parent bedrock, and \(H_brw\) is the height of bedrock weathered into soil.

Note

This component requires a soil flux field calculated by a hillslope diffusion component. This component is implemented by applying a start_tracking method immediately before every diffusion step and a stop_tracking method immediately after every diffusion step. These methods are applied instead of the typical run_one_step method. See the docstring examples below.

Currently, this component will only work if coupled with the DepthDependentDiffuser or the DepthDependentTaylorDiffuser (without the dynamic timestep option).

Examples

A 1-D hillslope:

>>> import numpy as np
>>> from landlab import NodeStatus, RasterModelGrid
>>> from landlab.components import DepthDependentDiffuser
>>> from landlab.components import ConcentrationTrackerForDiffusion
>>> mg = RasterModelGrid((3, 5), xy_spacing=2.0)
>>> mg.set_status_at_node_on_edges(
...     right=NodeStatus.CLOSED,
...     top=NodeStatus.CLOSED,
...     left=NodeStatus.CLOSED,
...     bottom=NodeStatus.CLOSED,
... )
>>> mg.status_at_node[5] = NodeStatus.FIXED_VALUE
>>> mg.status_at_node.reshape(mg.shape)
array([[4, 4, 4, 4, 4],
       [1, 0, 0, 0, 4],
       [4, 4, 4, 4, 4]], dtype=uint8)
>>> mg.at_node["sediment_property__concentration"] = [
...     [0.0, 0.0, 0.0, 0.0, 0.0],
...     [0.0, 0.0, 0.0, 1.0, 0.0],
...     [0.0, 0.0, 0.0, 0.0, 0.0],
... ]
>>> mg.at_node["soil__depth"] = mg.node_x.copy()
>>> mg.at_node["bedrock__elevation"] = mg.node_x.copy()
>>> mg.at_node["topographic__elevation"] = (
...     mg.at_node["soil__depth"] + mg.at_node["bedrock__elevation"]
... )
>>> _ = mg.add_zeros("soil_production__rate", at="node")
>>> ddd = DepthDependentDiffuser(mg)
>>> ct = ConcentrationTrackerForDiffusion(mg)
>>> ct.start_tracking()
>>> ddd.run_one_step(1.0)
>>> ct.stop_tracking(1.0)
>>> mg.at_node["topographic__elevation"].reshape(mg.shape)
array([[ 0. ,  4.        ,  8.        , 12.        , 16. ],
       [ 0. ,  4.11701964,  8.01583689, 11.00247875, 16. ],
       [ 0. ,  4.        ,  8.        , 12.        , 16. ]])
>>> mg.at_node["sediment_property__concentration"].reshape(mg.shape)
array([[0. , 0. , 0.        , 0. , 0. ],
       [0. , 0. , 0.24839685, 1. , 0. ],
       [0. , 0. , 0.        , 0. , 0. ]])

Now, a 2-D pyramid-shaped hillslope.

>>> mg = RasterModelGrid((5, 5), xy_spacing=2.0)
>>> mg.at_node["sediment_property__concentration"] = [
...     [0.0, 0.0, 0.0, 0.0, 0.0],
...     [0.0, 0.0, 0.0, 0.0, 0.0],
...     [0.0, 0.0, 1.0, 0.0, 0.0],
... ]
>>> h = mg.add_full("soil__depth", 2.0, at="node")
>>> z_br = mg.add_field(
...     "bedrock__elevation",
...     8.0 - abs(4.0 - mg.node_x) - abs(4.0 - mg.node_y),
...     at="node",
... )
>>> z = mg.add_field("topographic__elevation", z_br + h, at="node")
>>> _ = mg.add_zeros("soil_production__rate", at="node")
>>> ddd = DepthDependentDiffuser(mg)
>>> ct = ConcentrationTrackerForDiffusion(mg)
>>> ct.start_tracking()
>>> ddd.run_one_step(1.0)
>>> ct.stop_tracking(1.0)
>>> mg.at_node["topographic__elevation"][mg.core_nodes].reshape((3, 3))
array([[6. ,        7.13533528, 6. ],
       [7.13533528, 8.27067057, 7.13533528],
       [6. ,        7.13533528, 6. ]])
>>> mg.at_node["sediment_property__concentration"][mg.core_nodes].reshape((3, 3))
array([[0.        , 0.38079708, 0. ],
       [0.38079708, 1.        , 0.38079708],
       [0.        , 0.38079708, 0. ]])

And running one more step.

>>> ct.start_tracking()
>>> ddd.run_one_step(1.0)
>>> ct.stop_tracking(1.0)
>>> mg.at_node["topographic__elevation"][mg.core_nodes].reshape((3, 3))
array([[5.52060315, 6.62473963, 5.52060315],
       [6.62473963, 8.00144598, 6.62473963],
       [5.52060315, 6.62473963, 5.52060315]])
>>> mg.at_node["sediment_property__concentration"][mg.core_nodes].reshape((3, 3))
array([[0.09648071, 0.44750673, 0.09648071],
       [0.44750673, 1.        , 0.44750673],
       [0.09648071, 0.44750673, 0.09648071]])

Finally, the same 2D hillslope now using the DepthDependentTaylorDiffuser. Note that the timestep must be smaller than 1 to maintain stability in the diffusion calculation. Typically, one could use the dynamic timestepping option. However, here it will provide incorrect soil flux values to the ConcentrationTrackerForDiffusion, which cannot do sub-timestep calculations. Use the if_unstable="warn" flag when instantiating the Taylor diffuser and pick a timestep that is stable.

>>> from landlab.components import DepthDependentTaylorDiffuser
>>> mg = RasterModelGrid((5, 5), xy_spacing=2.0)
>>> mg.at_node["sediment_property__concentration"] = [
...     [0.0, 0.0, 0.0, 0.0, 0.0],
...     [0.0, 0.0, 0.0, 0.0, 0.0],
...     [0.0, 0.0, 1.0, 0.0, 0.0],
... ]
>>> h = mg.add_full("soil__depth", 2.0, at="node")
>>> z_br = mg.add_field(
...     "bedrock__elevation",
...     8.0 - abs(4.0 - mg.node_x) - abs(4.0 - mg.node_y),
...     at="node",
... )
>>> z = mg.add_field("topographic__elevation", z_br + h, at="node")
>>> _ = mg.add_zeros("soil_production__rate", at="node")
>>> ddtd = DepthDependentTaylorDiffuser(mg, if_unstable="warn")
>>> ct = ConcentrationTrackerForDiffusion(mg)
>>> ct.start_tracking()
>>> ddtd.run_one_step(0.4)
>>> ct.stop_tracking(0.4)
>>> mg.at_node["topographic__elevation"][mg.core_nodes].reshape((3, 3))
array([[6.        , 7.30826823, 6.        ],
       [7.30826823, 8.61653645, 7.30826823],
       [6.        , 7.30826823, 6.        ]])
>>> mg.at_node["sediment_property__concentration"][mg.core_nodes].reshape((3, 3))
array([[0.        , 0.26436925, 0.        ],
       [0.26436925, 1.        , 0.26436925],
       [0.        , 0.26436925, 0.        ]])
Parameters:
  • grid (ModelGrid) – Landlab ModelGrid object

  • concentration_initial (float, array, or str, optional) – Initial concentration in soil/sediment as either a scalar, array, or the name of an existing node field, -/m^3.

  • concentration_in_bedrock (float, array, or str, optional) – Concentration in bedrock as either a scalar, array, or the name of an existing node field, -/m^3.

  • concentration_from_weathering (float or array, optional) – Concentration generated during the weathering process, -/m^3. Defaults to None, which causes all weathered bedrock to retain its original parent material concentration (concentration_in_bedrock) as it weathers to soil. Use this parameter to differentiate between the concentration in weathered material compared to its parent bedrock.

__init__(grid, concentration_initial=0, concentration_in_bedrock=0, concentration_from_weathering=None)[source]
Parameters:
  • grid (ModelGrid) – Landlab ModelGrid object

  • concentration_initial (float, array, or str, optional) – Initial concentration in soil/sediment as either a scalar, array, or the name of an existing node field, -/m^3.

  • concentration_in_bedrock (float, array, or str, optional) – Concentration in bedrock as either a scalar, array, or the name of an existing node field, -/m^3.

  • concentration_from_weathering (float or array, optional) – Concentration generated during the weathering process, -/m^3. Defaults to None, which causes all weathered bedrock to retain its original parent material concentration (concentration_in_bedrock) as it weathers to soil. Use this parameter to differentiate between the concentration in weathered material compared to its parent bedrock.

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

Concentration in bedrock (kg/m^3).

property conc_init

Initial concentration in soil/sediment (kg/m^3).

property conc_w

Concentration from the weathering process (kg/m^3).

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 = (('bedrock_property__concentration', 'Mass concentration of property per unit volume of bedrock'), ('sediment_property__concentration', 'Mass concentration of property per unit volume of sediment'), ('soil__depth', 'Depth of soil or weathered bedrock'), ('soil__flux', 'flux of soil in direction of link'), ('soil_production__rate', 'rate of soil production at nodes'), ('topographic__elevation', 'Land surface topographic elevation'))
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 = ('soil__depth', 'soil__flux', 'soil_production__rate', 'topographic__elevation')
name = 'ConcentrationTrackerForDiffusion'
optional_var_names = ()
output_var_names = ('bedrock_property__concentration', 'sediment_property__concentration')
run_one_step()[source]

run_one_step is not implemented for this component.

property shape

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

start_tracking()[source]

Stores values necessary for calculating changes in concentration. This method must be called prior to running the sediment flux component that changes physical properties of bedrock, soil, and/or topography.

stop_tracking(dt)[source]

Calculate changes in concentration that have occurred in the timestep since tracking was started. This method must be called after running the sediment flux component that changes physical properties of bedrock, soil, and/or topography.

Parameters:

dt (float (time)) – The imposed timestep.

unit_agnostic = True
units = (('bedrock_property__concentration', '-/m^3'), ('sediment_property__concentration', '-/m^3'), ('soil__depth', 'm'), ('soil__flux', 'm^2/yr'), ('soil_production__rate', 'm/yr'), ('topographic__elevation', 'm'))
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 = (('bedrock_property__concentration', 'node'), ('sediment_property__concentration', 'node'), ('soil__depth', 'node'), ('soil__flux', 'link'), ('soil_production__rate', 'node'), ('topographic__elevation', '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