landlab.components.geoenthalpy_delta.geoenthalpy_delta

Landlab component for 2D enthalpy-based sediment diffusion transport.

This version, v1.0, only deals with a fixed basement. A future version will account for an input (erodible) topography.

class GeoEnthalpyDelta[source]

Bases: Component

Simulate 2D sediment diffusion, transport, and deposition using an enthalpy formulation of a topset/foreset delta model.

This component is a structured Landlab wrapper around the core physics of a manuscript on 2D GeoEnthalpy-Delta modeling.

Sediment is supplied at every node according to the sediment__influx field (a per-node volumetric rate mixed into the local sediment thickness before transport, each substep) and is transported as a nonlinear, slope-threshold diffusive flux. At every node the transport diffusivity and slope threshold depend on whether that node is a “topset” (subaerial or shallow, eta >= Z) or “foreset” (below sea level, eta < Z) node, where eta is the land surface elevation and Z is the (possibly time varying) sea level.

The land surface elevation eta (topographic__elevation) is the sum of a non-erodible basement elevation eta_b and a mobile sediment thickness H: eta = eta_b + H. Neither the basement nor the sediment thickness is a field; the thickness is tracked internally (see sediment_thickness to read it) and the basement is re-derived, at the start of every run_one_step call, as topographic__elevation - sediment_thickness. Because topographic__elevation is the only mutable field this component exposes, another component can’t corrupt the tracked thickness by writing to a shared grid field; it can only shift the elevation, which this component then reinterprets as a change in basement on its next step.

Lateral (grid-y) fluxes between neighboring nodes are calculated first, limited so that no node can lose more sediment than it holds. Downstream (grid-x) fluxes are then calculated node-by-node from west to east, accounting for the upstream flux and the (already limited) net lateral flux, which guarantees a non-negative thickness update everywhere without an iterative solve.

Because the transport scheme distinguishes an upstream (grid-x) and a cross-stream (grid-y) direction and assumes a uniform, structured grid, this component requires a RasterModelGrid.

Every node, including those on the grid’s perimeter, is part of the active transport domain, so run_one_step requires every node to have status BC_NODE_IS_CORE and raises a ValueError otherwise, since this component would otherwise silently compute transport on nodes the grid says are fixed, closed, or looped. No flux crosses the grid’s outer edges: sediment can only enter through sediment__influx and never leaves the domain.

Examples

>>> import numpy as np
>>> from landlab import RasterModelGrid
>>> from landlab.components import GeoEnthalpyDelta
>>> nrows, ncols = 50, 50
>>> dx = dy = 0.2
>>> grid = RasterModelGrid((nrows, ncols), xy_spacing=dx)
>>> grid.status_at_node[:] = grid.BC_NODE_IS_CORE
>>> x = grid.x_of_node.reshape(grid.shape)
>>> x[0, 1], x[0, -1]
(0.2, 9.8)
>>> topo = grid.add_zeros("topographic__elevation", at="node")
>>> topo[:] = (-x).reshape(-1)  # planar surface, e.g. from a DEM
>>> topo.min(), topo.max()
(-9.8, -0.0)
>>> sea_level = grid.add_field("sea_level__elevation", -5.0, at="grid")
>>> influx = grid.add_zeros("sediment__influx", at="node")
>>> influx.reshape(grid.shape)[20:25, 0] = 0.1  # feeder on the west edge
>>> component = GeoEnthalpyDelta(
...     grid,
...     topset_threshold=(0.1, 0.1),
...     foreset_threshold=(2.0, 2.0),
...     topset_diffusivity=(1.0, 1.0),
...     foreset_diffusivity=(1.0, 1.0),
... )
>>> nsteps = 50
>>> for _ in range(nsteps):
...     component.run_one_step()  # dt chosen automatically for CFL stability
...     sea_level += 0.1  # sea level rises by 0.1/step, set externally
...
>>> model_volume = np.sum(component.sediment_thickness) * grid.dx * grid.dy
>>> expected_volume = np.sum(influx) * component.time_elapsed
>>> np.isclose(model_volume, expected_volume, rtol=1e-6)
True

References

Required Software Citation(s) Specific to this Component

Lorenzo-Trueba, J., Anderson, W., Bui, V., and Voller, V. R.: GeoEnthalpy-Delta v1.0: an enthalpy-based model for coupled subaerial and subaqueous delta evolution with diagnostic moving boundaries, manuscript in preparation for Geoscientific Model Development.

Additional References

https://github.com/GeoJorge/GeoEnthalpy-Delta/

Initialize the GeoEnthalpyDelta component.

topographic__elevation, sea_level__elevation, and sediment__influx must already exist on the grid before this component is constructed. The component has no basement__elevation or sediment__thickness field: instead, it tracks the mobile sediment thickness internally (see sediment_thickness) and re-derives the basement, at the start of every run_one_step call, as topographic__elevation - sediment_thickness. This means the initial topographic__elevation you supply (e.g. from a DEM) should already include any sediment thickness you pass in via sediment_thickness.

This component transports sediment at every node, including the grid’s perimeter. Every call to run_one_step requires every node to have status BC_NODE_IS_CORE (grid.status_at_node[:] = grid.BC_NODE_IS_CORE on a default grid) and raises ValueError otherwise; boundary conditions are checked there rather than here, since they may not be finalized yet at construction time and can change between calls.

Sea level and sediment supply are both external forcing:

  • Sea level: read and, if it varies with time, update it yourself via the sea_level property (or grid.at_grid directly) between calls to run_one_step.

  • Sediment supply: set sediment__influx values (volume per time) at any node(s) before construction; a value at a given node is mixed into that node’s sediment thickness before transport each substep. A west-edge feeder is just the special case of setting influx only on the grid’s west (minimum-x) column. Must be non-negative and finite. Update the field yourself between calls to run_one_step for a time-varying or nonuniform supply.

Parameters:
  • grid (RasterModelGrid)

  • sediment_thickness (float or array_like, optional) – Initial sediment thickness at each node. A scalar applies everywhere. Must be non-negative.

  • topset_threshold (float or (float, float), optional) – Critical slope thresholds, in the grid-x and grid-y directions respectively, above which topset (subaerial) transport occurs. A scalar applies to both directions. Must be non-negative.

  • foreset_threshold (float or (float, float), optional) – Critical slope thresholds, in the grid-x and grid-y directions respectively, above which foreset (subaqueous) transport occurs. A scalar applies to both directions. Must be non-negative.

  • topset_diffusivity (float or (float, float), optional) – Diffusivities for topset transport, in the grid-x and grid-y directions respectively. A scalar applies to both directions. Must be positive.

  • foreset_diffusivity (float or (float, float), optional) – Diffusivities for foreset transport, in the grid-x and grid-y directions respectively. A scalar applies to both directions. Must be positive.

  • cfl (float, optional) – Courant-Friedrichs-Lewy stability factor used to pick a stable time step automatically in run_one_step. Must be in the interval (0, 1].

__init__(grid, sediment_thickness=0.0, topset_threshold=0.0, foreset_threshold=2.0, topset_diffusivity=1.0, foreset_diffusivity=1.0, cfl=0.4)[source]

Initialize the GeoEnthalpyDelta component.

topographic__elevation, sea_level__elevation, and sediment__influx must already exist on the grid before this component is constructed. The component has no basement__elevation or sediment__thickness field: instead, it tracks the mobile sediment thickness internally (see sediment_thickness) and re-derives the basement, at the start of every run_one_step call, as topographic__elevation - sediment_thickness. This means the initial topographic__elevation you supply (e.g. from a DEM) should already include any sediment thickness you pass in via sediment_thickness.

This component transports sediment at every node, including the grid’s perimeter. Every call to run_one_step requires every node to have status BC_NODE_IS_CORE (grid.status_at_node[:] = grid.BC_NODE_IS_CORE on a default grid) and raises ValueError otherwise; boundary conditions are checked there rather than here, since they may not be finalized yet at construction time and can change between calls.

Sea level and sediment supply are both external forcing:

  • Sea level: read and, if it varies with time, update it yourself via the sea_level property (or grid.at_grid directly) between calls to run_one_step.

  • Sediment supply: set sediment__influx values (volume per time) at any node(s) before construction; a value at a given node is mixed into that node’s sediment thickness before transport each substep. A west-edge feeder is just the special case of setting influx only on the grid’s west (minimum-x) column. Must be non-negative and finite. Update the field yourself between calls to run_one_step for a time-varying or nonuniform supply.

Parameters:
  • grid (RasterModelGrid)

  • sediment_thickness (float or array_like, optional) – Initial sediment thickness at each node. A scalar applies everywhere. Must be non-negative.

  • topset_threshold (float or (float, float), optional) – Critical slope thresholds, in the grid-x and grid-y directions respectively, above which topset (subaerial) transport occurs. A scalar applies to both directions. Must be non-negative.

  • foreset_threshold (float or (float, float), optional) – Critical slope thresholds, in the grid-x and grid-y directions respectively, above which foreset (subaqueous) transport occurs. A scalar applies to both directions. Must be non-negative.

  • topset_diffusivity (float or (float, float), optional) – Diffusivities for topset transport, in the grid-x and grid-y directions respectively. A scalar applies to both directions. Must be positive.

  • foreset_diffusivity (float or (float, float), optional) – Diffusivities for foreset transport, in the grid-x and grid-y directions respectively. A scalar applies to both directions. Must be positive.

  • cfl (float, optional) – Courant-Friedrichs-Lewy stability factor used to pick a stable time step automatically in run_one_step. Must be in the interval (0, 1].

static __new__(cls, *args, **kwds)
cite_as = ''
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 = (('sea_level__elevation', 'Sea level elevation'), ('sediment__influx', 'Sediment flux (volume per unit time of sediment entering each node)'), ('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 accomplish this task.

input_var_names = ('sea_level__elevation', 'sediment__influx', 'topographic__elevation')
name = 'GeoEnthalpyDelta'
optional_var_names = ()
output_var_names = ('topographic__elevation',)
run_one_step(dt=None)[source]

Advance the sediment diffusion model by a time step dt.

Internally, dt is divided into one or more substeps that satisfy the CFL stability criterion (see _calc_stable_time_step), so any dt produces a numerically stable result without the caller having to manage substepping.

Parameters:

dt (float, optional) – Time step duration. If not given, a single CFL-stable substep is taken. Must be positive and finite.

property sea_level

Sea level elevation, read from the sea_level__elevation grid field.

This is external forcing owned by the caller: update grid.at_grid["sea_level__elevation"] directly between calls to run_one_step if you want sea level to vary with time.

property sediment_thickness

Thickness of the mobile sediment deposit at each node.

Tracked internally rather than as a field, so it can’t be corrupted by another component writing to a shared grid field.

property shape

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

property time_elapsed

Cumulative model time advanced by run_one_step.

unit_agnostic = True
units = (('sea_level__elevation', '-'), ('sediment__influx', '-'), ('topographic__elevation', '-'))
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 = (('sea_level__elevation', 'grid'), ('sediment__influx', '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