landlab

OverlandFlow: Model shallow water flow over topography using the numerical approximation of de Almeida

Landlab component that simulates overland flow.

This component simulates overland flow using the 2-D numerical model of shallow-water flow over topography using the de Almeida et al., 2012 algorithm for storage-cell inundation modeling.

Code author: Jordan Adams

Examples

>>> import numpy as np
>>> from landlab import RasterModelGrid
>>> from landlab.components.overland_flow import OverlandFlow

Create a grid on which to calculate overland flow.

>>> grid = RasterModelGrid((4, 5))

The grid will need some data to provide the overland flow component. To check the names of the fields that provide input to the overland flow component use the input_var_names class property.

>>> OverlandFlow.input_var_names
('surface_water__depth', 'topographic__elevation')

Create fields of data for each of these input variables.

>>> grid.at_node['topographic__elevation'] = np.array([
...     0., 0., 0., 0., 0.,
...     1., 1., 1., 1., 1.,
...     2., 2., 2., 2., 2.,
...     3., 3., 3., 3., 3.])
>>> grid.at_node['surface_water__depth'] = np.array([
...     0. , 0. , 0. , 0. , 0. ,
...     0. , 0. , 0. , 0. , 0. ,
...     0. , 0. , 0. , 0. , 0. ,
...     0.1, 0.1, 0.1, 0.1, 0.1])

Instantiate the OverlandFlow component to work on this grid, and run it.

>>> of = OverlandFlow(grid, steep_slopes=True)
>>> of.run_one_step()

After calculating the overland flow, new fields have been added to the grid. Use the output_var_names property to see the names of the fields that have been changed.

>>> of.output_var_names
('surface_water__depth', 'surface_water__discharge', 'water_surface__gradient')

The surface_water__depth field is defined at nodes.

>>> of.var_loc('surface_water__depth')
'node'
>>> grid.at_node['surface_water__depth'] 
array([  1.00000000e-05,   1.00000000e-05,   1.00000000e-05,
         1.00000000e-05,   1.00000000e-05,   1.00000000e-05,
         1.00000000e-05,   1.00000000e-05,   1.00000000e-05,
         1.00000000e-05,   1.00000000e-05,   2.00100000e-02,
         2.00100000e-02,   2.00100000e-02,   1.00000000e-05,
         1.00010000e-01,   1.00010000e-01,   1.00010000e-01,
         1.00010000e-01,   1.00010000e-01])

The surface_water__discharge field is defined at links. Because our initial topography was a dipping plane, there is no water discharge in the horizontal direction, only toward the bottom of the grid.

>>> of.var_loc('surface_water__discharge')
'link'
>>> q = grid.at_link['surface_water__discharge'] 
>>> np.all(q[grid.horizontal_links] == 0.)
True
>>> np.all(q[grid.vertical_links] <= 0.)
True

The water_surface__gradient is also defined at links.

>>> of.var_loc('water_surface__gradient')
'link'
>>> grid.at_link['water_surface__gradient'] 
array([ 0. ,  0. ,  0. ,  0. ,
        0. ,  1. ,  1. ,  1. ,  0. ,
        0. ,  0. ,  0. ,  0. ,
        0. ,  1. ,  1. ,  1. ,  0. ,
        0. ,  0. ,  0. ,  0. ,
        0. ,  1.1,  1.1,  1.1,  0. ,
        0. ,  0. ,  0. ,  0. ])
class OverlandFlow(*args, **kwds)[source]

Bases: landlab.core.model_component.Component

Simulate overland flow using de Almeida approximations.

Landlab component that simulates overland flow using the de Almeida et al., 2012 approximations of the 1D shallow water equations to be used for 2D flood inundation modeling.

This component calculates discharge, depth and shear stress after some precipitation event across any raster grid. Default input file is named “overland_flow_input.txt’ and is contained in the landlab.components.overland_flow folder.

Parameters:

grid : RasterModelGrid

A landlab grid.

h_init : float, optional

Thicknes of initial thin layer of water to prevent divide by zero errors (m).

alpha : float, optional

Time step coeffcient, described in Bates et al., 2010 and de Almeida et al., 2012.

mannings_n : float, optional

Manning’s roughness coefficient.

g : float, optional

Acceleration due to gravity (m/s^2).

theta : float, optional

Weighting factor from de Almeida et al., 2012.

rainfall_intensity : float, optional

Rainfall intensity.

The primary method of this class is :func:`run_one_step`.

Construction::

OverlandFlow(grid, default_fixed_links=False, h_init=0.00001,

alpha=0.7, mannings_n=0.03, g=9.81, theta=0.8, rainfall_intensity=0.0, steep_slopes=False, **kwds)

calc_time_step()[source]

Calculate time step.

Adaptive time stepper from Bates et al., 2010 and de Almeida et al., 2012

discharge_mapper(input_discharge, convert_to_volume=False)[source]

Maps discharge value from links onto nodes.

This method takes the discharge values on links and determines the links that are flowing INTO a given node. The fluxes moving INTO a given node are summed.

This method ignores all flow moving OUT of a given node.

This takes values from the OverlandFlow component (by default) in units of [L^2/T]. If the convert_to_cms flag is raised as True, this method converts discharge to units [L^3/T] - as of Aug 2016, only operates for square RasterModelGrid instances.

The output array is of length grid.number_of_nodes and can be used with the Landlab imshow_grid plotter.

Returns a numpy array (discharge_vals)

overland_flow(dt=None)[source]

Generate overland flow across a grid.

For one time step, this generates ‘overland flow’ across a given grid by calculating discharge at each node.

Using the depth slope product, shear stress is calculated at every node.

Outputs water depth, discharge and shear stress values through time at every point in the input grid.

run_one_step(dt=None)[source]

Generate overland flow across a grid.

For one time step, this generates ‘overland flow’ across a given grid by calculating discharge at each node.

Using the depth slope product, shear stress is calculated at every node.

Outputs water depth, discharge and shear stress values through time at every point in the input grid.

set_up_neighbor_arrays()[source]

Create and initialize link neighbor arrays.

Set up arrays of neighboring horizontal and vertical links that are needed for the de Almeida solution.

Find active link neighbors for every fixed link.

Specialized link ID function used to ID the active links that neighbor fixed links in the vertical and horizontal directions.

If the user wants to assign fixed gradients or values to the fixed links dynamically, this function identifies the nearest active_link neighbor.

Each fixed link can either have 0 or 1 active neighbor. This function finds if and where that active neighbor is and stores those IDs in an array.

Parameters:

grid : RasterModelGrid

A landlab grid.

Returns:

ndarray of int, shape (*, )

Flat array of links.

Examples

>>> from landlab.grid.structured_quad.links import neighbors_at_link
>>> from landlab import RasterModelGrid
>>> from landlab.components.overland_flow.generate_overland_flow_deAlmeida import find_active_neighbors_for_fixed_links
>>> from landlab import RasterModelGrid, FIXED_GRADIENT_BOUNDARY
>>> grid = RasterModelGrid((4, 5))
>>> grid.status_at_node[:5] = FIXED_GRADIENT_BOUNDARY
>>> grid.status_at_node[::5] = FIXED_GRADIENT_BOUNDARY
>>> grid.status_at_node 
array([2, 2, 2, 2, 2,
       2, 0, 0, 0, 1,
       2, 0, 0, 0, 1,
       2, 1, 1, 1, 1], dtype=int8)
>>> grid.fixed_links
array([ 5,  6,  7,  9, 18])
>>> grid.active_links
array([10, 11, 12, 14, 15, 16, 19, 20, 21, 23, 24, 25])
>>> find_active_neighbors_for_fixed_links(grid)
array([14, 15, 16, 10, 19])
>>> rmg = RasterModelGrid((4, 7))
>>> rmg.at_node['topographic__elevation'] = rmg.zeros(at='node')
>>> rmg.at_link['topographic__slope'] = rmg.zeros(at='link')
>>> rmg.set_fixed_link_boundaries_at_grid_edges(True, True, True, True)
>>> find_active_neighbors_for_fixed_links(rmg)
array([20, 21, 22, 23, 24, 14, 17, 27, 30, 20, 21, 22, 23, 24])

OverlandFlowBates: Model shallow water flow over topography using the numerical approximation of Bates

generate_overland_flow.py

This component simulates overland flow using the 2-D numerical model of shallow-water flow over topography using the Bates et al. (2010) algorithm for storage-cell inundation modeling.

Written by Jordan Adams, based on code written by Greg Tucker.

Last updated: April 21, 2016

class OverlandFlowBates(grid, h_init=1e-05, alpha=0.7, mannings_n=0.03, g=9.81, rainfall_intensity=0.0, **kwds)[source]

Bases: landlab.core.model_component.Component

Simulate overland flow using Bates et al. (2010).

Landlab component that simulates overland flow using the Bates et al., (2010) approximations of the 1D shallow water equations to be used for 2D flood inundation modeling.

This component calculates discharge, depth and shear stress after some precipitation event across any raster grid. Default input file is named “overland_flow_input.txt’ and is contained in the landlab.components.overland_flow folder.

Parameters:

grid : RasterGridModel

A grid.

input_file : str

Contains necessary and optional inputs. If not given, default input file is used.

  • Manning’s n is required.
  • Storm duration is needed if rainfall_duration is not passed in the initialization
  • Rainfall intensity is needed if rainfall_intensity is not passed in the initialization
  • Model run time can be provided in initialization. If not it is set to the storm duration

h_init : float, optional

Some initial depth in the channels. Default = 0.001 m

g : float, optional

Gravitational acceleration, \(m / s^2\)

alpha : float, optional

Non-dimensional time step factor from Bates et al., (2010)

rho : integer, optional

Density of water, \(kg / m^3\)

ten_thirds : float, optional

Precalculated value of \(10 / 3\) which is used in the implicit shallow water equation.

Examples

>>> DEM_name = 'DEM_name.asc'
>>> (rg, z) = read_esri_ascii(DEM_name) 
>>> of = OverlandFlowBates(rg) 
calc_time_step()[source]
overland_flow(dt=None, **kwds)[source]

For one time step, this generates ‘overland flow’ across a given grid by calculating discharge at each node.

Using the depth slope product, shear stress is calculated at every node.

Outputs water depth, discharge and shear stress values through time at every point in the input grid.

Parameters:

grid : RasterModelGrid

A grid.

dt : float, optional

Time step. Either set when called or the component will do it for you.

KinematicWaveRengers: Model kinematic wave flood propagation after Rengers et al (2016)

class KinematicWaveRengers(*args, **kwds)[source]

Bases: landlab.core.model_component.Component

A mid-complexity kinematic wave flood model, after Rengers et al (2016)

This code is based on an overland flow model by Francis Rengers and colleagues, after Julien et al., 1995. It uses an explicit face-centered solution to a depth-varying Manning’s equation, broadly following, e.g., Mugler et al., 2011. It was implemented in Landlab by DEJH, March ‘16. Please cite Rengers et al., 2016, Model Predictions of Water Runoff in Steep Catchments after Wildfire, WRR.

Note: You will not have a good day if you have pits present in your topo before routing flow with this component. Fill pits before instantiating the component (or call update_topographic_params() once you have filled after instantiation).

Note this module assumes that the topography DOES NOT change during the run. If it does, call update_topographic_params() to update the component to the new topo.

Boundary condition control can be... interesting with this component. Be sure to close boundaries you do not wish water to leave - or enter! - through. To allow free water discharge from the grid edge it is recommended to use fixed gradient boundary conditions at the open edges. The component will then set the fixed gradient as equal to the underlying topographic gradient throughout the run.

It is also possible to fix the water depth at the open edge, but this is not really recommended.

Construction:

KinematicWaveRengers(grid, mannings_n=0.03, critical_flow_depth=0.003,
                     mannings_epsilon=0.33333333, dt_max=0.3,
                     max_courant=0.2, min_surface_water_depth=1.e-8)
Parameters:

grid : RasterModelGrid

A grid.

mannings_n : float

A value to use for Manning’s n in the Manning discharge equation.

critical_flow_depth : float (m)

An index flow depth for the depth-varying Manning’s equation, controlling the depth at which the effective Manning’s n begins to increase.

mannings_epsilon : float

An exponent for the depth-varying Manning’s equation, controlling the rate of increase of effective Manning’s n at small flow depths.

dt_max : float or None (s)

The largest permitted internal timestep for the component. If the Courant criterion produces a more restrictive condition, that will be used instead.

max_courant : float

The maximum permitted Courant number for the courant stability criterion.

min_surface_water_depth : float (m)

A water depth below which surface water thickness may never fall, to ensure model stabilty.

Examples

>>> from landlab import RasterModelGrid
>>> from landlab import CLOSED_BOUNDARY, FIXED_GRADIENT_BOUNDARY
>>> mg = RasterModelGrid((5, 10), spacing=10.)
>>> mg.status_at_node[mg.nodes_at_left_edge] = FIXED_GRADIENT_BOUNDARY
>>> mg.status_at_node[mg.nodes_at_top_edge] = CLOSED_BOUNDARY
>>> mg.status_at_node[mg.nodes_at_bottom_edge] = CLOSED_BOUNDARY
>>> mg.status_at_node[mg.nodes_at_right_edge] = CLOSED_BOUNDARY
>>> _ = mg.add_field('node', 'topographic__elevation', 0.05*mg.node_x)
>>> _ = mg.add_empty('node', 'surface_water__depth')
>>> mg.at_node['surface_water__depth'].fill(1.e-8)
>>> dt = 60.  # 1 min intervals
>>> rain_intensities = (1.e-5, 1.e-5, 1.e-5, 1.e-5, 1.e-5)
>>> kw = KinematicWaveRengers(mg)
>>> for i in rain_intensities:
...     kw.run_one_step(dt, rainfall_intensity=i)
>>> mg.at_node['surface_water__depth']
array([  1.00000000e-08,   1.00000000e-08,   1.00000000e-08,
         1.00000000e-08,   1.00000000e-08,   1.00000000e-08,
         1.00000000e-08,   1.00000000e-08,   1.00000000e-08,
         1.00000000e-08,   2.95578314e-03,   2.95578314e-03,
         2.90945761e-03,   2.82912876e-03,   2.70127141e-03,
         2.51202011e-03,   2.24617193e-03,   1.88032853e-03,
         1.35451064e-03,   1.00000000e-08,   2.95578314e-03,
         2.95578314e-03,   2.90945761e-03,   2.82912876e-03,
         2.70127141e-03,   2.51202011e-03,   2.24617193e-03,
         1.88032853e-03,   1.35451064e-03,   1.00000000e-08,
         2.95578314e-03,   2.95578314e-03,   2.90945761e-03,
         2.82912876e-03,   2.70127141e-03,   2.51202011e-03,
         2.24617193e-03,   1.88032853e-03,   1.35451064e-03,
         1.00000000e-08,   1.00000000e-08,   1.00000000e-08,
         1.00000000e-08,   1.00000000e-08,   1.00000000e-08,
         1.00000000e-08,   1.00000000e-08,   1.00000000e-08,
         1.00000000e-08,   1.00000000e-08])
calc_grads_and_timesteps(update_topography, track_min_depth)[source]

Perform the first part of the calculation for the main run, mainly velocities and fluxes. The main objective of this part of the calculation is to derive the stable timestep for the run.

Parameters:

update_topography : bool

If False, the underlying surface topography is assumed unchanged since the last run.

track_min_depth : bool

If True, the internal list _water_balance will be appended with the volumetric fractional change in mass balance during the run.

Returns:

internal_dt : float

The internally stable timestep that will be used on this loop.

internal_timestep

Return the internal timestep last used by the kinematic wave component.

run_one_step(dt, rainfall_intensity=1e-05, update_topography=False, track_min_depth=False)[source]

Update fields with current hydrologic conditions.

Parameters:

rain_intensity : float or array (m/s)

The rainfall intensity across the grid (water input rate at each node).

update_topography : bool

Set to true if the topography of the grid evolves during the run.

track_min_depth : bool

At very low rainfall inputs, there is a possibility this component could allow creation of small amounts of water mass. Set to true to track this mass, and use the water_balance() property to investigate its evolution through time.

update_topographic_params()[source]

If the topo changes during the run, change the held params used by run_one_step().

water_balance

Return a list of the fractional gain/loss of water mass during the run, if it was tracked using the track_min_depth flag.