Coupling GIPL and ECSimpleSnow models

Before you begin, install:

conda install -c conda-forge pymt pymt_gipl pymt_ecsimplesnow seaborn


In [1]:
import pymt.models
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import matplotlib.colors as mcolors
from matplotlib.colors import LinearSegmentedColormap
sns.set(style='whitegrid', font_scale= 1.2)


➡ models: FrostNumber, Ku, Hydrotrend, GIPL, ECSimpleSnow, Cem, Waves

Load ECSimpleSnow module from PyMT


In [2]:
ec = pymt.models.ECSimpleSnow()
print(ec.name)

# List input and output variable names.
print(ec.output_var_names)
print(ec.input_var_names)


The 1D Snow Model
('snowpack__depth', 'snowpack__mass-per-volume_density')
('precipitation_mass_flux', 'land_surface_air__temperature', 'precipitation_mass_flux_adjust_factor', 'snow_class', 'open_area_or_not', 'snowpack__initial_depth', 'snowpack__initial_mass-per-volume_density')

Load GIPL module from PyMT


In [3]:
gipl = pymt.models.GIPL()
print(gipl.name)

# List input and output variable names.
print(gipl.output_var_names)
print(gipl.input_var_names)


The 1D GIPL Model
('soil__temperature', 'model_soil_layer__count')
('land_surface_air__temperature', 'snowpack__depth', 'snow__thermal_conductivity', 'soil_water__volume_fraction', 'soil_unfrozen_water__a', 'soil_unfrozen_water__b')

Call the setup method on both ECSimpleSnow and GIPL to get default configuration files and data.


In [4]:
ec_defaults = ec.setup('.')
print(ec_defaults)

gipl_defaults = gipl.setup('.')
print(gipl_defaults)


('snow_model.cfg', '/Users/mpiper/projects/GIPL-BMI-Fortran/Notebooks')
('gipl_config.cfg', '/Users/mpiper/projects/GIPL-BMI-Fortran/Notebooks')

In [5]:
ec.initialize('snow_model.cfg')

In [6]:
gipl.initialize('gipl_config.cfg')

In [7]:
# Get soil depth: [unit: m]
depth = gipl.get_grid_z(2)
n_depth = int(len(depth))

In [8]:
# Get the length of forcing data:
ntime = int(gipl.end_time)

# Define a variable to store soil temperature through the time period

tsoil = np.zeros((n_depth, ntime)) * np.nan

print('Final soil temperatures will be ', tsoil.shape)


Final soil temperatures will be  (176, 365)

In [9]:
fig = plt.figure(figsize=[12,6])

ax2 = fig.add_subplot(2,3,1)
ax2.set_title('Air Temperature (Input)')

ax3 = fig.add_subplot(2,3,2)
ax3.set_title('Precipition (Input)')

ax4 = fig.add_subplot(2,3,4)
ax4.set_title('Snow Depth (EC Output)')

ax5 = fig.add_subplot(2,3,5)
ax5.set_title('Snow Density (EC Output)')

ax1 = fig.add_subplot(2,3,(3,6))
ax1.set_ylim([15,0])
ax1.set_xlim([-20,20])
ax1.set_xlabel('Soil Temperature ($^oC$)')
ax1.set_ylabel('Depth (m)')
ax1.plot([0,0],[15,0],'k--')

for i in np.arange(365):
    
    ec.update() # Update Snow Model Once
    
    # Get output from snow model
    tair  = ec.get_value('land_surface_air__temperature')
    prec  = ec.get_value('precipitation_mass_flux')
    snd   = ec.get_value('snowpack__depth', units='m')
    rsn   = ec.get_value('snowpack__mass-per-volume_density', units = 'g cm-3')
    
    # Pass value to GIPL model
    gipl.set_value('land_surface_air__temperature', tair)
    gipl.set_value('snowpack__depth', snd)
    gipl.set_value('snow__thermal_conductivity', rsn * rsn * 2.846)
    
    gipl.update() # Update GIPL model Once
    
    tsoil[:,i] = gipl.get_value('soil__temperature') # Save results to a matrix
    
    ax1.plot(tsoil[depth>=0,i], depth[depth>=0],color = [0.7,0.7,0.7], alpha = 0.1)
    
    ax2.scatter(i, tair, c = 'k')
    ax3.scatter(i, prec, c = 'k')
    ax4.scatter(i, snd , c = 'k')
    ax5.scatter(i, rsn , c = 'k')
    
ax1.plot(tsoil[depth>=0,:].max(axis=1), depth[depth>=0], 'r', linewidth = 2, label = 'Max')
ax1.plot(tsoil[depth>=0,:].min(axis=1), depth[depth>=0], 'b', linewidth = 2, label = 'Min')
ax1.plot(tsoil[depth>=0,:].mean(axis=1), depth[depth>=0], 'k', linewidth = 2, label = 'Mean')
ax1.legend()
ax1.set_title('Ground Temperatures (GIPL output)')

ax2.set_xticks([])
ax3.set_xticks([])


Out[9]:
[]

In [10]:
fig = plt.figure(figsize=[9,4])
divnorm = mcolors.DivergingNorm(vmin=-25., vcenter=0., vmax=10)
plt.contourf(np.arange(ntime), depth, tsoil, np.linspace(-25,10,15), 
             norm = divnorm,
             cmap="RdBu_r", extend = 'both')

plt.ylim([5,0])
cb = plt.colorbar()
plt.xlabel('Day')
plt.ylabel('Depth (m)')
cb.ax.set_ylabel('Soil Temperature ($^oC$)')

plt.contour(np.arange(ntime), depth, tsoil, [0]) # ZERO


Out[10]:
<matplotlib.contour.QuadContourSet at 0x1c1c9bfeb8>

In [ ]: