diff --git a/CMakeLists.txt b/CMakeLists.txt
index db576a054f..226aea148a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -85,6 +85,7 @@ add_library(fv3atm
cpl/module_block_data.F90
cpl/module_cplfields.F90
cpl/module_cap_cpl.F90
+ io/clm_lake_io.F90
io/FV3GFS_io.F90
io/FV3GFS_restart_io.F90
io/module_write_netcdf.F90
diff --git a/ccpp/config/ccpp_prebuild_config.py b/ccpp/config/ccpp_prebuild_config.py
index dda560ed57..aaf540bcc3 100755
--- a/ccpp/config/ccpp_prebuild_config.py
+++ b/ccpp/config/ccpp_prebuild_config.py
@@ -183,6 +183,7 @@
'physics/physics/lsm_noah.f',
'physics/physics/noahmpdrv.F90',
'physics/physics/flake_driver.F90',
+ 'physics/physics/clm_lake.f90',
'physics/physics/sfc_nst_pre.f',
'physics/physics/sfc_nst.f',
'physics/physics/sfc_nst_post.f',
diff --git a/ccpp/data/CCPP_typedefs.F90 b/ccpp/data/CCPP_typedefs.F90
index b886beb3e4..9a6a387ba0 100644
--- a/ccpp/data/CCPP_typedefs.F90
+++ b/ccpp/data/CCPP_typedefs.F90
@@ -184,7 +184,6 @@ module CCPP_typedefs
integer, pointer :: idxday(:) => null() !<
logical, pointer :: icy(:) => null() !<
logical, pointer :: lake(:) => null() !<
- logical, pointer :: use_flake(:) => null() !<
logical, pointer :: ocean(:) => null() !<
integer :: ipr !<
integer, pointer :: islmsk(:) => null() !<
@@ -647,7 +646,6 @@ subroutine gfs_interstitial_create (Interstitial, IM, Model)
allocate (Interstitial%idxday (IM))
allocate (Interstitial%icy (IM))
allocate (Interstitial%lake (IM))
- allocate (Interstitial%use_flake (IM))
allocate (Interstitial%ocean (IM))
allocate (Interstitial%islmsk (IM))
allocate (Interstitial%islmsk_cice (IM))
@@ -1327,7 +1325,6 @@ subroutine gfs_interstitial_phys_reset (Interstitial, Model)
Interstitial%dry = .false.
Interstitial%icy = .false.
Interstitial%lake = .false.
- Interstitial%use_flake = .false.
Interstitial%ocean = .false.
Interstitial%islmsk = 0
Interstitial%islmsk_cice = 0
diff --git a/ccpp/data/CCPP_typedefs.meta b/ccpp/data/CCPP_typedefs.meta
index 09c4feda55..3fd32d7c96 100644
--- a/ccpp/data/CCPP_typedefs.meta
+++ b/ccpp/data/CCPP_typedefs.meta
@@ -1238,12 +1238,6 @@
units = flag
dimensions = (horizontal_loop_extent)
type = logical
-[use_flake]
- standard_name = flag_for_using_flake
- long_name = flag indicating lake points using flake model
- units = flag
- dimensions = (horizontal_loop_extent)
- type = logical
[ocean]
standard_name = flag_nonzero_ocean_surface_fraction
long_name = flag indicating presence of some ocean surface area fraction
diff --git a/ccpp/data/GFS_typedefs.F90 b/ccpp/data/GFS_typedefs.F90
index 0a394587f0..d831942f28 100644
--- a/ccpp/data/GFS_typedefs.F90
+++ b/ccpp/data/GFS_typedefs.F90
@@ -1,7 +1,7 @@
module GFS_typedefs
use machine, only: kind_phys, kind_dbl_prec, kind_sngl_prec
- use physcons, only: con_cp, con_fvirt, con_g, &
+ use physcons, only: con_cp, con_fvirt, con_g, rholakeice, &
con_hvap, con_hfus, con_pi, con_rd, con_rv, &
con_t0c, con_cvap, con_cliq, con_eps, con_epsq, &
con_epsm1, con_ttp, rlapse, con_jcal, con_rhw0, &
@@ -211,8 +211,26 @@ module GFS_typedefs
real (kind=kind_phys), pointer :: slmsk (:) => null() !< sea/land mask array (sea:0,land:1,sea-ice:2)
real (kind=kind_phys), pointer :: oceanfrac(:) => null() !< ocean fraction [0:1]
real (kind=kind_phys), pointer :: landfrac(:) => null() !< land fraction [0:1]
+
+!--- In (lakes)
real (kind=kind_phys), pointer :: lakefrac(:) => null() !< lake fraction [0:1]
real (kind=kind_phys), pointer :: lakedepth(:) => null() !< lake depth [ m ]
+ real (kind=kind_phys), pointer :: clm_lakedepth(:) => null() !< clm internal lake depth [ m ]
+ integer, pointer :: use_lake_model(:) => null()!1=run lake, 2=run lake&nsst, 0=no lake
+ real (kind=kind_phys), pointer :: lake_t2m (:) => null() !< 2 meter temperature from CLM Lake model
+ real (kind=kind_phys), pointer :: lake_q2m (:) => null() !< 2 meter humidity from CLM Lake model
+
+ real (kind=kind_phys), pointer :: h_ML(:) => null() !Mixed Layer depth of lakes [m]
+ real (kind=kind_phys), pointer :: t_ML(:) => null() !Mixing layer temperature in K
+ real (kind=kind_phys), pointer :: t_mnw(:) => null() !Mean temperature of the water column [K]
+ real (kind=kind_phys), pointer :: h_talb(:) => null() !the thermally active layer depth of the bottom sediments [m]
+ real (kind=kind_phys), pointer :: t_talb(:) => null() !Temperature at the bottom of the sediment upper layer [K]
+ real (kind=kind_phys), pointer :: t_bot1(:) => null() !Temperature at the water-bottom sediment interface [K]
+ real (kind=kind_phys), pointer :: t_bot2(:) => null() !Temperature for bottom layer of water [K]
+ real (kind=kind_phys), pointer :: c_t(:) => null() !Shape factor of water temperature vertical profile
+ real (kind=kind_phys), pointer :: T_snow(:) => null() !temperature of snow on a lake [K]
+ real (kind=kind_phys), pointer :: T_ice(:) => null() !temperature of ice on a lake [K]
+
real (kind=kind_phys), pointer :: tsfc (:) => null() !< surface air temperature in K
real (kind=kind_phys), pointer :: vegtype_frac (:,:) => null() !< fractions [0:1] of veg. categories
real (kind=kind_phys), pointer :: soiltype_frac(:,:) => null() !< fractions [0:1] of soil categories
@@ -409,6 +427,36 @@ module GFS_typedefs
real (kind=kind_phys), pointer :: dsnowprv (:) => null() !< snow precipitation rate from previous timestep
real (kind=kind_phys), pointer :: dgraupelprv(:) => null() !< graupel precipitation rate from previous timestep
+ ! CLM Lake model internal variables:
+ real (kind=kind_phys), pointer :: lake_albedo(:) => null() !
+ real (kind=kind_phys), pointer :: lake_z3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_dz3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_soil_watsat3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_csol3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_soil_tkmg3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_soil_tkdry3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_soil_tksatu3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_h2osno2d(:) => null() !
+ real (kind=kind_phys), pointer :: lake_sndpth2d(:) => null() !
+ real (kind=kind_phys), pointer :: lake_snl2d(:) => null() !
+ real (kind=kind_phys), pointer :: lake_snow_z3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_snow_dz3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_snow_zi3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_h2osoi_vol3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_h2osoi_liq3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_h2osoi_ice3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_tsfc(:) => null() !
+ real (kind=kind_phys), pointer :: lake_t_soisno3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_t_lake3d(:,:) => null() !
+ real (kind=kind_phys), pointer :: lake_savedtke12d(:)=> null() !
+ real (kind=kind_phys), pointer :: lake_icefrac3d(:,:)=> null()
+ real (kind=kind_phys), pointer :: lake_rho0(:)=> null()
+ real (kind=kind_phys), pointer :: lake_ht(:)=> null()
+ real (kind=kind_phys), pointer :: lake_clay3d(:,:) => null()
+ real (kind=kind_phys), pointer :: lake_sand3d(:,:) => null()
+ integer, pointer :: lake_is_salty(:) => null()
+ integer, pointer :: lake_cannot_freeze(:) => null()
+ real (kind=kind_phys), pointer :: clm_lake_initialized(:) => null() !< lakeini was called
!--- aerosol surface emissions for Thompson microphysics & smoke dust
real (kind=kind_phys), pointer :: emdust (:) => null() !< instantaneous dust emission
real (kind=kind_phys), pointer :: emseas (:) => null() !< instantaneous sea salt emission
@@ -1012,8 +1060,24 @@ module GFS_typedefs
integer :: ntsflg !< flag for updating skin temperature in the GFDL surface layer scheme
real(kind=kind_phys) :: sfenth !< enthalpy flux factor 0 zot via charnock ..>0 zot enhanced>15m/s
-!--- flake model parameters
- integer :: lkm !< flag for flake model
+!--- lake model parameters
+ integer :: lkm !< =0 no lake, =1 lake, =2 lake&nsst
+ integer :: iopt_lake !< =1 flake, =2 clm lake
+ integer :: iopt_lake_flake = 1
+ integer :: iopt_lake_clm = 2
+ real(kind_phys) :: lakedepth_threshold !< lakedepth must be GREATER than this value to enable a lake model
+ real(kind_phys) :: lakefrac_threshold !< lakefrac must be GREATER than this value to enable a lake model
+ logical :: use_lake2m !< use 2m T & Q calculated by the lake model
+
+!--- clm lake model parameters
+ integer :: nlevlake_clm_lake !< Number of lake levels for clm lake model
+ integer :: nlevsoil_clm_lake !< Number of soil levels for clm lake model
+ integer :: nlevsnow_clm_lake !< Number of snow levels for clm lake model
+ integer :: nlevsnowsoil_clm_lake !< -nlevsnow:nlevsoil dimensioned variables
+ integer :: nlevsnowsoil1_clm_lake !< -nlevsnow+1:nlevsoil dimensioned variables
+ real(kind_phys) :: clm_lake_depth_default !< minimum lake elevation in clm lake model
+ logical :: clm_lake_use_lakedepth !< initialize lake from lakedepth
+ logical :: clm_lake_debug !< verbose debugging in clm_lake
!--- tuning parameters for physical parameterizations
logical :: ras !< flag for ras convection scheme
@@ -1207,6 +1271,7 @@ module GFS_typedefs
!< nstf_name(5) : zsea2 in mm
!--- fractional grid
logical :: frac_grid !< flag for fractional grid
+ logical :: frac_ice !< flag for fractional ice when fractional grid is not in use
logical :: ignore_lake !< flag for ignoring lakes
real(kind=kind_phys) :: min_lakeice !< minimum lake ice value
real(kind=kind_phys) :: min_seaice !< minimum sea ice value
@@ -2174,6 +2239,26 @@ subroutine sfcprop_create (Sfcprop, IM, Model)
allocate (Sfcprop%soiltype_frac(IM,Model%nsoilcat))
allocate (Sfcprop%lakefrac (IM))
allocate (Sfcprop%lakedepth(IM))
+
+ allocate (Sfcprop%use_lake_model(IM))
+
+ if(Model%lkm > 0) then
+ if(Model%iopt_lake==Model%iopt_lake_clm) then
+ allocate (Sfcprop%clm_lakedepth(IM))
+ else if(Model%iopt_lake==Model%iopt_lake_flake) then
+ allocate (Sfcprop%h_ML (IM))
+ allocate (Sfcprop%t_ML (IM))
+ allocate (Sfcprop%t_mnw (IM))
+ allocate (Sfcprop%h_talb (IM))
+ allocate (Sfcprop%t_talb (IM))
+ allocate (Sfcprop%t_bot1 (IM))
+ allocate (Sfcprop%t_bot2 (IM))
+ allocate (Sfcprop%c_t (IM))
+ endif
+ allocate (Sfcprop%T_snow (IM))
+ allocate (Sfcprop%T_ice (IM))
+ endif
+
allocate (Sfcprop%tsfc (IM))
allocate (Sfcprop%tsfco (IM))
allocate (Sfcprop%tsfcl (IM))
@@ -2211,6 +2296,25 @@ subroutine sfcprop_create (Sfcprop, IM, Model)
Sfcprop%soiltype_frac = clear_val
Sfcprop%lakefrac = clear_val
Sfcprop%lakedepth = clear_val
+
+ Sfcprop%use_lake_model = zero
+ if(Model%lkm > 0) then
+ if(Model%iopt_lake==Model%iopt_lake_clm) then
+ Sfcprop%clm_lakedepth = clear_val
+ else if(Model%iopt_lake==Model%iopt_lake_flake) then
+ Sfcprop%h_ML = clear_val
+ Sfcprop%t_ML = clear_val
+ Sfcprop%t_mnw = clear_val
+ Sfcprop%h_talb = clear_val
+ Sfcprop%t_talb = clear_val
+ Sfcprop%t_bot1 = clear_val
+ Sfcprop%t_bot2 = clear_val
+ Sfcprop%c_t = clear_val
+ endif
+ Sfcprop%T_snow = clear_val
+ Sfcprop%T_ice = clear_val
+ endif
+
Sfcprop%tsfc = clear_val
Sfcprop%tsfco = clear_val
Sfcprop%tsfcl = clear_val
@@ -2402,18 +2506,20 @@ subroutine sfcprop_create (Sfcprop, IM, Model)
Sfcprop%xlaixy = clear_val
Sfcprop%rca = clear_val
end if
- if (Model%lsm == Model%lsm_ruc .or. Model%lsm == Model%lsm_noahmp) then
- allocate(Sfcprop%raincprv (IM))
- allocate(Sfcprop%rainncprv (IM))
+ if (Model%lsm == Model%lsm_ruc .or. Model%lsm == Model%lsm_noahmp .or. &
+ (Model%lkm>0 .and. Model%iopt_lake==Model%iopt_lake_clm)) then
+ allocate(Sfcprop%raincprv (IM))
+ allocate(Sfcprop%rainncprv (IM))
+ Sfcprop%raincprv = clear_val
+ Sfcprop%rainncprv = clear_val
+ if (Model%lsm == Model%lsm_ruc .or. Model%lsm == Model%lsm_noahmp) then
allocate(Sfcprop%iceprv (IM))
allocate(Sfcprop%snowprv (IM))
allocate(Sfcprop%graupelprv(IM))
-
- Sfcprop%raincprv = clear_val
- Sfcprop%rainncprv = clear_val
Sfcprop%iceprv = clear_val
Sfcprop%snowprv = clear_val
Sfcprop%graupelprv = clear_val
+ end if
end if
! Noah MP allocate and init when used
!
@@ -2589,6 +2695,73 @@ subroutine sfcprop_create (Sfcprop, IM, Model)
Sfcprop%conv_act_m = zero
end if
+ ! CLM Lake Model variables
+ if (Model%lkm/=0 .and. Model%iopt_lake==Model%iopt_lake_clm) then
+ allocate(Sfcprop%lake_t2m(IM))
+ allocate(Sfcprop%lake_q2m(IM))
+ allocate(Sfcprop%lake_albedo(IM))
+ allocate(Sfcprop%lake_z3d(IM,Model%nlevlake_clm_lake))
+ allocate(Sfcprop%lake_dz3d(IM,Model%nlevlake_clm_lake))
+ allocate(Sfcprop%lake_soil_watsat3d(IM,Model%nlevlake_clm_lake))
+ allocate(Sfcprop%lake_csol3d(IM,Model%nlevlake_clm_lake))
+ allocate(Sfcprop%lake_soil_tkmg3d(IM,Model%nlevlake_clm_lake))
+ allocate(Sfcprop%lake_soil_tkdry3d(IM,Model%nlevlake_clm_lake))
+ allocate(Sfcprop%lake_soil_tksatu3d(IM,Model%nlevlake_clm_lake))
+ allocate(Sfcprop%lake_h2osno2d(IM))
+ allocate(Sfcprop%lake_sndpth2d(IM))
+ allocate(Sfcprop%lake_snl2d(IM))
+ allocate(Sfcprop%lake_snow_z3d(IM,Model%nlevsnowsoil1_clm_lake))
+ allocate(Sfcprop%lake_snow_dz3d(IM,Model%nlevsnowsoil1_clm_lake))
+ allocate(Sfcprop%lake_snow_zi3d(IM,Model%nlevsnowsoil_clm_lake))
+ allocate(Sfcprop%lake_h2osoi_vol3d(IM,Model%nlevsnowsoil1_clm_lake))
+ allocate(Sfcprop%lake_h2osoi_liq3d(IM,Model%nlevsnowsoil1_clm_lake))
+ allocate(Sfcprop%lake_h2osoi_ice3d(IM,Model%nlevsnowsoil1_clm_lake))
+ allocate(Sfcprop%lake_tsfc(IM))
+ allocate(Sfcprop%lake_t_soisno3d(IM,Model%nlevsnowsoil1_clm_lake))
+ allocate(Sfcprop%lake_t_lake3d(IM,Model%nlevlake_clm_lake))
+ allocate(Sfcprop%lake_savedtke12d(IM))
+ allocate(Sfcprop%lake_icefrac3d(IM,Model%nlevlake_clm_lake))
+ allocate(Sfcprop%lake_rho0(IM))
+ allocate(Sfcprop%lake_ht(IM))
+ allocate(Sfcprop%lake_clay3d(IM,Model%nlevsoil_clm_lake))
+ allocate(Sfcprop%lake_sand3d(IM,Model%nlevsoil_clm_lake))
+ allocate(Sfcprop%lake_is_salty(IM))
+ allocate(Sfcprop%lake_cannot_freeze(IM))
+ allocate(Sfcprop%clm_lake_initialized(IM))
+
+ Sfcprop%lake_t2m = clear_val
+ Sfcprop%lake_q2m = clear_val
+ Sfcprop%lake_albedo = clear_val
+ Sfcprop%lake_z3d = clear_val
+ Sfcprop%lake_dz3d = clear_val
+ Sfcprop%lake_soil_watsat3d = clear_val
+ Sfcprop%lake_csol3d = clear_val
+ Sfcprop%lake_soil_tkmg3d = clear_val
+ Sfcprop%lake_soil_tkdry3d = clear_val
+ Sfcprop%lake_soil_tksatu3d = clear_val
+ Sfcprop%lake_h2osno2d = clear_val
+ Sfcprop%lake_sndpth2d = clear_val
+ Sfcprop%lake_snl2d = clear_val
+ Sfcprop%lake_snow_z3d = clear_val
+ Sfcprop%lake_snow_dz3d = clear_val
+ Sfcprop%lake_snow_zi3d = clear_val
+ Sfcprop%lake_h2osoi_vol3d = clear_val
+ Sfcprop%lake_h2osoi_liq3d = clear_val
+ Sfcprop%lake_h2osoi_ice3d = clear_val
+ Sfcprop%lake_tsfc = clear_val
+ Sfcprop%lake_t_soisno3d = clear_val
+ Sfcprop%lake_t_lake3d = clear_val
+ Sfcprop%lake_savedtke12d = clear_val
+ Sfcprop%lake_icefrac3d = clear_val
+ Sfcprop%lake_rho0 = -111
+ Sfcprop%lake_ht = -111
+ Sfcprop%lake_clay3d = clear_val
+ Sfcprop%lake_sand3d = clear_val
+ Sfcprop%lake_is_salty = zero
+ Sfcprop%lake_cannot_freeze = zero
+ Sfcprop%clm_lake_initialized = zero
+ endif
+
if(Model%rrfs_sd) then
!--- needed for smoke aerosol option
allocate (Sfcprop%emdust (IM))
@@ -3266,6 +3439,18 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
!--- Thompson,GFDL microphysical parameter
logical :: lrefres = .false. !< flag for radar reflectivity in restart file
+ !--- CLM Lake Model parameters (MUST match clm_lake.F90)
+ integer, parameter :: nlevlake_clm_lake = 10 !< number of lake levels
+ integer, parameter :: nlevsoil_clm_lake = 10 !< number of soil levels
+ integer, parameter :: nlevsnow_clm_lake = 5 !< number of snow levels
+ integer, parameter :: nlevsnowsoil_clm_lake = nlevsnow_clm_lake+nlevsoil_clm_lake+1 !< -nlevsno:nlevsoil dimensioned variables
+ integer, parameter :: nlevsnowsoil1_clm_lake = nlevsnow_clm_lake+nlevsoil_clm_lake !< -nlevsno+1:nlevsoil dimensioned variables
+
+ !--- CLM Lake configurables
+ real(kind_phys) :: clm_lake_depth_default = 50 !< default lake depth in clm lake model
+ logical :: clm_lake_use_lakedepth = .true. !< initialize depth from lakedepth
+ logical :: clm_lake_debug = .false. !< verbose debugging in clm_lake
+
!--- land/surface model parameters
integer :: lsm = 1 !< flag for land surface model to use =0 for osu lsm; =1 for noah lsm; =2 for noah mp lsm; =3 for RUC lsm
integer :: lsoil = 4 !< number of soil layers
@@ -3319,7 +3504,11 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
real(kind=kind_phys) :: sfenth = 0.0 !< enthalpy flux factor 0 zot via charnock ..>0 zot enhanced>15m/s
!--- flake model parameters
- integer :: lkm = 0 !< flag for flake model - default no flake
+ integer :: lkm = 0 !< =1 run lake, =2 run lake&nsst =0 no lake
+ integer :: iopt_lake = 2 !< =1 flake, =2 clm lake (default)
+ real(kind_phys) :: lakedepth_threshold = 1.0 !< lakedepth must be GREATER than this value to enable a lake model
+ real(kind_phys) :: lakefrac_threshold = 0.0 !< lakefrac must be GREATER than this value to enable a lake model
+ logical :: use_lake2m = .false. !< use 2m T & Q from clm lake model
!--- tuning parameters for physical parameterizations
logical :: ras = .false. !< flag for ras convection scheme
@@ -3504,6 +3693,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
!< nstf_name(5) : zsea2 in mm
!--- fractional grid
logical :: frac_grid = .false. !< flag for fractional grid
+ logical :: frac_ice = .false. !< flag for fractional ice when fractional grid is not in use
logical :: ignore_lake = .true. !< flag for ignoring lakes
real(kind=kind_phys) :: min_lakeice = 0.15d0 !< minimum lake ice value
real(kind=kind_phys) :: min_seaice = 1.0d-11 !< minimum sea ice value
@@ -3706,7 +3896,9 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
! GFDL surface layer options
lcurr_sf, pert_cd, ntsflg, sfenth, &
!--- lake model control
- lkm, &
+ lkm, iopt_lake, lakedepth_threshold, lakefrac_threshold, &
+ clm_lake_depth_default, clm_lake_use_lakedepth, &
+ clm_lake_debug, use_lake2m, &
!--- physical parameterizations
ras, trans_trac, old_monin, cnvgwd, mstrat, moist_adj, &
cscnv, cal_pre, do_aw, do_shoc, shocaftcnv, shoc_cld, &
@@ -3749,7 +3941,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
!--- near surface sea temperature model
nst_anl, lsea, nstf_name, &
frac_grid, min_lakeice, min_seaice, min_lake_height, &
- ignore_lake, &
+ ignore_lake, frac_ice, &
!--- surface layer
sfc_z0_type, &
!--- switch beteeen local and standard potential temperature
@@ -4418,8 +4610,22 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
Model%ntsflg = ntsflg
Model%sfenth = sfenth
-!--- flake model parameters
+!--- lake model parameters
Model%lkm = lkm
+ Model%iopt_lake = iopt_lake
+ Model%use_lake2m = use_lake2m
+ Model%lakedepth_threshold = lakedepth_threshold
+ Model%lakefrac_threshold = lakefrac_threshold
+
+!--- clm lake model parameters
+ Model%nlevlake_clm_lake = nlevlake_clm_lake
+ Model%nlevsoil_clm_lake = nlevsoil_clm_lake
+ Model%nlevsnow_clm_lake = nlevsnow_clm_lake
+ Model%nlevsnowsoil_clm_lake = nlevsnowsoil_clm_lake
+ Model%nlevsnowsoil1_clm_lake = nlevsnowsoil1_clm_lake
+ Model%clm_lake_depth_default = clm_lake_depth_default
+ Model%clm_lake_use_lakedepth = clm_lake_use_lakedepth
+ Model%clm_lake_debug = clm_lake_debug
! Noah MP options from namelist
!
@@ -4623,6 +4829,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
!--- fractional grid
Model%frac_grid = frac_grid
+ Model%frac_ice = frac_ice
Model%ignore_lake = ignore_lake
Model%min_lakeice = min_lakeice
Model%min_seaice = min_seaice
@@ -4851,6 +5058,18 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
Model%ntocl = get_tracer_index(Model%tracer_names, 'oc2', Model%me, Model%master, Model%debug)
end if
+ ! Lake & fractional grid safety checks
+ if(Model%me==Model%master) then
+ if(Model%lkm>0 .and. Model%frac_grid) then
+ write(0,*) 'WARNING: Lake fractional grid support is experimental. Use at your own risk!'
+ else if(Model%lkm>0 .and. Model%iopt_lake==Model%iopt_lake_clm .and. .not. Model%frac_ice) then
+ write(0,*) 'WARNING: CLM Lake Model will not work without frac_ice=.true.'
+ endif
+ if(Model%lkm==2) then
+ write(0,*) 'WARNING: Running both lake and nsst on lake points is experimental. Use at your own risk!'
+ endif
+ endif
+
if(ldiag3d) then
! Flags used to turn on or off tracer "causes"
have_pbl_edmf = Model%hybedmf .or. Model%satmedmf .or. Model%do_mynnedmf
@@ -5382,12 +5601,27 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
! endif
print *,' nst_anl=',Model%nst_anl,' use_ufo=',Model%use_ufo,' frac_grid=',Model%frac_grid,&
- ' ignore_lake=',ignore_lake
+ ' ignore_lake=',ignore_lake,' frac_ice=',Model%frac_ice
print *,' min_lakeice=',Model%min_lakeice,' min_seaice=',Model%min_seaice, &
'min_lake_height=',Model%min_lake_height
- print *, 'flake model parameters'
- print *, 'lkm : ', Model%lkm
+ print *, 'lake model parameters'
+ print *, ' lake master flag lkm : ', Model%lkm
+ if(Model%lkm>0) then
+ print *, ' lake model selection : ', Model%iopt_lake
+ if(Model%iopt_lake==Model%iopt_lake_clm) then
+ print *,' CLM Lake model configuration'
+ print *,' use_lake2m = ',Model%use_lake2m
+ print *,' clm_lake_use_lakedepth = ',Model%clm_lake_use_lakedepth
+ print *,' clm_lake_depth_default = ',Model%clm_lake_depth_default
+ print *,' clm_lake_debug = ',Model%clm_lake_debug
+ print *,' nlevlake_clm_lake = ',Model%nlevlake_clm_lake
+ print *,' nlevsoil_clm_lake = ',Model%nlevsoil_clm_lake
+ print *,' nlevsnow_clm_lake = ',Model%nlevsnow_clm_lake
+ print *,' nlevsnowsoil_clm_lake = ',Model%nlevsnowsoil_clm_lake
+ print *,' nlevsnowsoil1_clm_lake = ',Model%nlevsnowsoil1_clm_lake
+ endif
+ endif
if (Model%nstf_name(1) > 0 ) then
print *,' NSSTM is active '
diff --git a/ccpp/data/GFS_typedefs.meta b/ccpp/data/GFS_typedefs.meta
index 4354f7c109..4ab11dd4cb 100644
--- a/ccpp/data/GFS_typedefs.meta
+++ b/ccpp/data/GFS_typedefs.meta
@@ -641,6 +641,108 @@
dimensions = (horizontal_loop_extent)
type = real
kind = kind_phys
+[clm_lakedepth]
+ standard_name = clm_lake_depth
+ long_name = clm internal copy of lake depth with 10.0 replaced by default lake depth
+ units = m
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_execution_method > 0 .and. control_for_lake_model_selection == 2)
+[use_lake_model]
+ standard_name = flag_for_using_lake_model
+ long_name = flag indicating lake points using a lake model
+ units = flag
+ dimensions = (horizontal_loop_extent)
+ type = integer
+[lake_t2m]
+ standard_name = temperature_at_2m_from_clm_lake
+ long_name = temperature at 2m from clm lake
+ units = K
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_execution_method > 0 .and. control_for_lake_model_selection == 2)
+[lake_q2m]
+ standard_name = specific_humidity_at_2m_from_clm_lake
+ long_name = specific humidity at 2m from clm lake
+ units = frac
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_execution_method > 0 .and. control_for_lake_model_selection == 2)
+[h_ML]
+ standard_name = mixed_layer_depth_of_lakes
+ long_name = depth of lake mixing layer
+ units = m
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 1 .and. control_for_lake_model_execution_method > 0)
+[t_ML]
+ standard_name = lake_mixed_layer_temperature
+ long_name = temperature of lake mixing layer
+ units = K
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 1 .and. control_for_lake_model_execution_method > 0)
+[t_mnw]
+ standard_name = mean_temperature_of_the_water_column
+ long_name = thee mean temperature of the water column
+ units = K
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 1 .and. control_for_lake_model_execution_method > 0)
+[h_talb]
+ standard_name = the_thermally_active_layer_depth_of_the_bottom_sediment
+ long_name = the depth of the thermally active layer of the bottom sediment
+ units = m
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 1 .and. control_for_lake_model_execution_method > 0)
+[t_talb]
+ standard_name = temperature_at_the_bottom_of_the_sediment_upper_layer
+ long_name = the temperature at the bottom of the sediment upper layer
+ units = K
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 1 .and. control_for_lake_model_execution_method > 0)
+[t_bot1]
+ standard_name = lake_bottom_temperature
+ long_name = the temperature at the water-bottom sediment interface
+ units = K
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 1 .and. control_for_lake_model_execution_method > 0)
+[t_bot2]
+ standard_name = temperature_for_bottom_layer_of_water
+ long_name = the temperature at the lake bottom layer water
+ units = K
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 1 .and. control_for_lake_model_execution_method > 0)
+[c_t]
+ standard_name = shape_factor_of_water_temperature_vertical_profile
+ long_name = the shape factor of water temperature vertical profile
+ units = none
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 1 .and. control_for_lake_model_execution_method > 0)
+[T_snow]
+ standard_name = temperature_of_snow_on_lake
+ long_name = temperature of snow on a lake
+ units = K
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_execution_method > 0)
[tsfc]
standard_name = surface_skin_temperature
long_name = surface skin temperature
@@ -1811,7 +1913,7 @@
dimensions = (horizontal_loop_extent)
type = real
kind = kind_phys
- active = (control_for_land_surface_scheme == identifier_for_ruc_land_surface_scheme .or. control_for_land_surface_scheme == identifier_for_noahmp_land_surface_scheme)
+ active = (control_for_land_surface_scheme == identifier_for_ruc_land_surface_scheme .or. control_for_land_surface_scheme == identifier_for_noahmp_land_surface_scheme .or. ( control_for_lake_model_execution_method > 0 .and. control_for_lake_model_selection == 2) )
[rainncprv]
standard_name = lwe_thickness_of_explicit_precipitation_amount_on_previous_timestep
long_name = explicit rainfall from previous timestep
@@ -1819,7 +1921,7 @@
dimensions = (horizontal_loop_extent)
type = real
kind = kind_phys
- active = (control_for_land_surface_scheme == identifier_for_ruc_land_surface_scheme .or. control_for_land_surface_scheme == identifier_for_noahmp_land_surface_scheme)
+ active = (control_for_land_surface_scheme == identifier_for_ruc_land_surface_scheme .or. control_for_land_surface_scheme == identifier_for_noahmp_land_surface_scheme .or. ( control_for_lake_model_execution_method > 0 .and. control_for_lake_model_selection == 2) )
[iceprv]
standard_name = lwe_thickness_of_ice_precipitation_amount_on_previous_timestep
long_name = ice amount from previous timestep
@@ -1912,6 +2014,226 @@
dimensions = (horizontal_loop_extent)
type = real
kind = kind_phys
+[lake_albedo]
+ standard_name = mid_day_surface_albedo_over_lake
+ long_name = mid day surface albedo over lake
+ units = fraction
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_z3d]
+ standard_name = depth_of_lake_interface_layers
+ long_name = depth of lake interface layers
+ units = fraction
+ dimensions = (horizontal_loop_extent, lake_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_dz3d]
+ standard_name = thickness_of_lake_layers
+ long_name = thickness of lake layers
+ units = fraction
+ dimensions = (horizontal_loop_extent, lake_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_soil_watsat3d]
+ standard_name = saturated_volumetric_soil_water_in_lake_model
+ long_name = saturated volumetric soil water in lake model
+ units = m
+ dimensions = (horizontal_loop_extent, lake_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_csol3d]
+ standard_name = soil_heat_capacity_in_lake_model
+ long_name = soil heat capacity in lake model
+ units = m
+ dimensions = (horizontal_loop_extent, lake_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_soil_tkmg3d]
+ standard_name = soil_mineral_thermal_conductivity_in_lake_model
+ long_name = soil mineral thermal conductivity in lake model
+ units = m
+ dimensions = (horizontal_loop_extent, lake_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_soil_tkdry3d]
+ standard_name = dry_soil_thermal_conductivity_in_lake_model
+ long_name = dry soil thermal conductivity in lake model
+ units = m
+ dimensions = (horizontal_loop_extent, lake_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_soil_tksatu3d]
+ standard_name = saturated_soil_thermal_conductivity_in_lake_model
+ long_name = saturated soil thermal conductivity in lake model
+ units = m
+ dimensions = (horizontal_loop_extent, lake_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_h2osno2d]
+ standard_name = water_equivalent_accumulated_snow_depth_in_clm_lake_model
+ long_name = water equiv of acc snow depth over lake in clm lake model
+ units = mm
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_sndpth2d]
+ standard_name = actual_snow_depth_in_clm_lake_model
+ long_name = actual acc snow depth over lake in clm lake model
+ units = m
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_snl2d]
+ standard_name = snow_layers_in_clm_lake_model
+ long_name = snow layers in clm lake model (treated as integer)
+ units = count
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_snow_z3d]
+ standard_name = snow_level_depth_in_clm_lake_model
+ long_name = snow level depth in clm lake model
+ units = m
+ dimensions = (horizontal_loop_extent,snow_plus_soil_minus_one_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_snow_dz3d]
+ standard_name = snow_level_thickness_in_clm_lake_model
+ long_name = snow level thickness in clm lake model
+ units = m
+ dimensions = (horizontal_loop_extent,snow_plus_soil_minus_one_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_snow_zi3d]
+ standard_name = snow_interface_depth_in_clm_lake_model
+ long_name = snow interface_depth in clm lake model
+ units = m
+ dimensions = (horizontal_loop_extent,snow_plus_soil_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_h2osoi_vol3d]
+ standard_name = volumetric_soil_water_in_clm_lake_model
+ long_name = volumetric soil water in clm lake model
+ units = m3 m-3
+ dimensions = (horizontal_loop_extent,snow_plus_soil_minus_one_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_h2osoi_liq3d]
+ standard_name = soil_liquid_water_content_in_clm_lake_model
+ long_name = soil liquid water content in clm lake model
+ units = kg m-3
+ dimensions = (horizontal_loop_extent,snow_plus_soil_minus_one_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_h2osoi_ice3d]
+ standard_name = soil_ice_water_content_in_clm_lake_model
+ long_name = soil ice water content in clm lake model
+ units = kg m-3
+ dimensions = (horizontal_loop_extent,snow_plus_soil_minus_one_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_tsfc]
+ standard_name = skin_temperature_from_lake_model
+ long_name = skin temperature from lake model
+ units = K
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_t_soisno3d]
+ standard_name = soil_or_snow_layer_temperature_from_clm_lake_model
+ long_name = soil or snow layer temperature from clm lake model
+ units = K
+ dimensions = (horizontal_loop_extent,snow_plus_soil_minus_one_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_t_lake3d]
+ standard_name = lake_layer_temperature_from_clm_lake_model
+ long_name = lake layer temperature from clm lake model
+ units = K
+ dimensions = (horizontal_loop_extent,lake_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_savedtke12d]
+ standard_name = top_level_eddy_conductivity_from_previous_timestep_in_clm_lake_model
+ long_name = top level eddy conductivity from previous timestep in clm lake model
+ units = kg m-3
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_icefrac3d]
+ standard_name = lake_fractional_ice_cover_on_clm_lake_levels
+ long_name = lake fractional ice cover on clm lake levels
+ units = kg m-3
+ dimensions = (horizontal_loop_extent,lake_vertical_dimension_for_clm_lake_model)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_ht]
+ standard_name = test_lake_ht
+ long_name = test_lake_ht
+ dimensions = (horizontal_loop_extent)
+ units = unitless
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[clm_lake_initialized]
+ standard_name = flag_for_clm_lake_initialization
+ long_name = set to true in clm_lake_run after likeini is called for that gridpoint
+ units = flag
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_clay3d]
+ standard_name = clm_lake_percent_clay
+ long_name = percent clay in clm lake model
+ units = percent
+ dimensions = (horizontal_loop_extent,soil_vertical_dimension_for_clm_lake_model)
+ type = integer
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_sand3d]
+ standard_name = clm_lake_percent_sand
+ long_name = percent sand in clm lake model
+ units = percent
+ dimensions = (horizontal_loop_extent,soil_vertical_dimension_for_clm_lake_model)
+ type = integer
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_is_salty]
+ standard_name = clm_lake_is_salty
+ long_name = lake at this point is salty (1) or not (0)
+ units = 1
+ dimensions = (horizontal_loop_extent)
+ type = integer
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
+[lake_cannot_freeze]
+ standard_name = clm_lake_cannot_freeze
+ long_name = lake at this point is so salty it cannot freeze
+ units = 1
+ dimensions = (horizontal_loop_extent)
+ type = integer
+ active = (control_for_lake_model_selection == 2 .and. control_for_lake_model_execution_method > 0)
[emdust]
standard_name = emission_of_dust_for_smoke
long_name = emission of dust for smoke
@@ -4332,6 +4654,41 @@
units = count
dimensions = ()
type = integer
+[nlevlake_clm_lake]
+ standard_name = lake_vertical_dimension_for_clm_lake_model
+ long_name = lake vertical dimension for clm lake model
+ units = count
+ dimensions = ()
+ type = integer
+ active = (control_for_lake_surface_scheme == 2)
+[nlevsoil_clm_lake]
+ standard_name = soil_vertical_dimension_for_clm_lake_model
+ long_name = soil vertical dimension for clm lake model
+ units = count
+ dimensions = ()
+ type = integer
+ active = (control_for_lake_surface_scheme == 2)
+[nlevsnow_clm_lake]
+ standard_name = snow_vertical_dimension_for_clm_lake_model
+ long_name = snow vertical dimension for clm lake model
+ units = count
+ dimensions = ()
+ type = integer
+ active = (control_for_lake_surface_scheme == 2)
+[nlevsnowsoil_clm_lake]
+ standard_name = snow_plus_soil_vertical_dimension_for_clm_lake_model
+ long_name = snow plus soil vertical dimension for clm lake model
+ units = count
+ dimensions = ()
+ type = integer
+ active = (control_for_lake_surface_scheme == 2)
+[nlevsnowsoil1_clm_lake]
+ standard_name = snow_plus_soil_minus_one_vertical_dimension_for_clm_lake_model
+ long_name = snow plus soil minus one vertical dimension for clm lake model
+ units = count
+ dimensions = ()
+ type = integer
+ active = (control_for_lake_surface_scheme == 2)
[lsoil]
standard_name = vertical_dimension_of_soil
long_name = number of soil layers
@@ -4579,9 +4936,47 @@
dimensions = ()
type = real
kind = kind_phys
+[lakefrac_threshold]
+ standard_name = lakefrac_threshold_for_enabling_lake_model
+ long_name = fraction of horizontal grid area occupied by lake must be greater than this value to enable a lake model
+ units = frac
+ dimensions = ()
+ type = real
+ kind = kind_phys
+[lakedepth_threshold]
+ standard_name = lake_depth_threshold_for_enabling_lake_model
+ long_name = lake depth must be greater than this value to enable a lake model
+ units = m
+ dimensions = ()
+ type = real
+ kind = kind_phys
+[iopt_lake]
+ standard_name = control_for_lake_model_selection
+ long_name = control for lake model selection
+ units = 1
+ dimensions = ()
+ type = integer
+[iopt_lake_flake]
+ standard_name = flake_model_control_selection_value
+ long_name = value that indicates flake model in the control for lake model selection
+ units = 1
+ dimensions = ()
+ type = integer
+[iopt_lake_clm]
+ standard_name = clm_lake_model_control_selection_value
+ long_name = value that indicates clm lake model in the control for lake model selection
+ units = 1
+ dimensions = ()
+ type = integer
+[use_lake2m]
+ standard_name = use_2m_diagnostics_calculated_by_lake_model
+ long_name = model 2m diagnostics use the temperature and humidity calculated by the lake model
+ units = flag
+ dimensions = ()
+ type = integer
[lkm]
- standard_name = control_for_lake_surface_scheme
- long_name = flag for lake surface model
+ standard_name = control_for_lake_model_execution_method
+ long_name = control for lake model execution: 0=no lake, 1=lake, 2=lake+nsst
units = flag
dimensions = ()
type = integer
@@ -5153,6 +5548,12 @@
units = flag
dimensions = ()
type = logical
+[frac_ice]
+ standard_name = flag_for_fractional_ice_when_fractional_landmask_is_disabled
+ long_name = flag for fractional ice when fractional landmask is disabled
+ units = flag
+ dimensions = ()
+ type = logical
[min_lakeice]
standard_name = min_lake_ice_area_fraction
long_name = minimum lake ice value
@@ -6691,6 +7092,25 @@
units = flag
dimensions = ()
type = logical
+[clm_lake_depth_default]
+ standard_name = default_lake_depth_in_clm_lake_model
+ long_name = default lake depth in clm lake model
+ units = m
+ dimensions = ()
+ type = real
+ kind = kind_phys
+[clm_lake_use_lakedepth]
+ standard_name = flag_for_initializing_clm_lake_depth_from_lake_depth
+ long_name = flag for initializing clm lake depth from lake depth
+ units = flag
+ dimensions = ()
+ type = logical
+[clm_lake_debug]
+ standard_name = flag_for_verbose_debugging_in_clm_lake_model
+ long_name = flag for verbose debugging in clm lake model
+ units = flag
+ dimensions = ()
+ type = logical
[fire_aux_data_levels]
standard_name = fire_auxiliary_data_extent
long_name = number of levels of fire auxiliary data
@@ -9446,6 +9866,13 @@
dimensions = ()
type = real
kind = kind_phys
+[rholakeice]
+ standard_name = density_of_ice_on_lake
+ long_name = density of ice on a lake
+ units = kg m-3
+ dimensions = ()
+ type = real
+ kind = kind_phys
[con_csol]
standard_name = specific_heat_of_ice_at_constant_pressure
long_name = specific heat of ice at constant pressure
diff --git a/ccpp/driver/GFS_diagnostics.F90 b/ccpp/driver/GFS_diagnostics.F90
index 83d20ea595..c1598a28cb 100644
--- a/ccpp/driver/GFS_diagnostics.F90
+++ b/ccpp/driver/GFS_diagnostics.F90
@@ -1874,6 +1874,45 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop
! if(mpp_pe()==mpp_root_pe())print *,'in gfdl_diag_register,af totgrp,idx=',idx
+ if(associated(Coupling(1)%sfcdlw)) then
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'sfcdlw'
+ ExtDiag(idx)%desc = 'sfcdlw'
+ ExtDiag(idx)%unit = 'W m-2'
+ ExtDiag(idx)%mod_name = 'gfs_phys'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => Coupling(nb)%sfcdlw(:)
+ enddo
+ endif
+
+ if(associated(Coupling(1)%htrlw)) then
+ idx = idx + 1
+ ExtDiag(idx)%axes = 3
+ ExtDiag(idx)%name = 'htrlw'
+ ExtDiag(idx)%desc = 'htrlw'
+ ExtDiag(idx)%unit = 'W m-2'
+ ExtDiag(idx)%mod_name = 'gfs_phys'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var3 => Coupling(nb)%htrlw(:,:)
+ enddo
+ endif
+
+ if(associated(Radtend(1)%lwhc)) then
+ idx = idx + 1
+ ExtDiag(idx)%axes = 3
+ ExtDiag(idx)%name = 'lwhc'
+ ExtDiag(idx)%desc = 'lwhc'
+ ExtDiag(idx)%unit = 'K s-1'
+ ExtDiag(idx)%mod_name = 'gfs_phys'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var3 => Radtend(nb)%lwhc(:,:)
+ enddo
+ endif
+
!--- physics instantaneous diagnostics ---
idx = idx + 1
ExtDiag(idx)%axes = 2
@@ -2553,6 +2592,207 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop
enddo
endif
+ if (Model%lkm/=0) then
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'lakefrac'
+ ExtDiag(idx)%desc = 'Lake Fraction'
+ ExtDiag(idx)%unit = 'fraction'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%lakefrac(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'lakedepth'
+ ExtDiag(idx)%desc = 'Lake Depth'
+ ExtDiag(idx)%unit = 'm'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%lakedepth(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'T_snow'
+ ExtDiag(idx)%desc = 'Temperature of snow on a lake'
+ ExtDiag(idx)%unit = 'K'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%T_snow(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'T_ice'
+ ExtDiag(idx)%desc = 'Temperature of ice on a lake'
+ ExtDiag(idx)%unit = 'K'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%T_ice(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'use_lake_model'
+ ExtDiag(idx)%desc = 'Lake Model Flag'
+ ExtDiag(idx)%unit = 'flag'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%int2 => Sfcprop(nb)%use_lake_model(:)
+ enddo
+
+ if(Model%iopt_lake==Model%iopt_lake_clm) then
+
+ ! Populate the 3D arrays separately since the code is complicated:
+ call clm_lake_externaldiag_populate(ExtDiag, Model, Sfcprop, idx, cn_one, nblks)
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'lake_is_salty'
+ ExtDiag(idx)%desc = 'lake point is considered salty by clm lake model'
+ ExtDiag(idx)%unit = '1'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%int2 => Sfcprop(nb)%lake_is_salty(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'lake_cannot_freeze'
+ ExtDiag(idx)%desc = 'clm lake model considers the point to be so salty it cannot freeze'
+ ExtDiag(idx)%unit = '1'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%int2 => Sfcprop(nb)%lake_cannot_freeze(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'lake_t2m'
+ ExtDiag(idx)%desc = 'Temperature at 2 m from Lake Model'
+ ExtDiag(idx)%unit = 'K'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%lake_t2m(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'lake_q2m'
+ ExtDiag(idx)%desc = 'Humidity at 2 m from Lake Model'
+ ExtDiag(idx)%unit = '%'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%lake_q2m(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'lake_albedo'
+ ExtDiag(idx)%desc = 'mid day surface albedo over lake'
+ ExtDiag(idx)%unit = 'fraction'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%lake_albedo(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'lake_h2osno2d'
+ ExtDiag(idx)%desc = 'water equiv of acc snow depth over lake'
+ ExtDiag(idx)%unit = 'mm'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%lake_h2osno2d(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'lake_sndpth2d'
+ ExtDiag(idx)%desc = 'actual acc snow depth over lake in clm lake model'
+ ExtDiag(idx)%unit = 'm'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%lake_sndpth2d(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'lake_snl2d'
+ ExtDiag(idx)%desc = 'snow layers in clm lake model (treated as integer)'
+ ExtDiag(idx)%unit = 'count'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%lake_snl2d(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'lake_tsfc'
+ ExtDiag(idx)%desc = 'skin temperature from clm lake model'
+ ExtDiag(idx)%unit = 'K'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%lake_tsfc(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'lake_savedtke12d'
+ ExtDiag(idx)%desc = 'top level eddy conductivity from previous timestep in clm lake model'
+ ExtDiag(idx)%unit = 'kg m-3'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%lake_savedtke12d(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'lake_ht'
+ ExtDiag(idx)%desc = 'lake_ht'
+ ExtDiag(idx)%unit = 'unitless'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%lake_ht(:)
+ enddo
+
+ endif
+
+ endif
+
if (Model%ldiag_ugwp) THEN
!
! VAY-2018: Momentum and Temp-re tendencies
@@ -3715,6 +3955,28 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop
ExtDiag(idx)%data(nb)%var2 => sfcprop(nb)%weasd(:)
enddo
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'weasdi'
+ ExtDiag(idx)%desc = 'surface snow water equivalent over ice'
+ ExtDiag(idx)%unit = 'kg/m**2'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => sfcprop(nb)%weasdi(:)
+ enddo
+
+ idx = idx + 1
+ ExtDiag(idx)%axes = 2
+ ExtDiag(idx)%name = 'snodi'
+ ExtDiag(idx)%desc = 'water equivalent snow depth over ice'
+ ExtDiag(idx)%unit = 'mm'
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var2 => sfcprop(nb)%weasdi(:)
+ enddo
+
idx = idx + 1
ExtDiag(idx)%axes = 2
ExtDiag(idx)%name = 'hgtsfc'
@@ -4787,6 +5049,131 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop
end subroutine GFS_externaldiag_populate
+ subroutine clm_lake_externaldiag_populate(ExtDiag, Model, Sfcprop, idx, cn_one, nblks)
+ implicit none
+ type(GFS_externaldiag_type), intent(inout) :: ExtDiag(:)
+ type(GFS_control_type), intent(in) :: Model
+ type(GFS_sfcprop_type), intent(in) :: Sfcprop(:)
+ integer, intent(inout) :: idx
+ integer, intent(in) :: nblks
+ real(kind=kind_phys), intent(in) :: cn_one
+ character(:), allocatable :: fullname
+
+ integer :: nk, idx0, iblk
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_z3d, 'lake_z3d', 'lake_depth_on_interface_levels', 'm')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_clay3d, 'lake_clay3d', 'percent clay on soil levels in clm lake model', '%')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_sand3d, 'lake_sand3d', 'percent sand on soil levels in clm lake model', '%')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_dz3d, 'lake_dz3d', 'lake level thickness', 'm')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_soil_watsat3d, 'lake_soil_watsat3d', 'saturated volumetric soil water', 'm3 m-3')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_csol3d, 'lake_csol3d', 'soil heat capacity', 'J m-3 K-1')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_soil_tkmg3d, 'lake_soil_tkmg3d', 'soil thermal conductivity, minerals', 'W m-1 K-1')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_soil_tkdry3d, 'lake_soil_tkdry3d', 'soil thermal conductivity, dry soil', 'W m-1 K-1')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_soil_tksatu3d, 'lake_soil_tksatu3d', 'soil thermal conductivity, saturated soil', 'W m-1 K-1')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_snow_z3d, 'lake_snow_z3d', 'lake snow level depth', 'm')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_snow_dz3d, 'lake_snow_dz3d', 'lake snow level thickness', 'm')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_snow_zi3d, 'lake_snow_zi3d', 'lake snow interface depth', 'm')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_h2osoi_vol3d, 'lake_h2osoi_vol3d', 'volumetric soil water', 'm3 m-3')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_h2osoi_liq3d, 'lake_h2osoi_liq3d', 'soil liquid water content', 'kg m-2')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_h2osoi_ice3d, 'lake_h2osoi_ice3d', 'soil ice water content', 'kg m-2')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_t_soisno3d, 'lake_t_soisno3d', 'snow or soil level temperature', 'K')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_t_lake3d, 'lake_t_lake3d', 'lake layer temperature', 'K')
+ enddo
+
+ do iblk=1,nblks
+ call link_all_levels(Sfcprop(iblk)%lake_icefrac3d, 'lake_icefrac3d', 'lake fractional ice cover', 'fraction')
+ enddo
+
+ contains
+
+ subroutine link_all_levels(var3d, varname, levelname, unit)
+ implicit none
+ real(kind=kind_phys), target :: var3d(:,:)
+ character(len=*), intent(in) :: varname, levelname, unit
+ integer k, b, namelen
+
+ if(iblk==1) then
+ namelen = 30+max(len(varname),len(levelname))
+ allocate(character(namelen) :: fullname)
+ idx0 = idx
+ endif
+
+ var_z_loop: do k=1,size(var3d,2)
+ idx = idx0 + k
+ if(iblk==1) then
+ ExtDiag(idx)%axes = 2
+ write(fullname,"(A,'_',I0)") trim(varname),k
+ ExtDiag(idx)%name = trim(fullname)
+ write(fullname,"(A,' level ',I0,' of ',I0)") trim(levelname),k,size(var3d,2)
+ ExtDiag(idx)%desc = trim(fullname)
+ ExtDiag(idx)%unit = trim(unit)
+ ExtDiag(idx)%mod_name = 'gfs_sfc'
+ ExtDiag(idx)%intpl_method = 'nearest_stod'
+
+ allocate (ExtDiag(idx)%data(nblks))
+ do b=1,nblks
+ nullify(ExtDiag(idx)%data(b)%var2)
+ enddo
+ endif
+
+ ExtDiag(idx)%data(iblk)%var2 => var3d(:,k)
+ enddo var_z_loop
+
+ if(iblk==nblks) then
+ deallocate(fullname)
+ endif
+ end subroutine link_all_levels
+ end subroutine clm_lake_externaldiag_populate
+
function soil_layer_depth(lsm, lsm_ruc, lsm_noah, layer) result(layer_depth)
character(len=30) :: layer_depth
integer, intent(in) :: lsm, lsm_ruc, lsm_noah, layer
diff --git a/ccpp/driver/GFS_restart.F90 b/ccpp/driver/GFS_restart.F90
index c68f48535c..a1447b67b8 100644
--- a/ccpp/driver/GFS_restart.F90
+++ b/ccpp/driver/GFS_restart.F90
@@ -63,6 +63,7 @@ subroutine GFS_restart_populate (Restart, Model, Statein, Stateout, Sfcprop, &
integer :: ndiag_idx(20), itime
integer :: nblks, num, nb, max_rstrt, offset
character(len=2) :: c2 = ''
+ logical :: surface_layer_saves_rainprev
nblks = size(Init_parm%blksz)
max_rstrt = size(Restart%name2d)
@@ -106,6 +107,12 @@ subroutine GFS_restart_populate (Restart, Model, Statein, Stateout, Sfcprop, &
Restart%ldiag = 3 + Model%ntot2d + Model%nctp + ndiag_rst
Restart%num2d = 3 + Model%ntot2d + Model%nctp + ndiag_rst
+ ! The CLM Lake Model needs raincprev and rainncprv, which some
+ ! surface layer schemes save, and some don't. If the surface layer
+ ! scheme does not save that variable, then it'll be saved
+ ! separately for clm_lake.
+ surface_layer_saves_rainprev = .false.
+
! GF
if (Model%imfdeepcnv == Model%imfdeepcnv_gf) then
Restart%num2d = Restart%num2d + 3
@@ -121,15 +128,22 @@ subroutine GFS_restart_populate (Restart, Model, Statein, Stateout, Sfcprop, &
! NoahMP
if (Model%lsm == Model%lsm_noahmp) then
Restart%num2d = Restart%num2d + 10
+ surface_layer_saves_rainprev = .true.
endif
! RUC
if (Model%lsm == Model%lsm_ruc) then
Restart%num2d = Restart%num2d + 5
+ surface_layer_saves_rainprev = .true.
endif
! MYNN SFC
if (Model%do_mynnsfclay) then
Restart%num2d = Restart%num2d + 13
endif
+ ! Save rain prev for lake if surface layer doesn't.
+ if (Model%lkm>0 .and. Model%iopt_lake==Model%iopt_lake_clm .and. &
+ .not.surface_layer_saves_rainprev) then
+ Restart%num2d = Restart%num2d + 2
+ endif
! Thompson aerosol-aware
if (Model%imp_physics == Model%imp_physics_thompson .and. Model%ltaerosol) then
Restart%num2d = Restart%num2d + 2
@@ -429,6 +443,20 @@ subroutine GFS_restart_populate (Restart, Model, Statein, Stateout, Sfcprop, &
Restart%data(nb,num)%var2p => Sfcprop(nb)%qss(:)
enddo
endif
+ ! Save rain prev for lake if surface layer doesn't.
+ if (Model%lkm>0 .and. Model%iopt_lake==Model%iopt_lake_clm .and. &
+ .not.surface_layer_saves_rainprev) then
+ num = num + 1
+ Restart%name2d(num) = 'raincprv'
+ do nb = 1,nblks
+ Restart%data(nb,num)%var2p => Sfcprop(nb)%raincprv(:)
+ enddo
+ num = num + 1
+ Restart%name2d(num) = 'rainncprv'
+ do nb = 1,nblks
+ Restart%data(nb,num)%var2p => Sfcprop(nb)%rainncprv(:)
+ enddo
+ endif
! Thompson aerosol-aware
if (Model%imp_physics == Model%imp_physics_thompson .and. Model%ltaerosol) then
num = num + 1
diff --git a/ccpp/physics b/ccpp/physics
index 494356c907..eda81a58a1 160000
--- a/ccpp/physics
+++ b/ccpp/physics
@@ -1 +1 @@
-Subproject commit 494356c90724cc020c8b6e7e4089767324c4b215
+Subproject commit eda81a58a1e3dd87c945f0d9cc43d53a1c858d65
diff --git a/ccpp/suites/suite_FV3_GFS_v16_clm_lake.xml b/ccpp/suites/suite_FV3_GFS_v16_clm_lake.xml
new file mode 100644
index 0000000000..fb8dcd3ec3
--- /dev/null
+++ b/ccpp/suites/suite_FV3_GFS_v16_clm_lake.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+ fv_sat_adj
+
+
+
+
+ GFS_time_vary_pre
+ GFS_rrtmg_setup
+ GFS_rad_time_vary
+ GFS_phys_time_vary
+
+
+
+
+ GFS_suite_interstitial_rad_reset
+ GFS_rrtmg_pre
+ GFS_radiation_surface
+ rad_sw_pre
+ rrtmg_sw
+ rrtmg_sw_post
+ rrtmg_lw_pre
+ rrtmg_lw
+ rrtmg_lw_post
+ GFS_rrtmg_post
+
+
+
+
+ GFS_suite_interstitial_phys_reset
+ GFS_suite_stateout_reset
+ get_prs_fv3
+ GFS_suite_interstitial_1
+ GFS_surface_generic_pre
+ GFS_surface_composites_pre
+ dcyc2t3
+ GFS_surface_composites_inter
+ GFS_suite_interstitial_2
+
+
+
+ sfc_diff
+ GFS_surface_loop_control_part1
+ sfc_nst_pre
+ sfc_nst
+ sfc_nst_post
+ lsm_noah
+ clm_lake
+ sfc_sice
+ GFS_surface_loop_control_part2
+
+
+
+ GFS_surface_composites_post
+ sfc_diag
+ sfc_diag_post
+ GFS_surface_generic_post
+ GFS_PBL_generic_pre
+ satmedmfvdifq
+ GFS_PBL_generic_post
+ GFS_GWD_generic_pre
+ cires_ugwp
+ cires_ugwp_post
+ GFS_GWD_generic_post
+ GFS_suite_stateout_update
+ ozphys_2015
+ h2ophys
+ get_phi_fv3
+ GFS_suite_interstitial_3
+ GFS_DCNV_generic_pre
+ samfdeepcnv
+ GFS_DCNV_generic_post
+ GFS_SCNV_generic_pre
+ samfshalcnv
+ GFS_SCNV_generic_post
+ GFS_suite_interstitial_4
+ cnvc90
+ GFS_MP_generic_pre
+ gfdl_cloud_microphys
+ GFS_MP_generic_post
+ maximum_hourly_diagnostics
+ phys_tend
+
+
+
+
+ GFS_stochastics
+
+
+
+
diff --git a/ccpp/suites/suite_FV3_HRRR.xml b/ccpp/suites/suite_FV3_HRRR.xml
index 01c493d5a3..6ac35db14f 100644
--- a/ccpp/suites/suite_FV3_HRRR.xml
+++ b/ccpp/suites/suite_FV3_HRRR.xml
@@ -43,7 +43,7 @@
mynnsfc_wrapper
GFS_surface_loop_control_part1
lsm_ruc
- flake_driver
+ clm_lake
GFS_surface_loop_control_part2
diff --git a/ccpp/suites/suite_FV3_HRRR_flake.xml b/ccpp/suites/suite_FV3_HRRR_flake.xml
new file mode 100644
index 0000000000..3adea10694
--- /dev/null
+++ b/ccpp/suites/suite_FV3_HRRR_flake.xml
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+ GFS_time_vary_pre
+ GFS_rrtmg_setup
+ GFS_rad_time_vary
+ GFS_phys_time_vary
+
+
+
+
+ GFS_suite_interstitial_rad_reset
+ sgscloud_radpre
+ GFS_rrtmg_pre
+ GFS_radiation_surface
+ rad_sw_pre
+ rrtmg_sw
+ rrtmg_sw_post
+ rrtmg_lw_pre
+ rrtmg_lw
+ sgscloud_radpost
+ rrtmg_lw_post
+ GFS_rrtmg_post
+
+
+
+
+ GFS_suite_interstitial_phys_reset
+ GFS_suite_stateout_reset
+ get_prs_fv3
+ GFS_suite_interstitial_1
+ GFS_surface_generic_pre
+ GFS_surface_composites_pre
+ dcyc2t3
+ GFS_surface_composites_inter
+ GFS_suite_interstitial_2
+
+
+
+ mynnsfc_wrapper
+ GFS_surface_loop_control_part1
+ lsm_ruc
+ flake_driver
+ GFS_surface_loop_control_part2
+
+
+
+ GFS_surface_composites_post
+ sfc_diag
+ sfc_diag_post
+ GFS_surface_generic_post
+ rrfs_smoke_wrapper
+ mynnedmf_wrapper
+ rrfs_smoke_postpbl
+ GFS_GWD_generic_pre
+ drag_suite
+ GFS_GWD_generic_post
+ GFS_suite_stateout_update
+ ozphys_2015
+ h2ophys
+ get_phi_fv3
+ GFS_suite_interstitial_3
+ GFS_suite_interstitial_4
+ GFS_MP_generic_pre
+ mp_thompson_pre
+ mp_thompson
+ mp_thompson_post
+ GFS_MP_generic_post
+ maximum_hourly_diagnostics
+ phys_tend
+
+
+
+
+ GFS_stochastics
+
+
+
+
diff --git a/ccpp/suites/suite_FV3_RAP_clm_lake.xml b/ccpp/suites/suite_FV3_RAP_clm_lake.xml
new file mode 100644
index 0000000000..9a28a64212
--- /dev/null
+++ b/ccpp/suites/suite_FV3_RAP_clm_lake.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+ GFS_time_vary_pre
+ GFS_rrtmg_setup
+ GFS_rad_time_vary
+ GFS_phys_time_vary
+
+
+
+
+ GFS_suite_interstitial_rad_reset
+ sgscloud_radpre
+ GFS_rrtmg_pre
+ GFS_radiation_surface
+ rad_sw_pre
+ rrtmg_sw
+ rrtmg_sw_post
+ rrtmg_lw_pre
+ rrtmg_lw
+ sgscloud_radpost
+ rrtmg_lw_post
+ GFS_rrtmg_post
+
+
+
+
+ GFS_suite_interstitial_phys_reset
+ GFS_suite_stateout_reset
+ get_prs_fv3
+ GFS_suite_interstitial_1
+ GFS_surface_generic_pre
+ GFS_surface_composites_pre
+ dcyc2t3
+ GFS_surface_composites_inter
+ GFS_suite_interstitial_2
+
+
+
+ mynnsfc_wrapper
+ GFS_surface_loop_control_part1
+ sfc_nst_pre
+ sfc_nst
+ sfc_nst_post
+ lsm_ruc
+ clm_lake
+ GFS_surface_loop_control_part2
+
+
+
+ GFS_surface_composites_post
+ sfc_diag
+ sfc_diag_post
+ GFS_surface_generic_post
+ mynnedmf_wrapper
+ GFS_GWD_generic_pre
+ drag_suite
+ GFS_GWD_generic_post
+ GFS_suite_stateout_update
+ ozphys_2015
+ h2ophys
+ get_phi_fv3
+ GFS_suite_interstitial_3
+ GFS_DCNV_generic_pre
+ cu_gf_driver_pre
+ cu_gf_driver
+ GFS_DCNV_generic_post
+ GFS_SCNV_generic_pre
+ GFS_SCNV_generic_post
+ GFS_suite_interstitial_4
+ cnvc90
+ GFS_MP_generic_pre
+ mp_thompson_pre
+ mp_thompson
+ mp_thompson_post
+ GFS_MP_generic_post
+ cu_gf_driver_post
+ maximum_hourly_diagnostics
+ phys_tend
+
+
+
+
+ GFS_stochastics
+
+
+
+
diff --git a/io/FV3GFS_io.F90 b/io/FV3GFS_io.F90
index a84eabcfb7..876248d162 100644
--- a/io/FV3GFS_io.F90
+++ b/io/FV3GFS_io.F90
@@ -33,7 +33,7 @@ module FV3GFS_io_mod
use diag_util_mod, only: find_input_field
use constants_mod, only: grav, rdgas
use physcons, only: con_tice !saltwater freezing temp (K)
-
+ use clm_lake_io, only: clm_lake_data_type
!
!--- GFS_typedefs
use GFS_typedefs, only: GFS_sfcprop_type, GFS_control_type, &
@@ -99,7 +99,7 @@ module FV3GFS_io_mod
real(kind=kind_phys),dimension(:,:,:),allocatable:: uwork3d
logical :: uwork_set = .false.
character(128) :: uwindname
- integer, parameter, public :: DIAG_SIZE = 500
+ integer, parameter, public :: DIAG_SIZE = 800
real, parameter :: missing_value = 9.99e20_r8
real, parameter:: stndrd_atmos_ps = 101325.0_r8
real, parameter:: stndrd_atmos_lapse = 0.0065_r8
@@ -243,6 +243,10 @@ subroutine FV3GFS_GFS_checksum (Model, GFS_Data, Atm_block)
nsfcprop2d = nsfcprop2d + 16
endif
+ if(Model%lkm>0 .and. Model%iopt_lake==Model%iopt_lake_flake) then
+ nsfcprop2d = nsfcprop2d + 10
+ endif
+
allocate (temp2d(isc:iec,jsc:jec,nsfcprop2d+Model%ntot2d+Model%nctp))
allocate (temp3d(isc:iec,jsc:jec,1:lev,14+Model%ntot3d+2*ntr))
allocate (temp3dlevsp1(isc:iec,jsc:jec,1:lev+1,3))
@@ -480,6 +484,20 @@ subroutine FV3GFS_GFS_checksum (Model, GFS_Data, Atm_block)
call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,temp2d,GFS_Data(nb)%Sfcprop%qrain)
endif nstf_name_choice
+! Flake
+ if (Model%lkm > 0 .and. Model%iopt_lake==Model%iopt_lake_flake) then
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,temp2d,GFS_Data(nb)%Sfcprop%T_snow)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,temp2d,GFS_Data(nb)%Sfcprop%T_ice)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,temp2d,GFS_Data(nb)%Sfcprop%h_ML)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,temp2d,GFS_Data(nb)%Sfcprop%t_ML)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,temp2d,GFS_Data(nb)%Sfcprop%t_mnw)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,temp2d,GFS_Data(nb)%Sfcprop%h_talb)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,temp2d,GFS_Data(nb)%Sfcprop%t_talb)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,temp2d,GFS_Data(nb)%Sfcprop%t_bot1)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,temp2d,GFS_Data(nb)%Sfcprop%t_bot2)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,temp2d,GFS_Data(nb)%Sfcprop%c_t)
+ endif
+
call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,temp2d,GFS_Data(nb)%Tbd%phy_f2d)
call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,temp2d,GFS_Data(nb)%Tbd%phy_fctd)
@@ -837,6 +855,19 @@ pure subroutine fill_Sfcprop_names(Model,sfc_name2,sfc_name3,nvar_s2m,warm_start
else if (Model%lsm == Model%lsm_ruc .and. Model%rdlai) then
nt=nt+1 ; sfc_name2(nt) = 'lai'
endif
+
+ if (Model%lkm > 0 .and. Model%iopt_lake==Model%iopt_lake_flake) then
+ nt=nt+1 ; sfc_name2(nt) = 'T_snow'
+ nt=nt+1 ; sfc_name2(nt) = 'T_ice'
+ nt=nt+1 ; sfc_name2(nt) = 'h_ML'
+ nt=nt+1 ; sfc_name2(nt) = 't_ML'
+ nt=nt+1 ; sfc_name2(nt) = 't_mnw'
+ nt=nt+1 ; sfc_name2(nt) = 'h_talb'
+ nt=nt+1 ; sfc_name2(nt) = 't_talb'
+ nt=nt+1 ; sfc_name2(nt) = 't_bot1'
+ nt=nt+1 ; sfc_name2(nt) = 't_bot2'
+ nt=nt+1 ; sfc_name2(nt) = 'c_t'
+ endif
end subroutine fill_sfcprop_names
!----------------------------------------------------------------------
@@ -868,7 +899,7 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain, warm_sta
integer :: nvar_oro_ls_ss
integer :: nvar_vegfr, nvar_soilfr
integer :: nvar_s2r, nvar_s2mp, nvar_s3mp, isnow
- integer :: nvar_emi, nvar_dust12m, nvar_rrfssd
+ integer :: nvar_emi, nvar_dust12m, nvar_gbbepx, nvar_before_lake, nvar_s2l, nvar_rrfssd
integer, allocatable :: ii1(:), jj1(:)
real(kind=kind_phys), pointer, dimension(:,:) :: var2_p => NULL()
real(kind=kind_phys), pointer, dimension(:,:,:) :: var3_p => NULL()
@@ -887,6 +918,7 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain, warm_sta
logical :: amiopen
logical :: is_lsoil
+ type(clm_lake_data_type) :: clm_lake
type(rrfs_sd_data_type) :: rrfs_sd_data
nvar_o2 = 19
@@ -1042,8 +1074,20 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain, warm_sta
Sfcprop(nb)%lakefrac(ix) = -9999.0
num = num + 1 ; Sfcprop(nb)%landfrac(ix) = oro_var2(i,j,num) !land frac [0:1]
- num = num + 1 ; Sfcprop(nb)%lakefrac(ix) = oro_var2(i,j,num) !lake frac [0:1]
- num = num + 1 ; Sfcprop(nb)%lakedepth(ix) = oro_var2(i,j,num) !lake depth [m] !YWu
+ if (Model%lkm > 0 ) then
+ if(oro_var2(i,j,num+1)>Model%lakefrac_threshold .and. &
+ oro_var2(i,j,num+2)>Model%lakedepth_threshold) then
+ Sfcprop(nb)%lakefrac(ix) = oro_var2(i,j,num+1) !lake frac [0:1]
+ Sfcprop(nb)%lakedepth(ix) = oro_var2(i,j,num+2) !lake depth [m] !YWu
+ else
+ Sfcprop(nb)%lakefrac(ix) = 0
+ Sfcprop(nb)%lakedepth(ix) = -9999
+ endif
+ else
+ Sfcprop(nb)%lakefrac(ix) = oro_var2(i,j,num+1) !lake frac [0:1]
+ Sfcprop(nb)%lakedepth(ix) = oro_var2(i,j,num+2) !lake depth [m] !YWu
+ endif
+ num = num + 2 ! To account for lakefrac and lakedepth
Sfcprop(nb)%vegtype_frac(ix,:) = -9999.0
Sfcprop(nb)%soiltype_frac(ix,:) = -9999.0
@@ -1069,6 +1113,14 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain, warm_sta
if (Model%cplwav) then
nvar_s2m = nvar_s2m + 1
endif
+! CLM Lake and Flake
+ if (Model%lkm > 0 .and. Model%iopt_lake==Model%iopt_lake_flake ) then
+ nvar_s2l = 10
+ else
+ nvar_s2l = 0
+ endif
+
+ nvar_before_lake=nvar_s2m+nvar_s2o+nvar_s2r+nvar_s2mp
!--- deallocate containers and free restart container
deallocate(oro_name2, oro_var2)
@@ -1332,9 +1384,9 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain, warm_sta
if (.not. allocated(sfc_name2)) then
!--- allocate the various containers needed for restarts
- allocate(sfc_name2(nvar_s2m+nvar_s2o+nvar_s2mp+nvar_s2r))
+ allocate(sfc_name2(nvar_s2m+nvar_s2o+nvar_s2mp+nvar_s2r+nvar_s2l))
allocate(sfc_name3(0:nvar_s3+nvar_s3mp))
- allocate(sfc_var2(nx,ny,nvar_s2m+nvar_s2o+nvar_s2mp+nvar_s2r))
+ allocate(sfc_var2(nx,ny,nvar_s2m+nvar_s2o+nvar_s2mp+nvar_s2r+nvar_s2l))
! Note that this may cause problems with RUC LSM for coldstart runs from GFS data
! if the initial conditions do contain this variable, because Model%kice is 9 for
! RUC LSM, but tiice in the initial conditions will only have two vertical layers
@@ -1391,6 +1443,14 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain, warm_sta
call register_axis(Sfc_restart, 'Time', unlimited)
end if
+ ! Tell CLM Lake to allocate data, and register its axes and fields
+ if(Model%lkm>0 .and. Model%iopt_lake==Model%iopt_lake_clm) then
+ call clm_lake%allocate_data(Model)
+ call clm_lake%copy_to_temporaries(Model,Sfcprop,Atm_block)
+ call clm_lake%register_axes(Model, Sfc_restart)
+ call clm_lake%register_fields(Sfc_restart)
+ endif
+
if(Model%rrfs_sd) then
call rrfs_sd_data%allocate_data(Model)
call rrfs_sd_data%fill_data(Model, Sfcprop, Atm_block)
@@ -1466,6 +1526,20 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain, warm_sta
end if
enddo
endif ! noahmp
+
+! Flake
+ if (Model%lkm > 0 .and. Model%iopt_lake==Model%iopt_lake_flake) then
+ mand = .false.
+ do num = nvar_before_lake+1,nvar_before_lake+nvar_s2l
+ var2_p => sfc_var2(:,:,num)
+ if(is_lsoil) then
+ call register_restart_field(Sfc_restart, sfc_name2(num),var2_p,dimensions=(/'lat','lon'/), is_optional=.not.mand)
+ else
+ call register_restart_field(Sfc_restart, sfc_name2(num),var2_p,dimensions=(/'Time ','yaxis_1','xaxis_1'/), is_optional=.not.mand)
+ endif
+ enddo
+ endif
+
nullify(var2_p)
endif ! if not allocated
@@ -1547,6 +1621,11 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain, warm_sta
call read_restart(Sfc_restart, ignore_checksum=ignore_rst_cksum)
call close_file(Sfc_restart)
+ ! Tell clm_lake to copy data to temporary arrays
+ if(Model%lkm>0 .and. Model%iopt_lake==Model%iopt_lake_clm) then
+ call clm_lake%copy_from_temporaries(Model,Sfcprop,Atm_block)
+ endif
+
if(Model%rrfs_sd) then
call rrfs_sd_data%copy_from_temporaries(Model,Sfcprop,Atm_block)
end if
@@ -1839,7 +1918,18 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain, warm_sta
call copy_to_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%deeprechxy)
call copy_to_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%rechxy)
endif
-
+ if (Model%lkm > 0 .and. Model%iopt_lake==Model%iopt_lake_flake) then
+ call copy_to_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%T_snow)
+ call copy_to_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%T_ice)
+ call copy_to_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%h_ML)
+ call copy_to_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%t_ML)
+ call copy_to_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%t_mnw)
+ call copy_to_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%h_talb)
+ call copy_to_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%t_talb)
+ call copy_to_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%t_bot1)
+ call copy_to_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%t_bot2)
+ call copy_to_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%c_t)
+ endif
if (Model%lsm == Model%lsm_noah .or. Model%lsm == Model%lsm_noahmp .or. (.not.warm_start)) then
!--- 3D variables
nt=0
@@ -2114,7 +2204,7 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain, warm_sta
enddo
endif
- ! A standard-compliant Fortran 2003 compiler will call rrfs_sd_final here
+ ! A standard-compliant Fortran 2003 compiler will call clm_lake_final and rrfs_sd_final here.
end subroutine sfc_prop_restart_read
@@ -2141,7 +2231,7 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta
integer :: isc, iec, jsc, jec, npz, nx, ny
integer :: id_restart
integer :: nvar2m, nvar2o, nvar3
- integer :: nvar2r, nvar2mp, nvar3mp
+ integer :: nvar2r, nvar2mp, nvar3mp, nvar_before_lake, nvar2l
logical :: mand
integer, allocatable :: ii1(:), jj1(:)
character(len=32) :: fn_srf = 'sfc_data.nc'
@@ -2159,6 +2249,7 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta
!--- variables used for fms2_io register axis
integer :: is, ie
integer, allocatable, dimension(:) :: buffer
+ type(clm_lake_data_type), target :: clm_lake
!--- temporary variables for storing rrfs_sd fields
type(rrfs_sd_data_type) :: rrfs_sd_data
@@ -2190,6 +2281,14 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta
nvar2mp = 29
nvar3mp = 5
endif
+!CLM Lake and Flake
+ if (Model%lkm > 0 .and. Model%iopt_lake==Model%iopt_lake_flake) then
+ nvar2l = 10
+ else
+ nvar2l = 0
+ endif
+
+ nvar_before_lake=nvar2m+nvar2o+nvar2r+nvar2mp
isc = Atm_block%isc
iec = Atm_block%iec
@@ -2199,11 +2298,13 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta
nx = (iec - isc + 1)
ny = (jec - jsc + 1)
+ nvar_before_lake=nvar2m+nvar2o+nvar2r+nvar2mp
+
if (Model%lsm == Model%lsm_ruc) then
if (allocated(sfc_name2)) then
! Re-allocate if one or more of the dimensions don't match
- if (size(sfc_name2).ne.nvar2m+nvar2o+nvar2mp+nvar2r .or. &
- size(sfc_name3).ne.nvar3+nvar3mp .or. &
+ if (size(sfc_name2).ne.nvar2m+nvar2o+nvar2mp+nvar2r+nvar2l .or. &
+ size(sfc_name3).ne.nvar3+nvar3mp .or. &
size(sfc_var3,dim=3).ne.Model%lsoil_lsm) then
!--- deallocate containers and free restart container
deallocate(sfc_name2)
@@ -2285,6 +2386,13 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta
else
call mpp_error(FATAL, 'Error in opening file'//trim(infile) )
end if if_amiopen
+
+ ! Tell clm_lake to allocate data, register its axes, and call write_data for each axis's variable
+ if(Model%lkm>0 .and. Model%iopt_lake==Model%iopt_lake_clm) then
+ call clm_lake%allocate_data(Model)
+ call clm_lake%register_axes(Model, Sfc_restart)
+ call clm_lake%write_axes(Model, Sfc_restart)
+ endif
if(Model%rrfs_sd) then
call rrfs_sd_data%allocate_data(Model)
@@ -2294,9 +2402,9 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta
if (.not. allocated(sfc_name2)) then
!--- allocate the various containers needed for restarts
- allocate(sfc_name2(nvar2m+nvar2o+nvar2mp+nvar2r))
+ allocate(sfc_name2(nvar2m+nvar2o+nvar2mp+nvar2r+nvar2l))
allocate(sfc_name3(0:nvar3+nvar3mp))
- allocate(sfc_var2(nx,ny,nvar2m+nvar2o+nvar2mp+nvar2r))
+ allocate(sfc_var2(nx,ny,nvar2m+nvar2o+nvar2mp+nvar2r+nvar2l))
if (Model%lsm == Model%lsm_noah .or. Model%lsm == Model%lsm_noahmp) then
allocate(sfc_var3(nx,ny,Model%lsoil,nvar3))
elseif (Model%lsm == Model%lsm_ruc) then
@@ -2316,6 +2424,20 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta
call fill_Sfcprop_names(Model,sfc_name2,sfc_name3,nvar2m,.true.)
end if
+ if(Model%lkm>0) then
+ if(Model%iopt_lake==Model%iopt_lake_flake ) then
+ if(Model%me==0) then
+ if(size(sfc_name2)/=nvar_before_lake+10) then
+3814 format("ERROR: size mismatch size(sfc_name2)=",I0," /= nvar_before_lake+10=",I0)
+ write(0,3814) size(sfc_name2),nvar_before_lake+10
+ endif
+ endif
+ else if(Model%iopt_lake==Model%iopt_lake_clm) then
+ ! Tell clm_lake to register all of its fields
+ call clm_lake%register_fields(Sfc_restart)
+ endif
+ endif
+
if(Model%rrfs_sd) then
call rrfs_sd_data%register_fields
endif
@@ -2427,7 +2549,22 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta
nullify(var3_p3)
endif ! lsm = lsm_noahmp
- if(Model%rrfs_sd) then
+ !Flake
+ if (Model%lkm > 0 .and. Model%iopt_lake==Model%iopt_lake_flake) then
+ mand = .false.
+ do num = nvar_before_lake+1,nvar_before_lake+nvar2l
+ var2_p => sfc_var2(:,:,num)
+ call register_restart_field(Sfc_restart, sfc_name2(num),var2_p,dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/),&
+ &is_optional=.not.mand)
+ enddo
+ endif
+
+ ! Tell clm_lake to copy Sfcprop data to its internal temporary arrays.
+ if(Model%lkm>0 .and. Model%iopt_lake==Model%iopt_lake_clm) then
+ call clm_lake%copy_to_temporaries(Model,Sfcprop,Atm_block)
+ endif
+
+ if(Model%rrfs_sd) then
call rrfs_sd_data%copy_to_temporaries(Model,Sfcprop,Atm_block)
endif
@@ -2570,6 +2707,19 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta
call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%deeprechxy)
call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%rechxy)
endif
+! Flake
+ if(Model%lkm > 0 .and. Model%iopt_lake==Model%iopt_lake_flake) then
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%T_snow)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%T_ice)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%h_ML)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%t_ML)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%t_mnw)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%h_talb)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%t_talb)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%t_bot1)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%t_bot2)
+ call copy_from_GFS_Data(ii1,jj1,isc,jsc,nt,sfc_var2,Sfcprop(nb)%c_t)
+ endif
do k = 1,Model%kice
do ix = 1, Atm_block%blksz(nb)
ice=Sfcprop(nb)%tiice(ix,k)
@@ -2644,7 +2794,7 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta
call write_restart(Sfc_restart)
call close_file(Sfc_restart)
- ! A standard-compliant Fortran 2003 compiler will call rrfs_sd_final here
+ ! A standard-compliant Fortran 2003 compiler will call rrfs_sd_final and clm_lake_final here
end subroutine sfc_prop_restart_write
diff --git a/io/clm_lake_io.F90 b/io/clm_lake_io.F90
new file mode 100644
index 0000000000..6a47f3ab6a
--- /dev/null
+++ b/io/clm_lake_io.F90
@@ -0,0 +1,432 @@
+module clm_lake_io
+ use GFS_typedefs, only: GFS_sfcprop_type, GFS_control_type, &
+ GFS_data_type, kind_phys
+ use GFS_restart, only: GFS_restart_type
+ use GFS_diagnostics, only: GFS_externaldiag_type
+ use block_control_mod, only: block_control_type
+ use fms2_io_mod, only: FmsNetcdfDomainFile_t, unlimited, &
+ open_file, close_file, &
+ register_axis, register_restart_field, &
+ register_variable_attribute, register_field, &
+ read_restart, write_restart, write_data, &
+ get_global_io_domain_indices, variable_exists
+
+ implicit none
+
+ type clm_lake_data_type
+ ! The clm_lake_data_type derived type is a class that stores
+ ! temporary arrays used to read or write CLM Lake model restart
+ ! and axis variables. It can safely be declared and unused, but
+ ! you should only call these routines if the CLM Lake Model was
+ ! (or will be) used by this execution of the FV3. It is the
+ ! responsibility of the caller to ensure the necessary data is in
+ ! Sfc_restart, Sfcprop, and Model.
+
+ ! All 2D variables needed for a restart
+ real(kind_phys), pointer, private, dimension(:,:) :: &
+ T_snow=>null(), T_ice=>null(), &
+ lake_snl2d=>null(), lake_h2osno2d=>null(), lake_tsfc=>null(), clm_lakedepth=>null(), &
+ lake_savedtke12d=>null(), lake_sndpth2d=>null(), clm_lake_initialized=>null()
+
+ ! All 3D variables needed for a restart
+ real(kind_phys), pointer, private, dimension(:,:,:) :: &
+ lake_z3d=>null(), lake_dz3d=>null(), lake_soil_watsat3d=>null(), &
+ lake_csol3d=>null(), lake_soil_tkmg3d=>null(), lake_soil_tkdry3d=>null(), &
+ lake_soil_tksatu3d=>null(), lake_snow_z3d=>null(), lake_snow_dz3d=>null(), &
+ lake_snow_zi3d=>null(), lake_h2osoi_vol3d=>null(), lake_h2osoi_liq3d=>null(), &
+ lake_h2osoi_ice3d=>null(), lake_t_soisno3d=>null(), lake_t_lake3d=>null(), &
+ lake_icefrac3d=>null(), lake_clay3d=>null(), lake_sand3d=>null()
+
+ contains
+
+ ! register_axes calls registers_axis on Sfc_restart for all required axes
+ procedure, public :: register_axes => clm_lake_register_axes
+
+ ! allocate_data allocates all of the pointers in this object
+ procedure, public :: allocate_data => clm_lake_allocate_data
+
+ ! register_fields calls register_field on Sfc_restart for all CLM Lake model restart variables
+ procedure, public :: register_fields => clm_lake_register_fields
+
+ ! deallocate_data deallocates all pointers, allowing this object to be used repeatedly.
+ ! It is safe to call deallocate_data if no data has been allocated.
+ procedure, public :: deallocate_data => clm_lake_deallocate_data
+
+ ! write_axes writes variables to Sfc_restart, with the name of
+ ! each axis, containing the appropriate information
+ procedure, public :: write_axes => clm_lake_write_axes
+
+ ! copy_to_temporaries copies from Sfcprop to internal pointers (declared above)
+ procedure, public :: copy_to_temporaries => clm_lake_copy_to_temporaries
+
+ ! copy_to_temporaries copies from internal pointers (declared above) to Sfcprop
+ procedure, public :: copy_from_temporaries => clm_lake_copy_from_temporaries
+
+ ! A fortran 2003 compliant compiler will call clm_lake_final
+ ! automatically when an object of this type goes out of
+ ! scope. This will deallocate any arrays via a call to
+ ! deallocate_data. It is safe to call this routine if no data has
+ ! been allocated.
+ final :: clm_lake_final
+ end type clm_lake_data_type
+
+ CONTAINS
+ subroutine clm_lake_allocate_data(data,Model)
+ ! Deallocate all data, and reallocate to the size specified in Model
+ implicit none
+ class(clm_lake_data_type) :: data
+ type(GFS_control_type), intent(in) :: Model
+
+ integer :: nx, ny
+ call data%deallocate_data
+
+ nx=Model%nx
+ ny=Model%ny
+
+ allocate(data%T_snow(nx,ny))
+ allocate(data%T_ice(nx,ny))
+ allocate(data%lake_snl2d(nx,ny))
+ allocate(data%lake_h2osno2d(nx,ny))
+ allocate(data%lake_tsfc(nx,ny))
+ allocate(data%lake_savedtke12d(nx,ny))
+ allocate(data%lake_sndpth2d(nx,ny))
+ allocate(data%clm_lakedepth(nx,ny))
+ allocate(data%clm_lake_initialized(nx,ny))
+
+ allocate(data%lake_z3d(nx,ny,Model%nlevlake_clm_lake))
+ allocate(data%lake_dz3d(nx,ny,Model%nlevlake_clm_lake))
+ allocate(data%lake_soil_watsat3d(nx,ny,Model%nlevlake_clm_lake))
+ allocate(data%lake_csol3d(nx,ny,Model%nlevlake_clm_lake))
+ allocate(data%lake_soil_tkmg3d(nx,ny,Model%nlevlake_clm_lake))
+ allocate(data%lake_soil_tkdry3d(nx,ny,Model%nlevlake_clm_lake))
+ allocate(data%lake_soil_tksatu3d(nx,ny,Model%nlevlake_clm_lake))
+ allocate(data%lake_snow_z3d(nx,ny,Model%nlevsnowsoil1_clm_lake))
+ allocate(data%lake_snow_dz3d(nx,ny,Model%nlevsnowsoil1_clm_lake))
+ allocate(data%lake_snow_zi3d(nx,ny,Model%nlevsnowsoil_clm_lake))
+ allocate(data%lake_h2osoi_vol3d(nx,ny,Model%nlevsnowsoil1_clm_lake))
+ allocate(data%lake_h2osoi_liq3d(nx,ny,Model%nlevsnowsoil1_clm_lake))
+ allocate(data%lake_h2osoi_ice3d(nx,ny,Model%nlevsnowsoil1_clm_lake))
+ allocate(data%lake_t_soisno3d(nx,ny,Model%nlevsnowsoil1_clm_lake))
+ allocate(data%lake_t_lake3d(nx,ny,Model%nlevlake_clm_lake))
+ allocate(data%lake_icefrac3d(nx,ny,Model%nlevlake_clm_lake))
+ allocate(data%lake_clay3d(nx,ny,Model%nlevsoil_clm_lake))
+ allocate(data%lake_sand3d(nx,ny,Model%nlevsoil_clm_lake))
+ end subroutine clm_lake_allocate_data
+
+ subroutine clm_lake_register_axes(data,Model,Sfc_restart)
+ ! Register all five axes needed by CLM Lake restart data
+ implicit none
+ class(clm_lake_data_type) :: data
+ type(GFS_control_type), intent(in) :: Model
+ type(FmsNetcdfDomainFile_t) :: Sfc_restart
+ call register_axis(Sfc_restart, 'levlake_clm_lake', dimension_length=Model%nlevlake_clm_lake)
+
+ call register_axis(Sfc_restart, 'levsoil_clm_lake', dimension_length=Model%nlevsoil_clm_lake)
+
+ call register_axis(Sfc_restart, 'levsnow_clm_lake', dimension_length=Model%nlevsnow_clm_lake)
+
+ call register_axis(Sfc_restart, 'levsnowsoil_clm_lake', dimension_length=Model%nlevsnowsoil_clm_lake)
+
+ call register_axis(Sfc_restart, 'levsnowsoil1_clm_lake', dimension_length=Model%nlevsnowsoil1_clm_lake)
+ end subroutine clm_lake_register_axes
+
+ subroutine clm_lake_write_axes(data, Model, Sfc_restart)
+ ! Create variables with the name name as each clm_lake axis, and
+ ! fill the variable with the appropriate indices
+ implicit none
+ class(clm_lake_data_type) :: data
+ type(GFS_control_type), intent(in) :: Model
+ type(FmsNetcdfDomainFile_t) :: Sfc_restart
+ real(kind_phys) :: levlake_clm_lake(Model%nlevlake_clm_lake)
+ real(kind_phys) :: levsoil_clm_lake(Model%nlevsoil_clm_lake)
+ real(kind_phys) :: levsnow_clm_lake(Model%nlevsnow_clm_lake)
+ real(kind_phys) :: levsnowsoil_clm_lake(Model%nlevsnowsoil_clm_lake)
+ real(kind_phys) :: levsnowsoil1_clm_lake(Model%nlevsnowsoil1_clm_lake)
+ integer :: i
+ call register_field(Sfc_restart, 'levlake_clm_lake', 'double', (/'levlake_clm_lake'/))
+ call register_variable_attribute(Sfc_restart, 'levlake_clm_lake', 'cartesian_axis' ,'Z', str_len=1)
+
+ call register_field(Sfc_restart, 'levsoil_clm_lake', 'double', (/'levsoil_clm_lake'/))
+ call register_variable_attribute(Sfc_restart, 'levsoil_clm_lake', 'cartesian_axis' ,'Z', str_len=1)
+
+ call register_field(Sfc_restart, 'levsnow_clm_lake', 'double', (/'levsnow_clm_lake'/))
+ call register_variable_attribute(Sfc_restart, 'levsnow_clm_lake', 'cartesian_axis' ,'Z', str_len=1)
+
+ call register_field(Sfc_restart, 'levsnowsoil_clm_lake', 'double', (/'levsnowsoil_clm_lake'/))
+ call register_variable_attribute(Sfc_restart, 'levsnowsoil_clm_lake', 'cartesian_axis' ,'Z', str_len=1)
+
+ call register_field(Sfc_restart, 'levsnowsoil1_clm_lake', 'double', (/'levsnowsoil1_clm_lake'/))
+ call register_variable_attribute(Sfc_restart, 'levsnowsoil1_clm_lake', 'cartesian_axis' ,'Z', str_len=1)
+
+ do i=1,Model%nlevlake_clm_lake
+ levlake_clm_lake(i) = i
+ enddo
+ do i=1,Model%nlevsoil_clm_lake
+ levsoil_clm_lake(i) = i
+ enddo
+ do i=1,Model%nlevsnow_clm_lake
+ levsnow_clm_lake(i) = i
+ enddo
+ do i=-Model%nlevsnow_clm_lake,Model%nlevsoil_clm_lake
+ levsnowsoil_clm_lake(i+Model%nlevsnow_clm_lake+1) = i
+ enddo
+ do i=-Model%nlevsnow_clm_lake+1,Model%nlevsoil_clm_lake
+ levsnowsoil1_clm_lake(i+Model%nlevsnow_clm_lake) = i
+ enddo
+
+ call write_data(Sfc_restart, 'levlake_clm_lake', levlake_clm_lake)
+ call write_data(Sfc_restart, 'levsoil_clm_lake', levsoil_clm_lake)
+ call write_data(Sfc_restart, 'levsnow_clm_lake', levsnow_clm_lake)
+ call write_data(Sfc_restart, 'levsnowsoil_clm_lake', levsnowsoil_clm_lake)
+ call write_data(Sfc_restart, 'levsnowsoil1_clm_lake', levsnowsoil1_clm_lake)
+ end subroutine clm_lake_write_axes
+
+ subroutine clm_lake_copy_to_temporaries(data, Model, Sfcprop, Atm_block)
+ ! Copies from Sfcprop variables to the corresponding data temporary variables.
+ ! Terrible things will happen if you don't call data%allocate_data first.
+ implicit none
+ class(clm_lake_data_type) :: data
+ type(GFS_sfcprop_type), intent(in) :: Sfcprop(:)
+ type(GFS_control_type), intent(in) :: Model
+ type(block_control_type), intent(in) :: Atm_block
+
+ integer :: nb, ix, isc, jsc, i, j
+ isc = Model%isc
+ jsc = Model%jsc
+
+ ! Copy data to temporary arrays
+
+!$omp parallel do default(shared) private(i, j, nb, ix)
+ do nb = 1, Atm_block%nblks
+ do ix = 1, Atm_block%blksz(nb)
+ i = Atm_block%index(nb)%ii(ix) - isc + 1
+ j = Atm_block%index(nb)%jj(ix) - jsc + 1
+
+ data%T_snow(i,j) = Sfcprop(nb)%T_snow(ix)
+ data%T_ice(i,j) = Sfcprop(nb)%T_ice(ix)
+ data%lake_snl2d(i,j) = Sfcprop(nb)%lake_snl2d(ix)
+ data%lake_h2osno2d(i,j) = Sfcprop(nb)%lake_h2osno2d(ix)
+ data%lake_tsfc(i,j) = Sfcprop(nb)%lake_tsfc(ix)
+ data%lake_savedtke12d(i,j) = Sfcprop(nb)%lake_savedtke12d(ix)
+ data%lake_sndpth2d(i,j) = Sfcprop(nb)%lake_sndpth2d(ix)
+ data%clm_lakedepth(i,j) = Sfcprop(nb)%clm_lakedepth(ix)
+ data%clm_lake_initialized(i,j) = Sfcprop(nb)%clm_lake_initialized(ix)
+
+ data%lake_z3d(i,j,:) = Sfcprop(nb)%lake_z3d(ix,:)
+ data%lake_dz3d(i,j,:) = Sfcprop(nb)%lake_dz3d(ix,:)
+ data%lake_soil_watsat3d(i,j,:) = Sfcprop(nb)%lake_soil_watsat3d(ix,:)
+ data%lake_csol3d(i,j,:) = Sfcprop(nb)%lake_csol3d(ix,:)
+ data%lake_soil_tkmg3d(i,j,:) = Sfcprop(nb)%lake_soil_tkmg3d(ix,:)
+ data%lake_soil_tkdry3d(i,j,:) = Sfcprop(nb)%lake_soil_tkdry3d(ix,:)
+ data%lake_soil_tksatu3d(i,j,:) = Sfcprop(nb)%lake_soil_tksatu3d(ix,:)
+ data%lake_snow_z3d(i,j,:) = Sfcprop(nb)%lake_snow_z3d(ix,:)
+ data%lake_snow_dz3d(i,j,:) = Sfcprop(nb)%lake_snow_dz3d(ix,:)
+ data%lake_snow_zi3d(i,j,:) = Sfcprop(nb)%lake_snow_zi3d(ix,:)
+ data%lake_h2osoi_vol3d(i,j,:) = Sfcprop(nb)%lake_h2osoi_vol3d(ix,:)
+ data%lake_h2osoi_liq3d(i,j,:) = Sfcprop(nb)%lake_h2osoi_liq3d(ix,:)
+ data%lake_h2osoi_ice3d(i,j,:) = Sfcprop(nb)%lake_h2osoi_ice3d(ix,:)
+ data%lake_t_soisno3d(i,j,:) = Sfcprop(nb)%lake_t_soisno3d(ix,:)
+ data%lake_t_lake3d(i,j,:) = Sfcprop(nb)%lake_t_lake3d(ix,:)
+ data%lake_icefrac3d(i,j,:) = Sfcprop(nb)%lake_icefrac3d(ix,:)
+ data%lake_clay3d(i,j,:) = Sfcprop(nb)%lake_clay3d(ix,:)
+ data%lake_sand3d(i,j,:) = Sfcprop(nb)%lake_sand3d(ix,:)
+ enddo
+ enddo
+ end subroutine clm_lake_copy_to_temporaries
+
+ subroutine clm_lake_copy_from_temporaries(data, Model, Sfcprop, Atm_block)
+ ! Copies from data temporary variables to the corresponding Sfcprop variables.
+ ! Terrible things will happen if you don't call data%allocate_data first.
+ implicit none
+ class(clm_lake_data_type) :: data
+ type(GFS_sfcprop_type), intent(in) :: Sfcprop(:)
+ type(GFS_control_type), intent(in) :: Model
+ type(block_control_type), intent(in) :: Atm_block
+
+ integer :: nb, ix, isc, jsc, i, j
+ isc = Model%isc
+ jsc = Model%jsc
+
+ ! Copy data to temporary arrays
+
+!$omp parallel do default(shared) private(i, j, nb, ix)
+ do nb = 1, Atm_block%nblks
+ do ix = 1, Atm_block%blksz(nb)
+ i = Atm_block%index(nb)%ii(ix) - isc + 1
+ j = Atm_block%index(nb)%jj(ix) - jsc + 1
+
+ Sfcprop(nb)%T_snow(ix) = data%T_snow(i,j)
+ Sfcprop(nb)%T_ice(ix) = data%T_ice(i,j)
+ Sfcprop(nb)%lake_snl2d(ix) = data%lake_snl2d(i,j)
+ Sfcprop(nb)%lake_h2osno2d(ix) = data%lake_h2osno2d(i,j)
+ Sfcprop(nb)%lake_tsfc(ix) = data%lake_tsfc(i,j)
+ Sfcprop(nb)%lake_savedtke12d(ix) = data%lake_savedtke12d(i,j)
+ Sfcprop(nb)%lake_sndpth2d(ix) = data%lake_sndpth2d(i,j)
+ Sfcprop(nb)%clm_lakedepth(ix) = data%clm_lakedepth(i,j)
+ Sfcprop(nb)%clm_lake_initialized(ix) = data%clm_lake_initialized(i,j)
+
+ Sfcprop(nb)%lake_z3d(ix,:) = data%lake_z3d(i,j,:)
+ Sfcprop(nb)%lake_dz3d(ix,:) = data%lake_dz3d(i,j,:)
+ Sfcprop(nb)%lake_soil_watsat3d(ix,:) = data%lake_soil_watsat3d(i,j,:)
+ Sfcprop(nb)%lake_csol3d(ix,:) = data%lake_csol3d(i,j,:)
+ Sfcprop(nb)%lake_soil_tkmg3d(ix,:) = data%lake_soil_tkmg3d(i,j,:)
+ Sfcprop(nb)%lake_soil_tkdry3d(ix,:) = data%lake_soil_tkdry3d(i,j,:)
+ Sfcprop(nb)%lake_soil_tksatu3d(ix,:) = data%lake_soil_tksatu3d(i,j,:)
+ Sfcprop(nb)%lake_snow_z3d(ix,:) = data%lake_snow_z3d(i,j,:)
+ Sfcprop(nb)%lake_snow_dz3d(ix,:) = data%lake_snow_dz3d(i,j,:)
+ Sfcprop(nb)%lake_snow_zi3d(ix,:) = data%lake_snow_zi3d(i,j,:)
+ Sfcprop(nb)%lake_h2osoi_vol3d(ix,:) = data%lake_h2osoi_vol3d(i,j,:)
+ Sfcprop(nb)%lake_h2osoi_liq3d(ix,:) = data%lake_h2osoi_liq3d(i,j,:)
+ Sfcprop(nb)%lake_h2osoi_ice3d(ix,:) = data%lake_h2osoi_ice3d(i,j,:)
+ Sfcprop(nb)%lake_t_soisno3d(ix,:) = data%lake_t_soisno3d(i,j,:)
+ Sfcprop(nb)%lake_t_lake3d(ix,:) = data%lake_t_lake3d(i,j,:)
+ Sfcprop(nb)%lake_icefrac3d(ix,:) = data%lake_icefrac3d(i,j,:)
+ Sfcprop(nb)%lake_clay3d(ix,:) = data%lake_clay3d(i,j,:)
+ Sfcprop(nb)%lake_sand3d(ix,:) = data%lake_sand3d(i,j,:)
+ enddo
+ enddo
+ end subroutine clm_lake_copy_from_temporaries
+
+ subroutine clm_lake_register_fields(data, Sfc_restart)
+ ! Registers all restart fields needed by the CLM Lake Model.
+ ! Terrible things will happen if you don't call data%allocate_data
+ ! and data%register_axes first.
+ implicit none
+ class(clm_lake_data_type) :: data
+ type(FmsNetcdfDomainFile_t) :: Sfc_restart
+
+ ! Register 2D fields
+ call register_restart_field(Sfc_restart, 'T_snow', data%T_snow, &
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart, 'T_ice', data%T_ice, &
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart, 'lake_snl2d', data%lake_snl2d, &
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart, 'lake_h2osno2d', data%lake_h2osno2d, &
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart, 'lake_tsfc', data%lake_tsfc, &
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart, 'lake_savedtke12d', data%lake_savedtke12d, &
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart, 'lake_sndpth2d', data%lake_sndpth2d, &
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart, 'clm_lakedepth', data%clm_lakedepth, &
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart, 'clm_lake_initialized', data%clm_lake_initialized, &
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+
+ ! Register 3D fields
+ call register_restart_field(Sfc_restart, 'lake_z3d', data%lake_z3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart, 'lake_dz3d', data%lake_dz3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_soil_watsat3d', data%lake_soil_watsat3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_csol3d', data%lake_csol3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_soil_tkmg3d', data%lake_soil_tkmg3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_soil_tkdry3d', data%lake_soil_tkdry3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_soil_tksatu3d', data%lake_soil_tksatu3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_snow_z3d', data%lake_snow_z3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levsnowsoil1_clm_lake', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_snow_dz3d', data%lake_snow_dz3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levsnowsoil1_clm_lake', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_snow_zi3d', data%lake_snow_zi3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levsnowsoil_clm_lake ', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_h2osoi_vol3d', data%lake_h2osoi_vol3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levsnowsoil1_clm_lake', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_h2osoi_liq3d', data%lake_h2osoi_liq3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levsnowsoil1_clm_lake', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_h2osoi_ice3d', data%lake_h2osoi_ice3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levsnowsoil1_clm_lake', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_t_soisno3d', data%lake_t_soisno3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levsnowsoil1_clm_lake', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_t_lake3d', data%lake_t_lake3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_icefrac3d', data%lake_icefrac3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_clay3d', data%lake_clay3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levsoil_clm_lake ', 'Time '/), is_optional=.true.)
+ call register_restart_field(Sfc_restart,'lake_sand3d', data%lake_sand3d, &
+ dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
+ 'levsoil_clm_lake ', 'Time '/), is_optional=.true.)
+ end subroutine clm_lake_register_fields
+
+ subroutine clm_lake_final(data)
+ ! Final routine for clm_lake_data_type, called automatically when
+ ! an object of that type goes out of scope. This is simply a
+ ! wrapper around data%deallocate_data().
+ implicit none
+ type(clm_lake_data_type) :: data
+ call clm_lake_deallocate_data(data)
+ end subroutine clm_lake_final
+
+ subroutine clm_lake_deallocate_data(data)
+ ! Deallocates all data used, and nullifies the pointers. The data
+ ! object can safely be used again after this call. This is also
+ ! the implementation of the clm_lake_data_type final routine.
+ implicit none
+ class(clm_lake_data_type) :: data
+
+ ! Deallocate and nullify any associated pointers
+
+ ! This #define reduces code length by a lot
+#define IF_ASSOC_DEALLOC_NULL(var) \
+ if(associated(data%var)) then ; \
+ deallocate(data%var) ; \
+ nullify(data%var) ; \
+ endif
+
+ IF_ASSOC_DEALLOC_NULL(T_snow)
+ IF_ASSOC_DEALLOC_NULL(T_ice)
+ IF_ASSOC_DEALLOC_NULL(lake_snl2d)
+ IF_ASSOC_DEALLOC_NULL(lake_h2osno2d)
+ IF_ASSOC_DEALLOC_NULL(lake_tsfc)
+ IF_ASSOC_DEALLOC_NULL(lake_savedtke12d)
+ IF_ASSOC_DEALLOC_NULL(lake_sndpth2d)
+ IF_ASSOC_DEALLOC_NULL(clm_lakedepth)
+ IF_ASSOC_DEALLOC_NULL(clm_lake_initialized)
+
+ IF_ASSOC_DEALLOC_NULL(lake_z3d)
+ IF_ASSOC_DEALLOC_NULL(lake_dz3d)
+ IF_ASSOC_DEALLOC_NULL(lake_soil_watsat3d)
+ IF_ASSOC_DEALLOC_NULL(lake_csol3d)
+ IF_ASSOC_DEALLOC_NULL(lake_soil_tkmg3d)
+ IF_ASSOC_DEALLOC_NULL(lake_soil_tkdry3d)
+ IF_ASSOC_DEALLOC_NULL(lake_soil_tksatu3d)
+ IF_ASSOC_DEALLOC_NULL(lake_snow_z3d)
+ IF_ASSOC_DEALLOC_NULL(lake_snow_dz3d)
+ IF_ASSOC_DEALLOC_NULL(lake_snow_zi3d)
+ IF_ASSOC_DEALLOC_NULL(lake_h2osoi_vol3d)
+ IF_ASSOC_DEALLOC_NULL(lake_h2osoi_liq3d)
+ IF_ASSOC_DEALLOC_NULL(lake_h2osoi_ice3d)
+ IF_ASSOC_DEALLOC_NULL(lake_t_soisno3d)
+ IF_ASSOC_DEALLOC_NULL(lake_t_lake3d)
+ IF_ASSOC_DEALLOC_NULL(lake_icefrac3d)
+ IF_ASSOC_DEALLOC_NULL(lake_clay3d)
+ IF_ASSOC_DEALLOC_NULL(lake_sand3d)
+
+#undef IF_ASSOC_DEALLOC_NULL
+ end subroutine clm_lake_deallocate_data
+
+end module clm_lake_io