Lesson 4 - Run-time options for Gridded configuration

Overview

In Lesson 2 we covered the basics of constructing and running a WRF-Hydro simulation using a prepared domain for the 'Gridded' configuration. And in lesson 3, we covered how to do some basic plotting for the 2D input/output files and also plot some time series. In this lesson, we will experiment with few difference run-time options and do some basic visualization of the outputs using the Python library xarray.

NOTE: If you have not completed Lessons 2 and 3, please stop and do so now.

Software and conventions

The easiest way to run these lessons is via the wrfhydro/training Docker container, which has all software dependencies and data pre-installed.

For a complete description of the software environment used for this training please see Getting started.

You may either execute commands by running each cell of this notebook. Alternatively, you may open a terminal in Jupyter Lab by selecting New -> Terminal in your Home tab of Jupyter Lab and input the commands manually if you prefer. You can also use your own terminal by logging into the container with the command docker exec -it wrf-hydro-training bash

All paths used in this lesson assume that the lesson materials are located under your home directory in a folder named wrf-hydro-training. If your materials are located in another directory, you will not be able to run the commands in this notebook inside Jupyter and will need to type them manually in your terminal session.

Recap of Lessons 1 and 2, compiling and running WRF-Hydro

In this section, we will quickly recap the commands issued in Lessons 1 and 2 to compile WRF-Hydro and create our simulation directory. We will use the prepared domain for the remaining lessons, but feel free to replace the prepared domain with the domain you created in the geospatial hands-on training session. NOTE: Your domain directory structure and filenames must match the prepared domain EXACTLY

Compiling WRF-Hydro

Below are the commands to compile WRF-Hydro.

In [ ]:
%%bash
# Change to the trunk/NDHMS directory and configure for gfort
cd ~/wrf-hydro-training/wrf_hydro_nwm_public/trunk/NDHMS/; ./configure 2

# Make a copy of the template environment variable file, setEnvars.sh
cp ~/wrf-hydro-training/wrf_hydro_nwm_public/trunk/NDHMS/template/setEnvar.sh \
~/wrf-hydro-training/wrf_hydro_nwm_public/trunk/NDHMS/setEnvar.sh

Set compile-time options

Edit the setEnvar.sh script to set environment variables required by the compile script. Your setEnvar.sh should look like the bash script below when you are finished. NOTE: We are compiling with spatial soils active for this exercise.


#!/bin/bash
# WRF-Hydro compile time options

# This is a WRF environment variable. Always set to 1=On for compiling WRF-Hydro.
export WRF_HYDRO=1

# Enhanced diagnostic output for debugging: 0=Off, 1=On.
export HYDRO_D=1

# Spatially distributed parameters for NoahMP: 0=Off, 1=On.
export SPATIAL_SOIL=1  

# RAPID model: 0=Off, 1=On.
export WRF_HYDRO_RAPID=0

# Large netcdf file support: 0=Off, 1=On.
export WRFIO_NCD_LARGE_FILE_SUPPORT=1

# WCOSS file units: 0=Off, 1=On. 
export NCEP_WCOSS=0

# Streamflow nudging: 0=Off, 1=On.
export WRF_HYDRO_NUDGING=0

Compile WRF-Hydro in uncoupled mode

In [ ]:
%%bash
cd ~/wrf-hydro-training/wrf_hydro_nwm_public/trunk/NDHMS/; \
./compile_offline_NoahMP.sh setEnvar.sh >> compile.log 2>&1

tail -13 ~/wrf-hydro-training/wrf_hydro_nwm_public/trunk/NDHMS/compile.log

We have successfully compiled WRF-Hydro and we will use this binary and *.TBL files for the remaining simulations in this lesson

Creating the simulation directory and running a baseline WRF-Hydro simulation

Below are the commands from Lesson 2 to create the simulation directory and run a WRF-Hydro simulation. This simulation will be run exactly as was done in Lesson 2 and will serve as our baseline simulation. We will modify run-time options in subsequent simulations in the lesson and compare the outputs.

In [1]:
%%bash
# Make a new directory for our baseline simulation
mkdir -p ~/wrf-hydro-training/output/lesson4/run_gridded_baseline

# Copy our model files to the simulation directory
cp ~/wrf-hydro-training/wrf_hydro_nwm_public/trunk/NDHMS/Run/*.TBL \
~/wrf-hydro-training/output/lesson4/run_gridded_baseline
cp ~/wrf-hydro-training/wrf_hydro_nwm_public/trunk/NDHMS/Run/wrf_hydro.exe \
~/wrf-hydro-training/output/lesson4/run_gridded_baseline

# Create symbolic links to large domain files
cp -as $HOME/wrf-hydro-training/example_case/FORCING \
~/wrf-hydro-training/output/lesson4/run_gridded_baseline
cp -as $HOME/wrf-hydro-training/example_case/Gridded/DOMAIN \
~/wrf-hydro-training/output/lesson4/run_gridded_baseline
cp -as $HOME/wrf-hydro-training/example_case/Gridded/RESTART \
~/wrf-hydro-training/output/lesson4/run_gridded_baseline

# Copy namelist files
cp ~/wrf-hydro-training/example_case/Gridded/namelist.hrldas \
~/wrf-hydro-training/output/lesson4/run_gridded_baseline
cp ~/wrf-hydro-training/example_case/Gridded/hydro.namelist \
~/wrf-hydro-training/output/lesson4/run_gridded_baseline

# Run the simulation
cd ~/wrf-hydro-training/output/lesson4/run_gridded_baseline
mpirun -np 2 ./wrf_hydro.exe >> run.log 2>&1
In [2]:
%%bash
# Check that it finished successfully
tail -1 ~/wrf-hydro-training/output/lesson4/run_gridded_baseline/diag_hydro.00000
 The model finished successfully.......

Experimenting with run-time options

Setup

In this section we will run a few different simulations with different run-time options and explore their effects on the model output.

We will create a new simulation directory for each experiment. First, we will make a new simulation directory as we did with the baseline run above and use this as a template for creating multiple new simulation directories.

Step 1: Create a simulation directory to use as a template

In [3]:
%%bash
# Make a new directory for our baseline simulation
mkdir -p ~/wrf-hydro-training/output/lesson4/run_gridded_template

# Copy our model files to the simulation directory
cp ~/wrf-hydro-training/wrf_hydro_nwm_public/trunk/NDHMS/Run/*.TBL \
~/wrf-hydro-training/output/lesson4/run_gridded_template
cp ~/wrf-hydro-training/wrf_hydro_nwm_public/trunk/NDHMS/Run/wrf_hydro.exe \
~/wrf-hydro-training/output/lesson4/run_gridded_template

# Create symbolic links to large domain files
cp -as $HOME/wrf-hydro-training/example_case/FORCING \
~/wrf-hydro-training/output/lesson4/run_gridded_template
cp -as $HOME/wrf-hydro-training/example_case/Gridded/DOMAIN \
~/wrf-hydro-training/output/lesson4/run_gridded_template
cp -as $HOME/wrf-hydro-training/example_case/Gridded/RESTART \
~/wrf-hydro-training/output/lesson4/run_gridded_template

# Copy namelist files
cp ~/wrf-hydro-training/example_case/Gridded/namelist.hrldas \
~/wrf-hydro-training/output/lesson4/run_gridded_template
cp ~/wrf-hydro-training/example_case/Gridded/hydro.namelist \
~/wrf-hydro-training/output/lesson4/run_gridded_template

Step 2: View the contents

In [4]:
%%bash
ls ~/wrf-hydro-training/output/lesson4/run_gridded_template
CHANPARM.TBL
DOMAIN
FORCING
GENPARM.TBL
HYDRO.TBL
MPTABLE.TBL
RESTART
SOILPARM.TBL
hydro.namelist
namelist.hrldas
wrf_hydro.exe

We now have our template simulation directory ready to go. In each experiment we will copy this directory and edit the two namelist files namelist.hrldas and hydro.namelist to change run-time options.

Experiment 1 - Warm vs Cold start

Background

A model cold start is when you start your simulation with default initial conditions. In this case, model states are initialized from the wrfinput.nc file (land surface states) and GWBUCKPARM.nc (groundwater bucket states, if active). Often these initial values are guesses at global, physically plausible starting values. However, model states like soil moisture, groundwater levels, and stream levels need time to adjust to local climate and environment. So in most cases, we first spinup the model to reach an equilibrium state before launching a model experiment and evaluating output. Model states at the end of this spinup period can be used to warm start a simulation. A warm start is when the model simulation begins with the simulated values from a previous run. How long you need to spinup your model varies based on the local climate (e.g., drier climates generally take longer than wetter climates), the variables you are interested in (e.g., a fast stabilizing state like shallow soil moisture vs. a slower evolving state like deep groundwater), and local topography and soil types (e.g., sands have shorter memory than clays).

Objective

The goal of this experiment is to demonstrate the effect of starting a simulation from a cold stat vs. a warm start. The Gridded baseline run was started from a warm start, so all we need to do is construct a simulation directory and edit the namelists to start from a cold start.

Create experiment simulation directory

We will copy our template directory ~/wrf-hydro-training/output/lesson4/run_gridded_template and edit the namelist.hrldas and hydro.namelist files to start the model from a cold start.

In [5]:
%%bash
cp -r ~/wrf-hydro-training/output/lesson4/run_gridded_template ~/wrf-hydro-training/output/lesson4/run_cold_start

Edit the namelists and run the simulation

If restart files are not provided in the namelist.hrldas and hydro.namelist files then the simulation will start from a cold start.

Step 1: Edit the namelist.hrldas file Comment out this line RESTART_FILENAME_REQUESTED = "RESTART/RESTART.2017111100_DOMAIN1" in the namelist.hrldas by adding ! to the start of the line.

!RESTART_FILENAME_REQUESTED = "RESTART/RESTART.2017111100_DOMAIN1"

Step 2: Edit the hydro.namelist file Comment out this line RESTART_FILE = 'RESTART/HYDRO_RST.2011-08-26_00_00_DOMAIN1' in the hydro.namelist by adding ! to the start of the line.

! Specify the name of the restart file if starting from restart...comment out with '!' if not...
!RESTART_FILE  = 'RESTART/HYDRO_RST.2017-11-11_00:00_DOMAIN1'

Tell the code to use GWBUCKPARM.nc initialization values vs. the restart file starting states by editing the GW_RESTART option in the hydro.namelist.

! Specify baseflow/bucket model initialization...(0=cold start from table, 1=restart file)
GW_RESTART = 0

Step 3: Run the simulation

In [6]:
%%bash
cd ~/wrf-hydro-training/output/lesson4/run_cold_start
mpirun -np 2 ./wrf_hydro.exe >> run.log 2>&1

Step 4: Check that the simulation finished successfully

In [7]:
%%bash
tail -1 ~/wrf-hydro-training/output/lesson4/run_cold_start/diag_hydro.00000
 The model finished successfully.......

Results

We will now look at the differences in streamflow between our warm start simulation represented by the run_gridded_baseline simulation and our cold start simulation that we ran during this experiment.

We will use Python and the xarray library to create hydrographs and 2d plots of soil moisture. For an intro to these tools, please see Lesson 3.

Load the xarray python package

In [8]:
# Load the xarray package
%matplotlib inline
import xarray as xr
import matplotlib.pyplot as plt
import pandas as pd

Hydrographs

Load the CHANOBS streamflow datasets

We are going to use the CHANOBS output files to extract the streamflow time series. CHANOBS output files contain information for only the grid cells where we have specified a gage is located.

In [9]:
chanobs_baseline = xr.open_mfdataset('/home/docker/wrf-hydro-training/output/lesson4/run_gridded_baseline/*CHANOBS*',
                            combine='by_coords')
chanobs_cold = xr.open_mfdataset('/home/docker/wrf-hydro-training/output/lesson4/run_cold_start/*CHANOBS*',
                            combine='by_coords')
obs = pd.read_csv('/home/docker/wrf-hydro-training/example_case/obs_event.csv',dtype=str)
obs['dateTime'] = pd.to_datetime(obs['DATE'])
obs['streamflow_cms'] = pd.to_numeric(obs['streamflow_cms'])

Plot the hydrographs

In [10]:
fig, axes = plt.subplots(ncols=1,figsize=(12, 6))
plt.suptitle('Hydrographs for warm and cold starts',fontsize=24)
chanobs_baseline.sel(feature_id = 3).streamflow.plot(label='Warm start',
                                                     color='black',
                                                     linestyle='--')
chanobs_cold.sel(feature_id = 3).streamflow.plot(label='Cold start',
                                                        color='blue',
                                                        linestyle='-')
obs[obs['Location'] == 'Desague'].plot(x='dateTime',
                                       y='streamflow_cms',
                                       ax=axes,
                                       label='Observed',
                                       color='grey')
plt.legend()
plt.show()
/home/docker/miniconda3/lib/python3.7/site-packages/pandas/plotting/_matplotlib/converter.py:102: FutureWarning: Using an implicitly registered datetime converter for a matplotlib plotting method. The converter was registered by pandas on import. Future versions of pandas will require you to explicitly register matplotlib converters.

To register the converters:
	>>> from pandas.plotting import register_matplotlib_converters
	>>> register_matplotlib_converters()
  warnings.warn(msg, FutureWarning)

Soil moisture at start of simulation

The option t0OutputFlag in the hydro.namelist can be used to output models states at the start of the simulation.

! Option to write output files at time 0 (restart cold start time): 0=no, 1=yes (default)
t0OutputFlag = 1

We had this option set to 1 for both of our simulations so that we have outputs at the first timestep.

Load the LDASOUT datasets from the land surface model

In [11]:
ldasout_baseline = xr.open_mfdataset('/home/docker/wrf-hydro-training/output/lesson4/run_gridded_baseline/*LDASOUT*',
                            combine='by_coords')
ldasout_cold = xr.open_mfdataset('/home/docker/wrf-hydro-training/output/lesson4/run_cold_start/*LDASOUT*',
                            combine='by_coords')

Plot soil moisture at start of simulation

In [12]:
# Select data for t=0 at surface layer
ldasout_baseline_t0 = ldasout_baseline.sel(time = '2017-11-11T00:00:00').sel(soil_layers_stag = 0)
ldasout_cold_t0 = ldasout_cold.sel(time = '2017-11-11T00:00:00').sel(soil_layers_stag = 0)

fig, axes = plt.subplots(ncols=2,figsize=(12, 6))
plt.suptitle('Surface soil moisture states at t=0 for warm and cold starts',fontsize=24)
ldasout_baseline_t0.SOIL_M.plot(ax=axes[0],vmin=0.1,vmax=0.5)
axes[0].set_title('Warm start')
ldasout_cold_t0.SOIL_M.plot(ax=axes[1],vmin=0.1,vmax=0.5)
axes[1].set_title('Cold start')
plt.show()

Discussion

Note that the streamflow for the cold start at the start of the simulation is 0 while the streamflow from the warm start (baseline) is > 0. Additionally, the cold start simulation begins with relatively low soil moisture (coming from the SMOIS variable in wrfinput_d01.nc file) while the warm start simulation begins with higher soil moisture content (coming from the restart file). As a result they have different responses to the rainfall event. Since the cold-start simulation responds to the first peak and undergoes a "first flush" type of response, the soil column fills up early and then drains out. By the time the second event comes, the soil is relatively drier, it has a higher capacity to store water and therefore more precipitation is partitioned to soil moisture (vs. runoff) compared to the warm-start simulation. This is a good example of why you almost always want to spinup your model prior to analyzing output.

Experiment 2 - Supplemental Precipitation Data

Background

Precipitation in commonly the most important driver of hydrologic response. In some applications, for example a flood simulation, you may want to combine atmospheric analyses from reanalysis products or other models with a separate analysis of precipitation (e.g. a gridded gauge product, radar QPE, nowcasts, satellite QPE, etc). To enable such behavior, WRF-Hydro has an option (forcing type 6) to pair standard HRLDAS atmospheric forcing files with supplemental precipitation files.

Objective

Demonstrate the use of supplemental precipiation data for forcing our simulation.

Create experiment simulation directory

First we will copy our template directory ~/wrf-hydro-training/output/lesson4/run_gridded_template to create a new simulation directory for this experiment.

In [13]:
%%bash
cp -r ~/wrf-hydro-training/output/lesson4/run_gridded_template \
~/wrf-hydro-training/output/lesson4/run_supp_precip

Edit the namelist and FORCING data and run the simulation

Step 1: Edit the namelist.hrldas

The forcing data type is specified in the namelist.hrldas file with the variable FORC_TYP. We will change the value from FORC_TYP=1 for standard HRLDAS hourly format data (all input variables combined into a single LDASIN file per timestep) to FORC_TYP=6, which reads both the standard HRLDAS hourly input files AND supplemental precipitation data files.

&WRF_HYDRO_OFFLINE

! Specification of forcing data:  1=HRLDAS-hr format, 2=HRLDAS-min format, 3=WRF,
!    4=Idealized, 5=Ideal w/ Spec.Precip., 6=HRLDAS-hrl y fomat w/ Spec. Precip,
FORC_TYP = 6

Step 2: Extract the supplemental precipitation data included with the example case

In the supplemental folder in the example case there is a tar file supp_precip.tar.gz containing regridded StageIV precipitation data. We will extract this to use for augmenting our FORCING data.

In [14]:
%%bash
cd ~/wrf-hydro-training/example_case/supplemental/
tar -xf ~/wrf-hydro-training/example_case/supplemental/supplemental_precip_gpm.tar.gz 
ls ~/wrf-hydro-training/example_case/supplemental/GPM | head -10
201711210000.PRECIP_FORCING.nc
201711210030.PRECIP_FORCING.nc
201711210100.PRECIP_FORCING.nc
201711210130.PRECIP_FORCING.nc
201711210200.PRECIP_FORCING.nc
201711210230.PRECIP_FORCING.nc
201711210300.PRECIP_FORCING.nc
201711210330.PRECIP_FORCING.nc
201711210400.PRECIP_FORCING.nc
201711210430.PRECIP_FORCING.nc

Step 3: Create a symlink to the supplemental precipitation data

We will add in our supplemental precipitation data to the FORCING folder. Since these data can be rather large we will create a symbolic link.

In [15]:
%%bash
ln -s ~/wrf-hydro-training/example_case/supplemental/GPM/2017* \
~/wrf-hydro-training/output/lesson4/run_supp_precip/FORCING/

Lets take a look at the FORCING directory with the new data.

In [16]:
%%bash
ls ~/wrf-hydro-training/output/lesson4/run_supp_precip/FORCING/ | head -10
2017111000.LDASIN_DOMAIN1
2017111003.LDASIN_DOMAIN1
2017111006.LDASIN_DOMAIN1
2017111009.LDASIN_DOMAIN1
2017111012.LDASIN_DOMAIN1
2017111015.LDASIN_DOMAIN1
2017111018.LDASIN_DOMAIN1
2017111021.LDASIN_DOMAIN1
2017111100.LDASIN_DOMAIN1
2017111103.LDASIN_DOMAIN1

Now you see two files per hour. The PRECIP_FORCING files will be used for precipitation inputs and LDASIN_DOMAIN files will be used for all other forcing fields (e.g., temperature, radiation, wind). Note that the supplemental PRECIP_FORCING files are always specified to the minute.

Step 3: Run the simulation

In [21]:
%%bash
cd ~/wrf-hydro-training/output/lesson4/run_supp_precip
mpirun -np 2 ./wrf_hydro.exe >> run.log 2>&1

Results

We will now look at the differences in streamflow between our baseline run with GLDAS precipitation and our experiment with supplemental GPM precipitation.

We will use Python and the xarray library to load the data and plot hydrographs. For an intro to these tools, please see lesson 3.

Load the xarray python package

In [22]:
# Load the xarray package
%matplotlib inline
import xarray as xr
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

Hydrographs

Load the CHANOBS streamflow datasets

Again, we use the CHANOBS files to import the streamflow timeseries at specified gage locations.

In [23]:
chanobs_baseline = xr.open_mfdataset('/home/docker/wrf-hydro-training/output/lesson4/run_gridded_baseline/*CHANOBS*',
                            combine='by_coords')
chanobs_supp_precip = xr.open_mfdataset('/home/docker/wrf-hydro-training/output/lesson4/run_supp_precip/*CHANOBS*',
                            combine='by_coords')
obs = pd.read_csv('/home/docker/wrf-hydro-training/example_case/obs_event.csv',dtype=str)
obs['dateTime'] = pd.to_datetime(obs['DATE'])
obs['streamflow_cms'] = pd.to_numeric(obs['streamflow_cms'])

Plot the hydrographs

In [24]:
fig, axes = plt.subplots(ncols=1,figsize=(12, 6))
plt.suptitle('Hydrographs for GLDAS and GPM forcing',fontsize=24)
chanobs_baseline.sel(feature_id = 3).streamflow.plot(label='GLDAS',
                                                     color='black',
                                                     linestyle='--')
chanobs_supp_precip.sel(feature_id = 3).streamflow.plot(label='GPM',
                                                        color='blue',
                                                        linestyle='-')
obs[obs['Location'] == 'Desague'].plot(x='dateTime',
                                       y='streamflow_cms',
                                       ax=axes,
                                       label='Observed',
                                       color='grey')
plt.legend()
plt.show()

Precipitation data

We read in the precipitation time series data from the two different products using xarray.

In [26]:
ldasin = xr.open_mfdataset('/home/docker/wrf-hydro-training/output/lesson4/run_gridded_baseline/FORCING/*LDASIN*',
                            combine='nested', concat_dim='Time')
gpm = xr.open_mfdataset('/home/docker/wrf-hydro-training/output/lesson4/run_supp_precip/FORCING/*PRECIP*',
                            combine='nested', concat_dim='Time')

def fix_times(ds_in):
    times_strings = list(map(lambda x: x.decode('utf-8'), ds_in['Times'].values))
    ds_in['Times'] = ('Time', pd.to_datetime(times_strings, format='%Y-%m-%d_%H:%M:%S'))
    ds_in = ds_in.assign(Time=ds_in['Times']).drop('Times')
    return ds_in

ldasin = fix_times(ldasin)
gpm = fix_times(gpm)

Now we calculate a domain-wide mean precipitation time series and plots the two products.

In [27]:
# Calculate the mean precipitation rate (mm/hr) across the domain
ldasin_avg = ldasin.RAINRATE.mean(dim=('south_north','west_east')) * 3600
gpm_avg = gpm.precip_rate.mean(dim=('south_north','west_east')) * 3600

# Plot the precipitation time series
fig, axes = plt.subplots(ncols=1,figsize=(12, 6))
plt.suptitle('Hyetograph for GLDAS and GPM forcing',fontsize=24)
ldasin_avg.plot(label='GLDAS', color='black', linestyle='--')
gpm_avg.plot(label='GPM', color='blue', linestyle='-')
plt.legend()
plt.show()

GPM shows more precipitation and higher peaks, delayed from the GLDAS data. GLDAS is a coarser product which can also miss fast synoptic events.

Since the two products have different native spatial (GLDAS is ~13km while GPM is ~8km) and temporal resolutions (GLDAS is 3 hourly, GPM is 30 minute) we should also be careful to compare these as equivalent. To examine the spatial patterns of precipitation, let's check values from the 2D grids.

In [28]:
# Select data for roughly middle of event
ldasin_tmid = ldasin.sel(Time='2017-11-22 00:00:00')
gpm_tmid = gpm.sel(Time='2017-11-22 00:00:00')

# Plot the 2D precipitation grids at hour 270.
fig, axes = plt.subplots(ncols=2,figsize=(12, 6))
plt.suptitle('Precipitation rate for gldas and gpm',fontsize=24)
ldasin_tmid['RAINRATE'] = ldasin_tmid.RAINRATE*3600
ldasin_tmid.RAINRATE.plot(ax=axes[0],vmin=0,vmax=10)
axes[0].set_title('GLDAS')
gpm_tmid['precip_rate'] = gpm_tmid.precip_rate*3600
gpm_tmid.precip_rate.plot(ax=axes[1],vmin=0,vmax=10)
axes[1].set_title('GPM')
plt.show()

Next up - Exploring terrain physics

This concludes lesson 4. In the next lesson, we will explore terrain physics options and parameters.

IT IS BEST TO EITHER SHUTDOWN THIS LESSON OR CLOSE IT BEFORE PROCEEDING TO THE NEXT LESSON TO AVOID POSSIBLY EXCEEDING ALLOCATED MEMORY. Shutdown the lesson be either closing the browser tab for the lesson or selecting KERNAL->SHUTDOWN in the jupyter notebook toolbar.