pipedream

🚰 Interactive hydrodynamic solver for pipe and channel networks

View the Project on GitHub mdbartos/pipedream

Overview

    â€¢ Governing equations
    â€¢ Model structure

Examples

    â€¢ Flow on hillslope
    â€¢ Simulation context manager
    â€¢ Contaminant transport on hillslope
    â€¢ Uncoupled overland flow
    â€¢ Coupled overland flow
    â€¢ Simple dynamic control example
    â€¢ Adaptive step size control
    â€¢ Validation with real-world network
    â€¢ Kalman filtering with holdout analysis

Reference

    â€¢ Hydraulic solver API reference
    â€¢ Infiltration solver API reference
    â€¢ Water quality solver API reference
    â€¢ Model inputs
    â€¢ Hydraulic geometry reference

Flow on a hillslope

This tutorial demonstrates how to use the pipedream solver to simulate the flow of water on a simple hillslope.

Import modules

import numpy as np
import pandas as pd
from pipedream_solver.hydraulics import SuperLink

Load model data

Model structure can be saved to or loaded from CSV files. In this case, our model consists of a set of superjunctions and a set of superlinks.

input_path = '../data/hillslope'
superjunctions = pd.read_csv(f'{input_path}/hillslope_superjunctions.csv')
superlinks = pd.read_csv(f'{input_path}/hillslope_superlinks.csv')

Superjunctions

Superjunctions are basic finite volumes, and may represent manholes, retention ponds, or other bodies of water.

superjunctions
name id z_inv h_0 bc storage a b c max_depth map_x map_y
0 0 0 1 0.00001 False functional 0.0 0.0 200.0 inf 0 0
1 1 1 0 0.00001 False functional 0.0 0.0 1000.0 inf 1 1

Superlinks are sections of channel or conduit that connect superjunctions together. Each superlink consists of a number of internal junctions and nodes connected in a linear fashion. In this case, we have a single superlink that connects the uphill superjunction to the downhill superjunction.

superlinks
name id sj_0 sj_1 in_offset out_offset dx n shape g1 g2 g3 g4 Q_0 h_0 ctrl A_s A_c C
0 0 0 0 1 0.0 0.0 1000 0.035 rect_open 10 5 0 0 0 0.00001 False 100 0 0

Internal links and junctions can be specified explicitly, or generated automatically inside each superlink. In this case, we will use 24 automatically-generated internal links.

internal_links = 24

Instantiate model

The hydraulic model is instantiated with the SuperLink class.

model = SuperLink(superlinks, superjunctions, 
                  internal_links=internal_links)

Next, we specify the model parameters, including the default time step dt, the inflow into each superjunction Q_in, and the inflow into each internal junction Q_0Ik.

dt = 10                            # Model time step (s)
Q_in = 1e-3 * np.ones(model.M)     # Flow into each internal junction (cms)
Q_0Ik = 1e-3 * np.ones(model.NIk)  # Flow into each internal junction (cms)

Note that model.M is the number of superjunctions, and model.NIk is the number of internal junctions.

We can visualize the model with plot_profile. Note that the hillslope at the start of the model run is dry.

# Plot profile from superjunctions 0 to 1 (uphill to downhill)
_ = model.plot_profile([0, 1], width=100)

png

Run model

Apply rain to hillslope for 4 hours

Applying inflow to each superjunction and internal link causes water to flow down the hill.

# For each timestep...
for _ in range(4 * 360):
    # Advance model forward in time
    model.step(dt=dt, Q_in=Q_in, Q_0Ik=Q_0Ik)
_ = model.plot_profile([0, 1], width=100)

png

Progress forward in time for 3 hours with no rain

Ceasing the flow input and advancing the model in time causes the water to settle at the bottom of the hill.

for _ in range(3 * 360):
    model.step(dt=dt)
_ = model.plot_profile([0, 1], width=100)

png