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 experiment with few different 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.
In this section, we quickly recap the commands issued in Lessons 1 and 2 to compile WRF-Hydro and create our simulation directory. We use the prepared domain for the remaining lessons, but feel free to replace the prepared domain with the domain you create in the geospatial hands-on training session.
NOTE: Your domain directory structure and filenames must match the prepared domain EXACTLY
Below are the commands to compile WRF-Hydro.
%%bash
# Change to the trunk/NDHMS directory and configure for GNU gfortran
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
Configured: gfort
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 soil 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
# WCOSS file units: 0=Off, 1=On.
export NCEP_WCOSS=0
# NWM output metadata: 0=Off, 1=On.
export NWM_META=0
# Streamflow nudging: 0=Off, 1=On.
export WRF_HYDRO_NUDGING=0
Compile WRF-Hydro in standalone mode
%%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
***************************************************************** Make was successful ***************************************************************** The environment variables used in the compile: HYDRO_D=1 NCEP_WCOSS=0 NETCDF=/usr/local SPATIAL_SOIL=1 WRF_HYDRO=1 WRF_HYDRO_NUDGING=0 WRF_HYDRO_RAPID=0
We have successfully compiled WRF-Hydro and we will use this binary and *.TBL files for the remaining simulations in this lesson
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.
%%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
%%bash
# Check that it finished successfully
tail -1 ~/wrf-hydro-training/output/lesson4/run_gridded_baseline/diag_hydro.00000
The model finished successfully.......
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
%%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
%%bash
ls ~/wrf-hydro-training/output/lesson4/run_gridded_template
CHANPARM.TBL DOMAIN FORCING GENPARM.TBL hydro.namelist HYDRO.TBL MPTABLE.TBL namelist.hrldas RESTART SOILPARM.TBL 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.
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).
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.
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.
%%bash
cp -r ~/wrf-hydro-training/output/lesson4/run_gridded_template ~/wrf-hydro-training/output/lesson4/run_cold_start
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.2011082600_DOMAIN1"
in the namelist.hrldas by adding !
to the start of the line.
!RESTART_FILENAME_REQUESTED = "RESTART/RESTART.2011082600_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.2011-08-26_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
%%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
%%bash
tail -1 ~/wrf-hydro-training/output/lesson4/run_cold_start/diag_hydro.00000
The model finished successfully.......
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
# Load required packages
import xarray as xr
import matplotlib.pyplot as plt
import pandas as pd
import datetime as dt
xr.set_options(display_style="html")
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
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.
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/USGS_obs.csv',dtype=str)
obs['dateTime'] = pd.to_datetime(obs['dateTime'])
obs['streamflow_cms'] = pd.to_numeric(obs['streamflow_cms'])
Plot the hydrographs
Table 1. USGS Stream Gage IDs and associated WRF-Hydro feature_id indices.
USGS Gage ID | WRF-Hydro gage feature_id | Gage Information |
---|---|---|
01447680 | 1 | https://waterdata.usgs.gov/pa/nwis/uv/?site_no=01447680 |
01447720 | 2 | https://waterdata.usgs.gov/nwis/nwismap/?site_no=01447720 |
fig, axes = plt.subplots(ncols=1,figsize=(12, 6))
plt.suptitle('Hydrographs for warm and cold starts',fontsize=24)
chanobs_baseline.sel(feature_id = 2).streamflow.plot(label='Warm start',
color='red',
linestyle='--')
chanobs_cold.sel(feature_id = 2).streamflow.plot(label='Cold start',
color='blue',
linestyle='dotted')
obs[obs['site_no'] == '01447720'].plot(x='dateTime',
y='streamflow_cms',
ax=axes,
label='Observed',
color='gray')
plot_times = chanobs_baseline.time.data
plot_time_buffer = pd.to_timedelta(2, unit='D')
plt.xlim([plot_times.min()-plot_time_buffer, plot_times.max()+plot_time_buffer])
plt.legend()
plt.show()
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
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
# Select data for t=0 at surface layer
ldasout_baseline_t0 = ldasout_baseline.isel(time = 0).sel(soil_layers_stag = 0)
ldasout_cold_t0 = ldasout_cold.isel(time = 0).sel(soil_layers_stag = 0)
fig, axes = plt.subplots(ncols=2,figsize=(15, 6))
plt.subplots_adjust(wspace=.5)
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()
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 the 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 in the cold-start simulation 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.
Precipitation is 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.
Demonstrate the use of supplemental precipitation data for forcing our simulation.
First we will copy our template directory ~/wrf-hydro-training/output/lesson4/run_gridded_template
to create a new simulation directory for this experiment.
%%bash
cp -r ~/wrf-hydro-training/output/lesson4/run_gridded_template \
~/wrf-hydro-training/output/lesson4/run_supp_precip
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.
%%bash
cd ~/wrf-hydro-training/example_case/supplemental/
tar -xf ~/wrf-hydro-training/example_case/supplemental/supp_precip.tar.gz
ls ~/wrf-hydro-training/example_case/supplemental/supp_precip | head -10
201108010000.PRECIP_FORCING.nc 201108010100.PRECIP_FORCING.nc 201108010200.PRECIP_FORCING.nc 201108010300.PRECIP_FORCING.nc 201108010400.PRECIP_FORCING.nc 201108010500.PRECIP_FORCING.nc 201108010600.PRECIP_FORCING.nc 201108010700.PRECIP_FORCING.nc 201108010800.PRECIP_FORCING.nc 201108010900.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.
%%bash
ln -sf ~/wrf-hydro-training/example_case/supplemental/supp_precip/20110* \
~/wrf-hydro-training/output/lesson4/run_supp_precip/FORCING/
Lets take a look at the FORCING
directory with the new data.
%%bash
ls ~/wrf-hydro-training/output/lesson4/run_supp_precip/FORCING/ | head -10
201108010000.PRECIP_FORCING.nc 201108010100.PRECIP_FORCING.nc 201108010200.PRECIP_FORCING.nc 201108010300.PRECIP_FORCING.nc 201108010400.PRECIP_FORCING.nc 201108010500.PRECIP_FORCING.nc 201108010600.PRECIP_FORCING.nc 201108010700.PRECIP_FORCING.nc 201108010800.PRECIP_FORCING.nc 201108010900.PRECIP_FORCING.nc
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
%%bash
cd ~/wrf-hydro-training/output/lesson4/run_supp_precip
mpirun -np 2 ./wrf_hydro.exe >> run.log 2>&1
tail -1 ~/wrf-hydro-training/output/lesson4/run_cold_start/diag_hydro.00000
We will now look at the differences in streamflow between our baseline run with NLDAS precipitation and our experiment with supplemental StageIV precipitation.
Load the CHANOBS streamflow datasets
Again, we use the CHANOBS files to import the streamflow timeseries at specified gage locations.
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')
Plot the hydrographs
fig, axes = plt.subplots(ncols=1,figsize=(12, 6))
plt.suptitle('Hydrographs for NLDAS and Stage IV forcing',fontsize=24)
chanobs_baseline.sel(feature_id = 2).streamflow.plot(label='NLDAS',
color='red',
linestyle='--')
chanobs_supp_precip.sel(feature_id = 2).streamflow.plot(label='Stage IV',
color='blue',
linestyle='dotted')
plot_times = chanobs_baseline.time.data
plot_time_buffer = pd.to_timedelta(2, unit='D')
plt.xlim([plot_times.min()-plot_time_buffer, plot_times.max()+plot_time_buffer])
plt.legend()
plt.show()
We read in the precipitation time series data from the two different products using xarray.
ldasin = xr.open_mfdataset('/home/docker/wrf-hydro-training/output/lesson4/run_gridded_baseline/FORCING/*LDASIN*',
combine='nested', concat_dim='Time')
stageiv = xr.open_mfdataset('/home/docker/wrf-hydro-training/output/lesson4/run_supp_precip/FORCING/*PRECIP*',
combine='nested', concat_dim='Time')
# Add a coordinate variable for time to aid in plotting
ldasin = ldasin.assign_coords(Time=pd.to_datetime(ldasin['Times'].data.astype(str), format='%Y-%m-%d_%X'))
stageiv = stageiv.assign_coords(Time=pd.to_datetime(stageiv['Times'].data.astype(str), format='%Y-%m-%d_%X'))
stageiv.precip_rate
<xarray.DataArray 'precip_rate' (Time: 1464, south_north: 28, west_east: 22)> dask.array<concatenate, shape=(1464, 28, 22), dtype=float64, chunksize=(1, 28, 22), chunktype=numpy.ndarray> Coordinates: * Time (Time) datetime64[ns] 2011-08-01 ... 2011-09-30T23:00:00 Dimensions without coordinates: south_north, west_east Attributes: remap: remapped via ESMF_regrid_with_weights: Bilinear description: precipitation rate sub_center: Environmental Modeling Center center: US National Weather Service - NCEP (WMC) long_name: precip_rate units: mm s^-1 level_indicator: 1 gds_grid_type: 5 parameter_table_version: 2 parameter_number: 61 model: River Forecast Center Quantitative Precipitatio... forecast_time: 1 forecast_time_units: hours initial_time: 07/31/2011 (23:00)
|
array(['2011-08-01T00:00:00.000000000', '2011-08-01T01:00:00.000000000', '2011-08-01T02:00:00.000000000', ..., '2011-09-30T21:00:00.000000000', '2011-09-30T22:00:00.000000000', '2011-09-30T23:00:00.000000000'], dtype='datetime64[ns]')
Now we calculate a domain-wide mean precipitation time series and plots the two products.
# Calculate the mean precipitation rate (mm/hr) across the domain
ldasin_avg = ldasin.RAINRATE.mean(dim=('south_north','west_east')) * 3600
stageiv_avg = stageiv.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 NLDAS and Stage IV forcing',fontsize=24)
ldasin_avg.plot(label='NLDAS', color='black', linestyle='--')
stageiv_avg.plot(label='Stage IV', color='blue', linestyle='-')
plot_times = ldasin.Time.data
plot_time_buffer = pd.to_timedelta(1, unit='D')
plt.xlim([plot_times.min()-plot_time_buffer, plot_times.max()+plot_time_buffer])
plt.legend()
plt.show()
While the domain-average precipitation time series is mostly consistent between the products, Stage IV shows somewhat lower precipitation towards the end of the event.
Since the two products have different native spatial resolutions (NLDAS is ~13km while Stage IV is ~4km), we should also examine the spatial patterns of precipitation.
# Select time of maximum precip difference
event_hr = abs(ldasin_avg - stageiv_avg).argmax().values
print('Maximum precip rate difference at timestep {0}'.format(event_hr))
# Select data for roughly middle of event
ldasin_tmid = ldasin.isel(Time = event_hr)
stageiv_tmid = stageiv.isel(Time = event_hr)
# Plot the 2D precipitation grids at hour of maximum difference.
fig, axes = plt.subplots(ncols=2,figsize=(12, 6))
plt.suptitle('Precipitation rate for nldas and stage IV',fontsize=24)
ldasin_tmid['RAINRATE'] = ldasin_tmid.RAINRATE*3600
ldasin_tmid.RAINRATE.plot(ax=axes[0],vmin=5,vmax=15)
axes[0].set_title('NLDAS')
stageiv_tmid['precip_rate'] = stageiv_tmid.precip_rate*3600
stageiv_tmid.precip_rate.plot(ax=axes[1],vmin=5,vmax=15)
axes[1].set_title('StageIV')
plt.show()
Maximum precip rate difference at timestep 35
The spatial pattern of the two precipitation forcing datasets are not very different for this event. Both Stage IV and NLDAS have similar event patterns, with flashy peaks in precipitation contributing to moderate streamflow generation.
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 Kernel -> Shut Down Kernel
in JupyterLab.
© UCAR 2020