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 astop_tracking
method immediately after every diffusion step. These methods are applied instead of the typicalrun_one_step
method. See the docstring examples below.Currently, this component will only work if coupled with the
DepthDependentDiffuser
or theDepthDependentTaylorDiffuser
(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 theConcentrationTrackerForDiffusion
, which cannot do sub-timestep calculations. Use theif_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.
- 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')¶
- 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.
- var_mapping = (('bedrock_property__concentration', 'node'), ('sediment_property__concentration', 'node'), ('soil__depth', 'node'), ('soil__flux', 'link'), ('soil_production__rate', 'node'), ('topographic__elevation', 'node'))¶