<jupyter_start><jupyter_text>Green-Ampt infiltration and kinematic wave overland flowThis tutorial shows how to create a simple model of rainfall, infiltration, runoff, and overland flow, using two hydrologic components: `SoilInfiltrationGreenAmpt` and `KinwaveImplicitOverlandFlow`.*(<NAME>, September 2021)*<jupyter_code>import numpy as np
import matplotlib.pyplot as plt
from landlab import imshow_grid, RasterModelGrid
from landlab.io import read_esri_ascii
from landlab.components import SoilInfiltrationGreenAmpt, KinwaveImplicitOverlandFlow<jupyter_output><empty_output><jupyter_text>TheoryThe Green-Ampt method was introduced by Green and Ampt (1911) as a means of approximating the rate of water infiltration into soil from a layer of surface water. The method represents infiltration in terms of a wetting front that descends into the soil as infiltration progresses. A description of the method can be found in many hydrology textbooks, and in various online resources. The following is a brief summary, using the notation of Julien et al. (1995). The dimensions of each variable are indicated in square brackets, using the common convention that [L] means length, [M] is mass, and [T] is time.The Green-Ampt method approximates the rate of water infiltration into the soil, $f$ (dimensions of [L/T], representing water volume per unit surface area). Infiltration is driven by two effects:  gravitational force, and downward suction (the "paper towel effect") due to a gradient in moisture at the wetting front. The method treats the infiltration rate as a function of the following parameters:- $K$ - saturated hydraulic conductivity [L/T]- $H_f$ - capillary pressure head at the wetting front [L]- $\phi$ - total soil porosity [-]- $\theta_r$ - residual saturation [-]- $\theta_e$ - effective porosity $= \phi - \theta_r$ [-]- $\theta_i$ - initial soil moisture content [-]- $M_d$ - moisture deficit $=\theta_e - \theta_i$ [-]- $F$ - total infiltrated water depth [L]The equation for infiltration rate is:$$f = K \left( 1 + \frac{H_fM_d}{F} \right)$$The first term in parentheses represents gravity and the second represents pore suction. If there were no pore suction effect, water would simply infiltrate downward at a rate equal to the  hydraulic conductivity, $K$. The suction effect increases this, but it becomes weaker as the cumulative infiltration depth $F$ grows. Effectively, the second term approximates the pore-pressure gradient, which declines as the wetting front descends.The version used in this component adds a term for the weight of the surface water with depth $H$:$$f = K \left( 1 + \frac{H_fM_d}{F} + \frac{H}{F} \right)$$The component uses a simple forward-difference numerical scheme, with time step duration $\Delta t$, in which the infiltration depth during one step is the lesser of the rate calculated above times $\Delta t$, or the available surface water, $H$:$$\Delta F = \min( f\Delta t, H)$$Note that the cumulative infitration $F$ must be greater than zero in order to avoid division by zero; therefore, one should initialize the `soil_water_infiltration__depth` to a small positive value.  Example Read in topography from a sample DEMThis is a lidar digital elevation model (DEM) from the West Bijou Creek escarpment on the Colorado High Plains, coarsened to 5 m grid resolution.Note: it is convenient to use local grid coordinates rather than UTM coordinates, which are what the DEM provides. Therefore, after reading topography data into a grid called `demgrid`, which uses UTM coordinates, we copy over the elevation data into a second grid (`grid`) of the same dimensions that uses local coordinates (i.e., the lower left corner is (0, 0)).<jupyter_code># Read topography into a grid
(demgrid, demelev) = read_esri_ascii(
    "bijou_gully_subset_5m_edit_dx_filled.asc", name="topographic__elevation"
)
# Create Landlab model grid and assign the DEM elevations to it,
# then display the terrain.
# (note: DEM horizontal and vertical units are meters)
grid = RasterModelGrid(
    (demgrid.number_of_node_rows, demgrid.number_of_node_columns), xy_spacing=5.0
)
elev = grid.add_zeros("topographic__elevation", at="node")
elev[:] = demelev
imshow_grid(grid, elev, colorbar_label="Elevation (m)")<jupyter_output><empty_output><jupyter_text>Simulate a heavy 5-minute stormThe next bits of code use the `SoilInfiltrationGreenAmpt` and `KinwaveImplicitOverlandFlow` components to model infiltration and runoff during a 5-minute, 90 mm/hr storm.<jupyter_code># Create and initialize required input fields for infiltration
# component: depth of surface water, and depth (water volume per
# area) of infiltrated water.
depth = grid.add_zeros("surface_water__depth", at="node")
infilt = grid.add_zeros("soil_water_infiltration__depth", at="node")
infilt[:] = 1.0e-4  # small amount infiltrated (0.1 mm)

# Instantiate an infiltration component
ga = SoilInfiltrationGreenAmpt(
    grid,
)

# Instantiate an overland flow component
kw = KinwaveImplicitOverlandFlow(
    grid, runoff_rate=90.0, roughness=0.1, depth_exp=5.0 / 3.0
)
# Set time step and storm duration
dt = 10.0  # time step, sec
storm_duration = 300.0  # storm duration, sec
report_every = 60.0  # report progress this often

nsteps = int(storm_duration / dt)
next_report = report_every
# Run it for 10 minutes of heavy rain
for i in range(nsteps):
    kw.run_one_step(dt)
    ga.run_one_step(dt)
    if ((i + 1) * dt) >= next_report:
        print("Time =", (i + 1) * dt, "sec")
        next_report += report_every<jupyter_output><empty_output><jupyter_text>Plot the cumulative infiltrationThe plot below illustrates how the convergence of water in the branches of the gully network leads to greater infiltration, with less infiltration on steeper slopes and higher points in the landscape.<jupyter_code>imshow_grid(
    grid, 1000.0 * infilt, colorbar_label="Infiltration depth (mm)", cmap="GnBu"
)<jupyter_output><empty_output><jupyter_text>Optional parametersThe `SoilInfiltrationGreenAmpt` component provides a variety parameters that can be set by the user. A list and description of these can be found in the component's `__init__` docstring, which is printed below:<jupyter_code>print(SoilInfiltrationGreenAmpt.__init__.__doc__)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07814992025518341, 'fraction_numerical': 0.00909090909090909, 'mean_word_length': 5.315206445115811, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '144291', 'license': 'MIT', 'n_tokens_mistral': 1919, 'n_tokens_neox': 1737, 'n_words': 768, 'path': 'notebooks/tutorials/overland_flow/soil_infiltration_green_ampt/infilt_green_ampt_with_overland_flow.ipynb', 'repo_name': 'Joseph-A-Mason/landlab', 'size': '6275'}