diff --git a/ccpp/config/ccpp_prebuild_config.py b/ccpp/config/ccpp_prebuild_config.py index 72203192b..ea5557f0f 100755 --- a/ccpp/config/ccpp_prebuild_config.py +++ b/ccpp/config/ccpp_prebuild_config.py @@ -242,6 +242,10 @@ 'FV3/ccpp/physics/physics/GFS_suite_init_finalize_test.F90' : [ 'slow_physics' ], } +# Default build dir, relative to current working directory, +# if not specified as command-line argument +DEFAULT_BUILD_DIR = 'FV3' + # Auto-generated makefile/cmakefile snippets that contain all schemes SCHEMES_MAKEFILE = '{build_dir}/ccpp/physics/CCPP_SCHEMES.mk' SCHEMES_CMAKEFILE = '{build_dir}/ccpp/physics/CCPP_SCHEMES.cmake' diff --git a/ccpp/framework b/ccpp/framework index 6da780825..f7ae56dba 160000 --- a/ccpp/framework +++ b/ccpp/framework @@ -1 +1 @@ -Subproject commit 6da78082547b573d714a359368353dd065f59393 +Subproject commit f7ae56dbaaff833222c77a313d22f894bd4167ac diff --git a/ccpp/physics b/ccpp/physics index 73b8c0ded..ac7e80dea 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit 73b8c0dedd2aab842c55045864dee233e07edfe2 +Subproject commit ac7e80deab52f72dea63dddb3c097bc7dcf6d6a0 diff --git a/ccpp/suites/suite_FV3_GSD_SAR.xml b/ccpp/suites/suite_FV3_GSD_SAR.xml new file mode 100644 index 000000000..e563301c4 --- /dev/null +++ b/ccpp/suites/suite_FV3_GSD_SAR.xml @@ -0,0 +1,83 @@ + + + + + + + GFS_time_vary_pre + GFS_rrtmg_setup + GFS_rad_time_vary + GFS_phys_time_vary + + + + + GFS_suite_interstitial_rad_reset + GFS_rrtmg_pre + rrtmg_sw_pre + mynnrad_pre + rrtmg_sw + rrtmg_sw_post + rrtmg_lw_pre + rrtmg_lw + mynnrad_post + 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_ruc + lsm_ruc_sfc_sice_pre + sfc_sice + lsm_ruc_sfc_sice_post + GFS_surface_loop_control_part2 + + + + GFS_surface_composites_post + dcyc2t3_post + sfc_diag + sfc_diag_post + GFS_surface_generic_post + mynnedmf_wrapper + GFS_GWD_generic_pre + cires_ugwp + cires_ugwp_post + GFS_GWD_generic_post + rayleigh_damp + GFS_suite_stateout_update + ozphys_2015 + h2ophys + GFS_MP_generic_pre + mp_thompson_pre + mp_thompson + mp_thompson_post + GFS_MP_generic_post + maximum_hourly_diagnostics + + + + + GFS_stochastics + + + + diff --git a/gfsphysics/GFS_layer/GFS_diagnostics.F90 b/gfsphysics/GFS_layer/GFS_diagnostics.F90 index ec6c1233b..95f7f51e7 100644 --- a/gfsphysics/GFS_layer/GFS_diagnostics.F90 +++ b/gfsphysics/GFS_layer/GFS_diagnostics.F90 @@ -2804,6 +2804,19 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop enddo #ifdef CCPP + if (Model%rdlai) then + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'xlaixy' + ExtDiag(idx)%desc = 'leaf area index' + ExtDiag(idx)%unit = 'number' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => sfcprop(nb)%xlaixy(:) + enddo + endif + if (Model%lsm == Model%lsm_ruc) then do num = 1,Model%lsoil_lsm write (xtra,'(i1)') num diff --git a/gfsphysics/GFS_layer/GFS_typedefs.F90 b/gfsphysics/GFS_layer/GFS_typedefs.F90 index d3137ed95..c6593edf3 100644 --- a/gfsphysics/GFS_layer/GFS_typedefs.F90 +++ b/gfsphysics/GFS_layer/GFS_typedefs.F90 @@ -712,6 +712,7 @@ 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 + logical :: rdlai #endif integer :: ivegsrc !< ivegsrc = 0 => USGS, !< ivegsrc = 1 => IGBP (20 category) @@ -2321,6 +2322,11 @@ subroutine sfcprop_create (Sfcprop, IM, Model) Sfcprop%tsnow = clear_val Sfcprop%snowfallac = clear_val Sfcprop%acsnow = clear_val + ! + if (Model%rdlai) then + allocate (Sfcprop%xlaixy (IM)) + Sfcprop%xlaixy = clear_val + end if end if if (Model%do_mynnsfclay) then ! For MYNN surface layer scheme @@ -2796,6 +2802,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & #ifdef CCPP integer :: lsoil_lsm = -1 !< number of soil layers internal to land surface model; -1 use lsoil integer :: lsnow_lsm = 3 !< maximum number of snow layers internal to land surface model + logical :: rdlai = .false. #endif integer :: ivegsrc = 2 !< ivegsrc = 0 => USGS, !< ivegsrc = 1 => IGBP (20 category) @@ -3078,7 +3085,8 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & avg_max_length, & !--- land/surface model control #ifdef CCPP - lsm, lsoil, lsoil_lsm, lsnow_lsm, nmtvr, ivegsrc, use_ufo, & + lsm, lsoil, lsoil_lsm, lsnow_lsm, rdlai, & + nmtvr, ivegsrc, use_ufo, & #else lsm, lsoil, nmtvr, ivegsrc, use_ufo, & #endif @@ -3382,6 +3390,12 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & write(0,*) 'Logic error: RUC LSM cannot be used with surface data cycling at this point (fhcyc>0)' stop end if + ! Flag to read leaf area index from input files (initial conditions) + Model%rdlai = rdlai + if (Model%rdlai .and. .not. Model%lsm == Model%lsm_ruc) then + write(0,*) 'Logic error: rdlai = .true. only works with RUC LSM' + stop + end if ! Set surface layers for CCPP physics if (lsoil_lsm==-1) then Model%lsoil_lsm = lsoil @@ -3834,7 +3848,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & ' Boundary layer and Shallow Convection', & ' nshoc_3d=',Model%nshoc_3d, & ' nshoc_2d=',Model%nshoc_2d, & - ' ntke=',Model%ntke,'shoc_parm=',shoc_parm + ' ntke=',Model%ntke,' shoc_parm=',shoc_parm endif #ifdef CCPP @@ -4437,6 +4451,7 @@ subroutine control_print(Model) print *, ' lsm : ', Model%lsm print *, ' lsoil : ', Model%lsoil #ifdef CCPP + print *, ' rdlai : ', Model%rdlai print *, ' lsoil_lsm : ', Model%lsoil_lsm print *, ' lsnow_lsm : ', Model%lsnow_lsm #endif @@ -4867,7 +4882,7 @@ subroutine tbd_create (Tbd, IM, Model) Tbd%snowprv = clear_val Tbd%graupelprv = clear_val end if - + if (Model%lsm == Model%lsm_noahmp) then allocate(Tbd%draincprv (IM)) allocate(Tbd%drainncprv (IM)) @@ -4902,7 +4917,7 @@ subroutine tbd_create (Tbd, IM, Model) Tbd%qsq = clear_val Tbd%cov = clear_val end if - + ! MYJ variables if (Model%do_myjsfc.or.Model%do_myjpbl) then !print*,"Allocating all MYJ surface variables:" @@ -6033,7 +6048,6 @@ subroutine interstitial_setup_tracers(Interstitial, Model) Interstitial%nncl = 5 endif - if (Model%imp_physics == Model%imp_physics_mg) then if (abs(Model%fprcp) == 1) then Interstitial%nncl = 4 ! MG2 with rain and snow @@ -6185,8 +6199,7 @@ subroutine interstitial_rad_reset (Interstitial, Model) Interstitial%tsfg = clear_val ! F-A scheme - !if (Model%imp_physics == Model%imp_physics_fer_hires) then - if (Model%imp_physics == Model%imp_physics_fer_hires ) then + if (Model%imp_physics == Model%imp_physics_fer_hires) then Interstitial%qv_r = clear_val Interstitial%qc_r = clear_val Interstitial%qi_r = clear_val @@ -6768,17 +6781,17 @@ subroutine interstitial_print(Interstitial, Model, mpirank, omprank, blkno) ! Print arrays that are conditional on physics choices if (Model%imp_physics == Model%imp_physics_gfdl .or. Model%imp_physics == Model%imp_physics_thompson) then write (0,*) 'Interstitial_print: values specific to GFDL/Thompson microphysics' - write (0,*) 'sum(Interstitial%graupelmp) = ', sum(Interstitial%graupelmp ) - write (0,*) 'sum(Interstitial%icemp ) = ', sum(Interstitial%icemp ) - write (0,*) 'sum(Interstitial%rainmp ) = ', sum(Interstitial%rainmp ) - write (0,*) 'sum(Interstitial%snowmp ) = ', sum(Interstitial%snowmp ) + write (0,*) 'sum(Interstitial%graupelmp ) = ', sum(Interstitial%graupelmp ) + write (0,*) 'sum(Interstitial%icemp ) = ', sum(Interstitial%icemp ) + write (0,*) 'sum(Interstitial%rainmp ) = ', sum(Interstitial%rainmp ) + write (0,*) 'sum(Interstitial%snowmp ) = ', sum(Interstitial%snowmp ) !F-A scheme else if (Model%imp_physics == Model%imp_physics_fer_hires) then write (0,*) 'Interstitial_print: values specific to F-A microphysics' - write (0,*) 'sum(Interstitial%f_ice ) = ', sum(Interstitial%f_ice ) - write (0,*) 'sum(Interstitial%f_rain ) = ', sum(Interstitial%f_rain ) - write (0,*) 'sum(Interstitial%f_rimef ) = ', sum(Interstitial%f_rimef ) - write (0,*) 'sum(Interstitial%cwm ) = ', sum(Interstitial%cwm ) + write (0,*) 'sum(Interstitial%f_ice ) = ', sum(Interstitial%f_ice ) + write (0,*) 'sum(Interstitial%f_rain ) = ', sum(Interstitial%f_rain ) + write (0,*) 'sum(Interstitial%f_rimef ) = ', sum(Interstitial%f_rimef ) + write (0,*) 'sum(Interstitial%cwm ) = ', sum(Interstitial%cwm ) else if (Model%imp_physics == Model%imp_physics_mg) then write (0,*) 'Interstitial_print: values specific to MG microphysics' write (0,*) 'sum(Interstitial%ncgl ) = ', sum(Interstitial%ncgl ) @@ -6808,8 +6821,8 @@ subroutine interstitial_print(Interstitial, Model, mpirank, omprank, blkno) write (0,*) 'sum(Interstitial%ncpl ) = ', sum(Interstitial%ncpl ) end if if (Model%lsm == Model%lsm_noahmp) then - write (0,*) 'sum(Interstitial%t2mmp ) = ', sum(Interstitial%t2mmp ) - write (0,*) 'sum(Interstitial%q2mp ) = ', sum(Interstitial%q2mp ) + write (0,*) 'sum(Interstitial%t2mmp ) = ', sum(Interstitial%t2mmp ) + write (0,*) 'sum(Interstitial%q2mp ) = ', sum(Interstitial%q2mp ) end if write (0,*) 'Interstitial_print: end' ! diff --git a/gfsphysics/GFS_layer/GFS_typedefs.meta b/gfsphysics/GFS_layer/GFS_typedefs.meta index d0c054032..b6c5cead2 100644 --- a/gfsphysics/GFS_layer/GFS_typedefs.meta +++ b/gfsphysics/GFS_layer/GFS_typedefs.meta @@ -2556,6 +2556,12 @@ units = count dimensions = () type = integer +[rdlai] + standard_name = flag_for_reading_leaf_area_index_from_input + long_name = flag for reading leaf area index from initial conditions for RUC LSM + units = flag + dimensions = () + type = logical [ivegsrc] standard_name = vegetation_type_dataset_choice long_name = land use dataset choice diff --git a/io/FV3GFS_io.F90 b/io/FV3GFS_io.F90 index 3e7b7d2e7..e9d2e2c53 100644 --- a/io/FV3GFS_io.F90 +++ b/io/FV3GFS_io.F90 @@ -513,10 +513,18 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain) nvar_s2o = 18 #ifdef CCPP if (Model%lsm == Model%lsm_ruc .and. warm_start) then - nvar_s2r = 6 + if(Model%rdlai) then + nvar_s2r = 7 + else + nvar_s2r = 6 + end if nvar_s3 = 5 else - nvar_s2r = 0 + if(Model%rdlai) then + nvar_s2r = 1 + else + nvar_s2r = 0 + endif nvar_s3 = 3 endif #else @@ -759,6 +767,11 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain) sfc_name2(nvar_s2m+22) = 'tsnow' sfc_name2(nvar_s2m+23) = 'snowfall_acc' sfc_name2(nvar_s2m+24) = 'swe_snowfall_acc' + if (Model%rdlai) then + sfc_name2(nvar_s2m+25) = 'lai' + endif + else if (Model%lsm == Model%lsm_ruc .and. Model%rdlai) then + sfc_name2(nvar_s2m+19) = 'lai' #endif endif @@ -957,6 +970,11 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain) 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) + if (Model%rdlai) then + Sfcprop(nb)%xlaixy(ix) = sfc_var2(i,j,nvar_s2m+25) + endif + else if (Model%lsm == Model%lsm_ruc .and. Model%rdlai) then + Sfcprop(nb)%xlaixy(ix) = sfc_var2(i,j,nvar_s2m+19) elseif (Model%lsm == Model%lsm_noahmp) then !--- Extra Noah MP variables #else @@ -1453,7 +1471,11 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta nvar2o = 18 #ifdef CCPP if (Model%lsm == Model%lsm_ruc) then - nvar2r = 6 + if (Model%rdlai) then + nvar2r = 7 + else + nvar2r = 6 + endif nvar3 = 5 else nvar2r = 0 @@ -1587,6 +1609,9 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta sfc_name2(nvar2m+22) = 'tsnow' sfc_name2(nvar2m+23) = 'snowfall_acc' sfc_name2(nvar2m+24) = 'swe_snowfall_acc' + if (Model%rdlai) then + sfc_name2(nvar2m+25) = 'lai' + endif else if(Model%lsm == Model%lsm_noahmp) then #else ! Only needed when Noah MP LSM is used - 29 2D @@ -1789,6 +1814,9 @@ subroutine sfc_prop_restart_write (Sfcprop, Atm_block, Model, fv_domain, timesta 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) + if (Model%rdlai) then + sfc_var2(i,j,nvar2m+25) = Sfcprop(nb)%xlaixy(ix) + endif else if (Model%lsm == Model%lsm_noahmp) then #else