Net longwave radiative flux in the Meteorology component

Goal: In this example, check whether the Meteorology component produces output for land_surface_net-longwave-radiation__energy_flux (Qn_LW internally) when the model state is updated, given scalar inputs for temperature and emissivity.

Begin with an import and some magic:


In [ ]:
%matplotlib inline
import numpy as np

BMI component

Import the BMI Meteorology component, create an instance, and initialize the component:


In [ ]:
from topoflow.components.met_base import met_component
m = met_component()
m.initialize('./input/meteorology.cfg')

There's no input value for Qn_LW; rather, it's calculated from temperature and emissivity values. It's initialized to an np.zeros array with the dimensions of the grid (line 951 of met_base.py):


In [ ]:
Q = m.get_value('land_surface_net-longwave-radiation__energy_flux')  # `Qn_LW` internally
print type(Q)
print Q.size
print Q.shape
Q

Advance the model by one time step:


In [ ]:
m.update()
print '\nCurrent time: {} s'.format(m.get_current_time())

Check the calculated value of Qn_LW:


In [ ]:
Q = m.get_value('land_surface_net-longwave-radiation__energy_flux')
print type(Q)
print Q.size
print Q.shape
Q

The initial Qn_LW array has been converted into a scalar.

The Qn_LW calculation starts on line 1631 of met_base.py:

#--------------------------------
# Compute Qn_LW for this time
#--------------------------------
T_air_K  = self.T_air  + self.C_to_K
T_surf_K = self.T_surf + self.C_to_K
LW_in    = self.em_air  * self.sigma * (T_air_K)** 4.0
LW_out   = self.em_surf * self.sigma * (T_surf_K)** 4.0
LW_out   = LW_out + ((1.0 - self.em_surf) * LW_in)

self.Qn_LW = (LW_in - LW_out)   # [W m-2]

The temperature and emissivity values are set to scalars in the cfg file, so Qn_LW is also a scalar.

Result: A scalar value of Qn_LW is calculated from scalar values of temperature and emissivity, which seems legit.

Babel-wrapped component

Import the Babel-wrapped Meteorology component, create an instance, and initialize the component:


In [ ]:
from cmt.components import Meteorology
bm = Meteorology()
bm.initialize('./input/meteorology.cfg')

As above, Qn_LW is initialized to an np.zeros array with the dimensions of the grid. However, the Bocca implementation flattens the array:


In [ ]:
bQ = bm.get_value('land_surface_net-longwave-radiation__energy_flux')  # `Qn_LW` internally
print type(bQ)
print bQ.size
print bQ.shape
bQ

Get the model time step (which has been broadcast over the grid):


In [ ]:
time_step = bm.get_value('model__time_step')  # `dt` internally
time_step = time_step.max()
print time_step

Advance the model by one time step:


In [ ]:
bm.update(time_step)
print '\nCurrent time: {} s'.format(bm.get_current_time())

Check the calculated value of Qn_LW:


In [ ]:
Q = bm.get_value('land_surface_net-longwave-radiation__energy_flux')
print type(Q)
print Q.size
print Q.shape
Q

The calculated value of Qn_LW matches that of the BMI case above, but it has been broadcast over the grid. This is what we expect.

Advance the model by a second time step:


In [ ]:
bm.update(2*time_step)
print '\nCurrent time: {} s'.format(bm.get_current_time())

Again, check the calculated value of Qn_LW:


In [ ]:
Q = bm.get_value('land_surface_net-longwave-radiation__energy_flux')
print type(Q)
print Q.size
print Q.shape
Q

There are no changes to the value of Qn_LW, which is expected, because there are no changes to the temperature or emissivity values.

Result: An array of Qn_LW values, matching the shape of its associated grid, are calculated from scalar values of temperature and emissivity, which is what we expect!