diff --git a/physics/GFS_MP_generic.F90 b/physics/GFS_MP_generic.F90 index 6a8d3bfcb..cb072068e 100644 --- a/physics/GFS_MP_generic.F90 +++ b/physics/GFS_MP_generic.F90 @@ -13,12 +13,12 @@ end subroutine GFS_MP_generic_pre_init !! \htmlinclude GFS_MP_generic_pre_run.html !! subroutine GFS_MP_generic_pre_run(im, levs, ldiag3d, qdiag3d, do_aw, ntcw, nncl, & - ntrac, gt0, gq0, save_t, save_q, errmsg, errflg) + ntrac, gt0, gq0, save_t, save_q, num_dfi_radar, errmsg, errflg) ! use machine, only: kind_phys implicit none - integer, intent(in) :: im, levs, ntcw, nncl, ntrac + integer, intent(in) :: im, levs, ntcw, nncl, ntrac, num_dfi_radar logical, intent(in) :: ldiag3d, qdiag3d, do_aw real(kind=kind_phys), dimension(:,:), intent(in) :: gt0 real(kind=kind_phys), dimension(:,:,:), intent(in) :: gq0 @@ -35,12 +35,14 @@ subroutine GFS_MP_generic_pre_run(im, levs, ldiag3d, qdiag3d, do_aw, ntcw, nncl, errmsg = '' errflg = 0 - if (ldiag3d .or. do_aw) then + if (ldiag3d .or. do_aw .or. num_dfi_radar>0) then do k=1,levs do i=1,im save_t(i,k) = gt0(i,k) enddo enddo + endif + if (ldiag3d .or. do_aw) then if(qdiag3d) then do n=1,ntrac do k=1,levs @@ -91,28 +93,36 @@ subroutine GFS_MP_generic_post_run( graupel0, del, rain, domr_diag, domzr_diag, domip_diag, doms_diag, tprcp, srflag, sr, cnvprcp, totprcp, totice, & totsnw, totgrp, cnvprcpb, totprcpb, toticeb, totsnwb, totgrpb, rain_cpl, rainc_cpl, snow_cpl, pwat, & drain_cpl, dsnow_cpl, lsm, lsm_ruc, lsm_noahmp, raincprv, rainncprv, iceprv, snowprv, & - graupelprv, draincprv, drainncprv, diceprv, dsnowprv, dgraupelprv, dtp, & - dtend, dtidx, index_of_temperature, index_of_process_mp,ldiag3d, qdiag3d, lssav, & - errmsg, errflg) + graupelprv, draincprv, drainncprv, diceprv, dsnowprv, dgraupelprv, dtp, dfi_radar_max_intervals, & + dtend, dtidx, index_of_temperature, index_of_process_mp,ldiag3d, qdiag3d, lssav, num_dfi_radar, fh_dfi_radar, & + index_of_process_dfi_radar, ix_dfi_radar, dfi_radar_tten, radar_tten_limits, fhour, errmsg, errflg) ! use machine, only: kind_phys implicit none - integer, intent(in) :: im, levs, kdt, nrcm, nncl, ntcw, ntrac + integer, intent(in) :: im, levs, kdt, nrcm, nncl, ntcw, ntrac, num_dfi_radar, index_of_process_dfi_radar integer, intent(in) :: imp_physics, imp_physics_gfdl, imp_physics_thompson, imp_physics_mg, imp_physics_fer_hires logical, intent(in) :: cal_pre, lssav, ldiag3d, qdiag3d, cplflx, cplchm integer, intent(in) :: index_of_temperature,index_of_process_mp + integer :: dfi_radar_max_intervals + real(kind=kind_phys), intent(in) :: fh_dfi_radar(:), fhour + real(kind=kind_phys), intent(in) :: radar_tten_limits(:) + integer :: ix_dfi_radar(:) + real(kind=kind_phys), dimension(:,:), intent(inout) :: gt0 + real(kind=kind_phys), intent(in) :: dtf, frain, con_g, rainmin real(kind=kind_phys), dimension(:), intent(in) :: rain1, xlat, xlon, tsfc real(kind=kind_phys), dimension(:), intent(inout) :: ice, snow, graupel, rainc real(kind=kind_phys), dimension(:), intent(in) :: rain0, ice0, snow0, graupel0 real(kind=kind_phys), dimension(:,:), intent(in) :: rann - real(kind=kind_phys), dimension(:,:), intent(in) :: gt0, prsl, save_t, del + real(kind=kind_phys), dimension(:,:), intent(in) :: prsl, save_t, del real(kind=kind_phys), dimension(:,:), intent(in) :: prsi, phii real(kind=kind_phys), dimension(:,:,:), intent(in) :: gq0, save_q + real(kind=kind_phys), dimension(:,:,:), intent(in) :: dfi_radar_tten + real(kind=kind_phys), dimension(:), intent(in ) :: sr real(kind=kind_phys), dimension(:), intent(inout) :: rain, domr_diag, domzr_diag, domip_diag, doms_diag, tprcp, & srflag, cnvprcp, totprcp, totice, totsnw, totgrp, cnvprcpb, & @@ -150,10 +160,10 @@ subroutine GFS_MP_generic_post_run( real(kind=kind_phys), parameter :: p850 = 85000.0_kind_phys ! *DH - integer :: i, k, ic, itrac, idtend + integer :: i, k, ic, itrac, idtend, itime, idtend_radar, idtend_mp real(kind=kind_phys), parameter :: zero = 0.0_kind_phys, one = 1.0_kind_phys - real(kind=kind_phys) :: crain, csnow, onebg, tem, total_precip, tem1, tem2 + real(kind=kind_phys) :: crain, csnow, onebg, tem, total_precip, tem1, tem2, ttend real(kind=kind_phys), dimension(im) :: domr, domzr, domip, doms, t850, work1 ! Initialize CCPP error handling variables @@ -244,6 +254,52 @@ subroutine GFS_MP_generic_post_run( endif + do itime=1,num_dfi_radar + if(ix_dfi_radar(itime)<1) cycle + if(fhour=fh_dfi_radar(itime+1)) cycle + exit + enddo + if_radar: if(itime<=num_dfi_radar) then + radar_k: do k=3,levs-2 ! Avoid model top and bottom in case DA forgets to + radar_i: do i=1,im + ttend = dfi_radar_tten(i,k,itime) + if_active: if (ttend>-19) then + ttend = max(ttend,radar_tten_limits(1)) + ttend = min(ttend,radar_tten_limits(2)) + + ! add radar temp tendency + ! there is radar coverage + gt0(i,k) = save_t(i,k) + ttend*dtp + end if if_active + end do radar_i + end do radar_k + if(ldiag3d) then + idtend_radar = dtidx(index_of_temperature,index_of_process_dfi_radar) + idtend_mp = dtidx(index_of_temperature,index_of_process_mp) + if(idtend_radar>0 .or. idtend_mp>0) then + if(idtend_mp>0) then + dtend(:,1:2,idtend_mp) = dtend(:,1:2,idtend_mp) + (gt0(:,1:2)-save_t(:,1:2))*frain + endif + do k=3,levs-2 ! Avoid model top and bottom in case DA forgets to + do i=1,im + ttend = dfi_radar_tten(i,k,itime) + if (ttend>-19) then + if(idtend_radar>0) then + dtend(i,k,idtend_radar) = dtend(i,k,idtend_radar) + (gt0(i,k)-save_t(i,k)) * frain + endif + else if(idtend_mp>0) then + dtend(i,k,idtend_mp) = dtend(i,k,idtend_mp) + (gt0(i,k)-save_t(i,k)) * frain + endif + enddo + enddo + if(idtend_mp>0) then + dtend(:,levs-1:levs,idtend_mp) = dtend(:,levs-1:levs,idtend_mp) + (gt0(:,levs-1:levs)-save_t(:,levs-1:levs))*frain + endif + endif + endif + endif if_radar + t850(1:im) = gt0(1:im,1) do k = 1, levs-1 diff --git a/physics/GFS_MP_generic.meta b/physics/GFS_MP_generic.meta index d14c11baf..1bcbf4ab1 100644 --- a/physics/GFS_MP_generic.meta +++ b/physics/GFS_MP_generic.meta @@ -95,6 +95,13 @@ type = real kind = kind_phys intent = inout +[num_dfi_radar] + standard_name = number_of_radar_derived_temperature_or_convection_suppression_intervals + long_name = number of time ranges with radar-derived microphysics temperature tendencies or radar-derived convection suppression + units = count + dimensions = () + type = integer + intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP @@ -727,6 +734,66 @@ type = real kind = kind_phys intent = in +[dfi_radar_max_intervals] + standard_name = maximum_number_of_radar_derived_temperature_or_convection_suppression_intervals + long_name = maximum allowed number of time ranges with radar-derived microphysics temperature tendencies or radar-derived convection suppression + units = count + dimensions = () + type = integer + intent = in +[num_dfi_radar] + standard_name = number_of_radar_derived_temperature_or_convection_suppression_intervals + long_name = number of time ranges with radar-derived microphysics temperature tendencies or radar-derived convection suppression + units = count + dimensions = () + type = integer + intent = in +[fh_dfi_radar] + standard_name = forecast_lead_times_bounding_radar_derived_temperature_or_convection_suppression_intervals + long_name = forecast lead times bounding radar derived temperature or convection suppression intervals + units = h + dimensions = (maximum_number_of_radar_derived_temperature_or_convection_suppression_intervals_plus_one) + type = real + kind = kind_phys + intent = in +[ix_dfi_radar] + standard_name = indices_with_radar_derived_temperature_or_convection_suppression_data + long_name = indices with radar derived temperature or convection suppression data + units = index + dimensions = (maximum_number_of_radar_derived_temperature_or_convection_suppression_intervals) + type = integer + intent = in +[dfi_radar_tten] + standard_name = radar_derived_microphysics_temperature_tendency + long_name = radar-derived microphysics temperature tendency + units = K s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_radar_derived_temperature_or_convection_suppression_intervals) + type = real + kind = kind_phys + intent = in +[fhour] + standard_name = forecast_time + long_name = current forecast time + units = h + dimensions = () + type = real + kind = kind_phys + intent = in +[radar_tten_limits] + standard_name = allowed_bounds_of_radar_prescribed_tendencies + long_name = allowed bounds of prescribed microphysics temperature tendencies + units = K s-1 + dimensions = (2) + type = real + kind = kind_phys + intent = in +[index_of_process_dfi_radar] + standard_name = index_of_radar_derived_microphysics_temperature_forcing_in_cumulative_change_index + long_name = index of radar-derived microphysics temperature forcing in second dimension of array cumulative change index + units = index + dimensions = () + type = integer + intent = in [dtend] standard_name = cumulative_change_of_state_variables long_name = diagnostic tendencies for state variables diff --git a/physics/cu_gf_deep.F90 b/physics/cu_gf_deep.F90 index 102179bee..e26afef3e 100644 --- a/physics/cu_gf_deep.F90 +++ b/physics/cu_gf_deep.F90 @@ -111,9 +111,7 @@ subroutine cu_gf_deep_run( & !! more is possible, talk to developer or !! implement yourself. pattern is expected to be !! betwee -1 and +1 -#if ( wrf_dfi_radar == 1 ) ,do_capsuppress,cap_suppress_j & ! -#endif ,k22 & ! ,jmin,tropics) ! @@ -129,16 +127,8 @@ subroutine cu_gf_deep_run( & real(kind=kind_phys), dimension (its:ite) & ,intent (in ) :: rand_mom,rand_vmas -#if ( wrf_dfi_radar == 1 ) -! -! option of cap suppress: -! do_capsuppress = 1 do -! do_capsuppress = other don't -! -! - integer, intent(in ) ,optional :: do_capsuppress - real(kind=kind_phys), dimension( its:ite ) :: cap_suppress_j -#endif + integer, intent(in) :: do_capsuppress + real(kind=kind_phys), intent(in), optional, dimension(:) :: cap_suppress_j ! ! ! @@ -458,6 +448,16 @@ subroutine cu_gf_deep_run( & ztexec(:)=0 zqexec(:)=0 endif + if(do_capsuppress == 1) then + do i=its,itf + cap_max(i)=cap_maxs + if (abs(cap_suppress_j(i) - 1.0 ) < 0.1 ) then + cap_max(i)=cap_maxs+75. + elseif (abs(cap_suppress_j(i) - 0.0 ) < 0.1 ) then + cap_max(i)=10.0 + endif + enddo + endif ! !--- initial entrainment rate (these may be changed later on in the !--- program diff --git a/physics/cu_gf_driver.F90 b/physics/cu_gf_driver.F90 index d134b7d02..f83f673ba 100644 --- a/physics/cu_gf_driver.F90 +++ b/physics/cu_gf_driver.F90 @@ -83,7 +83,9 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& flag_for_scnv_generic_tend,flag_for_dcnv_generic_tend, & dtend,dtidx,ntqv,ntiw,ntcw,index_of_temperature,index_of_x_wind, & index_of_y_wind,index_of_process_scnv,index_of_process_dcnv, & - ldiag3d,qci_conv,errmsg,errflg) + fhour,fh_dfi_radar,ix_dfi_radar,num_dfi_radar,cap_suppress, & + dfi_radar_max_intervals,ldiag3d,qci_conv,do_cap_suppress, & + errmsg,errflg) !------------------------------------------------------------- implicit none integer, parameter :: maxiens=1 @@ -98,6 +100,7 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& integer, parameter :: ichoicem=13 ! 0 2 5 13 integer, parameter :: ichoice_s=3 ! 0 1 2 3 + logical, intent(in) :: do_cap_suppress real(kind=kind_phys), parameter :: aodc0=0.14 real(kind=kind_phys), parameter :: aodreturn=30. real(kind=kind_phys) :: dts,fpi,fp @@ -125,6 +128,11 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& real(kind=kind_phys), allocatable :: clcw_save(:,:), cliw_save(:,:) + integer, intent(in) :: dfi_radar_max_intervals + real(kind=kind_phys), intent(in) :: fhour, fh_dfi_radar(:) + integer, intent(in) :: num_dfi_radar, ix_dfi_radar(:) + real(kind=kind_phys), intent(in) :: cap_suppress(:,:) + integer, dimension (:), intent(out) :: hbot,htop,kcnv integer, dimension (:), intent(in) :: xland real(kind=kind_phys), dimension (:), intent(in) :: pbl @@ -213,6 +221,9 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& real(kind=kind_phys) :: cliw_deep,clcw_deep,tem_deep, clcw_both integer :: cliw_deep_idx, clcw_deep_idx, cliw_shal_idx, clcw_shal_idx + real(kind=kind_phys) :: cap_suppress_j(im) + integer :: itime, do_cap_suppress_here + !parameter (tf=243.16, tcr=270.16, tcrf=1.0/(tcr-tf)) ! FV3 original !parameter (tf=263.16, tcr=273.16, tcrf=1.0/(tcr-tf)) !parameter (tf=233.16, tcr=263.16, tcrf=1.0/(tcr-tf)) @@ -221,6 +232,22 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& errmsg = '' errflg = 0 + if(do_cap_suppress) then + do itime=1,num_dfi_radar + if(ix_dfi_radar(itime)<1) cycle + if(fhour=fh_dfi_radar(itime+1)) cycle + exit + enddo + endif + if(do_cap_suppress .and. itime<=num_dfi_radar) then + do_cap_suppress_here = 1 + cap_suppress_j = cap_suppress(:,itime) + else + do_cap_suppress_here = 0 + cap_suppress_j = 0 + endif + if(ldiag3d) then if(flag_for_dcnv_generic_tend) then cliw_deep_idx=0 @@ -643,9 +670,7 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& ! more is possible, talk to developer or ! implement yourself. pattern is expected to be ! betwee -1 and +1 -#if ( wrf_dfi_radar == 1 ) - ,do_capsuppress,cap_suppress_j & -#endif + ,do_cap_suppress_here,cap_suppress_j & ,k22m & ,jminm,tropics) @@ -726,9 +751,7 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& ! more is possible, talk to developer or ! implement yourself. pattern is expected to be ! betwee -1 and +1 -#if ( wrf_dfi_radar == 1 ) - ,do_capsuppress,cap_suppress_j & -#endif + ,do_cap_suppress_here,cap_suppress_j & ,k22 & ,jmin,tropics) jpr=0 diff --git a/physics/cu_gf_driver.meta b/physics/cu_gf_driver.meta index 3a54a9ecc..3fb9fe232 100644 --- a/physics/cu_gf_driver.meta +++ b/physics/cu_gf_driver.meta @@ -486,6 +486,13 @@ dimensions = () type = integer intent = in +[dfi_radar_max_intervals] + standard_name = maximum_number_of_radar_derived_temperature_or_convection_suppression_intervals + long_name = maximum allowed number of time ranges with radar-derived microphysics temperature tendencies or radar-derived convection suppression + units = count + dimensions = () + type = integer + intent = in [ldiag3d] standard_name = flag_for_diagnostics_3D long_name = flag for 3d diagnostic fields @@ -501,6 +508,51 @@ type = real kind = kind_phys intent = inout +[fhour] + standard_name = forecast_time + long_name = current forecast time + units = h + dimensions = () + type = real + kind = kind_phys + intent = in +[do_cap_suppress] + standard_name = flag_for_radar_derived_convection_suppression + long_name = flag for radar-derived convection suppression + units = flag + dimensions = () + type = logical + intent = in +[fh_dfi_radar] + standard_name = forecast_lead_times_bounding_radar_derived_temperature_or_convection_suppression_intervals + long_name = forecast lead times bounding radar derived temperature or convection suppression intervals + units = h + dimensions = (maximum_number_of_radar_derived_temperature_or_convection_suppression_intervals_plus_one) + type = real + kind = kind_phys + intent = in +[ix_dfi_radar] + standard_name = indices_with_radar_derived_temperature_or_convection_suppression_data + long_name = indices with radar derived temperature or convection suppression data + units = index + dimensions = (maximum_number_of_radar_derived_temperature_or_convection_suppression_intervals) + type = integer + intent = in +[num_dfi_radar] + standard_name = number_of_radar_derived_temperature_or_convection_suppression_intervals + long_name = number of time ranges with radar-derived microphysics temperature tendencies or radar-derived convection suppression + units = count + dimensions = () + type = integer + intent = in +[cap_suppress] + standard_name = radar_derived_convection_suppression + long_name = radar-derived convection suppression + units = unitless + dimensions = (horizontal_loop_extent,number_of_radar_derived_temperature_or_convection_suppression_intervals) + type = real + kind = kind_phys + intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP