From 478d3482fef6ae7be0a2ebd6d7fdcb407a3f4209 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Wed, 25 Nov 2020 13:32:39 -0700 Subject: [PATCH 1/9] Update .gitmodules and submodule pointers for ccpp-framework and ccpp-physics for gsl/develop branch --- .gitmodules | 8 ++++---- ccpp/framework | 2 +- ccpp/physics | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitmodules b/.gitmodules index d253f6966..4760351ce 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,9 +4,9 @@ branch = dev/emc [submodule "ccpp/framework"] path = ccpp/framework - url = https://github.com/NCAR/ccpp-framework - branch = master + url = https://github.com/NOAA-GSL/ccpp-framework + branch = gsl/develop [submodule "ccpp/physics"] path = ccpp/physics - url = https://github.com/NCAR/ccpp-physics - branch = master + url = https://github.com/NOAA-GSL/ccpp-physics + branch = gsl/develop diff --git a/ccpp/framework b/ccpp/framework index f1dc8d6f0..16271557a 160000 --- a/ccpp/framework +++ b/ccpp/framework @@ -1 +1 @@ -Subproject commit f1dc8d6f038e590508c272070f673d1fd7ea566f +Subproject commit 16271557a692b2c6871bf4e2209b8035a9addc52 diff --git a/ccpp/physics b/ccpp/physics index 4e39b50a2..d12329a9a 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit 4e39b50a248fc093c055fc6a8ae245065da7c730 +Subproject commit d12329a9ada515766ccb81771e8ba299ea3a8464 From bd71c2afd1195e9e25962ec94bdb5e41de349769 Mon Sep 17 00:00:00 2001 From: DomHeinzeller <58610420+DomHeinzeller@users.noreply.github.com> Date: Tue, 1 Dec 2020 10:06:50 -0700 Subject: [PATCH 2/9] RUC ice for gsl/develop (replaces #54 and #56) (#60) Implementation of RUC LSM ice model in CCPP * Squash-merge climbfuji:rucice_gfsv16dzmin into gsl/develop * Fix bug in gfsphysics/GFS_layer/GFS_typedefs.F90 from merge * Remove lsm_ruc_sfc_sice from suite FV3_GSD_v0_unified_ugwp_suite and update submodule pointer for ccpp-physics * Remove sfc_sice from ccpp/suites/suite_FV3_GSD_v0_unified_ugwp_suite.xml * Update submodule pointer for ccpp-physics * Revert change to .gitmodules and update submodule pointer for ccpp-physics Co-authored-by: Dom Heinzeller --- ccpp/config/ccpp_prebuild_config.py | 1 - ccpp/physics | 2 +- ccpp/suites/suite_FV3_GSD_SAR.xml | 3 - ccpp/suites/suite_FV3_GSD_v0.xml | 3 - ccpp/suites/suite_FV3_GSD_v0_drag_suite.xml | 3 - ccpp/suites/suite_FV3_GSD_v0_mynnsfc.xml | 3 - .../suite_FV3_GSD_v0_unified_ugwp_suite.xml | 3 - ccpp/suites/suite_FV3_HRRR.xml | 3 - ccpp/suites/suite_FV3_RAP.xml | 3 - gfsphysics/GFS_layer/GFS_diagnostics.F90 | 12 +- gfsphysics/GFS_layer/GFS_typedefs.F90 | 110 ++++++++++-------- gfsphysics/GFS_layer/GFS_typedefs.meta | 66 +++++++---- io/FV3GFS_io.F90 | 85 +++++++++----- 13 files changed, 168 insertions(+), 129 deletions(-) diff --git a/ccpp/config/ccpp_prebuild_config.py b/ccpp/config/ccpp_prebuild_config.py index f954a07f5..f649535ac 100755 --- a/ccpp/config/ccpp_prebuild_config.py +++ b/ccpp/config/ccpp_prebuild_config.py @@ -171,7 +171,6 @@ 'ccpp/physics/physics/sfc_diag.f', 'ccpp/physics/physics/sfc_diag_post.F90', 'ccpp/physics/physics/sfc_drv_ruc.F90', - 'ccpp/physics/physics/lsm_ruc_sfc_sice_interstitial.F90', 'ccpp/physics/physics/sfc_cice.f', 'ccpp/physics/physics/sfc_diff.f', 'ccpp/physics/physics/sfc_drv.f', diff --git a/ccpp/physics b/ccpp/physics index d12329a9a..bafcc9ebb 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit d12329a9ada515766ccb81771e8ba299ea3a8464 +Subproject commit bafcc9ebb6788696666e7592cf7577db81e5fbbe diff --git a/ccpp/suites/suite_FV3_GSD_SAR.xml b/ccpp/suites/suite_FV3_GSD_SAR.xml index 08541847a..29f6d3707 100644 --- a/ccpp/suites/suite_FV3_GSD_SAR.xml +++ b/ccpp/suites/suite_FV3_GSD_SAR.xml @@ -45,9 +45,6 @@ sfc_nst sfc_nst_post lsm_ruc - lsm_ruc_sfc_sice_pre - sfc_sice - lsm_ruc_sfc_sice_post GFS_surface_loop_control_part2 diff --git a/ccpp/suites/suite_FV3_GSD_v0.xml b/ccpp/suites/suite_FV3_GSD_v0.xml index 06c4d7dcd..7838db77b 100644 --- a/ccpp/suites/suite_FV3_GSD_v0.xml +++ b/ccpp/suites/suite_FV3_GSD_v0.xml @@ -45,9 +45,6 @@ sfc_nst sfc_nst_post lsm_ruc - lsm_ruc_sfc_sice_pre - sfc_sice - lsm_ruc_sfc_sice_post GFS_surface_loop_control_part2 diff --git a/ccpp/suites/suite_FV3_GSD_v0_drag_suite.xml b/ccpp/suites/suite_FV3_GSD_v0_drag_suite.xml index 7d55abfd2..21d45de21 100644 --- a/ccpp/suites/suite_FV3_GSD_v0_drag_suite.xml +++ b/ccpp/suites/suite_FV3_GSD_v0_drag_suite.xml @@ -45,9 +45,6 @@ sfc_nst sfc_nst_post lsm_ruc - lsm_ruc_sfc_sice_pre - sfc_sice - lsm_ruc_sfc_sice_post GFS_surface_loop_control_part2 diff --git a/ccpp/suites/suite_FV3_GSD_v0_mynnsfc.xml b/ccpp/suites/suite_FV3_GSD_v0_mynnsfc.xml index b3b629550..d19d991f2 100644 --- a/ccpp/suites/suite_FV3_GSD_v0_mynnsfc.xml +++ b/ccpp/suites/suite_FV3_GSD_v0_mynnsfc.xml @@ -45,9 +45,6 @@ sfc_nst sfc_nst_post lsm_ruc - lsm_ruc_sfc_sice_pre - sfc_sice - lsm_ruc_sfc_sice_post GFS_surface_loop_control_part2 diff --git a/ccpp/suites/suite_FV3_GSD_v0_unified_ugwp_suite.xml b/ccpp/suites/suite_FV3_GSD_v0_unified_ugwp_suite.xml index 8a717abc3..8a8d69b88 100644 --- a/ccpp/suites/suite_FV3_GSD_v0_unified_ugwp_suite.xml +++ b/ccpp/suites/suite_FV3_GSD_v0_unified_ugwp_suite.xml @@ -45,9 +45,6 @@ sfc_nst sfc_nst_post lsm_ruc - lsm_ruc_sfc_sice_pre - sfc_sice - lsm_ruc_sfc_sice_post GFS_surface_loop_control_part2 diff --git a/ccpp/suites/suite_FV3_HRRR.xml b/ccpp/suites/suite_FV3_HRRR.xml index 4487b8e27..c74fe17f8 100644 --- a/ccpp/suites/suite_FV3_HRRR.xml +++ b/ccpp/suites/suite_FV3_HRRR.xml @@ -45,9 +45,6 @@ sfc_nst sfc_nst_post lsm_ruc - lsm_ruc_sfc_sice_pre - sfc_sice - lsm_ruc_sfc_sice_post GFS_surface_loop_control_part2 diff --git a/ccpp/suites/suite_FV3_RAP.xml b/ccpp/suites/suite_FV3_RAP.xml index 9440efa69..da3fe46bf 100644 --- a/ccpp/suites/suite_FV3_RAP.xml +++ b/ccpp/suites/suite_FV3_RAP.xml @@ -45,9 +45,6 @@ sfc_nst sfc_nst_post lsm_ruc - lsm_ruc_sfc_sice_pre - sfc_sice - lsm_ruc_sfc_sice_post GFS_surface_loop_control_part2 diff --git a/gfsphysics/GFS_layer/GFS_diagnostics.F90 b/gfsphysics/GFS_layer/GFS_diagnostics.F90 index a289df88a..cf19c7cd3 100644 --- a/gfsphysics/GFS_layer/GFS_diagnostics.F90 +++ b/gfsphysics/GFS_layer/GFS_diagnostics.F90 @@ -3030,24 +3030,24 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop if (Model%lsm == Model%lsm_ruc) then idx = idx + 1 ExtDiag(idx)%axes = 2 - ExtDiag(idx)%name = 'snowfall_acc' - ExtDiag(idx)%desc = 'total accumulated frozen precipitation' + ExtDiag(idx)%name = 'snowfall_acc_land' + ExtDiag(idx)%desc = 'total accumulated frozen precipitation over land' 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)%snowfallac(:) + ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%snowfallac_land(:) enddo idx = idx + 1 ExtDiag(idx)%axes = 2 - ExtDiag(idx)%name = 'swe_snowfall_acc' - ExtDiag(idx)%desc = 'accumulated water equivalent of frozen precipitation' + ExtDiag(idx)%name = 'snowfall_acc_ice' + ExtDiag(idx)%desc = 'total accumulated frozen precipitation 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)%acsnow(:) + ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%snowfallac_ice(:) enddo endif #endif diff --git a/gfsphysics/GFS_layer/GFS_typedefs.F90 b/gfsphysics/GFS_layer/GFS_typedefs.F90 index b5b50b6af..2fef16ee4 100644 --- a/gfsphysics/GFS_layer/GFS_typedefs.F90 +++ b/gfsphysics/GFS_layer/GFS_typedefs.F90 @@ -255,7 +255,8 @@ module GFS_typedefs real (kind=kind_phys), pointer :: semisbase(:) => null() !< background surface emissivity !--- In (radiation only) - real (kind=kind_phys), pointer :: sncovr (:) => null() !< snow cover in fraction + real (kind=kind_phys), pointer :: sncovr (:) => null() !< snow cover in fraction over land + real (kind=kind_phys), pointer :: sncovr_ice (:) => null() !< snow cover in fraction over ice (RUC LSM only) real (kind=kind_phys), pointer :: snoalb (:) => null() !< maximum snow albedo in fraction real (kind=kind_phys), pointer :: alvsf (:) => null() !< mean vis albedo with strong cosz dependency real (kind=kind_phys), pointer :: alnsf (:) => null() !< mean nir albedo with strong cosz dependency @@ -365,20 +366,22 @@ module GFS_typedefs #ifdef CCPP ! Soil properties for RUC LSM (number of levels different from NOAH 4-layer model) - real (kind=kind_phys), pointer :: wetness(:) => null() !< normalized soil wetness for lsm - real (kind=kind_phys), pointer :: sh2o(:,:) => null() !< volume fraction of unfrozen soil moisture for lsm - real (kind=kind_phys), pointer :: keepsmfr(:,:) => null() !< RUC LSM: frozen moisture in soil - real (kind=kind_phys), pointer :: smois(:,:) => null() !< volumetric fraction of soil moisture for lsm - real (kind=kind_phys), pointer :: tslb(:,:) => null() !< soil temperature for land surface model - real (kind=kind_phys), pointer :: flag_frsoil(:,:) => null() !< RUC LSM: flag for frozen soil physics + real (kind=kind_phys), pointer :: wetness(:) => null() !< normalized soil wetness for lsm + real (kind=kind_phys), pointer :: sh2o(:,:) => null() !< volume fraction of unfrozen soil moisture for lsm + real (kind=kind_phys), pointer :: keepsmfr(:,:) => null() !< RUC LSM: frozen moisture in soil + real (kind=kind_phys), pointer :: smois(:,:) => null() !< volumetric fraction of soil moisture for lsm + real (kind=kind_phys), pointer :: tslb(:,:) => null() !< soil temperature for land surface model + real (kind=kind_phys), pointer :: flag_frsoil(:,:) => null() !< RUC LSM: flag for frozen soil physics ! - real (kind=kind_phys), pointer :: clw_surf(:) => null() !< RUC LSM: moist cloud water mixing ratio at surface - real (kind=kind_phys), pointer :: qwv_surf(:) => null() !< RUC LSM: water vapor mixing ratio at surface - real (kind=kind_phys), pointer :: cndm_surf(:) => null() !< RUC LSM: surface condensation mass - real (kind=kind_phys), pointer :: rhofr(:) => null() !< RUC LSM: density of frozen precipitation - real (kind=kind_phys), pointer :: tsnow(:) => null() !< RUC LSM: snow temperature at the bottom of the first soil layer - real (kind=kind_phys), pointer :: snowfallac(:) => null() !< ruc lsm diagnostics - real (kind=kind_phys), pointer :: acsnow(:) => null() !< ruc lsm diagnostics + real (kind=kind_phys), pointer :: clw_surf_land(:) => null() !< RUC LSM: moist cloud water mixing ratio at surface over land + real (kind=kind_phys), pointer :: clw_surf_ice(:) => null() !< RUC LSM: moist cloud water mixing ratio at surface over ice + real (kind=kind_phys), pointer :: qwv_surf_land(:) => null() !< RUC LSM: water vapor mixing ratio at surface over land + real (kind=kind_phys), pointer :: qwv_surf_ice(:) => null() !< RUC LSM: water vapor mixing ratio at surface over ice + real (kind=kind_phys), pointer :: rhofr(:) => null() !< RUC LSM: density of frozen precipitation + real (kind=kind_phys), pointer :: tsnow_land(:) => null() !< RUC LSM: snow temperature at the bottom of the first snow layer over land + real (kind=kind_phys), pointer :: tsnow_ice(:) => null() !< RUC LSM: snow temperature at the bottom of the first snow layer over ice + real (kind=kind_phys), pointer :: snowfallac_land(:) => null() !< ruc lsm diagnostics over land + real (kind=kind_phys), pointer :: snowfallac_ice(:) => null() !< ruc lsm diagnostics over ice ! MYNN surface layer real (kind=kind_phys), pointer :: ustm (:) => null() !u* including drag @@ -804,7 +807,6 @@ module GFS_typedefs integer :: isot !< isot = 0 => Zobler soil type ( 9 category) !< isot = 1 => STATSGO soil type (19 category, AKA 'STAS'(?)) !< isot = 2 => STAS-RUC soil type (19 category, NOAH WRFv4 only) - integer :: kice=2 !< number of layers in sice #ifdef CCPP integer :: lsoil_lsm !< number of soil layers internal to land surface model integer :: lsnow_lsm !< maximum number of snow layers internal to land surface model @@ -821,6 +823,9 @@ module GFS_typedefs integer :: iopt_thcnd !< option to treat thermal conductivity in Noah LSM (new in 3.8) !< = 1, original (default) !< = 2, McCumber and Pielke for silt loam and sandy loam + integer :: kice !< number of layers in ice model +#else + integer :: kice=2 !< number of layers in sice #endif ! -- the Noah MP options @@ -1422,7 +1427,7 @@ module GFS_typedefs !--- Out (radiation only) real (kind=kind_phys), pointer :: htrsw (:,:) => null() !< swh total sky sw heating rate in k/sec real (kind=kind_phys), pointer :: htrlw (:,:) => null() !< hlw total sky lw heating rate in k/sec - real (kind=kind_phys), pointer :: sfalb (:) => null() !< mean surface diffused sw albedo + real (kind=kind_phys), pointer :: sfalb (:) => null() !< mean surface diffused sw albedo real (kind=kind_phys), pointer :: coszen(:) => null() !< mean cos of zenith angle over rad call period real (kind=kind_phys), pointer :: tsflw (:) => null() !< surface air temp during lw calculation in k @@ -1768,13 +1773,11 @@ module GFS_typedefs real (kind=kind_phys), pointer :: cld1d(:) => null() !< real (kind=kind_phys), pointer :: clouds(:,:,:) => null() !< real (kind=kind_phys), pointer :: clw(:,:,:) => null() !< - real (kind=kind_phys), pointer :: clw_surf(:) => null() !< real (kind=kind_phys), pointer :: clx(:,:) => null() !< real (kind=kind_phys), pointer :: cmc(:) => null() !< real (kind=kind_phys), pointer :: cmm_ice(:) => null() !< real (kind=kind_phys), pointer :: cmm_land(:) => null() !< real (kind=kind_phys), pointer :: cmm_ocean(:) => null() !< - real (kind=kind_phys), pointer :: cndm_surf(:) => null() !< real (kind=kind_phys), pointer :: cnv_dqldt(:,:) => null() !< real (kind=kind_phys), pointer :: cnv_fice(:,:) => null() !< real (kind=kind_phys), pointer :: cnv_mfd(:,:) => null() !< @@ -2025,7 +2028,6 @@ module GFS_typedefs real (kind=kind_phys), pointer :: tsfc_land_save(:) => null() !< real (kind=kind_phys), pointer :: tsfc_ocean(:) => null() !< real (kind=kind_phys), pointer :: tsfg(:) => null() !< - real (kind=kind_phys), pointer :: tsnow(:) => null() !< real (kind=kind_phys), pointer :: tsurf(:) => null() !< real (kind=kind_phys), pointer :: tsurf_ice(:) => null() !< real (kind=kind_phys), pointer :: tsurf_land(:) => null() !< @@ -2349,7 +2351,6 @@ subroutine sfcprop_create (Sfcprop, IM, Model) Sfcprop%hprime = clear_val !--- In (radiation only) - allocate (Sfcprop%sncovr (IM)) allocate (Sfcprop%snoalb (IM)) allocate (Sfcprop%alvsf (IM)) allocate (Sfcprop%alnsf (IM)) @@ -2358,7 +2359,6 @@ subroutine sfcprop_create (Sfcprop, IM, Model) allocate (Sfcprop%facsf (IM)) allocate (Sfcprop%facwf (IM)) - Sfcprop%sncovr = clear_val Sfcprop%snoalb = clear_val Sfcprop%alvsf = clear_val Sfcprop%alnsf = clear_val @@ -2403,6 +2403,9 @@ subroutine sfcprop_create (Sfcprop, IM, Model) allocate (Sfcprop%hice (IM)) allocate (Sfcprop%weasd (IM)) allocate (Sfcprop%sncovr (IM)) + if (Model%lsm == Model%lsm_ruc) then + allocate (Sfcprop%sncovr_ice (IM)) + end if allocate (Sfcprop%canopy (IM)) allocate (Sfcprop%ffmm (IM)) allocate (Sfcprop%ffhh (IM)) @@ -2416,6 +2419,9 @@ subroutine sfcprop_create (Sfcprop, IM, Model) Sfcprop%hice = clear_val Sfcprop%weasd = clear_val Sfcprop%sncovr = clear_val + if (Model%lsm == Model%lsm_ruc) then + Sfcprop%sncovr_ice = clear_val + end if Sfcprop%canopy = clear_val Sfcprop%ffmm = clear_val Sfcprop%ffhh = clear_val @@ -2606,33 +2612,37 @@ subroutine sfcprop_create (Sfcprop, IM, Model) if (Model%lsm == Model%lsm_ruc) then ! For land surface models with different numbers of levels than the four NOAH levels - allocate (Sfcprop%wetness (IM)) - allocate (Sfcprop%sh2o (IM,Model%lsoil_lsm)) - allocate (Sfcprop%keepsmfr (IM,Model%lsoil_lsm)) - allocate (Sfcprop%smois (IM,Model%lsoil_lsm)) - allocate (Sfcprop%tslb (IM,Model%lsoil_lsm)) - allocate (Sfcprop%flag_frsoil (IM,Model%lsoil_lsm)) - allocate (Sfcprop%clw_surf (IM)) - allocate (Sfcprop%qwv_surf (IM)) - allocate (Sfcprop%cndm_surf (IM)) - allocate (Sfcprop%rhofr (IM)) - allocate (Sfcprop%tsnow (IM)) - allocate (Sfcprop%snowfallac (IM)) - allocate (Sfcprop%acsnow (IM)) + allocate (Sfcprop%wetness (IM)) + allocate (Sfcprop%sh2o (IM,Model%lsoil_lsm)) + allocate (Sfcprop%keepsmfr (IM,Model%lsoil_lsm)) + allocate (Sfcprop%smois (IM,Model%lsoil_lsm)) + allocate (Sfcprop%tslb (IM,Model%lsoil_lsm)) + allocate (Sfcprop%flag_frsoil (IM,Model%lsoil_lsm)) + allocate (Sfcprop%clw_surf_land (IM)) + allocate (Sfcprop%clw_surf_ice (IM)) + allocate (Sfcprop%qwv_surf_land (IM)) + allocate (Sfcprop%qwv_surf_ice (IM)) + allocate (Sfcprop%rhofr (IM)) + allocate (Sfcprop%tsnow_land (IM)) + allocate (Sfcprop%tsnow_ice (IM)) + allocate (Sfcprop%snowfallac_land (IM)) + allocate (Sfcprop%snowfallac_ice (IM)) ! - Sfcprop%wetness = clear_val - Sfcprop%sh2o = clear_val - Sfcprop%keepsmfr = clear_val - Sfcprop%smois = clear_val - Sfcprop%tslb = clear_val - Sfcprop%clw_surf = clear_val - Sfcprop%qwv_surf = clear_val - Sfcprop%cndm_surf = clear_val - Sfcprop%flag_frsoil = clear_val - Sfcprop%rhofr = clear_val - Sfcprop%tsnow = clear_val - Sfcprop%snowfallac = clear_val - Sfcprop%acsnow = clear_val + Sfcprop%wetness = clear_val + Sfcprop%sh2o = clear_val + Sfcprop%keepsmfr = clear_val + Sfcprop%smois = clear_val + Sfcprop%tslb = clear_val + Sfcprop%clw_surf_land = clear_val + Sfcprop%clw_surf_ice = clear_val + Sfcprop%qwv_surf_land = clear_val + Sfcprop%qwv_surf_ice = clear_val + Sfcprop%flag_frsoil = clear_val + Sfcprop%rhofr = clear_val + Sfcprop%tsnow_land = clear_val + Sfcprop%tsnow_ice = clear_val + Sfcprop%snowfallac_land = clear_val + Sfcprop%snowfallac_ice = clear_val ! if (Model%rdlai) then allocate (Sfcprop%xlaixy (IM)) @@ -3173,6 +3183,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & integer :: iopt_thcnd = 1 !< option to treat thermal conductivity in Noah LSM (new in 3.8) !< = 1, original (default) !< = 2, McCumber and Pielke for silt loam and sandy loam + integer :: kice = 2 !< number of layers in ice; default is 2 (GFS sice) #endif integer :: ivegsrc = 2 !< ivegsrc = 0 => USGS, !< ivegsrc = 1 => IGBP (20 category) @@ -3503,7 +3514,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & avg_max_length, & !--- land/surface model control #ifdef CCPP - lsm, lsoil, lsoil_lsm, lsnow_lsm, rdlai, & + lsm, lsoil, lsoil_lsm, lsnow_lsm, kice, rdlai, & nmtvr, ivegsrc, use_ufo, iopt_thcnd, ua_phys, usemonalb, & aoasis, fasdas, & #else @@ -3968,6 +3979,8 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & allocate (Model%zs(Model%lsoil_lsm)) Model%zs = clear_val end if + ! Set number of ice model layers + Model%kice = kice ! if (lsnow_lsm /= 3) then write(0,*) 'Logic error: NoahMP expects the maximum number of snow layers to be exactly 3 (see sfc_noahmp_drv.f)' @@ -5145,6 +5158,7 @@ subroutine control_print(Model) print *, ' usemonalb : ', Model%usemonalb print *, ' aoasis : ', Model%aoasis print *, ' fasdas : ', Model%fasdas + print *, ' kice : ', Model%kice #endif print *, ' ivegsrc : ', Model%ivegsrc print *, ' isot : ', Model%isot diff --git a/gfsphysics/GFS_layer/GFS_typedefs.meta b/gfsphysics/GFS_layer/GFS_typedefs.meta index 84e447237..4dfb5046e 100644 --- a/gfsphysics/GFS_layer/GFS_typedefs.meta +++ b/gfsphysics/GFS_layer/GFS_typedefs.meta @@ -606,6 +606,14 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys +[sncovr_ice] + standard_name = surface_snow_area_fraction_over_ice + long_name = surface snow area fraction over ice + units = frac + dimensions = (horizontal_dimension) + type = real + kind = kind_phys + active = (flag_for_land_surface_scheme == flag_for_ruc_land_surface_scheme) [snoalb] standard_name = upper_bound_on_max_albedo_over_deep_snow long_name = maximum snow albedo @@ -1266,27 +1274,35 @@ dimensions = (horizontal_loop_extent,soil_vertical_dimension_for_land_surface_model) type = real kind = kind_phys - active = (flag_for_land_surface_scheme == flag_for_ruc_land_surface_scheme) -[clw_surf] - standard_name = cloud_condensed_water_mixing_ratio_at_surface - long_name = moist cloud water mixing ratio at surface + active = (flag_for_land_surface_scheme == flag_for_ruc_land_surface_scheme) +[clw_surf_land] + standard_name = cloud_condensed_water_mixing_ratio_at_surface_over_land + long_name = moist cloud water mixing ratio at surface over land units = kg kg-1 dimensions = (horizontal_loop_extent) type = real kind = kind_phys - active = (flag_for_land_surface_scheme == flag_for_ruc_land_surface_scheme) -[qwv_surf] - standard_name = water_vapor_mixing_ratio_at_surface - long_name = water vapor mixing ratio at surface + active = (flag_for_land_surface_scheme == flag_for_ruc_land_surface_scheme) +[clw_surf_ice] + standard_name = cloud_condensed_water_mixing_ratio_at_surface_over_ice + long_name = moist cloud water mixing ratio at surface over ice units = kg kg-1 dimensions = (horizontal_loop_extent) type = real kind = kind_phys active = (flag_for_land_surface_scheme == flag_for_ruc_land_surface_scheme) -[cndm_surf] - standard_name = surface_condensation_mass - long_name = surface condensation mass - units = kg m-2 +[qwv_surf_land] + standard_name = water_vapor_mixing_ratio_at_surface_over_land + long_name = water vapor mixing ratio at surface over land + units = kg kg-1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (flag_for_land_surface_scheme == flag_for_ruc_land_surface_scheme) +[qwv_surf_ice] + standard_name = water_vapor_mixing_ratio_at_surface_over_ice + long_name = water vapor mixing ratio at surface over ice + units = kg kg-1 dimensions = (horizontal_loop_extent) type = real kind = kind_phys @@ -1307,25 +1323,33 @@ type = real kind = kind_phys active = (flag_for_land_surface_scheme == flag_for_ruc_land_surface_scheme) -[tsnow] - standard_name = snow_temperature_bottom_first_layer - long_name = snow temperature at the bottom of the first snow layer +[tsnow_land] + standard_name = snow_temperature_bottom_first_layer_over_land + long_name = snow temperature at the bottom of the first snow layer over land + units = K + dimensions = (horizontal_dimension) + type = real + kind = kind_phys + active = (flag_for_land_surface_scheme == flag_for_ruc_land_surface_scheme) +[tsnow_ice] + standard_name = snow_temperature_bottom_first_layer_over_ice + long_name = snow temperature at the bottom of the first snow layer over ice units = K dimensions = (horizontal_loop_extent) type = real kind = kind_phys active = (flag_for_land_surface_scheme == flag_for_ruc_land_surface_scheme) -[snowfallac] - standard_name = total_accumulated_snowfall +[snowfallac_land] + standard_name = total_accumulated_snowfall_over_land long_name = run-total snow accumulation on the ground units = kg m-2 dimensions = (horizontal_loop_extent) type = real kind = kind_phys - active = (flag_for_land_surface_scheme == flag_for_ruc_land_surface_scheme) -[acsnow] - standard_name = accumulated_water_equivalent_of_frozen_precip - long_name = snow water equivalent of run-total frozen precip + active = (flag_for_land_surface_scheme == flag_for_ruc_land_surface_scheme) +[snowfallac_ice] + standard_name = total_accumulated_snowfall_over_ice + long_name = run-total snow accumulation on the ice units = kg m-2 dimensions = (horizontal_loop_extent) type = real diff --git a/io/FV3GFS_io.F90 b/io/FV3GFS_io.F90 index 08f792b05..a710941e2 100644 --- a/io/FV3GFS_io.F90 +++ b/io/FV3GFS_io.F90 @@ -530,9 +530,9 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain) #ifdef CCPP if (Model%lsm == Model%lsm_ruc .and. warm_start) then if(Model%rdlai) then - nvar_s2r = 7 + nvar_s2r = 11 else - nvar_s2r = 6 + nvar_s2r = 10 end if nvar_s3 = 5 else @@ -872,13 +872,17 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain) #ifdef CCPP else if (Model%lsm == Model%lsm_ruc .and. warm_start) then sfc_name2(nvar_s2m+19) = 'wetness' - sfc_name2(nvar_s2m+20) = 'clw_surf' - sfc_name2(nvar_s2m+21) = 'qwv_surf' - sfc_name2(nvar_s2m+22) = 'tsnow' - sfc_name2(nvar_s2m+23) = 'snowfall_acc' - sfc_name2(nvar_s2m+24) = 'swe_snowfall_acc' + sfc_name2(nvar_s2m+20) = 'clw_surf_land' + sfc_name2(nvar_s2m+21) = 'clw_surf_ice' + sfc_name2(nvar_s2m+22) = 'qwv_surf_land' + sfc_name2(nvar_s2m+23) = 'qwv_surf_ice' + sfc_name2(nvar_s2m+24) = 'tsnow_land' + sfc_name2(nvar_s2m+25) = 'tsnow_ice' + sfc_name2(nvar_s2m+26) = 'snowfall_acc_land' + sfc_name2(nvar_s2m+27) = 'snowfall_acc_ice' + sfc_name2(nvar_s2m+28) = 'sncovr_ice' if (Model%rdlai) then - sfc_name2(nvar_s2m+25) = 'lai' + sfc_name2(nvar_s2m+29) = 'lai' endif else if (Model%lsm == Model%lsm_ruc .and. Model%rdlai) then sfc_name2(nvar_s2m+19) = 'lai' @@ -1142,17 +1146,21 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain) #ifdef CCPP if (Model%lsm == Model%lsm_ruc .and. warm_start) then !--- Extra RUC variables - Sfcprop(nb)%wetness(ix) = sfc_var2(i,j,nvar_s2m+19) - Sfcprop(nb)%clw_surf(ix) = sfc_var2(i,j,nvar_s2m+20) - Sfcprop(nb)%qwv_surf(ix) = sfc_var2(i,j,nvar_s2m+21) - Sfcprop(nb)%tsnow(ix) = sfc_var2(i,j,nvar_s2m+22) - Sfcprop(nb)%snowfallac(ix) = sfc_var2(i,j,nvar_s2m+23) - Sfcprop(nb)%acsnow(ix) = sfc_var2(i,j,nvar_s2m+24) + Sfcprop(nb)%wetness(ix) = sfc_var2(i,j,nvar_s2m+19) + Sfcprop(nb)%clw_surf_land(ix) = sfc_var2(i,j,nvar_s2m+20) + Sfcprop(nb)%clw_surf_ice(ix) = sfc_var2(i,j,nvar_s2m+21) + Sfcprop(nb)%qwv_surf_land(ix) = sfc_var2(i,j,nvar_s2m+22) + Sfcprop(nb)%qwv_surf_ice(ix) = sfc_var2(i,j,nvar_s2m+23) + Sfcprop(nb)%tsnow_land(ix) = sfc_var2(i,j,nvar_s2m+24) + Sfcprop(nb)%tsnow_ice(ix) = sfc_var2(i,j,nvar_s2m+25) + Sfcprop(nb)%snowfallac_land(ix) = sfc_var2(i,j,nvar_s2m+26) + Sfcprop(nb)%snowfallac_ice(ix) = sfc_var2(i,j,nvar_s2m+27) + Sfcprop(nb)%sncovr_ice(ix) = sfc_var2(i,j,nvar_s2m+28) if (Model%rdlai) then - Sfcprop(nb)%xlaixy(ix) = sfc_var2(i,j,nvar_s2m+25) + Sfcprop(nb)%xlaixy(ix) = sfc_var2(i,j,nvar_s2m+29) endif else if (Model%lsm == Model%lsm_ruc .and. Model%rdlai) then - Sfcprop(nb)%xlaixy(ix) = sfc_var2(i,j,nvar_s2m+19) + Sfcprop(nb)%xlaixy(ix) = sfc_var2(i,j,nvar_s2m+19) elseif (Model%lsm == Model%lsm_noahmp) then !--- Extra Noah MP variables #else @@ -1282,7 +1290,7 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain) !--- if sncovr does not exist in the restart, need to create it if (sfc_var2(i,j,32) < -9990.0_r8) then - if (Model%me == Model%master ) call mpp_error(NOTE, 'gfs_driver::surface_props_input - computing sncovr') + if (Model%me == Model%master ) call mpp_error(NOTE, 'gfs_driver::surface_props_input - computing sncovr') !--- compute sncovr from existing variables !--- code taken directly from read_fix.f !$omp parallel do default(shared) private(nb, ix, vegtyp, rsnow) @@ -1301,6 +1309,13 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain) endif enddo enddo + !--- For RUC LSM: create sncovr_ice from sncovr + if (Model%lsm == Model%lsm_ruc) then + if (Model%me == Model%master ) call mpp_error(NOTE, 'gfs_driver::surface_props_input - fill sncovr_ice with sncovr') + do nb = 1, Atm_block%nblks + Sfcprop(nb)%sncovr_ice(:) = Sfcprop(nb)%sncovr(:) + end do + endif endif ! if (Model%frac_grid) then @@ -1730,9 +1745,9 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta #ifdef CCPP if (Model%lsm == Model%lsm_ruc) then if (Model%rdlai) then - nvar2r = 7 + nvar2r = 11 else - nvar2r = 6 + nvar2r = 10 endif nvar3 = 5 else @@ -1869,13 +1884,17 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta #ifdef CCPP if (Model%lsm == Model%lsm_ruc) then sfc_name2(nvar2m+19) = 'wetness' - sfc_name2(nvar2m+20) = 'clw_surf' - sfc_name2(nvar2m+21) = 'qwv_surf' - sfc_name2(nvar2m+22) = 'tsnow' - sfc_name2(nvar2m+23) = 'snowfall_acc' - sfc_name2(nvar2m+24) = 'swe_snowfall_acc' + sfc_name2(nvar2m+20) = 'clw_surf_land' + sfc_name2(nvar2m+21) = 'clw_surf_ice' + sfc_name2(nvar2m+22) = 'qwv_surf_land' + sfc_name2(nvar2m+23) = 'qwv_surf_ice' + sfc_name2(nvar2m+24) = 'tsnow_land' + sfc_name2(nvar2m+25) = 'tsnow_ice' + sfc_name2(nvar2m+26) = 'snowfall_acc_land' + sfc_name2(nvar2m+27) = 'snowfall_acc_ice' + sfc_name2(nvar2m+28) = 'sncovr_ice' if (Model%rdlai) then - sfc_name2(nvar2m+25) = 'lai' + sfc_name2(nvar2m+29) = 'lai' endif else if(Model%lsm == Model%lsm_noahmp) then #else @@ -2094,13 +2113,17 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta if (Model%lsm == Model%lsm_ruc) then !--- Extra RUC variables sfc_var2(i,j,nvar2m+19) = Sfcprop(nb)%wetness(ix) - sfc_var2(i,j,nvar2m+20) = Sfcprop(nb)%clw_surf(ix) - sfc_var2(i,j,nvar2m+21) = Sfcprop(nb)%qwv_surf(ix) - sfc_var2(i,j,nvar2m+22) = Sfcprop(nb)%tsnow(ix) - sfc_var2(i,j,nvar2m+23) = Sfcprop(nb)%snowfallac(ix) - sfc_var2(i,j,nvar2m+24) = Sfcprop(nb)%acsnow(ix) + sfc_var2(i,j,nvar2m+20) = Sfcprop(nb)%clw_surf_land(ix) + sfc_var2(i,j,nvar2m+21) = Sfcprop(nb)%clw_surf_ice(ix) + sfc_var2(i,j,nvar2m+22) = Sfcprop(nb)%qwv_surf_land(ix) + sfc_var2(i,j,nvar2m+23) = Sfcprop(nb)%qwv_surf_ice(ix) + sfc_var2(i,j,nvar2m+24) = Sfcprop(nb)%tsnow_land(ix) + sfc_var2(i,j,nvar2m+25) = Sfcprop(nb)%tsnow_ice(ix) + sfc_var2(i,j,nvar2m+26) = Sfcprop(nb)%snowfallac_land(ix) + sfc_var2(i,j,nvar2m+27) = Sfcprop(nb)%snowfallac_ice(ix) + sfc_var2(i,j,nvar2m+28) = Sfcprop(nb)%sncovr_ice(ix) if (Model%rdlai) then - sfc_var2(i,j,nvar2m+25) = Sfcprop(nb)%xlaixy(ix) + sfc_var2(i,j,nvar2m+29) = Sfcprop(nb)%xlaixy(ix) endif else if (Model%lsm == Model%lsm_noahmp) then From c59787a89dd81f3a642a4ec8c6a32dab20e6ab56 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Tue, 8 Dec 2020 15:54:33 -0700 Subject: [PATCH 3/9] Update gsl/develop from develop 2020/12/08 (#61) * Fix for updating stochastic physics on separate time-step. (#199) This bug fix allows the random patterns in the stochastic physics persist the for a period of time (defined as SKEBINT,SPPTINT, etc.) before calculating new patterns. The fix is to move the allocation of the saved variables into the init section of stochastic_physics_wrapper, and remove the deallocates in the run section. * Bug fixes in (1) running with frac_grid=T and GFDL MP and (2) restarting with frac_grid=T (#204) * -- Pointing to Moorthi's modifications in ccpp/physics, which fixed the crash when running GFDL MP with frac_grid=T; -- Not setting fice to zero in order to leave lake ice untouched; -- Restart in the coupled model with the default physics is reproducible, if bad water temperature is only filtered at initial time; Co-authored-with: Shrinivas Moorthi Co-authored-with: Denise Worthen * Revert change to .gitmodules and update submodule pointer for ccpp-physics Co-authored-by: Phil Pegion <38869668+pjpegion@users.noreply.github.com> Co-authored-by: shansun6 <48043606+shansun6@users.noreply.github.com> --- atmos_model.F90 | 8 +- ccpp/physics | 2 +- io/FV3GFS_io.F90 | 45 ++++--- .../stochastic_physics_wrapper.F90 | 111 ++++++++++-------- 4 files changed, 97 insertions(+), 69 deletions(-) diff --git a/atmos_model.F90 b/atmos_model.F90 index 860079949..051f5918d 100644 --- a/atmos_model.F90 +++ b/atmos_model.F90 @@ -100,7 +100,7 @@ module atmos_model_mod use IPD_driver, only: IPD_initialize, IPD_initialize_rst use CCPP_driver, only: CCPP_step, non_uniform_blocks -use stochastic_physics_wrapper_mod, only: stochastic_physics_wrapper +use stochastic_physics_wrapper_mod, only: stochastic_physics_wrapper,stochastic_physics_wrapper_end #else use IPD_driver, only: IPD_initialize, IPD_initialize_rst, IPD_step use physics_abstraction_layer, only: time_vary_step, radiation_step1, physics_step1, physics_step2 @@ -962,6 +962,9 @@ subroutine atmos_model_end (Atmos) !---- termination routine for atmospheric model ---- call atmosphere_end (Atmos % Time, Atmos%grid, restart_endfcst) + + call stochastic_physics_wrapper_end(IPD_Control) + if(restart_endfcst) then call FV3GFS_restart_write (IPD_Data, IPD_Restart, Atm_block, & IPD_Control, Atmos%domain) @@ -1761,7 +1764,6 @@ subroutine assign_importdata(rc) nb = Atm_block%blkno(i,j) ix = Atm_block%ixp(i,j) - IPD_Data(nb)%Sfcprop%fice(ix) = zero IPD_Data(nb)%Coupling%slimskin_cpl(ix) = IPD_Data(nb)%Sfcprop%slmsk(ix) ofrac = IPD_Data(nb)%Sfcprop%oceanfrac(ix) if (ofrac > zero) then @@ -1776,7 +1778,7 @@ subroutine assign_importdata(rc) if (abs(one-ofrac) < epsln) then IPD_Data(nb)%Sfcprop%slmsk(ix) = zero IPD_Data(nb)%Coupling%slimskin_cpl(ix) = zero - end if + endif endif endif enddo diff --git a/ccpp/physics b/ccpp/physics index bafcc9ebb..91b772665 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit bafcc9ebb6788696666e7592cf7577db81e5fbbe +Subproject commit 91b77266541d8a80dd23d09f80ee1e72e34af2d9 diff --git a/io/FV3GFS_io.F90 b/io/FV3GFS_io.F90 index a710941e2..46fdd8779 100644 --- a/io/FV3GFS_io.F90 +++ b/io/FV3GFS_io.F90 @@ -1070,14 +1070,7 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain) endif if(Model%frac_grid) then ! obtain slmsk from landfrac -!! next 5 lines are temporary till lake model is available - if (Sfcprop(nb)%lakefrac(ix) > zero) then -! Sfcprop(nb)%lakefrac(ix) = nint(Sfcprop(nb)%lakefrac(ix)) - Sfcprop(nb)%landfrac(ix) = one - Sfcprop(nb)%lakefrac(ix) - if (Sfcprop(nb)%lakefrac(ix) == zero) Sfcprop(nb)%fice(ix) = zero - endif - Sfcprop(nb)%slmsk(ix) = ceiling(Sfcprop(nb)%landfrac(ix)) - if (Sfcprop(nb)%fice(ix) > Model%min_lakeice .and. Sfcprop(nb)%landfrac(ix) == zero) Sfcprop(nb)%slmsk(ix) = 2 ! land dominates ice if co-exist + Sfcprop(nb)%slmsk(ix) = ceiling(Sfcprop(nb)%landfrac(ix)) !nint/floor are options else ! obtain landfrac from slmsk if (Sfcprop(nb)%slmsk(ix) > 1.9_r8) then Sfcprop(nb)%landfrac(ix) = zero @@ -1088,16 +1081,32 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain) if (Sfcprop(nb)%lakefrac(ix) > zero) then Sfcprop(nb)%oceanfrac(ix) = zero ! lake & ocean don't coexist in a cell -! if (Sfcprop(nb)%fice(ix) < Model%min_lakeice) then -! Sfcprop(nb)%fice(ix) = zero -! if (Sfcprop(nb)%slmsk(ix) == 2) Sfcprop(nb)%slmsk(ix) = 0 -! endif + if (Sfcprop(nb)%slmsk(ix) /= one) then + if (Sfcprop(nb)%fice(ix) >= Model%min_lakeice) then + if (Sfcprop(nb)%slmsk(ix) < 1.9_r8) & + write(*,'(a,2i3,3f6.2)') 'reset lake slmsk=2 at nb,ix=' & + ,nb,ix,Sfcprop(nb)%fice(ix),Sfcprop(nb)%slmsk(ix),Sfcprop(nb)%lakefrac(ix) + Sfcprop(nb)%slmsk(ix) = 2. + else if (Sfcprop(nb)%slmsk(ix) > 1.e-7) then + write(*,'(a,2i3,3f6.2)') 'reset lake slmsk=0 at nb,ix=' & + ,nb,ix,Sfcprop(nb)%fice(ix),Sfcprop(nb)%slmsk(ix),Sfcprop(nb)%lakefrac(ix) + Sfcprop(nb)%slmsk(ix) = zero + end if + end if else Sfcprop(nb)%oceanfrac(ix) = one - Sfcprop(nb)%landfrac(ix) -! if (Sfcprop(nb)%fice(ix) < Model%min_seaice) then -! Sfcprop(nb)%fice(ix) = zero -! if (Sfcprop(nb)%slmsk(ix) == 2) Sfcprop(nb)%slmsk(ix) = 0 -! endif + if (Sfcprop(nb)%slmsk(ix) /= one) then + if (Sfcprop(nb)%fice(ix) >= Model%min_seaice) then + if (Sfcprop(nb)%slmsk(ix) < 1.9_r8) & + write(*,'(a,2i3,3f6.2)') 'reset sea slmsk=2 at nb,ix=' & + ,nb,ix,Sfcprop(nb)%fice(ix),Sfcprop(nb)%slmsk(ix),Sfcprop(nb)%landfrac(ix) + Sfcprop(nb)%slmsk(ix) = 2. + else if (Sfcprop(nb)%slmsk(ix) > 1.e-7) then + write(*,'(a,2i3,4f6.2)') 'reset sea slmsk=0 at nb,ix=' & + ,nb,ix,Sfcprop(nb)%fice(ix),Sfcprop(nb)%slmsk(ix),Sfcprop(nb)%landfrac(ix) + Sfcprop(nb)%slmsk(ix) = zero + end if + end if endif ! !--- NSSTM variables @@ -1351,7 +1360,7 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain) endif if (sfc_var2(i,j,nvar_s2m) < -9990.0_r8) then - if (Model%me == Model%master ) call mpp_error(NOTE, 'gfs_driver::surface_props_input - computing zorli') + if (Model%me == Model%master ) call mpp_error(NOTE, 'gfs_driver::surface_props_input - computing zorlw') !$omp parallel do default(shared) private(nb, ix) do nb = 1, Atm_block%nblks do ix = 1, Atm_block%blksz(nb) @@ -1366,7 +1375,7 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain) !$omp parallel do default(shared) private(nb, ix, tem, tem1) do nb = 1, Atm_block%nblks do ix = 1, Atm_block%blksz(nb) - Sfcprop(nb)%tsfco(ix) = max(con_tice, Sfcprop(nb)%tsfco(ix)) + if( Model%phour < 1.e-7) Sfcprop(nb)%tsfco(ix) = max(con_tice, Sfcprop(nb)%tsfco(ix)) ! this may break restart reproducibility tem1 = one - Sfcprop(nb)%landfrac(ix) tem = tem1 * Sfcprop(nb)%fice(ix) ! tem = ice fraction wrt whole cell Sfcprop(nb)%zorl(ix) = Sfcprop(nb)%zorll(ix) * Sfcprop(nb)%landfrac(ix) & diff --git a/stochastic_physics/stochastic_physics_wrapper.F90 b/stochastic_physics/stochastic_physics_wrapper.F90 index b5a1be065..5a3701aa8 100644 --- a/stochastic_physics/stochastic_physics_wrapper.F90 +++ b/stochastic_physics/stochastic_physics_wrapper.F90 @@ -92,16 +92,36 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) return endif end if + allocate(xlat(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(xlon(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + if (GFS_Control%do_sppt) then + allocate(sppt_wts(1:Atm_block%nblks,maxval(GFS_Control%blksz),1:GFS_Control%levs)) + end if + if (GFS_Control%do_shum) then + allocate(shum_wts(1:Atm_block%nblks,maxval(GFS_Control%blksz),1:GFS_Control%levs)) + end if + if (GFS_Control%do_skeb) then + allocate(skebu_wts(1:Atm_block%nblks,maxval(GFS_Control%blksz),1:GFS_Control%levs)) + allocate(skebv_wts(1:Atm_block%nblks,maxval(GFS_Control%blksz),1:GFS_Control%levs)) + end if + if ( GFS_Control%lndp_type .EQ. 2 ) then ! this scheme updates through forecast + allocate(sfc_wts(1:Atm_block%nblks,maxval(GFS_Control%blksz),1:GFS_Control%n_var_lndp)) + end if + if (GFS_Control%lndp_type .EQ. 2) then ! save wts, and apply lndp scheme + allocate(smc(1:Atm_block%nblks,maxval(GFS_Control%blksz),GFS_Control%lsoil)) + allocate(slc(1:Atm_block%nblks,maxval(GFS_Control%blksz),GFS_Control%lsoil)) + allocate(stc(1:Atm_block%nblks,maxval(GFS_Control%blksz),GFS_Control%lsoil)) + allocate(stype(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(vfrac(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + endif + + do nb=1,Atm_block%nblks + xlat(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Grid%xlat(:) + xlon(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Grid%xlon(:) + end do if ( GFS_Control%lndp_type .EQ. 1 ) then ! this scheme sets perts once - ! Copy blocked data into contiguous arrays; no need to copy sfc_wts in (intent out) - allocate(xlat(1:Atm_block%nblks,maxval(GFS_Control%blksz))) - allocate(xlon(1:Atm_block%nblks,maxval(GFS_Control%blksz))) allocate(sfc_wts(1:Atm_block%nblks,maxval(GFS_Control%blksz),GFS_Control%n_var_lndp)) - do nb=1,Atm_block%nblks - xlat(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Grid%xlat(:) - xlon(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Grid%xlon(:) - end do call run_stochastic_physics(GFS_Control%levs, GFS_Control%kdt, GFS_Control%phour, GFS_Control%blksz, xlat=xlat, xlon=xlon, & sppt_wts=sppt_wts, shum_wts=shum_wts, skebu_wts=skebu_wts, skebv_wts=skebv_wts, sfc_wts=sfc_wts, & nthreads=nthreads) @@ -109,8 +129,6 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) do nb=1,Atm_block%nblks GFS_Data(nb)%Coupling%sfc_wts(:,:) = sfc_wts(nb,1:GFS_Control%blksz(nb),:) end do - deallocate(xlat) - deallocate(xlon) deallocate(sfc_wts) end if ! Consistency check for cellular automata @@ -126,27 +144,6 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) else initalize_stochastic_physics if (GFS_Control%do_sppt .OR. GFS_Control%do_shum .OR. GFS_Control%do_skeb .OR. (GFS_Control%lndp_type .EQ. 2) ) then - ! Copy blocked data into contiguous arrays; no need to copy weights in (intent(out)) - allocate(xlat(1:Atm_block%nblks,maxval(GFS_Control%blksz))) - allocate(xlon(1:Atm_block%nblks,maxval(GFS_Control%blksz))) - do nb=1,Atm_block%nblks - xlat(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Grid%xlat(:) - xlon(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Grid%xlon(:) - end do - if (GFS_Control%do_sppt) then - allocate(sppt_wts(1:Atm_block%nblks,maxval(GFS_Control%blksz),1:GFS_Control%levs)) - end if - if (GFS_Control%do_shum) then - allocate(shum_wts(1:Atm_block%nblks,maxval(GFS_Control%blksz),1:GFS_Control%levs)) - end if - if (GFS_Control%do_skeb) then - allocate(skebu_wts(1:Atm_block%nblks,maxval(GFS_Control%blksz),1:GFS_Control%levs)) - allocate(skebv_wts(1:Atm_block%nblks,maxval(GFS_Control%blksz),1:GFS_Control%levs)) - end if - if ( GFS_Control%lndp_type .EQ. 2 ) then ! this scheme updates through forecast - allocate(sfc_wts(1:Atm_block%nblks,maxval(GFS_Control%blksz),1:GFS_Control%n_var_lndp)) - end if - call run_stochastic_physics(GFS_Control%levs, GFS_Control%kdt, GFS_Control%phour, GFS_Control%blksz, xlat=xlat, xlon=xlon, & sppt_wts=sppt_wts, shum_wts=shum_wts, skebu_wts=skebu_wts, skebv_wts=skebv_wts, sfc_wts=sfc_wts, & nthreads=nthreads) @@ -155,32 +152,23 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) do nb=1,Atm_block%nblks GFS_Data(nb)%Coupling%sppt_wts(:,:) = sppt_wts(nb,1:GFS_Control%blksz(nb),:) end do - deallocate(sppt_wts) end if if (GFS_Control%do_shum) then do nb=1,Atm_block%nblks GFS_Data(nb)%Coupling%shum_wts(:,:) = shum_wts(nb,1:GFS_Control%blksz(nb),:) end do - deallocate(shum_wts) end if if (GFS_Control%do_skeb) then do nb=1,Atm_block%nblks GFS_Data(nb)%Coupling%skebu_wts(:,:) = skebu_wts(nb,1:GFS_Control%blksz(nb),:) GFS_Data(nb)%Coupling%skebv_wts(:,:) = skebv_wts(nb,1:GFS_Control%blksz(nb),:) end do - deallocate(skebu_wts) - deallocate(skebv_wts) end if if (GFS_Control%lndp_type .EQ. 2) then ! save wts, and apply lndp scheme do nb=1,Atm_block%nblks GFS_Data(nb)%Coupling%sfc_wts(:,:) = sfc_wts(nb,1:GFS_Control%blksz(nb),:) end do - allocate(smc(1:Atm_block%nblks,maxval(GFS_Control%blksz),GFS_Control%lsoil)) - allocate(slc(1:Atm_block%nblks,maxval(GFS_Control%blksz),GFS_Control%lsoil)) - allocate(stc(1:Atm_block%nblks,maxval(GFS_Control%blksz),GFS_Control%lsoil)) - allocate(stype(1:Atm_block%nblks,maxval(GFS_Control%blksz))) - allocate(vfrac(1:Atm_block%nblks,maxval(GFS_Control%blksz))) do nb=1,Atm_block%nblks stype(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%stype(:) smc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%smc(:,:) @@ -202,21 +190,13 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) write(6,*) 'call to GFS_apply_lndp failed' return endif - deallocate(stype) - deallocate(sfc_wts) do nb=1,Atm_block%nblks GFS_Data(nb)%Sfcprop%smc(:,:) = smc(nb,1:GFS_Control%blksz(nb),:) GFS_Data(nb)%Sfcprop%slc(:,:) = slc(nb,1:GFS_Control%blksz(nb),:) GFS_Data(nb)%Sfcprop%stc(:,:) = stc(nb,1:GFS_Control%blksz(nb),:) GFS_Data(nb)%Sfcprop%vfrac(:) = vfrac(nb,1:GFS_Control%blksz(nb)) enddo - deallocate(smc) - deallocate(slc) - deallocate(stc) - deallocate(vfrac) endif ! lndp block - deallocate(xlat) - deallocate(xlon) end if endif initalize_stochastic_physics @@ -309,4 +289,41 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) end subroutine stochastic_physics_wrapper + + subroutine stochastic_physics_wrapper_end (GFS_Control) + + use GFS_typedefs, only: GFS_control_type, GFS_data_type + use stochastic_physics, only: finalize_stochastic_physics + + implicit none + + type(GFS_control_type), intent(inout) :: GFS_Control + + if (GFS_Control%do_sppt .OR. GFS_Control%do_shum .OR. GFS_Control%do_skeb .OR. (GFS_Control%lndp_type .GT. 0) ) then + if (allocated(xlat)) deallocate(xlat) + if (allocated(xlon)) deallocate(xlon) + if (GFS_Control%do_sppt) then + if (allocated(sppt_wts)) deallocate(sppt_wts) + end if + if (GFS_Control%do_shum) then + if (allocated(shum_wts)) deallocate(shum_wts) + end if + if (GFS_Control%do_skeb) then + if (allocated(skebu_wts)) deallocate(skebu_wts) + if (allocated(skebv_wts)) deallocate(skebv_wts) + end if + if ( GFS_Control%lndp_type .EQ. 2 ) then ! this scheme updates through forecast + if (allocated(sfc_wts)) deallocate(sfc_wts) + end if + if (GFS_Control%lndp_type .EQ. 2) then ! save wts, and apply lndp scheme + if (allocated(smc)) deallocate(smc) + if (allocated(slc)) deallocate(slc) + if (allocated(stc)) deallocate(stc) + if (allocated(stype)) deallocate(stype) + if (allocated(vfrac)) deallocate(vfrac) + endif + call finalize_stochastic_physics() + endif + end subroutine stochastic_physics_wrapper_end + end module stochastic_physics_wrapper_mod From b1e98cf2b91a593203637115b85882c0ba198aa4 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Wed, 16 Dec 2020 13:37:51 -0700 Subject: [PATCH 4/9] Update submodule pointer for ccpp-physics - MYNN surface layer updates and bugfixes (#63) --- ccpp/physics | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ccpp/physics b/ccpp/physics index 91b772665..0ac8068d5 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit 91b77266541d8a80dd23d09f80ee1e72e34af2d9 +Subproject commit 0ac8068d53a19d342fc176dd62d4267f1b43008e From 6ecee94d0cdc82def576d56633a8a1ec93da39bd Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Fri, 8 Jan 2021 19:51:30 -0700 Subject: [PATCH 5/9] Land stochastic perturbations (wrapper PR for #65) (#68) * Move initialization of stochastic physics after the physics initialization in CCPP. * Add albedo variables to land perturbations with lndp_type=2 option. Change to accommodate soil perturbations with RUC LSM. * Max/min soil moisture variables are introduced via GFS_Control_type variables instead of through the use of namelist_soilveg*. This is a more flexible way for different LSMs. * Added pores and resid variables for max/min soil moisture to GFS_typedefs.f90. * Remove tracer_sanitizer from all suites and from CCPP prebuild config * Add namelist option to apply land surface perturbations at every time step, clean up stochastic_physics/stochastic_physics_wrapper.F90 Co-authored-by: tanyasmirnova --- atmos_model.F90 | 9 +- ccpp/config/ccpp_prebuild_config.py | 1 - ccpp/physics | 2 +- ccpp/suites/suite_FV3_GSD_noah.xml | 1 - ccpp/suites/suite_FV3_GSD_v0.xml | 1 - gfsphysics/GFS_layer/GFS_typedefs.F90 | 26 +++- gfsphysics/GFS_layer/GFS_typedefs.meta | 14 +++ .../stochastic_physics_wrapper.F90 | 115 +++++++++++++++--- 8 files changed, 139 insertions(+), 30 deletions(-) diff --git a/atmos_model.F90 b/atmos_model.F90 index 051f5918d..c010789cd 100644 --- a/atmos_model.F90 +++ b/atmos_model.F90 @@ -627,9 +627,9 @@ subroutine atmos_model_init (Atmos, Time_init, Time, Time_step) IPD_Interstitial, commglobal, mpp_npes(), Init_parm) !--- Initialize stochastic physics pattern generation / cellular automata for first time step - call stochastic_physics_wrapper(IPD_Control, IPD_Data, Atm_block, ierr) - if (ierr/=0) call mpp_error(FATAL, 'Call to stochastic_physics_wrapper failed') - +! call stochastic_physics_wrapper(IPD_Control, IPD_Data, Atm_block, ierr) +! if (ierr/=0) call mpp_error(FATAL, 'Call to stochastic_physics_wrapper failed') +! #else call IPD_initialize (IPD_Control, IPD_Data, IPD_Diag, IPD_Restart, Init_parm) #endif @@ -684,6 +684,9 @@ subroutine atmos_model_init (Atmos, Time_init, Time, Time_step) ! Initialize the CCPP physics call CCPP_step (step="physics_init", nblks=Atm_block%nblks, ierr=ierr) if (ierr/=0) call mpp_error(FATAL, 'Call to CCPP physics_init step failed') +!--- Initialize stochastic physics pattern generation / cellular automata for first time step + call stochastic_physics_wrapper(IPD_Control, IPD_Data, Atm_block, ierr) + if (ierr/=0) call mpp_error(FATAL, 'Call to stochastic_physics_wrapper failed') #endif !--- set the initial diagnostic timestamp diff --git a/ccpp/config/ccpp_prebuild_config.py b/ccpp/config/ccpp_prebuild_config.py index f649535ac..cfa0b5eb6 100755 --- a/ccpp/config/ccpp_prebuild_config.py +++ b/ccpp/config/ccpp_prebuild_config.py @@ -159,7 +159,6 @@ 'ccpp/physics/physics/ozphys_2015.f', 'ccpp/physics/physics/precpd.f', 'ccpp/physics/physics/phys_tend.F90', - 'ccpp/physics/physics/tracer_sanitizer.F90', 'ccpp/physics/physics/radlw_main.F90', 'ccpp/physics/physics/radsw_main.F90', 'ccpp/physics/physics/rascnv.F90', diff --git a/ccpp/physics b/ccpp/physics index 0ac8068d5..acf281a01 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit 0ac8068d53a19d342fc176dd62d4267f1b43008e +Subproject commit acf281a01e19b840a1f0e0fb947d9672c6d10c05 diff --git a/ccpp/suites/suite_FV3_GSD_noah.xml b/ccpp/suites/suite_FV3_GSD_noah.xml index 4d7d4e00f..42d55a5e4 100644 --- a/ccpp/suites/suite_FV3_GSD_noah.xml +++ b/ccpp/suites/suite_FV3_GSD_noah.xml @@ -79,7 +79,6 @@ mp_thompson_post GFS_MP_generic_post cu_gf_driver_post - maximum_hourly_diagnostics diff --git a/ccpp/suites/suite_FV3_GSD_v0.xml b/ccpp/suites/suite_FV3_GSD_v0.xml index 7838db77b..0d6531d19 100644 --- a/ccpp/suites/suite_FV3_GSD_v0.xml +++ b/ccpp/suites/suite_FV3_GSD_v0.xml @@ -78,7 +78,6 @@ mp_thompson_post GFS_MP_generic_post cu_gf_driver_post - maximum_hourly_diagnostics diff --git a/gfsphysics/GFS_layer/GFS_typedefs.F90 b/gfsphysics/GFS_layer/GFS_typedefs.F90 index 2fef16ee4..1a63d5bc8 100644 --- a/gfsphysics/GFS_layer/GFS_typedefs.F90 +++ b/gfsphysics/GFS_layer/GFS_typedefs.F90 @@ -811,7 +811,9 @@ module GFS_typedefs integer :: lsoil_lsm !< number of soil layers internal to land surface model integer :: lsnow_lsm !< maximum number of snow layers internal to land surface model integer :: lsnow_lsm_lbound!< lower bound for snow arrays, depending on lsnow_lsm - real(kind=kind_phys), pointer :: zs(:) => null() !< depth of soil levels for land surface model + real(kind=kind_phys), pointer :: zs(:) => null() !< depth of soil levels for land surface model + real(kind=kind_phys), pointer :: pores(:) => null() !< max soil moisture for a given soil type for land surface model + real(kind=kind_phys), pointer :: resid(:) => null() !< min soil moisture for a given soil type for land surface model logical :: rdlai !< read LAI from input file (for RUC LSM or NOAH LSM WRFv4) logical :: ua_phys !< flag for using University of Arizona? extension to NOAH LSM WRFv4 logical :: usemonalb !< flag to read surface diffused shortwave albedo from input file for NOAH LSM WRFv4 @@ -1110,6 +1112,8 @@ module GFS_typedefs integer :: skeb_npass integer :: lndp_type integer :: n_var_lndp + logical :: lndp_each_step ! flag to indicate that land perturbations are applied at every time step, + ! otherwise they are applied only after gcycle is run character(len=3) :: lndp_var_list(6) ! dimension here must match n_var_max_lndp in stochy_nml_def real(kind=kind_phys) :: lndp_prt_list(6) ! dimension here must match n_var_max_lndp in stochy_nml_def ! also previous code had dimension 5 for each pert, to allow @@ -3469,8 +3473,9 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & logical :: do_shum = .false. logical :: do_skeb = .false. integer :: skeb_npass = 11 - integer :: lndp_type = 0 - integer :: n_var_lndp = 0 + integer :: lndp_type = 0 + integer :: n_var_lndp = 0 + logical :: lndp_each_step = .false. !--- aerosol scavenging factors character(len=20) :: fscav_aero(20) = 'default' @@ -3555,7 +3560,8 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & do_deep, jcap, & cs_parm, flgmin, cgwf, ccwf, cdmbgwd, sup, ctei_rm, crtrh, & dlqf, rbcr, shoc_parm, psauras, prauras, wminras, & - do_sppt, do_shum, do_skeb, lndp_type, n_var_lndp, & + do_sppt, do_shum, do_skeb, & + lndp_type, n_var_lndp, lndp_each_step, & !--- Rayleigh friction prslrd0, ral_ts, ldiag_ugwp, do_ugwp, do_tofd, & ! --- Ferrier-Aligo @@ -3981,6 +3987,12 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & end if ! Set number of ice model layers Model%kice = kice + + ! Allocate variable for min/max soil moisture for a given soil type + allocate (Model%pores(30)) + allocate (Model%resid(30)) + Model%pores = clear_val + Model%resid = clear_val ! if (lsnow_lsm /= 3) then write(0,*) 'Logic error: NoahMP expects the maximum number of snow layers to be exactly 3 (see sfc_noahmp_drv.f)' @@ -4216,6 +4228,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%do_skeb = do_skeb Model%lndp_type = lndp_type Model%n_var_lndp = n_var_lndp + Model%lndp_each_step = lndp_each_step !--- cellular automata options Model%nca = nca @@ -5159,6 +5172,8 @@ subroutine control_print(Model) print *, ' aoasis : ', Model%aoasis print *, ' fasdas : ', Model%fasdas print *, ' kice : ', Model%kice + print *, ' shape(pores) : ', shape(Model%pores) + print *, ' shape(resid) : ', shape(Model%resid) #endif print *, ' ivegsrc : ', Model%ivegsrc print *, ' isot : ', Model%isot @@ -5316,7 +5331,8 @@ subroutine control_print(Model) print *, ' do_shum : ', Model%do_shum print *, ' do_skeb : ', Model%do_skeb print *, ' lndp_type : ', Model%lndp_type - print *, ' n_var_lndp : ', Model%n_var_lndp + print *, ' n_var_lndp : ', Model%n_var_lndp + print *, ' lndp_each_step : ', Model%lndp_each_step print *, ' ' print *, 'cellular automata' print *, ' nca : ', Model%nca diff --git a/gfsphysics/GFS_layer/GFS_typedefs.meta b/gfsphysics/GFS_layer/GFS_typedefs.meta index 4dfb5046e..dcacc8644 100644 --- a/gfsphysics/GFS_layer/GFS_typedefs.meta +++ b/gfsphysics/GFS_layer/GFS_typedefs.meta @@ -3285,6 +3285,20 @@ type = real kind = kind_phys active = (flag_for_land_surface_scheme == flag_for_ruc_land_surface_scheme) +[pores] + standard_name = maximum_soil_moisture_content_for_land_surface_model + long_name = maximum soil moisture for a given soil type for land surface model + units = m + dimensions = (30) + type = real + kind = kind_phys +[resid] + standard_name = minimum_soil_moisture_content_for_land_surface_model + long_name = minimum soil moisture for a given soil type for land surface model + units = m + dimensions = (30) + type = real + kind = kind_phys [rdlai] standard_name = flag_for_reading_leaf_area_index_from_input long_name = flag for reading leaf area index from initial conditions diff --git a/stochastic_physics/stochastic_physics_wrapper.F90 b/stochastic_physics/stochastic_physics_wrapper.F90 index 5a3701aa8..44c82ecbd 100644 --- a/stochastic_physics/stochastic_physics_wrapper.F90 +++ b/stochastic_physics/stochastic_physics_wrapper.F90 @@ -13,10 +13,23 @@ module stochastic_physics_wrapper_mod real(kind=kind_phys), dimension(:,:,:), allocatable, save :: skebv_wts real(kind=kind_phys), dimension(:,:,:), allocatable, save :: sfc_wts + integer, save :: lsoil = -999 real(kind=kind_phys), dimension(:,:,:), allocatable, save :: smc real(kind=kind_phys), dimension(:,:,:), allocatable, save :: stc real(kind=kind_phys), dimension(:,:,:), allocatable, save :: slc + ! real(kind=kind_phys), dimension(:,:), allocatable, save :: vfrac + !albedo + real(kind=kind_phys), dimension(:,:), allocatable, save :: snoalb + real(kind=kind_phys), dimension(:,:), allocatable, save :: alvsf + real(kind=kind_phys), dimension(:,:), allocatable, save :: alnsf + real(kind=kind_phys), dimension(:,:), allocatable, save :: alvwf + real(kind=kind_phys), dimension(:,:), allocatable, save :: alnwf + real(kind=kind_phys), dimension(:,:), allocatable, save :: facsf + real(kind=kind_phys), dimension(:,:), allocatable, save :: facwf + !emissivity + real(kind=kind_phys), dimension(:,:), allocatable, save :: semis + real(kind=kind_phys), dimension(:,:), allocatable, save :: stype ! For cellular automata @@ -58,7 +71,6 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) use cellular_automata_global_mod, only: cellular_automata_global use cellular_automata_sgs_mod, only: cellular_automata_sgs use lndp_apply_perts_mod, only: lndp_apply_perts - use namelist_soilveg, only: maxsmc implicit none @@ -108,11 +120,24 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) allocate(sfc_wts(1:Atm_block%nblks,maxval(GFS_Control%blksz),1:GFS_Control%n_var_lndp)) end if if (GFS_Control%lndp_type .EQ. 2) then ! save wts, and apply lndp scheme - allocate(smc(1:Atm_block%nblks,maxval(GFS_Control%blksz),GFS_Control%lsoil)) - allocate(slc(1:Atm_block%nblks,maxval(GFS_Control%blksz),GFS_Control%lsoil)) - allocate(stc(1:Atm_block%nblks,maxval(GFS_Control%blksz),GFS_Control%lsoil)) + if (GFS_Control%lsm == GFS_Control%lsm_noah) then + lsoil = GFS_Control%lsoil + elseif (GFS_Control%lsm == GFS_Control%lsm_ruc) then + lsoil = GFS_Control%lsoil_lsm + endif + allocate(smc(1:Atm_block%nblks,maxval(GFS_Control%blksz),lsoil)) + allocate(slc(1:Atm_block%nblks,maxval(GFS_Control%blksz),lsoil)) + allocate(stc(1:Atm_block%nblks,maxval(GFS_Control%blksz),lsoil)) allocate(stype(1:Atm_block%nblks,maxval(GFS_Control%blksz))) allocate(vfrac(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(snoalb(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(alvsf(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(alnsf(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(alvwf(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(alnwf(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(facsf(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(facwf(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(semis(1:Atm_block%nblks,maxval(GFS_Control%blksz))) endif do nb=1,Atm_block%nblks @@ -171,31 +196,76 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) do nb=1,Atm_block%nblks stype(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%stype(:) - smc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%smc(:,:) - slc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%slc(:,:) - stc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%stc(:,:) vfrac(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%vfrac(:) + snoalb(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%snoalb(:) + alvsf(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%alvsf(:) + alnsf(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%alnsf(:) + alvwf(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%alvwf(:) + alnwf(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%alnwf(:) + facsf(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%facsf(:) + facwf(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%facwf(:) + semis(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Radtend%semis(:) end do - ! determine whether land paramaters have been over-written - if (mod(GFS_Control%kdt,GFS_Control%nscyc) == 1) then ! logic copied from GFS_driver - param_update_flag = .true. + if (GFS_Control%lsm == GFS_Control%lsm_noah) then + do nb=1,Atm_block%nblks + smc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%smc(:,:) + slc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%slc(:,:) + stc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%stc(:,:) + end do + elseif (GFS_Control%lsm == GFS_Control%lsm_ruc) then + do nb=1,Atm_block%nblks + smc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%smois(:,:) + slc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%sh2o(:,:) + stc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%tslb(:,:) + end do + endif + + ! determine whether land paramaters have been over-written to + ! trigger applying perturbations (logic copied from GFS_driver), + ! or if perturbations should be applied at every time step + if (mod(GFS_Control%kdt,GFS_Control%nscyc) == 1 ) then + param_update_flag = .true. else - param_update_flag = .false. + param_update_flag = .false. endif - call lndp_apply_perts( GFS_Control%blksz, GFS_Control%lsm, GFS_Control%lsoil, GFS_Control%dtf, & - GFS_Control%n_var_lndp, GFS_Control%lndp_var_list, GFS_Control%lndp_prt_list, & - sfc_wts, xlon, xlat, stype, maxsmc,param_update_flag, smc, slc,stc, vfrac, ierr) + + call lndp_apply_perts(GFS_Control%blksz, GFS_Control%lsm, GFS_Control%lsm_noah, GFS_Control%lsm_ruc, lsoil, & + GFS_Control%dtf, GFS_Control%kdt, GFS_Control%lndp_each_step, & + GFS_Control%n_var_lndp, GFS_Control%lndp_var_list, GFS_Control%lndp_prt_list, & + sfc_wts, xlon, xlat, stype, GFS_Control%pores, GFS_Control%resid,param_update_flag, & + smc, slc, stc, vfrac, alvsf, alnsf, alvwf, alnwf, facsf, facwf, snoalb, semis, ierr) if (ierr/=0) then write(6,*) 'call to GFS_apply_lndp failed' return endif + do nb=1,Atm_block%nblks - GFS_Data(nb)%Sfcprop%smc(:,:) = smc(nb,1:GFS_Control%blksz(nb),:) - GFS_Data(nb)%Sfcprop%slc(:,:) = slc(nb,1:GFS_Control%blksz(nb),:) - GFS_Data(nb)%Sfcprop%stc(:,:) = stc(nb,1:GFS_Control%blksz(nb),:) - GFS_Data(nb)%Sfcprop%vfrac(:) = vfrac(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%vfrac(:) = vfrac(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%snoalb(:) = snoalb(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%alvsf(:) = alvsf(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%alnsf(:) = alnsf(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%alvwf(:) = alvwf(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%alnwf(:) = alnwf(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%facsf(:) = facsf(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%facwf(:) = facwf(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Radtend%semis(:) = semis(nb,1:GFS_Control%blksz(nb)) enddo + + if (GFS_Control%lsm == GFS_Control%lsm_noah) then + do nb=1,Atm_block%nblks + GFS_Data(nb)%Sfcprop%smc(:,:) = smc(nb,1:GFS_Control%blksz(nb),:) + GFS_Data(nb)%Sfcprop%slc(:,:) = slc(nb,1:GFS_Control%blksz(nb),:) + GFS_Data(nb)%Sfcprop%stc(:,:) = stc(nb,1:GFS_Control%blksz(nb),:) + enddo + elseif (GFS_Control%lsm == GFS_Control%lsm_ruc) then + do nb=1,Atm_block%nblks + GFS_Data(nb)%Sfcprop%smois(:,:) = smc(nb,1:GFS_Control%blksz(nb),:) + GFS_Data(nb)%Sfcprop%sh2o(:,:) = slc(nb,1:GFS_Control%blksz(nb),:) + GFS_Data(nb)%Sfcprop%tslb(:,:) = stc(nb,1:GFS_Control%blksz(nb),:) + enddo + endif + endif ! lndp block end if @@ -313,6 +383,7 @@ subroutine stochastic_physics_wrapper_end (GFS_Control) if (allocated(skebv_wts)) deallocate(skebv_wts) end if if ( GFS_Control%lndp_type .EQ. 2 ) then ! this scheme updates through forecast + lsoil = -999 if (allocated(sfc_wts)) deallocate(sfc_wts) end if if (GFS_Control%lndp_type .EQ. 2) then ! save wts, and apply lndp scheme @@ -321,6 +392,14 @@ subroutine stochastic_physics_wrapper_end (GFS_Control) if (allocated(stc)) deallocate(stc) if (allocated(stype)) deallocate(stype) if (allocated(vfrac)) deallocate(vfrac) + if (allocated(snoalb)) deallocate(snoalb) + if (allocated(alvsf)) deallocate(alvsf) + if (allocated(alnsf)) deallocate(alnsf) + if (allocated(alvwf)) deallocate(alvwf) + if (allocated(alnwf)) deallocate(alnwf) + if (allocated(facsf)) deallocate(facsf) + if (allocated(facwf)) deallocate(facwf) + if (allocated(semis)) deallocate(semis) endif call finalize_stochastic_physics() endif From fa070c83497debb2c34e310f7f6cdb767d282a80 Mon Sep 17 00:00:00 2001 From: tanyasmirnova <38667904+tanyasmirnova@users.noreply.github.com> Date: Tue, 19 Jan 2021 11:28:37 -0700 Subject: [PATCH 6/9] Stochastic land perturbations: add roughness length over land to the perturbed variables (#70) * Added roughness length over land to the perturbed variables. * Bugfix in gfsphysics/GFS_layer/GFS_typedefs.F90: remove Diag%cldcov, in particular the reset call because the variable is not allocated Co-authored-by: Dom Heinzeller --- ccpp/physics | 2 +- gfsphysics/GFS_layer/GFS_typedefs.F90 | 13 ++++--------- stochastic_physics/stochastic_physics_wrapper.F90 | 8 +++++++- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/ccpp/physics b/ccpp/physics index acf281a01..1fd346fc6 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit acf281a01e19b840a1f0e0fb947d9672c6d10c05 +Subproject commit 1fd346fc6eabc6d26f6dfca6056323baf478a082 diff --git a/gfsphysics/GFS_layer/GFS_typedefs.F90 b/gfsphysics/GFS_layer/GFS_typedefs.F90 index 1a63d5bc8..8868ae0b8 100644 --- a/gfsphysics/GFS_layer/GFS_typedefs.F90 +++ b/gfsphysics/GFS_layer/GFS_typedefs.F90 @@ -1618,7 +1618,6 @@ module GFS_typedefs real (kind=kind_phys), pointer :: upd_mf (:,:) => null() !< instantaneous convective updraft mass flux real (kind=kind_phys), pointer :: dwn_mf (:,:) => null() !< instantaneous convective downdraft mass flux real (kind=kind_phys), pointer :: det_mf (:,:) => null() !< instantaneous convective detrainment mass flux - real (kind=kind_phys), pointer :: cldcov (:,:) => null() !< instantaneous 3D cloud fraction !--- F-A MP scheme #ifdef CCPP real (kind=kind_phys), pointer :: TRAIN (:,:) => null() !< accumulated stratiform T tendency (K s-1) @@ -5892,7 +5891,6 @@ subroutine diag_create (Diag, IM, Model) ! allocate (Diag%upd_mf (IM,Model%levs)) ! allocate (Diag%dwn_mf (IM,Model%levs)) ! allocate (Diag%det_mf (IM,Model%levs)) -! allocate (Diag%cldcov (IM,Model%levs)) endif !vay-2018 @@ -6089,9 +6087,6 @@ subroutine diag_rad_zero(Diag, Model) Diag%topfsw%upfx0 = zero Diag%topflw%upfxc = zero Diag%topflw%upfx0 = zero - if (Model%ldiag3d) then - Diag%cldcov = zero - endif end subroutine diag_rad_zero @@ -6241,11 +6236,11 @@ subroutine diag_phys_zero (Diag, Model, linit, iauwindow_center) Diag%dv3dt = zero Diag%dt3dt = zero if (Model%qdiag3d) then - Diag%dq3dt = zero + Diag%dq3dt = zero +! Diag%upd_mf = zero +! Diag%dwn_mf = zero +! Diag%det_mf = zero endif -! Diag%upd_mf = zero -! Diag%dwn_mf = zero -! Diag%det_mf = zero endif ! diff --git a/stochastic_physics/stochastic_physics_wrapper.F90 b/stochastic_physics/stochastic_physics_wrapper.F90 index 44c82ecbd..479270a9f 100644 --- a/stochastic_physics/stochastic_physics_wrapper.F90 +++ b/stochastic_physics/stochastic_physics_wrapper.F90 @@ -29,6 +29,8 @@ module stochastic_physics_wrapper_mod real(kind=kind_phys), dimension(:,:), allocatable, save :: facwf !emissivity real(kind=kind_phys), dimension(:,:), allocatable, save :: semis + !roughness length for land + real(kind=kind_phys), dimension(:,:), allocatable, save :: zorll real(kind=kind_phys), dimension(:,:), allocatable, save :: stype @@ -138,6 +140,7 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) allocate(facsf(1:Atm_block%nblks,maxval(GFS_Control%blksz))) allocate(facwf(1:Atm_block%nblks,maxval(GFS_Control%blksz))) allocate(semis(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(zorll(1:Atm_block%nblks,maxval(GFS_Control%blksz))) endif do nb=1,Atm_block%nblks @@ -205,6 +208,7 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) facsf(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%facsf(:) facwf(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%facwf(:) semis(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Radtend%semis(:) + zorll(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%zorll(:) end do if (GFS_Control%lsm == GFS_Control%lsm_noah) then @@ -234,7 +238,7 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) GFS_Control%dtf, GFS_Control%kdt, GFS_Control%lndp_each_step, & GFS_Control%n_var_lndp, GFS_Control%lndp_var_list, GFS_Control%lndp_prt_list, & sfc_wts, xlon, xlat, stype, GFS_Control%pores, GFS_Control%resid,param_update_flag, & - smc, slc, stc, vfrac, alvsf, alnsf, alvwf, alnwf, facsf, facwf, snoalb, semis, ierr) + smc, slc, stc, vfrac, alvsf, alnsf, alvwf, alnwf, facsf, facwf, snoalb, semis, zorll, ierr) if (ierr/=0) then write(6,*) 'call to GFS_apply_lndp failed' return @@ -250,6 +254,7 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) GFS_Data(nb)%Sfcprop%facsf(:) = facsf(nb,1:GFS_Control%blksz(nb)) GFS_Data(nb)%Sfcprop%facwf(:) = facwf(nb,1:GFS_Control%blksz(nb)) GFS_Data(nb)%Radtend%semis(:) = semis(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%zorll(:) = zorll(nb,1:GFS_Control%blksz(nb)) enddo if (GFS_Control%lsm == GFS_Control%lsm_noah) then @@ -400,6 +405,7 @@ subroutine stochastic_physics_wrapper_end (GFS_Control) if (allocated(facsf)) deallocate(facsf) if (allocated(facwf)) deallocate(facwf) if (allocated(semis)) deallocate(semis) + if (allocated(zorll)) deallocate(zorll) endif call finalize_stochastic_physics() endif From bc265eaf44d854e01899a1f4d904fa6450aff3e5 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Wed, 20 Jan 2021 10:40:02 -0700 Subject: [PATCH 7/9] Update .gitmodules and submodule pointer for GFDL_atmos_cubed_sphere for code review and testing --- .gitmodules | 6 ++++-- atmos_cubed_sphere | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 027cac4a0..1390b8066 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,9 @@ [submodule "atmos_cubed_sphere"] path = atmos_cubed_sphere - url = https://github.com/NOAA-EMC/GFDL_atmos_cubed_sphere - branch = dev/emc + #url = https://github.com/NOAA-EMC/GFDL_atmos_cubed_sphere + #branch = dev/emc + url = https://github.com/XiaqiongZhou-NOAA/GFDL_atmos_cubed_sphere + branch = psmbc [submodule "ccpp/framework"] path = ccpp/framework #url = https://github.com/NOAA-GSL/ccpp-framework diff --git a/atmos_cubed_sphere b/atmos_cubed_sphere index 00397ef24..0a0077023 160000 --- a/atmos_cubed_sphere +++ b/atmos_cubed_sphere @@ -1 +1 @@ -Subproject commit 00397ef249aac0377026a733b3e698b74a43ee8f +Subproject commit 0a0077023f2418e08a7795b1d5921cfd5729d64d From 1eca8cd8cb9b5b5fd5529643b94dd1dae0f85146 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Thu, 21 Jan 2021 09:18:22 -0700 Subject: [PATCH 8/9] Revert change to .gitmodules for ccpp-physics, update submodule pointer for ccpp-physics --- .gitmodules | 12 ++++-------- ccpp/physics | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.gitmodules b/.gitmodules index 1390b8066..08bf14cb4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,13 +6,9 @@ branch = psmbc [submodule "ccpp/framework"] path = ccpp/framework - #url = https://github.com/NOAA-GSL/ccpp-framework - #branch = gsl/develop - url = https://github.com/climbfuji/ccpp-framework - branch = update_master_from_gsl_develop + url = https://github.com/NCAR/ccpp-framework + branch = master [submodule "ccpp/physics"] path = ccpp/physics - #url = https://github.com/NOAA-GSL/ccpp-physics - #branch = gsl/develop - url = https://github.com/climbfuji/ccpp-physics - branch = update_master_from_gsl_develop + url = https://github.com/NCAR/ccpp-physics + branch = master diff --git a/ccpp/physics b/ccpp/physics index 95ae4086c..469cb9051 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit 95ae4086c7fa250d27a841acaf38dcaa12cc33cc +Subproject commit 469cb905176e83bb01d9ecaaaaff1ab34d358cc3 From 7b2d558f514d3aabad3e4d17f9fefc6f28307c58 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Thu, 21 Jan 2021 11:35:05 -0700 Subject: [PATCH 9/9] Revert change to .gitmodules and update submodule pointer for GFDL_atmos_cubed_sphere --- .gitmodules | 6 ++---- atmos_cubed_sphere | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitmodules b/.gitmodules index 08bf14cb4..d253f6966 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,7 @@ [submodule "atmos_cubed_sphere"] path = atmos_cubed_sphere - #url = https://github.com/NOAA-EMC/GFDL_atmos_cubed_sphere - #branch = dev/emc - url = https://github.com/XiaqiongZhou-NOAA/GFDL_atmos_cubed_sphere - branch = psmbc + url = https://github.com/NOAA-EMC/GFDL_atmos_cubed_sphere + branch = dev/emc [submodule "ccpp/framework"] path = ccpp/framework url = https://github.com/NCAR/ccpp-framework diff --git a/atmos_cubed_sphere b/atmos_cubed_sphere index 0a0077023..00397ef24 160000 --- a/atmos_cubed_sphere +++ b/atmos_cubed_sphere @@ -1 +1 @@ -Subproject commit 0a0077023f2418e08a7795b1d5921cfd5729d64d +Subproject commit 00397ef249aac0377026a733b3e698b74a43ee8f