Note

This page was generated from a jupyter notebook.

Using SedimentPulserEachParcel to add sediment parcels to a channel network

This tutorial illustrates how to use SedimentPulserEachParcel with a network model grid and the NetworkSedimentTransporter.

  • SedimentPulserEachParcel overview: The user specifies the link and distance on link that parcels are placed within a channel network in a Pandas DataFrame.

In this example we will:

  1. Set up a network model grid with an initial set of parcels,

  2. Add pulses of sediment to the grid using SedimentPulserEachParcel, and

  3. Run NetworkSedimentTransporter between pulses

1. Setup the work space

[ ]:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from landlab.components import FlowDirectorSteepest, NetworkSedimentTransporter
from landlab.components.network_sediment_transporter.bed_parcel_initializers import (
    BedParcelInitializerArea,
)
from landlab.components.network_sediment_transporter.sediment_pulser_each_parcel import (
    SedimentPulserEachParcel,
)
from landlab.grid.network import NetworkModelGrid
from landlab.plot import graph, plot_network_and_parcels

2. Define the network model grid topology

[ ]:
x_of_node = (0, 0, 100, -50, -100, 50, -150, -100)
y_of_node = (0, 100, 200, 200, 300, 400, 400, 125)
nodes_at_link = ((1, 0), (1, 2), (7, 1), (3, 1), (4, 3), (5, 4), (6, 4))
nmg = NetworkModelGrid((y_of_node, x_of_node), nodes_at_link)

to help visualize where the pulses will be sent, plot the network with link and node id numbers

[ ]:
fig, axs = plt.subplots(1, 1, figsize=(4, 6))
graph.plot_links(nmg, with_id=True)
graph.plot_nodes(nmg, with_id=True)

4. Create an initial set of parcels on the grid.

Note, we start with a small number of initial parcels so that parcels from later pulses of material are visible in plots of the parcels and network

[ ]:
initialize_parcels = BedParcelInitializerArea(
    nmg,
    drainage_area_coefficient=0.1,
    drainage_area_exponent=0.2,
    median_number_of_starting_parcels=2,
)
parcels = initialize_parcels()

View the initial parcels on the network model grid, shaded by grain diameter

[ ]:
fig = plot_network_and_parcels(
    nmg,
    parcels,
    parcel_time_index=0,  # index of time, not the time value
    parcel_color_attribute="D",
    parcel_size=10,
    parcel_alpha=1.0,
    figsize=(3, 6),
)

Viewing the element id of the parcels in the network shows that ParcelInitializer added 15 parcels to the network

[ ]:
parcels.dataset["element_id"]

6. Instantiate SedimentPulserEachParcel

SedimentPulserEachParcel is instantiated with a network model grid. Optionally, default parcel attributes and a parcel DataRecord can be defined. If a parcel DataRecord is not provided, SedimentPulserEachParcel will create a new parcel DataRecord.

[ ]:
make_pulse = SedimentPulserEachParcel(
    nmg, parcels=parcels, parcel_volume=1
)  # set the default max parcel_volume as 1 m^3

7. create the PulseDF (Pulse DataFrame).

Each row of the PulseDF contains information on the deposition location and volume of a single pulse of sediment. The pulse is divided into ‘n’ number of parcels, where ‘n’ equals numpy.ceil(pulse volume / max parcel volume) For details on the format of the PulseDF, see the docstring for function SedimentPulserEachParcel._sediment_pulse_dataframe

Here we send a pulse to specific locations on links 1, 3, 5 and 2(see first figure for link id’s)> Note that any parcel attributes not specified use default values. Default values can be set when SedimentPulserAtLinks is instantiated.

[ ]:
time = nst.time
# volume of each pulse
PulseDF = pd.DataFrame(
    {
        "pulse_volume": [50, 5, 10, 15],
        # pulses enter channel network at these links
        "link_#": [1, 3, 5, 2],
        # the normalized distance on the link (distance from link inlet / link length)
        "normalized_downstream_distance": [0.8, 0.7, 0.5, 0.2],
    }
)
[ ]:
parcels = make_pulse(time, PulseDF)

view the location of the new parcels from the pulse.

Note that all parcels from a pulse are placed at the same point in the network and appear as 4 points on the plot

[ ]:
fig = plot_network_and_parcels(
    nmg,
    parcels,
    parcel_time_index=1,  # index of time, not the time value
    parcel_color_attribute="D",
    parcel_size=10,
    parcel_alpha=1.0,
    figsize=(3, 6),
)

Viewing the element id of the parcels in the network shows that we actually added roughly 80 new parcels

[ ]:
parcels.dataset["element_id"]

now apply another 24 hr flow event

[ ]:
nst.run_one_step(dt=3600 * 24)

View parcel locations after the flow event

[ ]:
fig = plot_network_and_parcels(
    nmg,
    parcels,
    parcel_time_index=2,  # index of time, not the time value
    parcel_color_attribute="D",
    parcel_size=10,
    parcel_alpha=1.0,
    figsize=(3, 6),
)

Notice that after the flow event, the parcels at each pulse location spread out.

8. Send a second pulseDF

This pulseDF includes two pulses:

  1. A 30 m^3 landslide in thin-bedded siltstone near the channel head (inlet) of link 3

  2. A 50 m^3 bedrock landslide in fractured, massive sandstone beds near the outlet of link 6

[ ]:
time = nst.time
PulseDF = pd.DataFrame(
    {
        "pulse_volume": [30, 50],  # pulse volume
        "link_#": [3, 6],  # link id
        "normalized_downstream_distance": [0.1, 0.9],  # distance on link
        "D50": [0.02, 0.5],  # median grain size
        "abrasion_rate": [0.1, 0.01],  # abrasion rate
        "parcel_volume": [0.25, 2],
    }
)  # parcel volume
[ ]:
parcels = make_pulse(time, PulseDF)

view the new parcels

[ ]:
fig = plot_network_and_parcels(
    nmg,
    parcels,
    parcel_time_index=2,  # index of time, not the time value
    parcel_color_attribute="D",
    parcel_size=10,
    parcel_alpha=1.0,
    figsize=(3, 6),
)

apply another day long flow event

[ ]:
nst.run_one_step(dt=3600 * 24)
[ ]:
fig = plot_network_and_parcels(
    nmg,
    parcels,
    parcel_time_index=3,  # index of time, not the time value
    parcel_color_attribute="D",
    parcel_size=10,
    parcel_alpha=1.0,
    figsize=(3, 6),
)

Generated by nbsphinx from a Jupyter notebook.