INTERFACE:
subroutine BiogeophysicsLake(lbc, ubc, lbp, ubp, num_lakec, filter_lakec, &
num_lakep, filter_lakep)
DESCRIPTION:
Calculates lake temperatures and surface fluxes. Lake temperatures are determined from a one-dimensional thermal stratification model based on eddy diffusion concepts to represent vertical mixing of heat.
d ts d d ts 1 ds -- = - [(km + ke) --] + - - dt dz dz cw dz
where: ts = temperature (kelvin) t = time (s) z = depth (m) km = molecular diffusion coefficient (m**2/s) ke = eddy diffusion coefficient (m**2/s) cw = heat capacity (j/m**3/kelvin) s = heat source term (w/m**2)
There are two types of lakes: Deep lakes are 50 m. Shallow lakes are 10 m deep.
For unfrozen deep lakes: ke > 0 and convective mixing For unfrozen shallow lakes: ke = 0 and no convective mixing
Use the Crank-Nicholson method to set up tridiagonal system of equations to solve for ts at time n+1, where the temperature equation for layer i is r_i = a_i [ts_i-1] n+1 + b_i [ts_i] n+1 + c_i [ts_i+1] n+1
The solution conserves energy as:
cw*([ts( 1)] n+1 - [ts( 1)] n)*dz( 1)/dt + ... + cw*([ts(nlevlak)] n+1 - [ts(nlevlak)] n)*dz(nlevlak)/dt = fin
where: [ts] n = old temperature (kelvin) [ts] n+1 = new temperature (kelvin) fin = heat flux into lake (w/m**2) = beta*sabg + forc_lwrad - eflx_lwrad_out - eflx_sh_tot - eflx_lh_tot - hm + phi(1) + ... + phi(nlevlak)
WARNING: This subroutine assumes lake columns have one and only one pft.
USES:
use shr_kind_mod, only: r8 => shr_kind_r8
use clmtype
use clm_atmlnd , only : clm_a2l
use clm_time_manager , only : get_step_size
use clm_varpar , only : nlevlak
use clm_varcon , only : hvap, hsub, hfus, cpair, cpliq, cpice, tkwat, tkice, &
sb, vkc, grav, denh2o, tfrz, spval
use QSatMod , only : QSat
use FrictionVelocityMod, only : FrictionVelocity, MoninObukIni
use TridiagonalMod , only : Tridiagonal
ARGUMENTS:
implicit none
integer, intent(in) :: lbc, ubc ! column-index bounds
integer, intent(in) :: lbp, ubp ! pft-index bounds
integer, intent(in) :: num_lakec ! number of column non-lake points in column filter
integer, intent(in) :: filter_lakec(ubc-lbc+1) ! column filter for non-lake points
integer, intent(in) :: num_lakep ! number of column non-lake points in pft filter
integer, intent(in) :: filter_lakep(ubp-lbp+1) ! pft filter for non-lake points
CALLED FROM:
subroutine clm_driver1REVISION HISTORY:
Author: Gordon Bonan 15 September 1999: Yongjiu Dai; Initial code 15 December 1999: Paul Houser and Jon Radakovich; F90 Revision Migrated to clm2.1 new data structures by Peter Thornton and M. VertensteinLOCAL VARIABLES:
local pointers to implicit in arguments
integer , pointer :: pcolumn(:) ! pft's column index
integer , pointer :: pgridcell(:) ! pft's gridcell index
integer , pointer :: cgridcell(:) ! column's gridcell index
real(r8), pointer :: forc_t(:) ! atmospheric temperature (Kelvin)
real(r8), pointer :: forc_pbot(:) ! atmospheric pressure (Pa)
real(r8), pointer :: forc_hgt_u_pft(:) ! observational height of wind at pft level [m]
real(r8), pointer :: forc_hgt_t_pft(:) ! observational height of temperature at pft level [m]
real(r8), pointer :: forc_hgt_q_pft(:) ! observational height of specific humidity at pft level [m]
real(r8), pointer :: forc_th(:) ! atmospheric potential temperature (Kelvin)
real(r8), pointer :: forc_q(:) ! atmospheric specific humidity (kg/kg)
real(r8), pointer :: forc_u(:) ! atmospheric wind speed in east direction (m/s)
real(r8), pointer :: forc_v(:) ! atmospheric wind speed in north direction (m/s)
real(r8), pointer :: forc_lwrad(:) ! downward infrared (longwave) radiation (W/m**2)
real(r8), pointer :: forc_rho(:) ! density (kg/m**3)
real(r8), pointer :: forc_snow(:) ! snow rate [mm/s]
real(r8), pointer :: forc_rain(:) ! rain rate [mm/s]
real(r8), pointer :: t_grnd(:) ! ground temperature (Kelvin)
real(r8), pointer :: hc_soisno(:) ! soil plus snow plus lake heat content (MJ/m2)
real(r8), pointer :: h2osno(:) ! snow water (mm H2O)
real(r8), pointer :: snowdp(:) ! snow height (m)
real(r8), pointer :: sabg(:) ! solar radiation absorbed by ground (W/m**2)
real(r8), pointer :: lat(:) ! latitude (radians)
real(r8), pointer :: dz(:,:) ! layer thickness (m)
real(r8), pointer :: z(:,:) ! layer depth (m)
local pointers to implicit out arguments
real(r8), pointer :: qflx_prec_grnd(:) ! water onto ground including canopy runoff [kg/(m2 s)]
real(r8), pointer :: qflx_evap_soi(:) ! soil evaporation (mm H2O/s) (+ = to atm)
real(r8), pointer :: qflx_evap_tot(:) ! qflx_evap_soi + qflx_evap_can + qflx_tran_veg
real(r8), pointer :: qflx_snwcp_liq(:) ! excess rainfall due to snow capping (mm H2O /s) [+]`
real(r8), pointer :: qflx_snwcp_ice(:) ! excess snowfall due to snow capping (mm H2O /s) [+]`
real(r8), pointer :: eflx_sh_grnd(:) ! sensible heat flux from ground (W/m**2) [+ to atm]
real(r8), pointer :: eflx_lwrad_out(:) ! emitted infrared (longwave) radiation (W/m**2)
real(r8), pointer :: eflx_lwrad_net(:) ! net infrared (longwave) rad (W/m**2) [+ = to atm]
real(r8), pointer :: eflx_soil_grnd(:) ! soil heat flux (W/m**2) [+ = into soil]
real(r8), pointer :: eflx_sh_tot(:) ! total sensible heat flux (W/m**2) [+ to atm]
real(r8), pointer :: eflx_lh_tot(:) ! total latent heat flux (W/m8*2) [+ to atm]
real(r8), pointer :: eflx_lh_grnd(:) ! ground evaporation heat flux (W/m**2) [+ to atm]
real(r8), pointer :: t_veg(:) ! vegetation temperature (Kelvin)
real(r8), pointer :: t_ref2m(:) ! 2 m height surface air temperature (Kelvin)
real(r8), pointer :: q_ref2m(:) ! 2 m height surface specific humidity (kg/kg)
real(r8), pointer :: rh_ref2m(:) ! 2 m height surface relative humidity (%)
real(r8), pointer :: taux(:) ! wind (shear) stress: e-w (kg/m/s**2)
real(r8), pointer :: tauy(:) ! wind (shear) stress: n-s (kg/m/s**2)
real(r8), pointer :: qmelt(:) ! snow melt [mm/s]
real(r8), pointer :: ram1(:) ! aerodynamical resistance (s/m)
real(r8), pointer :: errsoi(:) ! soil/lake energy conservation error (W/m**2)
real(r8), pointer :: t_lake(:,:) ! lake temperature (Kelvin)
!OTHER LOCAL VARIABLES: