diff --git a/physics/cu_gf_deep.F90 b/physics/cu_gf_deep.F90 index 2d1d5f7df..b8f295f60 100644 --- a/physics/cu_gf_deep.F90 +++ b/physics/cu_gf_deep.F90 @@ -4436,7 +4436,9 @@ subroutine cup_up_moisture(name,ierr,z_cup,qc,qrc,pw,pwav, & !$acc loop independent do k=k22(i)+1,ktop(i) !$acc atomic + dp=p_cup(i,k-1)-p_cup(i,k) qc(i,k)=qc(i,k)-qrc(i,k) + clw_all(i,k)=qrc(i,k)*(g/dp)*zu(i,k) enddo endif ! ierr ! diff --git a/physics/cu_gf_driver.F90 b/physics/cu_gf_driver.F90 index d305989b6..af6aab1ae 100644 --- a/physics/cu_gf_driver.F90 +++ b/physics/cu_gf_driver.F90 @@ -1,4 +1,3 @@ -!>\file cu_gf_driver.F90 !! This file is scale-aware Grell-Freitas cumulus scheme driver. @@ -58,17 +57,18 @@ end subroutine cu_gf_driver_finalize !! !>\section gen_gf_driver GSD GF Cumulus Scheme General Algorithm !> @{ - subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& + subroutine cu_gf_driver_run(ntracer,garea,im,km,kdt,dt,flag_init,flag_restart,& cactiv,cactiv_m,g,cp,xlv,r_v,forcet,forceqv_spechum,phil,raincv, & qv_spechum,t,cld1d,us,vs,t2di,w,qv2di_spechum,p2di,psuri, & - hbot,htop,kcnv,xland,hfx2,qfx2,aerodp,aod_gf,cliw,clcw, & - pbl,ud_mf,dd_mf,dt_mf,cnvw_moist,cnvc,imfshalcnv, & + hbot,htop,kcnv,xland,hfx2,qfx2,gf_aeroic,aerodp,aod_gf,aod_da, & + cliw,clcw,pbl,ud_mf,dd_mf,dt_mf,cnvw_moist,cnvc,imfshalcnv, & 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, & fhour,fh_dfi_radar,ix_dfi_radar,num_dfi_radar,cap_suppress, & dfi_radar_max_intervals,ldiag3d,qci_conv,do_cap_suppress, & - errmsg,errflg) + fhswr,nsswr,qci_conv_accum,qci_conv_timeave,ud_mf_accum, & + ud_mf_timeave,errmsg,errflg) !------------------------------------------------------------- implicit none integer, parameter :: maxiens=1 @@ -79,8 +79,8 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& integer, parameter :: imid_gf=1 ! testgf2 turn on middle gf conv. integer, parameter :: ideep=1 integer, parameter :: ichoice=0 ! 0 2 5 13 8 - !integer, parameter :: ichoicem=5 ! 0 2 5 13 - integer, parameter :: ichoicem=13 ! 0 2 5 13 + integer, parameter :: ichoicem=5 ! 0 2 5 13 + !integer, parameter :: ichoicem=13 ! 0 2 5 13 integer, parameter :: ichoice_s=3 ! 0 1 2 3 logical, intent(in) :: do_cap_suppress @@ -92,7 +92,7 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& integer :: ishallow_g3 ! depend on imfshalcnv !------------------------------------------------------------- integer :: its,ite, jts,jte, kts,kte - integer, intent(in ) :: im,km,ntracer + integer, intent(in ) :: im,km,ntracer,gf_aeroic logical, intent(in ) :: flag_init, flag_restart logical, intent(in ) :: flag_for_scnv_generic_tend,flag_for_dcnv_generic_tend real (kind=kind_phys), intent(in) :: g,cp,xlv,r_v @@ -106,7 +106,8 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& !$acc declare copyin(dtidx) real(kind=kind_phys), dimension( : , : ), intent(in ) :: forcet,forceqv_spechum,w,phil real(kind=kind_phys), dimension( : , : ), intent(inout ) :: t,us,vs - real(kind=kind_phys), dimension( : , : ), intent(inout ) :: qci_conv + real(kind=kind_phys), dimension( : , : ), intent(inout ) :: qci_conv,qci_conv_accum,qci_conv_timeave + real(kind=kind_phys), dimension( : , : ), intent(inout ) :: ud_mf_accum,ud_mf_timeave real(kind=kind_phys), dimension( : , : ), intent(out ) :: cnvw_moist,cnvc real(kind=kind_phys), dimension( : , : ), intent(inout ) :: cliw, clcw !$acc declare copyin(forcet,forceqv_spechum,w,phil) @@ -140,6 +141,7 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& real(kind=kind_phys), dimension (:,:), intent(inout) :: qv_spechum real(kind=kind_phys), dimension (:,:), intent(in) :: aerodp real(kind=kind_phys), dimension (:), intent(inout) :: aod_gf + real(kind=kind_phys), dimension (:), intent(in) :: aod_da !$acc declare copyin(qv2di_spechum) copy(qv_spechum,aod_gf) ! Local water vapor mixing ratios and cloud water mixing ratios real(kind=kind_phys), dimension (im,km) :: qv2di, qv, forceqv, cnvw @@ -147,9 +149,9 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& ! real(kind=kind_phys), dimension(:),intent(in) :: garea !$acc declare copyin(garea) - real(kind=kind_phys), intent(in ) :: dt + real(kind=kind_phys), intent(in ) :: dt,fhswr - integer, intent(in ) :: imfshalcnv + integer, intent(in ) :: imfshalcnv,kdt,nsswr integer, dimension(:), intent(inout) :: cactiv,cactiv_m !$acc declare copy(cactiv,cactiv_m) @@ -306,6 +308,9 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& forceqv = forceqv_spechum/(1.0_kind_phys-qv2di_spechum) ! current state (updated by preceeding physics) qv = qv_spechum/(1.0_kind_phys-qv_spechum) + + clcw = clcw/(1.0_kind_phys-qv_spechum) + cliw = cliw/(1.0_kind_phys-qv_spechum) ! ! ! these should be coming in from outside @@ -375,6 +380,13 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& dd_mf(:,:) =0. dt_mf(:,:) =0. tau_ecmwf(:)=0. + if (flag_init .and. .not. flag_restart) then + ud_mf_accum(:,:)=0. + ud_mf_timeave(:,:)=0. + qci_conv_accum(:,:)=0. + qci_conv_timeave(:,:)=0. + endif + !$acc end kernels ! j=1 @@ -409,18 +421,36 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& ccn_m(i) = 0. ! set aod and ccn - if (flag_init .and. .not.flag_restart) then - aod_gf(i)=aerodp(i,1) - else - if (imid_gf .eq. 0) then - if((cactiv(i).eq.0) .and. (cactiv_m(i).eq.0))then - if(aerodp(i,1)>aod_gf(i)) aod_gf(i)=aod_gf(i)+((aerodp(i,1)-aod_gf(i))*(dt/(aodreturn*60))) - if(aod_gf(i)>aerodp(i,1)) aod_gf(i)=aerodp(i,1) + if (gf_aeroic .eq. 1) then + if (flag_init .and. .not.flag_restart) then + aod_gf(i)=aerodp(i,1) + else + if (imid_gf .eq. 1) then + if((cactiv(i).eq.0) .and. (cactiv_m(i).eq.0))then + if(aerodp(i,1)>aod_gf(i)) aod_gf(i)=aod_gf(i)+((aerodp(i,1)-aod_gf(i))*(dt/(aodreturn*60))) + if(aod_gf(i)>aerodp(i,1)) aod_gf(i)=aerodp(i,1) + endif + else + if(cactiv(i).eq.0)then + if(aerodp(i,1)>aod_gf(i)) aod_gf(i)=aod_gf(i)+((aerodp(i,1)-aod_gf(i))*(dt/(aodreturn*60))) + if(aod_gf(i)>aerodp(i,1)) aod_gf(i)=aerodp(i,1) + endif endif + endif + elseif (gf_aeroic .eq. 2) then + if (flag_init .and. .not.flag_restart) then + aod_gf(i)=aod_da(i) else - if(cactiv(i).eq.0)then - if(aerodp(i,1)>aod_gf(i)) aod_gf(i)=aod_gf(i)+((aerodp(i,1)-aod_gf(i))*(dt/(aodreturn*60))) - if(aod_gf(i)>aerodp(i,1)) aod_gf(i)=aerodp(i,1) + if (imid_gf .eq. 1) then + if((cactiv(i).eq.0) .and. (cactiv_m(i).eq.0))then + if(aod_da(i)>aod_gf(i)) aod_gf(i)=aod_gf(i)+((aod_da(i)-aod_gf(i))*(dt/(aodreturn*60))) + if(aod_gf(i)>aod_da(i)) aod_gf(i)=aod_da(i) + endif + else + if(cactiv(i).eq.0)then + if(aod_da(i)>aod_gf(i)) aod_gf(i)=aod_gf(i)+((aod_da(i)-aod_gf(i))*(dt/(aodreturn*60))) + if(aod_gf(i)>aod_da(i)) aod_gf(i)=aod_da(i) + endif endif endif endif @@ -878,9 +908,9 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& us(i,k)=us(i,k)+outu(i,k)*cuten(i)*dt +outum(i,k)*cutenm(i)*dt +outus(i,k)*cutens(i)*dt vs(i,k)=vs(i,k)+outv(i,k)*cuten(i)*dt +outvm(i,k)*cutenm(i)*dt +outvs(i,k)*cutens(i)*dt - gdc(i,k,1)= max(0.,tun_rad_shall(i)*cupclws(i,k)*cutens(i)) ! my mod + gdc(i,k,1)= max(0.,tun_rad_shall(i)*cupclws(i,k)*cutens(i)) ! my mod !gdc2(i,k,1)=max(0.,tun_rad_mid(i)*cupclwm(i,k)*cutenm(i)+tun_rad_deep(i)*cupclw(i,k)*cuten(i)+tun_rad_shall(i)*cupclws(i,k)*cutens(i)) - gdc2(i,k,1)=cnvw(i,k) + gdc2(i,k,1) = max(0., tun_rad_mid(i)*frhm(i)*cupclwm(i,k)*cutenm(i)*xmbm(i) + tun_rad_deep(i)*frhd(i)*cupclw(i,k)*cuten(i)*xmb(i) + tun_rad_shall(i)*cupclws(i,k)*cutens(i)*xmbs(i)) qci_conv(i,k)=gdc2(i,k,1) gdc(i,k,2)=(outt(i,k))*86400. gdc(i,k,3)=(outtm(i,k))*86400. @@ -979,6 +1009,27 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& !$acc end parallel !$acc kernels do i=its,itf + do k=kts,ktf + if (flag_init .and. .not. flag_restart) then + !write(0,*)'init',kdt + qci_conv_accum(i,k)=gdc2(i,k,1)/(1.0_kind_phys+qv(i,k)) + qci_conv_timeave(i,k)=gdc2(i,k,1)/(1.0_kind_phys+qv(i,k)) + ud_mf_accum(i,k)=ud_mf(i,k) + ud_mf_timeave(i,k)=ud_mf(i,k) + else if (MOD(kdt+1,nsswr) .eq. 0) then + qci_conv_timeave(i,k) = (qci_conv_accum(i,k) + (gdc2(i,k,1)/(1.0_kind_phys+qv(i,k))))/fhswr + qci_conv_accum(i,k)= 0. + ud_mf_timeave(i,k) = (ud_mf_accum(i,k) + ud_mf(i,k))/fhswr + ud_mf_accum(i,k)= 0. + !write(0,*)'recalc',kdt,ud_mf_accum(i,k),ud_mf_timeave(i,k),ud_mf(i,k) + else + qci_conv_accum(i,k) = qci_conv_accum(i,k) + (gdc2(i,k,1)/(1.0_kind_phys+qv(i,k))) + qci_conv_timeave(i,k) = qci_conv_timeave(i,k) + ud_mf_accum(i,k) = ud_mf_accum(i,k) + ud_mf(i,k) + ud_mf_timeave(i,k) = ud_mf_timeave(i,k) + !write(0,*)'hold',kdt,ud_mf_accum(i,k),ud_mf_timeave(i,k),ud_mf(i,k) + endif + enddo if(pret(i).gt.0.)then cactiv(i)=1 else @@ -1001,10 +1052,13 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& ! Convert ccn back to aod aod_gf(i)=0.0027*(ccn_gf(i)**0.64) - if(aod_gf(i)<0.007)then - aod_gf(i)=0.007 - elseif(aod_gf(i)>aerodp(i,1))then - aod_gf(i)=aerodp(i,1) + + if(aod_gf(i)<0.007) aod_gf(i)=0.007 + + if (gf_aeroic .eq. 1) then + if(aod_gf(i)>aerodp(i,1)) aod_gf(i)=aerodp(i,1) + elseif (gf_aeroic .eq. 2) then + if(aod_gf(i)>aod_da(i)) aod_gf(i)=aod_da(i) endif enddo !$acc end kernels @@ -1015,6 +1069,9 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& !$acc kernels qv_spechum = qv/(1.0_kind_phys+qv) cnvw_moist = cnvw/(1.0_kind_phys+qv) + + clcw = clcw/(1.0_kind_phys+qv) + cliw = cliw/(1.0_kind_phys+qv) !$acc end kernels ! ! Diagnostic tendency updates diff --git a/physics/cu_gf_driver.meta b/physics/cu_gf_driver.meta index 91ee59384..7d8d8e1e7 100644 --- a/physics/cu_gf_driver.meta +++ b/physics/cu_gf_driver.meta @@ -106,6 +106,28 @@ type = real kind = kind_phys intent = in +[kdt] + standard_name = index_of_timestep + long_name = current forecast iteration + units = index + dimensions = () + type = integer + intent = in +[nsswr] + standard_name = number_of_timesteps_between_shortwave_radiation_calls + long_name = number of timesteps between shortwave radiation calls + units = + dimensions = () + type = integer + intent = in +[fhswr] + standard_name = period_of_shortwave_radiation_calls + long_name = frequency for shortwave radiation + units = s + dimensions = () + type = real + kind = kind_phys + intent = in [flag_init] standard_name = flag_for_first_timestep long_name = flag signaling first time step for time integration loop @@ -322,6 +344,13 @@ type = real kind = kind_phys intent = in +[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 + intent = in [aerodp] standard_name = atmosphere_optical_thickness_due_to_ambient_aerosol_particles long_name = vertical integrated optical depth for various aerosol species @@ -338,6 +367,14 @@ type = real kind = kind_phys intent = inout +[aod_da] + standard_name = assimilated_aod_input + long_name = assimilated aod input + units = none + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in [cliw] standard_name = ice_water_mixing_ratio_convective_transport_tracer long_name = ratio of mass of ice water to mass of dry air plus vapor (without condensates) in the convectively transported tracer array @@ -370,6 +407,22 @@ type = real kind = kind_phys intent = out +[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 + intent = inout +[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 + intent = inout [dd_mf] standard_name = instantaneous_atmosphere_downdraft_convective_mass_flux long_name = (downdraft mass flux) * delt @@ -516,6 +569,22 @@ type = real kind = kind_phys intent = inout +[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 + intent = inout +[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 + intent = inout [fhour] standard_name = forecast_time long_name = current forecast time diff --git a/physics/sgscloud_radpre.F90 b/physics/sgscloud_radpre.F90 index 160039955..fea97a4d2 100644 --- a/physics/sgscloud_radpre.F90 +++ b/physics/sgscloud_radpre.F90 @@ -47,7 +47,7 @@ end subroutine sgscloud_radpre_finalize !>\section sgscloud_radpre GSD SGS Scheme General Algorithm !> @{ subroutine sgscloud_radpre_run( & - im,dt,levs, & + im,dt,fhswr,levs, & flag_init,flag_restart, & con_g, con_pi, eps, epsm1, & r_v, cpv, rcp, & @@ -56,6 +56,8 @@ subroutine sgscloud_radpre_run( & qc, qi, qv, T3D, P3D, exner, & qr, qs, qg, & qci_conv,ud_mf, & + qci_conv_timeave, & + ud_mf_timeave, & imfdeepcnv, imfdeepcnv_gf, & qc_save, qi_save, qs_save, & qc_bl,qi_bl,cldfra_bl, & @@ -79,7 +81,7 @@ subroutine sgscloud_radpre_run( & real(kind=kind_phys), intent(in) :: con_g, con_pi, eps, epsm1 real(kind=kind_phys), intent(in) :: r_v, cpv, rcp real(kind=kind_phys), intent(in) :: xlv, xlf, cp - real(kind=kind_phys), intent(in) :: dt + real(kind=kind_phys), intent(in) :: dt,fhswr real :: xls, xlvcp, xlscp !derived below real(kind=kind_phys) :: gfac integer, intent(in) :: im, levs, imfdeepcnv, imfdeepcnv_gf, & @@ -91,6 +93,7 @@ subroutine sgscloud_radpre_run( & ! qci_conv only allocated if GF is used real(kind=kind_phys), dimension(:,:), intent(inout) :: qci_conv real(kind=kind_phys), dimension(:,:), intent(in) :: ud_mf + real(kind=kind_phys), dimension(:,:), intent(in) :: ud_mf_timeave, qci_conv_timeave real(kind=kind_phys), dimension(:,:), intent(in) :: T3D,delp real(kind=kind_phys), dimension(:,:), intent(in) :: qv,P3D,exner real(kind=kind_phys), dimension(:,:), intent(inout) :: & @@ -283,16 +286,16 @@ subroutine sgscloud_radpre_run( & do k = 1, levs do i = 1, im !if ( qci_conv(i,k) > 0. .AND. (qi(i,k) < 1E-7 .AND. qc(i,k) < 1E-7 ) ) then - if ( qci_conv(i,k) > 0. ) then + if ( qci_conv_timeave(i,k) > 0. ) then Tk = T3D(i,k) Tc = Tk - 273.15 !Partition the convective clouds into water & frozen species liqfrac = min(1., max(0., (Tk-244.)/29.)) - !qc(i,k) = qc(i,k)+qci_conv(i,k)*liqfrac + qc(i,k) = qc(i,k)+qci_conv_timeave(i,k)*fhswr*liqfrac !split ice & snow 50-50% - !qi(i,k) = qi(i,k)+0.5*qci_conv(i,k)*(1. - liqfrac) - !qs(i,k) = qs(i,k)+0.5*qci_conv(i,k)*(1. - liqfrac) + qi(i,k) = qi(i,k)+0.5*qci_conv_timeave(i,k)*fhswr*(1. - liqfrac) + qs(i,k) = qs(i,k)+0.5*qci_conv_timeave(i,k)*fhswr*(1. - liqfrac) !eff radius cloud water (microns) if (nint(slmsk(i)) == 1) then !land @@ -305,7 +308,7 @@ subroutine sgscloud_radpre_run( & if(qi(i,k)>1.e-8)clouds5(i,k)=max( 173.45 + 2.14*Tc , 20.) if(qs(i,k)>1.e-8)clouds9(i,k)=max(2.0*(173.45 + 2.14*Tc), 50.) - if ( conv_cf_opt .eq. 0 ) then + if ( conv_cf_opt .eq. 0 .and. qci_conv_timeave(i,k) .gt. 0. ) then !print *,'Chab-Bechtold cloud fraction used' ! clouds1(i,k) = cldfra_bl(i,k) @@ -328,12 +331,13 @@ subroutine sgscloud_radpre_run( & else ! scaling function (CB2005) f = 1.0 endif - sigq = 1.5E-3 * ud_mf(i,k)/dt * f + sigq = ud_mf_timeave(i,k)/dt * f + !sigq = 1.5E-3 * ud_mf(i,k)/dt * f !sigq = 3.E-3 * ud_mf(i,k)/dt * f sigq = SQRT(sigq**2 + 1e-10) ! combined conv + background components qmq = a * (qt - qsat) ! saturation deficit/excess; ! the numerator of Q1 - cb_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.01),0.99) + cb_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.0),0.99) if (do_mynnedmf .and. qmq .ge. 0.0) then ! leverage C-B stratus clouds from MYNN in saturated conditions clouds1(i,k) = 0.5*(clouds1(i,k) + cb_cf) diff --git a/physics/sgscloud_radpre.meta b/physics/sgscloud_radpre.meta index 28c1b7da6..e8f234791 100644 --- a/physics/sgscloud_radpre.meta +++ b/physics/sgscloud_radpre.meta @@ -29,6 +29,14 @@ dimensions = () type = integer intent = in +[fhswr] + standard_name = period_of_shortwave_radiation_calls + long_name = frequency for shortwave radiation + units = s + dimensions = () + type = real + kind = kind_phys + intent = in [flag_init] standard_name = flag_for_first_timestep long_name = flag signaling first time step for time integration loop @@ -210,6 +218,14 @@ type = real kind = kind_phys intent = in +[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 + intent = in [qci_conv] standard_name = convective_cloud_condesate_after_rainout long_name = convective cloud condesate after rainout @@ -218,6 +234,14 @@ type = real kind = kind_phys intent = inout +[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 + intent = in [imfdeepcnv] standard_name = control_for_deep_convection_scheme long_name = flag for mass-flux deep convection scheme