Tutorial 02 – Running a Basic Simulation#
This tutorial walks through running a basic Pywr-DRB simulation. You’ll create a model configuration file in JSON format using ModelBuilder
and run a simulation using pywrdrb
that saves the output to a standardized HDF5 file.
This is a great place to start if you’re new to the Pywr-DRB model.
Model Overview#
Pywr-DRB is a river basin simulation model built on top of Pywr, a flexible node-link water resource modeling framework. In Pywr, the system is represented as a network of nodes (e.g., reservoirs, rivers, demands) and links (e.g., flow pathways), where each node has operational rules and constraints.
The Pywr-DRB implementation represents the full Delaware River Basin, including:
18 major reservoirs (e.g., Cannonsville, Pepacton, Blue Marsh)
Streamflow routing between sub-basins
Urban, agricultural, and ecological demands
Operating rules based on institutional agreements and historical patterns
Simulations are conducted at a daily time step, using input inflow datasets to drive flow dynamics through the network. In this tutorial, you’ll create a model configuration file that encodes this structure, along with the simulation period and hydrologic forcing data.
The remaining tutorials will walk through running, analyzing, and customizing these simulations.
import os
# Change to your preferred directory if needed
# os.chdir(my_directory)
cwd = os.getcwd()
print(f"Current working directory: {cwd}")
Step 1 – Initialize Model with ModelBuilder
#
We begin by creating a model configuration file (model.json
) using pywrdrb.ModelBuilder
. This configuration defines the model’s node-link structure and key metadata, including simulation dates, the inflow dataset, node relationships, and operational constraints.
ModelBuilder
requires three arguments:
inflow_type
: the selected inflow datasetstart_date
: simulation start date in"YYYY-MM-DD"
formatend_date
: simulation end date in"YYYY-MM-DD"
format
An optional options
dictionary is available for advanced usage (see advanced tutorials or the API documentation for details).
Supported Inflow Datasets and Simulation Periods#
Pywr-DRB supports a range of inflow datasets representing historic, modeled, and scenario-based hydrologic conditions:
Inflow Dataset |
Start Date |
End Date |
Notes |
---|---|---|---|
|
1983-10-01 |
2016-12-31 |
National Hydrologic Model v1.0 (raw) |
|
1983-10-01 |
2016-12-31 |
NHM v1.0 scaled with observed flows |
|
1983-10-01 |
2016-12-31 |
National Water Model v2.1 (raw) |
|
1983-10-01 |
2016-12-31 |
NWM v2.1 scaled with observed flows |
|
1945-01-01 |
2023-12-31 |
Median Reconstruction with bias correction |
|
1959-10-01 |
1969-12-31 |
WRF 1960s climate scenario |
|
1959-10-01 |
1969-12-31 |
WRF 2050s future scenario |
|
1979-10-01 |
2021-12-31 |
WRF historical simulation (AORC forcing) |
|
1983-10-01 |
2021-12-31 |
AORC-scaled with observed flows |
These inflow options enable users to test a range of hydrologic conditions, from observed historical records to future climate projections.
⚠ Always confirm that the selected
start_date
andend_date
fall within the supported range for your chosen dataset.
We will use the 'nhmv10_withObsScaled'
dataset in the example that follows.
import pywrdrb
mb = pywrdrb.ModelBuilder(
inflow_type='nhmv10_withObsScaled',
start_date="1983-10-01",
end_date="2016-12-31"
)
mb.make_model()
model_filename = os.path.join(cwd, "model.json")
# Save the model to a JSON file
mb.write_model(model_filename)
Step 2 – Load the Model#
Now that the model JSON file has been created, we can load it into memory using pywrdrb.Model.load()
. This initializes all the Pywr nodes, parameters, and connections defined in the JSON file.
model = pywrdrb.Model.load(model_filename)
Step 3 – Attach an Output Recorder#
Next, we attach an pywrdrb.OutputRecorder
to the model. This customized recorder tracks key outputs during the simulation, stores them in memory, and writes them to an .hdf5
file once the simulation is completed.
The output file will store time series data like reservoir storage, streamflow, releases, and more. Please check OutputRecorder
options for details.
Optional Arguments for OutputRecorder#
The pywrdrb.OutputRecorder
records and saves model simulation data to an HDF5 file.
It wraps the base pywr.Recorder
class and is optimized for efficiency while tracking all key model variables.
Key arguments:
model
→ thepywrdrb.Model
instance to record from (required)output_filename
→ name of the output HDF5 file (required)nodes
→ optional list ofpywr.core.Node
objects to record (ifNone
, all named nodes are recorded)parameters
→ optional list ofpywr.core.Parameter
objects to record (ifNone
, all named parameters are recorded)
output_filename = os.path.join(cwd,"pywrdrb_output.hdf5")
recorder = pywrdrb.OutputRecorder(model, output_filename)
Step 4 – Run the Simulation#
Now we run the model. This may take a few seconds depending on your machine. The simulation uses the configuration and input data to simulate reservoir operations and streamflows across the Delaware River Basin.
stats = model.run()
c:\Users\CL\miniconda3\envs\test_pywrdrb\Lib\site-packages\pywr\dataframe_tools.py:127: FutureWarning: Resampling with a PeriodIndex is deprecated. Cast index to DatetimeIndex before resampling instead.
new_df = new_df.resample(target_index.freq).agg(resample_func)
C:\Users\CL\AppData\Local\Temp\ipykernel_39240\737189858.py:1: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)
stats = model.run()
Step 5 – Confirm the Output File Was Created#
After running the simulation, check that the HDF5 output file was successfully created. This file will be used in the next tutorial to analyze results.
assert os.path.exists(output_filename), "Simulation output not found."
print(" Simulation completed and output file saved:", output_filename)
Simulation completed and output file saved: c:\Users\CL\Documents\GitHub\Pywr-DRB\notebooks\pywrdrb_output.hdf5