# Table of Contents

# 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.