diff --git a/ccpp/data/GFS_typedefs.F90 b/ccpp/data/GFS_typedefs.F90 index c56b591ad..4642f1ee8 100644 --- a/ccpp/data/GFS_typedefs.F90 +++ b/ccpp/data/GFS_typedefs.F90 @@ -244,6 +244,7 @@ module GFS_typedefs real (kind=kind_phys), pointer :: emis_ice (:) => null() !< surface emissivity over ice for LSM real (kind=kind_phys), pointer :: emis_wat (:) => null() !< surface emissivity over water real (kind=kind_phys), pointer :: sfalb_lnd_bck (:) => null() !< snow-free albedo over land + real (kind=kind_phys), pointer :: aod_in (:) => null() !< anthropogenic background input !--- In (radiation only) real (kind=kind_phys), pointer :: sncovr (:) => null() !< snow cover in fraction over land @@ -571,6 +572,8 @@ module GFS_typedefs !--- instantaneous quantities for chemistry coupling real (kind=kind_phys), pointer :: ushfsfci(:) => null() !< instantaneous upward sensible heat flux (w/m**2) real (kind=kind_phys), pointer :: qci_conv(:,:) => null() !< convective cloud condesate after rainout + real (kind=kind_phys), pointer :: qci_conv_accum(:,:) => null() !< accumulated cloud condesate after rainout + real (kind=kind_phys), pointer :: qci_conv_timeave(:,:) => null() !< time averaged cloud condesate after rainout real (kind=kind_phys), pointer :: pfi_lsan(:,:) => null() !< instantaneous 3D flux of ice nonconvective precipitation (kg m-2 s-1) real (kind=kind_phys), pointer :: pfl_lsan(:,:) => null() !< instantaneous 3D flux of liquid nonconvective precipitation (kg m-2 s-1) @@ -1019,6 +1022,9 @@ module GFS_typedefs integer :: imfshalcnv_gf = 3 !< flag for scale- & aerosol-aware Grell-Freitas scheme (GSD) integer :: imfshalcnv_ntiedtke = 4 !< flag for new Tiedtke scheme (CAPS) logical :: hwrf_samfdeep !< flag for HWRF SAMF deepcnv scheme (HWRF) + integer :: gf_aeroic !< flag determining which initial conditions to use for aerosol-aware gf + !< 1: MERRA2 climatology + !< 2: Analysis from chemistry model (user provided) integer :: imfdeepcnv !< flag for mass-flux deep convection scheme !< 1: July 2010 version of SAS conv scheme !< current operational version as of 2016 @@ -1512,6 +1518,8 @@ module GFS_typedefs !--- Diagnostic that needs to be carried over to the next time step (removed from diag_type) real (kind=kind_phys), pointer :: hpbl (:) => null() !< Planetary boundary layer height real (kind=kind_phys), pointer :: ud_mf (:,:) => null() !< updraft mass flux + real (kind=kind_phys), pointer :: ud_mf_accum (:,:) => null() !< accumulated updraft mass flux + real (kind=kind_phys), pointer :: ud_mf_timeave (:,:) => null() !< time averaged updraft mass flux !--- dynamical forcing variables for Grell-Freitas convection real (kind=kind_phys), pointer :: forcet (:,:) => null() !< @@ -2066,6 +2074,7 @@ subroutine sfcprop_create (Sfcprop, IM, Model) allocate (Sfcprop%emis_lnd (IM)) allocate (Sfcprop%emis_ice (IM)) allocate (Sfcprop%emis_wat (IM)) + allocate (Sfcprop%aod_in (IM)) Sfcprop%slmsk = clear_val Sfcprop%oceanfrac = clear_val @@ -2099,6 +2108,7 @@ subroutine sfcprop_create (Sfcprop, IM, Model) Sfcprop%emis_lnd = clear_val Sfcprop%emis_ice = clear_val Sfcprop%emis_wat = clear_val + Sfcprop%aod_in = clear_val !--- In (radiation only) allocate (Sfcprop%snoalb (IM)) @@ -2783,7 +2793,11 @@ subroutine coupling_create (Coupling, IM, Model) if (Model%imfdeepcnv == Model%imfdeepcnv_gf) then allocate (Coupling%qci_conv (IM,Model%levs)) + allocate (Coupling%qci_conv_accum (IM,Model%levs)) + allocate (Coupling%qci_conv_timeave (IM,Model%levs)) Coupling%qci_conv = clear_val + Coupling%qci_conv_accum = clear_val + Coupling%qci_conv_timeave = clear_val endif end subroutine coupling_create @@ -3152,6 +3166,9 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & !< 2: scale- & aerosol-aware mass-flux deep conv scheme (2017) !< 3: scale- & aerosol-aware Grell-Freitas scheme (GSD) !< 4: New Tiedtke scheme (CAPS) + integer :: gf_aeroic = 1 !< flag determining which initial conditions to use for aerosol-aware gf + !< 1: MERRA2 climatology + !< 2: Analysis from chemistry model (user provided) integer :: isatmedmf = 0 !< flag for scale-aware TKE-based moist edmf scheme !< 0: initial version of satmedmf (Nov. 2018) !< 1: updated version of satmedmf (as of May 2019) @@ -3464,8 +3481,8 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & hwrf_samfdeep, hwrf_samfshal, & h2o_phys, pdfcld, shcnvcw, redrag, hybedmf, satmedmf, & shinhong, do_ysu, dspheat, lheatstrg, lseaspray, cnvcld, & - random_clds, shal_cnv, imfshalcnv, imfdeepcnv, isatmedmf, & - do_deep, jcap, & + random_clds, shal_cnv, imfshalcnv, imfdeepcnv, gf_aeroic, & + isatmedmf, 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, & @@ -4151,6 +4168,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%shal_cnv = shal_cnv Model%imfshalcnv = imfshalcnv Model%imfdeepcnv = imfdeepcnv + Model%gf_aeroic = gf_aeroic Model%isatmedmf = isatmedmf Model%do_deep = do_deep Model%nmtvr = nmtvr @@ -5278,7 +5296,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & endif if(Model%ras .or. Model%cscnv) Model%cnvcld = .false. - if(Model%do_shoc .or. Model%pdfcld .or. Model%do_mynnedmf .or. Model%imfdeepcnv == Model%imfdeepcnv_gf) Model%cnvcld = .false. + if(Model%do_shoc .or. Model%pdfcld .or. Model%do_mynnedmf) Model%cnvcld = .false. if(Model%cnvcld) Model%ncnvcld3d = 1 !--- get cnvwind index in phy_f2d; last entry in phy_f2d array @@ -5848,6 +5866,7 @@ subroutine control_print(Model) print *, ' shal_cnv : ', Model%shal_cnv print *, ' imfshalcnv : ', Model%imfshalcnv print *, ' imfdeepcnv : ', Model%imfdeepcnv + print *, ' gf_aeroic : ', Model%gf_aeroic print *, ' do_deep : ', Model%do_deep print *, ' nmtvr : ', Model%nmtvr print *, ' jcap : ', Model%jcap @@ -6254,9 +6273,13 @@ subroutine tbd_create (Tbd, IM, Model) allocate(Tbd%cactiv(IM)) allocate(Tbd%cactiv_m(IM)) allocate(Tbd%aod_gf(IM)) + allocate(Tbd%ud_mf_accum(IM, Model%levs)) + allocate(Tbd%ud_mf_timeave(IM, Model%levs)) Tbd%cactiv = zero Tbd%cactiv_m = zero Tbd%aod_gf = zero + Tbd%ud_mf_accum = zero + Tbd%ud_mf_timeave = zero end if !--- MYNN variables: diff --git a/ccpp/data/GFS_typedefs.meta b/ccpp/data/GFS_typedefs.meta index 155b26d32..14661bdaf 100644 --- a/ccpp/data/GFS_typedefs.meta +++ b/ccpp/data/GFS_typedefs.meta @@ -754,6 +754,14 @@ type = real kind = kind_phys active = (do_smoke_coupling) +[aod_in] + standard_name = assimilated_aod_input + long_name = assimilated aod input + units = none + dimensions = (horizontal_dimension) + type = real + kind = kind_phys + active = (control_for_deep_convection_scheme == identifier_for_grell_freitas_deep_convection) [z0base] standard_name = baseline_surface_roughness_length long_name = baseline surface roughness length for momentum in meter @@ -2593,6 +2601,22 @@ type = real kind = kind_phys active = (control_for_deep_convection_scheme == identifier_for_grell_freitas_deep_convection) +[qci_conv_timeave] + standard_name = time_averaged_convective_cloud_condesate_after_rainout + long_name = time averaged convective cloud condesate after rainout + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + active = (control_for_deep_convection_scheme == identifier_for_grell_freitas_deep_convection) +[qci_conv_accum] + standard_name = accumulated_convective_cloud_condesate_after_rainout + long_name = accumulatedconvective cloud condesate after rainout + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + active = (control_for_deep_convection_scheme == identifier_for_grell_freitas_deep_convection) [pfi_lsan] standard_name = ice_flux_due_to_large_scale_precipitation long_name = instantaneous 3D flux of ice from nonconvective precipitation @@ -4509,6 +4533,12 @@ units = flag dimensions = () type = logical +[gf_aeroic] + standard_name = control_for_gf_aerosol_initial_conditions + long_name = flag for initial conditions used in aerosol-aware GF + units = flag + dimensions = () + type = integer [isatmedmf] standard_name = choice_of_scale_aware_TKE_moist_EDMF_PBL long_name = choice of scale-aware TKE moist EDMF PBL scheme @@ -6474,6 +6504,22 @@ type = real kind = kind_phys active = ( control_for_deep_convection_scheme .ge. 0 .or. control_for_shallow_convection_scheme .ge. 0 ) +[ud_mf_accum] + standard_name = accumulated_atmosphere_updraft_convective_mass_flux + long_name = accumulated (updraft mass flux) * delt + units = kg m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + active = (control_for_deep_convection_scheme == identifier_for_grell_freitas_deep_convection) +[ud_mf_timeave] + standard_name = time_average_atmosphere_updraft_convective_mass_flux + long_name = time averaged (updraft mass flux) * delt + units = kg m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + active = (control_for_deep_convection_scheme == identifier_for_grell_freitas_deep_convection) [in_nm] standard_name = ice_nucleation_number_from_climatology long_name = ice nucleation number in MG MP @@ -6502,7 +6548,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - active = (control_for_deep_convection_scheme == identifier_for_grell_freitas_deep_convection) + active = (control_for_gf_aerosol_initial_conditions == 2) [imap] standard_name = map_of_block_column_number_to_global_i_index long_name = map of local index ix to global index i for this block diff --git a/ccpp/driver/GFS_restart.F90 b/ccpp/driver/GFS_restart.F90 index 73e181b5f..232fab6d2 100644 --- a/ccpp/driver/GFS_restart.F90 +++ b/ccpp/driver/GFS_restart.F90 @@ -99,7 +99,7 @@ subroutine GFS_restart_populate (Restart, Model, Statein, Stateout, Sfcprop, & ! GF if (Model%imfdeepcnv == Model%imfdeepcnv_gf) then - Restart%num2d = Restart%num2d + 3 + Restart%num2d = Restart%num2d + 4 endif ! CA if (Model%imfdeepcnv == 2 .and. Model%do_ca) then @@ -132,13 +132,9 @@ subroutine GFS_restart_populate (Restart, Model, Statein, Stateout, Sfcprop, & if(Model%lrefres) then Restart%num3d = Model%ntot3d+1 endif - ! General Convection - if (Model%imfdeepcnv == Model%imfdeepcnv_gf) then - Restart%num3d = Restart%num3d + 1 - endif ! GF - if (Model%imfdeepcnv == 3) then - Restart%num3d = Restart%num3d + 3 + if (Model%imfdeepcnv == Model%imfdeepcnv_gf) then + Restart%num3d = Restart%num3d + 8 endif ! MYNN PBL if (Model%do_mynnedmf) then @@ -234,6 +230,11 @@ subroutine GFS_restart_populate (Restart, Model, Statein, Stateout, Sfcprop, & do nb = 1,nblks Restart%data(nb,num)%var2p => Tbd(nb)%aod_gf(:) enddo + num = num + 1 + Restart%name2d(num) = 'aod_in' + do nb = 1,nblks + Restart%data(nb,num)%var2p => Sfcprop(nb)%aod_in(:) + enddo endif ! NoahMP if (Model%lsm == Model%lsm_noahmp) then @@ -437,18 +438,17 @@ subroutine GFS_restart_populate (Restart, Model, Statein, Stateout, Sfcprop, & num = Model%ntot3d endif - !--Convection variable used in CB cloud fraction. Presently this - !--is only needed in sgscloud_radpre for imfdeepcnv == imfdeepcnv_gf. + ! GF if (Model%imfdeepcnv == Model%imfdeepcnv_gf) then + !--Convection variable used in CB cloud fraction. Presently this + !--is only needed in sgscloud_radpre for imfdeepcnv == imfdeepcnv_gf. num = num + 1 Restart%name3d(num) = 'cnv_3d_ud_mf' do nb = 1,nblks Restart%data(nb,num)%var3p => Tbd(nb)%ud_mf(:,:) enddo - endif - !--- RAP/HRRR-specific variables, 3D - ! GF - if (Model%imfdeepcnv == Model%imfdeepcnv_gf) then + + !--- RAP/HRRR-specific variables, 3D num = num + 1 Restart%name3d(num) = 'gf_3d_prevst' do nb = 1,nblks @@ -464,6 +464,26 @@ subroutine GFS_restart_populate (Restart, Model, Statein, Stateout, Sfcprop, & do nb = 1,nblks Restart%data(nb,num)%var3p => Coupling(nb)%qci_conv(:,:) enddo + num = num + 1 + Restart%name3d(num) = 'gf_ud_mf_accum' + do nb = 1,nblks + Restart%data(nb,num)%var3p => Tbd(nb)%ud_mf_accum(:,:) + enddo + num = num + 1 + Restart%name3d(num) = 'gf_ud_mf_timeave' + do nb = 1,nblks + Restart%data(nb,num)%var3p => Tbd(nb)%ud_mf_timeave(:,:) + enddo + num = num + 1 + Restart%name3d(num) = 'gf_qci_conv_accum' + do nb = 1,nblks + Restart%data(nb,num)%var3p => Coupling(nb)%qci_conv_accum(:,:) + enddo + num = num + 1 + Restart%name3d(num) = 'qci_conv_timeave' + do nb = 1,nblks + Restart%data(nb,num)%var3p => Coupling(nb)%qci_conv_timeave(:,:) + enddo endif ! MYNN PBL if (Model%do_mynnedmf) then diff --git a/ccpp/physics b/ccpp/physics index 2f2504c83..d56ab386e 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit 2f2504c837fb40537defe803cfaefb98c2e1c025 +Subproject commit d56ab386e40ef8a5ee01aa5992acb83b6efc2999 diff --git a/io/FV3GFS_io.F90 b/io/FV3GFS_io.F90 index ef7cbf008..c0e3b6bee 100644 --- a/io/FV3GFS_io.F90 +++ b/io/FV3GFS_io.F90 @@ -62,10 +62,11 @@ module FV3GFS_io_mod character(len=32) :: fn_phy = 'phy_data.nc' character(len=32) :: fn_dust12m= 'dust12m_data.nc' character(len=32) :: fn_emi = 'emi_data.nc' + character(len=32) :: fn_aod = 'aod.nc' character(len=32) :: fn_gbbepx = 'SMOKE_GBBEPx_data.nc' !--- GFDL FMS netcdf restart data types defined in fms2_io - type(FmsNetcdfDomainFile_t) :: Oro_restart, Sfc_restart, Phy_restart, dust12m_restart, emi_restart, gbbepx_restart + type(FmsNetcdfDomainFile_t) :: Oro_restart, Sfc_restart, Phy_restart, dust12m_restart, emi_restart, aod_restart, gbbepx_restart type(FmsNetcdfDomainFile_t) :: Oro_ls_restart, Oro_ss_restart !--- GFDL FMS restart containers @@ -74,10 +75,11 @@ module FV3GFS_io_mod character(len=32), allocatable, dimension(:) :: oro_ls_ss_name real(kind=kind_phys), allocatable, target, dimension(:,:,:) :: oro_ls_var, oro_ss_var real(kind=kind_phys), allocatable, target, dimension(:,:,:,:) :: sfc_var3, phy_var3 - character(len=32), allocatable, dimension(:) :: dust12m_name, emi_name, gbbepx_name + character(len=32), allocatable, dimension(:) :: dust12m_name, emi_name, aod_name, gbbepx_name real(kind=kind_phys), allocatable, target, dimension(:,:,:,:) :: gbbepx_var real(kind=kind_phys), allocatable, target, dimension(:,:,:,:) :: dust12m_var real(kind=kind_phys), allocatable, target, dimension(:,:,:) :: emi_var + real(kind=kind_phys), allocatable, target, dimension(:,:,:) :: aod_var !--- Noah MP restart containers real(kind=kind_phys), allocatable, target, dimension(:,:,:,:) :: sfc_var3sn,sfc_var3eq,sfc_var3zn @@ -522,7 +524,7 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain, warm_sta integer :: nvar_o2, nvar_s2m, nvar_s2o, nvar_s3 integer :: nvar_oro_ls_ss integer :: nvar_s2r, nvar_s2mp, nvar_s3mp, isnow - integer :: nvar_emi, nvar_dust12m, nvar_gbbepx + integer :: nvar_emi, nvar_aod, nvar_dust12m, nvar_gbbepx real(kind=kind_phys), pointer, dimension(:,:) :: var2_p => NULL() real(kind=kind_phys), pointer, dimension(:,:,:) :: var3_p => NULL() real(kind=kind_phys), pointer, dimension(:,:,:) :: var3_p1 => NULL() @@ -551,6 +553,7 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain, warm_sta nvar_gbbepx = 0 nvar_emi = 0 endif + nvar_aod = 1 if (Model%lsm == Model%lsm_ruc .and. warm_start) then if(Model%rdlai) then @@ -836,6 +839,47 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain, warm_sta deallocate(gbbepx_name, gbbepx_var) endif if_smoke ! RRFS_Smoke + gf_aeroic: if(Model%gf_aeroic.eq.2) then ! for chemistry analysis used in GF aerosol-aware + !--- open assimilated aod file + infile=trim(indir)//'/'//trim(fn_aod) + amiopen=open_file(aod_restart, trim(infile), 'read', domain=fv_domain, is_restart=.true., dont_add_res_to_filename=.true.) + if (.not.amiopen) call mpp_error( FATAL, 'Error with opening file'//trim(infile) ) + + if (.not. allocated(aod_name)) then + !--- allocate the various containers needed for DA AOD data + allocate(aod_name(nvar_aod)) + allocate(aod_var(nx,ny,nvar_aod)) + + aod_name(1) = 'aod' + !--- register axis + call register_axis( aod_restart, "x", 'X' ) + call register_axis( aod_restart, "y", 'Y' ) + !--- register the 2D fields + do num = 1,nvar_aod + var2_p => aod_var(:,:,num) + call register_restart_field(aod_restart, aod_name(num), var2_p, dimensions=(/'y','x'/)) + enddo + nullify(var2_p) + endif + + !--- read new GSL created aod restart/data + call mpp_error(NOTE,'reading aod information from INPUT/aod_data.tile*.nc') + call read_restart(aod_restart) + call close_file(aod_restart) + + do nb = 1, Atm_block%nblks + !--- 2D variables + 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)%aod_in(ix) = aod_var(i,j,1) + enddo + enddo + + !--- deallocate containers and free restart container + deallocate(aod_name, aod_var) + endif gf_aeroic ! chemistry analysis used in GF aerosol-aware + !--- Modify/read-in additional orographic static fields for GSL drag suite if (Model%gwd_opt==3 .or. Model%gwd_opt==33 .or. & Model%gwd_opt==2 .or. Model%gwd_opt==22 ) then