diff --git a/ccpp/data/GFS_typedefs.F90 b/ccpp/data/GFS_typedefs.F90 index 0262f5a98..3d699f171 100644 --- a/ccpp/data/GFS_typedefs.F90 +++ b/ccpp/data/GFS_typedefs.F90 @@ -706,9 +706,13 @@ module GFS_typedefs logical :: do_GPsw_Glw !< If set to true use rrtmgp for SW calculation, rrtmg for LW. character(len=128) :: active_gases_array(100) !< character array for each trace gas name logical :: use_LW_jacobian !< If true, use Jacobian of LW to update radiation tendency. + logical :: damp_LW_fluxadj !< If true, damp the LW flux adjustment using the Jacobian w/ height with logistic function + real(kind_phys) :: lfnc_k !< Logistic function transition depth (Pa) + real(kind_phys) :: lfnc_p0 !< Logistic function transition level (Pa) logical :: doGP_lwscat !< If true, include scattering in longwave cloud-optics, only compatible w/ GP cloud-optics real(kind_phys) :: minGPpres !< Minimum pressure allowed in RRTMGP. real(kind_phys) :: minGPtemp !< Minimum temperature allowed in RRTMGP. + real(kind_phys) :: maxGPtemp !< Maximum temperature allowed in RRTMGP. !--- microphysical switch integer :: ncld !< choice of cloud scheme @@ -785,6 +789,8 @@ module GFS_typedefs logical :: lradar !< flag for radar reflectivity real(kind=kind_phys) :: nsradar_reset !< seconds between resetting radar reflectivity calculation real(kind=kind_phys) :: ttendlim !< temperature tendency limiter per time step in K/s + logical :: ext_diag_thompson !< flag for extended diagnostic output from Thompson + integer :: thompson_ext_ndiag3d=37 !< number of 3d arrays for extended diagnostic output from Thompson !--- GFDL microphysical paramters logical :: lgfdlmprad !< flag for GFDL mp scheme and radiation consistency @@ -1698,6 +1704,9 @@ module GFS_typedefs real (kind=kind_phys), pointer :: tau_tofd(:) => null() ! !---vay-2018 UGWP-diagnostics + ! Extended output diagnostics for Thompson MP + real (kind=kind_phys), pointer :: thompson_ext_diag3d (:,:,:) => null() ! extended diagnostic 3d output arrays from Thompson MP + ! Auxiliary output arrays for debugging real (kind=kind_phys), pointer :: aux2d(:,:) => null() !< auxiliary 2d arrays in output (for debugging) real (kind=kind_phys), pointer :: aux3d(:,:,:)=> null() !< auxiliary 2d arrays in output (for debugging) @@ -1935,7 +1944,8 @@ module GFS_typedefs real (kind=kind_phys), pointer :: rb_ice(:) => null() !< real (kind=kind_phys), pointer :: rb_land(:) => null() !< real (kind=kind_phys), pointer :: rb_water(:) => null() !< - logical :: reset !< + logical :: max_hourly_reset !< + logical :: ext_diag_thompson_reset !< real (kind=kind_phys), pointer :: rhc(:,:) => null() !< real (kind=kind_phys), pointer :: rho1(:) => null() !< real (kind=kind_phys), pointer :: runoff(:) => null() !< @@ -3097,6 +3107,9 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & integer :: rrtmgp_nGauss_ang = 1 !< Number of angles used in Gaussian quadrature logical :: do_GPsw_Glw = .false. logical :: use_LW_jacobian = .false. !< Use Jacobian of LW to update LW radiation tendencies. + logical :: damp_LW_fluxadj = .false. !< Damp LW Jacobian flux adjustment with height. + real(kind=kind_phys) :: lfnc_k = -999 !< + real(kind=kind_phys) :: lfnc_p0 = -999 !< logical :: doGP_lwscat = .false. !< If true, include scattering in longwave cloud-optics, only compatible w/ GP cloud-optics !--- Z-C microphysical parameters integer :: ncld = 1 !< choice of cloud scheme @@ -3150,6 +3163,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & logical :: lradar = .false. !< flag for radar reflectivity real(kind=kind_phys) :: nsradar_reset = -999.0 !< seconds between resetting radar reflectivity calculation, set to <0 for every time step real(kind=kind_phys) :: ttendlim = -999.0 !< temperature tendency limiter, set to <0 to deactivate + logical :: ext_diag_thompson = .false. !< flag for extended diagnostic output from Thompson !--- GFDL microphysical parameters logical :: lgfdlmprad = .false. !< flag for GFDLMP radiation interaction @@ -3487,7 +3501,8 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & sw_file_gas, sw_file_clouds, rrtmgp_nBandsSW, rrtmgp_nGptsSW,& doG_cldoptics, doGP_cldoptics_PADE, doGP_cldoptics_LUT, & rrtmgp_nrghice, rrtmgp_nGauss_ang, do_GPsw_Glw, & - use_LW_jacobian, doGP_lwscat, & + use_LW_jacobian, doGP_lwscat, damp_LW_fluxadj, lfnc_k, & + lfnc_p0, & ! IN CCN forcing iccn, & !--- microphysical parameterizations @@ -3499,7 +3514,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & mg_ncnst, mg_ninst, mg_ngnst, sed_supersat, do_sb_physics, & mg_alf, mg_qcmin, mg_do_ice_gmao, mg_do_liq_liu, & ltaerosol, lradar, nsradar_reset, lrefres, ttendlim, & - lgfdlmprad, & + ext_diag_thompson, lgfdlmprad, & !--- max hourly avg_max_length, & !--- land/surface model control @@ -3845,6 +3860,9 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%doGP_cldoptics_PADE = doGP_cldoptics_PADE Model%doGP_cldoptics_LUT = doGP_cldoptics_LUT Model%use_LW_jacobian = use_LW_jacobian + Model%damp_LW_fluxadj = damp_LW_fluxadj + Model%lfnc_k = lfnc_k + Model%lfnc_p0 = lfnc_p0 Model%doGP_lwscat = doGP_lwscat if (Model%do_RRTMGP) then ! RRTMGP incompatible with levr /= levs @@ -3866,6 +3884,12 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & write(0,*) "Logic error, RRTMGP spectral dimensions (bands/gpts) need to be provided." stop endif + else + if (Model%use_LW_jacobian) then + write(0,*) "Logic error, RRTMGP LW Jacobian adjustment cannot be used with RRTMG radiation." + Model%use_LW_jacobian = .false. + Model%damp_LW_fluxadj = .false. + endif endif ! The CCPP versions of the RRTMG lw/sw schemes are configured @@ -3926,6 +3950,8 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%lradar = lradar Model%nsradar_reset = nsradar_reset Model%ttendlim = ttendlim + Model%ext_diag_thompson= ext_diag_thompson + !--- F-A MP parameters Model%rhgrd = rhgrd Model%spec_adv = spec_adv @@ -4744,6 +4770,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & if (Model%me == Model%master) print *,' Using Thompson double moment microphysics', & ' ltaerosol = ',Model%ltaerosol, & ' ttendlim =',Model%ttendlim, & + ' ext_diag_thompson =',Model%ext_diag_thompson, & ' effr_in =',Model%effr_in, & ' lradar =',Model%lradar, & ' nsradar_reset =',Model%nsradar_reset, & @@ -5127,6 +5154,9 @@ subroutine control_print(Model) print *, ' doGP_cldoptics_PADE: ', Model%doGP_cldoptics_PADE print *, ' doGP_cldoptics_LUT : ', Model%doGP_cldoptics_LUT print *, ' use_LW_jacobian : ', Model%use_LW_jacobian + print *, ' damp_LW_fluxadj : ', Model%damp_LW_fluxadj + print *, ' lfnc_k : ', Model%lfnc_k + print *, ' lfnc_p0 : ', Model%lfnc_p0 print *, ' doGP_lwscat : ', Model%doGP_lwscat endif print *, ' ' @@ -5150,6 +5180,7 @@ subroutine control_print(Model) print *, ' nsradar_reset : ', Model%nsradar_reset print *, ' lrefres : ', Model%lrefres print *, ' ttendlim : ', Model%ttendlim + print *, ' ext_diag_thompson : ', Model%ext_diag_thompson print *, ' ' endif if (Model%imp_physics == Model%imp_physics_mg) then @@ -6028,6 +6059,12 @@ subroutine diag_create (Diag, IM, Model) Diag%exch_m = clear_val endif + ! Extended diagnostics for Thompson MP + if (Model%ext_diag_thompson) then + allocate (Diag%thompson_ext_diag3d(IM,Model%levs,Model%thompson_ext_ndiag3d)) + Diag%thompson_ext_diag3d = clear_val + endif + ! Auxiliary arrays in output for debugging if (Model%naux2d>0) then allocate (Diag%aux2d(IM,Model%naux2d)) @@ -7391,7 +7428,10 @@ subroutine interstitial_phys_reset (Interstitial, Model) end if ! ! Set flag for resetting maximum hourly output fields - Interstitial%reset = mod(Model%kdt-1, nint(Model%avg_max_length/Model%dtp)) == 0 + Interstitial%max_hourly_reset = mod(Model%kdt-1, nint(Model%avg_max_length/Model%dtp)) == 0 + ! Use same logic in UFS to reset Thompson extended diagnostics + Interstitial%ext_diag_thompson_reset = Interstitial%max_hourly_reset + ! ! Set flag for resetting radar reflectivity calculation if (Model%nsradar_reset<0) then Interstitial%radar_reset = .true. @@ -7598,7 +7638,8 @@ subroutine interstitial_print(Interstitial, Model, mpirank, omprank, blkno) write (0,*) 'sum(Interstitial%rb_ice ) = ', sum(Interstitial%rb_ice ) write (0,*) 'sum(Interstitial%rb_land ) = ', sum(Interstitial%rb_land ) write (0,*) 'sum(Interstitial%rb_water ) = ', sum(Interstitial%rb_water ) - write (0,*) 'Interstitial%reset = ', Interstitial%reset + write (0,*) 'Interstitial%max_hourly_reset = ', Interstitial%max_hourly_reset + write (0,*) 'Interstitial%ext_diag_thompson_reset = ', Interstitial%ext_diag_thompson_reset write (0,*) 'sum(Interstitial%rhc ) = ', sum(Interstitial%rhc ) write (0,*) 'sum(Interstitial%runoff ) = ', sum(Interstitial%runoff ) write (0,*) 'sum(Interstitial%save_q ) = ', sum(Interstitial%save_q ) diff --git a/ccpp/data/GFS_typedefs.meta b/ccpp/data/GFS_typedefs.meta index 753e9eb41..894d3b229 100644 --- a/ccpp/data/GFS_typedefs.meta +++ b/ccpp/data/GFS_typedefs.meta @@ -2931,6 +2931,26 @@ units = flag dimensions = () type = logical +[damp_LW_fluxadj] + standard_name = flag_to_damp_RRTMGP_LW_jacobian_flux_adjustment + long_name = logical flag to control RRTMGP LW calculation + units = flag + dimensions = () + type = logical +[lfnc_k] + standard_name = transition_pressure_length_scale_for_flux_damping + long_name = depth of transition layer in logistic function for LW flux adjustment damping + units = Pa + dimensions = () + type = real + kind = kind_phys +[lfnc_p0] + standard_name = transition_pressure_for_flux_damping + long_name = transition pressure for LW flux adjustment damping + units = Pa + dimensions = () + type = real + kind = kind_phys [doGP_lwscat] standard_name = flag_to_include_longwave_scattering_in_cloud_optics long_name = logical flag to control the addition of LW scattering in RRTMGP @@ -2975,6 +2995,13 @@ dimensions = () type = real kind = kind_phys +[maxGPtemp] + standard_name = maximum_temperature_in_RRTMGP + long_name = maximum temperature allowed in RRTMGP + units = K + dimensions = () + type = real + kind = kind_phys [ncld] standard_name = number_of_hydrometeors long_name = choice of cloud scheme / number of hydrometeors @@ -3426,6 +3453,18 @@ dimensions = () type = real kind = kind_phys +[ext_diag_thompson] + standard_name = flag_for_extended_diagnostic_output_from_thompson_microphysics + long_name = flag for extended diagnostic output from thompson microphysics + units = flag + dimensions = () + type = logical +[thompson_ext_ndiag3d] + standard_name = number_of_3d_diagnostic_output_arrays_from_thompson_microphysics + long_name = number of 3d arrays for extended diagnostic output from thompson microphysics + units = count + dimensions = () + type = integer [lgfdlmprad] standard_name = flag_for_GFDL_microphysics_radiation_interaction long_name = flag for GFDL microphysics-radiation interaction @@ -7451,6 +7490,14 @@ type = real kind = kind_phys active = (diag_ugwp_flag) +[thompson_ext_diag3d] + standard_name = extended_diagnostics_output_from_thompson_microphysics + long_name = set of 3d arrays for extended diagnostics output from thompson microphysics + units = none + dimensions = (horizontal_loop_extent,vertical_dimension,number_of_3d_diagnostic_output_arrays_from_thompson_microphysics) + type = real + kind = kind_phys + active = (flag_for_extended_diagnostic_output_from_thompson_microphysics) [aux2d] standard_name = auxiliary_2d_arrays long_name = auxiliary 2d arrays to output (for debugging) @@ -9365,12 +9412,18 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys -[reset] +[max_hourly_reset] standard_name = flag_reset_maximum_hourly_fields long_name = flag for resetting maximum hourly fields units = flag dimensions = () type = logical +[ext_diag_thompson_reset] + standard_name = flag_reset_extended_diagnostics_output_arrays_from_thompson_microphysics + long_name = flag for resetting extended diagnostics output arrays from thompson microphysics + units = flag + dimensions = () + type = logical [rhc] standard_name = critical_relative_humidity long_name = critical relative humidity diff --git a/ccpp/driver/GFS_diagnostics.F90 b/ccpp/driver/GFS_diagnostics.F90 index 619191c10..a7dd9a5c4 100644 --- a/ccpp/driver/GFS_diagnostics.F90 +++ b/ccpp/driver/GFS_diagnostics.F90 @@ -3676,6 +3676,32 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop enddo endif + ! Extended diagnostics from Thompson MP + thompson_extended_diagnostics: if (Model%ext_diag_thompson) then + do num=1,Model%thompson_ext_ndiag3d + idx = idx + 1 + ExtDiag(idx)%axes = 3 + select case (num) + ! This is the place to add specific names, descriptions, + ! and units if so desired + !case (1) + ! ... + case default + write (xtra,'(I2.2)') num + ExtDiag(idx)%name = 'thompson_diag3d_' // trim(xtra) + ExtDiag(idx)%desc = 'Thompson extended diagnostics array ' // trim(xtra) + ExtDiag(idx)%unit = 'unknown' + end select + ExtDiag(idx)%mod_name = 'gfs_phys' + ExtDiag(idx)%intpl_method = 'bilinear' + ExtDiag(idx)%time_avg = .false. + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var3 => IntDiag(nb)%thompson_ext_diag3d(:,:,num) + enddo + enddo + end if thompson_extended_diagnostics + !! Cloud effective radii from Microphysics !if (Model%imp_physics == Model%imp_physics_thompson .or. Model%imp_physics == Model%imp_physics_wsm6 .or. Model%imp_physics == Model%imp_physics_fer_hires) then ! idx = idx + 1 diff --git a/ccpp/physics b/ccpp/physics index f8e883632..275b14c62 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit f8e883632dcdd3c1aaec8b90adb72b3f6aff4b9d +Subproject commit 275b14c6216ec2052b85d0857b5ada36744e1f7b diff --git a/ccpp/suites/suite_FV3_GFS_v15_thompson_mynn_RRTMGP.xml b/ccpp/suites/suite_FV3_GFS_v15_thompson_mynn_RRTMGP.xml index 29d4e4561..7848e25fa 100644 --- a/ccpp/suites/suite_FV3_GFS_v15_thompson_mynn_RRTMGP.xml +++ b/ccpp/suites/suite_FV3_GFS_v15_thompson_mynn_RRTMGP.xml @@ -15,6 +15,7 @@ GFS_suite_interstitial_rad_reset sgscloud_radpre GFS_rrtmgp_pre + GFS_radiation_surface GFS_rrtmgp_thompsonmp_pre GFS_rrtmgp_cloud_overlap_pre GFS_cloud_diagnostics diff --git a/ccpp/suites/suite_FV3_GFS_v16_coupled_noahmp.xml b/ccpp/suites/suite_FV3_GFS_v16_coupled_noahmp.xml index 3eab5b6f6..2b8d3b595 100644 --- a/ccpp/suites/suite_FV3_GFS_v16_coupled_noahmp.xml +++ b/ccpp/suites/suite_FV3_GFS_v16_coupled_noahmp.xml @@ -19,6 +19,7 @@ GFS_suite_interstitial_rad_reset GFS_rrtmg_pre + GFS_radiation_surface rrtmg_sw_pre rrtmg_sw rrtmg_sw_post diff --git a/ccpp/suites/suite_FV3_GFS_v16_coupled_nsstNoahmp.xml b/ccpp/suites/suite_FV3_GFS_v16_coupled_nsstNoahmp.xml index b917ec5f2..bdd124307 100644 --- a/ccpp/suites/suite_FV3_GFS_v16_coupled_nsstNoahmp.xml +++ b/ccpp/suites/suite_FV3_GFS_v16_coupled_nsstNoahmp.xml @@ -19,6 +19,7 @@ GFS_suite_interstitial_rad_reset GFS_rrtmg_pre + GFS_radiation_surface rrtmg_sw_pre rrtmg_sw rrtmg_sw_post diff --git a/ccpp/suites/suite_FV3_RRFS_v1alpha.xml b/ccpp/suites/suite_FV3_RRFS_v1alpha.xml index 33aaa6ece..ad982a5b0 100644 --- a/ccpp/suites/suite_FV3_RRFS_v1alpha.xml +++ b/ccpp/suites/suite_FV3_RRFS_v1alpha.xml @@ -15,6 +15,7 @@ GFS_suite_interstitial_rad_reset sgscloud_radpre GFS_rrtmg_pre + GFS_radiation_surface rrtmg_sw_pre rrtmg_sw rrtmg_sw_post