Transition from Landlab 0.x to 1.0#
Landlab 1.0beta was introduced May 12, 2016. This new version—the first official stable release—introduces some powerful new capabilities. It also brings some standardization, which means changes to certain function names and ways of doing things. In order to minimize the impact of these changes on your work, we’ve provided here a simple guide to some of the major changes.
Quick summary#
how to make your Landlab programs work with version 1.0beta
Grid element and attribute names#
Old: link_length
New: length_of_link
Old: node_x
, node_y
New: x_of_node
, y_of_node
OR node_x
, node_y
(NOTE: node_x
and node_y
are still supported, but best practice
is now to use x_of_node
and y_of_node
)
Old:cell_area
New:area_of_cell
Old: face_width
New: width_of_face
Common grid functions#
Old: calculate_gradients_at_active_links
,
calculate_gradients_at_links
New: calc_grad_at_link
(input is node-based array or field name;
output is a link-based array [not just active links])
Old: calculate_flux_divergence_at_nodes
New: calc_flux_div_at_node
(input is a link-based array [not
just active links])
New standardized function usage and syntax#
Syntax of grid properties and functions#
Data associated with Landlab grids include:
arrays that contain information about connections among grid elements
arrays that contain numerical attributes
grid functions
Arrays that contain information about how various grid elements now use a naming scheme that looks like this:
<element(s)>_at_<element>
Examples: link_at_face
, node_at_cell
, node_at_link_tail
,
links_at_node
, faces_at_cell
The word before _at_
indicates what is being returned: the IDs of
links, or nodes, or faces, etc. A plural word before _at_
, such as
links_at_node
, indicates that there are multiple values for each
element. For example, there are multiple links connected to every grid
node (in a raster grid, most nodes have four links).
The word(s) after _at_
indicate the dimension of the array returned.
For example, grid.link_at_face
contains an array of the IDs of a
link associated with a face. The array length is equal to the number of
faces. Element 0 contains the ID of the link that crosses face 0, and so
on.
In general, arrays containing a numerical attribute associated with elements, such as the length of links, are named with the pattern:
<attribute>_of_<element>
Examples: length_of_link
, width_of_face
, area_of_cell
Grid functions that return arrays of information have names that hint at
the complexity of the underlying computation. In general, names that
simply describe a property or attribute, such as length_of_link
,
have minimum computational cost. Often they either simply provide an
existing array, or compute the values once but retain them thereafter so
that no further cost is incurred on future calls (though creating the
array may have an extra memory cost). More computationally expensive
functions, such that require one or more multiple floating-point
operations at each grid element, have the prefix calc_
. For example,
calc_grad_at_link
performs a subtraction and division operation at
each grid link.
Gradient and flux divergence functions#
New functionality in Landlab’s built-in gradient and flux-divergence methods include:
1 - The primary gradient-calculation function (for scalar quantities
defined on nodes) is now calc_grad_at_link
. This replaces the
previous functions calculate_gradients_at_active_links
and
calculates_gradients_at_links
.
2 - calc_grad_at_link
returns gradient values at all links, not
just active links. In general, Landlab’s grid functions now only operate
with “complete” sets of grid elements. They will neither accept nor
return partial sets of a given element type (such as active or inactive
links, core or boundary nodes, etc.).
3 - The primary divergence operation function is now
calc_flux_div_at_node
. This replaces
calculate_flux_divergence_at_nodes
. Note that it accepts an array
(or grid field name) with flux values defined on all links (not just
active links). Alternatively, if you provide an array (or grid field
name) with a length equal to the number of cell faces, it assumes that
these represent flux vectors aligned with the links that cross the
faces.
4 - In general, previous function names that began with calculate_
have been shortened to calc_
. Similarly, names involving
_gradient_
are shortened to _grad_
, and those involving
_divergence_
are shortened to _div_
.
3 - Names are singular. For example, calc_grad_at_link
replaces
calculate_gradients_at_links
, even though the function returns a
value for every link.
4 - Landlab now provides a net flux function:
calc_net_flux_at_node
adds up fluxes around the perimeter of each
cell, essentially performing a numerical line integral. Values at
perimeter nodes (which do not have corresponding cells) are either set
to zero, or (if the user passes in an array to hold the result) are left
unchanged. The function calc_net_flux_at_node
is identical to
`calc_flux_div_at_node except that the net flux is not divided by cell
area.
5 - Stay tuned for equivalent functions that calculates the gradient
along faces, and net flux and flux divergence within patches
(with the resulting values tied to corners). These will appear in a
future version, and will be named: calc_grad_at_face
,
calc_net_flux_at_corner
, and calc_flux_div_at_corner
.
For more information and examples about the new grad and div functions, see the entries in the Reference manual for gradient functions and divergence functions.
Changes in Component Usage#
Components are now standardised across Landlab, eliminating the numerous inconsistencies that existed before. This standardisation is as follows:
1 - All component classes can now be imported directly from
landlab.components
, e.g.:
from landlab.components import FlowRouter
2 - All components are now instantiated using the same signature. The first argument is the ModelGrid. Subsequent arguments are the keywords to provide the input parameters needed by the component, and any other flags.
Components no longer take an input file, per se. Rather, in keeping with
the spirit of numpy, the necessary input parameters are passed as
keywords. This has several advantages, including allowing explicit
default values to be present, and clear to the user, and also allowing
dynamic Python objects (e.g., an existing array of values) to be passed
in as arguments. Note however that it is still possible (and indeed
encouraged) to use an input file, but now you will need to turn it into
a Python dictionary before passing it to the component (see below). The
recommended way to do this is with the load_params
function, which
performs typing of arguments automatically and can read a variety of
file types. However, the older ways of using the Landlab
ModelParameterDictionary
will also still work (though are
deprecated).
This construction format will be listed explicitly in the documentation.
Try help(MyComponent)
in an interactive session to see it, or look
it up online.
For the moment, many components are back compatible with the old ways of doing things, but this is deprecated functionality and no longer documented. It may disappear entirely in future releases.
All this means that all of the following are possible ways to instantiate a component:
>>> from landlab.components import FastscapeEroder
>>> from landlab import RasterModelGrid, load_params, ModelParameterDictionary
>>> mg = RasterModelGrid((4, 5), 1.)
>>> sp1 = FastscapeEroder(mg, K_sp=1.e-6) # the minimum information needed, passed by hand, OR
>>> sp2 = FastscapeEroder(mg, K_sp=np.random.rand(20.), m_sp=0.5, n_sp=1.,
... threshold_sp=0., rainfall_intensity=1.) # note the array, OR
>>> myparamdict1 = load_params('my_input_file.txt')
>>> sp3 = FastscapeEroder(mg, **myparamdict1) # note the "**". Necessary args come from the dict, OR
>>> myparamdict2 = ModelParameterDictionary('my_input_file.txt', auto_type=True)
>>> sp4 = FastscapeEroder(mg, **myparamdict2) # ...but it's best practice to use load_params instead
>>> sp5 = FastscapeEroder(mg, 'my_input_file.txt') # still works in many cases, but DEPRECATED
3 - All components now have a “run method” with the standardised name
run_one_step
. The first argument is always the timestep, dt, if
needed by the component. Subsequent arguments may be present as flags to
control run behaviour. As an example:
>>> sp = FastscapeEroder(mg, K_sp=1.e-6)
>>> dt = 1000.
>>> for i in range(100): # 100 ka of erosion
... sp.run_one_step(dt)
The old run methods still exist inside many components, but we encourage migration to this new standardised format.
4 - run_one_step()
never returns anything. There is no need; the
grid object will already have been updated as necessary.
5 - All components should now have comprehensive and up-to-date
documentation. View it on the website, or in an interactive Python
session use either help(MyComponent)
or MyComponent?
.
Standardisation of Component Standard Field Names#
In the interests of internal self consistency and repeatability, the currently in-use component standard field names have been overhauled. This is likely to break quite a bit of code, but a search-and-replace will fix things very fast.
The following represents a (hopefully) almost complete list of the name substitutions:
‘channel_bed_shear_stress’ → ‘channel__bed_shear_stress’
‘channel_depth’ → ‘channel__depth’
‘channel_discharge’ → ‘channel__discharge’
‘channel_width’ → ‘channel__width’
‘drainage_area’ –> We’re keeping it BOOM
‘effective_fluvial_diffusivity’ → field removed
‘elevation’ –> ‘topographic__elevation’
‘flow_receiver’ –> ‘flow__receiver_node’
‘flow_sinks’ –> ‘flow__sink_flag’
‘fluvial_sediment_flux_into_node’ → ‘channel_sediment__volumetric_flux’
‘Fluvial_sediment_transport_capacity’ → ‘channel_sediment__volumetric_transport_capacity’
‘Links_to_flow_receiver’ →flow__link_to_receiver_node’
‘lithosphere__elevation’ –> ‘lithosphere_surface__elevation’
‘lithosphere__elevation_increment’ → ‘lithosphere_surface__elevation_increment’
‘planet_surface_sediment__deposition_increment’ –> ‘sediment__deposition_increment’
‘potentiality_field’ –> ‘flow__potential’
‘relative_sediment_flux’ → ‘channel_sediment__relative_flux’
‘shear_stress’ –> ‘channel__bed_shear_stress’
‘slope_at_nodes’ –> ‘topographic__steepest_slope’ (slope === downhill gradient)
‘stream_power_erosion’ → field removed
‘surface_gradient’ –> ‘topographic__slope’
‘upstream_ID_order’ –> ‘flow__upstream_node_order’
‘Upstream_node_order’ –> ‘flow__upstream_node_order’
‘water__volume_flux’ → ‘water__discharge’
‘water__volume_flux_in’ → ‘water__unit_flux_in’ (special case in flow router)
‘water__volume_flux_magnitude’, → ‘water__discharge’
‘water__volume_flux_xcomponent’, → ‘water__discharge_x_component’
‘water__volume_flux_ycomponent’, → ‘water__discharge_y_component’
‘water_depth’ –> ‘water__depth’
‘water_discharge’ –> ‘water__discharge’
‘water_discharge_at_nodes’ –> ‘water__discharge’
‘water_surface_slope_at_nodes’ –> ‘water_surface__gradient’
These changes are likely to occur in components probably not released as part of LL1.0, but will have likely occurred once the components return in a future release:
‘ActualEvapotranspiration’ –> surface__evapotranspiration_rate
‘CumulativeWaterStress’ –> vegetation__cumulative_water_stress
‘DeadBiomass’ –> vegetation__dead_biomass
‘DeadLeafAreaIndex –> vegetation__dead_leaf_area_index
‘Drainage’ –> duplicate of ‘drainage_area’ ?
‘Elevation’ –> duplicate of topographic__elevation, or needs to be more specific
‘LiveBiomass’ –> vegetation__live_biomass
‘LiveLeafAreaIndex’ –> vegetation__live_leaf_area_index
‘NetLongWaveRadiation’ –> radiation__net_longwave
‘NetRadiation’ –> radiation__net
‘NetShortWaveRadiation’ –> radiation__net_shortwave
‘PlantAge’ –> plant__age
‘PlantLiveIndex’ –> plant__live_index
‘PotentialEvapotranspiration’ –> surface__potential_evapotranspiration_rate
‘RadiationFactor’ –> radiation__ratio_to_flat_surface
‘Runoff’ –> I think I’m OK with runoff__rate
‘SaturationFraction’ –> soil_moisture__saturation_fraction
‘TotalShortWaveRadiation’ –> radiation__incoming_shortwave
‘VegetationCover’, –> vegetation__cover_fraction
‘VegetationType’ –> vegetation__type
‘WaterStress’ –> soil_moisture__water_stress