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 dataset

  • start_date: simulation start date in "YYYY-MM-DD" format

  • end_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

nhmv10

1983-10-01

2016-12-31

National Hydrologic Model v1.0 (raw)

nhmv10_withObsScaled

1983-10-01

2016-12-31

NHM v1.0 scaled with observed flows

nwmv21

1983-10-01

2016-12-31

National Water Model v2.1 (raw)

nwmv21_withObsScaled

1983-10-01

2016-12-31

NWM v2.1 scaled with observed flows

pub_nhmv10_BC_withObsScaled

1945-01-01

2023-12-31

Median Reconstruction with bias correction

wrf1960s_calib_nlcd2016

1959-10-01

1969-12-31

WRF 1960s climate scenario

wrf2050s_calib_nlcd2016

1959-10-01

1969-12-31

WRF 2050s future scenario

wrfaorc_calib_nlcd2016

1979-10-01

2021-12-31

WRF historical simulation (AORC forcing)

wrfaorc_withObsScaled

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 and end_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 → the pywrdrb.Model instance to record from (required)

  • output_filename → name of the output HDF5 file (required)

  • nodes → optional list of pywr.core.Node objects to record (if None, all named nodes are recorded)

  • parameters → optional list of pywr.core.Parameter objects to record (if None, 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