diff --git a/physics/GFS_cloud_diagnostics.F90 b/physics/GFS_cloud_diagnostics.F90 index 215143bb2..5dd757a43 100644 --- a/physics/GFS_cloud_diagnostics.F90 +++ b/physics/GFS_cloud_diagnostics.F90 @@ -39,43 +39,51 @@ end subroutine GFS_cloud_diagnostics_init !! \section arg_table_GFS_cloud_diagnostics_run !! \htmlinclude GFS_cloud_diagnostics_run.html !! - subroutine GFS_cloud_diagnostics_run(nCol, nLev, lsswr, lslwr, lat, de_lgth, p_lay, & + subroutine GFS_cloud_diagnostics_run(nCol, nLev, iovr_rand, iovr_maxrand, iovr_max, & + iovr_dcorr, iovr_exp, iovr_exprand, lsswr, lslwr, lat, de_lgth, p_lay, & cld_frac, p_lev, deltaZ, cloud_overlap_param, precip_overlap_param, con_pi, & mtopa, mbota, cldsa, errmsg, errflg) implicit none ! Inputs - integer, intent(in) :: & - nCol, & ! Number of horizontal grid-points - nLev ! Number of vertical-layers + integer, intent(in) :: & + nCol, & ! Number of horizontal grid-points + nLev ! Number of vertical-layers + integer, intent(in) :: & + iovr_rand, & ! Flag for random cloud overlap method + iovr_maxrand, & ! Flag for maximum-random cloud overlap method + iovr_max, & ! Flag for maximum cloud overlap method + iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method + iovr_exp, & ! Flag for exponential cloud overlap method + iovr_exprand ! Flag for exponential-random cloud overlap method logical, intent(in) :: & - lsswr, & ! Call SW radiation? - lslwr ! Call LW radiation - real(kind_phys), intent(in) :: & - con_pi ! Physical constant: pi - real(kind_phys), dimension(:), intent(in) :: & - lat, & ! Latitude - de_lgth ! Decorrelation length + lsswr, & ! Call SW radiation? + lslwr ! Call LW radiation + real(kind_phys), intent(in) :: & + con_pi ! Physical constant: pi + real(kind_phys), dimension(:), intent(in) :: & + lat, & ! Latitude + de_lgth ! Decorrelation length real(kind_phys), dimension(:,:), intent(in) :: & - p_lay, & ! Pressure at model-layer - cld_frac ! Total cloud fraction + p_lay, & ! Pressure at model-layer + cld_frac ! Total cloud fraction real(kind_phys), dimension(:,:), intent(in) :: & - p_lev ! Pressure at model interfaces + p_lev ! Pressure at model interfaces real(kind_phys), dimension(:,:), intent(in) :: & - deltaZ, & ! Layer thickness (km) - cloud_overlap_param, & ! Cloud-overlap parameter - precip_overlap_param ! Precipitation overlap parameter + deltaZ, & ! Layer thickness (m) + cloud_overlap_param, & ! Cloud-overlap parameter + precip_overlap_param ! Precipitation overlap parameter ! Outputs - character(len=*), intent(out) :: & - errmsg ! Error message - integer, intent(out) :: & - errflg ! Error flag - integer,dimension(:,:),intent(out) :: & - mbota, & ! Vertical indices for cloud tops - mtopa ! Vertical indices for cloud bases - real(kind_phys), dimension(:,:), intent(out) :: & - cldsa ! Fraction of clouds for low, middle, high, total and BL + character(len=*), intent(out) :: & + errmsg ! Error message + integer, intent(out) :: & + errflg ! Error flag + integer,dimension(:,:),intent(out) :: & + mbota, & ! Vertical indices for cloud tops + mtopa ! Vertical indices for cloud bases + real(kind_phys),dimension(:,:), intent(out) :: & + cldsa ! Fraction of clouds for low, middle, high, total and BL ! Local variables integer i,id,iCol,iLay,icld @@ -105,8 +113,9 @@ subroutine GFS_cloud_diagnostics_run(nCol, nLev, lsswr, lslwr, lat, de_lgth, p_l ! layer indices for low, mid, and high clouds. The three cloud domain boundaries are ! defined by ptopc. The cloud overlapping method is defined by control flag 'iovr', which may ! be different for lw and sw radiation programs. - call gethml(p_lay/100., ptop1, cld_frac, cldcnv, deltaZ, de_lgth, cloud_overlap_param,& - nCol, nLev, cldsa, mtopa, mbota) + call gethml(p_lay*0.01, ptop1, cld_frac, cldcnv, deltaZ, de_lgth, cloud_overlap_param,& + nCol, nLev, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, iovr_exp, & + iovr_exprand, cldsa, mtopa, mbota) end subroutine GFS_cloud_diagnostics_run @@ -116,76 +125,6 @@ subroutine GFS_cloud_diagnostics_finalize() end subroutine GFS_cloud_diagnostics_finalize ! ###################################################################################### - ! Initialization routine for High/Mid/Low cloud diagnostics. + ! Subroutine hml_cloud_diagnostics_initialize is removed (refer to GFS_rrtmgp_setup.F90) ! ###################################################################################### - subroutine hml_cloud_diagnostics_initialize(imp_physics, imp_physics_fer_hires, & - imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & - imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, imp_physics_mg, nLev, & - mpi_rank, sigmainit, errflg) - implicit none - ! Inputs - integer, intent(in) :: & - imp_physics, & ! Flag for MP scheme - imp_physics_fer_hires, & ! Flag for fer-hires scheme - imp_physics_gfdl, & ! Flag for gfdl scheme - imp_physics_thompson, & ! Flag for thompsonscheme - imp_physics_wsm6, & ! Flag for wsm6 scheme - imp_physics_zhao_carr, & ! Flag for zhao-carr scheme - imp_physics_zhao_carr_pdf, & ! Flag for zhao-carr+PDF scheme - imp_physics_mg ! Flag for MG scheme - integer, intent(in) :: & - nLev, & ! Number of vertical-layers - mpi_rank - real(kind_phys), dimension(:), intent(in) :: & - sigmainit - ! Outputs - integer, intent(out) :: & - errflg - - ! Local variables - integer :: iLay, kl - - ! Initialize error flag - errflg = 0 - - if (mpi_rank == 0) print *, VTAGCLD !print out version tag - - if ( icldflg == 0 ) then - print *,' - Diagnostic Cloud Method has been discontinued' - errflg = 1 - else - if (mpi_rank == 0) then - print *,' - Using Prognostic Cloud Method' - if (imp_physics == imp_physics_zhao_carr) then - print *,' --- Zhao/Carr/Sundqvist microphysics' - elseif (imp_physics == imp_physics_zhao_carr_pdf) then - print *,' --- zhao/carr/sundqvist + pdf cloud' - elseif (imp_physics == imp_physics_gfdl) then - print *,' --- GFDL Lin cloud microphysics' - elseif (imp_physics == imp_physics_thompson) then - print *,' --- Thompson cloud microphysics' - elseif (imp_physics == imp_physics_wsm6) then - print *,' --- WSM6 cloud microphysics' - elseif (imp_physics == imp_physics_mg) then - print *,' --- MG cloud microphysics' - elseif (imp_physics == imp_physics_fer_hires) then - print *,' --- Ferrier-Aligo cloud microphysics' - else - print *,' !!! ERROR in cloud microphysc specification!!!', & - ' imp_physics (NP3D) =',imp_physics - errflg = 1 - endif - endif - endif - - ! Compute the top of BL cld (llyr), which is the topmost non cld(low) layer for - ! stratiform (at or above lowest 0.1 of the atmosphere). - lab_do_k0 : do iLay = nLev, 2, -1 - kl = iLay - if (sigmainit(iLay) < 0.9e0) exit lab_do_k0 - enddo lab_do_k0 - llyr = kl - - return - end subroutine hml_cloud_diagnostics_initialize end module GFS_cloud_diagnostics diff --git a/physics/GFS_cloud_diagnostics.meta b/physics/GFS_cloud_diagnostics.meta index aab5387d0..dd88bbc46 100644 --- a/physics/GFS_cloud_diagnostics.meta +++ b/physics/GFS_cloud_diagnostics.meta @@ -20,6 +20,48 @@ dimensions = () type = integer intent = in +[iovr_rand] + standard_name = flag_for_random_cloud_overlap_method + long_name = choice of random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_maxrand] + standard_name = flag_for_maximum_random_cloud_overlap_method + long_name = choice of maximum-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_max] + standard_name = flag_for_maximum_cloud_overlap_method + long_name = choice of maximum cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_dcorr] + standard_name = flag_for_decorrelation_length_cloud_overlap_method + long_name = choice of decorrelation-length cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exp] + standard_name = flag_for_exponential_cloud_overlap_method + long_name = choice of exponential cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exprand] + standard_name = flag_for_exponential_random_cloud_overlap_method + long_name = choice of exponential-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in [lsswr] standard_name = flag_for_calling_shortwave_radiation long_name = logical flags for sw radiation calls diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index 89c9cec7f..46649f7cc 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -18,13 +18,15 @@ end subroutine GFS_rrtmg_pre_init ! in the CCPP version - they are defined in the interstitial_create routine subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & imfdeepcnv, imfdeepcnv_gf, me, ncnd, ntrac, num_p3d, npdf3d, ncnvcld3d,& - ntqv, ntcw,ntiw, ntlnc, ntinc, ntrnc, ntsnc, ntccn, & + ntqv, ntcw,ntiw, ntlnc, ntinc, ntrnc, ntsnc, ntccn, & ntrw, ntsw, ntgl, nthl, ntwa, ntoz, & ntclamt, nleffr, nieffr, nseffr, lndp_type, kdt, & imp_physics,imp_physics_nssl, nssl_ccn_on, nssl_invertccn, & imp_physics_thompson, imp_physics_gfdl, imp_physics_zhao_carr, & imp_physics_zhao_carr_pdf, imp_physics_mg, imp_physics_wsm6, & - imp_physics_fer_hires, julian, yearlen, lndp_var_list, lsswr, lslwr, & + imp_physics_fer_hires, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, & + iovr_exp, iovr_exprand, idcor_con, idcor_hogan, idcor_oreopoulos, & + julian, yearlen, lndp_var_list, lsswr, lslwr, & ltaerosol, lgfdlmprad, uni_cld, effr_in, do_mynnedmf, lmfshal, & lmfdeep2, fhswr, fhlwr, solhr, sup, con_eps, epsm1, fvirt, & rog, rocp, con_rd, xlat_d, xlat, xlon, coslat, sinlat, tsfc, slmsk, & @@ -53,12 +55,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & use module_radiation_aerosols, only: NF_AESW, NF_AELW, setaer, & ! aer_init, aer_update, & NSPC1 use module_radiation_clouds, only: NF_CLDS, & ! cld_init - & progcld1, progcld3, & - & progcld2, & - & progcld4, progcld5, & - & progcld6, & - & progcld_thompson, & - & progclduni, & + & radiation_clouds_prop, & & cal_cldfra3, & & find_cloudLayers, & & adjust_cloudIce, & @@ -102,6 +99,17 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & imp_physics_fer_hires, & yearlen, icloud + integer, intent(in) :: & + iovr_rand, & ! Flag for random cloud overlap method + iovr_maxrand, & ! Flag for maximum-random cloud overlap method + iovr_max, & ! Flag for maximum cloud overlap method + iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method + iovr_exp, & ! Flag for exponential cloud overlap method + iovr_exprand, & ! Flag for exponential-random cloud overlap method + idcor_con, & + idcor_hogan, & + idcor_oreopoulos + character(len=3), dimension(:), intent(in) :: lndp_var_list logical, intent(in) :: lsswr, lslwr, ltaerosol, lgfdlmprad, & @@ -109,8 +117,8 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & lmfshal, lmfdeep2, pert_clds logical, intent(in) :: nssl_ccn_on, nssl_invertccn - integer, intent(in) :: spp_rad - real(kind_phys), intent(in) :: spp_wts_rad(:,:) + integer, intent(in) :: spp_rad + real(kind_phys), intent(in) :: spp_wts_rad(:,:) real(kind=kind_phys), intent(in) :: fhswr, fhlwr, solhr, sup, julian, sppt_amp real(kind=kind_phys), intent(in) :: con_eps, epsm1, fvirt, rog, rocp, con_rd @@ -214,7 +222,9 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & real(kind=kind_phys), dimension(im,lm+LTP,min(4,ncnd)) :: ccnd real(kind=kind_phys), dimension(im,lm+LTP,2:ntrac) :: tracer1 - real(kind=kind_phys), dimension(im,lm+LTP,NF_CLDS) :: clouds + real(kind=kind_phys), dimension(im,lm+LTP) :: & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & + & cld_rwp, cld_rerain, cld_swp, cld_resnow real(kind=kind_phys), dimension(im,lm+LTP,NF_VGAS) :: gasvmr real(kind=kind_phys), dimension(im,lm+LTP,NBDSW,NF_AESW) :: faersw real(kind=kind_phys), dimension(im,lm+LTP,NBDLW,NF_AELW) :: faerlw @@ -621,9 +631,9 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & !! (clouds,cldsa,mtopa,mbota) !!\n for prognostic cloud: !! - For Zhao/Moorthi's prognostic cloud scheme, -!! call module_radiation_clouds::progcld1() +!! call module_radiation_clouds::progcld_zhao_carr() !! - For Zhao/Moorthi's prognostic cloud+pdfcld, -!! call module_radiation_clouds::progcld3() +!! call module_radiation_clouds::progcld_zhao_carr_pdf() !! call module_radiation_clouds::progclduni() for unified cloud and ncnd>=2 ! --- ... obtain cloud information for radiation calculations @@ -652,7 +662,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & ccnd(i,k,4) = tracer1(i,k,ntsw) ! snow water enddo enddo - elseif ( ncnd == 5 .or. ncnd == 6) then ! GFDL MP, Thompson, MG3, NSSL + elseif (ncnd == 5 .or. ncnd == 6) then ! GFDL MP, Thompson, MG3, NSSL do k=1,LMK do i=1,IM ccnd(i,k,1) = tracer1(i,k,ntcw) ! liquid water @@ -822,8 +832,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & ! not used yet -- effr_in should always be true for now endif - elseif (imp_physics == imp_physics_thompson) then ! Thompson MP - + elseif (imp_physics == imp_physics_thompson) then ! Thompson MP ! ! Compute effective radii for QC, QI, QS with (GF, MYNN) or without (all others) sub-grid clouds ! @@ -912,170 +921,28 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & ccnd(1:IM,1:LMK,1) = ccnd(1:IM,1:LMK,1) + cnvw(1:IM,1:LMK) endif - if (imp_physics == imp_physics_zhao_carr .or. imp_physics == imp_physics_mg) then ! zhao/moorthi's prognostic cloud scheme - ! or unified cloud and/or with MG microphysics - - if (uni_cld .and. ncndl >= 2) then - call progclduni (plyr, plvl, tlyr, tvly, ccnd, ncndl, & ! --- inputs - xlat, xlon, slmsk, dz, delp, & - IM, LMK, LMP, cldcov, & - effrl, effri, effrr, effrs, effr_in, & - dzb, xlat_d, julian, yearlen, & - clouds, cldsa, mtopa, mbota, de_lgth, alpha) ! --- outputs - else - call progcld1 (plyr ,plvl, tlyr, tvly, qlyr, qstl, rhly, & ! --- inputs - ccnd(1:IM,1:LMK,1), xlat, xlon, slmsk, dz, & - delp, IM, LMK, LMP, uni_cld, lmfshal, lmfdeep2,& - cldcov, effrl, effri, effrr, effrs, effr_in, & - dzb, xlat_d, julian, yearlen, & - clouds, cldsa, mtopa, mbota, de_lgth, alpha) ! --- outputs - endif - - elseif(imp_physics == imp_physics_zhao_carr_pdf) then ! zhao/moorthi's prognostic cloud+pdfcld - - call progcld3 (plyr, plvl, tlyr, tvly, qlyr, qstl, rhly, & ! --- inputs - ccnd(1:IM,1:LMK,1), cnvw, cnvc, xlat, xlon, & - slmsk, dz, delp, im, lmk, lmp, deltaq, sup, kdt, & - me, dzb, xlat_d, julian, yearlen, & - clouds, cldsa, mtopa, mbota, de_lgth, alpha) ! --- outputs - - elseif (imp_physics == imp_physics_gfdl) then ! GFDL cloud scheme - - if (.not. lgfdlmprad) then - call progcld4 (plyr, plvl, tlyr, tvly, qlyr, qstl, rhly, & ! --- inputs - ccnd(1:IM,1:LMK,1), cnvw, cnvc, xlat, xlon, & - slmsk, cldcov, dz, delp, im, lmk, lmp, & - dzb, xlat_d, julian, yearlen, & - clouds, cldsa, mtopa, mbota, de_lgth, alpha) ! --- outputs - else - - call progclduni (plyr, plvl, tlyr, tvly, ccnd, ncndl, xlat, & ! --- inputs - xlon, slmsk, dz,delp, IM, LMK, LMP, cldcov, & - effrl, effri, effrr, effrs, effr_in, & - dzb, xlat_d, julian, yearlen, & - clouds, cldsa, mtopa, mbota, de_lgth, alpha) ! --- outputs -! call progcld4o (plyr, plvl, tlyr, tvly, qlyr, qstl, rhly, & ! --- inputs -! tracer1, xlat, xlon, slmsk, dz, delp, & -! ntrac-1, ntcw-1,ntiw-1,ntrw-1, & -! ntsw-1,ntgl-1,ntclamt-1, & -! im, lmk, lmp, & -! dzb, xlat_d, julian, yearlen, & -! clouds, cldsa, mtopa, mbota, de_lgth, alpha) ! --- outputs - endif - - elseif(imp_physics == imp_physics_fer_hires) then - if (kdt == 1) then - effrl_inout(:,:) = 10. - effri_inout(:,:) = 50. - effrs_inout(:,:) = 250. - endif - - call progcld5 (plyr,plvl,tlyr,tvly,qlyr,qstl,rhly,tracer1, & ! --- inputs - xlat,xlon,slmsk,dz,delp, & - ntrac-1, ntcw-1,ntiw-1,ntrw-1, & - im, lmk, lmp, icloud, uni_cld, lmfshal, lmfdeep2, & - cldcov(:,1:LMK),effrl_inout(:,:), & - effri_inout(:,:), effrs_inout(:,:), & - dzb, xlat_d, julian, yearlen, & - clouds,cldsa,mtopa,mbota, de_lgth, alpha) ! --- outputs - - elseif ( imp_physics == imp_physics_nssl ) then ! NSSL MP - - if(do_mynnedmf .or. imfdeepcnv == imfdeepcnv_gf ) then ! MYNN PBL or GF conv - !-- MYNN PBL or convective GF - !-- use cloud fractions with SGS clouds - do k=1,lmk - do i=1,im - clouds(i,k,1) = clouds1(i,k) - enddo - enddo - - ! --- use clduni with the NSSL microphysics. - ! --- make sure that effr_in=.true. in the input.nml! - call progclduni (plyr, plvl, tlyr, tvly, ccnd, ncndl, & ! --- inputs - xlat, xlon, slmsk, dz, delp, IM, LMK, LMP, & - clouds(:,1:LMK,1), & - effrl, effri, effrr, effrs, effr_in , & - dzb, xlat_d, julian, yearlen, & - clouds, cldsa, mtopa, mbota, de_lgth, alpha) ! --- outputs - - else - ! MYNN PBL or GF convective are not used - call progcld6 (plyr,plvl,tlyr,qlyr,qstl,rhly,tracer1, & ! --- inputs - xlat,xlon,slmsk,dz,delp, & - ntrac-1, ntcw-1,ntiw-1,ntrw-1, & - ntsw-1,ntgl-1, & - im, lmk, lmp, uni_cld, lmfshal, lmfdeep2, & - cldcov(:,1:LMK), cnvw, effrl_inout, & - effri_inout, effrs_inout, & - lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - dzb, xlat_d, julian, yearlen, & - clouds, cldsa, mtopa ,mbota, de_lgth, alpha) ! --- outputs - endif ! MYNN PBL or GF - - - elseif(imp_physics == imp_physics_thompson) then ! Thompson MP - - if(do_mynnedmf .or. imfdeepcnv == imfdeepcnv_gf ) then ! MYNN PBL or GF conv - - if (icloud == 3) then - call progcld_thompson (plyr,plvl,tlyr,qlyr,qstl,rhly, & ! --- inputs - tracer1,xlat,xlon,slmsk,dz,delp, & - ntrac-1, ntcw-1,ntiw-1,ntrw-1, & - ntsw-1,ntgl-1, & - im, lm, lmp, uni_cld, lmfshal, lmfdeep2, & - cldcov(:,1:LM), effrl, effri, effrs, & - lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - dzb, xlat_d, julian, yearlen, gridkm, & - clouds, cldsa, mtopa ,mbota, de_lgth, alpha) ! --- outputs - else - - !-- MYNN PBL or convective GF - !-- use cloud fractions with SGS clouds - do k=1,lmk - do i=1,im - clouds(i,k,1) = clouds1(i,k) - enddo - enddo - - ! --- use clduni as with the GFDL microphysics. - ! --- make sure that effr_in=.true. in the input.nml! - call progclduni (plyr, plvl, tlyr, tvly, ccnd, ncndl, & ! --- inputs - xlat, xlon, slmsk, dz, delp, IM, LMK, LMP, & - clouds(:,1:LMK,1), & - effrl, effri, effrr, effrs, effr_in , & - dzb, xlat_d, julian, yearlen, & - clouds, cldsa, mtopa, mbota, de_lgth, alpha) ! --- outputs - endif - - else - ! MYNN PBL or GF convective are not used - - if (icloud == 3) then - call progcld_thompson (plyr,plvl,tlyr,qlyr,qstl,rhly, & ! --- inputs - tracer1,xlat,xlon,slmsk,dz,delp, & - ntrac-1, ntcw-1,ntiw-1,ntrw-1, & - ntsw-1,ntgl-1, & - im, lm, lmp, uni_cld, lmfshal, lmfdeep2, & - cldcov(:,1:LM), effrl, effri, effrs, & - lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - dzb, xlat_d, julian, yearlen, gridkm, & - clouds, cldsa, mtopa ,mbota, de_lgth, alpha) ! --- outputs - - else - call progcld6 (plyr,plvl,tlyr,qlyr,qstl,rhly, & ! --- inputs - tracer1,xlat,xlon,slmsk,dz,delp, & - ntrac-1, ntcw-1,ntiw-1,ntrw-1, & - ntsw-1,ntgl-1, & - im, lmk, lmp, uni_cld, lmfshal, lmfdeep2, & - cldcov(:,1:LMK), cnvw, effrl, effri, effrs,& - lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - dzb, xlat_d, julian, yearlen, & - clouds, cldsa, mtopa ,mbota, de_lgth, alpha) ! --- outputs - endif - endif ! MYNN PBL or GF - - endif ! end if_imp_physics + call radiation_clouds_prop & + & ( plyr, plvl, tlyr, tvly, qlyr, qstl, rhly, & ! --- inputs: + & ccnd, ncndl, cnvw, cnvc, tracer1, & + & xlat, xlon, slmsk, dz, delp, IM, LM, LMK, LMP, & + & deltaq, sup, me, icloud, kdt, & + & ntrac, ntcw, ntiw, ntrw, ntsw, ntgl, ntclamt, & + & imp_physics, imp_physics_nssl, imp_physics_fer_hires, & + & imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & + & imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, & + & imp_physics_mg, iovr_rand, iovr_maxrand, iovr_max, & + & iovr_dcorr, iovr_exp, iovr_exprand, idcor_con, & + & idcor_hogan, idcor_oreopoulos, & + & imfdeepcnv, imfdeepcnv_gf, do_mynnedmf, lgfdlmprad, & + & uni_cld, lmfshal, lmfdeep2, cldcov, clouds1, & + & effrl, effri, effrr, effrs, effr_in, & + & effrl_inout, effri_inout, effrs_inout, & + & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & + & dzb, xlat_d, julian, yearlen, gridkm, & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & ! --- outputs: + & cld_rwp, cld_rerain, cld_swp, cld_resnow, & ! --- outputs: + & cldsa, mtopa, mbota, de_lgth, alpha & ! --- outputs: + & ) ! endif ! end_if_ntcw @@ -1089,7 +956,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & do k = 1, LMK do i = 1, IM ! compute beta distribution parameters - m = clouds(i,k,1) + m = cld_frac(i,k) if (m<0.99 .AND. m > 0.01) then s = sppt_amp*m*(1.-m) alpha0 = m*m*(1.-m)/(s*s)-m @@ -1097,25 +964,25 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & ! compute beta distribution value corresponding ! to the given percentile albPpert to use as new albedo call ppfbet(cldp1d(i),alpha0,beta0,iflag,cldtmp) - clouds(i,k,1) = cldtmp + cld_frac(i,k) = cldtmp else - clouds(i,k,1) = m + cld_frac(i,k) = m endif enddo ! end_do_i_loop enddo ! end_do_k_loop endif do k = 1, LM do i = 1, IM - clouds1(i,k) = clouds(i,k,1) - clouds2(i,k) = clouds(i,k,2) - clouds3(i,k) = clouds(i,k,3) - clouds4(i,k) = clouds(i,k,4) - clouds5(i,k) = clouds(i,k,5) - clouds6(i,k) = clouds(i,k,6) - clouds7(i,k) = clouds(i,k,7) - clouds8(i,k) = clouds(i,k,8) - clouds9(i,k) = clouds(i,k,9) - cldfra(i,k) = clouds(i,k,1) + clouds1(i,k) = cld_frac(i,k) + clouds2(i,k) = cld_lwp(i,k) + clouds3(i,k) = cld_reliq(i,k) + clouds4(i,k) = cld_iwp(i,k) + clouds5(i,k) = cld_reice(i,k) + clouds6(i,k) = cld_rwp(i,k) + clouds7(i,k) = cld_rerain(i,k) + clouds8(i,k) = cld_swp(i,k) + clouds9(i,k) = cld_resnow(i,k) + cldfra(i,k) = cld_frac(i,k) enddo enddo do i = 1, IM @@ -1135,9 +1002,9 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & enddo else do i=1,im - clouds3(i,k) = clouds3(i,k) - spp_wts_rad(i,k) * clouds3(i,k) - clouds5(i,k) = clouds5(i,k) - spp_wts_rad(i,k) * clouds5(i,k) - clouds9(i,k) = clouds9(i,k) - spp_wts_rad(i,k) * clouds9(i,k) + clouds3(i,k) = clouds3(i,k) - spp_wts_rad(i,levs) * clouds3(i,k) + clouds5(i,k) = clouds5(i,k) - spp_wts_rad(i,levs) * clouds5(i,k) + clouds9(i,k) = clouds9(i,k) - spp_wts_rad(i,levs) * clouds9(i,k) enddo endif enddo diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index df2553790..15bd94fb8 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -324,6 +324,69 @@ dimensions = () type = integer intent = in +[iovr_rand] + standard_name = flag_for_random_cloud_overlap_method + long_name = choice of random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_maxrand] + standard_name = flag_for_maximum_random_cloud_overlap_method + long_name = choice of maximum-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_max] + standard_name = flag_for_maximum_cloud_overlap_method + long_name = choice of maximum cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_dcorr] + standard_name = flag_for_decorrelation_length_cloud_overlap_method + long_name = choice of decorrelation-length cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exp] + standard_name = flag_for_exponential_cloud_overlap_method + long_name = choice of exponential cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exprand] + standard_name = flag_for_exponential_random_cloud_overlap_method + long_name = choice of exponential-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[idcor_con] + standard_name = flag_for_constant_decorrelation_length_method + long_name = choice of decorrelation length computation (costant) + units = flag + dimensions = () + type = integer + intent = in +[idcor_hogan] + standard_name = flag_for_hogan_decorrelation_length_method + long_name = choice of decorrelation length computation (hogan) + units = flag + dimensions = () + type = integer + intent = in +[idcor_oreopoulos] + standard_name = flag_for_oreopoulos_decorrelation_length_method + long_name = choice of decorrelation length computation (oreopoulos) + units = flag + dimensions = () + type = integer + intent = in [julian] standard_name = forecast_julian_day long_name = julian day diff --git a/physics/GFS_rrtmgp_cloud_mp.F90 b/physics/GFS_rrtmgp_cloud_mp.F90 new file mode 100644 index 000000000..53b4d801c --- /dev/null +++ b/physics/GFS_rrtmgp_cloud_mp.F90 @@ -0,0 +1,883 @@ +! ######################################################################################## +! ######################################################################################## +module GFS_rrtmgp_cloud_mp + use machine, only: kind_phys + use radiation_tools, only: check_error_msg + use module_radiation_clouds, only: progcld_thompson + use rrtmgp_lw_cloud_optics, only: & + radliq_lwr => radliq_lwrLW, radliq_upr => radliq_uprLW,& + radice_lwr => radice_lwrLW, radice_upr => radice_uprLW + use module_mp_thompson, only: calc_effectRad, Nt_c, re_qc_min, re_qc_max, re_qi_min, & + re_qi_max, re_qs_min, re_qs_max + use module_mp_thompson_make_number_concentrations, only: make_IceNumber, & + make_DropletNumber, make_RainNumber + + real (kind_phys), parameter :: & + cld_limit_lower = 0.001, & + cld_limit_ovcst = 1.0 - 1.0e-8, & + reliq_def = 10.0 , & ! Default liq radius to 10 micron (used when effr_in=F) + reice_def = 50.0, & ! Default ice radius to 50 micron (used when effr_in=F) + rerain_def = 1000.0, & ! Default rain radius to 1000 micron (used when effr_in=F) + resnow_def = 250.0, & ! Default snow radius to 250 micron (used when effr_in=F) + reice_min = 10.0, & ! Minimum ice size allowed by GFDL MP scheme + reice_max = 150.0 ! Maximum ice size allowed by GFDL MP scheme + + public GFS_rrtmgp_cloud_mp_init, GFS_rrtmgp_cloud_mp_run, GFS_rrtmgp_cloud_mp_finalize + +contains + +!! \section arg_table_GFS_rrtmgp_cloud_mp_run +!! \htmlinclude GFS_rrtmgp_cloud_mp_run_html +!! + ! ###################################################################################### + ! ###################################################################################### + subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, & + i_cldrain, i_cldsnow, i_cldgrpl, i_cldtot, i_cldliq_nc, i_cldice_nc, i_twa, kdt, & + imfdeepcnv, imfdeepcnv_gf, imfdeepcnv_samf, doSWrad, doLWrad, effr_in, lmfshal, & + ltaerosol, icloud, imp_physics, imp_physics_thompson, imp_physics_gfdl, & + lgfdlmprad, do_mynnedmf, uni_cld, lmfdeep2, p_lev, p_lay, t_lay, qs_lay, q_lay, & + relhum, lsmask, xlon, xlat, dx, tv_lay, effrin_cldliq, effrin_cldice, & + effrin_cldrain, effrin_cldsnow, tracer, cnv_mixratio, cld_cnv_frac, qci_conv, & + deltaZ, deltaZc, deltaP, qc_mynn, qi_mynn, cld_pbl_frac, con_g, con_rd, con_eps, & + con_ttp, doGP_cldoptics_PADE, doGP_cldoptics_LUT, cld_frac, cld_lwp, cld_reliq, & + cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, cld_rerain, precip_frac, & + cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, cld_cnv_reice, cld_pbl_lwp, & + cld_pbl_reliq, cld_pbl_iwp, cld_pbl_reice, lwp_ex, iwp_ex, lwp_fc, iwp_fc, & + errmsg, errflg) + implicit none + + ! Inputs + integer, intent(in) :: & + nCol, & ! Number of horizontal grid points + nLev, & ! Number of vertical layers + ncnd, & ! Number of cloud condensation types. + nTracers, & ! Number of tracers from model. + i_cldliq, & ! Index into tracer array for cloud liquid. + i_cldice, & ! Index into tracer array for cloud ice. + i_cldrain, & ! Index into tracer array for cloud rain. + i_cldsnow, & ! Index into tracer array for cloud snow. + i_cldgrpl, & ! Index into tracer array for cloud groupel. + i_cldtot, & ! Index into tracer array for cloud total amount. + i_cldliq_nc, & ! cloud liquid number concentration. + i_cldice_nc, & ! cloud ice number concentration. + i_twa, & ! water friendly aerosol. + imfdeepcnv, & ! Choice of mass-flux deep convection scheme + imfdeepcnv_gf, & ! Flag for Grell-Freitas deep convection scheme + imfdeepcnv_samf, & ! Flag for scale awware mass flux convection scheme + kdt, & ! Current forecast iteration + imp_physics, & ! Choice of microphysics scheme + imp_physics_thompson, & ! Choice of Thompson + imp_physics_gfdl, & ! Choice of GFDL + icloud ! Control for cloud are fraction option + logical, intent(in) :: & + doSWrad, & ! Call SW radiation? + doLWrad, & ! Call LW radiation? + effr_in, & ! Provide hydrometeor radii from macrophysics? + lmfshal, & ! Flag for mass-flux shallow convection scheme used by Xu-Randall + ltaerosol, & ! Flag for aerosol option + lgfdlmprad, & ! Flag for GFDLMP radiation interaction + do_mynnedmf, & ! Flag to activate MYNN-EDMF + uni_cld, & ! Flag for unified cloud scheme + lmfdeep2, & ! Flag for mass flux deep convection + doGP_cldoptics_LUT, & ! Flag to do GP cloud-optics (LUTs) + doGP_cldoptics_PADE ! (PADE approximation) + real(kind_phys), intent(in) :: & + con_g, & ! Physical constant: gravitational constant + con_rd, & ! Physical constant: gas-constant for dry air + con_ttp, & ! Triple point temperature of water (K) + con_eps ! Physical constant: gas constant air / gas constant H2O + real(kind_phys), dimension(:), intent(in) :: & + lsmask, & ! Land/Sea mask + xlon, & ! Longitude + xlat, & ! Latitude + dx ! Characteristic grid lengthscale (m) + real(kind_phys), dimension(:,:), intent(in) :: & + tv_lay, & ! Virtual temperature (K) + t_lay, & ! Temperature (K) + qs_lay, & ! Saturation vapor pressure (Pa) + q_lay, & ! water-vapor mixing ratio (kg/kg) + relhum, & ! Relative humidity + p_lay, & ! Pressure at model-layers (Pa) + cnv_mixratio, & ! Convective cloud mixing-ratio (kg/kg) + qci_conv, & ! Convective cloud condesate after rainout (kg/kg) + deltaZ, & ! Layer-thickness (m) + deltaZc, & ! Layer-thickness, from layer centers (m) + deltaP, & ! Layer-thickness (Pa) + qc_mynn, & ! + qi_mynn, & ! + cld_pbl_frac ! + real(kind_phys), dimension(:,:), intent(inout) :: & + effrin_cldliq, & ! Effective radius for stratiform liquid cloud-particles (microns) + effrin_cldice, & ! Effective radius for stratiform ice cloud-particles (microns) + effrin_cldsnow ! Effective radius for stratiform snow cloud-particles (microns) + real(kind_phys), dimension(:,:), intent(in) :: & + effrin_cldrain ! Effective radius for stratiform rain cloud-particles (microns) + real(kind_phys), dimension(:,:), intent(in) :: & + p_lev ! Pressure at model-level interfaces (Pa) + real(kind_phys), dimension(:,:,:),intent(in) :: & + tracer ! Cloud condensate amount in layer by type () + + ! Outputs + real(kind_phys), dimension(:), intent(inout) :: & + lwp_ex, & ! Total liquid water path from explicit microphysics + iwp_ex, & ! Total ice water path from explicit microphysics + lwp_fc, & ! Total liquid water path from cloud fraction scheme + iwp_fc ! Total ice water path from cloud fraction scheme + real(kind_phys), dimension(:,:),intent(inout) :: & + cld_frac, & ! Cloud-fraction for stratiform clouds + cld_lwp, & ! Water path for stratiform liquid cloud-particles + cld_reliq, & ! Effective radius for stratiform liquid cloud-particles + cld_iwp, & ! Water path for stratiform ice cloud-particles + cld_reice, & ! Effective radius for stratiform ice cloud-particles + cld_swp, & ! Water path for snow hydrometeors + cld_resnow, & ! Effective radius for snow hydrometeors + cld_rwp, & ! Water path for rain hydrometeors + cld_rerain, & ! Effective radius for rain hydrometeors + precip_frac, & ! Precipitation fraction + cld_cnv_frac, & ! Cloud-fraction for convective clouds + cld_cnv_lwp, & ! Water path for convective liquid cloud-particles + cld_cnv_reliq, & ! Effective radius for convective liquid cloud-particles + cld_cnv_iwp, & ! Water path for convective ice cloud-particles + cld_cnv_reice, & ! Effective radius for convective ice cloud-particles + cld_pbl_lwp, & ! Water path for SGS PBL liquid cloud-particles + cld_pbl_reliq, & ! Effective radius for SGS PBL liquid cloud-particles + cld_pbl_iwp, & ! Water path for SGS PBL ice cloud-particles + cld_pbl_reice ! Effective radius for SGS PBL ice cloud-particles + character(len=*), intent(out) :: & + errmsg ! Error message + integer, intent(out) :: & + errflg ! Error flag + + ! Local + integer :: iCol, iLay + real(kind_phys) :: alpha0 + real(kind_phys), dimension(nCol,nLev) :: cldcov, cldtot, cldcnv + + if (.not. (doSWrad .or. doLWrad)) return + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! ################################################################################### + ! GFDL Microphysics + ! ("Implicit" SGS cloud-coupling to the radiation) + ! ################################################################################### + if (imp_physics == imp_physics_gfdl) then + ! GFDL-Lin + if (.not. lgfdlmprad) then + errflg = 1 + errmsg = "ERROR: MP choice not available with RRTMGP" + return + ! GFDL-EMC + else + + ! "cld_frac" is modified prior to include subgrid scale cloudiness, see + ! module_SGSCloud_RadPre.F90. + do iLay = 1, nLev + do iCol = 1, nCol + ! + ! SGS clouds present, use cloud-fraction modified to include sgs clouds. + ! + if ((imfdeepcnv==imfdeepcnv_gf .or. do_mynnedmf) .and. kdt>1) then + ! MYNN sub-grid cloud fraction. + if (do_mynnedmf) then + ! If rain/snow present, use GFDL MP cloud-fraction... + if (tracer(iCol,iLay,i_cldrain)>1.0e-7 .OR. tracer(iCol,iLay,i_cldsnow)>1.0e-7) then + cld_frac(iCol,iLay) = tracer(iCol,iLay,i_cldtot) + endif + ! GF sub-grid cloud fraction. + else + ! If no convective cloud condensate present, use GFDL MP cloud-fraction.... + if (qci_conv(iCol,iLay) <= 0.) then + cld_frac(iCol,iLay) = tracer(iCol,iLay,i_cldtot) + endif + endif + ! + ! No SGS clouds, use GFDL MP cloud-fraction... + ! + else + cld_frac(iCol,iLay) = tracer(iCol,iLay,i_cldtot) + endif + enddo + enddo + + call cloud_mp_uni(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_cldrain, & + i_cldsnow, i_cldgrpl, i_cldtot, effr_in, kdt, lsmask, p_lev, p_lay, & + t_lay, tv_lay, effrin_cldliq, effrin_cldice, effrin_cldsnow, tracer, & + con_g, con_rd, con_ttp, cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice,& + cld_swp, cld_resnow, cld_rwp, cld_rerain, effrin_cldrain=effrin_cldrain) + end if + endif + + ! ################################################################################### + ! Thompson Microphysics + ! ("Explicit" SGS cloud-coupling to the radiation) + ! ################################################################################### + if (imp_physics == imp_physics_thompson) then + + ! MYNN-EDMF PBL clouds? + if(do_mynnedmf) then + call cloud_mp_MYNN(nCol, nLev, lsmask, t_lay, p_lev, p_lay, qs_lay, relhum, & + qc_mynn, qi_mynn, con_ttp, con_g, & + cld_pbl_lwp, cld_pbl_reliq, cld_pbl_iwp, cld_pbl_reice, cld_pbl_frac) + endif + + ! Grell-Freitas convective clouds? + if (imfdeepcnv == imfdeepcnv_gf) then + alpha0 = 100. + call cloud_mp_GF(nCol, nLev, lsmask, t_lay, p_lev, p_lay, qs_lay, relhum, & + qci_conv, con_ttp, con_g, alpha0, & + cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, cld_cnv_reice, cld_cnv_frac) + endif + + ! SAMF scale & aerosol-aware mass-flux convective clouds? + if (imfdeepcnv == imfdeepcnv_samf) then + alpha0 = 200. + call cloud_mp_SAMF(nCol, nLev, t_lay, p_lev, p_lay, qs_lay, relhum, & + cnv_mixratio, con_ttp, con_g, alpha0, & + cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, cld_cnv_reice, cld_cnv_frac) + endif + + ! Update particle size using modified mixing-ratios from Thompson. + call cmp_reff_Thompson(nLev, nCol, i_cldliq, i_cldice, i_cldsnow, i_cldice_nc, & + i_cldliq_nc, i_twa, q_lay, p_lay, t_lay, tracer, con_eps, con_rd, ltaerosol,& + effrin_cldliq, effrin_cldice, effrin_cldsnow) + cld_reliq = effrin_cldliq + cld_reice = effrin_cldice + cld_resnow = effrin_cldsnow + + ! Thomson MP using modified Xu-Randall cloud-fraction (additionally conditioned on RH) + alpha0 = 2000. + if (lmfshal) then + alpha0 = 100. + if (lmfdeep2) alpha0 = 200. + endif + call cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_cldrain,& + i_cldsnow, i_cldgrpl, p_lev, p_lay, tv_lay, t_lay, tracer, qs_lay, q_lay, & + relhum, con_g, con_rd, con_eps, alpha0, lwp_ex, iwp_ex, lwp_fc, iwp_fc, & + cld_frac, cld_lwp, cld_iwp, cld_swp, cld_rwp, cond_cfrac_onRH = .true.) + endif + + ! Bound effective radii for RRTMGP, LUT's for cloud-optics go from + ! 2.5 - 21.5 microns for liquid clouds, + ! 10 - 180 microns for ice-clouds + if (doGP_cldoptics_PADE .or. doGP_cldoptics_LUT) then + where(cld_reliq .lt. radliq_lwr) cld_reliq = radliq_lwr + where(cld_reliq .gt. radliq_upr) cld_reliq = radliq_upr + where(cld_reice .lt. radice_lwr) cld_reice = radice_lwr + where(cld_reice .gt. radice_upr) cld_reice = radice_upr + if (imfdeepcnv == imfdeepcnv_samf .or. imfdeepcnv == imfdeepcnv_gf) then + where(cld_cnv_reliq .lt. radliq_lwr) cld_cnv_reliq = radliq_lwr + where(cld_cnv_reliq .gt. radliq_upr) cld_cnv_reliq = radliq_upr + where(cld_cnv_reice .lt. radice_lwr) cld_cnv_reice = radice_lwr + where(cld_cnv_reice .gt. radice_upr) cld_cnv_reice = radice_upr + endif + if (do_mynnedmf) then + where(cld_pbl_reliq .lt. radliq_lwr) cld_pbl_reliq = radliq_lwr + where(cld_pbl_reliq .gt. radliq_upr) cld_pbl_reliq = radliq_upr + where(cld_pbl_reice .lt. radice_lwr) cld_pbl_reice = radice_lwr + where(cld_pbl_reice .gt. radice_upr) cld_pbl_reice = radice_upr + endif + endif + + precip_frac(1:nCol,1:nLev) = cld_frac(1:nCol,1:nLev) + + end subroutine GFS_rrtmgp_cloud_mp_run + + ! ###################################################################################### + ! Compute cloud radiative properties for Grell-Freitas convective cloud scheme. + ! (Adopted from module_SGSCloud_RadPre) + ! + ! - The total convective cloud condensate is partitoned by phase, using temperature, into + ! liquid/ice convective cloud mixing-ratios. Compute convective cloud LWP and IWP's. + ! + ! - The liquid and ice cloud effective particle sizes are assigned reference values*. + ! *TODO* Find references, include DOIs, parameterize magic numbers, etc... + ! + ! - The convective cloud-fraction is computed using Xu-Randall (1996). + ! (DJS asks: Does the GF scheme produce a cloud-fraction? If so, maybe use instead of + ! Xu-Randall? Xu-Randall is consistent with the Thompson MP scheme, but + ! not GFDL-EMC) + ! + ! ###################################################################################### + subroutine cloud_mp_GF(nCol, nLev, lsmask, t_lay, p_lev, p_lay, qs_lay, relhum, & + qci_conv, con_ttp, con_g, alpha0, cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, & + cld_cnv_reice, cld_cnv_frac) + implicit none + + ! Inputs + integer, intent(in) :: & + nCol, & ! Number of horizontal grid points + nLev ! Number of vertical layers + real(kind_phys), dimension(:), intent(in) :: & + lsmask ! Land/Sea mask + real(kind_phys), intent(in) :: & + con_g, & ! Physical constant: gravitational constant + con_ttp, & ! Triple point temperature of water (K) + alpha0 ! + real(kind_phys), dimension(:,:),intent(in) :: & + t_lay, & ! Temperature at layer centers (K) + p_lev, & ! Pressure at layer interfaces (Pa) + p_lay, & ! + qs_lay, & ! + relhum, & ! + qci_conv ! + ! Outputs + real(kind_phys), dimension(:,:),intent(inout) :: & + cld_cnv_lwp, & ! Convective cloud liquid water path + cld_cnv_reliq, & ! Convective cloud liquid effective radius + cld_cnv_iwp, & ! Convective cloud ice water path + cld_cnv_reice, & ! Convective cloud ice effecive radius + cld_cnv_frac ! Convective cloud-fraction (1) + ! Local + integer :: iCol, iLay + real(kind_phys) :: tem1, deltaP, clwc, qc, qi + + tem1 = 1.0e5/con_g + do iLay = 1, nLev + do iCol = 1, nCol + if (qci_conv(iCol,iLay) > 0.) then + ! Partition the convective clouds by phase. + qc = qci_conv(iCol,iLay)*( min(1., max(0., (t_lay(iCol,iLay)-244.)*0.04))) + qi = qci_conv(iCol,iLay)*(1. - min(1., max(0., (t_lay(iCol,iLay)-244.)*0.04))) + + ! Compute LWP/IWP + deltaP = abs(p_lev(iCol,iLay+1)-p_lev(iCol,iLay))*0.01 + cld_cnv_lwp(iCol,iLay) = max(0., qc * tem1 * deltaP) + cld_cnv_iwp(iCol,iLay) = max(0., qi * tem1 * deltaP) + + ! Particle sizes + if (nint(lsmask(iCol)) == 1) then !land + if(qc > 1.E-8) cld_cnv_reliq(iCol,iLay) = 5.4 + else + !eff radius cloud water (microns), from Miles et al. + if(qc > 1.E-8) cld_cnv_reliq(iCol,iLay) = 9.6 + endif + !eff radius cloud ice (microns), from Mishra et al. (2014, JGR Atmos, fig 6b) + if(qi > 1.E-8) cld_cnv_reice(iCol,iLay) = max(173.45 + 2.14*(t_lay(iCol,iLay)-273.15), 20.) + + ! Xu-Randall (1996) cloud-fraction. + cld_cnv_frac(iCol,iLay) = cld_frac_XuRandall(p_lay(iCol,iLay), & + qs_lay(iCol,iLay), relhum(iCol,iLay), qc+qi, alpha0) + endif + enddo + enddo + end subroutine cloud_mp_GF + + ! ###################################################################################### + ! Compute cloud radiative properties for MYNN-EDMF PBL cloud scheme. + ! (Adopted from module_SGSCloud_RadPre) + ! + ! - Cloud-fraction, liquid, and ice condensate mixing-ratios from MYNN-EDMF cloud scheme + ! are provided as inputs. Cloud LWP and IWP are computed. + ! + ! - The liquid and ice cloud effective particle sizes are assigned reference values*. + ! *TODO* Find references, include DOIs, parameterize magic numbers, etc... + ! + ! ###################################################################################### + subroutine cloud_mp_MYNN(nCol, nLev, lsmask, t_lay, p_lev, p_lay, qs_lay, relhum, & + qc_mynn, qi_mynn, con_ttp, con_g, cld_pbl_lwp, cld_pbl_reliq, cld_pbl_iwp, & + cld_pbl_reice, cld_pbl_frac) + implicit none + + ! Inputs + integer, intent(in) :: & + nCol, & ! Number of horizontal grid points + nLev ! Number of vertical layers + real(kind_phys), dimension(:), intent(in) :: & + lsmask ! Land/Sea mask + real(kind_phys), intent(in) :: & + con_g, & ! Physical constant: gravitational constant + con_ttp ! Triple point temperature of water (K) + real(kind_phys), dimension(:,:),intent(in) :: & + t_lay, & ! Temperature at layer centers (K) + p_lev, & ! Pressure at layer interfaces (Pa) + p_lay, & ! + qs_lay, & ! + relhum, & ! + qc_mynn, & ! Liquid cloud mixing-ratio (MYNN PBL cloud) + qi_mynn, & ! Ice cloud mixing-ratio (MYNN PBL cloud) + cld_pbl_frac ! Cloud-fraction (MYNN PBL cloud) + ! Outputs + real(kind_phys), dimension(:,:),intent(inout) :: & + cld_pbl_lwp, & ! Convective cloud liquid water path + cld_pbl_reliq, & ! Convective cloud liquid effective radius + cld_pbl_iwp, & ! Convective cloud ice water path + cld_pbl_reice ! Convective cloud ice effecive radius + + ! Local + integer :: iCol, iLay + real(kind_phys) :: tem1, qc, qi, deltaP + + tem1 = 1.0e5/con_g + do iLay = 1, nLev + do iCol = 1, nCol + if (cld_pbl_frac(iCol,iLay) > cld_limit_lower) then + ! Cloud mixing-ratios (DJS asks: Why is this done?) + qc = qc_mynn(iCol,iLay)*cld_pbl_frac(iCol,iLay) + qi = qi_mynn(iCol,iLay)*cld_pbl_frac(iCol,iLay) + + ! LWP/IWP + deltaP = abs(p_lev(iCol,iLay+1)-p_lev(iCol,iLay)) + cld_pbl_lwp(iCol,iLay) = max(0., qc * tem1 * deltaP) + cld_pbl_iwp(iCol,iLay) = max(0., qi * tem1 * deltaP) + + ! Particle sizes + if (nint(lsmask(iCol)) == 1) then + if(qc > 1.E-8) cld_pbl_reliq(iCol,iLay) = 5.4 + else + ! Cloud water (microns), from Miles et al. + if(qc > 1.E-8) cld_pbl_reliq(iCol,iLay) = 9.6 + endif + ! Cloud ice (microns), from Mishra et al. (2014, JGR Atmos, fig 6b) + if(qi > 1.E-8) cld_pbl_reice(iCol,iLay) = max(173.45 + 2.14*(t_lay(iCol,iLay)-273.15), 20.) + endif + enddo + enddo + end subroutine cloud_mp_MYNN + + ! ###################################################################################### + ! Compute cloud radiative properties for SAMF convective cloud scheme. + ! + ! - The total-cloud convective mixing-ratio is partitioned by phase into liquid/ice + ! cloud properties. LWP and IWP are computed. + ! + ! - The liquid and ice cloud effective particle sizes are assigned reference values. + ! + ! - The convective cloud-fraction is computed using Xu-Randall (1996). + ! (DJS asks: Does the SAMF scheme produce a cloud-fraction?) + ! + ! ###################################################################################### + subroutine cloud_mp_SAMF(nCol, nLev, t_lay, p_lev, p_lay, qs_lay, relhum, & + cnv_mixratio, con_ttp, con_g, alpha0, cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, & + cld_cnv_reice, cld_cnv_frac) + implicit none + + ! Inputs + integer, intent(in) :: & + nCol, & ! Number of horizontal grid points + nLev ! Number of vertical layers + real(kind_phys), intent(in) :: & + con_g, & ! Physical constant: gravitational constant + con_ttp, & ! Triple point temperature of water (K) + alpha0 ! + real(kind_phys), dimension(:,:),intent(in) :: & + t_lay, & ! Temperature at layer centers (K) + p_lev, & ! Pressure at layer interfaces (Pa) + p_lay, & ! + qs_lay, & ! + relhum, & ! + cnv_mixratio ! Convective cloud mixing-ratio (kg/kg) + ! Outputs + real(kind_phys), dimension(:,:),intent(inout) :: & + cld_cnv_lwp, & ! Convective cloud liquid water path + cld_cnv_reliq, & ! Convective cloud liquid effective radius + cld_cnv_iwp, & ! Convective cloud ice water path + cld_cnv_reice, & ! Convective cloud ice effecive radius + cld_cnv_frac ! Convective cloud-fraction (1) + ! Local + integer :: iCol, iLay + real(kind_phys) :: tem1, deltaP, clwc + + do iLay = 1, nLev + do iCol = 1, nCol + if (cnv_mixratio(iCol,iLay) > 0._kind_phys) then + tem1 = min(1.0, max(0.0, (con_ttp-t_lay(iCol,iLay))*0.05)) + deltaP = abs(p_lev(iCol,iLay+1)-p_lev(iCol,iLay))*0.01 + clwc = max(0.0, cnv_mixratio(iCol,iLay)) * con_g * deltaP + cld_cnv_iwp(iCol,iLay) = clwc * tem1 + cld_cnv_lwp(iCol,iLay) = clwc - cld_cnv_iwp(iCol,iLay) + cld_cnv_reliq(iCol,iLay) = reliq_def + cld_cnv_reice(iCol,iLay) = reice_def + + ! Xu-Randall (1996) cloud-fraction. + cld_cnv_frac(iCol,iLay) = cld_frac_XuRandall(p_lay(iCol,iLay), & + qs_lay(iCol,iLay), relhum(iCol,iLay), cnv_mixratio(iCol,iLay), alpha0) + endif + enddo + enddo + + end subroutine cloud_mp_SAMF + + ! ###################################################################################### + ! This routine computes the cloud radiative properties for a "unified cloud". + ! + ! - "unified cloud" implies that the cloud-fraction is PROVIDED. + ! + ! - The cloud water path is computed for all provided cloud mixing-ratios and hydrometeors. + ! + ! - If particle sizes are provided, they are used. If not, default values are assigned. + ! + ! ###################################################################################### + subroutine cloud_mp_uni(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_cldrain, & + i_cldsnow, i_cldgrpl, i_cldtot, effr_in, kdt, lsmask, p_lev, p_lay, t_lay, tv_lay,& + effrin_cldliq, effrin_cldice, effrin_cldsnow, tracer, con_g, con_rd, con_ttp, & + cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, & + cld_rerain, effrin_cldrain) + implicit none + + ! Inputs + integer, intent(in) :: & + nCol, & ! Number of horizontal grid points + nLev, & ! Number of vertical layers + ncnd, & ! Number of cloud condensation types. + nTracers, & ! Number of tracers from model. + i_cldliq, & ! Index into tracer array for cloud liquid. + i_cldice, & ! Index into tracer array for cloud ice. + i_cldrain, & ! Index into tracer array for cloud rain. + i_cldsnow, & ! Index into tracer array for cloud snow. + i_cldgrpl, & ! Index into tracer array for cloud groupel. + i_cldtot, & ! Index into tracer array for cloud total amount. + kdt + logical, intent(in) :: & + effr_in ! Provide hydrometeor radii from macrophysics? + real(kind_phys), intent(in) :: & + con_g, & ! Physical constant: gravitational constant + con_ttp, & ! Triple point temperature of water (K) + con_rd ! Physical constant: gas-constant for dry air + real(kind_phys), dimension(:), intent(in) :: & + lsmask + real(kind_phys), dimension(:,:), intent(in) :: & + t_lay, & ! Temperature at model-layers (K) + tv_lay, & ! Virtual temperature (K) + p_lay, & ! Pressure at model-layers (Pa) + cld_frac, & ! Total cloud fraction + effrin_cldliq, & ! Effective radius for liquid cloud-particles (microns) + effrin_cldice, & ! Effective radius for ice cloud-particles (microns) + effrin_cldsnow ! Effective radius for snow cloud-particles (microns) + real(kind_phys), dimension(:,:), intent(in) ,optional :: & + effrin_cldrain ! Effective radius for rain cloud-particles (microns) + real(kind_phys), dimension(:,:), intent(in) :: & + p_lev ! Pressure at model-level interfaces (Pa) + real(kind_phys), dimension(:,:,:),intent(in) :: & + tracer ! Cloud condensate amount in layer by type () + + ! Outputs + real(kind_phys), dimension(:,:),intent(inout) :: & + cld_lwp, & ! Cloud liquid water path + cld_reliq, & ! Cloud liquid effective radius + cld_iwp, & ! Cloud ice water path + cld_reice, & ! Cloud ice effecive radius + cld_swp, & ! Cloud snow water path + cld_resnow, & ! Cloud snow effective radius + cld_rwp, & ! Cloud rain water path + cld_rerain ! Cloud rain effective radius + + ! Local variables + real(kind_phys) :: tem1,tem2,tem3,pfac,deltaP + real(kind_phys), dimension(nCol, nLev, min(4,ncnd)) :: cld_condensate + integer :: iCol,iLay,l,ncndl + + ! Cloud condensate + cld_condensate(1:nCol,1:nLev,1) = tracer(1:nCol,1:nLev,i_cldliq) ! -liquid water + cld_condensate(1:nCol,1:nLev,2) = tracer(1:nCol,1:nLev,i_cldice) ! -ice water + if (ncnd > 2) then + cld_condensate(1:nCol,1:nLev,3) = tracer(1:nCol,1:nLev,i_cldrain) ! -rain water + cld_condensate(1:nCol,1:nLev,4) = tracer(1:nCol,1:nLev,i_cldsnow) + &! -snow + grapuel + tracer(1:nCol,1:nLev,i_cldgrpl) + endif + + ! Cloud water path (g/m2) + tem1 = 1.0e5/con_g + do iLay = 1, nLev + do iCol = 1, nCol + ! Compute liquid/ice condensate path from mixing ratios (kg/kg)->(g/m2) + if (cld_frac(iCol,iLay) > cld_limit_lower) then + deltaP = abs(p_lev(iCol,iLay+1)-p_lev(iCol,iLay))*0.01 + cld_lwp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,1) * tem1 * deltaP) + cld_iwp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,2) * tem1 * deltaP) + if (ncnd > 2) then + cld_rwp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,3) * tem1 * deltaP) + cld_swp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,4) * tem1 * deltaP) + endif + endif + enddo + enddo + + ! Particle size + do iLay = 1, nLev + do iCol = 1, nCol + ! Use radii provided from the macrophysics + if (effr_in) then + cld_reliq(iCol,iLay) = effrin_cldliq(iCol,iLay) + cld_reice(iCol,iLay) = max(reice_min, min(reice_max,effrin_cldice(iCol,iLay))) + cld_resnow(iCol,iLay) = effrin_cldsnow(iCol,iLay) + if (present(effrin_cldrain)) then + cld_rerain(iCol,iLay) = effrin_cldrain(iCol,iLay) + else + cld_rerain(iCol,iLay) = rerain_def + endif + else + ! Compute effective liquid cloud droplet radius over land. + if (nint(lsmask(iCol)) == 1) then + cld_reliq(iCol,iLay) = 5.0 + 5.0 * min(1.0, max(0.0, (con_ttp-t_lay(iCol,iLay))*0.05)) + endif + ! Compute effective ice cloud droplet radius following Heymsfield + ! and McFarquhar (1996) \cite heymsfield_and_mcfarquhar_1996. + tem2 = t_lay(iCol,iLay) - con_ttp + if (cld_iwp(iCol,iLay) > 0.0) then + deltaP = abs(p_lev(iCol,iLay+1)-p_lev(iCol,iLay))*0.01 + tem3 = (con_g/con_rd ) * cld_iwp(iCol,iLay) * (0.01*p_lay(iCol,iLay)) / (deltaP*tv_lay(iCol,iLay)) + if (tem2 < -50.0) then + cld_reice(iCol,iLay) = (1250.0/9.917) * tem3 ** 0.109 + elseif (tem2 < -40.0) then + cld_reice(iCol,iLay) = (1250.0/9.337) * tem3 ** 0.08 + elseif (tem2 < -30.0) then + cld_reice(iCol,iLay) = (1250.0/9.208) * tem3 ** 0.055 + else + cld_reice(iCol,iLay) = (1250.0/9.387) * tem3 ** 0.031 + endif + cld_reice(iCol,iLay) = max(10.0, min(cld_reice(iCol,iLay), 150.0)) + endif + endif ! effr_in + enddo ! nCol + enddo ! nLev + + end subroutine cloud_mp_uni + ! ###################################################################################### + ! This routine computes the cloud radiative properties for the Thompson cloud micro- + ! physics scheme. + ! + ! - The cloud water path is computed for all provided cloud mixing-ratios and hydrometeors. + ! + ! - There are no assumptions about particle size applied here. Effective particle sizes + ! are updated prior to this routine, see cmp_reff_Thompson(). + ! + ! - The cloud-fraction is computed using Xu-Randall** (1996). + ! **Additionally, Conditioned on relative-humidity** + ! + ! ###################################################################################### + subroutine cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_cldrain,& + i_cldsnow, i_cldgrpl, p_lev, p_lay, tv_lay, t_lay, tracer, qs_lay, q_lay, relhum, & + con_g, con_rd, con_eps, alpha0, lwp_ex, iwp_ex, lwp_fc, iwp_fc, cld_frac, cld_lwp,& + cld_iwp, cld_swp, cld_rwp, cond_cfrac_onRH) + implicit none + + ! Inputs + logical, intent(in), optional :: & + cond_cfrac_onRH + integer, intent(in) :: & + nCol, & ! Number of horizontal grid points + nLev, & ! Number of vertical layers + ncnd, & ! Number of cloud condensation types. + nTracers, & ! Number of tracers from model. + i_cldliq, & ! Index into tracer array for cloud liquid amount. + i_cldice, & ! cloud ice amount. + i_cldrain, & ! cloud rain amount. + i_cldsnow, & ! cloud snow amount. + i_cldgrpl ! cloud groupel amount. + real(kind_phys), intent(in) :: & + con_g, & ! Physical constant: gravitational constant + con_rd, & ! Physical constant: gas-constant for dry air + con_eps, & ! Physical constant: gas constant air / gas constant H2O + alpha0 ! + real(kind_phys), dimension(:,:), intent(in) :: & + tv_lay, & ! Virtual temperature (K) + t_lay, & ! Temperature (K) + qs_lay, & ! Saturation vapor pressure (Pa) + q_lay, & ! water-vapor mixing ratio (kg/kg) + relhum, & ! Relative humidity + p_lay ! Pressure at model-layers (Pa) + real(kind_phys), dimension(:,:), intent(in) :: & + p_lev ! Pressure at model-level interfaces (Pa) + real(kind_phys), dimension(:,:,:),intent(in) :: & + tracer ! Cloud condensate amount in layer by type () + + ! In/Outs + real(kind_phys), dimension(:), intent(inout) :: & + lwp_ex, & ! total liquid water path from explicit microphysics + iwp_ex, & ! total ice water path from explicit microphysics + lwp_fc, & ! total liquid water path from cloud fraction scheme + iwp_fc ! total ice water path from cloud fraction scheme + real(kind_phys), dimension(:,:), intent(inout) :: & + cld_frac, & ! Total cloud fraction + cld_lwp, & ! Cloud liquid water path + cld_iwp, & ! Cloud ice water path + cld_swp, & ! Cloud snow water path + cld_rwp ! Cloud rain water path + + ! Local variables + real(kind_phys) :: tem1, pfac, cld_mr, deltaP + real(kind_phys), dimension(nCol, nLev, min(4,ncnd)) :: cld_condensate + integer :: iCol,iLay,l + + ! Cloud condensate + cld_condensate(1:nCol,1:nLev,1) = tracer(1:nCol,1:nLev,i_cldliq) ! -liquid water + cld_condensate(1:nCol,1:nLev,2) = tracer(1:nCol,1:nLev,i_cldice) ! -ice water + cld_condensate(1:nCol,1:nLev,3) = tracer(1:nCol,1:nLev,i_cldrain) ! -rain water + cld_condensate(1:nCol,1:nLev,4) = tracer(1:nCol,1:nLev,i_cldsnow) + &! -snow + grapuel + tracer(1:nCol,1:nLev,i_cldgrpl) + + cld_lwp(:,:) = 0.0 + cld_iwp(:,:) = 0.0 + cld_rwp(:,:) = 0.0 + cld_swp(:,:) = 0.0 + cld_frac(:,:) = 0.0 + tem1 = 1.0e5/con_g + do iLay = 1, nLev-1 + do iCol = 1, nCol + ! Compute liquid/ice condensate path from mixing ratios (kg/kg)->(g/m2) + deltaP = abs(p_lev(iCol,iLay+1)-p_lev(iCol,iLay))*0.01 + cld_lwp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,1) * tem1 * deltaP) + cld_iwp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,2) * tem1 * deltaP) + cld_rwp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,3) * tem1 * deltaP) + cld_swp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,4) * tem1 * deltaP) + + ! Xu-Randall (1996) cloud-fraction. **Additionally, Conditioned on relative-humidity** + if (present(cond_cfrac_onRH) .and. relhum(iCol,iLay) > 0.99) then + cld_frac(iCol,iLay) = 1._kind_phys + else + cld_mr = cld_condensate(iCol,iLay,1) + cld_condensate(iCol,iLay,2) + & + cld_condensate(iCol,iLay,4) + cld_frac(iCol,iLay) = cld_frac_XuRandall(p_lay(iCol,iLay), & + qs_lay(iCol,iLay), relhum(iCol,iLay), cld_mr, alpha0) + endif + enddo + enddo + + ! Sum the liquid water and ice paths that come from explicit micro + ! What portion of water and ice contents is associated with the partly cloudy boxes? + do iCol = 1, nCol + lwp_ex(iCol) = 0.0 + iwp_ex(iCol) = 0.0 + lwp_fc(iCol) = 0.0 + iwp_fc(iCol) = 0.0 + do iLay = 1, nLev-1 + lwp_ex(iCol) = lwp_ex(iCol) + cld_lwp(iCol,iLay) + iwp_ex(iCol) = iwp_ex(iCol) + cld_iwp(iCol,iLay) + cld_swp(iCol,iLay) + if (cld_frac(iCol,iLay) .ge. cld_limit_lower .and. & + cld_frac(iCol,iLay) .lt. cld_limit_ovcst) then + lwp_fc(iCol) = lwp_fc(iCol) + cld_lwp(iCol,iLay) + iwp_fc(iCol) = iwp_fc(iCol) + cld_iwp(iCol,iLay) + cld_swp(iCol,iLay) + endif + enddo + lwp_fc(iCol) = lwp_fc(iCol)*1.E-3 + iwp_fc(iCol) = iwp_fc(iCol)*1.E-3 + lwp_ex(iCol) = lwp_ex(iCol)*1.E-3 + iwp_ex(iCol) = iwp_ex(iCol)*1.E-3 + enddo + + end subroutine cloud_mp_thompson + + ! ###################################################################################### + ! This function computes the cloud-fraction following. + ! Xu-Randall(1996) A Semiempirical Cloudiness Parameterization for Use in Climate Models + ! https://doi.org/10.1175/1520-0469(1996)053<3084:ASCPFU>2.0.CO;2 + ! + ! cld_frac = {1-exp[-alpha*cld_mr/((1-relhum)*qs_lay)**lambda]}*relhum**P + ! + ! ###################################################################################### + function cld_frac_XuRandall(p_lay, qs_lay, relhum, cld_mr, alpha) + implicit none + ! Inputs + real(kind_phys), intent(in) :: & + p_lay, & ! Pressure (Pa) + qs_lay, & ! Saturation vapor-pressure (Pa) + relhum, & ! Relative humidity + cld_mr, & ! Total cloud mixing ratio + alpha ! Scheme parameter (default=100) + + ! Outputs + real(kind_phys) :: cld_frac_XuRandall + + ! Locals + real(kind_phys) :: clwt, clwm, onemrh, tem1, tem2, tem3 + + ! Parameters + real(kind_phys) :: & + lambda = 0.50, & ! + P = 0.25 + + clwt = 1.0e-6 * (p_lay*0.001) + if (cld_mr > clwt) then + onemrh = max(1.e-10, 1.0 - relhum) + tem1 = alpha / min(max((onemrh*qs_lay)**lambda,0.0001),1.0) + tem2 = max(min(tem1*(cld_mr - clwt), 50.0 ), 0.0 ) + tem3 = sqrt(sqrt(relhum)) ! This assumes "p" = 0.25. Identical, but cheaper than relhum**p + ! + cld_frac_XuRandall = max( tem3*(1.0-exp(-tem2)), 0.0 ) + else + cld_frac_XuRandall = 0.0 + endif + + return + end function + + ! ###################################################################################### + ! This routine is a wrapper to update the Thompson effective particle sizes used by the + ! RRTMGP radiation scheme. + ! + ! ###################################################################################### + subroutine cmp_reff_Thompson(nLev, nCol, i_cldliq, i_cldice, i_cldsnow, i_cldice_nc, & + i_cldliq_nc, i_twa, q_lay, p_lay, t_lay, tracer, con_eps, con_rd, ltaerosol, & + effrin_cldliq, effrin_cldice, effrin_cldsnow) + implicit none + + ! Inputs + integer, intent(in) :: nLev, nCol, i_cldliq, i_cldice, i_cldsnow, i_cldice_nc, & + i_cldliq_nc, i_twa + logical, intent(in) :: ltaerosol + real(kind_phys), intent(in) :: con_eps,con_rd + real(kind_phys), dimension(:,:),intent(in) :: q_lay, p_lay, t_lay + real(kind_phys), dimension(:,:,:),intent(in) :: tracer + + ! Outputs + real(kind_phys), dimension(:,:), intent(inout) :: effrin_cldliq, effrin_cldice, & + effrin_cldsnow + + ! Local + integer :: iCol, iLay + real(kind_phys) :: rho, orho + real(kind_phys),dimension(nCol,nLev) :: qv_mp, qc_mp, qi_mp, qs_mp, ni_mp, nc_mp, & + nwfa, re_cloud, re_ice, re_snow + + ! Prepare cloud mixing-ratios and number concentrations for calc_effectRa + do iLay = 1, nLev + do iCol = 1, nCol + qv_mp(iCol,iLay) = q_lay(iCol,iLay)/(1.-q_lay(iCol,iLay)) + rho = con_eps*p_lay(iCol,iLay)/(con_rd*t_lay(iCol,iLay)*(qv_mp(iCol,iLay)+con_eps)) + orho = 1./rho + qc_mp(iCol,iLay) = tracer(iCol,iLay,i_cldliq) / (1.-q_lay(iCol,iLay)) + qi_mp(iCol,iLay) = tracer(iCol,iLay,i_cldice) / (1.-q_lay(iCol,iLay)) + qs_mp(iCol,iLay) = tracer(iCol,iLay,i_cldsnow) / (1.-q_lay(iCol,iLay)) + ni_mp(iCol,iLay) = tracer(iCol,iLay,i_cldice_nc) / (1.-q_lay(iCol,iLay)) + if (ltaerosol) then + nc_mp(iCol,iLay) = tracer(iCol,iLay,i_cldliq_nc) / (1.-q_lay(iCol,iLay)) + nwfa(iCol,iLay) = tracer(iCol,iLay,i_twa) + if (qc_mp(iCol,iLay) > 1.e-12 .and. nc_mp(iCol,iLay) < 100.) then + nc_mp(iCol,iLay) = make_DropletNumber(qc_mp(iCol,iLay)*rho, nwfa(iCol,iLay)*rho) * orho + endif + else + nc_mp(iCol,iLay) = nt_c*orho + endif + if (qi_mp(iCol,iLay) > 1.e-12 .and. ni_mp(iCol,iLay) < 100.) then + ni_mp(iCol,iLay) = make_IceNumber(qi_mp(iCol,iLay)*rho, t_lay(iCol,iLay)) * orho + endif + enddo + enddo + + ! Compute effective radii for liquid/ice/snow. + do iCol=1,nCol + call calc_effectRad (t_lay(iCol,:), p_lay(iCol,:), qv_mp(iCol,:), qc_mp(iCol,:), & + nc_mp(iCol,:), qi_mp(iCol,:), ni_mp(iCol,:), qs_mp(iCol,:), & + re_cloud(iCol,:), re_ice(iCol,:), re_snow(iCol,:), 1, nLev ) + do iLay = 1, nLev + re_cloud(iCol,iLay) = MAX(re_qc_min, MIN(re_cloud(iCol,iLay), re_qc_max)) + re_ice(iCol,iLay) = MAX(re_qi_min, MIN(re_ice(iCol,iLay), re_qi_max)) + re_snow(iCol,iLay) = MAX(re_qs_min, MIN(re_snow(iCol,iLay), re_qs_max)) + enddo + enddo + + ! Scale to microns. + do iLay = 1, nLev + do iCol = 1, nCol + effrin_cldliq(iCol,iLay) = re_cloud(iCol,iLay)*1.e6 + effrin_cldice(iCol,iLay) = re_ice(iCol,iLay)*1.e6 + effrin_cldsnow(iCol,iLay) = re_snow(iCol,iLay)*1.e6 + enddo + enddo + + end subroutine cmp_reff_Thompson + +end module GFS_rrtmgp_cloud_mp diff --git a/physics/GFS_rrtmgp_thompsonmp_pre.meta b/physics/GFS_rrtmgp_cloud_mp.meta similarity index 55% rename from physics/GFS_rrtmgp_thompsonmp_pre.meta rename to physics/GFS_rrtmgp_cloud_mp.meta index ff8d0e13b..88530d84c 100644 --- a/physics/GFS_rrtmgp_thompsonmp_pre.meta +++ b/physics/GFS_rrtmgp_cloud_mp.meta @@ -1,11 +1,11 @@ [ccpp-table-properties] - name = GFS_rrtmgp_thompsonmp_pre + name = GFS_rrtmgp_cloud_mp type = scheme - dependencies = radiation_tools.F90, module_mp_thompson_make_number_concentrations.F90, module_mp_thompson.F90, rrtmgp_lw_cloud_optics.F90 + dependencies = radiation_tools.F90, radiation_clouds.f, module_mp_thompson_make_number_concentrations.F90, module_mp_thompson.F90, rrtmgp_lw_cloud_optics.F90 ######################################################################## [ccpp-arg-table] - name = GFS_rrtmgp_thompsonmp_pre_run + name = GFS_rrtmgp_cloud_mp_run type = scheme [nCol] standard_name = horizontal_loop_extent @@ -35,19 +35,12 @@ dimensions = () type = integer intent = in -[doSWrad] - standard_name = flag_for_calling_shortwave_radiation - long_name = logical flags for sw radiation calls +[icloud] + standard_name = control_for_cloud_area_fraction_option + long_name = cloud effect to the optical depth and cloud fraction in radiation units = flag dimensions = () - type = logical - intent = in -[doLWrad] - standard_name = flag_for_calling_longwave_radiation - long_name = logical flags for lw radiation calls - units = flag - dimensions = () - type = logical + type = integer intent = in [i_cldliq] standard_name = index_of_cloud_liquid_water_mixing_ratio_in_tracer_concentration_array @@ -112,6 +105,20 @@ dimensions = () type = integer intent = in +[doSWrad] + standard_name = flag_for_calling_shortwave_radiation + long_name = logical flags for sw radiation calls + units = flag + dimensions = () + type = logical + intent = in +[doLWrad] + standard_name = flag_for_calling_longwave_radiation + long_name = logical flags for lw radiation calls + units = flag + dimensions = () + type = logical + intent = in [effr_in] standard_name = flag_for_cloud_effective_radii long_name = flag for cloud effective radii calculations in GFDL microphysics @@ -119,6 +126,129 @@ dimensions = () type = logical intent = in +[kdt] + standard_name = index_of_timestep + long_name = current forecast iteration + units = index + dimensions = () + type = integer + intent = in +[imp_physics] + standard_name = control_for_microphysics_scheme + long_name = choice of microphysics scheme + units = flag + dimensions = () + type = integer + intent = in +[imp_physics_thompson] + standard_name = identifier_for_thompson_microphysics_scheme + long_name = choice of Thompson microphysics scheme + units = flag + dimensions = () + type = integer + intent = in +[imp_physics_gfdl] + standard_name = identifier_for_gfdl_microphysics_scheme + long_name = choice of GFDL microphysics scheme + units = flag + dimensions = () + type = integer + intent = in +[do_mynnedmf] + standard_name = flag_for_mellor_yamada_nakanishi_niino_pbl_scheme + long_name = flag to activate MYNN-EDMF + units = flag + dimensions = () + type = logical + intent = in +[uni_cld] + standard_name = flag_for_shoc_cloud_area_fraction_for_radiation + long_name = flag for uni_cld + units = flag + dimensions = () + type = logical + intent = in +[lmfdeep2] + standard_name = flag_for_scale_aware_mass_flux_deep_convection_for_radiation + long_name = flag for some scale-aware mass-flux convection scheme active + units = flag + dimensions = () + type = logical + intent = in +[lmfshal] + standard_name = flag_for_cloud_area_fraction_option_for_radiation + long_name = flag for lmfshal + units = flag + dimensions = () + type = logical + intent = in +[ltaerosol] + standard_name = flag_for_aerosol_physics + long_name = flag for aerosol physics + units = flag + dimensions = () + type = logical + intent = in +[imfdeepcnv] + standard_name = control_for_deep_convection_scheme + long_name = flag for mass-flux deep convection scheme + units = flag + dimensions = () + type = integer + intent = in +[imfdeepcnv_gf] + standard_name = identifier_for_grell_freitas_deep_convection + long_name = flag for Grell-Freitas deep convection scheme + units = flag + dimensions = () + type = integer + intent = in +[imfdeepcnv_samf] + standard_name = identifer_for_scale_aware_mass_flux_deep_convection + long_name = flag for SAMF deep convection scheme + units = flag + dimensions = () + type = integer + intent = in +[lgfdlmprad] + standard_name = flag_for_GFDL_microphysics_radiation_interaction + long_name = flag for GFDL microphysics-radiation interaction + units = flag + dimensions = () + type = logical + intent = in +[lsmask] + standard_name = area_type + long_name = landmask: sea/land/ice=0/1/2 + units = flag + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[xlat] + standard_name = latitude + long_name = latitude + units = radian + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[xlon] + standard_name = longitude + long_name = longitude + units = radian + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[dx] + standard_name = characteristic_grid_lengthscale + long_name = relative dx for the grid cell + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in [p_lev] standard_name = air_pressure_at_interface_for_RRTMGP long_name = air pressure at vertical interface for radiation calculation @@ -151,6 +281,30 @@ type = real kind = kind_phys intent = in +[qs_lay] + standard_name = saturation_vapor_pressure + long_name = saturation vapor pressure + units = Pa + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[q_lay] + standard_name = water_vapor_mixing_ratio + long_name = water vaport mixing ratio + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[relhum] + standard_name = relative_humidity + long_name = layer relative humidity + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in [effrin_cldliq] standard_name = effective_radius_of_stratiform_cloud_liquid_water_particle long_name = eff. radius of cloud liquid water particle in micrometer @@ -167,6 +321,14 @@ type = real kind = kind_phys intent = inout +[effrin_cldrain] + standard_name = effective_radius_of_stratiform_cloud_rain_particle + long_name = effective radius of cloud rain particle in micrometers + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in [effrin_cldsnow] standard_name = effective_radius_of_stratiform_cloud_snow_particle long_name = effective radius of cloud snow particle in micrometers @@ -183,26 +345,66 @@ type = real kind = kind_phys intent = in -[qs_lay] - standard_name = saturation_vapor_pressure - long_name = saturation vapor pressure +[cnv_mixratio] + standard_name = convective_cloud_water_mixing_ratio + long_name = moist convective cloud water mixing ratio + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_frac] + standard_name = convective_cloud_fraction_for_RRTMGP + long_name = layer convective cloud fraction + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[qci_conv] + standard_name = convective_cloud_condesate_after_rainout + long_name = convective cloud condesate after rainout + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[deltaZ] + standard_name = layer_thickness + long_name = layer_thickness + units = m + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[deltaZc] + standard_name = layer_thickness_from_layer_center + long_name = layer_thickness + units = m + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[deltaP] + standard_name = layer_thickness_in_Pa + long_name = layer_thickness_in_Pa units = Pa dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = in -[q_lay] - standard_name = water_vapor_mixing_ratio - long_name = water vaport mixing ratio +[qc_mynn] + standard_name = subgrid_scale_cloud_liquid_water_mixing_ratio + long_name = subgrid cloud water mixing ratio from PBL scheme units = kg kg-1 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = in -[relhum] - standard_name = relative_humidity - long_name = layer relative humidity - units = frac +[qi_mynn] + standard_name = subgrid_scale_cloud_ice_mixing_ratio + long_name = subgrid cloud ice mixing ratio from PBL scheme + units = kg kg-1 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys @@ -231,40 +433,13 @@ type = real kind = kind_phys intent = in -[lmfshal] - standard_name = flag_for_cloud_area_fraction_option_for_radiation - long_name = flag for lmfshal - units = flag - dimensions = () - type = logical - intent = in -[ltaerosol] - standard_name = flag_for_aerosol_physics - long_name = flag for aerosol physics - units = flag - dimensions = () - type = logical - intent = in -[do_mynnedmf] - standard_name = flag_for_mellor_yamada_nakanishi_niino_pbl_scheme - long_name = flag to activate MYNN-EDMF - units = flag - dimensions = () - type = logical - intent = in -[imfdeepcnv] - standard_name = control_for_deep_convection_scheme - long_name = flag for mass-flux deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_gf] - standard_name = identifier_for_grell_freitas_deep_convection - long_name = flag for Grell-Freitas deep convection scheme - units = flag +[con_ttp] + standard_name = triple_point_temperature_of_water + long_name = triple point temperature of water + units = K dimensions = () - type = integer + type = real + kind = kind_phys intent = in [doGP_cldoptics_PADE] standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_PADE @@ -360,6 +535,110 @@ type = real kind = kind_phys intent = inout +[cld_cnv_lwp] + standard_name = convective_cloud_liquid_water_path + long_name = layer convective cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[cld_cnv_iwp] + standard_name = convective_cloud_ice_water_path + long_name = layer convective cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[cld_cnv_reliq] + standard_name = mean_effective_radius_for_liquid_convective_cloud + long_name = mean effective radius for liquid convective cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[cld_cnv_reice] + standard_name = mean_effective_radius_for_ice_convective_cloud + long_name = mean effective radius for ice convective cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[cld_pbl_frac] + standard_name = subgrid_scale_cloud_area_fraction_in_atmosphere_layer + long_name = subgrid cloud fraction from PBL scheme + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_lwp] + standard_name = MYNN_SGS_cloud_liquid_water_path + long_name = layer convective cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[cld_pbl_iwp] + standard_name = MYNN_SGS_cloud_ice_water_path + long_name = layer convective cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[cld_pbl_reliq] + standard_name = mean_effective_radius_for_liquid_MYNN_SGS_cloud + long_name = mean effective radius for liquid MYNN_SGS cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[cld_pbl_reice] + standard_name = mean_effective_radius_for_ice_MYNN_SGS_cloud + long_name = mean effective radius for ice MYNN_SGS cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[lwp_ex] + standard_name = liq_water_path_from_microphysics + long_name = total liquid water path from explicit microphysics + units = kg m-2 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[iwp_ex] + standard_name = ice_water_path_from_microphysics + long_name = total ice water path from explicit microphysics + units = kg m-2 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[lwp_fc] + standard_name = liq_water_path_from_cloud_fraction + long_name = total liquid water path from cloud fraction scheme + units = kg m-2 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[iwp_fc] + standard_name = ice_water_path_from_cloud_fraction + long_name = total ice water path from cloud fraction scheme + units = kg m-2 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/GFS_rrtmgp_cloud_overlap.F90 b/physics/GFS_rrtmgp_cloud_overlap.F90 new file mode 100644 index 000000000..13794641b --- /dev/null +++ b/physics/GFS_rrtmgp_cloud_overlap.F90 @@ -0,0 +1,126 @@ +! ######################################################################################## +! +! ######################################################################################## +module GFS_rrtmgp_cloud_overlap + use machine, only: kind_phys + use radiation_tools, only: check_error_msg + use module_radiation_cloud_overlap, only: cmp_dcorr_lgth, get_alpha_exper + + public GFS_rrtmgp_cloud_overlap_init, GFS_rrtmgp_cloud_overlap_run, GFS_rrtmgp_cloud_overlap_finalize + +contains + ! ###################################################################################### + ! ###################################################################################### +!! \section arg_table_GFS_rrtmgp_cloud_overlap_run +!! \htmlinclude GFS_rrtmgp_cloud_overlap_run.html +!! + subroutine GFS_rrtmgp_cloud_overlap_run(nCol, nLev, yearlen, doSWrad, doLWrad, & + julian, lat, p_lev, p_lay, tv_lay, deltaZc, con_pi, con_g, con_rd, con_epsq, & + dcorr_con, idcor, iovr, iovr_dcorr, iovr_exp, iovr_exprand, idcor_con, & + idcor_hogan, idcor_oreopoulos, cld_frac, cld_cnv_frac, iovr_convcld, top_at_1, & + imfdeepcnv, imfdeepcnv_gf, imfdeepcnv_samf, de_lgth, cloud_overlap_param, & + cnv_cloud_overlap_param, precip_overlap_param, errmsg, errflg) + implicit none + + ! Inputs + integer, intent(in) :: & + nCol, & ! Number of horizontal grid points + nLev, & ! Number of vertical layers + yearlen, & ! Length of current year (365/366) WTF? + imfdeepcnv, & ! + imfdeepcnv_gf, & ! + imfdeepcnv_samf, & ! + iovr, & ! Choice of cloud-overlap method + iovr_convcld, & ! Choice of convective cloud-overlap method + iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method + iovr_exp, & ! Flag for exponential cloud overlap method + iovr_exprand, & ! Flag for exponential-random cloud overlap method + idcor, & ! Choice of method for decorrelation length computation + idcor_con, & ! Flag for decorrelation-length. Use constant value + idcor_hogan, & ! Flag for decorrelation-length. (https://rmets.onlinelibrary.wiley.com/doi/full/10.1002/qj.647) + idcor_oreopoulos ! Flag for decorrelation-length. (10.5194/acp-12-9097-2012) + logical, intent(in) :: & + top_at_1, & ! Vertical ordering flag + doSWrad, & ! Call SW radiation? + doLWrad ! Call LW radiation + real(kind_phys), intent(in) :: & + julian, & ! Julian day + con_pi, & ! Physical constant: pi + con_g, & ! Physical constant: gravitational constant + con_rd, & ! Physical constant: gas-constant for dry air + con_epsq, & ! Physical constant: Minimum value for specific humidity + dcorr_con ! Decorrelation-length (used if idcor = idcor_con) + real(kind_phys), dimension(:), intent(in) :: & + lat ! Latitude + real(kind_phys), dimension(:,:), intent(in) :: & + tv_lay, & ! Virtual temperature (K) + p_lay, & ! Pressure at model-layers (Pa) + cld_frac, & ! Total cloud fraction + cld_cnv_frac ! Convective cloud-fraction + real(kind_phys), dimension(:,:), intent(in) :: & + p_lev, & ! Pressure at model-level interfaces (Pa) + deltaZc ! Layer thickness (from layer-centers)(m) + + ! Outputs + real(kind_phys), dimension(:),intent(out) :: & + de_lgth ! Decorrelation length + real(kind_phys), dimension(:,:),intent(out) :: & + cloud_overlap_param, & ! Cloud-overlap parameter + cnv_cloud_overlap_param,& ! Convective cloud-overlap parameter + precip_overlap_param ! Precipitation overlap parameter + character(len=*), intent(out) :: & + errmsg ! Error message + integer, intent(out) :: & + errflg ! Error flag + + ! Local variables + integer :: iCol,iLay + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + if (.not. (doSWrad .or. doLWrad)) return + + ! + ! Cloud decorrelation length + ! + if (idcor == idcor_hogan) then + call cmp_dcorr_lgth(nCol, lat, con_pi, de_lgth) + endif + if (idcor == idcor_oreopoulos) then + call cmp_dcorr_lgth(nCol, lat*(180._kind_phys/con_pi), julian, yearlen, de_lgth) + endif + if (idcor == idcor_con) then + de_lgth(:) = dcorr_con + endif + + ! + ! Cloud overlap parameter + ! + if (iovr == iovr_dcorr .or. iovr == iovr_exp .or. iovr == iovr_exprand) then + call get_alpha_exper(nCol, nLev, iovr, iovr_exprand, deltaZc*0.001, de_lgth, cld_frac, cloud_overlap_param) + else + de_lgth(:) = 0. + cloud_overlap_param(:,:) = 0. + endif + + ! + ! Convective cloud overlap parameter + ! + if (imfdeepcnv == imfdeepcnv_samf .or. imfdeepcnv == imfdeepcnv_gf) then + if (iovr_convcld == iovr_dcorr .or. iovr_convcld == iovr_exp .or. iovr_convcld == iovr_exprand) then + call get_alpha_exper(nCol, nLev, iovr_convcld, iovr_exprand, deltaZc*0.001, de_lgth, cld_cnv_frac, cnv_cloud_overlap_param) + else + de_lgth(:) = 0. + cnv_cloud_overlap_param(:,:) = 0. + endif + endif + + ! + ! Compute precipitation overlap parameter (Hack. Using same as cloud for now) + ! + precip_overlap_param = cloud_overlap_param + + end subroutine GFS_rrtmgp_cloud_overlap_run +end module GFS_rrtmgp_cloud_overlap diff --git a/physics/GFS_rrtmgp_cloud_overlap_pre.meta b/physics/GFS_rrtmgp_cloud_overlap.meta similarity index 81% rename from physics/GFS_rrtmgp_cloud_overlap_pre.meta rename to physics/GFS_rrtmgp_cloud_overlap.meta index a4620cfa2..f7d12bed5 100644 --- a/physics/GFS_rrtmgp_cloud_overlap_pre.meta +++ b/physics/GFS_rrtmgp_cloud_overlap.meta @@ -1,11 +1,11 @@ [ccpp-table-properties] - name = GFS_rrtmgp_cloud_overlap_pre + name = GFS_rrtmgp_cloud_overlap type = scheme dependencies = radiation_tools.F90, radiation_cloud_overlap.F90 ######################################################################## [ccpp-arg-table] - name = GFS_rrtmgp_cloud_overlap_pre_run + name = GFS_rrtmgp_cloud_overlap_run type = scheme [nCol] standard_name = horizontal_loop_extent @@ -82,6 +82,14 @@ type = real kind = kind_phys intent = in +[deltaZc] + standard_name = layer_thickness_from_layer_center + long_name = layer_thickness + units = m + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in [con_pi] standard_name = pi long_name = ratio of a circle's circumference to its diameter @@ -136,6 +144,13 @@ dimensions = () type = integer intent = in +[iovr_convcld] + standard_name = flag_for_convective_cloud_overlap_method_for_radiation + long_name = flag for convective cloud overlap method + units = flag + dimensions = () + type = integer + intent = in [iovr_dcorr] standard_name = flag_for_decorrelation_length_cloud_overlap_method long_name = choice of decorrelation-length cloud overlap method @@ -186,6 +201,14 @@ type = real kind = kind_phys intent = in +[cld_cnv_frac] + standard_name = convective_cloud_fraction_for_RRTMGP + long_name = layer convective cloud fraction + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in [top_at_1] standard_name = flag_for_vertical_ordering_in_RRTMGP long_name = flag for vertical ordering in RRTMGP @@ -193,6 +216,27 @@ dimensions = () type = logical intent = in +[imfdeepcnv] + standard_name = control_for_deep_convection_scheme + long_name = flag for mass-flux deep convection scheme + units = flag + dimensions = () + type = integer + intent = in +[imfdeepcnv_gf] + standard_name = identifier_for_grell_freitas_deep_convection + long_name = flag for Grell-Freitas deep convection scheme + units = flag + dimensions = () + type = integer + intent = in +[imfdeepcnv_samf] + standard_name = identifer_for_scale_aware_mass_flux_deep_convection + long_name = flag for SAMF deep convection scheme + units = flag + dimensions = () + type = integer + intent = in [de_lgth] standard_name = cloud_decorrelation_length long_name = cloud decorrelation length @@ -217,10 +261,10 @@ type = real kind = kind_phys intent = out -[deltaZc] - standard_name = layer_thickness - long_name = layer_thickness - units = m +[cnv_cloud_overlap_param] + standard_name = convective_cloud_overlap_param + long_name = convective cloud overlap parameter + units = km dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys diff --git a/physics/GFS_rrtmgp_cloud_overlap_pre.F90 b/physics/GFS_rrtmgp_cloud_overlap_pre.F90 deleted file mode 100644 index f85621d8f..000000000 --- a/physics/GFS_rrtmgp_cloud_overlap_pre.F90 +++ /dev/null @@ -1,182 +0,0 @@ -! ######################################################################################## -! -! ######################################################################################## -module GFS_rrtmgp_cloud_overlap_pre - use machine, only: kind_phys - use radiation_tools, only: check_error_msg - use module_radiation_cloud_overlap, only: cmp_dcorr_lgth, get_alpha_exp - - public GFS_rrtmgp_cloud_overlap_pre_init, GFS_rrtmgp_cloud_overlap_pre_run, GFS_rrtmgp_cloud_overlap_pre_finalize - -contains - ! ###################################################################################### - ! ###################################################################################### - subroutine GFS_rrtmgp_cloud_overlap_pre_init() - end subroutine GFS_rrtmgp_cloud_overlap_pre_init - - ! ###################################################################################### - ! ###################################################################################### -!! \section arg_table_GFS_rrtmgp_cloud_overlap_pre_run -!! \htmlinclude GFS_rrtmgp_cloud_overlap_pre_run.html -!! - subroutine GFS_rrtmgp_cloud_overlap_pre_run(nCol, nLev, yearlen, doSWrad, doLWrad, & - julian, lat, p_lev, p_lay, tv_lay, con_pi, con_g, con_rd, con_epsq, dcorr_con, & - idcor, iovr, iovr_dcorr, iovr_exp, iovr_exprand, idcor_con, idcor_hogan, & - idcor_oreopoulos, cld_frac, top_at_1, & - de_lgth, cloud_overlap_param, precip_overlap_param, deltaZc, errmsg, errflg) - implicit none - - ! Inputs - integer, intent(in) :: & - nCol, & ! Number of horizontal grid points - nLev, & ! Number of vertical layers - yearlen, & ! Length of current year (365/366) WTF? - iovr, & ! Choice of cloud-overlap method - iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method - iovr_exp, & ! Flag for exponential cloud overlap method - iovr_exprand, & ! Flag for exponential-random cloud overlap method - idcor, & ! Choice of method for decorrelation length computation - idcor_con, & ! Flag for decorrelation-length. Use constant value - idcor_hogan, & ! Flag for decorrelation-length. (https://rmets.onlinelibrary.wiley.com/doi/full/10.1002/qj.647) - idcor_oreopoulos ! Flag for decorrelation-length. (10.5194/acp-12-9097-2012) - logical, intent(in) :: & - top_at_1, & ! Vertical ordering flag - doSWrad, & ! Call SW radiation? - doLWrad ! Call LW radiation - real(kind_phys), intent(in) :: & - julian, & ! Julian day - con_pi, & ! Physical constant: pi - con_g, & ! Physical constant: gravitational constant - con_rd, & ! Physical constant: gas-constant for dry air - con_epsq, & ! Physical constant: Minimum value for specific humidity - dcorr_con ! Decorrelation-length (used if idcor = idcor_con) - real(kind_phys), dimension(:), intent(in) :: & - lat ! Latitude - real(kind_phys), dimension(:,:), intent(in) :: & - tv_lay, & ! Virtual temperature (K) - p_lay, & ! Pressure at model-layers (Pa) - cld_frac ! Total cloud fraction - real(kind_phys), dimension(:,:), intent(in) :: & - p_lev ! Pressure at model-level interfaces (Pa) - - ! Outputs - real(kind_phys), dimension(:),intent(out) :: & - de_lgth ! Decorrelation length - real(kind_phys), dimension(:,:),intent(out) :: & - cloud_overlap_param, & ! Cloud-overlap parameter - precip_overlap_param, & ! Precipitation overlap parameter - deltaZc ! Layer thickness (from layer-centers)(km) - character(len=*), intent(out) :: & - errmsg ! Error message - integer, intent(out) :: & - errflg ! Error flag - - ! Local variables - real(kind_phys) :: tem1,pfac - real(kind_phys), dimension(nLev+1) :: hgtb - real(kind_phys), dimension(nLev) :: hgtc - integer :: iCol,iLay,l - real(kind_phys), dimension(nCol,nLev) :: deltaZ - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. (doSWrad .or. doLWrad)) return - - ! - ! Compute layer-thickness between layer boundaries (deltaZ) and layer centers (deltaZc) - ! - do iCol=1,nCol - if (top_at_1) then - ! Layer thickness (km) - do iLay=1,nLev - deltaZ(iCol,iLay) = ((con_rd/con_g)*0.001) * abs(log(p_lev(iCol,iLay+1)) - log(p_lev(iCol,iLay))) * tv_lay(iCol,iLay) - enddo - ! Height at layer boundaries - hgtb(nLev+1) = 0._kind_phys - do iLay=nLev,1,-1 - hgtb(iLay)= hgtb(iLay+1) + deltaZ(iCol,iLay) - enddo - ! Height at layer centers - do iLay = nLev, 1, -1 - pfac = abs(log(p_lev(iCol,iLay+1)) - log(p_lay(iCol,iLay))) / & - abs(log(p_lev(iCol,iLay+1)) - log(p_lev(iCol,iLay))) - hgtc(iLay) = hgtb(iLay+1) + pfac * (hgtb(iLay) - hgtb(iLay+1)) - enddo - ! Layer thickness between centers - do iLay = nLev-1, 1, -1 - deltaZc(iCol,iLay) = hgtc(iLay) - hgtc(iLay+1) - enddo - deltaZc(iCol,nLev) = hgtc(nLev) - hgtb(nLev+1) - else - do iLay=nLev,1,-1 - deltaZ(iCol,iLay) = ((con_rd/con_g)*0.001) * abs(log(p_lev(iCol,iLay)) - log(p_lev(iCol,iLay+1))) * tv_lay(iCol,iLay) - enddo - ! Height at layer boundaries - hgtb(1) = 0._kind_phys - do iLay=1,nLev - hgtb(iLay+1)= hgtb(iLay) + deltaZ(iCol,iLay) - enddo - ! Height at layer centers - do iLay = 1, nLev - pfac = abs(log(p_lev(iCol,iLay)) - log(p_lay(iCol,iLay) )) / & - abs(log(p_lev(iCol,iLay)) - log(p_lev(iCol,iLay+1))) - hgtc(iLay) = hgtb(iLay) + pfac * (hgtb(iLay+1) - hgtb(iLay)) - enddo - ! Layer thickness between centers - do iLay = 2, nLev - deltaZc(iCol,iLay) = hgtc(iLay) - hgtc(iLay-1) - enddo - deltaZc(iCol,1) = hgtc(1) - hgtb(1) - endif - enddo - - ! - ! Cloud decorrelation length - ! - if (idcor == idcor_hogan) then - call cmp_dcorr_lgth(nCol, lat, con_pi, de_lgth) - endif - if (idcor == idcor_oreopoulos) then - call cmp_dcorr_lgth(nCol, lat*(180._kind_phys/con_pi), julian, yearlen, de_lgth) - endif - if (idcor == idcor_con) then - de_lgth(:) = dcorr_con - endif - - ! - ! Cloud overlap parameter - ! - if (iovr == iovr_dcorr .or. iovr == iovr_exp .or. iovr == iovr_exprand) then - call get_alpha_exp(nCol, nLev, deltaZc, de_lgth, cloud_overlap_param) - else - de_lgth(:) = 0. - cloud_overlap_param(:,:) = 0. - endif - - ! For exponential random overlap... - ! Decorrelate layers when a clear layer follows a cloudy layer to enforce - ! random correlation between non-adjacent blocks of cloudy layers - if (iovr == iovr_exprand) then - do iLay = 1, nLev - do iCol = 1, nCol - if (cld_frac(iCol,iLay) .eq. 0. .and. cld_frac(iCol,iLay-1) .gt. 0.) then - cloud_overlap_param(iCol,iLay) = 0._kind_phys - endif - enddo - enddo - endif - - ! - ! Compute precipitation overlap parameter (Hack. Using same as cloud for now) - ! - precip_overlap_param = cloud_overlap_param - - end subroutine GFS_rrtmgp_cloud_overlap_pre_run - - ! ######################################################################################### - ! ######################################################################################### - subroutine GFS_rrtmgp_cloud_overlap_pre_finalize() - end subroutine GFS_rrtmgp_cloud_overlap_pre_finalize -end module GFS_rrtmgp_cloud_overlap_pre diff --git a/physics/GFS_rrtmgp_gfdlmp_pre.F90 b/physics/GFS_rrtmgp_gfdlmp_pre.F90 deleted file mode 100644 index 92429fc28..000000000 --- a/physics/GFS_rrtmgp_gfdlmp_pre.F90 +++ /dev/null @@ -1,191 +0,0 @@ -! ######################################################################################## -! This module contains the interface between the GFDL macrophysics and the RRTMGP radiation -! schemes. Only compatable with Model%imp_physics = Model%imp_physics_gfdl -! ######################################################################################## -module GFS_rrtmgp_gfdlmp_pre - use machine, only: kind_phys - use radiation_tools, only: check_error_msg - use module_radiation_cloud_overlap, only: cmp_dcorr_lgth, get_alpha_exp - use rrtmgp_lw_cloud_optics, only: radliq_lwr => radliq_lwrLW, radliq_upr => radliq_uprLW,& - radice_lwr => radice_lwrLW, radice_upr => radice_uprLW - - ! Parameters - real(kind_phys), parameter :: & - reliq_def = 10.0 , & ! Default liq radius to 10 micron (used when effr_in=F) - reice_def = 50.0, & ! Default ice radius to 50 micron (used when effr_in=F) - rerain_def = 1000.0, & ! Default rain radius to 1000 micron (used when effr_in=F) - resnow_def = 250.0, & ! Default snow radius to 250 micron (used when effr_in=F) - reice_min = 10.0, & ! Minimum ice size allowed by GFDL MP scheme - reice_max = 150.0 ! Maximum ice size allowed by GFDL MP scheme - ! NOTE: When using RRTMGP cloud-optics, the min/max particle size allowed are imported - ! from initialization. - - public GFS_rrtmgp_gfdlmp_pre_init, GFS_rrtmgp_gfdlmp_pre_run, GFS_rrtmgp_gfdlmp_pre_finalize - -contains - ! ###################################################################################### - ! ###################################################################################### - subroutine GFS_rrtmgp_gfdlmp_pre_init() - end subroutine GFS_rrtmgp_gfdlmp_pre_init - - ! ###################################################################################### - ! ###################################################################################### -!! \section arg_table_GFS_rrtmgp_gfdlmp_pre_run -!! \htmlinclude GFS_rrtmgp_gfdlmp_pre_run.html -!! - subroutine GFS_rrtmgp_gfdlmp_pre_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, & - i_cldrain, i_cldsnow, i_cldgrpl, i_cldtot, doSWrad, doLWrad, effr_in, kdt, & - do_mynnedmf, p_lev, p_lay, tv_lay, effrin_cldliq, effrin_cldice, effrin_cldrain, & - effrin_cldsnow, tracer, con_g, con_rd, doGP_cldoptics_PADE, doGP_cldoptics_LUT, & - cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, & - cld_rerain, precip_frac, errmsg, errflg) - implicit none - - ! Inputs - integer, intent(in) :: & - nCol, & ! Number of horizontal grid points - nLev, & ! Number of vertical layers - ncnd, & ! Number of cloud condensation types. - nTracers, & ! Number of tracers from model. - i_cldliq, & ! Index into tracer array for cloud liquid. - i_cldice, & ! Index into tracer array for cloud ice. - i_cldrain, & ! Index into tracer array for cloud rain. - i_cldsnow, & ! Index into tracer array for cloud snow. - i_cldgrpl, & ! Index into tracer array for cloud groupel. - i_cldtot, & ! Index into tracer array for cloud total amount. - kdt ! Current forecast iteration - logical, intent(in) :: & - doSWrad, & ! Call SW radiation? - doLWrad, & ! Call LW radiation - effr_in, & ! Provide hydrometeor radii from macrophysics? - do_mynnedmf, & ! Flag to activate MYNN-EDMF - doGP_cldoptics_LUT, & ! Flag to do GP cloud-optics (LUTs) - doGP_cldoptics_PADE ! (PADE approximation) - real(kind_phys), intent(in) :: & - con_g, & ! Physical constant: gravitational constant - con_rd ! Physical constant: gas-constant for dry air - real(kind_phys), dimension(:,:), intent(in) :: & - tv_lay, & ! Virtual temperature (K) - p_lay, & ! Pressure at model-layers (Pa) - effrin_cldliq, & ! Effective radius for liquid cloud-particles (microns) - effrin_cldice, & ! Effective radius for ice cloud-particles (microns) - effrin_cldrain, & ! Effective radius for rain cloud-particles (microns) - effrin_cldsnow ! Effective radius for snow cloud-particles (microns) - real(kind_phys), dimension(:,:), intent(in) :: & - p_lev ! Pressure at model-level interfaces (Pa) - real(kind_phys), dimension(:,:,:),intent(in) :: & - tracer ! Cloud condensate amount in layer by type () - - ! Outputs - real(kind_phys), dimension(:,:),intent(inout) :: & - cld_frac, & ! Total cloud fraction - cld_lwp, & ! Cloud liquid water path - cld_reliq, & ! Cloud liquid effective radius - cld_iwp, & ! Cloud ice water path - cld_reice, & ! Cloud ice effecive radius - cld_swp, & ! Cloud snow water path - cld_resnow, & ! Cloud snow effective radius - cld_rwp, & ! Cloud rain water path - cld_rerain, & ! Cloud rain effective radius - precip_frac ! Precipitation fraction - character(len=*), intent(out) :: & - errmsg ! Error message - integer, intent(out) :: & - errflg ! Error flag - - ! Local variables - real(kind_phys) :: tem1,pfac - real(kind_phys), dimension(nCol, nLev, min(4,ncnd)) :: cld_condensate - integer :: iCol,iLay,l,ncndl - real(kind_phys), dimension(nCol,nLev) :: deltaP,deltaZ - - if (.not. (doSWrad .or. doLWrad)) return - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - ! Test inputs - if (ncnd .ne. 5 .and. ncnd .ne. 6 ) then - errmsg = 'Incorrect number of cloud condensates provided' - errflg = 1 - call check_error_msg('GFS_rrtmgp_gfdlmp_pre_run',errmsg) - return - endif - - ! Initialize outputs - cld_reliq(:,:) = reliq_def - cld_reice(:,:) = reice_def - cld_rerain(:,:) = rerain_def - cld_resnow(:,:) = resnow_def - - ! #################################################################################### - ! Pull out cloud information for GFDL MP scheme. - ! #################################################################################### - ! Condensate - cld_condensate(1:nCol,1:nLev,1) = tracer(1:nCol,1:nLev,i_cldliq) ! -liquid water - cld_condensate(1:nCol,1:nLev,2) = tracer(1:nCol,1:nLev,i_cldice) ! -ice water - cld_condensate(1:nCol,1:nLev,3) = tracer(1:nCol,1:nLev,i_cldrain) ! -rain water - cld_condensate(1:nCol,1:nLev,4) = tracer(1:nCol,1:nLev,i_cldsnow) + &! -snow + grapuel - tracer(1:nCol,1:nLev,i_cldgrpl) - - ! Cloud water path (g/m2) - deltaP = abs(p_lev(:,2:nLev+1)-p_lev(:,1:nLev))/100. - do iLay = 1, nLev - do iCol = 1, nCol - ! Compute liquid/ice condensate path from mixing ratios (kg/kg)->(g/m2) - tem1 = (1.0e5/con_g) * deltaP(iCol,iLay) - cld_lwp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,1) * tem1) - cld_iwp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,2) * tem1) - cld_rwp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,3) * tem1) - cld_swp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,4) * tem1) - enddo - enddo - - ! Particle size - do iLay = 1, nLev - do iCol = 1, nCol - ! Use radii provided from the macrophysics - if (effr_in) then - cld_reliq(iCol,iLay) = effrin_cldliq(iCol,iLay) - cld_reice(iCol,iLay) = max(reice_min, min(reice_max,effrin_cldice(iCol,iLay))) - cld_rerain(iCol,iLay) = effrin_cldrain(iCol,iLay) - cld_resnow(iCol,iLay) = effrin_cldsnow(iCol,iLay) - endif - enddo - enddo - - ! Bound effective radii for RRTMGP, LUT's for cloud-optics go from - ! 2.5 - 21.5 microns for liquid clouds, - ! 10 - 180 microns for ice-clouds - if (doGP_cldoptics_PADE .or. doGP_cldoptics_LUT) then - where(cld_reliq .lt. radliq_lwr) cld_reliq = radliq_lwr - where(cld_reliq .gt. radliq_upr) cld_reliq = radliq_upr - where(cld_reice .lt. radice_lwr) cld_reice = radice_lwr - where(cld_reice .gt. radice_upr) cld_reice = radice_upr - endif - - ! Cloud-fraction. For mynnedmf, cld_frac is adjusted for precipitation here, otherwise - ! it passes through this interface. It is adjusted prior in sgscloudradpre. - if (do_mynnedmf .and. kdt .gt. 1) then - do iLay = 1, nLev - do iCol = 1, nCol - if (tracer(iCol,iLay,i_cldrain) > 1.0e-7 .OR. tracer(iCol,iLay,i_cldsnow)>1.0e-7) then - cld_frac(iCol,iLay) = tracer(iCol,iLay,i_cldtot) - endif - enddo - enddo - else - cld_frac(1:nCol,1:nLev) = tracer(1:nCol,1:nLev,i_cldtot) - endif - - ! Precipitation fraction (Hack. For now use cloud-fraction) - precip_frac(1:nCol,1:nLev) = cld_frac(1:nCol,1:nLev) - - end subroutine GFS_rrtmgp_gfdlmp_pre_run - - ! ######################################################################################### - ! ######################################################################################### - subroutine GFS_rrtmgp_gfdlmp_pre_finalize() - end subroutine GFS_rrtmgp_gfdlmp_pre_finalize -end module GFS_rrtmgp_gfdlmp_pre diff --git a/physics/GFS_rrtmgp_gfdlmp_pre.meta b/physics/GFS_rrtmgp_gfdlmp_pre.meta deleted file mode 100644 index c45054613..000000000 --- a/physics/GFS_rrtmgp_gfdlmp_pre.meta +++ /dev/null @@ -1,303 +0,0 @@ -[ccpp-table-properties] - name = GFS_rrtmgp_gfdlmp_pre - type = scheme - dependencies = radiation_tools.F90, radiation_cloud_overlap.F90, rrtmgp_lw_cloud_optics.F90 - -######################################################################## -[ccpp-arg-table] - name = GFS_rrtmgp_gfdlmp_pre_run - type = scheme -[nCol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[nTracers] - standard_name = number_of_tracers - long_name = number of tracers - units = count - dimensions = () - type = integer - intent = in -[ncnd] - standard_name = number_of_condensate_species - long_name = number of cloud condensate types - units = count - dimensions = () - type = integer - intent = in -[i_cldliq] - standard_name = index_of_cloud_liquid_water_mixing_ratio_in_tracer_concentration_array - long_name = tracer index for cloud condensate (or liquid water) - units = index - dimensions = () - type = integer - intent = in -[i_cldice] - standard_name = index_of_cloud_ice_mixing_ratio_in_tracer_concentration_array - long_name = tracer index for ice water - units = index - dimensions = () - type = integer - intent = in -[i_cldrain] - standard_name = index_of_rain_mixing_ratio_in_tracer_concentration_array - long_name = tracer index for rain water - units = index - dimensions = () - type = integer - intent = in -[i_cldsnow] - standard_name = index_of_snow_mixing_ratio_in_tracer_concentration_array - long_name = tracer index for snow water - units = index - dimensions = () - type = integer - intent = in -[i_cldgrpl] - standard_name = index_of_graupel_mixing_ratio_in_tracer_concentration_array - long_name = tracer index for graupel - units = index - dimensions = () - type = integer - intent = in -[i_cldtot] - standard_name = index_of_cloud_area_fraction_in_atmosphere_layer_in_tracer_concentration_array - long_name = tracer index for cloud amount integer - units = index - dimensions = () - type = integer - intent = in -[doSWrad] - standard_name = flag_for_calling_shortwave_radiation - long_name = logical flags for sw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[doLWrad] - standard_name = flag_for_calling_longwave_radiation - long_name = logical flags for lw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[effr_in] - standard_name = flag_for_cloud_effective_radii - long_name = flag for cloud effective radii calculations in GFDL microphysics - units = flag - dimensions = () - type = logical - intent = in -[kdt] - standard_name = index_of_timestep - long_name = current forecast iteration - units = index - dimensions = () - type = integer - intent = in -[do_mynnedmf] - standard_name = flag_for_mellor_yamada_nakanishi_niino_pbl_scheme - long_name = flag to activate MYNN-EDMF - units = flag - dimensions = () - type = logical - intent = in -[p_lev] - standard_name = air_pressure_at_interface_for_RRTMGP - long_name = air pressure at vertical interface for radiation calculation - units = Pa - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[p_lay] - standard_name = air_pressure_at_layer_for_RRTMGP - long_name = air pressure at vertical layer for radiation calculation - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[tv_lay] - standard_name = virtual_temperature - long_name = layer virtual temperature - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[effrin_cldliq] - standard_name = effective_radius_of_stratiform_cloud_liquid_water_particle - long_name = eff. radius of cloud liquid water particle in micrometer - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[effrin_cldice] - standard_name = effective_radius_of_stratiform_cloud_ice_particle - long_name = eff. radius of cloud ice water particle in micrometer - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[effrin_cldrain] - standard_name = effective_radius_of_stratiform_cloud_rain_particle - long_name = effective radius of cloud rain particle in micrometers - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[effrin_cldsnow] - standard_name = effective_radius_of_stratiform_cloud_snow_particle - long_name = effective radius of cloud snow particle in micrometers - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[tracer] - standard_name = chemical_tracers - long_name = chemical tracers - units = g g-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) - type = real - kind = kind_phys - intent = in -[con_g] - standard_name = gravitational_acceleration - long_name = gravitational acceleration - units = m s-2 - dimensions = () - type = real - kind = kind_phys - intent = in -[con_rd] - standard_name = gas_constant_of_dry_air - long_name = ideal gas constant for dry air - units = J kg-1 K-1 - dimensions = () - type = real - kind = kind_phys - intent = in -[doGP_cldoptics_PADE] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_PADE - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_cldoptics_LUT] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_LUT - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[cld_frac] - standard_name = total_cloud_fraction - long_name = layer total cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[cld_lwp] - standard_name = cloud_liquid_water_path - long_name = layer cloud liquid water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[cld_reliq] - standard_name = mean_effective_radius_for_liquid_cloud - long_name = mean effective radius for liquid cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[cld_iwp] - standard_name = cloud_ice_water_path - long_name = layer cloud ice water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[cld_reice] - standard_name = mean_effective_radius_for_ice_cloud - long_name = mean effective radius for ice cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[cld_swp] - standard_name = cloud_snow_water_path - long_name = layer cloud snow water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[cld_resnow] - standard_name = mean_effective_radius_for_snow_flake - long_name = mean effective radius for snow cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[cld_rwp] - standard_name = cloud_rain_water_path - long_name = layer cloud rain water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[cld_rerain] - standard_name = mean_effective_radius_for_rain_drop - long_name = mean effective radius for rain cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[precip_frac] - standard_name = precipitation_fraction_by_layer - long_name = precipitation fraction in each layer - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/GFS_rrtmgp_pre.F90 b/physics/GFS_rrtmgp_pre.F90 index d3620a5fd..faf8d4986 100644 --- a/physics/GFS_rrtmgp_pre.F90 +++ b/physics/GFS_rrtmgp_pre.F90 @@ -99,11 +99,11 @@ end subroutine GFS_rrtmgp_pre_init !! \htmlinclude GFS_rrtmgp_pre_run.html !! subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhswr, fhlwr, & - xlat, xlon, prsl, tgrs, prslk, prsi, qgrs, tsfc, coslat, sinlat, con_eps, con_epsm1,& - con_fvirt, con_epsqs, solhr, minGPpres, maxGPpres, minGPtemp, maxGPtemp, raddt, & - p_lay, t_lay, p_lev, t_lev, tsfg, tsfa, qs_lay, q_lay, tv_lay, relhum, tracer, & - active_gases_array, gas_concentrations, tsfc_radtime, coszen, coszdg, top_at_1, iSFC,& - iTOA, errmsg, errflg) + xlat, xlon, prsl, tgrs, prslk, prsi, qgrs, tsfc, coslat, sinlat, con_g, con_rd, & + con_eps, con_epsm1, con_fvirt, con_epsqs, solhr, minGPpres, maxGPpres, minGPtemp, & + maxGPtemp, raddt, p_lay, t_lay, p_lev, t_lev, tsfg, tsfa, qs_lay, q_lay, tv_lay, & + relhum, tracer, deltaZ, deltaZc, deltaP, active_gases_array, gas_concentrations, & + tsfc_radtime, coszen, coszdg, top_at_1, iSFC, iTOA, errmsg, errflg) ! Inputs integer, intent(in) :: & @@ -122,25 +122,28 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw fhswr, & ! Frequency of SW radiation call. fhlwr ! Frequency of LW radiation call. real(kind_phys), intent(in) :: & + con_g, & ! Physical constant: gravitational constant + con_rd, & ! Physical constant: gas-constant for dry air con_eps, & ! Physical constant: Epsilon (Rd/Rv) con_epsm1, & ! Physical constant: Epsilon (Rd/Rv) minus one con_fvirt, & ! Physical constant: Inverse of epsilon minus one con_epsqs, & ! Physical constant: Minimum saturation mixing-ratio (kg/kg) solhr ! Time in hours after 00z at the current timestep - real(kind_phys), dimension(nCol), intent(in) :: & + real(kind_phys), dimension(:), intent(in) :: & xlon, & ! Longitude xlat, & ! Latitude tsfc, & ! Surface skin temperature (K) coslat, & ! Cosine(latitude) sinlat ! Sine(latitude) - real(kind_phys), dimension(nCol,nLev), intent(in) :: & + real(kind_phys), dimension(:,:), intent(in) :: & prsl, & ! Pressure at model-layer centers (Pa) tgrs, & ! Temperature at model-layer centers (K) - prslk ! Exner function at model layer centers (1) - real(kind_phys), dimension(nCol,nLev+1), intent(in) :: & + prslk, & ! Exner function at model layer centers (1) prsi ! Pressure at model-interfaces (Pa) - real(kind_phys), dimension(nCol,nLev,nTracers), intent(in) :: & + real(kind_phys), dimension(:,:,:), intent(in) :: & qgrs ! Tracer concentrations (kg/kg) + character(len=*), dimension(:), intent(in) :: & + active_gases_array ! List of active gases from namelist as array ! Outputs character(len=*), intent(out) :: & @@ -153,36 +156,38 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw top_at_1 ! Vertical ordering flag real(kind_phys), intent(inout) :: & raddt ! Radiation time-step - real(kind_phys), dimension(ncol), intent(inout) :: & + real(kind_phys), dimension(:), intent(inout) :: & tsfg, & ! Ground temperature tsfa, & ! Skin temperature - tsfc_radtime ! Surface temperature at radiation timestep - real(kind_phys), dimension(nCol,nLev), intent(inout) :: & + tsfc_radtime, & ! Surface temperature at radiation timestep + coszen, & ! Cosine of SZA + coszdg ! Cosine of SZA, daytime + real(kind_phys), dimension(:,:), intent(inout) :: & p_lay, & ! Pressure at model-layer t_lay, & ! Temperature at model layer q_lay, & ! Water-vapor mixing ratio (kg/kg) tv_lay, & ! Virtual temperature at model-layers relhum, & ! Relative-humidity at model-layers - qs_lay ! Saturation vapor pressure at model-layers - real(kind_phys), dimension(nCol,nLev+1), intent(inout) :: & + qs_lay, & ! Saturation vapor pressure at model-layers + deltaZ, & ! Layer thickness (m) + deltaZc, & ! Layer thickness (m) (between layer centers) + deltaP, & ! Layer thickness (Pa) p_lev, & ! Pressure at model-interface t_lev ! Temperature at model-interface - real(kind_phys), dimension(nCol, nLev, nTracers),intent(inout) :: & + real(kind_phys), dimension(:,:,:),intent(inout) :: & tracer ! Array containing trace gases - character(len=*), dimension(:), intent(in) :: & - active_gases_array ! List of active gases from namelist as array type(ty_gas_concs), intent(inout) :: & gas_concentrations ! RRTMGP DDT: gas volumne mixing ratios - real(kind_phys), dimension(:), intent(inout) :: & - coszen, & ! Cosine of SZA - coszdg ! Cosine of SZA, daytime - + ! Local variables - integer :: i, j, iCol, iBand, iLay + integer :: i, j, iCol, iBand, iLay, iLev, iSFC_ilev real(kind_phys),dimension(nCol,nLev) :: vmr_o3, vmr_h2o - real(kind_phys) :: es, tem1, tem2 + real(kind_phys) :: es, tem1, tem2, pfac + real(kind_phys), dimension(nLev+1) :: hgtb + real(kind_phys), dimension(nLev) :: hgtc real(kind_phys), dimension(nCol,nLev) :: o3_lay real(kind_phys), dimension(nCol,nLev, NF_VGAS) :: gas_vmr + real(kind_phys) :: con_rdog ! Initialize CCPP error handling variables errmsg = '' @@ -197,9 +202,11 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw if (top_at_1) then iSFC = nLev iTOA = 1 + iSFC_ilev = iSFC + 1 else iSFC = 1 iTOA = nLev + iSFC_ilev = 1 endif ! ####################################################################################### @@ -220,8 +227,8 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw t_lay(1:NCOL,:) = tgrs(1:NCOL,:) ! Bound temperature/pressure at layer centers. - do iCol=1,NCOL - do iLay=1,nLev + do iLay=1,nLev + do iCol=1,NCOL if (t_lay(iCol,iLay) .le. minGPtemp) then t_lay(iCol,iLay) = minGPtemp + epsilon(minGPtemp) endif @@ -239,6 +246,12 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw ! Temperature at layer-interfaces call cmp_tlev(nCol,nLev,minGPpres,p_lay,t_lay,p_lev,tsfc,t_lev) + do iLev=1,nLev+1 + do iCol=1,nCol + if (t_lev(iCol,iLev) .le. minGPtemp) t_lev(iCol,iLev) = minGPtemp + epsilon(minGPtemp) + if (t_lev(iCol,iLev) .ge. maxGPtemp) t_lev(iCol,iLev) = maxGPtemp - epsilon(maxGPtemp) + enddo + enddo ! Save surface temperature at radiation time-step, used for LW flux adjustment betwen ! radiation calls. @@ -247,8 +260,8 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw ! Compute a bunch of thermodynamic fields needed by the cloud microphysics schemes. ! Relative humidity, saturation mixing-ratio, vapor mixing-ratio, virtual temperature, ! layer thickness,... - do iCol=1,NCOL - do iLay=1,nLev + do iLay=1,nLev + do iCol=1,NCOL es = min( p_lay(iCol,iLay), fpvs( t_lay(iCol,iLay) ) ) ! fpvs and prsl in pa qs_lay(iCol,iLay) = max( con_epsqs, con_eps * es / (p_lay(iCol,iLay) + con_epsm1*es) ) relhum(iCol,iLay) = max( 0._kind_phys, min( 1._kind_phys, max(con_epsqs, q_lay(iCol,iLay))/qs_lay(iCol,iLay) ) ) @@ -256,6 +269,57 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw enddo enddo + ! + ! Compute layer-thickness between layer boundaries (deltaZ) and layer centers (deltaZc) + ! + deltaP = abs(p_lev(:,2:nLev+1)-p_lev(:,1:nLev)) + con_rdog = con_rd/con_g + do iCol=1,nCol + if (top_at_1) then + ! Layer thickness (m) + do iLay=1,nLev + deltaZ(iCol,iLay) = con_rdog * abs(log(p_lev(iCol,iLay+1)) - log(p_lev(iCol,iLay))) * tv_lay(iCol,iLay) + enddo + ! Height at layer boundaries + hgtb(nLev+1) = 0._kind_phys + do iLay=nLev,1,-1 + hgtb(iLay)= hgtb(iLay+1) + deltaZ(iCol,iLay) + enddo + ! Height at layer centers + do iLay = nLev, 1, -1 + pfac = abs(log(p_lev(iCol,iLay+1)) - log(p_lay(iCol,iLay))) / & + abs(log(p_lev(iCol,iLay+1)) - log(p_lev(iCol,iLay))) + hgtc(iLay) = hgtb(iLay+1) + pfac * (hgtb(iLay) - hgtb(iLay+1)) + enddo + ! Layer thickness between centers + do iLay = nLev-1, 1, -1 + deltaZc(iCol,iLay) = hgtc(iLay) - hgtc(iLay+1) + enddo + deltaZc(iCol,nLev) = hgtc(nLev) - hgtb(nLev+1) + else + ! Layer thickness (m) + do iLay=nLev,1,-1 + deltaZ(iCol,iLay) = con_rdog * abs(log(p_lev(iCol,iLay)) - log(p_lev(iCol,iLay+1))) * tv_lay(iCol,iLay) + enddo + ! Height at layer boundaries + hgtb(1) = 0._kind_phys + do iLay=1,nLev + hgtb(iLay+1)= hgtb(iLay) + deltaZ(iCol,iLay) + enddo + ! Height at layer centers + do iLay = 1, nLev + pfac = abs(log(p_lev(iCol,iLay)) - log(p_lay(iCol,iLay) )) / & + abs(log(p_lev(iCol,iLay)) - log(p_lev(iCol,iLay+1))) + hgtc(iLay) = hgtb(iLay) + pfac * (hgtb(iLay+1) - hgtb(iLay)) + enddo + ! Layer thickness between centers + do iLay = 2, nLev + deltaZc(iCol,iLay) = hgtc(iLay) - hgtc(iLay-1) + enddo + deltaZc(iCol,1) = hgtc(1) - hgtb(1) + endif + enddo + ! ####################################################################################### ! Get layer ozone mass mixing ratio ! ####################################################################################### @@ -305,7 +369,7 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw ! ####################################################################################### ! Setup surface ground temperature and ground/air skin temperature if required. ! ####################################################################################### - tsfg(1:NCOL) = tsfc(1:NCOL) + tsfg(1:NCOL) = t_lev(1:NCOL,iSFC_ilev) tsfa(1:NCOL) = t_lay(1:NCOL,iSFC) ! ####################################################################################### diff --git a/physics/GFS_rrtmgp_pre.meta b/physics/GFS_rrtmgp_pre.meta index 501dacfa1..88face855 100644 --- a/physics/GFS_rrtmgp_pre.meta +++ b/physics/GFS_rrtmgp_pre.meta @@ -204,6 +204,22 @@ type = real kind = kind_phys intent = in +[con_g] + standard_name = gravitational_acceleration + long_name = gravitational acceleration + units = m s-2 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_rd] + standard_name = gas_constant_of_dry_air + long_name = ideal gas constant for dry air + units = J kg-1 K-1 + dimensions = () + type = real + kind = kind_phys + intent = in [con_eps] standard_name = ratio_of_dry_air_to_water_vapor_gas_constants long_name = rd/rv @@ -308,6 +324,30 @@ type = real kind = kind_phys intent = inout +[deltaZ] + standard_name = layer_thickness + long_name = layer_thickness + units = m + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[deltaZc] + standard_name = layer_thickness_from_layer_center + long_name = layer_thickness + units = m + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[deltaP] + standard_name = layer_thickness_in_Pa + long_name = layer_thickness_in_Pa + units = Pa + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout [top_at_1] standard_name = flag_for_vertical_ordering_in_RRTMGP long_name = flag for vertical ordering in RRTMGP diff --git a/physics/GFS_rrtmgp_setup.F90 b/physics/GFS_rrtmgp_setup.F90 index d518cb6e3..f7f657b50 100644 --- a/physics/GFS_rrtmgp_setup.F90 +++ b/physics/GFS_rrtmgp_setup.F90 @@ -5,7 +5,7 @@ module GFS_rrtmgp_setup use module_radiation_astronomy, only : sol_init, sol_update use module_radiation_aerosols, only : aer_init, aer_update use module_radiation_gases, only : gas_init, gas_update - use GFS_cloud_diagnostics, only : hml_cloud_diagnostics_initialize + ! use GFS_cloud_diagnostics, only : hml_cloud_diagnostics_initialize ! *NOTE* These parameters below are required radiation_****** modules. They are not ! directly used by the RRTMGP routines. use physparam, only : isolar, ictmflg, ico2flg, ioznflg, iaerflg, & @@ -130,10 +130,10 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, call sol_init ( me ) call aer_init ( levr, me ) call gas_init ( me ) - call hml_cloud_diagnostics_initialize(imp_physics, imp_physics_fer_hires, & - imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & - imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, imp_physics_mg, levr, me, si,& - errflg) + !call hml_cloud_diagnostics_initialize(imp_physics, imp_physics_fer_hires, & + ! imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & + ! imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, imp_physics_mg, levr, me, si,& + ! errflg) if ( me == 0 ) then print *,' return from rad_initialize (GFS_rrtmgp_setup_init) - after calling radinit' diff --git a/physics/GFS_rrtmgp_sw_post.F90 b/physics/GFS_rrtmgp_sw_post.F90 index 377afdadc..fafa162d9 100644 --- a/physics/GFS_rrtmgp_sw_post.F90 +++ b/physics/GFS_rrtmgp_sw_post.F90 @@ -52,7 +52,7 @@ subroutine GFS_rrtmgp_sw_post_run (nCol, nLev, nDay, idxday, lsswr, do_sw_clrsky coszdg ! Cosine(SZA), daytime real(kind_phys), dimension(nCol, nLev+1), intent(in) :: & p_lev ! Pressure @ model layer-interfaces (Pa) - real(kind_phys), dimension(sw_gas_props%get_nband(),ncol), intent(in) :: & + real(kind_phys), dimension(ncol), intent(in) :: & sfc_alb_nir_dir, & ! Surface albedo (direct) sfc_alb_nir_dif, & ! Surface albedo (diffuse) sfc_alb_uvvis_dir, & ! Surface albedo (direct) @@ -170,10 +170,10 @@ subroutine GFS_rrtmgp_sw_post_run (nCol, nLev, nDay, idxday, lsswr, do_sw_clrsky nirdfdi(i) = scmpsw(i)%nirdf visbmdi(i) = scmpsw(i)%visbm visdfdi(i) = scmpsw(i)%visdf - nirbmui(i) = scmpsw(i)%nirbm * sfc_alb_nir_dir(1,i) - nirdfui(i) = scmpsw(i)%nirdf * sfc_alb_nir_dif(1,i) - visbmui(i) = scmpsw(i)%visbm * sfc_alb_uvvis_dir(1,i) - visdfui(i) = scmpsw(i)%visdf * sfc_alb_uvvis_dif(1,i) + nirbmui(i) = scmpsw(i)%nirbm * sfc_alb_nir_dir(i) + nirdfui(i) = scmpsw(i)%nirdf * sfc_alb_nir_dif(i) + visbmui(i) = scmpsw(i)%visbm * sfc_alb_uvvis_dir(i) + visdfui(i) = scmpsw(i)%visdf * sfc_alb_uvvis_dif(i) enddo else ! if_nday_block ! ####################################################################################### diff --git a/physics/GFS_rrtmgp_sw_post.meta b/physics/GFS_rrtmgp_sw_post.meta index 0e93b78e6..7da3b10b0 100644 --- a/physics/GFS_rrtmgp_sw_post.meta +++ b/physics/GFS_rrtmgp_sw_post.meta @@ -112,34 +112,34 @@ kind = kind_phys intent = in [sfc_alb_nir_dir] - standard_name = surface_albedo_nearIR_direct - long_name = near-IR (direct) surface albedo (sfc_alb_nir_dir) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) + standard_name = surface_albedo_due_to_near_IR_direct + long_name = surface albedo due to near IR direct beam + units = frac + dimensions = (horizontal_loop_extent) type = real kind = kind_phys intent = in [sfc_alb_nir_dif] - standard_name = surface_albedo_nearIR_diffuse - long_name = near-IR (diffuse) surface albedo (sfc_alb_nir_dif) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) + standard_name = surface_albedo_due_to_near_IR_diffused + long_name = surface albedo due to near IR diffused beam + units = frac + dimensions = (horizontal_loop_extent) type = real kind = kind_phys intent = in [sfc_alb_uvvis_dir] - standard_name = surface_albedo_uvvis_direct - long_name = UVVIS (direct) surface albedo (sfc_alb_uvvis_dir) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) + standard_name = surface_albedo_due_to_UV_and_VIS_direct + long_name = surface albedo due to UV+VIS direct beam + units = frac + dimensions = (horizontal_loop_extent) type = real kind = kind_phys intent = in [sfc_alb_uvvis_dif] - standard_name = surface_albedo_uvvis_diffuse - long_name = UVVIS (diffuse) surface albedo (sfc_alb_uvvis_dif) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) + standard_name = surface_albedo_due_to_UV_and_VIS_diffused + long_name = surface albedo due to UV+VIS diffused beam + units = frac + dimensions = (horizontal_loop_extent) type = real kind = kind_phys intent = in diff --git a/physics/GFS_rrtmgp_thompsonmp_pre.F90 b/physics/GFS_rrtmgp_thompsonmp_pre.F90 deleted file mode 100644 index 85877704f..000000000 --- a/physics/GFS_rrtmgp_thompsonmp_pre.F90 +++ /dev/null @@ -1,291 +0,0 @@ -! ######################################################################################## -! This module contains the interface between the THOMPSON macrophysics and the RRTMGP radiation -! schemes. Only compatable with Model%imp_physics = Model%imp_physics_thompson -! ######################################################################################## -module GFS_rrtmgp_thompsonmp_pre - use machine, only: & - kind_phys - use radiation_tools, only: & - check_error_msg - use module_mp_thompson, only: & - calc_effectRad, Nt_c, & - re_qc_min, re_qc_max, & - re_qi_min, re_qi_max, & - re_qs_min, re_qs_max - use module_mp_thompson_make_number_concentrations, only: & - make_IceNumber, & - make_DropletNumber, & - make_RainNumber - use rrtmgp_lw_cloud_optics, only: radliq_lwr => radliq_lwrLW, radliq_upr => radliq_uprLW,& - radice_lwr => radice_lwrLW, radice_upr => radice_uprLW - implicit none - - ! Parameters specific to THOMPSON MP scheme. - real(kind_phys), parameter :: & - rerain_def = 1000.0 ! Default rain radius to 1000 microns - - public GFS_rrtmgp_thompsonmp_pre_init, GFS_rrtmgp_thompsonmp_pre_run, GFS_rrtmgp_thompsonmp_pre_finalize - -contains - ! ###################################################################################### - ! ###################################################################################### - subroutine GFS_rrtmgp_thompsonmp_pre_init() - end subroutine GFS_rrtmgp_thompsonmp_pre_init - - ! ###################################################################################### - ! ###################################################################################### -!! \section arg_table_GFS_rrtmgp_thompsonmp_pre_run -!! \htmlinclude GFS_rrtmgp_thompsonmp_pre_run.html -!! - subroutine GFS_rrtmgp_thompsonmp_pre_run(nCol, nLev, nTracers, ncnd, doSWrad, doLWrad, & - i_cldliq, i_cldice, i_cldrain, i_cldsnow, i_cldgrpl, i_cldtot, i_cldliq_nc, & - i_cldice_nc, i_twa, effr_in, p_lev, p_lay, tv_lay, t_lay, effrin_cldliq, & - effrin_cldice, effrin_cldsnow, tracer, qs_lay, q_lay, relhum, con_g, con_rd, & - con_eps, lmfshal, ltaerosol, do_mynnedmf, imfdeepcnv, imfdeepcnv_gf, & - doGP_cldoptics_PADE, doGP_cldoptics_LUT, & - cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, & - cld_rerain, precip_frac, errmsg, errflg) - - ! Inputs - integer, intent(in) :: & - nCol, & ! Number of horizontal grid points - nLev, & ! Number of vertical layers - ncnd, & ! Number of cloud condensation types. - nTracers, & ! Number of tracers from model. - i_cldliq, & ! Index into tracer array for cloud liquid amount. - i_cldice, & ! cloud ice amount. - i_cldrain, & ! cloud rain amount. - i_cldsnow, & ! cloud snow amount. - i_cldgrpl, & ! cloud groupel amount. - i_cldtot, & ! cloud total amount. - i_cldliq_nc, & ! cloud liquid number concentration. - i_cldice_nc, & ! cloud ice number concentration. - i_twa, & ! water friendly aerosol. - imfdeepcnv, & ! Choice of mass-flux deep convection scheme - imfdeepcnv_gf ! Flag for Grell-Freitas deep convection scheme - logical, intent(in) :: & - doSWrad, & ! Call SW radiation? - doLWrad, & ! Call LW radiation - effr_in, & ! Use cloud effective radii provided by model? - lmfshal, & ! Flag for mass-flux shallow convection scheme used by Xu-Randall - ltaerosol, & ! Flag for aerosol option - do_mynnedmf, & ! Flag to activate MYNN-EDMF - doGP_cldoptics_LUT,& ! Flag to do GP cloud-optics (LUTs) - doGP_cldoptics_PADE ! (PADE approximation) - real(kind_phys), intent(in) :: & - con_g, & ! Physical constant: gravitational constant - con_rd, & ! Physical constant: gas-constant for dry air - con_eps ! Physical constant: gas constant air / gas constant H2O - - real(kind_phys), dimension(:,:), intent(in) :: & - tv_lay, & ! Virtual temperature (K) - t_lay, & ! Temperature (K) - qs_lay, & ! Saturation vapor pressure (Pa) - q_lay, & ! water-vapor mixing ratio (kg/kg) - relhum, & ! Relative humidity - p_lay ! Pressure at model-layers (Pa) - real(kind_phys), dimension(:,:), intent(in) :: & - p_lev ! Pressure at model-level interfaces (Pa) - real(kind_phys), dimension(:,:,:),intent(in) :: & - tracer ! Cloud condensate amount in layer by type () - - ! In/Outs - real(kind_phys), dimension(:,:), intent(inout) :: & - cld_frac, & ! Total cloud fraction - cld_lwp, & ! Cloud liquid water path - cld_reliq, & ! Cloud liquid effective radius - cld_iwp, & ! Cloud ice water path - cld_reice, & ! Cloud ice effecive radius - cld_swp, & ! Cloud snow water path - cld_resnow, & ! Cloud snow effective radius - cld_rwp, & ! Cloud rain water path - cld_rerain, & ! Cloud rain effective radius - precip_frac, & ! Precipitation fraction - effrin_cldliq, & ! Effective radius for liquid cloud-particles (microns) - effrin_cldice, & ! Effective radius for ice cloud-particles (microns) - effrin_cldsnow ! Effective radius for snow cloud-particles (microns) - - ! Outputs - character(len=*), intent(out) :: & - errmsg ! Error message - integer, intent(out) :: & - errflg ! Error flag - - ! Local variables - real(kind_phys) :: alpha0, pfac, tem1, cld_mr - real(kind_phys), dimension(nCol, nLev, min(4,ncnd)) :: cld_condensate - integer :: iCol,iLay,l - real(kind_phys) :: rho, orho - real(kind_phys), dimension(nCol,nLev) :: deltaP, deltaZ, re_cloud, re_ice,& - re_snow, qv_mp, qc_mp, qi_mp, qs_mp, nc_mp, ni_mp, nwfa - logical :: top_at_1 - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. (doSWrad .or. doLWrad)) return - - ! Cloud condensate - cld_condensate(1:nCol,1:nLev,1) = tracer(1:nCol,1:nLev,i_cldliq) ! -liquid water - cld_condensate(1:nCol,1:nLev,2) = tracer(1:nCol,1:nLev,i_cldice) ! -ice water - cld_condensate(1:nCol,1:nLev,3) = tracer(1:nCol,1:nLev,i_cldrain) ! -rain water - cld_condensate(1:nCol,1:nLev,4) = tracer(1:nCol,1:nLev,i_cldsnow) + &! -snow + grapuel - tracer(1:nCol,1:nLev,i_cldgrpl) - - ! Cloud water path (g/m2) - deltaP = abs(p_lev(:,2:nLev+1)-p_lev(:,1:nLev))/100. - do iLay = 1, nLev - do iCol = 1, nCol - ! Compute liquid/ice condensate path from mixing ratios (kg/kg)->(g/m2) - tem1 = (1.0e5/con_g) * deltaP(iCol,iLay) - cld_lwp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,1) * tem1) - cld_iwp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,2) * tem1) - cld_rwp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,3) * tem1) - cld_swp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,4) * tem1) - enddo - enddo - - ! Cloud particle sizes and number concentrations... - - ! Prepare cloud mixing-ratios and number concentrations for calc_effectRad, - ! and update number concentrations, consistent with sub-grid clouds - do iLay = 1, nLev - do iCol = 1, nCol - qv_mp(iCol,iLay) = q_lay(iCol,iLay)/(1.-q_lay(iCol,iLay)) - rho = con_eps*p_lay(iCol,iLay)/(con_rd*t_lay(iCol,iLay)*(qv_mp(iCol,iLay)+con_eps)) - orho = 1./rho - qc_mp(iCol,iLay) = tracer(iCol,iLay,i_cldliq) / (1.-q_lay(iCol,iLay)) - qi_mp(iCol,iLay) = tracer(iCol,iLay,i_cldice) / (1.-q_lay(iCol,iLay)) - qs_mp(iCol,iLay) = tracer(iCol,iLay,i_cldsnow) / (1.-q_lay(iCol,iLay)) - ni_mp(iCol,iLay) = tracer(iCol,iLay,i_cldice_nc) / (1.-q_lay(iCol,iLay)) - if (ltaerosol) then - nc_mp(iCol,iLay) = tracer(iCol,iLay,i_cldliq_nc) / (1.-q_lay(iCol,iLay)) - nwfa(iCol,iLay) = tracer(iCol,iLay,i_twa) - if (qc_mp(iCol,iLay) > 1.e-12 .and. nc_mp(iCol,iLay) < 100.) then - nc_mp(iCol,iLay) = make_DropletNumber(qc_mp(iCol,iLay)*rho, nwfa(iCol,iLay)*rho) * orho - endif - else - nc_mp(iCol,iLay) = nt_c*orho - endif - if (qi_mp(iCol,iLay) > 1.e-12 .and. ni_mp(iCol,iLay) < 100.) then - ni_mp(iCol,iLay) = make_IceNumber(qi_mp(iCol,iLay)*rho, t_lay(iCol,iLay)) * orho - endif - enddo - enddo - - ! Compute effective radii for liquid/ice/snow using subgrid scale clouds - ! Call Thompson's subroutine to compute effective radii - do iCol=1,nCol - call calc_effectRad (t_lay(iCol,:), p_lay(iCol,:), qv_mp(iCol,:), qc_mp(iCol,:), & - nc_mp(iCol,:), qi_mp(iCol,:), ni_mp(iCol,:), qs_mp(iCol,:), & - re_cloud(iCol,:), re_ice(iCol,:), re_snow(iCol,:), 1, nLev ) - do iLay = 1, nLev - re_cloud(iCol,iLay) = MAX(re_qc_min, MIN(re_cloud(iCol,iLay), re_qc_max)) - re_ice(iCol,iLay) = MAX(re_qi_min, MIN(re_ice(iCol,iLay), re_qi_max)) - re_snow(iCol,iLay) = MAX(re_qs_min, MIN(re_snow(iCol,iLay), re_qs_max)) - enddo - enddo - - ! Scale Thompson's effective radii from meter to micron - do iLay = 1, nLev - do iCol = 1, nCol - effrin_cldliq(iCol,iLay) = re_cloud(iCol,iLay)*1.e6 - effrin_cldice(iCol,iLay) = re_ice(iCol,iLay)*1.e6 - effrin_cldsnow(iCol,iLay) = re_snow(iCol,iLay)*1.e6 - enddo - enddo - - ! Bound effective radii for RRTMGP, LUT's for cloud-optics go from - ! 2.5 - 21.5 microns for liquid clouds, - ! 10 - 180 microns for ice-clouds - if (doGP_cldoptics_PADE .or. doGP_cldoptics_LUT) then - do iLay = 1, nLev - do iCol = 1, nCol - if (effrin_cldliq(iCol,iLay) .lt. radliq_lwr) effrin_cldliq(iCol,iLay) = radliq_lwr - if (effrin_cldliq(iCol,iLay) .gt. radliq_upr) effrin_cldliq(iCol,iLay) = radliq_upr - if (effrin_cldice(iCol,iLay) .lt. radice_lwr) effrin_cldice(iCol,iLay) = radice_lwr - if (effrin_cldice(iCol,iLay) .gt. radice_upr) effrin_cldice(iCol,iLay) = radice_upr - enddo - enddo - endif - - ! Update global effective radii arrays. - do iLay = 1, nLev - do iCol = 1, nCol - cld_reliq(iCol,iLay) = effrin_cldliq(iCol,iLay) - cld_reice(iCol,iLay) = effrin_cldice(iCol,iLay) - cld_resnow(iCol,iLay) = effrin_cldsnow(iCol,iLay) - cld_rerain(iCol,iLay) = rerain_def - enddo - enddo - ! Compute cloud-fraction. Else, use value provided - if(.not. do_mynnedmf .and. imfdeepcnv .ne. imfdeepcnv_gf ) then ! MYNN PBL or GF conv - ! Cloud-fraction - if( lmfshal) alpha0 = 100. ! Default (from GATE simulations) - if(.not. lmfshal) alpha0 = 2000. - ! Xu-Randall (1996) cloud-fraction - do iLay = 1, nLev - do iCol = 1, nCol - cld_mr = cld_condensate(iCol,iLay,1) + cld_condensate(iCol,iLay,2) + & - cld_condensate(iCol,iLay,4) - cld_frac(iCol,iLay) = cld_frac_XuRandall(p_lay(iCol,iLay), & - qs_lay(iCol,iLay), relhum(iCol,iLay), cld_mr, alpha0) - enddo - enddo - endif - - ! Precipitation fraction (Hack. For now use cloud-fraction) - precip_frac(1:nCol,1:nLev) = cld_frac(1:nCol,1:nLev) - - end subroutine GFS_rrtmgp_thompsonmp_pre_run - - ! ###################################################################################### - ! ###################################################################################### - subroutine GFS_rrtmgp_thompsonmp_pre_finalize() - end subroutine GFS_rrtmgp_thompsonmp_pre_finalize - - ! ###################################################################################### - ! This function computes the cloud-fraction following. - ! Xu-Randall(1996) A Semiempirical Cloudiness Parameterization for Use in Climate Models - ! https://doi.org/10.1175/1520-0469(1996)053<3084:ASCPFU>2.0.CO;2 - ! - ! cld_frac = {1-exp[-alpha*cld_mr/((1-relhum)*qs_lay)**lambda]}*relhum**P - ! - ! ###################################################################################### - function cld_frac_XuRandall(p_lay, qs_lay, relhum, cld_mr, alpha) - - ! Inputs - real(kind_phys), intent(in) :: & - p_lay, & ! Pressure (Pa) - qs_lay, & ! Saturation vapor-pressure (Pa) - relhum, & ! Relative humidity - cld_mr, & ! Total cloud mixing ratio - alpha ! Scheme parameter (default=100) - - ! Outputs - real(kind_phys) :: cld_frac_XuRandall - - ! Locals - real(kind_phys) :: clwt, clwm, onemrh, tem1, tem2, tem3 - - ! Parameters - real(kind_phys) :: & - lambda = 0.50, & ! - P = 0.25 - - clwt = 1.0e-6 * (p_lay*0.001) - if (cld_mr > clwt) then - onemrh = max(1.e-10, 1.0 - relhum) - tem1 = alpha / min(max((onemrh*qs_lay)**lambda,0.0001),1.0) - tem2 = max(min(tem1*(cld_mr - clwt), 50.0 ), 0.0 ) - tem3 = sqrt(sqrt(relhum)) ! This assumes "p" = 0.25. Identical, but cheaper than relhum**p - ! - cld_frac_XuRandall = max( tem3*(1.0-exp(-tem2)), 0.0 ) - else - cld_frac_XuRandall = 0.0 - endif - - return - end function -end module GFS_rrtmgp_thompsonmp_pre diff --git a/physics/GFS_rrtmgp_zhaocarr_pre.F90 b/physics/GFS_rrtmgp_zhaocarr_pre.F90 deleted file mode 100644 index d7eecd090..000000000 --- a/physics/GFS_rrtmgp_zhaocarr_pre.F90 +++ /dev/null @@ -1,253 +0,0 @@ -! ######################################################################################## -! This module contains the interface between the Zhao-Carr macrophysics and the RRTMGP -! radiation schemes. Only compatable with imp_physics = imp_physics_zhaocarr -! ######################################################################################## -module GFS_rrtmgp_zhaocarr_pre - use machine, only: kind_phys - use radiation_tools, only: check_error_msg - use funcphys, only: fpvs - use module_radiation_clouds, only: get_alpha_dcorr - - ! Zhao-Carr MP parameters. - real(kind_phys), parameter :: & - reliq_def = 10.0 , & ! Default liq radius to 10 micron - reice_def = 50.0, & ! Default ice radius to 50 micron - rerain_def = 1000.0, & ! Default rain radius to 1000 micron - resnow_def = 250.0 ! Default snow radius to 250 micron - - public GFS_rrtmgp_zhaocarr_pre_init, GFS_rrtmgp_zhaocarr_pre_run, GFS_rrtmgp_zhaocarr_pre_finalize - -contains - ! ###################################################################################### - ! ###################################################################################### - subroutine GFS_rrtmgp_zhaocarr_pre_init() - end subroutine GFS_rrtmgp_zhaocarr_pre_init - - ! ###################################################################################### - ! ###################################################################################### -!! \section arg_table_GFS_rrtmgp_zhaocarr_pre_run -!! \htmlinclude GFS_rrtmgp_zhaocarr_pre_run.html -!! - subroutine GFS_rrtmgp_zhaocarr_pre_run(nCol, nLev, nCnd, nTracers, i_cldliq, lsswr, & - lslwr, effr_in, uni_cld, lmfshal, lat, lsmask, p_lev, p_lay, t_lay, relhum, & - tv_lay, effrin_cldliq, effrin_cldice, effrin_cldrain, effrin_cldsnow, & - shoc_sgs_cldfrac, cncvw, tracer, & - con_ttp, con_epsq, con_epsqs, con_eps, con_epsm1, con_g, con_rd, con_pi, & - cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, & - cld_rerain, deltaZ, de_lgth, cloud_overlap_param, errmsg, errflg) - implicit none - - ! Inputs - integer, intent(in) :: & - nCol, & ! Number of horizontal grid points - nLev, & ! Number of vertical layers - nCnd, & ! Number of cloud condensation types. - nTracers, & ! Number of tracers from model. - i_cldliq ! Index into tracer array for cloud liquid. - logical, intent(in) :: & - lsswr, & ! Call SW radiation? - lslwr, & ! Call LW radiation - effr_in, & ! Provide hydrometeor radii from macrophysics? - uni_cld, & ! - lmfshal - real(kind_phys), intent(in) :: & - con_eps, & ! rd/rv - con_epsm1, & ! (rd/rv) - 1 - con_epsq, & ! Floor value for specific humidity - con_epsqs, & ! Floor value for saturation mixing ratio - con_g, & ! Gravitational acceleration (m/s2) - con_ttp, & ! Triple point temperature of water (K) - con_rd, & ! Ideal gas constant for dry air (J/kg/K) - con_pi ! Pi - real(kind_phys), dimension(:), intent(in) :: & - lsmask, & ! Land/Sea mask - lat ! Latitude - real(kind_phys), dimension(:, :), intent(in) :: & - tv_lay, & ! Virtual temperature (K) - p_lay, & ! Pressure at model-layers (Pa) - t_lay, & ! Temperature at model-layers (K) - relhum, & ! Relative humidity at model-layers () - effrin_cldliq, & ! Effective radius for liquid cloud-particles (microns) - effrin_cldice, & ! Effective radius for ice cloud-particles (microns) - effrin_cldrain, & ! Effective radius for rain cloud-particles (microns) - effrin_cldsnow, & ! Effective radius for snow cloud-particles (microns) - shoc_sgs_cldfrac, & ! Subgrid-scale cloud fraction from the SHOC scheme - cncvw ! Convective cloud water mixing ratio (kg/kg) - real(kind_phys), dimension(:, :), intent(in) :: & - p_lev ! Pressure at model-level interfaces (Pa) - real(kind_phys), dimension(:, :, :),intent(in) :: & - tracer ! Cloud condensate amount in layer by type () - - ! Outputs - real(kind_phys), dimension(:),intent(out) :: & - de_lgth ! Decorrelation length - real(kind_phys), dimension(:, :),intent(out) :: & - cld_frac, & ! Total cloud fraction - cld_lwp, & ! Cloud liquid water path - cld_reliq, & ! Cloud liquid effective radius - cld_iwp, & ! Cloud ice water path - cld_reice, & ! Cloud ice effecive radius - cld_swp, & ! Cloud snow water path - cld_resnow, & ! Cloud snow effective radius - cld_rwp, & ! Cloud rain water path - cld_rerain, & ! Cloud rain effective radius - deltaZ, & ! Layer thickness (km) - cloud_overlap_param ! Cloud-overlap parameter - character(len=*), intent(out) :: & - errmsg ! Error message - integer, intent(out) :: & - errflg ! Error flag - - ! Local variables - real(kind_phys) :: tem1,tem2,tem3,clwt,onemrh,clwm,clwmin,es,qs,value - real(kind_phys), dimension(nCol, nLev, min(4,nCnd)) :: cld_condensate - integer :: iCol,iLay - real(kind_phys), dimension(nCol,nLev) :: deltaP - - if (.not. (lsswr .or. lslwr)) return - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - ! Initialize outputs - cld_lwp(:,:) = 0.0 - cld_reliq(:,:) = 0.0 - cld_iwp(:,:) = 0.0 - cld_reice(:,:) = 0.0 - cld_rwp(:,:) = 0.0 - cld_rerain(:,:) = 0.0 - cld_swp(:,:) = 0.0 - cld_resnow(:,:) = 0.0 - - ! #################################################################################### - ! Pull out cloud information for Zhao-Carr MP scheme. - ! #################################################################################### - ! Condensate - cld_condensate(1:nCol,1:nLev,1) = tracer(1:nCol,1:nLev,i_cldliq) ! Liquid water - - ! Set really tiny suspended particle amounts to clear - do iLay=1,nLev - do iCol=1,nCol - if (cld_condensate(iCol,iLay,1) < con_epsq) cld_condensate(iCol,iLay,1) = 0.0 - enddo - enddo - - ! Use radii provided from the macrophysics? - if (effr_in) then - cld_reliq(1:nCol,1:nLev) = effrin_cldliq(1:nCol,1:nLev) - cld_reice(1:nCol,1:nLev) = effrin_cldice(1:nCol,1:nLev) - cld_rerain(1:nCol,1:nLev) = effrin_cldrain(1:nCol,1:nLev) - cld_resnow(1:nCol,1:nLev) = effrin_cldsnow(1:nCol,1:nLev) - endif - - ! Use cloud-fraction from SHOC? - if (uni_cld) then - cld_frac(1:nCol,1:nLev) = shoc_sgs_cldfrac(1:nCol,1:nLev) - ! Compute cloud-fraction? - else - clwmin = 0.0e-6 - if (.not. lmfshal) then - do iLay = 1,nLev - do iCol = 1, nCol - es = min( p_lay(iCol,iLay), fpvs( t_lay(iCol,iLay) ) ) ! fpvs and prsl in pa - qs = max( con_epsqs, con_eps * es / (p_lay(iCol,iLay) + con_epsm1*es) ) - clwt = 1.0e-6 * (p_lay(iCol,iLay)*0.00001) - if (cld_condensate(iCol,iLay,1) > clwt) then - onemrh= max( 1.e-10, 1.0-relhum(iCol,iLay) ) - clwm = clwmin / max( 0.01, p_lay(iCol,iLay)*0.00001 ) - tem1 = min(max(sqrt(sqrt(onemrh*qs)),0.0001),1.0) - tem1 = 2000.0 / tem1 - value = max( min( tem1*(cld_condensate(iCol,iLay,1)-clwm), 50.0 ), 0.0 ) - tem2 = sqrt( sqrt(relhum(iCol,iLay)) ) - cld_frac(iCol,iLay) = max( tem2*(1.0-exp(-value)), 0.0 ) - endif - enddo - enddo - else - do iLay=1,nLev - do iCol = 1, nCol - es = min( p_lay(iCol,iLay), fpvs( t_lay(iCol,iLay) ) ) ! fpvs and prsl in pa - qs = max( con_epsqs, con_eps * es / (p_lay(iCol,iLay) + con_epsm1*es) ) - clwt = 1.0e-6 * (p_lay(iCol,iLay)*0.00001) - if (cld_condensate(iCol,iLay,1) > clwt) then - onemrh= max( 1.e-10, 1.0-relhum(iCol,iLay) ) - clwm = clwmin / max( 0.01, p_lay(iCol,iLay)*0.00001 ) - tem1 = min(max((onemrh*qs)**0.49,0.0001),1.0) !jhan - tem1 = 100.0 / tem1 - value = max( min( tem1*(cld_condensate(iCol,iLay,1)-clwm), 50.0 ), 0.0 ) - tem2 = sqrt( sqrt(relhum(iCol,iLay)) ) - cld_frac(iCol,iLay) = max( tem2*(1.0-exp(-value)), 0.0 ) - endif - enddo - enddo - endif - endif - - ! Add suspended convective cloud water to grid-scale cloud water only for cloud - ! fraction & radiation computation it is to enhance cloudiness due to suspended convec - ! cloud water for zhao/moorthi's (imp_phys=99) - cld_condensate(1:nCol,1:nLev,1) = cld_condensate(1:nCol,1:nLev,1) + cncvw(1:nCol,1:nLev) - - ! Compute cloud liquid/ice condensate path. - deltaP = abs(p_lev(:,2:nLev+1)-p_lev(:,1:nLev))/100. - do iLay=1,nLev - do iCol=1,nCol - tem1 = max(0.0, cld_condensate(iCol,iLay,1)) * (1.0e5/con_g) * deltaP(iCol,iLay) - cld_iwp(iCol,iLay) = tem1*(t_lay(iCol,iLay) - 273.16) - cld_lwp(iCol,iLay) = tem1 - cld_iwp(iCol,iLay) - enddo - enddo - - ! Compute effective liquid cloud droplet radius over land. - if(.not. effr_in) then - do iCol = 1, nCol - if (nint(lsmask(iCol)) == 1) then - do iLay = 1, nLev - cld_reliq(iCol,iLay) = 5.0 + 5.0 * (t_lay(iCol,iLay) - 273.16) - enddo - endif - enddo - - ! Compute effective ice cloud droplet radius following Heymsfield - ! and McFarquhar (1996) \cite heymsfield_and_mcfarquhar_1996. - do iLay=1,nLev - do iCol=1,nCol - tem2 = t_lay(iCol,iLay) - con_ttp - if (cld_iwp(iCol,iLay) > 0.0) then - tem3 = (con_g/con_rd ) * cld_iwp(iCol,iLay) * (0.01*p_lay(iCol,iLay)) / (deltaP(iCol,iLay)*tv_lay(iCol,iLay)) - if (tem2 < -50.0) then - cld_reice(iCol,iLay) = (1250.0/9.917) * tem3 ** 0.109 - elseif (tem2 < -40.0) then - cld_reice(iCol,iLay) = (1250.0/9.337) * tem3 ** 0.08 - elseif (tem2 < -30.0) then - cld_reice(iCol,iLay) = (1250.0/9.208) * tem3 ** 0.055 - else - cld_reice(iCol,iLay) = (1250.0/9.387) * tem3 ** 0.031 - endif - cld_reice(iCol,iLay) = max(10.0, min(cld_reice(iCol,iLay), 150.0)) - endif - enddo - enddo - endif - - ! #################################################################################### - ! Cloud (and precipitation) overlap ! #################################################################################### - ! Compute layer-thickness - do iCol=1,nCol - do iLay=1,nLev - deltaZ(iCol,iLay) = ((con_rd/con_g)*0.001) * abs(log(p_lev(iCol,iLay)) - log(p_lev(iCol,iLay+1))) * tv_lay(iCol,iLay) - enddo - enddo - - ! Cloud overlap parameter - call get_alpha_dcorr(nCol, nLev, lat, con_pi, deltaZ, de_lgth, cloud_overlap_param) - - end subroutine GFS_rrtmgp_zhaocarr_pre_run - - ! ######################################################################################### - ! ######################################################################################### - subroutine GFS_rrtmgp_zhaocarr_pre_finalize() - end subroutine GFS_rrtmgp_zhaocarr_pre_finalize - -end module GFS_rrtmgp_zhaocarr_pre diff --git a/physics/GFS_rrtmgp_zhaocarr_pre.meta b/physics/GFS_rrtmgp_zhaocarr_pre.meta deleted file mode 100644 index 2eb333115..000000000 --- a/physics/GFS_rrtmgp_zhaocarr_pre.meta +++ /dev/null @@ -1,366 +0,0 @@ -[ccpp-table-properties] - name = GFS_rrtmgp_zhaocarr_pre - type = scheme - dependencies = radiation_tools.F90 - -######################################################################## -[ccpp-arg-table] - name = GFS_rrtmgp_zhaocarr_pre_run - type = scheme -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[ncnd] - standard_name = number_of_condensate_species - long_name = number of cloud condensate types - units = count - dimensions = () - type = integer - intent = in -[nTracers] - standard_name = number_of_tracers - long_name = number of tracers - units = count - dimensions = () - type = integer - intent = in -[i_cldliq] - standard_name = index_of_cloud_liquid_water_mixing_ratio_in_tracer_concentration_array - long_name = tracer index for cloud condensate (or liquid water) - units = index - dimensions = () - type = integer - intent = in -[lsswr] - standard_name = flag_for_calling_shortwave_radiation - long_name = logical flags for sw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[lslwr] - standard_name = flag_for_calling_longwave_radiation - long_name = logical flags for lw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[effr_in] - standard_name = flag_for_cloud_effective_radii - long_name = flag for cloud effective radii calculations in GFDL microphysics - units = flag - dimensions = () - type = logical - intent = in -[uni_cld] - standard_name = flag_for_shoc_cloud_area_fraction_for_radiation - long_name = flag for uni_cld - units = flag - dimensions = () - type = logical - intent = in -[lmfshal] - standard_name = flag_for_cloud_area_fraction_option_for_radiation - long_name = flag for lmfshal - units = flag - dimensions = () - type = logical - intent = in -[lat] - standard_name = latitude - long_name = latitude - units = radian - dimensions = (horizontal_loop_extent) - type = real - intent = in - kind = kind_phys -[lsmask] - standard_name = area_type - long_name = landmask: sea/land/ice=0/1/2 - units = flag - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[p_lev] - standard_name = air_pressure_at_interface_for_RRTMGP - long_name = air pressure at vertical interface for radiation calculation - units = Pa - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[p_lay] - standard_name = air_pressure_at_layer_for_RRTMGP - long_name = air pressure at vertical layer for radiation calculation - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[t_lay] - standard_name = air_temperature_at_layer_for_RRTMGP - long_name = air temperature at vertical layer for radiation calculation - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[relhum] - standard_name = relative_humidity - long_name = layer relative humidity - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[tv_lay] - standard_name = virtual_temperature - long_name = layer virtual temperature - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[effrin_cldliq] - standard_name = effective_radius_of_stratiform_cloud_liquid_water_particle - long_name = eff. radius of cloud liquid water particle in micrometer - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[effrin_cldice] - standard_name = effective_radius_of_stratiform_cloud_ice_particle - long_name = eff. radius of cloud ice water particle in micrometer - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[effrin_cldrain] - standard_name = effective_radius_of_stratiform_cloud_rain_particle - long_name = effective radius of cloud rain particle in micrometers - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[effrin_cldsnow] - standard_name = effective_radius_of_stratiform_cloud_snow_particle - long_name = effective radius of cloud snow particle in micrometers - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[shoc_sgs_cldfrac] - standard_name = subgrid_scale_cloud_fraction_from_shoc - long_name = subgrid-scale cloud fraction from the SHOC scheme - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cncvw] - standard_name = convective_cloud_condensate_mixing_ratio - long_name = convective cloud water mixing ratio in the phy_f3d array - units = kg kg-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[tracer] - standard_name = chemical_tracers - long_name = chemical tracers - units = g g-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) - type = real - kind = kind_phys - intent = in -[con_ttp] - standard_name = triple_point_temperature_of_water - long_name = triple point temperature of water - units = K - dimensions = () - type = real - kind = kind_phys - intent = in -[con_epsq] - standard_name = minimum_value_of_specific_humidity - long_name = floor value for specific humidity - units = kg kg-1 - dimensions = () - type = real - kind = kind_phys - intent = in -[con_epsqs] - standard_name = minimum_value_of_saturation_mixing_ratio - long_name = floor value for saturation mixing ratio - units = kg kg-1 - dimensions = () - type = real - kind = kind_phys - intent = in -[con_eps] - standard_name = ratio_of_dry_air_to_water_vapor_gas_constants - long_name = rd/rv - units = none - dimensions = () - type = real - kind = kind_phys - intent = in -[con_epsm1] - standard_name = ratio_of_dry_air_to_water_vapor_gas_constants_minus_one - long_name = (rd/rv) - 1 - units = none - dimensions = () - type = real - kind = kind_phys - intent = in -[con_g] - standard_name = gravitational_acceleration - long_name = gravitational acceleration - units = m s-2 - dimensions = () - type = real - kind = kind_phys - intent = in -[con_rd] - standard_name = gas_constant_of_dry_air - long_name = ideal gas constant for dry air - units = J kg-1 K-1 - dimensions = () - type = real - kind = kind_phys - intent = in -[con_pi] - standard_name = pi - long_name = ratio of a circle's circumference to its diameter - units = none - dimensions = () - type = real - kind = kind_phys - intent = in -[cld_frac] - standard_name = total_cloud_fraction - long_name = layer total cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out -[cld_lwp] - standard_name = cloud_liquid_water_path - long_name = layer cloud liquid water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out -[cld_reliq] - standard_name = mean_effective_radius_for_liquid_cloud - long_name = mean effective radius for liquid cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out -[cld_iwp] - standard_name = cloud_ice_water_path - long_name = layer cloud ice water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out -[cld_reice] - standard_name = mean_effective_radius_for_ice_cloud - long_name = mean effective radius for ice cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out -[cld_swp] - standard_name = cloud_snow_water_path - long_name = layer cloud snow water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out -[cld_resnow] - standard_name = mean_effective_radius_for_snow_flake - long_name = mean effective radius for snow cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out -[cld_rwp] - standard_name = cloud_rain_water_path - long_name = layer cloud rain water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out -[cld_rerain] - standard_name = mean_effective_radius_for_rain_drop - long_name = mean effective radius for rain cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out -[deltaZ] - standard_name = layer_thickness - long_name = layer_thickness - units = m - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out -[de_lgth] - standard_name = cloud_decorrelation_length - long_name = cloud decorrelation length - units = km - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = out -[cloud_overlap_param] - standard_name = cloud_overlap_param - long_name = cloud overlap parameter - units = km - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rad_sw_pre.F90 b/physics/rad_sw_pre.F90 new file mode 100644 index 000000000..8c33c17b8 --- /dev/null +++ b/physics/rad_sw_pre.F90 @@ -0,0 +1,59 @@ +! ###################################################################################### +!>\file rad_sw_pre.f90 +!! +!! This file gathers the sunlit points for the shortwave radiation schemes. +!! +!> \defgroup rad_sw_pre GFS radiation pre routine. +!! @{ +!! +! ###################################################################################### +module rad_sw_pre +contains + + ! ################################################################################### +!> \section arg_table_rad_sw_pre_run Argument Table +!! \htmlinclude rad_sw_pre_run.html +!! +!! \section rad_sw_pre_run +!! @{ + ! ################################################################################### + subroutine rad_sw_pre_run (im, lsswr, coszen, nday, idxday, errmsg, errflg) + use machine, only: kind_phys + implicit none + + ! Inputs + integer, intent(in) :: im + logical, intent(in) :: lsswr + real(kind_phys), dimension(:), intent(in) :: coszen + + ! Outputs + integer, intent(out) :: nday + integer, dimension(:), intent(out) :: idxday + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg + + ! Local variables + integer :: i + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + if (lsswr) then + ! Check for daytime points for SW radiation. + nday = 0 + idxday = 0 + do i = 1, IM + if (coszen(i) >= 0.0001) then + nday = nday + 1 + idxday(nday) = i + endif + enddo + else + nday = 0 + idxday = 0 + endif + + end subroutine rad_sw_pre_run +!! @} +end module rad_sw_pre diff --git a/physics/rrtmg_sw_pre.meta b/physics/rad_sw_pre.meta similarity index 96% rename from physics/rrtmg_sw_pre.meta rename to physics/rad_sw_pre.meta index 6a3a4e0a4..ccbdbf74b 100644 --- a/physics/rrtmg_sw_pre.meta +++ b/physics/rad_sw_pre.meta @@ -1,11 +1,11 @@ [ccpp-table-properties] - name = rrtmg_sw_pre + name = rad_sw_pre type = scheme dependencies = iounitdef.f,machine.F ######################################################################## [ccpp-arg-table] - name = rrtmg_sw_pre_run + name = rad_sw_pre_run type = scheme [im] standard_name = horizontal_loop_extent diff --git a/physics/radiation_cloud_overlap.F90 b/physics/radiation_cloud_overlap.F90 index a94923ba5..7fa44ec07 100644 --- a/physics/radiation_cloud_overlap.F90 +++ b/physics/radiation_cloud_overlap.F90 @@ -21,10 +21,10 @@ subroutine cmp_dcorr_lgth_hogan(nCol, lat, con_pi, dcorr_lgth) nCol ! Number of horizontal grid-points real(kind_phys), intent(in) :: & con_pi ! Physical constant: Pi - real(kind_phys), dimension(nCol), intent(in) :: & + real(kind_phys), dimension(:), intent(in) :: & lat ! Latitude ! Outputs - real(kind_phys), dimension(nCol),intent(out) :: & + real(kind_phys), dimension(:),intent(out) :: & dcorr_lgth ! Decorrelation length ! Local variables @@ -52,11 +52,11 @@ subroutine cmp_dcorr_lgth_oreopoulos(nCol, lat, juldat, yearlength, dcorr_lgth) real(kind_phys), intent(in) :: & juldat ! Julian date - real(kind_phys), dimension(nCol), intent(in) :: & + real(kind_phys), dimension(:), intent(in) :: & lat ! Latitude ! Outputs - real(kind_phys), dimension(nCol),intent(out) :: & + real(kind_phys), dimension(:),intent(out) :: & dcorr_lgth ! Decorrelation length (km) ! Parameters for the Gaussian fits per Eqs. (10) and (11) (See Table 1) @@ -84,19 +84,25 @@ end subroutine cmp_dcorr_lgth_oreopoulos ! ###################################################################################### ! ! ###################################################################################### - subroutine get_alpha_exp(nCol, nLay, dzlay, dcorr_lgth, alpha) + subroutine get_alpha_exper(nCol, nLay, iovr, iovr_exprand, dzlay, & + dcorr_lgth, cld_frac, alpha) ! Inputs integer, intent(in) :: & nCol, & ! Number of horizontal grid points nLay ! Number of vertical grid points - real(kind_phys), dimension(nCol), intent(in) :: & + integer, intent(in) :: & + iovr, & + iovr_exprand + real(kind_phys), dimension(:), intent(in) :: & dcorr_lgth ! Decorrelation length (km) - real(kind_phys), dimension(nCol,nLay), intent(in) :: & + real(kind_phys), dimension(:,:), intent(in) :: & dzlay ! + real(kind_phys), dimension(:,:), intent(in) :: & + cld_frac ! Outputs - real(kind_phys), dimension(nCol,nLay) :: & + real(kind_phys), dimension(:,:) :: & alpha ! Cloud overlap parameter ! Local variables @@ -108,9 +114,22 @@ subroutine get_alpha_exp(nCol, nLay, dzlay, dcorr_lgth, alpha) alpha(iCol,iLay) = exp( -(dzlay(iCol,iLay)) / dcorr_lgth(iCol)) enddo enddo - + + ! Revise alpha for exponential-random cloud overlap + ! Decorrelate layers when a clear layer follows a cloudy layer to enforce + ! random correlation between non-adjacent blocks of cloudy layers + if (iovr == iovr_exprand) then + do iLay = 2, nLay + do iCol = 1, nCol + if (cld_frac(iCol,iLay) == 0.0 .and. cld_frac(iCol,iLay-1) > 0.0) then + alpha(iCol,iLay) = 0.0 + endif + enddo + enddo + endif + return - end subroutine get_alpha_exp + end subroutine get_alpha_exper end module module_radiation_cloud_overlap diff --git a/physics/radiation_clouds.f b/physics/radiation_clouds.f index c9f417bf8..16ea93d26 100644 --- a/physics/radiation_clouds.f +++ b/physics/radiation_clouds.f @@ -18,82 +18,53 @@ ! outputs: ! ! ( none ) ! ! ! -! 'progcld1' --- zhao/moorthi prognostic cloud scheme ! +! 'radiation_clouds_prop' --- radiation cloud properties ! +! obtained from various cloud schemes ! ! inputs: ! -! (plyr,plvl,tlyr,tvly,qlyr,qstl,rhly,clw, ! -! xlat,xlon,slmsk,dz,delp, ! -! IX, NLAY, NLP1, ! -! uni_cld, lmfshal, lmfdeep2, cldcov, ! -! effrl,effri,effrr,effrs,effr_in, ! -! dzlay, latdeg, julian, yearlen, ! +! (plyr,plvl,tlyr,tvly,qlyr,qstl,rhly, ! +! ccnd, ncndl, cnvw, cnvc, tracer1, ! +! xlat,xlon,slmsk,dz,delp, IX, LM, NLAY, NLP1, ! +! deltaq, sup, me, icloud, kdt, ! +! ntrac, ntcw, ntiw, ntrw, ntsw, ntgl, ntclamt, ! +! imp_physics, imp_physics_nssl, imp_physics_fer_hires, ! +! imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, ! +! imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, ! +! imp_physics_mg, iovr_rand, iovr_maxrand, iovr_max, ! +! iovr_dcorr, iovr_exp, iovr_exprand, idcor_con, ! +! idcor_hogan, idcor_oreopoulos, ! +! imfdeepcnv, imfdeepcnv_gf, do_mynnedmf, lgfdlmprad, ! +! uni_cld, lmfshal, lmfdeep2, cldcov, clouds1, ! +! effrl, effri, effrr, effrs, effr_in, ! +! effrl_inout, effri_inout, effrs_inout, ! +! lwp_ex, iwp_ex, lwp_fc, iwp_fc, ! +! dzlay, latdeg, julian, yearlen, gridkm, ! ! outputs: ! -! clouds,clds,mtop,mbot,de_lgth,alpha) ! +! cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, ! +! cld_rwp, cld_rerain, cld_swp, cld_resnow, ! +! clds,mtop,mbot,de_lgth,alpha) ! ! ! -! 'progcld2' --- ferrier prognostic cloud microphysics ! -! inputs: ! -! (plyr,plvl,tlyr,tvly,qlyr,qstl,rhly,clw, ! -! xlat,xlon,slmsk,dz,delp, f_ice,f_rain,r_rime,flgmin, ! -! IX, NLAY, NLP1, lmfshal, lmfdeep2, ! -! dzlay, latdeg, julian, yearlen, ! -! outputs: ! -! clouds,clds,mtop,mbot,de_lgth,alpha) ! -! ! -! 'progcld3' --- zhao/moorthi prognostic cloud + pdfcld! -! inputs: ! -! (plyr,plvl,tlyr,tvly,qlyr,qstl,rhly,clw,cnvw,cnvc, ! -! xlat,xlon,slmsk, dz, delp, ! -! ix, nlay, nlp1, ! -! deltaq,sup,kdt,me, ! -! dzlay, latdeg, julian, yearlen, ! -! outputs: ! -! clouds,clds,mtop,mbot,de_lgth,alpha) ! -! ! -! 'progcld4' --- gfdl-lin cloud microphysics ! -! inputs: ! -! (plyr,plvl,tlyr,tvly,qlyr,qstl,rhly,clw,cnvw,cnvc, ! -! xlat,xlon,slmsk, dz, delp, ! -! ix, nlay, nlp1, ! -! dzlay, latdeg, julian, yearlen, ! -! outputs: ! -! clouds,clds,mtop,mbot,de_lgth,alpha) ! -! ! -! 'progcld4o' --- inactive ! -! ! -! 'progcld5' --- wsm6 cloud microphysics ! -! inputs: ! -! (plyr,plvl,tlyr,qlyr,qstl,rhly,clw, ! -! xlat,xlon,slmsk, dz, delp, ! -! ntrac,ntcw,ntiw,ntrw,ntsw,ntgl, ! -! ix, nlay, nlp1, ! -! uni_cld, lmfshal, lmfdeep2, cldcov, ! -! re_cloud,re_ice,re_snow, ! -! dzlay, latdeg, julian, yearlen, ! -! outputs: ! -! clouds,clds,mtop,mbot,de_lgth,alpha) ! -! ! -! 'progclduni' --- for unified clouds with MG microphys! -! inputs: ! -! (plyr,plvl,tlyr,tvly,ccnd,ncnd, ! -! xlat,xlon,slmsk,dz,delp, IX, NLAY, NLP1, cldtot, ! -! effrl,effri,effrr,effrs,effr_in, ! -! dzlay, latdeg, julian, yearlen, ! -! outputs: ! -! clouds,clds,mtop,mbot,de_lgth,alpha) ! -! ! -! internal accessable only subroutines: ! -! 'gethml' --- get diagnostic hi, mid, low clouds ! +! internal/external accessable subroutines: ! +! 'progcld_zhao_carr' --- zhao/moorthi prognostic cloud scheme ! +! 'progcld_zhao_carr_pdf' --- zhao/moorthi prognostic cloud + pdfcld ! +! 'progcld_gfdl_lin' --- GFDL-Lin cloud microphysics ! +! 'progcld_fer_hires' --- Ferrier-Aligo cloud microphysics ! +! 'progcld_thompson_wsm6' --- Thompson/wsm6 cloud microphysics (EMC) ! +! 'progclduni' --- MG2/3 cloud microphysics ! +! (with/without SHOC) (EMC) ! +! also used by GFDL MP (EMC) ! +! 'progcld_thompson' --- Thompson MP (added by G. Thompson) ! +! 'gethml' --- get diagnostic hi, mid, low clouds ! ! ! -! ! -! cloud array description: ! -! clouds(:,:,1) - layer total cloud fraction ! -! clouds(:,:,2) - layer cloud liq water path ! -! clouds(:,:,3) - mean effective radius for liquid cloud ! -! clouds(:,:,4) - layer cloud ice water path ! -! clouds(:,:,5) - mean effective radius for ice cloud ! -! clouds(:,:,6) - layer rain drop water path ! -! clouds(:,:,7) - mean effective radius for rain drop ! -! ** clouds(:,:,8) - layer snow flake water path ! -! clouds(:,:,9) - mean effective radius for snow flake ! +! cloud property array description: ! +! cld_frac (:,:) - layer total cloud fraction ! +! cld_lwp (:,:) - layer cloud liq water path ! +! cld_reliq (:,:) - mean effective radius for liquid cloud ! +! cld_iwp (:,:) - layer cloud ice water path ! +! cld_reice (:,:) - mean effective radius for ice cloud ! +! cld_rwp (:,:) - layer rain drop water path ! +! cld_rerain(:,:) - mean effective radius for rain drop ! +! ** cld_swp (:,:) - layer snow flake water path ! +! cld_resnow(:,:) - mean effective radius for snow flake ! ! ** fu's scheme need to be normalized by snow density (g/m**3/1.0e6)! ! ! ! external modules referenced: ! @@ -131,8 +102,6 @@ ! apr 2004, yu-tai hou - separated calculation of the ! ! averaged h,m,l,bl cloud amounts from each of the cld schemes ! ! to become an shared individule subprogram 'gethml'. ! -! may 2004, yu-tai hou - rewritten ferrier's scheme as a ! -! separated program 'progcld2' in the cloud module. ! ! apr 2005, yu-tai hou - modified cloud array and module ! ! structures. ! ! dec 2008, yu-tai hou - changed low-cld calculation, ! @@ -141,7 +110,7 @@ ! adjusted for better agreement with observations. ! ! jan 2011, yu-tai hou - changed virtual temperature ! ! as input variable instead of originally computed inside the ! -! two prognostic cld schemes 'progcld1' and 'progcld2'. ! +! two prognostic cld schemes 'progcld_zhao_carr' ! ! aug 2012, yu-tai hou - modified subroutine cld_init ! ! to pass all fixed control variables at the start. and set ! ! their correponding internal module variables to be used by ! @@ -165,6 +134,9 @@ ! either a constant or a latitude-varying and day-of-year ! ! varying decorrelation length selected with parameter "idcor". ! ! ! +! Jan 2022, Q.Liu - add subroutine radiation_clouds_prop, and ! +! move all the subroutine call "progcld*" from ! +! GFS_rrtmg_pre.F90 to this new subroutine ! !!!!! ========================================================== !!!!! !!!!! end descriptions !!!!! !!!!! ========================================================== !!!!! @@ -217,7 +189,7 @@ module module_radiation_clouds use module_microphysics, only : rsipath2 use module_iounitdef, only : NICLTUN use module_radiation_cloud_overlap, only: cmp_dcorr_lgth, & - & get_alpha_exp + & get_alpha_exper use machine, only : kind_phys ! implicit none @@ -277,9 +249,10 @@ module module_radiation_clouds & 161.503, 168.262, 175.248, 182.473, 189.952, 197.699, & & 205.728, 214.055, 222.694, 231.661, 240.971, 250.639/) - public progcld1, progcld2, progcld3, progcld4, progclduni, & - & cld_init, progcld5, progcld4o, & - & progcld6, progcld_thompson, cal_cldfra3, & + public progcld_zhao_carr, progcld_zhao_carr_pdf, & + & progcld_gfdl_lin, progclduni, progcld_fer_hires, & + & cld_init, radiation_clouds_prop, & + & progcld_thompson_wsm6, progcld_thompson, cal_cldfra3, & & find_cloudLayers, adjust_cloudIce, adjust_cloudH2O, & & adjust_cloudFinal, gethml @@ -302,7 +275,7 @@ module module_radiation_clouds !!\n =15: Ferrier-Aligo microphysics !!\n =17/18: NSSL microphysics !!\param me print control flag -!>\section gen_cld_init cld_init General Algorithm +!>\section cld_init General Algorithm !! @{ subroutine cld_init & & ( si, NLAY, imp_physics, me ) ! --- inputs @@ -429,67 +402,36 @@ end subroutine cld_init !----------------------------------- !> \ingroup module_radiation_clouds -!> This subroutine computes cloud related quantities using -!! zhao/moorthi's prognostic cloud microphysics scheme. -!!\param plyr (IX,NLAY), model layer mean pressure in mb (100Pa) -!!\param plvl (IX,NLP1), model level pressure in mb (100Pa) -!!\param tlyr (IX,NLAY), model layer mean temperature in K -!!\param tvly (IX,NLAY), model layer virtual temperature in K -!!\param qlyr (IX,NLAY), layer specific humidity in gm/gm -!!\param qstl (IX,NLAY), layer saturate humidity in gm/gm -!!\param rhly (IX,NLAY), layer relative humidity \f$ (=qlyr/qstl) \f$ -!!\param clw (IX,NLAY), layer cloud condensate amount -!!\param xlat (IX), grid latitude in radians, default to pi/2 -> -!! -pi/2 range, otherwise see in-line comment -!!\param xlon (IX), grid longitude in radians (not used) -!!\param slmsk (IX), sea/land mask array (sea:0,land:1,sea-ice:2) -!!\param dz (IX,NLAY), layer thickness (km) -!!\param delp (IX,NLAY), model layer pressure thickness in mb (100Pa) -!!\param IX horizontal dimention -!!\param NLAY vertical layer -!!\param NLP1 level dimensions -!!\param uni_cld logical, true for cloud fraction from shoc -!!\param lmfshal logical, mass-flux shallow convection scheme flag -!!\param lmfdeep2 logical, scale-aware mass-flux deep convection scheme flag -!!\param cldcov layer cloud fraction (used when uni_cld=.true.) -!!\param effrl effective radius for liquid water -!!\param effri effective radius for ice water -!!\param effrr effective radius for rain water -!!\param effrs effective radius for snow water -!!\param effr_in logical, if .true. use input effective radii -!!\param dzlay(ix,nlay) distance between model layer centers -!!\param latdeg(ix) latitude (in degrees 90 -> -90) -!!\param julian day of the year (fractional julian day) -!!\param yearlen current length of the year (365/366 days) -!!\param clouds (IX,NLAY,NF_CLDS), cloud profiles -!!\n (:,:,1) - layer total cloud fraction -!!\n (:,:,2) - layer cloud liq water path \f$(g/m^2)\f$ -!!\n (:,:,3) - mean eff radius for liq cloud (micron) -!!\n (:,:,4) - layer cloud ice water path \f$(g/m^2)\f$ -!!\n (:,:,5) - mean eff radius for ice cloud (micron) -!!\n (:,:,6) - layer rain drop water path (not assigned) -!!\n (:,:,7) - mean eff radius for rain drop (micron) -!!\n (:,:,8) - layer snow flake water path (not assigned) -!!\n (:,:,9) - mean eff radius for snow flake (micron) -!!\param clds (IX,5), fraction of clouds for low, mid, hi, tot, bl -!!\param mtop (IX,3), vertical indices for low, mid, hi cloud tops -!!\param mbot (IX,3), vertical indices for low, mid, hi cloud bases -!!\param de_lgth (IX), clouds decorrelation length (km) -!!\param alpha (IX,NLAY), alpha decorrelation parameter -!>\section gen_progcld1 progcld1 General Algorithm +!> Subroutine radiation_clouds_prop computes cloud related quantities +!! for different cloud microphysics schemes. +!>\section radiation_clouds_prop General Algorithm !> @{ - subroutine progcld1 & - & ( plyr,plvl,tlyr,tvly,qlyr,qstl,rhly,clw, & ! --- inputs: - & xlat,xlon,slmsk,dz,delp, IX, NLAY, NLP1, & - & uni_cld, lmfshal, lmfdeep2, cldcov, & - & effrl,effri,effrr,effrs,effr_in, & - & dzlay, latdeg, julian, yearlen, & - & clouds,clds,mtop,mbot,de_lgth,alpha & ! --- outputs: + subroutine radiation_clouds_prop & + & ( plyr, plvl, tlyr, tvly, qlyr, qstl, rhly, & ! --- inputs: + & ccnd, ncndl, cnvw, cnvc, tracer1, & + & xlat, xlon, slmsk, dz, delp, IX, LM, NLAY, NLP1, & + & deltaq, sup, me, icloud, kdt, & + & ntrac, ntcw, ntiw, ntrw, ntsw, ntgl, ntclamt, & + & imp_physics, imp_physics_nssl, imp_physics_fer_hires, & + & imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & + & imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, & + & imp_physics_mg, iovr_rand, iovr_maxrand, iovr_max, & + & iovr_dcorr, iovr_exp, iovr_exprand, idcor_con, & + & idcor_hogan, idcor_oreopoulos, & + & imfdeepcnv, imfdeepcnv_gf, do_mynnedmf, lgfdlmprad, & + & uni_cld, lmfshal, lmfdeep2, cldcov, clouds1, & + & effrl, effri, effrr, effrs, effr_in, & + & effrl_inout, effri_inout, effrs_inout, & + & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & + & dzlay, latdeg, julian, yearlen, gridkm, & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & ! --- outputs: + & cld_rwp, cld_rerain, cld_swp, cld_resnow, & + & clds, mtop, mbot, de_lgth, alpha & & ) ! ================= subprogram documentation block ================ ! ! ! -! subprogram: progcld1 computes cloud related quantities using ! +! subprogram: radiation_clouds_prop computes cloud related quantities using ! ! zhao/moorthi's prognostic cloud microphysics scheme. ! ! ! ! abstract: this program computes cloud fractions from cloud ! @@ -497,11 +439,22 @@ subroutine progcld1 & ! and computes the low, mid, high, total and boundary layer cloud ! ! fractions and the vertical indices of low, mid, and high cloud ! ! top and base. the three vertical cloud domains are set up in the ! -! initial subroutine "cld_init". ! +! initial subroutine "cld_init". ! ! ! -! usage: call progcld1 ! +! usage: call radiation_clouds_prop ! ! ! -! subprograms called: gethml ! +! subprograms called: ! +! ! +! 'progcld_zhao_carr' --- zhao/moorthi prognostic cloud scheme ! +! 'progcld_zhao_carr_pdf' --- zhao/moorthi prognostic cloud + pdfcld ! +! 'progcld_gfdl_lin' --- GFDL-Lin cloud microphysics ! +! 'progcld_fer_hires' --- Ferrier-Aligo cloud microphysics ! +! 'progcld_thompson_wsm6' --- Thompson/wsm6 cloud microphysics (EMC) ! +! 'progclduni' --- MG cloud microphysics ! +! --- GFDL cloud microphysics (EMC) ! +! --- Thompson + MYNN PBL (or GF convection) ! +! 'progcld_thompson' --- Thompson MP (added by G. Thompson) ! +! 'gethml' --- get diagnostic hi, mid, low clouds ! ! ! ! attributes: ! ! language: fortran 90 ! @@ -518,7 +471,12 @@ subroutine progcld1 & ! qlyr (IX,NLAY) : layer specific humidity in gm/gm ! ! qstl (IX,NLAY) : layer saturate humidity in gm/gm ! ! rhly (IX,NLAY) : layer relative humidity (=qlyr/qstl) ! -! clw (IX,NLAY) : layer cloud condensate amount ! +! ccnd (IX,NLAY,ncndl) : layer cloud condensate amount ! +! water, ice, rain, snow (+ graupel) ! +! ncndl : number of layer cloud condensate types (max of 4) ! +! cnvw (IX,NLAY) : layer convective cloud condensate ! +! cnvc (IX,NLAY) : layer convective cloud cover ! +! tracer1 (IX,NLAY,1:ntrac-1) : all tracers (except sphum) ! ! xlat (IX) : grid latitude in radians, default to pi/2 -> -pi/2! ! range, otherwise see in-line comment ! ! xlon (IX) : grid longitude in radians (not used) ! @@ -526,27 +484,75 @@ subroutine progcld1 & ! dz (ix,nlay) : layer thickness (km) ! ! delp (ix,nlay) : model layer pressure thickness in mb (100Pa) ! ! IX : horizontal dimention ! -! NLAY,NLP1 : vertical layer/level dimensions ! +! LM,NLAY,NLP1 : vertical layer/level dimensions ! +! deltaq (ix,nlay), half total water distribution width ! +! sup supersaturation ! +! me print control flag ! +! icloud : cloud effect to the optical depth in radiation ! +! kdt : current time step index ! +! ntrac number of tracers (Model%ntrac) ! +! ntcw tracer index for cloud liquid water (Model%ntcw) ! +! ntiw tracer index for cloud ice water (Model%ntiw) ! +! ntrw tracer index for rain water (Model%ntrw) ! +! ntsw tracer index for snow water (Model%ntsw) ! +! ntgl tracer index for graupel (Model%ntgl) ! +! ntclamt tracer index for cloud amount (Model%ntclamt) ! +! imp_physics : cloud microphysics scheme control flag ! +! imp_physics_nssl : NSSL microphysics ! +! imp_physics_fer_hires : Ferrier-Aligo microphysics scheme ! +! imp_physics_gfdl : GFDL microphysics scheme ! +! imp_physics_thompson : Thompson microphysics scheme ! +! imp_physics_wsm6 : WSMG microphysics scheme ! +! imp_physics_zhao_carr : Zhao-Carr microphysics scheme ! +! imp_physics_zhao_carr_pdf : Zhao-Carr microphysics scheme with PDF clouds +! imp_physics_mg : Morrison-Gettelman microphysics scheme ! +! iovr_rand : choice of cloud-overlap: random (=0) +! iovr_maxrand : choice of cloud-overlap: maximum random (=1) +! iovr_max : choice of cloud-overlap: maximum (=2) +! iovr_dcorr : choice of cloud-overlap: decorrelation length (=3) +! iovr_exp : choice of cloud-overlap: exponential (=4) +! iovr_exprand : choice of cloud-overlap: exponential random (=5) +! idcor_con : choice for decorrelation-length: Use constant value (=0) +! idcor_hogan : choice for decorrelation-length: (=1) +! idcor_oreopoulos: choice for decorrelation-length: (=2) +! imfdeepcnv : flag for mass-flux deep convection scheme ! +! imfdeepcnv_gf : flag for scale- & aerosol-aware Grell-Freitas scheme (GSD) +! do_mynnedmf : flag for MYNN-EDMF ! +! lgfdlmprad : flag for GFDLMP radiation interaction ! ! uni_cld : logical - true for cloud fraction from shoc ! ! lmfshal : logical - true for mass flux shallow convection ! ! lmfdeep2 : logical - true for mass flux deep convection ! ! cldcov : layer cloud fraction (used when uni_cld=.true. ! +! clouds1 : layer total cloud fraction +! effrl, : effective radius for liquid water +! effri, : effective radius for ice water +! effrr, : effective radius for rain water +! effrs, : effective radius for snow water +! effr_in, : flag to use effective radii of cloud species in radiation +! effrl_inout, : eff. radius of cloud liquid water particle +! effri_inout, : eff. radius of cloud ice water particle +! effrs_inout : effective radius of cloud snow particle +! lwp_ex : total liquid water path from explicit microphysics +! iwp_ex : total ice water path from explicit microphysics +! lwp_fc : total liquid water path from cloud fraction scheme +! iwp_fc : total ice water path from cloud fraction scheme ! dzlay(ix,nlay) : thickness between model layer centers (km) ! ! latdeg(ix) : latitude (in degrees 90 -> -90) ! ! julian : day of the year (fractional julian day) ! ! yearlen : current length of the year (365/366 days) ! +! gridkm : grid length in km ! ! ! output variables: ! -! clouds(IX,NLAY,NF_CLDS) : cloud profiles ! -! clouds(:,:,1) - layer total cloud fraction ! -! clouds(:,:,2) - layer cloud liq water path (g/m**2) ! -! clouds(:,:,3) - mean eff radius for liq cloud (micron) ! -! clouds(:,:,4) - layer cloud ice water path (g/m**2) ! -! clouds(:,:,5) - mean eff radius for ice cloud (micron) ! -! clouds(:,:,6) - layer rain drop water path not assigned ! -! clouds(:,:,7) - mean eff radius for rain drop (micron) ! -! *** clouds(:,:,8) - layer snow flake water path not assigned ! -! clouds(:,:,9) - mean eff radius for snow flake (micron) ! +! cloud profiles: ! +! cld_frac (:,:) - layer total cloud fraction ! +! cld_lwp (:,:) - layer cloud liq water path (g/m**2) ! +! cld_reliq (:,:) - mean eff radius for liq cloud (micron) ! +! cld_iwp (:,:) - layer cloud ice water path (g/m**2) ! +! cld_reice (:,:) - mean eff radius for ice cloud (micron) ! +! cld_rwp (:,:) - layer rain drop water path not assigned ! +! cld_rerain(:,:) - mean eff radius for rain drop (micron) ! +! *** cld_swp (:,:) - layer snow flake water path not assigned ! +! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! *** fu's scheme need to be normalized by snow density (g/m**3/1.0e6) ! ! clds (IX,5) : fraction of clouds for low, mid, hi, tot, bl ! ! mtop (IX,3) : vertical indices for low, mid, hi cloud tops ! @@ -568,28 +574,65 @@ subroutine progcld1 & ! =f: not normalize cloud condensate ! ! ! ! ==================== end of description ===================== ! -! implicit none ! --- inputs - integer, intent(in) :: IX, NLAY, NLP1 + integer, intent(in) :: IX, LM, NLAY, NLP1, me, ncndl, icloud + integer, intent(in) :: ntrac, ntcw, ntiw, ntrw, ntsw, ntgl, & + & ntclamt + integer, intent(in) :: kdt, imfdeepcnv, imfdeepcnv_gf + integer, intent(in) :: & + & imp_physics, ! Flag for MP scheme + & imp_physics_nssl, ! Flag for NSSL scheme + & imp_physics_fer_hires, ! Flag for fer-hires scheme + & imp_physics_gfdl, ! Flag for gfdl scheme + & imp_physics_thompson, ! Flag for thompsonscheme + & imp_physics_wsm6, ! Flag for wsm6 scheme + & imp_physics_zhao_carr, ! Flag for zhao-carr scheme + & imp_physics_zhao_carr_pdf, ! Flag for zhao-carr+PDF scheme + & imp_physics_mg ! Flag for MG scheme + + integer, intent(in) :: & + & iovr_rand, ! Flag for random cloud overlap method + & iovr_maxrand, ! Flag for maximum-random cloud overlap method + & iovr_max, ! Flag for maximum cloud overlap method + & iovr_dcorr, ! Flag for decorrelation-length cloud overlap method + & iovr_exp, ! Flag for exponential cloud overlap method + & iovr_exprand, ! Flag for exponential-random cloud overlap method + & idcor_con, + & idcor_hogan, + & idcor_oreopoulos + logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, effr_in + logical, intent(in) :: do_mynnedmf, lgfdlmprad + real (kind=kind_phys), dimension(:,:,:), intent(in) :: ccnd, & + & tracer1 real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & - & tlyr, tvly, qlyr, qstl, rhly, clw, cldcov, delp, dz, & - & effrl, effri, effrr, effrs, dzlay + & tlyr, tvly, qlyr, qstl, rhly, cnvw, cnvc, cldcov, & + & delp, dz, effrl, effri, effrr, effrs, dzlay, clouds1 + real (kind=kind_phys), intent(in) :: sup real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & & slmsk - real(kind=kind_phys), dimension(:), intent(in) :: latdeg + real(kind=kind_phys), dimension(:), intent(in) :: latdeg, gridkm real(kind=kind_phys), intent(in) :: julian integer, intent(in) :: yearlen +! --- inout + real(kind=kind_phys),dimension(:,:) :: deltaq + real(kind=kind_phys),dimension(:,:),intent(inout) :: & + & effrl_inout, effri_inout, effrs_inout + real(kind=kind_phys), dimension(:), intent(inout) :: & + & lwp_ex, iwp_ex, lwp_fc, iwp_fc + ! --- outputs - real (kind=kind_phys), dimension(:,:,:), intent(out) :: clouds + real (kind=kind_phys), dimension(:,:), intent(out) :: & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & + & cld_rwp, cld_rerain, cld_swp, cld_resnow real (kind=kind_phys), dimension(:,:), intent(out) :: clds real (kind=kind_phys), dimension(:), intent(out) :: de_lgth real (kind=kind_phys), dimension(:,:), intent(out) :: alpha @@ -614,15 +657,418 @@ subroutine progcld1 & ! !===> ... begin here ! - do nf=1,nf_clds - do k=1,nlay - do i=1,ix - clouds(i,k,nf) = 0.0 - enddo + if (me == 0 .and. kdt == 1) then & + print*, 'in radiation_clouds_prop=', imp_physics, uni_cld, & + & ncndl, lgfdlmprad, do_mynnedmf, imfdeepcnv, kdt + end if + + do k = 1, NLAY + do i = 1, IX + cld_frac(i,k) = 0.0 + cld_lwp(i,k) = 0.0 + cld_reliq(i,k) = 0.0 + cld_iwp(i,k) = 0.0 + cld_reice(i,k) = 0.0 + cld_rwp(i,k) = 0.0 + cld_rerain(i,k) = 0.0 + cld_swp(i,k) = 0.0 + cld_resnow(i,k) = 0.0 + enddo + enddo + + do k = 1, NLAY + do i = 1, IX + cldtot(i,k) = 0.0 + cldcnv(i,k) = 0.0 + end do + end do + + if (imp_physics == imp_physics_zhao_carr .or. & + & imp_physics == imp_physics_mg) then ! zhao/moorthi's p + ! or unified cloud and/or with MG microphysics + + if (uni_cld .and. ncndl >= 2) then + call progclduni (plyr, plvl, tlyr, tvly, ccnd, ncndl, & ! --- inputs + & xlat, xlon, slmsk, dz, delp, & + & IX, NLAY, NLP1, cldcov, & + & effrl, effri, effrr, effrs, effr_in, & + & dzlay, & + & cldtot, cldcnv, & ! inout + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, & + & cld_resnow) + else + call progcld_zhao_carr (plyr ,plvl, tlyr, tvly, qlyr, & ! --- inputs + & qstl, rhly, ccnd(1:IX,1:NLAY,1), xlat, xlon, & + & slmsk, dz, delp, IX, NLAY, NLP1, uni_cld, & + & lmfshal, lmfdeep2, & + & cldcov, effrl, effri, effrr, effrs, effr_in, & + & dzlay, & + & cldtot, cldcnv, & ! inout + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, & + & cld_resnow) + endif + + elseif(imp_physics == imp_physics_zhao_carr_pdf) then ! zhao/moorthi's prognostic cloud+pdfcld + + call progcld_zhao_carr_pdf (plyr, plvl, tlyr, tvly, qlyr, & ! --- inputs + & qstl, rhly, ccnd(1:IX,1:NLAY,1), cnvw, cnvc, & + & xlat, xlon, slmsk, dz, delp, IX, NLAY, NLP1, & + & deltaq, sup, kdt, me, dzlay, & + & cldtot, cldcnv, & ! inout + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, & + & cld_resnow) + + elseif (imp_physics == imp_physics_gfdl) then ! GFDL cloud scheme + + if (.not. lgfdlmprad) then + call progcld_gfdl_lin (plyr, plvl, tlyr, tvly, qlyr, & ! --- inputs + & qstl, rhly, ccnd(1:IX,1:NLAY,1), cnvw, cnvc, & + & xlat, xlon, slmsk, cldcov, dz, delp, & + & IX, NLAY, NLP1, dzlay, & + & cldtot, cldcnv, & ! inout + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, & + & cld_resnow) + else + + call progclduni (plyr, plvl, tlyr, tvly, ccnd, ncndl, xlat, & ! --- inputs + & xlon, slmsk, dz,delp, IX, NLAY, NLP1, cldcov, & + & effrl, effri, effrr, effrs, effr_in, & + & dzlay, & + & cldtot, cldcnv, & ! inout + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, & + & cld_resnow) + endif + + + elseif(imp_physics == imp_physics_fer_hires) then + if (kdt == 1) then + effrl_inout(:,:) = 10. + effri_inout(:,:) = 50. + effrs_inout(:,:) = 250. + endif + + call progcld_fer_hires (plyr,plvl,tlyr,tvly,qlyr,qstl,rhly, & ! --- inputs + & tracer1,xlat,xlon,slmsk,dz,delp, & + & ntrac-1, ntcw-1,ntiw-1,ntrw-1, & + & IX,NLAY,NLP1, icloud, uni_cld, & + & lmfshal, lmfdeep2, & + & cldcov(:,1:NLAY),effrl_inout(:,:), & + & effri_inout(:,:), effrs_inout(:,:), & + & dzlay, & + & cldtot, cldcnv, & ! inout + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, & + & cld_resnow) + + elseif ( imp_physics == imp_physics_nssl ) then ! NSSL MP + + if(do_mynnedmf .or. imfdeepcnv == imfdeepcnv_gf ) then ! MYNN PBL or GF conv + !-- MYNN PBL or convective GF + !-- use cloud fractions with SGS clouds + do k=1,NLAY + do i=1,IX + cld_frac(i,k) = clouds1(i,k) + enddo + enddo + + ! --- use clduni with the NSSL microphysics. + ! --- make sure that effr_in=.true. in the input.nml! + call progclduni (plyr, plvl, tlyr, tvly, ccnd, ncndl, & ! --- inputs + & xlat, xlon, slmsk, dz, delp, IX, NLAY, NLP1, & + & cld_frac, & + & effrl, effri, effrr, effrs, effr_in , & + & dzlay, & + & cldtot, cldcnv, & ! inout + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, & + & cld_resnow) + else + ! MYNN PBL or GF convective are not used + call progcld_thompson_wsm6 (plyr,plvl,tlyr,qlyr,qstl, & ! --- inputs + & rhly,tracer1,xlat,xlon,slmsk,dz,delp, & + & ntrac-1, ntcw-1,ntiw-1,ntrw-1, & + & ntsw-1,ntgl-1, & + & IX, NLAY, NLP1, uni_cld, lmfshal, lmfdeep2, & + & cldcov(:,1:NLAY), cnvw, effrl_inout, & + & effri_inout, effrs_inout, & + & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & + & dzlay, & + & cldtot, cldcnv, & ! inout + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, & + & cld_resnow) + endif ! MYNN PBL or GF + + elseif(imp_physics == imp_physics_thompson) then ! Thompson MP + + if(do_mynnedmf .or. imfdeepcnv == imfdeepcnv_gf ) then ! MYNN PBL or GF conv + + if (icloud == 3) then + call progcld_thompson (plyr,plvl,tlyr,qlyr,qstl,rhly, & ! --- inputs + & tracer1,xlat,xlon,slmsk,dz,delp, & + & ntrac-1, ntcw-1,ntiw-1,ntrw-1, & + & ntsw-1,ntgl-1, & + & IX, LM, NLP1, uni_cld, lmfshal, lmfdeep2, & + & cldcov(:,1:LM), effrl, effri, effrs, & + & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & + & dzlay, gridkm, & + & cldtot, cldcnv, & ! inout + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, & + & cld_resnow) + else + + !-- MYNN PBL or convective GF + !-- use cloud fractions with SGS clouds + do k=1,NLAY + do i=1,IX + cld_frac(i,k) = clouds1(i,k) + enddo + enddo + + ! --- use clduni as with the GFDL microphysics. + ! --- make sure that effr_in=.true. in the input.nml! + call progclduni (plyr, plvl, tlyr, tvly, ccnd, ncndl, & ! --- inputs + & xlat, xlon, slmsk, dz, delp, IX, NLAY, NLP1, & + & cld_frac, & + & effrl, effri, effrr, effrs, effr_in , & + & dzlay, & + & cldtot, cldcnv, & ! inout + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, & + & cld_resnow) + endif + + else + ! MYNN PBL or GF convective are not used + + if (icloud == 3) then + call progcld_thompson (plyr,plvl,tlyr,qlyr,qstl,rhly, & ! --- inputs + & tracer1,xlat,xlon,slmsk,dz,delp, & + & ntrac-1, ntcw-1,ntiw-1,ntrw-1, & + & ntsw-1,ntgl-1, & + & IX, LM, NLP1, uni_cld, lmfshal, lmfdeep2, & + & cldcov(:,1:LM), effrl, effri, effrs, & + & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & + & dzlay, gridkm, & + & cldtot, cldcnv, & ! inout + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, & + & cld_resnow) + + else + call progcld_thompson_wsm6 (plyr,plvl,tlyr,qlyr,qstl, & ! --- inputs + & rhly,tracer1,xlat,xlon,slmsk,dz,delp, & + & ntrac-1, ntcw-1,ntiw-1,ntrw-1, & + & ntsw-1,ntgl-1, & + & IX, NLAY, NLP1, uni_cld, lmfshal, lmfdeep2, & + & cldcov(:,1:NLAY), cnvw, effrl, effri, effrs, & + & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & + & dzlay, & + & cldtot, cldcnv, & ! inout + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, & + & cld_resnow) + endif + endif ! MYNN PBL or GF + + endif ! end if_imp_physics + +!> - Compute SFC/low/middle/high cloud top pressure for each cloud +!! domain for given latitude. +! ptopc(k,i): top presure of each cld domain (k=1-4 are sfc,L,m,h; +! --- i=1,2 are low-lat (<45 degree) and pole regions) + + do i =1, IX + rxlat(i) = abs( xlat(i) / con_pi ) ! if xlat in pi/2 -> -pi/2 range +! rxlat(i) = abs(0.5 - xlat(i)/con_pi) ! if xlat in 0 -> pi range + enddo + + do id = 1, 4 + tem1 = ptopc(id,2) - ptopc(id,1) + + do i =1, IX + ptop1(i,id) = ptopc(id,1) + tem1*max( 0.0, 4.0*rxlat(i)-1.0 ) enddo enddo -! clouds(:,:,:) = 0.0 + + ! Compute cloud decorrelation length + if (idcor == idcor_hogan) then + call cmp_dcorr_lgth(ix, xlat, con_pi, de_lgth) + endif + if (idcor == idcor_oreopoulos) then + call cmp_dcorr_lgth(ix, latdeg, julian, yearlen, de_lgth) + endif + if (idcor == idcor_con) then + de_lgth(:) = decorr_con + endif + + ! Call subroutine get_alpha_exper to define alpha parameter for exponential cloud overlap options + if ( iovr == iovr_dcorr .or. iovr == iovr_exp & + & .or. iovr == iovr_exprand) then + call get_alpha_exper(ix, nLay, iovr, iovr_exprand, dzlay, & + & de_lgth, cld_frac, alpha) + else + de_lgth(:) = 0. + alpha(:,:) = 0. + endif + +!> - Call gethml() to compute low,mid,high,total, and boundary layer +!! cloud fractions and clouds top/bottom layer indices for low, mid, +!! and high clouds. +! --- compute low, mid, high, total, and boundary layer cloud fractions +! and clouds top/bottom layer indices for low, mid, and high clouds. +! The three cloud domain boundaries are defined by ptopc. The cloud +! overlapping method is defined by control flag 'iovr', which may +! be different for lw and sw radiation programs. + + call gethml & +! --- inputs: + & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & + & IX, NLAY, iovr_rand, iovr_maxrand, iovr_max, & + & iovr_dcorr, iovr_exp, iovr_exprand, & +! --- outputs: + & clds, mtop, mbot & + & ) + + return +!................................... + end subroutine radiation_clouds_prop + +!> \ingroup module_radiation_clouds +!> This subroutine computes cloud related quantities using +!! zhao/moorthi's prognostic cloud microphysics scheme. +!>\section progcld_zhao_carr General Algorithm +!> @{ + subroutine progcld_zhao_carr & + & ( plyr,plvl,tlyr,tvly,qlyr,qstl,rhly,clw, & ! --- inputs: + & xlat,xlon,slmsk,dz,delp, IX, NLAY, NLP1, & + & uni_cld, lmfshal, lmfdeep2, cldcov, & + & effrl,effri,effrr,effrs,effr_in, & + & dzlay, cldtot, cldcnv, & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & + & ) + +! ================= subprogram documentation block ================ ! +! ! +! subprogram: progcld_zhao_carr computes cloud related quantities using ! +! zhao/moorthi's prognostic cloud microphysics scheme. ! +! ! +! abstract: this program computes cloud fractions from cloud ! +! condensates, calculates liquid/ice cloud droplet effective radius, ! +! and computes the low, mid, high, total and boundary layer cloud ! +! fractions and the vertical indices of low, mid, and high cloud ! +! top and base. the three vertical cloud domains are set up in the ! +! initial subroutine "cld_init". ! +! ! +! usage: call progcld_zhao_carr ! +! ! +! subprograms called: gethml ! +! ! +! attributes: ! +! language: fortran 90 ! +! machine: ibm-sp, sgi ! +! ! +! ! +! ==================== definition of variables ==================== ! +! ! +! input variables: ! +! plyr (IX,NLAY) : model layer mean pressure in mb (100Pa) ! +! plvl (IX,NLP1) : model level pressure in mb (100Pa) ! +! tlyr (IX,NLAY) : model layer mean temperature in k ! +! tvly (IX,NLAY) : model layer virtual temperature in k ! +! qlyr (IX,NLAY) : layer specific humidity in gm/gm ! +! qstl (IX,NLAY) : layer saturate humidity in gm/gm ! +! rhly (IX,NLAY) : layer relative humidity (=qlyr/qstl) ! +! clw (IX,NLAY) : layer cloud condensate amount ! +! xlat (IX) : grid latitude in radians, default to pi/2 -> -pi/2! +! range, otherwise see in-line comment ! +! xlon (IX) : grid longitude in radians (not used) ! +! slmsk (IX) : sea/land mask array (sea:0,land:1,sea-ice:2) ! +! dz (ix,nlay) : layer thickness (km) ! +! delp (ix,nlay) : model layer pressure thickness in mb (100Pa) ! +! IX : horizontal dimention ! +! NLAY,NLP1 : vertical layer/level dimensions ! +! uni_cld : logical - true for cloud fraction from shoc ! +! lmfshal : logical - true for mass flux shallow convection ! +! lmfdeep2 : logical - true for mass flux deep convection ! +! cldcov : layer cloud fraction (used when uni_cld=.true. ! +! effrl : effective radius for liquid water +! effri : effective radius for ice water +! effrr : effective radius for rain water +! effrs : effective radius for snow water +! effr_in : logical, if .true. use input effective radii +! dzlay(ix,nlay) : thickness between model layer centers (km) ! +! ! +! output variables: ! +! cloud profiles: ! +! cld_frac (:,:) - layer total cloud fraction ! +! cld_lwp (:,:) - layer cloud liq water path (g/m**2) ! +! cld_reliq (:,:) - mean eff radius for liq cloud (micron) ! +! cld_iwp (:,:) - layer cloud ice water path (g/m**2) ! +! cld_reice (:,:) - mean eff radius for ice cloud (micron) ! +! cld_rwp (:,:) - layer rain drop water path not assigned ! +! cld_rerain(:,:) - mean eff radius for rain drop (micron) ! +! *** cld_swp (:,:) - layer snow flake water path not assigned ! +! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! +! ! +! module variables: ! +! ivflip : control flag of vertical index direction ! +! =0: index from toa to surface ! +! =1: index from surface to toa ! +! lmfshal : mass-flux shallow conv scheme flag ! +! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! +! ! +! ==================== end of description ===================== ! +! + implicit none + +! --- inputs + integer, intent(in) :: IX, NLAY, NLP1 + + logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, effr_in + + real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & + & tlyr, tvly, qlyr, qstl, rhly, clw, cldcov, delp, dz, & + & effrl, effri, effrr, effrs, dzlay + + real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & + & slmsk + +! --- inputs/outputs + + real (kind=kind_phys), dimension(:,:), intent(inout) :: & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & + & cld_rwp, cld_rerain, cld_swp, cld_resnow + +! --- local variables: + real (kind=kind_phys), dimension(IX,NLAY) :: cldtot, cldcnv, & + & cwp, cip, crp, csp, rew, rei, res, rer, tem2d, clwf + + real (kind=kind_phys) :: clwmin, clwm, clwt, onemrh, value, & + & tem1, tem2, tem3 + + integer :: i, k, id, nf +! --- constant values +! real (kind=kind_phys), parameter :: xrc3 = 200. + real (kind=kind_phys), parameter :: xrc3 = 100. + +! +!===> ... begin here +! !> - Assgin liquid/ice/rain/snow cloud effective radius from input or predefined values. if(effr_in) then do k = 1, NLAY @@ -678,24 +1124,6 @@ subroutine progcld1 & enddo endif -!> - Compute SFC/low/middle/high cloud top pressure for each cloud -!! domain for given latitude. -! ptopc(k,i): top presure of each cld domain (k=1-4 are sfc,L,m,h; -! --- i=1,2 are low-lat (<45 degree) and pole regions) - - do i =1, IX - rxlat(i) = abs( xlat(i) / con_pi ) ! if xlat in pi/2 -> -pi/2 range -! rxlat(i) = abs(0.5 - xlat(i)/con_pi) ! if xlat in 0 -> pi range - enddo - - do id = 1, 4 - tem1 = ptopc(id,2) - ptopc(id,1) - - do i =1, IX - ptop1(i,id) = ptopc(id,1) + tem1*max( 0.0, 4.0*rxlat(i)-1.0 ) - enddo - enddo - !> - Compute cloud liquid/ice condensate path in \f$ g/m^2 \f$ . do k = 1, NLAY @@ -729,57 +1157,18 @@ subroutine progcld1 & !> - Compute layer cloud fraction. - clwmin = 0.0 - if (.not. lmfshal) then - do k = 1, NLAY - do i = 1, IX - clwt = 1.0e-6 * (plyr(i,k)*0.001) -! clwt = 2.0e-6 * (plyr(i,k)*0.001) - - if (clwf(i,k) > clwt) then - - onemrh= max( 1.e-10, 1.0-rhly(i,k) ) - clwm = clwmin / max( 0.01, plyr(i,k)*0.001 ) - - tem1 = min(max(sqrt(sqrt(onemrh*qstl(i,k))),0.0001),1.0) - tem1 = 2000.0 / tem1 -! tem1 = 1000.0 / tem1 + if (.not. lmfshal) then + call cloud_fraction_XuRandall & + & ( IX, NLAY, plyr, clwf, rhly, qstl, & ! --- inputs + & cldtot ) & ! --- outputs + else + call cloud_fraction_mass_flx_1 & + & ( IX, NLAY, lmfdeep2, xrc3, plyr, clwf, rhly, qstl, & ! --- inputs + & cldtot ) + endif - value = max( min( tem1*(clwf(i,k)-clwm), 50.0 ), 0.0 ) - tem2 = sqrt( sqrt(rhly(i,k)) ) - - cldtot(i,k) = max( tem2*(1.0-exp(-value)), 0.0 ) - endif - enddo - enddo - else - do k = 1, NLAY - do i = 1, IX - clwt = 1.0e-6 * (plyr(i,k)*0.001) -! clwt = 2.0e-6 * (plyr(i,k)*0.001) - - if (clwf(i,k) > clwt) then - onemrh= max( 1.e-10, 1.0-rhly(i,k) ) - clwm = clwmin / max( 0.01, plyr(i,k)*0.001 ) -! - tem1 = min(max((onemrh*qstl(i,k))**0.49,0.0001),1.0) !jhan - if (lmfdeep2) then - tem1 = xrc3 / tem1 - else - tem1 = 100.0 / tem1 - endif -! - value = max( min( tem1*(clwf(i,k)-clwm), 50.0 ), 0.0 ) - tem2 = sqrt( sqrt(rhly(i,k)) ) - - cldtot(i,k) = max( tem2*(1.0-exp(-value)), 0.0 ) - endif - enddo - enddo - endif - - endif ! if (uni_cld) then + endif ! if (uni_cld) then do k = 1, NLAY do i = 1, IX @@ -839,990 +1228,44 @@ subroutine progcld1 & ! do k = 1, NLAY do i = 1, IX - clouds(i,k,1) = cldtot(i,k) - clouds(i,k,2) = cwp(i,k) - clouds(i,k,3) = rew(i,k) - clouds(i,k,4) = cip(i,k) - clouds(i,k,5) = rei(i,k) -! clouds(i,k,6) = 0.0 - clouds(i,k,7) = rer(i,k) -! clouds(i,k,8) = 0.0 - clouds(i,k,9) = res(i,k) + cld_frac(i,k) = cldtot(i,k) + cld_lwp(i,k) = cwp(i,k) + cld_reliq(i,k) = rew(i,k) + cld_iwp(i,k) = cip(i,k) + cld_reice(i,k) = rei(i,k) +! cld_rwp(i,k) = 0.0 + cld_rerain(i,k) = rer(i,k) +! cld_swp(i,k) = 0.0 + cld_resnow(i,k) = res(i,k) enddo enddo - -! --- ... estimate clouds decorrelation length in km -! this is only a tentative test, need to consider change later - - if ( iovr == 3 ) then - do i = 1, ix - de_lgth(i) = max( 0.6, 2.78-4.6*rxlat(i) ) - enddo - endif - - ! Compute cloud decorrelation length - if (idcor == 1) then - call cmp_dcorr_lgth(ix, xlat, con_pi, de_lgth) - endif - if (idcor == 2) then - call cmp_dcorr_lgth(ix, latdeg, julian, yearlen, de_lgth) - endif - if (idcor == 0) then - de_lgth(:) = decorr_con - endif - - ! Call subroutine get_alpha_exp to define alpha parameter for exponential cloud overlap options - if (iovr == 3 .or. iovr == 4 .or. iovr == 5) then - call get_alpha_exp(ix, nLay, dzlay, de_lgth, alpha) - else - de_lgth(:) = 0. - alpha(:,:) = 0. - endif - - ! Revise alpha for exponential-random cloud overlap - ! Decorrelate layers when a clear layer follows a cloudy layer to enforce - ! random correlation between non-adjacent blocks of cloudy layers - if (iovr == 5) then - do k = 2, nLay - do i = 1, ix - if (clouds(i,k,1) == 0.0 .and. clouds(i,k-1,1) > 0.0) then - alpha(i,k) = 0.0 - endif - enddo - enddo - endif - -!> - Call gethml() to compute low,mid,high,total, and boundary layer -!! cloud fractions and clouds top/bottom layer indices for low, mid, -!! and high clouds. The three cloud domain boundaries are defined by -!! ptopc. The cloud overlapping method is defined by control flag -!! 'iovr', which may be different for lw and sw radiation programs. - call gethml & -! --- inputs: - & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & - & IX,NLAY, & -! --- outputs: - & clds, mtop, mbot & - & ) - - ! return !................................... - end subroutine progcld1 + end subroutine progcld_zhao_carr !----------------------------------- !> @} - -!> \ingroup module_radiation_clouds -!> This subroutine computes cloud related quantities using Ferrier's -!! prognostic cloud microphysics scheme. -!!\param plyr (IX,NLAY), model layer mean pressure in mb (100Pa) -!!\param plvl (IX,NLP1), model level pressure in mb (100Pa) -!!\param tlyr (IX,NLAY), model layer mean temperature in K -!!\param tvly (IX,NLAY), model layer virtual temperature in K -!!\param qlyr (IX,NLAY), layer specific humidity in gm/gm -!!\param qstl (IX,NLAY), layer saturate humidity in gm/gm -!!\param rhly (IX,NLAY), layer relative humidity (=qlyr/qstl) -!!\param clw (IX,NLAY), layer cloud condensate amount -!!\param f_ice (IX,NLAY), fraction of layer cloud ice (ferrier micro-phys) -!!\param f_rain (IX,NLAY), fraction of layer rain water (ferrier micro-phys) -!!\param r_rime (IX,NLAY), mass ratio of total ice to unrimed ice (>=1) -!!\param flgmin (IX), minimum large ice fraction -!!\param xlat (IX), grid latitude in radians, default to pi/2 -> -!! -pi/2 range, otherwise see in-line comment -!!\param xlon (IX), grid longitude in radians (not used) -!!\param slmsk (IX), sea/land mask array (sea:0,land:1,sea-ice:2) -!!\param dz (IX,NLAY), layer thickness (km) -!!\param delp (IX,NLAY), model layer pressure thickness in mb (100Pa) -!!\param IX horizontal dimention -!!\param NLAY,NLP1 vertical layer/level dimensions -!!\param lmfshal flag for mass-flux shallow convection scheme in the cloud fraction calculation -!!\param lmfdeep2 flag for mass-flux deep convection scheme in the cloud fraction calculation -!!\param dzlay(ix,nlay) distance between model layer centers -!!\param latdeg(ix) latitude (in degrees 90 -> -90) -!!\param julian day of the year (fractional julian day) -!!\param yearlen current length of the year (365/366 days) -!!\param clouds (IX,NLAY,NF_CLDS), cloud profiles -!!\n (:,:,1) - layer total cloud fraction -!!\n (:,:,2) - layer cloud liq water path \f$(g/m^2)\f$ -!!\n (:,:,3) - mean eff radius for liq cloud (micron) -!!\n (:,:,4) - layer cloud ice water path \f$(g/m^2)\f$ -!!\n (:,:,5) - mean eff radius for ice cloud (micron) -!!\n (:,:,6) - layer rain drop water path \f$(g/m^2)\f$ -!!\n (:,:,7) - mean eff radius for rain drop (micron) -!!\n (:,:,8) - layer snow flake water path \f$(g/m^2)\f$ -!!\n (:,:,9) - mean eff radius for snow flake (micron) -!!\param clds (IX,5), fraction of clouds for low, mid, hi, tot, bl -!!\param mtop (IX,3), vertical indices for low, mid, hi cloud tops -!!\param mbot (IX,3), vertical indices for low, mid, hi cloud bases -!!\param de_lgth (IX), clouds decorrelation length (km) -!>\section gen_progcld2 progcld2 General Algorithm for the F-A MP scheme -!> @{ - subroutine progcld2 & - & ( plyr,plvl,tlyr,qlyr,qstl,rhly,tvly,clw, & ! --- inputs: - & xlat,xlon,slmsk,dz,delp, & - & ntrac, ntcw, ntiw, ntrw, & - & IX, NLAY, NLP1, lmfshal, lmfdeep2, & - & dzlay, latdeg, julian, yearlen, & - & clouds,clds,mtop,mbot,de_lgth,alpha & ! --- outputs: - & ) - -! ================= subprogram documentation block ================ ! -! ! -! subprogram: progcld2 computes cloud related quantities using ! -! WSM6 cloud microphysics scheme. ! -! ! -! abstract: this program computes cloud fractions from cloud ! -! condensates, ! -! and computes the low, mid, high, total and boundary layer cloud ! -! fractions and the vertical indices of low, mid, and high cloud ! -! top and base. the three vertical cloud domains are set up in the ! -! initial subroutine "cld_init". ! -! ! -! usage: call progcld2 ! -! ! -! subprograms called: gethml ! -! ! -! attributes: ! -! language: fortran 90 ! -! machine: ibm-sp, sgi ! -! ! -! ! -! ==================== definition of variables ==================== ! -! ! -! input variables: ! -! plyr (IX,NLAY) : model layer mean pressure in mb (100Pa) ! -! plvl (IX,NLP1) : model level pressure in mb (100Pa) ! -! tlyr (IX,NLAY) : model layer mean temperature in k ! -! tvly (IX,NLAY) : model layer virtual temperature in k ! -! qlyr (IX,NLAY) : layer specific humidity in gm/gm ! -! qstl (IX,NLAY) : layer saturate humidity in gm/gm ! -! rhly (IX,NLAY) : layer relative humidity (=qlyr/qstl) ! -! clw (IX,NLAY) : layer cloud condensate amount ! -! xlat (IX) : grid latitude in radians, default to pi/2 -> -pi/2! -! range, otherwise see in-line comment ! -! xlon (IX) : grid longitude in radians (not used) ! -! slmsk (IX) : sea/land mask array (sea:0,land:1,sea-ice:2) ! -! dz (ix,nlay) : layer thickness (km) ! -! delp (ix,nlay) : model layer pressure thickness in mb (100Pa) ! -! IX : horizontal dimention ! -! NLAY,NLP1 : vertical layer/level dimensions ! -! lmfshal : logical - true for mass flux shallow convection ! -! lmfdeep2 : logical - true for mass flux deep convection ! -! dzlay(ix,nlay) : thickness between model layer centers (km) ! -! latdeg(ix) : latitude (in degrees 90 -> -90) ! -! julian : day of the year (fractional julian day) ! -! yearlen : current length of the year (365/366 days) ! -! ! -! output variables: ! -! clouds(IX,NLAY,NF_CLDS) : cloud profiles ! -! clouds(:,:,1) - layer total cloud fraction ! -! clouds(:,:,2) - layer cloud liq water path (g/m**2) ! -! clouds(:,:,3) - mean eff radius for liq cloud (micron) ! -! clouds(:,:,4) - layer cloud ice water path (g/m**2) ! -! clouds(:,:,5) - mean eff radius for ice cloud (micron) ! -! clouds(:,:,6) - layer rain drop water path not assigned ! -! clouds(:,:,7) - mean eff radius for rain drop (micron) ! -! *** clouds(:,:,8) - layer snow flake water path not assigned ! -! clouds(:,:,9) - mean eff radius for snow flake (micron) ! -! *** fu's scheme need to be normalized by snow density (g/m**3/1.0e6) ! -! clds (IX,5) : fraction of clouds for low, mid, hi, tot, bl ! -! mtop (IX,3) : vertical indices for low, mid, hi cloud tops ! -! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! -! de_lgth(ix) : clouds decorrelation length (km) ! -! alpha(ix,nlay) : alpha decorrelation parameter -! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lmfshal : mass-flux shallow conv scheme flag ! -! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! ! -! ==================== end of description ===================== ! -! - implicit none - -! --- inputs - integer, intent(in) :: IX, NLAY, NLP1 - integer, intent(in) :: ntrac, ntcw, ntiw, ntrw - - logical, intent(in) :: lmfshal, lmfdeep2 - - real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & - & tlyr, qlyr, qstl, rhly, tvly, dz, delp, dzlay - - real (kind=kind_phys), dimension(:,:,:), intent(in) :: clw - - real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & - & slmsk - - real(kind=kind_phys), dimension(:), intent(in) :: latdeg - real(kind=kind_phys), intent(in) :: julian - integer, intent(in) :: yearlen - -! --- outputs - real (kind=kind_phys), dimension(:,:,:), intent(out) :: clouds - - real (kind=kind_phys), dimension(:,:), intent(out) :: clds - real (kind=kind_phys), dimension(:), intent(out) :: de_lgth - real (kind=kind_phys), dimension(:,:), intent(out) :: alpha - - integer, dimension(:,:), intent(out) :: mtop,mbot - -! --- local variables: - real (kind=kind_phys), dimension(IX,NLAY) :: cldtot, cldcnv, & - & cwp, cip, crp, csp, rew, rei, res, rer, tem2d, clwf - - real (kind=kind_phys) :: ptop1(IX,NK_CLDS+1), rxlat(ix) - - real (kind=kind_phys) :: clwmin, clwm, clwt, onemrh, value, & - & tem1, tem2, tem3 - - integer :: i, k, id, nf - -! --- constant values -! real (kind=kind_phys), parameter :: xrc3 = 200. - real (kind=kind_phys), parameter :: xrc3 = 100. - -! -!===> ... begin here -! - do nf=1,nf_clds - do k=1,nlay - do i=1,ix - clouds(i,k,nf) = 0.0 - enddo - enddo - enddo -! clouds(:,:,:) = 0.0 - - do k = 1, NLAY - do i = 1, IX - cldtot(i,k) = 0.0 - cldcnv(i,k) = 0.0 - cwp (i,k) = 0.0 - cip (i,k) = 0.0 - crp (i,k) = 0.0 - csp (i,k) = 0.0 - rew (i,k) = reliq_def - rei (i,k) = reice_def - rer (i,k) = rrain_def ! default rain radius to 1000 micron - res (i,k) = rsnow_def - clwf(i,k) = 0.0 - enddo - enddo -! - - do k = 1, NLAY - do i = 1, IX - clwf(i,k) = clw(i,k,ntcw) + clw(i,k,ntiw) - enddo - enddo -!> - Find top pressure for each cloud domain for given latitude. -!! ptopc(k,i): top presure of each cld domain (k=1-4 are sfc,L,m,h; -!! i=1,2 are low-lat (<45 degree) and pole regions) - - do i =1, IX - rxlat(i) = abs( xlat(i) / con_pi ) ! if xlat in pi/2 -> -pi/2 range -! rxlat(i) = abs(0.5 - xlat(i)/con_pi) ! if xlat in 0 -> pi range - enddo - - do id = 1, 4 - tem1 = ptopc(id,2) - ptopc(id,1) - - do i =1, IX - ptop1(i,id) = ptopc(id,1) + tem1*max( 0.0, 4.0*rxlat(i)-1.0 ) - enddo - enddo - -!> - Compute cloud liquid/ice condensate path in \f$ g/m^2 \f$ . - - do k = 1, NLAY - do i = 1, IX - cwp(i,k) = max(0.0, clw(i,k,ntcw) * gfac * delp(i,k)) - cip(i,k) = max(0.0, clw(i,k,ntiw) * gfac * delp(i,k)) - crp(i,k) = max(0.0, clw(i,k,ntrw) * gfac * delp(i,k)) - csp(i,k) = 0.0 - enddo - enddo - -!> - Compute cloud ice effective radii - - do k = 1, NLAY - do i = 1, IX - tem2 = tlyr(i,k) - con_ttp - - if (cip(i,k) > 0.0) then - tem3 = gord * cip(i,k) * plyr(i,k) / (delp(i,k)*tvly(i,k)) - - if (tem2 < -50.0) then - rei(i,k) = (1250.0/9.917) * tem3 ** 0.109 - elseif (tem2 < -40.0) then - rei(i,k) = (1250.0/9.337) * tem3 ** 0.08 - elseif (tem2 < -30.0) then - rei(i,k) = (1250.0/9.208) * tem3 ** 0.055 - else - rei(i,k) = (1250.0/9.387) * tem3 ** 0.031 - endif - rei(i,k) = max(10.0, min(rei(i,k), 150.0)) - endif - enddo - enddo - -!> - Calculate layer cloud fraction. - - clwmin = 0.0 - if (.not. lmfshal) then - do k = 1, NLAY - do i = 1, IX - clwt = 1.0e-6 * (plyr(i,k)*0.001) -! clwt = 2.0e-6 * (plyr(i,k)*0.001) - - if (clwf(i,k) > clwt) then - - onemrh= max( 1.e-10, 1.0-rhly(i,k) ) - clwm = clwmin / max( 0.01, plyr(i,k)*0.001 ) - - tem1 = min(max(sqrt(sqrt(onemrh*qstl(i,k))),0.0001),1.0) - tem1 = 2000.0 / tem1 - -! tem1 = 1000.0 / tem1 - - value = max( min( tem1*(clwf(i,k)-clwm), 50.0 ), 0.0 ) - tem2 = sqrt( sqrt(rhly(i,k)) ) - - cldtot(i,k) = max( tem2*(1.0-exp(-value)), 0.0 ) - endif - enddo - enddo - else - do k = 1, NLAY - do i = 1, IX - clwt = 1.0e-6 * (plyr(i,k)*0.001) -! clwt = 2.0e-6 * (plyr(i,k)*0.001) - - if (clwf(i,k) > clwt) then - onemrh= max( 1.e-10, 1.0-rhly(i,k) ) - clwm = clwmin / max( 0.01, plyr(i,k)*0.001 ) -! - tem1 = min(max((onemrh*qstl(i,k))**0.49,0.0001),1.0) !jhan - if (lmfdeep2) then - tem1 = xrc3 / tem1 - else - tem1 = 100.0 / tem1 - endif -! - value = max( min( tem1*(clwf(i,k)-clwm), 50.0 ), 0.0 ) - tem2 = sqrt( sqrt(rhly(i,k)) ) - - cldtot(i,k) = max( tem2*(1.0-exp(-value)), 0.0 ) - endif - enddo - enddo - endif - - do k = 1, NLAY - do i = 1, IX - if (cldtot(i,k) < climit) then - cldtot(i,k) = 0.0 - cwp(i,k) = 0.0 - cip(i,k) = 0.0 - crp(i,k) = 0.0 - csp(i,k) = 0.0 - endif - enddo - enddo - - if ( lcnorm ) then - do k = 1, NLAY - do i = 1, IX - if (cldtot(i,k) >= climit) then - tem1 = 1.0 / max(climit2, cldtot(i,k)) - cwp(i,k) = cwp(i,k) * tem1 - cip(i,k) = cip(i,k) * tem1 - crp(i,k) = crp(i,k) * tem1 - csp(i,k) = csp(i,k) * tem1 - endif - enddo - enddo - endif - -! - do k = 1, NLAY - do i = 1, IX - clouds(i,k,1) = cldtot(i,k) - clouds(i,k,2) = cwp(i,k) - clouds(i,k,3) = rew(i,k) - clouds(i,k,4) = cip(i,k) - clouds(i,k,5) = rei(i,k) - clouds(i,k,6) = crp(i,k) ! added for Thompson - clouds(i,k,7) = rer(i,k) - clouds(i,k,8) = csp(i,k) ! added for Thompson - clouds(i,k,9) = res(i,k) - enddo - enddo - - ! Compute cloud decorrelation length - if (idcor == 1) then - call cmp_dcorr_lgth(ix, xlat, con_pi, de_lgth) - endif - if (idcor == 2) then - call cmp_dcorr_lgth(ix, latdeg, julian, yearlen, de_lgth) - endif - if (idcor == 0) then - de_lgth(:) = decorr_con - endif - - ! Call subroutine get_alpha_exp to define alpha parameter for exponential cloud overlap options - if (iovr == 3 .or. iovr == 4 .or. iovr == 5) then - call get_alpha_exp(ix, nLay, dzlay, de_lgth, alpha) - else - de_lgth(:) = 0. - alpha(:,:) = 0. - endif - - ! Revise alpha for exponential-random cloud overlap - ! Decorrelate layers when a clear layer follows a cloudy layer to enforce - ! random correlation between non-adjacent blocks of cloudy layers - if (iovr == 5) then - do k = 2, nLay - do i = 1, ix - if (clouds(i,k,1) == 0.0 .and. clouds(i,k-1,1) > 0.0) then - alpha(i,k) = 0.0 - endif - enddo - enddo - endif - -!> - Call gethml() to compute low,mid,high,total, and boundary layer -!! cloud fractions and clouds top/bottom layer indices for low, mid, -!! and high clouds. -! --- compute low, mid, high, total, and boundary layer cloud fractions -! and clouds top/bottom layer indices for low, mid, and high clouds. -! The three cloud domain boundaries are defined by ptopc. The cloud -! overlapping method is defined by control flag 'iovr', which may -! be different for lw and sw radiation programs. - - call gethml & -! --- inputs: - & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & - & IX,NLAY, & -! --- outputs: - & clds, mtop, mbot & - & ) - - -! - return -!................................... - end subroutine progcld2 -!................................... - -!> @} -!----------------------------------- +!----------------------------------- !> \ingroup module_radiation_clouds !> This subroutine computes cloud related quantities using !! zhao/moorthi's prognostic cloud microphysics scheme + pdfcld. -!!\param plyr (ix,nlay), model layer mean pressure in mb (100pa) -!!\param plvl (ix,nlp1), model level pressure in mb (100pa) -!!\param tlyr (ix,nlay), model layer mean temperature in K -!!\param tvly (ix,nlay), model layer virtual temperature in K -!!\param qlyr (ix,nlay), layer specific humidity in gm/gm -!!\param qstl (ix,nlay), layer saturate humidity in gm/gm -!!\param rhly (ix,nlay), layer relative humidity (=qlyr/qstl) -!!\param clw (ix,nlay), layer cloud condensate amount -!!\param cnvw (ix,nlay), layer convective cloud condensate -!!\param cnvc (ix,nlay), layer convective cloud cover -!!\param xlat (ix), grid latitude in radians, default to pi/2 -> -!! -pi/2 range, otherwise see in-line comment -!!\param xlon (ix), grid longitude in radians (not used) -!!\param slmsk (ix), sea/land mask array (sea:0,land:1,sea-ice:2) -!!\param dz (IX,NLAY), layer thickness (km) -!!\param delp (IX,NLAY), model layer pressure thickness in mb (100Pa) -!!\param ix horizontal dimention -!!\param nlay,nlp1 vertical layer/level dimensions -!!\param deltaq (ix,nlay), half total water distribution width -!!\param sup supersaturation -!!\param kdt -!!\param me print control flag -!!\param dzlay(ix,nlay) distance between model layer centers -!!\param latdeg(ix) latitude (in degrees 90 -> -90) -!!\param julian day of the year (fractional julian day) -!!\param yearlen current length of the year (365/366 days) -!!\param clouds (ix,nlay,nf_clds), cloud profiles -!!\n (:,:,1) - layer total cloud fraction -!!\n (:,:,2) - layer cloud liq water path (g/m**2) -!!\n (:,:,3) - mean eff radius for liq cloud (micron) -!!\n (:,:,4) - layer cloud ice water path (g/m**2) -!!\n (:,:,5) - mean eff radius for ice cloud (micron) -!!\n (:,:,6) - layer rain drop water path not assigned -!!\n (:,:,7) - mean eff radius for rain drop (micron) -!!\n (:,:,8) - layer snow flake water path not assigned -!!\n (:,:,9) - mean eff radius for snow flake(micron) -!!\param clds (ix,5), fraction of clouds for low, mid, hi, tot, bl -!!\param mtop (ix,3), vertical indices for low, mid, hi cloud tops -!!\param mbot (ix,3), vertical indices for low, mid, hi cloud bases -!!\param de_lgth (ix), clouds decorrelation length (km) -!!\param alpha (IX,NLAY), alpha decorrelation parameter -!>\section gen_progcld3 progcld3 General Algorithm +!>\section progcld_zhao_carr_pdf General Algorithm !! @{ - subroutine progcld3 & + subroutine progcld_zhao_carr_pdf & & ( plyr,plvl,tlyr,tvly,qlyr,qstl,rhly,clw,cnvw,cnvc, & ! --- inputs: & xlat,xlon,slmsk, dz, delp, & & ix, nlay, nlp1, & - & deltaq,sup,kdt,me, & - & dzlay, latdeg, julian, yearlen, & - & clouds,clds,mtop,mbot,de_lgth,alpha & ! --- outputs: - & ) - -! ================= subprogram documentation block ================ ! -! ! -! subprogram: progcld3 computes cloud related quantities using ! -! zhao/moorthi's prognostic cloud microphysics scheme. ! -! ! -! abstract: this program computes cloud fractions from cloud ! -! condensates, calculates liquid/ice cloud droplet effective radius, ! -! and computes the low, mid, high, total and boundary layer cloud ! -! fractions and the vertical indices of low, mid, and high cloud ! -! top and base. the three vertical cloud domains are set up in the ! -! initial subroutine "cld_init". ! -! ! -! usage: call progcld3 ! -! ! -! subprograms called: gethml ! -! ! -! attributes: ! -! language: fortran 90 ! -! machine: ibm-sp, sgi ! -! ! -! ! -! ==================== defination of variables ==================== ! -! ! -! input variables: ! -! plyr (ix,nlay) : model layer mean pressure in mb (100pa) ! -! plvl (ix,nlp1) : model level pressure in mb (100pa) ! -! tlyr (ix,nlay) : model layer mean temperature in k ! -! tvly (ix,nlay) : model layer virtual temperature in k ! -! qlyr (ix,nlay) : layer specific humidity in gm/gm ! -! qstl (ix,nlay) : layer saturate humidity in gm/gm ! -! rhly (ix,nlay) : layer relative humidity (=qlyr/qstl) ! -! clw (ix,nlay) : layer cloud condensate amount ! -! xlat (ix) : grid latitude in radians, default to pi/2 -> -pi/2! -! range, otherwise see in-line comment ! -! xlon (ix) : grid longitude in radians (not used) ! -! slmsk (ix) : sea/land mask array (sea:0,land:1,sea-ice:2) ! -! dz (ix,nlay) : layer thickness (km) ! -! delp (ix,nlay) : model layer pressure thickness in mb (100Pa) ! -! ix : horizontal dimention ! -! nlay,nlp1 : vertical layer/level dimensions ! -! cnvw (ix,nlay) : layer convective cloud condensate ! -! cnvc (ix,nlay) : layer convective cloud cover ! -! deltaq(ix,nlay) : half total water distribution width ! -! sup : supersaturation ! -! dzlay(ix,nlay) : thickness between model layer centers (km) ! -! latdeg(ix) : latitude (in degrees 90 -> -90) ! -! julian : day of the year (fractional julian day) ! -! yearlen : current length of the year (365/366 days) ! - -! ! -! output variables: ! -! clouds(ix,nlay,nf_clds) : cloud profiles ! -! clouds(:,:,1) - layer total cloud fraction ! -! clouds(:,:,2) - layer cloud liq water path (g/m**2) ! -! clouds(:,:,3) - mean eff radius for liq cloud (micron) ! -! clouds(:,:,4) - layer cloud ice water path (g/m**2) ! -! clouds(:,:,5) - mean eff radius for ice cloud (micron) ! -! clouds(:,:,6) - layer rain drop water path not assigned ! -! clouds(:,:,7) - mean eff radius for rain drop (micron) ! -! *** clouds(:,:,8) - layer snow flake water path not assigned ! -! clouds(:,:,9) - mean eff radius for snow flake (micron) ! -! *** fu's scheme need to be normalized by snow density (g/m**3/1.0e6) ! -! clds (ix,5) : fraction of clouds for low, mid, hi, tot, bl ! -! mtop (ix,3) : vertical indices for low, mid, hi cloud tops ! -! mbot (ix,3) : vertical indices for low, mid, hi cloud bases ! -! de_lgth(ix) : clouds decorrelation length (km) ! -! alpha(ix,nlay) : alpha decorrelation parameter -! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lcrick : control flag for eliminating crick ! -! =t: apply layer smoothing to eliminate crick ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! ! -! ==================== end of description ===================== ! -! - implicit none - -! --- inputs - integer, intent(in) :: ix, nlay, nlp1,kdt - - real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & - & tlyr, tvly, qlyr, qstl, rhly, clw, dz, delp, dzlay -! & tlyr, tvly, qlyr, qstl, rhly, clw, cnvw, cnvc -! real (kind=kind_phys), dimension(:,:), intent(in) :: deltaq - real (kind=kind_phys), dimension(:,:) :: deltaq, cnvw, cnvc - real (kind=kind_phys) qtmp,qsc,rhs - real (kind=kind_phys), intent(in) :: sup - real (kind=kind_phys), parameter :: epsq = 1.0e-12 - - real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & - & slmsk - integer :: me - - real(kind=kind_phys), dimension(:), intent(in) :: latdeg - real(kind=kind_phys), intent(in) :: julian - integer, intent(in) :: yearlen - -! --- outputs - real (kind=kind_phys), dimension(:,:,:), intent(out) :: clouds - - real (kind=kind_phys), dimension(:,:), intent(out) :: clds - real (kind=kind_phys), dimension(:), intent(out) :: de_lgth - real (kind=kind_phys), dimension(:,:), intent(out) :: alpha - - integer, dimension(:,:), intent(out) :: mtop,mbot - -! --- local variables: - real (kind=kind_phys), dimension(ix,nlay) :: cldtot, cldcnv, & - & cwp, cip, crp, csp, rew, rei, res, rer, tem2d, clwf - - real (kind=kind_phys) :: ptop1(ix,nk_clds+1), rxlat(ix) - - real (kind=kind_phys) :: clwmin, clwm, clwt, onemrh, value, & - & tem1, tem2, tem3 - - integer :: i, k, id, nf - -! -!===> ... begin here -! - do nf=1,nf_clds - do k=1,nlay - do i=1,ix - clouds(i,k,nf) = 0.0 - enddo - enddo - enddo -! clouds(:,:,:) = 0.0 - - do k = 1, nlay - do i = 1, ix - cldtot(i,k) = 0.0 - cldcnv(i,k) = 0.0 - cwp (i,k) = 0.0 - cip (i,k) = 0.0 - crp (i,k) = 0.0 - csp (i,k) = 0.0 - rew (i,k) = reliq_def ! default liq radius to 10 micron - rei (i,k) = reice_def ! default ice radius to 50 micron - rer (i,k) = rrain_def ! default rain radius to 1000 micron - res (i,k) = rsnow_def ! default snow radius to 250 micron - tem2d (i,k) = min( 1.0, max( 0.0, (con_ttp-tlyr(i,k))*0.05 ) ) - clwf(i,k) = 0.0 - enddo - enddo -! - if ( lcrick ) then - do i = 1, ix - clwf(i,1) = 0.75*clw(i,1) + 0.25*clw(i,2) - clwf(i,nlay) = 0.75*clw(i,nlay) + 0.25*clw(i,nlay-1) - enddo - do k = 2, nlay-1 - do i = 1, ix - clwf(i,k) = 0.25*clw(i,k-1) + 0.5*clw(i,k) + 0.25*clw(i,k+1) - enddo - enddo - else - do k = 1, nlay - do i = 1, ix - clwf(i,k) = clw(i,k) - enddo - enddo - endif - - if(kdt==1) then - do k = 1, nlay - do i = 1, ix - deltaq(i,k) = (1.-0.95)*qstl(i,k) - enddo - enddo - endif - -!> -# Find top pressure (ptopc) for each cloud domain for given latitude. -! ptopc(k,i): top presure of each cld domain (k=1-4 are sfc,l,m,h; -! --- i=1,2 are low-lat (<45 degree) and pole regions) - - do i =1, IX - rxlat(i) = abs( xlat(i) / con_pi ) ! if xlat in pi/2 -> -pi/2 range -! rxlat(i) = abs(0.5 - xlat(i)/con_pi) ! if xlat in 0 -> pi range - enddo - - do id = 1, 4 - tem1 = ptopc(id,2) - ptopc(id,1) - - do i =1, ix - ptop1(i,id) = ptopc(id,1) + tem1*max( 0.0, 4.0*rxlat(i)-1.0 ) - enddo - enddo - -!> -# Calculate liquid/ice condensate path in \f$ g/m^2 \f$ - - do k = 1, nlay - do i = 1, ix - clwt = max(0.0,(clwf(i,k)+cnvw(i,k))) * gfac * delp(i,k) - cip(i,k) = clwt * tem2d(i,k) - cwp(i,k) = clwt - cip(i,k) - enddo - enddo - -!> -# Calculate effective liquid cloud droplet radius over land. - - do i = 1, ix - if (nint(slmsk(i)) == 1) then - do k = 1, nlay - rew(i,k) = 5.0 + 5.0 * tem2d(i,k) - enddo - endif - enddo - -!> -# Calculate layer cloud fraction. - - do k = 1, nlay - do i = 1, ix - tem1 = tlyr(i,k) - 273.16 - if(tem1 < con_thgni) then ! for pure ice, has to be consistent with gscond - qsc = sup * qstl(i,k) - rhs = sup - else - qsc = qstl(i,k) - rhs = 1.0 - endif - if(rhly(i,k) >= rhs) then - cldtot(i,k) = 1.0 - else - qtmp = qlyr(i,k) + clwf(i,k) - qsc - if(deltaq(i,k) > epsq) then -! if(qtmp <= -deltaq(i,k) .or. cwmik < epsq) then - if(qtmp <= -deltaq(i,k)) then - cldtot(i,k) = 0.0 - elseif(qtmp >= deltaq(i,k)) then - cldtot(i,k) = 1.0 - else - cldtot(i,k) = 0.5*qtmp/deltaq(i,k) + 0.5 - cldtot(i,k) = max(cldtot(i,k),0.0) - cldtot(i,k) = min(cldtot(i,k),1.0) - endif - else - if(qtmp > 0.) then - cldtot(i,k) = 1.0 - else - cldtot(i,k) = 0.0 - endif - endif - endif - cldtot(i,k) = cnvc(i,k) + (1-cnvc(i,k))*cldtot(i,k) - cldtot(i,k) = max(cldtot(i,k),0.) - cldtot(i,k) = min(cldtot(i,k),1.) - - enddo - enddo - - do k = 1, nlay - do i = 1, ix - if (cldtot(i,k) < climit) then - cldtot(i,k) = 0.0 - cwp(i,k) = 0.0 - cip(i,k) = 0.0 - crp(i,k) = 0.0 - csp(i,k) = 0.0 - endif - enddo - enddo - - if ( lcnorm ) then - do k = 1, nlay - do i = 1, ix - if (cldtot(i,k) >= climit) then - tem1 = 1.0 / max(climit2, cldtot(i,k)) - cwp(i,k) = cwp(i,k) * tem1 - cip(i,k) = cip(i,k) * tem1 - crp(i,k) = crp(i,k) * tem1 - csp(i,k) = csp(i,k) * tem1 - endif - enddo - enddo - endif - -!> -# Calculate effective ice cloud droplet radius following Heymsfield -!! and McFarquhar (1996) \cite heymsfield_and_mcfarquhar_1996. - - do k = 1, nlay - do i = 1, ix - tem2 = tlyr(i,k) - con_ttp - - if (cip(i,k) > 0.0) then -! tem3 = gord * cip(i,k) * (plyr(i,k)/delp(i,k)) / tvly(i,k) - tem3 = gord * cip(i,k) * plyr(i,k) / (delp(i,k)*tvly(i,k)) - - if (tem2 < -50.0) then - rei(i,k) = (1250.0/9.917) * tem3 ** 0.109 - elseif (tem2 < -40.0) then - rei(i,k) = (1250.0/9.337) * tem3 ** 0.08 - elseif (tem2 < -30.0) then - rei(i,k) = (1250.0/9.208) * tem3 ** 0.055 - else - rei(i,k) = (1250.0/9.387) * tem3 ** 0.031 - endif -! rei(i,k) = max(20.0, min(rei(i,k), 300.0)) -! rei(i,k) = max(10.0, min(rei(i,k), 100.0)) - rei(i,k) = max(10.0, min(rei(i,k), 150.0)) -! rei(i,k) = max(5.0, min(rei(i,k), 130.0)) - endif - enddo - enddo - -! - do k = 1, nlay - do i = 1, ix - clouds(i,k,1) = cldtot(i,k) - clouds(i,k,2) = cwp(i,k) - clouds(i,k,3) = rew(i,k) - clouds(i,k,4) = cip(i,k) - clouds(i,k,5) = rei(i,k) -! clouds(i,k,6) = 0.0 - clouds(i,k,7) = rer(i,k) -! clouds(i,k,8) = 0.0 - clouds(i,k,9) = res(i,k) - enddo - enddo - - ! Compute cloud decorrelation length - if (idcor == 1) then - call cmp_dcorr_lgth(ix, xlat, con_pi, de_lgth) - endif - if (idcor == 2) then - call cmp_dcorr_lgth(ix, latdeg, julian, yearlen, de_lgth) - endif - if (idcor == 0) then - de_lgth(:) = decorr_con - endif - - ! Call subroutine get_alpha_exp to define alpha parameter for exponential cloud overlap options - if (iovr == 3 .or. iovr == 4 .or. iovr == 5) then - call get_alpha_exp(ix, nLay, dzlay, de_lgth, alpha) - else - de_lgth(:) = 0. - alpha(:,:) = 0. - endif - - ! Revise alpha for exponential-random cloud overlap - ! Decorrelate layers when a clear layer follows a cloudy layer to enforce - ! random correlation between non-adjacent blocks of cloudy layers - if (iovr == 5) then - do k = 2, nLay - do i = 1, ix - if (clouds(i,k,1) == 0.0 .and. clouds(i,k-1,1) > 0.0) then - alpha(i,k) = 0.0 - endif - enddo - enddo - endif - -!> -# Call gethml() to compute low,mid,high,total, and boundary layer -!! cloud fractions and clouds top/bottom layer indices for low, mid, -!! and high clouds. -! the three cloud domain boundaries are defined by ptopc. the cloud -! overlapping method is defined by control flag 'iovr', which may -! be different for lw and sw radiation programs. - - - call gethml & -! --- inputs: - & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & - & ix,nlay, & -! --- outputs: - & clds, mtop, mbot & - & ) - - -! - return -!................................... - end subroutine progcld3 -!! @} -!----------------------------------- - - -!----------------------------------- -!> \ingroup module_radiation_clouds -!> This subroutine computes cloud related quantities using -!! GFDL Lin MP prognostic cloud microphysics scheme. -!!\param plyr (ix,nlay), model layer mean pressure in mb (100Pa) -!!\param plvl (ix,nlp1), model level pressure in mb (100Pa) -!!\param tlyr (ix,nlay), model layer mean temperature in K -!!\param tvly (ix,nlay), model layer virtual temperature in K -!!\param qlyr (ix,nlay), layer specific humidity in gm/gm -!!\param qstl (ix,nlay), layer saturate humidity in gm/gm -!!\param rhly (ix,nlay), layer relative humidity (=qlyr/qstl) -!!\param clw (ix,nlay), layer cloud condensate amount -!!\param cnvw (ix,nlay), layer convective cloud condensate -!!\param cnvc (ix,nlay), layer convective cloud cover -!!\param xlat (ix), grid latitude in radians, default to pi/2 -> -pi/2 -!! range, otherwise see in-line comment -!!\param xlon (ix), grid longitude in radians (not used) -!!\param slmsk (ix), sea/land mask array (sea:0, land:1, sea-ice:2) -!!\param cldtot (ix,nlay), layer total cloud fraction -!!\param dz (ix,nlay), layer thickness (km) -!!\param delp (ix,nlay), model layer pressure thickness in mb (100Pa) -!!\param ix horizontal dimension -!!\param nlay vertical layer dimension -!!\param nlp1 vertical level dimension -!!\param dzlay(ix,nlay) distance between model layer centers -!!\param latdeg(ix) latitude (in degrees 90 -> -90) -!!\param julian day of the year (fractional julian day) -!!\param yearlen current length of the year (365/366 days) -!!\param clouds (ix,nlay,nf_clds), cloud profiles -!!\n clouds(:,:,1) - layer total cloud fraction -!!\n clouds(:,:,2) - layer cloud liquid water path (\f$g m^{-2}\f$) -!!\n clouds(:,:,3) - mean effective radius for liquid cloud (micron) -!!\n clouds(:,:,4) - layer cloud ice water path (\f$g m^{-2}\f$) -!!\n clouds(:,:,5) - mean effective radius for ice cloud (micron) -!!\n clouds(:,:,6) - layer rain drop water path (\f$g m^{-2}\f$) (not assigned) -!!\n clouds(:,:,7) - mean effective radius for rain drop (micron) -!!\n clouds(:,:,8) - layer snow flake water path (not assigned) (\f$g m^{-2}\f$) (not assigned) -!!\n clouds(:,:,9) - mean effective radius for snow flake (micron) -!!\param clds fraction of clouds for low, mid, hi cloud tops -!!\param mtop vertical indices for low, mid, hi cloud tops -!!\param mbot vertical indices for low, mid, hi cloud bases -!!\param de_lgth clouds decorrelation length (km) -!!\param alpha (IX,NLAY), alpha decorrelation parameter -!>\section gen_progcld4 progcld4 General Algorithm -!! @{ - subroutine progcld4 & - & ( plyr,plvl,tlyr,tvly,qlyr,qstl,rhly,clw,cnvw,cnvc, & ! --- inputs: - & xlat,xlon,slmsk,cldtot, dz, delp, & - & IX, NLAY, NLP1, & - & dzlay, latdeg, julian, yearlen, & - & clouds,clds,mtop,mbot,de_lgth,alpha & ! --- outputs: + & deltaq,sup,kdt,me, & + & dzlay, cldtot, cldcnv, & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) ! ================= subprogram documentation block ================ ! ! ! -! subprogram: progcld4 computes cloud related quantities using ! -! GFDL Lin MP prognostic cloud microphysics scheme. ! +! subprogram: progcld_zhao_carr_pdf computes cloud related quantities using ! +! zhao/moorthi's prognostic cloud microphysics scheme. ! ! ! ! abstract: this program computes cloud fractions from cloud ! ! condensates, calculates liquid/ice cloud droplet effective radius, ! @@ -1831,7 +1274,7 @@ subroutine progcld4 & ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! ! ! -! usage: call progcld4 ! +! usage: call progcld_zhao_carr_pdf ! ! ! ! subprograms called: gethml ! ! ! @@ -1840,57 +1283,49 @@ subroutine progcld4 & ! machine: ibm-sp, sgi ! ! ! ! ! -! ==================== definition of variables ==================== ! +! ==================== defination of variables ==================== ! ! ! ! input variables: ! -! plyr (IX,NLAY) : model layer mean pressure in mb (100Pa) ! -! plvl (IX,NLP1) : model level pressure in mb (100Pa) ! -! tlyr (IX,NLAY) : model layer mean temperature in k ! -! tvly (IX,NLAY) : model layer virtual temperature in k ! -! qlyr (IX,NLAY) : layer specific humidity in gm/gm ! -! qstl (IX,NLAY) : layer saturate humidity in gm/gm ! -! rhly (IX,NLAY) : layer relative humidity (=qlyr/qstl) ! -! clw (IX,NLAY) : layer cloud condensate amount ! -! cnvw (IX,NLAY) : layer convective cloud condensate ! -! cnvc (IX,NLAY) : layer convective cloud cover ! -! xlat (IX) : grid latitude in radians, default to pi/2 -> -pi/2! +! plyr (ix,nlay) : model layer mean pressure in mb (100pa) ! +! plvl (ix,nlp1) : model level pressure in mb (100pa) ! +! tlyr (ix,nlay) : model layer mean temperature in k ! +! tvly (ix,nlay) : model layer virtual temperature in k ! +! qlyr (ix,nlay) : layer specific humidity in gm/gm ! +! qstl (ix,nlay) : layer saturate humidity in gm/gm ! +! rhly (ix,nlay) : layer relative humidity (=qlyr/qstl) ! +! clw (ix,nlay) : layer cloud condensate amount ! +! xlat (ix) : grid latitude in radians, default to pi/2 -> -pi/2! ! range, otherwise see in-line comment ! -! xlon (IX) : grid longitude in radians (not used) ! -! slmsk (IX) : sea/land mask array (sea:0,land:1,sea-ice:2) ! +! xlon (ix) : grid longitude in radians (not used) ! +! slmsk (ix) : sea/land mask array (sea:0,land:1,sea-ice:2) ! ! dz (ix,nlay) : layer thickness (km) ! ! delp (ix,nlay) : model layer pressure thickness in mb (100Pa) ! -! IX : horizontal dimention ! -! NLAY,NLP1 : vertical layer/level dimensions ! +! ix : horizontal dimention ! +! nlay,nlp1 : vertical layer/level dimensions ! +! cnvw (ix,nlay) : layer convective cloud condensate ! +! cnvc (ix,nlay) : layer convective cloud cover ! +! deltaq(ix,nlay) : half total water distribution width ! +! sup : supersaturation ! ! dzlay(ix,nlay) : thickness between model layer centers (km) ! -! latdeg(ix) : latitude (in degrees 90 -> -90) ! -! julian : day of the year (fractional julian day) ! -! yearlen : current length of the year (365/366 days) ! ! ! ! output variables: ! -! clouds(IX,NLAY,NF_CLDS) : cloud profiles ! -! clouds(:,:,1) - layer total cloud fraction ! -! clouds(:,:,2) - layer cloud liq water path (g/m**2) ! -! clouds(:,:,3) - mean eff radius for liq cloud (micron) ! -! clouds(:,:,4) - layer cloud ice water path (g/m**2) ! -! clouds(:,:,5) - mean eff radius for ice cloud (micron) ! -! clouds(:,:,6) - layer rain drop water path not assigned ! -! clouds(:,:,7) - mean eff radius for rain drop (micron) ! -! *** clouds(:,:,8) - layer snow flake water path not assigned ! -! clouds(:,:,9) - mean eff radius for snow flake (micron) ! -! *** fu's scheme need to be normalized by snow density (g/m**3/1.0e6) ! -! clds (IX,5) : fraction of clouds for low, mid, hi, tot, bl ! -! mtop (IX,3) : vertical indices for low, mid, hi cloud tops ! -! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! -! de_lgth(ix) : clouds decorrelation length (km) ! -! alpha(ix,nlay) : alpha decorrelation parameter +! cloud profiles: ! +! cld_frac (:,:) - layer total cloud fraction ! +! cld_lwp (:,:) - layer cloud liq water path (g/m**2) ! +! cld_reliq (:,:) - mean eff radius for liq cloud (micron) ! +! cld_iwp (:,:) - layer cloud ice water path (g/m**2) ! +! cld_reice (:,:) - mean eff radius for ice cloud (micron) ! +! cld_rwp (:,:) - layer rain drop water path not assigned ! +! cld_rerain(:,:) - mean eff radius for rain drop (micron) ! +! *** cld_swp (:,:) - layer snow flake water path not assigned ! +! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! ! ! module variables: ! ! ivflip : control flag of vertical index direction ! ! =0: index from toa to surface ! ! =1: index from surface to toa ! -! lsashal : control flag for shallow convection ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! +! lcrick : control flag for eliminating crick ! +! =t: apply layer smoothing to eliminate crick ! ! =f: do not apply layer smoothing ! ! lcnorm : control flag for in-cld condensate ! ! =t: normalize cloud condensate ! @@ -1901,34 +1336,31 @@ subroutine progcld4 & implicit none ! --- inputs - integer, intent(in) :: IX, NLAY, NLP1 + integer, intent(in) :: ix, nlay, nlp1,kdt - real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & - & tlyr, tvly, qlyr, qstl, rhly, clw, cldtot, cnvw, cnvc, & - & delp, dz, dzlay + real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & + & tlyr, tvly, qlyr, qstl, rhly, clw, dz, delp, dzlay +! & tlyr, tvly, qlyr, qstl, rhly, clw, cnvw, cnvc +! real (kind=kind_phys), dimension(:,:), intent(in) :: deltaq + real (kind=kind_phys), dimension(:,:) :: deltaq, cnvw, cnvc + real (kind=kind_phys) qtmp,qsc,rhs + real (kind=kind_phys), intent(in) :: sup + real (kind=kind_phys), parameter :: epsq = 1.0e-12 - real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & + real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & & slmsk + integer :: me - real(kind=kind_phys), dimension(:), intent(in) :: latdeg - real(kind=kind_phys), intent(in) :: julian - integer, intent(in) :: yearlen - -! --- outputs - real (kind=kind_phys), dimension(:,:,:), intent(out) :: clouds - - real (kind=kind_phys), dimension(:,:), intent(out) :: clds - real (kind=kind_phys), dimension(:), intent(out) :: de_lgth - real (kind=kind_phys), dimension(:,:), intent(out) :: alpha +! --- inputs/outputs - integer, dimension(:,:), intent(out) :: mtop,mbot + real (kind=kind_phys), dimension(:,:), intent(inout) :: & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & + & cld_rwp, cld_rerain, cld_swp, cld_resnow ! --- local variables: - real (kind=kind_phys), dimension(IX,NLAY) :: cldcnv, & + real (kind=kind_phys), dimension(ix,nlay) :: cldtot, cldcnv, & & cwp, cip, crp, csp, rew, rei, res, rer, tem2d, clwf - real (kind=kind_phys) :: ptop1(IX,NK_CLDS+1), rxlat(ix) - real (kind=kind_phys) :: clwmin, clwm, clwt, onemrh, value, & & tem1, tem2, tem3 @@ -1937,90 +1369,115 @@ subroutine progcld4 & ! !===> ... begin here ! - do nf=1,nf_clds - do k=1,nlay - do i=1,ix - clouds(i,k,nf) = 0.0 - enddo - enddo - enddo -! clouds(:,:,:) = 0.0 - -!> - Assign liquid/ice/rain/snow cloud doplet effective radius as default value. - do k = 1, NLAY - do i = 1, IX + do k = 1, nlay + do i = 1, ix + cldtot(i,k) = 0.0 cldcnv(i,k) = 0.0 cwp (i,k) = 0.0 cip (i,k) = 0.0 crp (i,k) = 0.0 csp (i,k) = 0.0 - rew (i,k) = reliq_def !< default liq radius to 10 micron - rei (i,k) = reice_def !< default ice radius to 50 micron - rer (i,k) = rrain_def !< default rain radius to 1000 micron - res (i,k) = rsnow_def !< default snow radius to 250 micron + rew (i,k) = reliq_def ! default liq radius to 10 micron + rei (i,k) = reice_def ! default ice radius to 50 micron + rer (i,k) = rrain_def ! default rain radius to 1000 micron + res (i,k) = rsnow_def ! default snow radius to 250 micron tem2d (i,k) = min( 1.0, max( 0.0, (con_ttp-tlyr(i,k))*0.05 ) ) clwf(i,k) = 0.0 enddo enddo ! if ( lcrick ) then - do i = 1, IX + do i = 1, ix clwf(i,1) = 0.75*clw(i,1) + 0.25*clw(i,2) clwf(i,nlay) = 0.75*clw(i,nlay) + 0.25*clw(i,nlay-1) enddo - do k = 2, NLAY-1 - do i = 1, IX - clwf(i,K) = 0.25*clw(i,k-1) + 0.5*clw(i,k) + 0.25*clw(i,k+1) + do k = 2, nlay-1 + do i = 1, ix + clwf(i,k) = 0.25*clw(i,k-1) + 0.5*clw(i,k) + 0.25*clw(i,k+1) enddo enddo else - do k = 1, NLAY - do i = 1, IX + do k = 1, nlay + do i = 1, ix clwf(i,k) = clw(i,k) enddo enddo endif -!> - Compute top pressure for each cloud domain for given latitude. -!!\n ptopc(k,i): top presure of each cld domain (k=1-4 are sfc,L,m,h; -!! i=1,2 are low-lat (<45 degree) and pole regions) - - do i =1, IX - rxlat(i) = abs( xlat(i) / con_pi ) ! if xlat in pi/2 -> -pi/2 range -! rxlat(i) = abs(0.5 - xlat(i)/con_pi) ! if xlat in 0 -> pi range - enddo - - do id = 1, 4 - tem1 = ptopc(id,2) - ptopc(id,1) - - do i =1, IX - ptop1(i,id) = ptopc(id,1) + tem1*max( 0.0, 4.0*rxlat(i)-1.0 ) + if(kdt==1) then + do k = 1, nlay + do i = 1, ix + deltaq(i,k) = (1.-0.95)*qstl(i,k) + enddo enddo - enddo + endif -!> - Compute liquid/ice condensate path in \f$g m^{-2}\f$. +!> -# Calculate liquid/ice condensate path in \f$ g/m^2 \f$ - do k = 1, NLAY - do i = 1, IX - clwt = max(0.0,(clwf(i,k)+cnvw(i,k))) * gfac * delp(i,k) + do k = 1, nlay + do i = 1, ix + clwt = max(0.0,(clwf(i,k)+cnvw(i,k))) * gfac * delp(i,k) cip(i,k) = clwt * tem2d(i,k) cwp(i,k) = clwt - cip(i,k) enddo enddo -!> - Compute effective liquid cloud droplet radius over land. +!> -# Calculate effective liquid cloud droplet radius over land. - do i = 1, IX + do i = 1, ix if (nint(slmsk(i)) == 1) then - do k = 1, NLAY + do k = 1, nlay rew(i,k) = 5.0 + 5.0 * tem2d(i,k) enddo endif enddo - do k = 1, NLAY - do i = 1, IX +!> -# Calculate layer cloud fraction. + + do k = 1, nlay + do i = 1, ix + tem1 = tlyr(i,k) - 273.16 + if(tem1 < con_thgni) then ! for pure ice, has to be consistent with gscond + qsc = sup * qstl(i,k) + rhs = sup + else + qsc = qstl(i,k) + rhs = 1.0 + endif + if(rhly(i,k) >= rhs) then + cldtot(i,k) = 1.0 + else + qtmp = qlyr(i,k) + clwf(i,k) - qsc + if(deltaq(i,k) > epsq) then +! if(qtmp <= -deltaq(i,k) .or. cwmik < epsq) then + if(qtmp <= -deltaq(i,k)) then + cldtot(i,k) = 0.0 + elseif(qtmp >= deltaq(i,k)) then + cldtot(i,k) = 1.0 + else + cldtot(i,k) = 0.5*qtmp/deltaq(i,k) + 0.5 + cldtot(i,k) = max(cldtot(i,k),0.0) + cldtot(i,k) = min(cldtot(i,k),1.0) + endif + else + if(qtmp > 0.) then + cldtot(i,k) = 1.0 + else + cldtot(i,k) = 0.0 + endif + endif + endif + cldtot(i,k) = cnvc(i,k) + (1-cnvc(i,k))*cldtot(i,k) + cldtot(i,k) = max(cldtot(i,k),0.) + cldtot(i,k) = min(cldtot(i,k),1.) + + enddo + enddo + + do k = 1, nlay + do i = 1, ix if (cldtot(i,k) < climit) then + cldtot(i,k) = 0.0 cwp(i,k) = 0.0 cip(i,k) = 0.0 crp(i,k) = 0.0 @@ -2030,8 +1487,8 @@ subroutine progcld4 & enddo if ( lcnorm ) then - do k = 1, NLAY - do i = 1, IX + do k = 1, nlay + do i = 1, ix if (cldtot(i,k) >= climit) then tem1 = 1.0 / max(climit2, cldtot(i,k)) cwp(i,k) = cwp(i,k) * tem1 @@ -2043,14 +1500,15 @@ subroutine progcld4 & enddo endif -!> - Compute effective ice cloud droplet radius in Heymsfield and McFarquhar (1996) -!! \cite heymsfield_and_mcfarquhar_1996 . +!> -# Calculate effective ice cloud droplet radius following Heymsfield +!! and McFarquhar (1996) \cite heymsfield_and_mcfarquhar_1996. - do k = 1, NLAY - do i = 1, IX + do k = 1, nlay + do i = 1, ix tem2 = tlyr(i,k) - con_ttp if (cip(i,k) > 0.0) then +! tem3 = gord * cip(i,k) * (plyr(i,k)/delp(i,k)) / tvly(i,k) tem3 = gord * cip(i,k) * plyr(i,k) / (delp(i,k)*tvly(i,k)) if (tem2 < -50.0) then @@ -2065,7 +1523,7 @@ subroutine progcld4 & ! rei(i,k) = max(20.0, min(rei(i,k), 300.0)) ! rei(i,k) = max(10.0, min(rei(i,k), 100.0)) rei(i,k) = max(10.0, min(rei(i,k), 150.0)) -! rei(i,k) = max(5.0, min(rei(i,k), 130.0)) +! rei(i,k) = max(5.0, min(rei(i,k), 130.0)) endif enddo enddo @@ -2073,137 +1531,44 @@ subroutine progcld4 & ! do k = 1, NLAY do i = 1, IX - clouds(i,k,1) = cldtot(i,k) - clouds(i,k,2) = cwp(i,k) - clouds(i,k,3) = rew(i,k) - clouds(i,k,4) = cip(i,k) - clouds(i,k,5) = rei(i,k) -! clouds(i,k,6) = 0.0 - clouds(i,k,7) = rer(i,k) -! clouds(i,k,8) = 0.0 - clouds(i,k,9) = res(i,k) + cld_frac(i,k) = cldtot(i,k) + cld_lwp(i,k) = cwp(i,k) + cld_reliq(i,k) = rew(i,k) + cld_iwp(i,k) = cip(i,k) + cld_reice(i,k) = rei(i,k) +! cld_rwp(i,k) = 0.0 + cld_rerain(i,k) = rer(i,k) +! cld_swp(i,k) = 0.0 + cld_resnow(i,k) = res(i,k) enddo enddo - - ! Compute cloud decorrelation length - if (idcor == 1) then - call cmp_dcorr_lgth(ix, xlat, con_pi, de_lgth) - endif - if (idcor == 2) then - call cmp_dcorr_lgth(ix, latdeg, julian, yearlen, de_lgth) - endif - if (idcor == 0) then - de_lgth(:) = decorr_con - endif - - ! Call subroutine get_alpha_exp to define alpha parameter for exponential cloud overlap options - if (iovr == 3 .or. iovr == 4 .or. iovr == 5) then - call get_alpha_exp(ix, nLay, dzlay, de_lgth, alpha) - else - de_lgth(:) = 0. - alpha(:,:) = 0. - endif - - ! Revise alpha for exponential-random cloud overlap - ! Decorrelate layers when a clear layer follows a cloudy layer to enforce - ! random correlation between non-adjacent blocks of cloudy layers - if (iovr == 5) then - do k = 2, nLay - do i = 1, ix - if (clouds(i,k,1) == 0.0 .and. clouds(i,k-1,1) > 0.0) then - alpha(i,k) = 0.0 - endif - enddo - enddo - endif - -! --- compute low, mid, high, total, and boundary layer cloud fractions -! and clouds top/bottom layer indices for low, mid, and high clouds. -! The three cloud domain boundaries are defined by ptopc. The cloud -! overlapping method is defined by control flag 'iovr', which may -! be different for lw and sw radiation programs. - - call gethml & -! --- inputs: - & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & - & IX,NLAY, & -! --- outputs: - & clds, mtop, mbot & - & ) - - ! return !................................... - end subroutine progcld4 + end subroutine progcld_zhao_carr_pdf !! @} !----------------------------------- + !----------------------------------- !> \ingroup module_radiation_clouds -!! This subroutine computes cloud related quantities using GFDL Lin MP -!! prognostic cloud microphysics scheme. Moist species from MP are fed -!! into the corresponding arrays for calculation of cloud fractions. -!! -!>\param plyr (ix,nlay), model layer mean pressure in mb (100Pa) -!>\param plvl (ix,nlp1), model level pressure in mb (100Pa) -!>\param tlyr (ix,nlay), model layer mean temperature in K -!>\param tvly (ix,nlay), model layer virtual temperature in K -!>\param qlyr (ix,nlay), layer specific humidity in \f$gm gm^{-1}\f$ -!>\param qstl (ix,nlay), layer saturate humidity in \f$gm gm^{-1}\f$ -!>\param rhly (ix,nlay), layer relative humidity (=qlyr/qstl) -!>\param clw (ix,nlay,ntrac), layer cloud condensate amount -!>\param xlat (ix), grid latitude in radians, default to pi/2->-pi/2 -!! range, otherwise see in-line comment -!>\param xlon (ix), grid longitude in radians (not used) -!>\param slmsk (ix), sea/land mask array (sea:0, land:1, sea-ice:2) -!>\param dz layer thickness (km) -!>\param delp model layer pressure thickness in mb (100Pa) -!>\param ntrac number of tracers minus one (Model%ntrac-1) -!>\param ntcw tracer index for cloud liquid water minus one (Model%ntcw-1) -!>\param ntiw tracer index for cloud ice water minus one (Model%ntiw-1) -!>\param ntrw tracer index for rain water minus one (Model%ntrw-1) -!>\param ntsw tracer index for snow water minus one (Model%ntsw-1) -!>\param ntgl tracer index for graupel minus one (Model%ntgl-1) -!>\param ntclamt tracer index for cloud amount minus one (Model%ntclamt-1) -!>\param ix horizontal dimension -!>\param nlay vertical layer dimension -!>\param nlp1 vertical level dimension -!!\param dzlay(ix,nlay) distance between model layer centers -!!\param latdeg(ix) latitude (in degrees 90 -> -90) -!!\param julian day of the year (fractional julian day) -!!\param yearlen current length of the year (365/366 days) -!>\param clouds (ix,nlay,nf_clds), cloud profiles -!!\n clouds(:,:,1) - layer totoal cloud fraction -!!\n clouds(:,:,2) - layer cloud liquid water path (\f$g m^{-2}\f$) -!!\n clouds(:,:,3) - mean effective radius for liquid cloud (micron) -!!\n clouds(:,:,4) - layer cloud ice water path (\f$g m^{-2}\f$) -!!\n clouds(:,:,5) - mean effective radius for ice cloud (micron) -!!\n clouds(:,:,6) - layer rain dropwater path (\f$g m^{-2}\f$) -!!\n clouds(:,:,7) - mean effective radius for rain drop (micron) -!!\n clouds(:,:,8) - layer snow flake water path (\f$g m^{-2}\f$) -!!\n clouds(:,:,9) - mean effective radius for snow flake (micron) -!>\param clds (ix,5), fraction of clouds for low, mid, hi, tot, bl -!>\param mtop (ix,3), vertical indices for low, mid, hi cloud tops -!>\param mbot (ix,3), vertical indices for low, mid, hi cloud bases -!>\param de_lgth clouds decorrelation length (km) -!!\param alpha (IX,NLAY), alpha decorrelation parameter -!>\section gen_progcld4o progcld4o General Algorithm +!> This subroutine computes cloud related quantities using +!! GFDL Lin MP prognostic cloud microphysics scheme. +!>\section progcld_gfdl_lin General Algorithm !! @{ - subroutine progcld4o & - & ( plyr,plvl,tlyr,tvly,qlyr,qstl,rhly,clw, & ! --- inputs: - & xlat,xlon,slmsk, dz, delp, & - & ntrac,ntcw,ntiw,ntrw,ntsw,ntgl,ntclamt, & + subroutine progcld_gfdl_lin & + & ( plyr,plvl,tlyr,tvly,qlyr,qstl,rhly,clw,cnvw,cnvc, & ! --- inputs: + & xlat,xlon,slmsk,cldtot, dz, delp, & & IX, NLAY, NLP1, & - & dzlay, latdeg, julian, yearlen, & - & clouds,clds,mtop,mbot,de_lgth,alpha & ! --- outputs: + & dzlay, cldtot1, cldcnv, & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) ! ================= subprogram documentation block ================ ! ! ! -! subprogram: progcld4o computes cloud related quantities using ! -! GFDL Lin MP prognostic cloud microphysics scheme. Moist species ! -! from MP are fed into the corresponding arrays for calcuation of ! +! subprogram: progcld_gfdl_lin computes cloud related quantities using ! +! GFDL Lin MP prognostic cloud microphysics scheme. ! ! ! ! abstract: this program computes cloud fractions from cloud ! ! condensates, calculates liquid/ice cloud droplet effective radius, ! @@ -2212,7 +1577,7 @@ subroutine progcld4o & ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! ! ! -! usage: call progcld4o ! +! usage: call progcld_gfdl_lin ! ! ! ! subprograms called: gethml ! ! ! @@ -2231,7 +1596,9 @@ subroutine progcld4o & ! qlyr (IX,NLAY) : layer specific humidity in gm/gm ! ! qstl (IX,NLAY) : layer saturate humidity in gm/gm ! ! rhly (IX,NLAY) : layer relative humidity (=qlyr/qstl) ! -! clw (IX,NLAY,NTRAC) : layer cloud condensate amount ! +! clw (IX,NLAY) : layer cloud condensate amount ! +! cnvw (IX,NLAY) : layer convective cloud condensate ! +! cnvc (IX,NLAY) : layer convective cloud cover ! ! xlat (IX) : grid latitude in radians, default to pi/2 -> -pi/2! ! range, otherwise see in-line comment ! ! xlon (IX) : grid longitude in radians (not used) ! @@ -2241,27 +1608,18 @@ subroutine progcld4o & ! IX : horizontal dimention ! ! NLAY,NLP1 : vertical layer/level dimensions ! ! dzlay(ix,nlay) : thickness between model layer centers (km) ! -! latdeg(ix) : latitude (in degrees 90 -> -90) ! -! julian : day of the year (fractional julian day) ! -! yearlen : current length of the year (365/366 days) ! ! ! ! output variables: ! -! clouds(IX,NLAY,NF_CLDS) : cloud profiles ! -! clouds(:,:,1) - layer total cloud fraction ! -! clouds(:,:,2) - layer cloud liq water path (g/m**2) ! -! clouds(:,:,3) - mean eff radius for liq cloud (micron) ! -! clouds(:,:,4) - layer cloud ice water path (g/m**2) ! -! clouds(:,:,5) - mean eff radius for ice cloud (micron) ! -! clouds(:,:,6) - layer rain drop water path not assigned ! -! clouds(:,:,7) - mean eff radius for rain drop (micron) ! -! *** clouds(:,:,8) - layer snow flake water path not assigned ! -! clouds(:,:,9) - mean eff radius for snow flake (micron) ! -! *** fu's scheme need to be normalized by snow density (g/m**3/1.0e6) ! -! clds (IX,5) : fraction of clouds for low, mid, hi, tot, bl ! -! mtop (IX,3) : vertical indices for low, mid, hi cloud tops ! -! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! -! de_lgth(ix) : clouds decorrelation length (km) ! -! alpha(ix,nlay) : alpha decorrelation parameter +! cloud profiles: ! +! cld_frac (:,:) - layer total cloud fraction ! +! cld_lwp (:,:) - layer cloud liq water path (g/m**2) ! +! cld_reliq (:,:) - mean eff radius for liq cloud (micron) ! +! cld_iwp (:,:) - layer cloud ice water path (g/m**2) ! +! cld_reice (:,:) - mean eff radius for ice cloud (micron) ! +! cld_rwp (:,:) - layer rain drop water path not assigned ! +! cld_rerain(:,:) - mean eff radius for rain drop (micron) ! +! *** cld_swp (:,:) - layer snow flake water path not assigned ! +! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! ! ! module variables: ! ! ivflip : control flag of vertical index direction ! @@ -2281,55 +1639,35 @@ subroutine progcld4o & ! --- inputs integer, intent(in) :: IX, NLAY, NLP1 - integer, intent(in) :: ntrac, ntcw, ntiw, ntrw, ntsw, ntgl, & - & ntclamt real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & - & tlyr, tvly, qlyr, qstl, rhly, delp, dz, dzlay - + & tlyr, tvly, qlyr, qstl, rhly, clw, cldtot, cnvw, cnvc, & + & delp, dz, dzlay - real (kind=kind_phys), dimension(:,:,:), intent(in) :: clw real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & & slmsk - real(kind=kind_phys), dimension(:), intent(in) :: latdeg - real(kind=kind_phys), intent(in) :: julian - integer, intent(in) :: yearlen - -! --- outputs - real (kind=kind_phys), dimension(:,:,:), intent(out) :: clouds + real (kind=kind_phys), dimension(:,:), intent(inout) :: cldtot1 - real (kind=kind_phys), dimension(:,:), intent(out) :: clds - real (kind=kind_phys), dimension(:), intent(out) :: de_lgth - real (kind=kind_phys), dimension(:,:), intent(out) :: alpha +! --- inputs/outputs - integer, dimension(:,:), intent(out) :: mtop,mbot + real (kind=kind_phys), dimension(:,:), intent(inout) :: & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & + & cld_rwp, cld_rerain, cld_swp, cld_resnow ! --- local variables: real (kind=kind_phys), dimension(IX,NLAY) :: cldcnv, & - & cwp, cip, crp, csp, rew, rei, res, rer, tem2d - - real (kind=kind_phys) :: ptop1(IX,NK_CLDS+1), rxlat(ix) + & cwp, cip, crp, csp, rew, rei, res, rer, tem2d, clwf real (kind=kind_phys) :: clwmin, clwm, clwt, onemrh, value, & & tem1, tem2, tem3 - real (kind=kind_phys), dimension(IX,NLAY) :: cldtot integer :: i, k, id, nf ! !===> ... begin here ! - do nf=1,nf_clds - do k=1,nlay - do i=1,ix - clouds(i,k,nf) = 0.0 - enddo - enddo - enddo -! clouds(:,:,:) = 0.0 - -!> - Assign liquid/ice/rain/snow cloud droplet effective radius as default value. +!> - Assign liquid/ice/rain/snow cloud doplet effective radius as default value. do k = 1, NLAY do i = 1, IX cldcnv(i,k) = 0.0 @@ -2337,41 +1675,40 @@ subroutine progcld4o & cip (i,k) = 0.0 crp (i,k) = 0.0 csp (i,k) = 0.0 - rew (i,k) = reliq_def ! default liq radius to 10 micron - rei (i,k) = reice_def ! default ice radius to 50 micron - rer (i,k) = rrain_def ! default rain radius to 1000 micron - res (i,k) = rsnow_def ! default snow radius to 250 micron + rew (i,k) = reliq_def !< default liq radius to 10 micron + rei (i,k) = reice_def !< default ice radius to 50 micron + rer (i,k) = rrain_def !< default rain radius to 1000 micron + res (i,k) = rsnow_def !< default snow radius to 250 micron tem2d (i,k) = min( 1.0, max( 0.0, (con_ttp-tlyr(i,k))*0.05 ) ) - cldtot(i,k) = clw(i,k,ntclamt) + clwf(i,k) = 0.0 enddo enddo - -!> - Compute top pressure for each cloud domain for given latitude. -!! ptopc(k,i): top presure of each cld domain (k=1-4 are sfc,L,m,h; -!! i=1,2 are low-lat (<45 degree) and pole regions) - - do i =1, IX - rxlat(i) = abs( xlat(i) / con_pi ) ! if xlat in pi/2 -> -pi/2 range -! rxlat(i) = abs(0.5 - xlat(i)/con_pi) ! if xlat in 0 -> pi range - enddo - - do id = 1, 4 - tem1 = ptopc(id,2) - ptopc(id,1) - - do i =1, IX - ptop1(i,id) = ptopc(id,1) + tem1*max( 0.0, 4.0*rxlat(i)-1.0 ) +! + if ( lcrick ) then + do i = 1, IX + clwf(i,1) = 0.75*clw(i,1) + 0.25*clw(i,2) + clwf(i,nlay) = 0.75*clw(i,nlay) + 0.25*clw(i,nlay-1) enddo - enddo + do k = 2, NLAY-1 + do i = 1, IX + clwf(i,K) = 0.25*clw(i,k-1) + 0.5*clw(i,k) + 0.25*clw(i,k+1) + enddo + enddo + else + do k = 1, NLAY + do i = 1, IX + clwf(i,k) = clw(i,k) + enddo + enddo + endif -!> - Compute liquid/ice condensate path in \f$g m^{-2}\f$ +!> - Compute liquid/ice condensate path in \f$g m^{-2}\f$. do k = 1, NLAY do i = 1, IX - cwp(i,k) = max(0.0, clw(i,k,ntcw) * gfac * delp(i,k)) - cip(i,k) = max(0.0, clw(i,k,ntiw) * gfac * delp(i,k)) - crp(i,k) = max(0.0, clw(i,k,ntrw) * gfac * delp(i,k)) - csp(i,k) = max(0.0, (clw(i,k,ntsw)+clw(i,k,ntgl)) * & - & gfac * delp(i,k)) + clwt = max(0.0,(clwf(i,k)+cnvw(i,k))) * gfac * delp(i,k) + cip(i,k) = clwt * tem2d(i,k) + cwp(i,k) = clwt - cip(i,k) enddo enddo @@ -2411,7 +1748,7 @@ subroutine progcld4o & endif !> - Compute effective ice cloud droplet radius in Heymsfield and McFarquhar (1996) -!!\cite heymsfield_and_mcfarquhar_1996. +!! \cite heymsfield_and_mcfarquhar_1996 . do k = 1, NLAY do i = 1, IX @@ -2437,72 +1774,30 @@ subroutine progcld4o & enddo enddo -! do k = 1, NLAY do i = 1, IX - clouds(i,k,1) = cldtot(i,k) - clouds(i,k,2) = cwp(i,k) - clouds(i,k,3) = rew(i,k) - clouds(i,k,4) = cip(i,k) - clouds(i,k,5) = rei(i,k) - clouds(i,k,6) = crp(i,k) - clouds(i,k,7) = rer(i,k) - clouds(i,k,8) = csp(i,k) - clouds(i,k,9) = rei(i,k) + cldtot1(i,k) = cldtot(i,k) enddo enddo - ! Compute cloud decorrelation length - if (idcor == 1) then - call cmp_dcorr_lgth(ix, xlat, con_pi, de_lgth) - endif - if (idcor == 2) then - call cmp_dcorr_lgth(ix, latdeg, julian, yearlen, de_lgth) - endif - if (idcor == 0) then - de_lgth(:) = decorr_con - endif - - ! Call subroutine get_alpha_exp to define alpha parameter for exponential cloud overlap options - if (iovr == 3 .or. iovr == 4 .or. iovr == 5) then - call get_alpha_exp(ix, nLay, dzlay, de_lgth, alpha) - else - de_lgth(:) = 0. - alpha(:,:) = 0. - endif - - ! Revise alpha for exponential-random cloud overlap - ! Decorrelate layers when a clear layer follows a cloudy layer to enforce - ! random correlation between non-adjacent blocks of cloudy layers - if (iovr == 5) then - do k = 2, nLay - do i = 1, ix - if (clouds(i,k,1) == 0.0 .and. clouds(i,k-1,1) > 0.0) then - alpha(i,k) = 0.0 - endif - enddo +! + do k = 1, NLAY + do i = 1, IX + cld_frac(i,k) = cldtot(i,k) + cld_lwp(i,k) = cwp(i,k) + cld_reliq(i,k) = rew(i,k) + cld_iwp(i,k) = cip(i,k) + cld_reice(i,k) = rei(i,k) +! cld_rwp(i,k) = 0.0 + cld_rerain(i,k) = rer(i,k) +! cld_swp(i,k) = 0.0 + cld_resnow(i,k) = res(i,k) enddo - endif - -!> - Call gethml() to compute low, mid, high, total, and boundary layer cloud fractions -!! and clouds top/bottom layer indices for low, mid, and high clouds. -!! The three cloud domain boundaries are defined by ptopc. The cloud -!! overlapping method is defined by control flag 'iovr', which may -!! be different for lw and sw radiation programs. - - call gethml & -! --- inputs: - & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & - & IX,NLAY, & -! --- outputs: - & clds, mtop, mbot & - & ) - - + enddo ! return !................................... - end subroutine progcld4o + end subroutine progcld_gfdl_lin !! @} !----------------------------------- @@ -2510,20 +1805,21 @@ end subroutine progcld4o !> \ingroup module_radiation_clouds !! This subroutine computes cloud related quantities using !! Ferrier-Aligo cloud microphysics scheme. - subroutine progcld5 & + subroutine progcld_fer_hires & & ( plyr,plvl,tlyr,tvly,qlyr,qstl,rhly,clw, & ! --- inputs: & xlat,xlon,slmsk,dz,delp, & & ntrac,ntcw,ntiw,ntrw, & & IX, NLAY, NLP1, icloud, & & uni_cld, lmfshal, lmfdeep2, cldcov, & & re_cloud,re_ice,re_snow, & - & dzlay, latdeg, julian, yearlen, & - & clouds,clds,mtop,mbot,de_lgth,alpha & ! --- outputs: + & dzlay, cldtot, cldcnv, & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) ! ================= subprogram documentation block ================ ! ! ! -! subprogram: progcld5 computes cloud related quantities using ! +! subprogram: progcld_fer_hires computes cloud related quantities using ! ! Ferrier-Aligo cloud microphysics scheme. ! ! ! ! abstract: this program computes cloud fractions from cloud ! @@ -2533,7 +1829,7 @@ subroutine progcld5 & ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! ! ! -! usage: call progcld5 ! +! usage: call progcld_fer_hires ! ! ! ! subprograms called: gethml ! ! ! @@ -2567,27 +1863,18 @@ subroutine progcld5 & ! lmfdeep2 : logical - true for mass flux deep convection ! ! cldcov : layer cloud fraction (used when uni_cld=.true. ! ! dzlay(ix,nlay) : thickness between model layer centers (km) ! -! latdeg(ix) : latitude (in degrees 90 -> -90) ! -! julian : day of the year (fractional julian day) ! -! yearlen : current length of the year (365/366 days) ! ! ! ! output variables: ! -! clouds(IX,NLAY,NF_CLDS) : cloud profiles ! -! clouds(:,:,1) - layer total cloud fraction ! -! clouds(:,:,2) - layer cloud liq water path (g/m**2) ! -! clouds(:,:,3) - mean eff radius for liq cloud (micron) ! -! clouds(:,:,4) - layer cloud ice water path (g/m**2) ! -! clouds(:,:,5) - mean eff radius for ice cloud (micron) ! -! clouds(:,:,6) - layer rain drop water path not assigned ! -! clouds(:,:,7) - mean eff radius for rain drop (micron) ! -! *** clouds(:,:,8) - layer snow flake water path not assigned ! -! clouds(:,:,9) - mean eff radius for snow flake (micron) ! -! *** fu's scheme need to be normalized by snow density (g/m**3/1.0e6) ! -! clds (IX,5) : fraction of clouds for low, mid, hi, tot, bl ! -! mtop (IX,3) : vertical indices for low, mid, hi cloud tops ! -! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! -! de_lgth(ix) : clouds decorrelation length (km) ! -! alpha(ix,nlay) : alpha decorrelation parameter +! cloud profiles: ! +! cld_frac (:,:) - layer total cloud fraction ! +! cld_lwp (:,:) - layer cloud liq water path (g/m**2) ! +! cld_reliq (:,:) - mean eff radius for liq cloud (micron) ! +! cld_iwp (:,:) - layer cloud ice water path (g/m**2) ! +! cld_reice (:,:) - mean eff radius for ice cloud (micron) ! +! cld_rwp (:,:) - layer rain drop water path not assigned ! +! cld_rerain(:,:) - mean eff radius for rain drop (micron) ! +! *** cld_swp (:,:) - layer snow flake water path not assigned ! +! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! ! ! module variables: ! ! ivflip : control flag of vertical index direction ! @@ -2623,25 +1910,16 @@ subroutine progcld5 & real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & & slmsk - real(kind=kind_phys), dimension(:), intent(in) :: latdeg - real(kind=kind_phys), intent(in) :: julian - integer, intent(in) :: yearlen - -! --- outputs - real (kind=kind_phys), dimension(:,:,:), intent(out) :: clouds - - real (kind=kind_phys), dimension(:,:), intent(out) :: clds - real (kind=kind_phys), dimension(:), intent(out) :: de_lgth - real (kind=kind_phys), dimension(:,:), intent(out) :: alpha +! --- inputs/outputs - integer, dimension(:,:), intent(out) :: mtop,mbot + real (kind=kind_phys), dimension(:,:), intent(inout) :: & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & + & cld_rwp, cld_rerain, cld_swp, cld_resnow ! --- local variables: real (kind=kind_phys), dimension(IX,NLAY) :: cldtot, cldcnv, & & cwp, cip, crp, csp, rew, rei, res, rer, tem2d, clwf - real (kind=kind_phys) :: ptop1(IX,NK_CLDS+1), rxlat(ix) - real (kind=kind_phys) :: clwmin, clwm, clwt, onemrh, value, & & tem1, tem2, tem3 @@ -2654,15 +1932,6 @@ subroutine progcld5 & ! !===> ... begin here ! - do nf=1,nf_clds - do k=1,nlay - do i=1,ix - clouds(i,k,nf) = 0.0 - enddo - enddo - enddo -! clouds(:,:,:) = 0.0 - do k = 1, NLAY do i = 1, IX cldtot(i,k) = 0.0 @@ -2703,22 +1972,6 @@ subroutine progcld5 & clwf(i,k) = clw(i,k,ntcw) + clw(i,k,ntiw) enddo enddo -!> - Find top pressure for each cloud domain for given latitude. -!! ptopc(k,i): top presure of each cld domain (k=1-4 are sfc,L,m,h; -!! i=1,2 are low-lat (<45 degree) and pole regions) - - do i =1, IX - rxlat(i) = abs( xlat(i) / con_pi ) ! if xlat in pi/2 -> -pi/2 range -! rxlat(i) = abs(0.5 - xlat(i)/con_pi) ! if xlat in 0 -> pi range - enddo - - do id = 1, 4 - tem1 = ptopc(id,2) - ptopc(id,1) - - do i =1, IX - ptop1(i,id) = ptopc(id,1) + tem1*max( 0.0, 4.0*rxlat(i)-1.0 ) - enddo - enddo !> - Compute cloud liquid/ice condensate path in \f$ g/m^2 \f$ . @@ -2744,54 +1997,14 @@ subroutine progcld5 & !> - Calculate layer cloud fraction. - clwmin = 0.0 if (.not. lmfshal) then - do k = 1, NLAY - do i = 1, IX - clwt = 1.0e-6 * (plyr(i,k)*0.001) -! clwt = 2.0e-6 * (plyr(i,k)*0.001) - - if (clwf(i,k) > clwt) then - - onemrh= max( 1.e-10, 1.0-rhly(i,k) ) - clwm = clwmin / max( 0.01, plyr(i,k)*0.001 ) - - tem1 = min(max(sqrt(sqrt(onemrh*qstl(i,k))),0.0001),1.0) - tem1 = 2000.0 / tem1 - -! tem1 = 1000.0 / tem1 - - value = max( min( tem1*(clwf(i,k)-clwm), 50.0 ), 0.0 ) - tem2 = sqrt( sqrt(rhly(i,k)) ) - - cldtot(i,k) = max( tem2*(1.0-exp(-value)), 0.0 ) - endif - enddo - enddo + call cloud_fraction_XuRandall & + & ( IX, NLAY, plyr, clwf, rhly, qstl, & ! --- inputs + & cldtot ) & ! --- outputs else - do k = 1, NLAY - do i = 1, IX - clwt = 1.0e-6 * (plyr(i,k)*0.001) -! clwt = 2.0e-6 * (plyr(i,k)*0.001) - - if (clwf(i,k) > clwt) then - onemrh= max( 1.e-10, 1.0-rhly(i,k) ) - clwm = clwmin / max( 0.01, plyr(i,k)*0.001 ) -! - tem1 = min(max((onemrh*qstl(i,k))**0.49,0.0001),1.0) !jhan - if (lmfdeep2) then - tem1 = xrc3 / tem1 - else - tem1 = 100.0 / tem1 - endif -! - value = max( min( tem1*(clwf(i,k)-clwm), 50.0 ), 0.0 ) - tem2 = sqrt( sqrt(rhly(i,k)) ) - - cldtot(i,k) = max( tem2*(1.0-exp(-value)), 0.0 ) - endif - enddo - enddo + call cloud_fraction_mass_flx_1 & + & ( IX, NLAY, lmfdeep2, xrc3, plyr, clwf, rhly, qstl, & ! --- inputs + & cldtot ) endif endif ! if (uni_cld) then @@ -2821,86 +2034,32 @@ subroutine progcld5 & enddo enddo endif +! do k = 1, NLAY do i = 1, IX - clouds(i,k,1) = cldtot(i,k) - clouds(i,k,2) = cwp(i,k) - clouds(i,k,3) = rew(i,k) - clouds(i,k,4) = cip(i,k) - clouds(i,k,5) = rei(i,k) - clouds(i,k,6) = crp(i,k) - clouds(i,k,7) = rer(i,k) - !mz inflg .ne.5 - clouds(i,k,8) = 0. - clouds(i,k,9) = 10. -!mz for diagnostics? + cld_frac(i,k) = cldtot(i,k) + cld_lwp(i,k) = cwp(i,k) + cld_reliq(i,k) = rew(i,k) + cld_iwp(i,k) = cip(i,k) + cld_reice(i,k) = rei(i,k) + cld_rwp(i,k) = crp(i,k) + cld_rerain(i,k) = rer(i,k) + cld_swp(i,k) = 0.0 + cld_resnow(i,k) = 10.0 re_cloud(i,k) = rew(i,k) re_ice(i,k) = rei(i,k) re_snow(i,k) = 10. - enddo enddo - - ! Compute cloud decorrelation length - if (idcor == 1) then - call cmp_dcorr_lgth(ix, xlat, con_pi, de_lgth) - endif - if (idcor == 2) then - call cmp_dcorr_lgth(ix, latdeg, julian, yearlen, de_lgth) - endif - if (idcor == 0) then - de_lgth(:) = decorr_con - endif - - ! Call subroutine get_alpha_exp to define alpha parameter for exponential cloud overlap options - if (iovr == 3 .or. iovr == 4 .or. iovr == 5) then - call get_alpha_exp(ix, nLay, dzlay, de_lgth, alpha) - else - de_lgth(:) = 0. - alpha(:,:) = 0. - endif - - ! Revise alpha for exponential-random cloud overlap - ! Decorrelate layers when a clear layer follows a cloudy layer to enforce - ! random correlation between non-adjacent blocks of cloudy layers - if (iovr == 5) then - do k = 2, nLay - do i = 1, ix - if (clouds(i,k,1) == 0.0 .and. clouds(i,k-1,1) > 0.0) then - alpha(i,k) = 0.0 - endif - enddo - enddo - endif - -!> - Call gethml() to compute low,mid,high,total, and boundary layer -!! cloud fractions and clouds top/bottom layer indices for low, mid, -!! and high clouds. -! --- compute low, mid, high, total, and boundary layer cloud fractions -! and clouds top/bottom layer indices for low, mid, and high clouds. -! The three cloud domain boundaries are defined by ptopc. The cloud -! overlapping method is defined by control flag 'iovr', which may -! be different for lw and sw radiation programs. - - call gethml & -! --- inputs: - & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & - & IX,NLAY, & -! --- outputs: - & clds, mtop, mbot & - & ) - - ! return !................................... - end subroutine progcld5 + end subroutine progcld_fer_hires !................................... -!mz: this is the original progcld5 for Thompson MP (and WSM6), -! to be replaced by the GSL version of progcld6 for Thompson MP and NSSL - subroutine progcld6 & +! This subroutine is used by Thompson/WSM6/NSSL cloud microphysics (EMC) + subroutine progcld_thompson_wsm6 & & ( plyr,plvl,tlyr,qlyr,qstl,rhly,clw, & ! --- inputs: & xlat,xlon,slmsk,dz,delp, & & ntrac,ntcw,ntiw,ntrw,ntsw,ntgl, & @@ -2908,14 +2067,16 @@ subroutine progcld6 & & uni_cld, lmfshal, lmfdeep2, cldcov, cnvw, & & re_cloud,re_ice,re_snow, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - & dzlay, latdeg, julian, yearlen, & - & clouds,clds,mtop,mbot,de_lgth,alpha & ! --- outputs: + & dzlay, cldtot, cldcnv, & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) ! ================= subprogram documentation block ================ ! ! ! -! subprogram: progcld6 computes cloud related quantities using ! -! Thompson/WSM6/NSSL cloud microphysics scheme. ! +! subprogram: progcld_thompson_wsm6 ! +! computes cloud related quantities using ! +! Thompson/WSM6/NSSL cloud microphysics scheme. ! ! ! ! abstract: this program computes cloud fractions from cloud ! ! condensates, ! @@ -2924,7 +2085,7 @@ subroutine progcld6 & ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! ! ! -! usage: call progcld6 ! +! usage: call progcld_thompson_wsm6 ! ! ! ! subprograms called: gethml ! ! ! @@ -2959,16 +2120,16 @@ subroutine progcld6 & ! cldcov : layer cloud fraction (used when uni_cld=.true. ! ! ! ! output variables: ! -! clouds(IX,NLAY,NF_CLDS) : cloud profiles ! -! clouds(:,:,1) - layer total cloud fraction ! -! clouds(:,:,2) - layer cloud liq water path (g/m**2) ! -! clouds(:,:,3) - mean eff radius for liq cloud (micron) ! -! clouds(:,:,4) - layer cloud ice water path (g/m**2) ! -! clouds(:,:,5) - mean eff radius for ice cloud (micron) ! -! clouds(:,:,6) - layer rain drop water path not assigned ! -! clouds(:,:,7) - mean eff radius for rain drop (micron) ! -! *** clouds(:,:,8) - layer snow flake water path not assigned ! -! clouds(:,:,9) - mean eff radius for snow flake (micron) ! +! cloud profiles: ! +! cld_frac (:,:) - layer total cloud fraction ! +! cld_lwp (:,:) - layer cloud liq water path (g/m**2) ! +! cld_reliq (:,:) - mean eff radius for liq cloud (micron) ! +! cld_iwp (:,:) - layer cloud ice water path (g/m**2) ! +! cld_reice (:,:) - mean eff radius for ice cloud (micron) ! +! cld_rwp (:,:) - layer rain drop water path not assigned ! +! cld_rerain(:,:) - mean eff radius for rain drop (micron) ! +! *** cld_swp (:,:) - layer snow flake water path not assigned ! +! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! *** fu's scheme need to be normalized by snow density (g/m**3/1.0e6) ! ! clds (IX,5) : fraction of clouds for low, mid, hi, tot, bl ! ! mtop (IX,3) : vertical indices for low, mid, hi cloud tops ! @@ -3009,25 +2170,16 @@ subroutine progcld6 & real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & & slmsk - real(kind=kind_phys), dimension(:), intent(in) :: latdeg - real(kind=kind_phys), intent(in) :: julian - integer, intent(in) :: yearlen - -! --- outputs - real (kind=kind_phys), dimension(:,:,:), intent(out) :: clouds - - real (kind=kind_phys), dimension(:,:), intent(out) :: clds - real (kind=kind_phys), dimension(:), intent(out) :: de_lgth - real (kind=kind_phys), dimension(:,:), intent(out) :: alpha +! --- inputs/outputs - integer, dimension(:,:), intent(out) :: mtop,mbot + real (kind=kind_phys), dimension(:,:), intent(inout) :: & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & + & cld_rwp, cld_rerain, cld_swp, cld_resnow ! --- local variables: real (kind=kind_phys), dimension(IX,NLAY) :: cldtot, cldcnv, & & cwp, cip, crp, csp, rew, rei, res, rer, tem2d, clwf - real (kind=kind_phys) :: ptop1(IX,NK_CLDS+1), rxlat(ix) - real (kind=kind_phys) :: clwmin, clwm, clwt, onemrh, value, & & tem1, tem2, tem3 @@ -3039,15 +2191,6 @@ subroutine progcld6 & ! !===> ... begin here - do nf=1,nf_clds - do k=1,nlay - do i=1,ix - clouds(i,k,nf) = 0.0 - enddo - enddo - enddo -! clouds(:,:,:) = 0.0 - do k = 1, NLAY do i = 1, IX cldtot(i,k) = 0.0 @@ -3090,22 +2233,6 @@ subroutine progcld6 & & + clw(i,k,ntrw) + cnvw(i,k) enddo enddo -!> - Find top pressure for each cloud domain for given latitude. -!! ptopc(k,i): top presure of each cld domain (k=1-4 are sfc,L,m,h; -!! i=1,2 are low-lat (<45 degree) and pole regions) - - do i =1, IX - rxlat(i) = abs( xlat(i) / con_pi ) ! if xlat in pi/2 -> -pi/2 range -! rxlat(i) = abs(0.5 - xlat(i)/con_pi) ! if xlat in 0 -> pi range - enddo - - do id = 1, 4 - tem1 = ptopc(id,2) - ptopc(id,1) - - do i =1, IX - ptop1(i,id) = ptopc(id,1) + tem1*max( 0.0, 4.0*rxlat(i)-1.0 ) - enddo - enddo !> - Compute cloud liquid/ice condensate path in \f$ g/m^2 \f$ . @@ -3144,57 +2271,16 @@ subroutine progcld6 & !> - Calculate layer cloud fraction. - clwmin = 0.0 if (.not. lmfshal) then - do k = 1, NLAY - do i = 1, IX - clwt = 1.0e-6 * (plyr(i,k)*0.001) - - if (clwf(i,k) > clwt) then - - onemrh= max( 1.e-10, 1.0-rhly(i,k) ) - clwm = clwmin / max( 0.01, plyr(i,k)*0.001 ) - - tem1 = min(max(sqrt(sqrt(onemrh*qstl(i,k))),0.0001),1.0) - tem1 = 2000.0 / tem1 - - value = max( min( tem1*(clwf(i,k)-clwm), 50.0 ), 0.0 ) - tem2 = sqrt( sqrt(rhly(i,k)) ) - - cldtot(i,k) = max( tem2*(1.0-exp(-value)), 0.0 ) - endif - enddo - enddo + call cloud_fraction_XuRandall & + & ( IX, NLAY, plyr, clwf, rhly, qstl, & ! --- inputs + & cldtot ) & ! --- outputs else - do k = 1, NLAY-1 - do i = 1, IX - clwt = 1.0e-10 * (plyr(i,k)*0.001) - - if (clwf(i,k) > clwt) then - if(rhly(i,k) > 0.99) then - cldtot(i,k) = 1. - else - onemrh= max( 1.e-10, 1.0-rhly(i,k) ) - clwm = clwmin / max( 0.01, plyr(i,k)*0.001 ) - - tem1 = min(max((onemrh*qstl(i,k))**0.49,0.0001),1.0) !jhan - if (lmfdeep2) then - tem1 = xrc3 / tem1 - else - tem1 = 100.0 / tem1 - endif - - value = max( min( tem1*(clwf(i,k)-clwm), 50.0 ), 0.0 ) - tem2 = sqrt( sqrt(rhly(i,k)) ) - - cldtot(i,k) = max( tem2*(1.0-exp(-value)), 0.0 ) - endif - else - cldtot(i,k) = 0.0 - endif - enddo - enddo - endif + call cloud_fraction_mass_flx_2 & + & ( IX, NLAY, lmfdeep2, xrc3, plyr, clwf, rhly, qstl, & ! --- inputs + & cldtot ) + endif + endif ! if (uni_cld) then do k = 1, NLAY @@ -3238,71 +2324,22 @@ subroutine progcld6 & do k = 1, NLAY do i = 1, IX - clouds(i,k,1) = cldtot(i,k) - clouds(i,k,2) = cwp(i,k) - clouds(i,k,3) = rew(i,k) - clouds(i,k,4) = cip(i,k) - clouds(i,k,5) = rei(i,k) - clouds(i,k,6) = crp(i,k) ! added for Thompson - clouds(i,k,7) = rer(i,k) - clouds(i,k,8) = csp(i,k) ! added for Thompson - clouds(i,k,9) = res(i,k) + cld_frac(i,k) = cldtot(i,k) + cld_lwp(i,k) = cwp(i,k) + cld_reliq(i,k) = rew(i,k) + cld_iwp(i,k) = cip(i,k) + cld_reice(i,k) = rei(i,k) + cld_rwp(i,k) = crp(i,k) ! added for Thompson + cld_rerain(i,k) = rer(i,k) + cld_swp(i,k) = csp(i,k) ! added for Thompson + cld_resnow(i,k) = res(i,k) enddo enddo - ! Compute cloud decorrelation length - if (idcor == 1) then - call cmp_dcorr_lgth(ix, xlat, con_pi, de_lgth) - endif - if (idcor == 2) then - call cmp_dcorr_lgth(ix, latdeg, julian, yearlen, de_lgth) - endif - if (idcor == 0) then - de_lgth(:) = decorr_con - endif - - ! Call subroutine get_alpha_exp to define alpha parameter for exponential cloud overlap options - if ( iovr == 3 .or. iovr == 4 .or. iovr == 5) then - call get_alpha_exp(ix, nLay, dzlay, de_lgth, alpha) - else - de_lgth(:) = 0. - alpha(:,:) = 0. - endif - - ! Revise alpha for exponential-random cloud overlap - ! Decorrelate layers when a clear layer follows a cloudy layer to enforce - ! random correlation between non-adjacent blocks of cloudy layers - if (iovr == 5) then - do k = 2, nLay - do i = 1, ix - if (clouds(i,k,1) == 0.0 .and. clouds(i,k-1,1) > 0.0) then - alpha(i,k) = 0.0 - endif - enddo - enddo - endif - -!> - Call gethml() to compute low,mid,high,total, and boundary layer -!! cloud fractions and clouds top/bottom layer indices for low, mid, -!! and high clouds. -! --- compute low, mid, high, total, and boundary layer cloud fractions -! and clouds top/bottom layer indices for low, mid, and high clouds. -! The three cloud domain boundaries are defined by ptopc. The cloud -! overlapping method is defined by control flag 'iovr', which may -! be different for lw and sw radiation programs. - - call gethml & -! --- inputs: - & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & - & IX,NLAY, & -! --- outputs: - & clds, mtop, mbot & - & ) - return !............................................ - end subroutine progcld6 + end subroutine progcld_thompson_wsm6 !............................................ !mz @@ -3325,8 +2362,9 @@ subroutine progcld_thompson & & uni_cld, lmfshal, lmfdeep2, cldcov, & & re_cloud,re_ice,re_snow, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - & dzlay, latdeg, julian, yearlen, gridkm, & - & clouds,clds,mtop,mbot,de_lgth,alpha & ! --- outputs: + & dzlay, gridkm, cldtot, cldcnv, & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) ! ================= subprogram documentation block ================ ! @@ -3377,21 +2415,16 @@ subroutine progcld_thompson & ! cldcov : layer cloud fraction (used when uni_cld=.true. ! ! ! ! output variables: ! -! clouds(IX,NLAY,NF_CLDS) : cloud profiles ! -! clouds(:,:,1) - layer total cloud fraction ! -! clouds(:,:,2) - layer cloud liq water path (g/m**2) ! -! clouds(:,:,3) - mean eff radius for liq cloud (micron) ! -! clouds(:,:,4) - layer cloud ice water path (g/m**2) ! -! clouds(:,:,5) - mean eff radius for ice cloud (micron) ! -! clouds(:,:,6) - layer rain drop water path not assigned ! -! clouds(:,:,7) - mean eff radius for rain drop (micron) ! -! clouds(:,:,8) - layer snow flake water path not assigned ! -! clouds(:,:,9) - mean eff radius for snow flake (micron) ! -! *** fu's scheme need to be normalized by snow density (g/m**3/1.0e6) ! -! clds (IX,5) : fraction of clouds for low, mid, hi, tot, bl ! -! mtop (IX,3) : vertical indices for low, mid, hi cloud tops ! -! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! -! de_lgth(ix) : clouds decorrelation length (km) ! +! cloud profiles: ! +! cld_frac (:,:) - layer total cloud fraction ! +! cld_lwp (:,:) - layer cloud liq water path (g/m**2) ! +! cld_reliq (:,:) - mean eff radius for liq cloud (micron) ! +! cld_iwp (:,:) - layer cloud ice water path (g/m**2) ! +! cld_reice (:,:) - mean eff radius for ice cloud (micron) ! +! cld_rwp (:,:) - layer rain drop water path not assigned ! +! cld_rerain(:,:) - mean eff radius for rain drop (micron) ! +! *** cld_swp (:,:) - layer snow flake water path not assigned ! +! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! ! ! module variables: ! ! ivflip : control flag of vertical index direction ! @@ -3426,19 +2459,13 @@ subroutine progcld_thompson & real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & & slmsk + real(kind=kind_phys), dimension(:), intent(in) :: gridkm - real(kind=kind_phys), dimension(:), intent(in) :: latdeg, gridkm - real(kind=kind_phys), intent(in) :: julian - integer, intent(in) :: yearlen - -! --- outputs - real (kind=kind_phys), dimension(:,:,:), intent(out) :: clouds - - real (kind=kind_phys), dimension(:,:), intent(out) :: clds - real (kind=kind_phys), dimension(:), intent(out) :: de_lgth - real (kind=kind_phys), dimension(:,:), intent(out) :: alpha +! --- inputs/outputs - integer, dimension(:,:), intent(out) :: mtop,mbot + real (kind=kind_phys), dimension(:,:), intent(inout) :: & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & + & cld_rwp, cld_rerain, cld_swp, cld_resnow ! --- local variables: real (kind=kind_phys), dimension(IX,NLAY) :: cldtot, cldcnv, & @@ -3447,8 +2474,6 @@ subroutine progcld_thompson & real (kind=kind_phys), dimension(NLAY) :: cldfra1d, qv1d, & & qc1d, qi1d, qs1d, dz1d, p1d, t1d - real (kind=kind_phys) :: ptop1(IX,NK_CLDS+1), rxlat(ix) - real (kind=kind_phys) :: clwmin, tem1 real (kind=kind_phys) :: corr, xland, snow_mass_factor real (kind=kind_phys), parameter :: max_relh = 1.5 @@ -3461,14 +2486,6 @@ subroutine progcld_thompson & clwmin = 1.0E-9 - do nf=1,nf_clds - do k=1,nlay - do i=1,ix - clouds(i,k,nf) = 0.0 - enddo - enddo - enddo - do k = 1, NLAY do i = 1, IX cldtot(i,k) = 0.0 @@ -3484,23 +2501,6 @@ subroutine progcld_thompson & enddo enddo -!> - Find top pressure for each cloud domain for given latitude. -!! ptopc(k,i): top presure of each cld domain (k=1-4 are sfc,L,m,h; -!! i=1,2 are low-lat (<45 degree) and pole regions) - - do i =1, IX - rxlat(i) = abs( xlat(i) / con_pi ) ! if xlat in pi/2 -> -pi/2 range -! rxlat(i) = abs(0.5 - xlat(i)/con_pi) ! if xlat in 0 -> pi range - enddo - - do id = 1, 4 - tem1 = ptopc(id,2) - ptopc(id,1) - - do i =1, IX - ptop1(i,id) = ptopc(id,1) + tem1*max( 0.0, 4.0*rxlat(i)-1.0 ) - enddo - enddo - !> - Compute cloud liquid/ice condensate path in \f$ g/m^2 \f$ . !> - Since using Thompson MP, assume 1 percent of snow is actually in !! ice sizes. @@ -3601,15 +2601,15 @@ subroutine progcld_thompson & do k = 1, NLAY do i = 1, IX - clouds(i,k,1) = cldtot(i,k) - clouds(i,k,2) = cwp(i,k) - clouds(i,k,3) = rew(i,k) - clouds(i,k,4) = cip(i,k) - clouds(i,k,5) = rei(i,k) - clouds(i,k,6) = crp(i,k) - clouds(i,k,7) = rer(i,k) - clouds(i,k,8) = csp(i,k) - clouds(i,k,9) = res(i,k) + cld_frac(i,k) = cldtot(i,k) + cld_lwp(i,k) = cwp(i,k) + cld_reliq(i,k) = rew(i,k) + cld_iwp(i,k) = cip(i,k) + cld_reice(i,k) = rei(i,k) + cld_rwp(i,k) = crp(i,k) ! added for Thompson + cld_rerain(i,k) = rer(i,k) + cld_swp(i,k) = csp(i,k) ! added for Thompson + cld_resnow(i,k) = res(i,k) enddo enddo @@ -3629,56 +2629,6 @@ subroutine progcld_thompson & lwp_ex(i) = lwp_ex(i)*1.E-3 iwp_ex(i) = iwp_ex(i)*1.E-3 enddo - - ! Compute cloud decorrelation length - if (idcor == 1) then - call cmp_dcorr_lgth(ix, xlat, con_pi, de_lgth) - endif - if (idcor == 2) then - call cmp_dcorr_lgth(ix, latdeg, julian, yearlen, de_lgth) - endif - if (idcor == 0) then - de_lgth(:) = decorr_con - endif - - ! Call subroutine get_alpha_exp to define alpha parameter for exponential cloud overlap options - if ( iovr == 3 .or. iovr == 4 .or. iovr == 5) then - call get_alpha_exp(ix, nLay, dzlay, de_lgth, alpha) - else - de_lgth(:) = 0. - alpha(:,:) = 0. - endif - - ! Revise alpha for exponential-random cloud overlap - ! Decorrelate layers when a clear layer follows a cloudy layer to enforce - ! random correlation between non-adjacent blocks of cloudy layers - if (iovr == 5) then - do k = 2, nLay - do i = 1, ix - if (clouds(i,k,1) == 0.0 .and. clouds(i,k-1,1) > 0.0) then - alpha(i,k) = 0.0 - endif - enddo - enddo - endif - -!> - Call gethml() to compute low,mid,high,total, and boundary layer -!! cloud fractions and clouds top/bottom layer indices for low, mid, -!! and high clouds. -! --- compute low, mid, high, total, and boundary layer cloud fractions -! and clouds top/bottom layer indices for low, mid, and high clouds. -! The three cloud domain boundaries are defined by ptopc. The cloud -! overlapping method is defined by control flag 'iovr', which may -! be different for lw and sw radiation programs. - - call gethml & -! --- inputs: - & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & - & IX,NLAY, & -! --- outputs: - & clds, mtop, mbot & - & ) - ! return @@ -3691,58 +2641,20 @@ end subroutine progcld_thompson !> \ingroup module_radiation_clouds !> This subroutine computes cloud related quantities using !! for unified cloud microphysics scheme. -!!\param plyr (IX,NLAY), model layer mean pressure in mb (100Pa) -!!\param plvl (IX,NLP1), model level pressure in mb (100Pa) -!!\param tlyr (IX,NLAY), model layer mean temperature in K -!!\param tvly (IX,NLAY), model layer virtual temperature in K -!!\param ccnd (IX,NLAY), layer cloud condensate amount -!!\param ncnd number of layer cloud condensate types -!!\param xlat (IX), grid latitude in radians, default to pi/2 -> -!! -pi/2 range, otherwise see in-line comment -!!\param xlon (IX), grid longitude in radians (not used) -!!\param slmsk (IX), sea/land mask array (sea:0,land:1,sea-ice:2) -!!\param dz (IX,NLAY), layer thickness (km) -!!\param delp (IX,NLAY), model layer pressure thickness in mb (100Pa) -!!\param IX horizontal dimention -!!\param NLAY,NLP1 vertical layer/level dimensions -!!\param cldtot unified cloud fraction from moist physics -!!\param effrl (IX,NLAY), effective radius for liquid water -!!\param effri (IX,NLAY), effective radius for ice water -!!\param effrr (IX,NLAY), effective radius for rain water -!!\param effrs (IX,NLAY), effective radius for snow water -!!\param effr_in logical - if .true. use input effective radii -!!\param dzlay(ix,nlay) distance between model layer centers -!!\param latdeg(ix) latitude (in degrees 90 -> -90) -!!\param julian day of the year (fractional julian day) -!!\param yearlen current length of the year (365/366 days) -!!\param clouds (IX,NLAY,NF_CLDS), cloud profiles -!!\n (:,:,1) - layer total cloud fraction -!!\n (:,:,2) - layer cloud liq water path \f$(g/m^2)\f$ -!!\n (:,:,3) - mean eff radius for liq cloud (micron) -!!\n (:,:,4) - layer cloud ice water path \f$(g/m^2)\f$ -!!\n (:,:,5) - mean eff radius for ice cloud (micron) -!!\n (:,:,6) - layer rain drop water path -!!\n (:,:,7) - mean eff radius for rain drop (micron) -!!\n (:,:,8) - layer snow flake water path -!!\n (:,:,9) - mean eff radius for snow flake (micron) -!!\param clds (IX,5), fraction of clouds for low, mid, hi, tot, bl -!!\param mtop (IX,3), vertical indices for low, mid, hi cloud tops -!!\param mbot (IX,3), vertical indices for low, mid, hi cloud bases -!!\param de_lgth (IX), clouds decorrelation length (km) -!!\param alpha (IX,NLAY), alpha decorrelation parameter -!>\section gen_progclduni progclduni General Algorithm +!>\section progclduni General Algorithm !> @{ subroutine progclduni & & ( plyr,plvl,tlyr,tvly,ccnd,ncnd, & ! --- inputs: & xlat,xlon,slmsk,dz,delp, IX, NLAY, NLP1, cldtot, & & effrl,effri,effrr,effrs,effr_in, & - & dzlay, latdeg, julian, yearlen, & - & clouds,clds,mtop,mbot,de_lgth,alpha & ! --- outputs: + & dzlay, cldtot1, cldcnv, & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) ! ================= subprogram documentation block ================ ! ! ! -! subprogram: progclduni computes cloud related quantities using ! +! subprogram: progclduni computes cloud related quantities using ! ! for unified cloud microphysics scheme. ! ! ! ! abstract: this program computes cloud fractions from cloud ! @@ -3751,8 +2663,11 @@ subroutine progclduni & ! fractions and the vertical indices of low, mid, and high cloud ! ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! +! This program is written by Moorthi ! +! to represent unified cloud across all physics while ! +! using SHOC+MG2/3+convection (RAS or SAS or CSAW) ! ! ! -! usage: call progclduni ! +! usage: call progclduni ! ! ! ! subprograms called: gethml ! ! ! @@ -3786,21 +2701,18 @@ subroutine progclduni & ! dz (ix,nlay) : layer thickness (km) ! ! delp (ix,nlay) : model layer pressure thickness in mb (100Pa) ! ! dzlay(ix,nlay) : thickness between model layer centers (km) ! -! latdeg(ix) : latitude (in degrees 90 -> -90) ! -! julian : day of the year (fractional julian day) ! -! yearlen : current length of the year (365/366 days) ! ! ! ! output variables: ! -! clouds(IX,NLAY,NF_CLDS) : cloud profiles ! -! clouds(:,:,1) - layer total cloud fraction ! -! clouds(:,:,2) - layer cloud liq water path (g/m**2) ! -! clouds(:,:,3) - mean eff radius for liq cloud (micron) ! -! clouds(:,:,4) - layer cloud ice water path (g/m**2) ! -! clouds(:,:,5) - mean eff radius for ice cloud (micron) ! -! clouds(:,:,6) - layer rain drop water path not assigned ! -! clouds(:,:,7) - mean eff radius for rain drop (micron) ! -! *** clouds(:,:,8) - layer snow flake water path not assigned ! -! clouds(:,:,9) - mean eff radius for snow flake (micron) ! +! cloud profiles: ! +! cld_frac (:,:) - layer total cloud fraction ! +! cld_lwp (:,:) - layer cloud liq water path (g/m**2) ! +! cld_reliq (:,:) - mean eff radius for liq cloud (micron) ! +! cld_iwp (:,:) - layer cloud ice water path (g/m**2) ! +! cld_reice (:,:) - mean eff radius for ice cloud (micron) ! +! cld_rwp (:,:) - layer rain drop water path not assigned ! +! cld_rerain(:,:) - mean eff radius for rain drop (micron) ! +! *** cld_swp (:,:) - layer snow flake water path not assigned ! +! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! *** fu's scheme need to be normalized by snow density (g/m**3/1.0e6) ! ! clds (IX,5) : fraction of clouds for low, mid, hi, tot, bl ! ! mtop (IX,3) : vertical indices for low, mid, hi cloud tops ! @@ -3837,42 +2749,25 @@ subroutine progclduni & real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & & slmsk - real(kind=kind_phys), dimension(:), intent(in) :: latdeg - real(kind=kind_phys), intent(in) :: julian - integer, intent(in) :: yearlen - -! --- outputs - real (kind=kind_phys), dimension(:,:,:), intent(out) :: clouds - - real (kind=kind_phys), dimension(:,:), intent(out) :: clds - - real (kind=kind_phys), dimension(:), intent(out) :: de_lgth + real (kind=kind_phys), dimension(:,:), intent(inout) :: cldtot1 - real (kind=kind_phys), dimension(:,:), intent(out) :: alpha +! --- inputs/outputs - integer, dimension(:,:), intent(out) :: mtop,mbot + real (kind=kind_phys), dimension(:,:), intent(inout) :: & + & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & + & cld_rwp, cld_rerain, cld_swp, cld_resnow ! --- local variables: real (kind=kind_phys), dimension(IX,NLAY) :: cldcnv, cwp, cip, & & crp, csp, rew, rei, res, rer real (kind=kind_phys), dimension(IX,NLAY,ncnd) :: cndf - real (kind=kind_phys) :: ptop1(IX,NK_CLDS+1), rxlat(ix) - real (kind=kind_phys) :: tem1, tem2, tem3 integer :: i, k, id, nf, n ! !===> ... begin here -! -! do nf=1,nf_clds -! do k=1,nlay -! do i=1,ix -! clouds(i,k,nf) = 0.0 -! enddo -! enddo -! enddo ! do k = 1, NLAY do i = 1, IX @@ -4009,87 +2904,26 @@ subroutine progclduni & enddo enddo endif -! + do k = 1, NLAY do i = 1, IX - clouds(i,k,1) = cldtot(i,k) - clouds(i,k,2) = cwp(i,k) - clouds(i,k,3) = rew(i,k) - clouds(i,k,4) = cip(i,k) - clouds(i,k,5) = rei(i,k) - clouds(i,k,6) = crp(i,k) - clouds(i,k,7) = rer(i,k) - clouds(i,k,8) = csp(i,k) - clouds(i,k,9) = res(i,k) + cldtot1(i,k) = cldtot(i,k) enddo enddo - -!> -# Find top pressure for each cloud domain for given latitude. -! ptopc(k,i): top presure of each cld domain (k=1-4 are sfc,L,m,h; -! --- i=1,2 are low-lat (<45 degree) and pole regions) - - do i =1, IX - rxlat(i) = abs( xlat(i) / con_pi ) ! if xlat in pi/2 -> -pi/2 range -! rxlat(i) = abs(0.5 - xlat(i)/con_pi) ! if xlat in 0 -> pi range - enddo - - do id = 1, 4 - tem1 = ptopc(id,2) - ptopc(id,1) - do i =1, IX - ptop1(i,id) = ptopc(id,1) + tem1*max( 0.0, 4.0*rxlat(i)-1.0 ) +! + do k = 1, NLAY + do i = 1, IX + cld_frac(i,k) = cldtot(i,k) + cld_lwp(i,k) = cwp(i,k) + cld_reliq(i,k) = rew(i,k) + cld_iwp(i,k) = cip(i,k) + cld_reice(i,k) = rei(i,k) + cld_rwp(i,k) = crp(i,k) ! added for Thompson + cld_rerain(i,k) = rer(i,k) + cld_swp(i,k) = csp(i,k) ! added for Thompson + cld_resnow(i,k) = res(i,k) enddo enddo - - ! Compute cloud decorrelation length - if (idcor == 1) then - call cmp_dcorr_lgth(ix, xlat, con_pi, de_lgth) - endif - if (idcor == 2) then - call cmp_dcorr_lgth(ix, latdeg, julian, yearlen, de_lgth) - endif - if (idcor == 0) then - de_lgth(:) = decorr_con - endif - - ! Call subroutine get_alpha_exp to define alpha parameter for exponential cloud overlap options - if (iovr == 3 .or. iovr == 4 .or. iovr == 5) then - call get_alpha_exp(ix, nLay, dzlay, de_lgth, alpha) - else - de_lgth(:) = 0. - alpha(:,:) = 0. - endif - - ! Revise alpha for exponential-random cloud overlap - ! Decorrelate layers when a clear layer follows a cloudy layer to enforce - ! random correlation between non-adjacent blocks of cloudy layers - if (iovr == 5) then - do k = 2, nLay - do i = 1, ix - if (clouds(i,k,1) == 0.0 .and. clouds(i,k-1,1) > 0.0) then - alpha(i,k) = 0.0 - endif - enddo - enddo - endif - -!> - Call gethml() to compute low,mid,high,total, and boundary layer -!! cloud fractions and clouds top/bottom layer indices for low, mid, -!! and high clouds. -! --- compute low, mid, high, total, and boundary layer cloud fractions -! and clouds top/bottom layer indices for low, mid, and high clouds. -! The three cloud domain boundaries are defined by ptopc. The cloud -! overlapping method is defined by control flag 'iovr', which may -! be different for lw and sw radiation programs. - - call gethml & -! --- inputs: - & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & - & IX,NLAY, & -! --- outputs: - & clds, mtop, mbot & - & ) - - ! return !................................... @@ -4121,7 +2955,8 @@ end subroutine progclduni !! @{ subroutine gethml & & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & ! --- inputs: - & IX, NLAY, & + & IX, NLAY, iovr_rand, iovr_maxrand, iovr_max, & + & iovr_dcorr, iovr_exp, iovr_exprand, & & clds, mtop, mbot & ! --- outputs: & ) @@ -4181,6 +3016,13 @@ subroutine gethml & ! --- inputs: integer, intent(in) :: IX, NLAY + integer, intent(in) :: & + & iovr_rand, ! Flag for random cloud overlap method + & iovr_maxrand, ! Flag for maximum-random cloud overlap method + & iovr_max, ! Flag for maximum cloud overlap method + & iovr_dcorr, ! Flag for decorrelation-length cloud overlap method + & iovr_exp, ! Flag for exponential cloud overlap method + & iovr_exprand ! Flag for exponential-random cloud overlap method real (kind=kind_phys), dimension(:,:), intent(in) :: plyr, ptop1, & & cldtot, cldcnv, dz @@ -4225,7 +3067,7 @@ subroutine gethml & kinc = 1 endif ! end_if_ivflip - if ( iovr == 0 ) then ! random overlap + if ( iovr == iovr_rand ) then ! random overlap do k = kstr, kend, kinc do i = 1, IX @@ -4244,7 +3086,7 @@ subroutine gethml & clds(i,4) = 1.0 - cl1(i) ! save total cloud enddo - elseif ( iovr == 1 ) then ! max/ran overlap + elseif ( iovr == iovr_maxrand ) then ! max/ran overlap do k = kstr, kend, kinc do i = 1, IX @@ -4268,7 +3110,7 @@ subroutine gethml & clds(i,4) = 1.0 - cl1(i) * cl2(i) ! save total cloud enddo - elseif ( iovr == 2 ) then ! maximum overlap all levels + elseif ( iovr == iovr_max ) then ! maximum overlap all levels cl1(:) = 0.0 @@ -4289,7 +3131,7 @@ subroutine gethml & clds(i,4) = cl1(i) ! save total cloud enddo - elseif ( iovr == 3 ) then ! random if clear-layer divided, + elseif ( iovr == iovr_dcorr ) then ! random if clear-layer divided, ! otherwise de-corrlength method do i = 1, ix dz1(i) = - dz(i,kstr) @@ -4321,7 +3163,7 @@ subroutine gethml & clds(i,4) = 1.0 - cl1(i) * cl2(i) ! save total cloud enddo - elseif ( iovr == 4 .or. iovr == 5 ) then ! exponential overlap (iovr=4), or + elseif ( iovr == iovr_exp .or. iovr == iovr_exprand ) then ! exponential overlap (iovr=4), or ! exponential-random (iovr=5); ! distinction defined by alpha @@ -4402,7 +3244,7 @@ subroutine gethml & if (kth2(i) == 0) kbt2(i) = k kth2(i) = kth2(i) + 1 - if ( iovr == 0 ) then + if ( iovr == iovr_rand ) then cl2(i) = cl2(i) + ccur - cl2(i)*ccur else cl2(i) = max( cl2(i), ccur ) @@ -4484,7 +3326,7 @@ subroutine gethml & if (kth2(i) == 0) kbt2(i) = k kth2(i) = kth2(i) + 1 - if ( iovr == 0 ) then + if ( iovr == iovr_rand ) then cl2(i) = cl2(i) + ccur - cl2(i)*ccur else cl2(i) = max( cl2(i), ccur ) @@ -4970,6 +3812,154 @@ SUBROUTINE adjust_cloudFinal(cfr, qc, qi, Rho,dz, kts,kte) END SUBROUTINE adjust_cloudFinal + subroutine cloud_fraction_XuRandall & + & ( IX, NLAY, plyr, clwf, rhly, qstl, & ! --- inputs + & cldtot ) & ! --- outputs + +! --- inputs: + integer, intent(in) :: IX, NLAY + real (kind=kind_phys), dimension(:,:), intent(in) :: plyr, clwf, & + & rhly, qstl + +! --- outputs + real (kind=kind_phys), dimension(:,:), intent(inout) :: cldtot + +! --- local variables: + + real (kind=kind_phys) :: clwmin, clwm, clwt, onemrh, value, & + & tem1, tem2 + integer :: i, k + +!> - Compute layer cloud fraction. + + clwmin = 0.0 + do k = 1, NLAY + do i = 1, IX + clwt = 1.0e-6 * (plyr(i,k)*0.001) +! clwt = 2.0e-6 * (plyr(i,k)*0.001) + + if (clwf(i,k) > clwt) then + + onemrh= max( 1.e-10, 1.0-rhly(i,k) ) + clwm = clwmin / max( 0.01, plyr(i,k)*0.001 ) + + tem1 = min(max(sqrt(sqrt(onemrh*qstl(i,k))),0.0001),1.0) + tem1 = 2000.0 / tem1 + +! tem1 = 1000.0 / tem1 + + value = max( min( tem1*(clwf(i,k)-clwm), 50.0 ), 0.0 ) + tem2 = sqrt( sqrt(rhly(i,k)) ) + + cldtot(i,k) = max( tem2*(1.0-exp(-value)), 0.0 ) + endif + enddo + enddo + + end subroutine cloud_fraction_XuRandall + + subroutine cloud_fraction_mass_flx_1 & + & ( IX, NLAY, lmfdeep2, xrc3, plyr, clwf, rhly, qstl, & ! --- inputs + & cldtot ) & ! --- outputs + +! --- inputs: + integer, intent(in) :: IX, NLAY + real (kind=kind_phys), intent(in) :: xrc3 + real (kind=kind_phys), dimension(:,:), intent(in) :: plyr, clwf, & + & rhly, qstl + logical, intent(in) :: lmfdeep2 + +! --- outputs + real (kind=kind_phys), dimension(:,:), intent(inout) :: cldtot + +! --- local variables: + + real (kind=kind_phys) :: clwmin, clwm, clwt, onemrh, value, & + & tem1, tem2 + integer :: i, k + +!> - Compute layer cloud fraction. + + clwmin = 0.0 + do k = 1, NLAY + do i = 1, IX + clwt = 1.0e-6 * (plyr(i,k)*0.001) +! clwt = 2.0e-6 * (plyr(i,k)*0.001) + + if (clwf(i,k) > clwt) then + onemrh= max( 1.e-10, 1.0-rhly(i,k) ) + clwm = clwmin / max( 0.01, plyr(i,k)*0.001 ) +! + tem1 = min(max((onemrh*qstl(i,k))**0.49,0.0001),1.0) !jhan + if (lmfdeep2) then + tem1 = xrc3 / tem1 + else + tem1 = 100.0 / tem1 + endif +! + value = max( min( tem1*(clwf(i,k)-clwm), 50.0 ), 0.0 ) + tem2 = sqrt( sqrt(rhly(i,k)) ) + + cldtot(i,k) = max( tem2*(1.0-exp(-value)), 0.0 ) + endif + enddo + enddo + + end subroutine cloud_fraction_mass_flx_1 + + subroutine cloud_fraction_mass_flx_2 & + & ( IX, NLAY, lmfdeep2, xrc3, plyr, clwf, rhly, qstl, & ! --- inputs + & cldtot ) & ! --- outputs + +! --- inputs: + integer, intent(in) :: IX, NLAY + real (kind=kind_phys), intent(in) :: xrc3 + real (kind=kind_phys), dimension(:,:), intent(in) :: plyr, clwf, & + & rhly, qstl + logical, intent(in) :: lmfdeep2 + +! --- outputs + real (kind=kind_phys), dimension(:,:), intent(inout) :: cldtot + +! --- local variables: + + real (kind=kind_phys) :: clwmin, clwm, clwt, onemrh, value, & + & tem1, tem2 + integer :: i, k + +!> - Compute layer cloud fraction. + + clwmin = 0.0 + do k = 1, NLAY-1 + do i = 1, IX + clwt = 1.0e-10 * (plyr(i,k)*0.001) + + if (clwf(i,k) > clwt) then + if(rhly(i,k) > 0.99) then + cldtot(i,k) = 1. + else + onemrh= max( 1.e-10, 1.0-rhly(i,k) ) + clwm = clwmin / max( 0.01, plyr(i,k)*0.001 ) + + tem1 = min(max((onemrh*qstl(i,k))**0.49,0.0001),1.0) !jhan + if (lmfdeep2) then + tem1 = xrc3 / tem1 + else + tem1 = 100.0 / tem1 + endif + + value = max( min( tem1*(clwf(i,k)-clwm), 50.0 ), 0.0 ) + tem2 = sqrt( sqrt(rhly(i,k)) ) + + cldtot(i,k) = max( tem2*(1.0-exp(-value)), 0.0 ) + endif + else + cldtot(i,k) = 0.0 + endif + enddo + enddo + + end subroutine cloud_fraction_mass_flx_2 !........................................! end module module_radiation_clouds !! @} diff --git a/physics/radlw_main.F90 b/physics/radlw_main.F90 index 95bc0b059..6d4f5750d 100644 --- a/physics/radlw_main.F90 +++ b/physics/radlw_main.F90 @@ -2082,7 +2082,7 @@ subroutine mcica_subcol & ! ! NOTE: The code below is identical for case (4) and (5) because the ! distinction in the vertical correlation between EXP and ER is already -! built into the specification of alpha (in subroutine get_alpha_exp). +! built into the specification of alpha (in subroutine get_alpha_exper). ! --- setup 2 sets of random numbers diff --git a/physics/radsw_main.F90 b/physics/radsw_main.F90 index d09f586a3..4067dd0ec 100644 --- a/physics/radsw_main.F90 +++ b/physics/radsw_main.F90 @@ -2197,7 +2197,7 @@ subroutine mcica_subcol & ! ! NOTE: The code below is identical for case (4) and (5) because the ! distinction in the vertical correlation between EXP and ER is already -! built into the specification of alpha (in subroutine get_alpha_exp). +! built into the specification of alpha (in subroutine get_alpha_exper). ! --- setup 2 sets of random numbers diff --git a/physics/rrtmg_sw_pre.F90 b/physics/rrtmg_sw_pre.F90 deleted file mode 100644 index 1c7d3d76b..000000000 --- a/physics/rrtmg_sw_pre.F90 +++ /dev/null @@ -1,59 +0,0 @@ -!>\file rrtmg_sw_pre.f90 - module rrtmg_sw_pre - contains - -!>\defgroup rrtmg_sw_pre GFS RRTMG scheme Pre -!! @{ - subroutine rrtmg_sw_pre_init () - end subroutine rrtmg_sw_pre_init - -!> \section arg_table_rrtmg_sw_pre_run Argument Table -!! \htmlinclude rrtmg_sw_pre_run.html -!! - subroutine rrtmg_sw_pre_run (im, lsswr, coszen, nday, idxday, errmsg, errflg) - - use machine, only: kind_phys - - implicit none - - integer, intent(in) :: im - logical, intent(in) :: lsswr - real(kind=kind_phys), dimension(:), intent(in) :: coszen - integer, intent(out) :: nday - integer, dimension(:), intent(out) :: idxday - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg - - ! Local variables - integer :: i - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - -! --- ... start radiation calculations -! remember to set heating rate unit to k/sec! - -!> -# Start SW radiation calculations - if (lsswr) then -!> - Check for daytime points for SW radiation. - nday = 0 - idxday = 0 - do i = 1, IM - if (coszen(i) >= 0.0001) then - nday = nday + 1 - idxday(nday) = i - endif - enddo - else - nday = 0 - idxday = 0 - endif - - end subroutine rrtmg_sw_pre_run - - subroutine rrtmg_sw_pre_finalize () - end subroutine rrtmg_sw_pre_finalize - -!! @} - end module rrtmg_sw_pre diff --git a/physics/rrtmgp_sw_aerosol_optics.F90 b/physics/rrtmgp_aerosol_optics.F90 similarity index 74% rename from physics/rrtmgp_sw_aerosol_optics.F90 rename to physics/rrtmgp_aerosol_optics.F90 index afd039249..eb7797125 100644 --- a/physics/rrtmgp_sw_aerosol_optics.F90 +++ b/physics/rrtmgp_aerosol_optics.F90 @@ -1,7 +1,7 @@ -module rrtmgp_sw_aerosol_optics +module rrtmgp_aerosol_optics use machine, only: kind_phys use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp - use mo_optical_props, only: ty_optical_props_2str + use mo_optical_props, only: ty_optical_props_2str, ty_optical_props_1scl use radiation_tools, only: check_error_msg use rrtmgp_sw_gas_optics, only: sw_gas_props use rrtmgp_lw_gas_optics, only: lw_gas_props @@ -14,29 +14,24 @@ module rrtmgp_sw_aerosol_optics implicit none - public rrtmgp_sw_aerosol_optics_init, rrtmgp_sw_aerosol_optics_run, rrtmgp_sw_aerosol_optics_finalize + public rrtmgp_aerosol_optics_run contains ! ######################################################################################### - ! SUBROUTINE rrtmgp_sw_aerosol_optics_init() + ! SUBROUTINE rrtmgp_aerosol_optics_run() ! ######################################################################################### - subroutine rrtmgp_sw_aerosol_optics_init() - end subroutine rrtmgp_sw_aerosol_optics_init - - ! ######################################################################################### - ! SUBROUTINE rrtmgp_sw_aerosol_optics_run() - ! ######################################################################################### -!! \section arg_table_rrtmgp_sw_aerosol_optics_run -!! \htmlinclude rrtmgp_sw_aerosol_optics_run.html +!! \section arg_table_rrtmgp_aerosol_optics_run +!! \htmlinclude rrtmgp_aerosol_optics_run.html !! - subroutine rrtmgp_sw_aerosol_optics_run(doSWrad, nCol, nLev, nTracer, nTracerAer, nDay, & - idxday, p_lev, p_lay, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, & - aerodp, sw_optical_props_aerosol, errmsg, errflg ) + subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTracerAer, & + nDay, idxday, p_lev, p_lay, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, & + aerodp, sw_optical_props_aerosol, lw_optical_props_aerosol, errmsg, errflg ) ! Inputs logical, intent(in) :: & - doSWrad ! Logical flag for shortwave radiation call + doSWrad, & ! Logical flag for shortwave radiation call + doLWrad ! Logical flag for longwave radiation call integer, intent(in) :: & nCol, & ! Number of horizontal grid points nDay, & ! Number of daylit points @@ -66,6 +61,8 @@ subroutine rrtmgp_sw_aerosol_optics_run(doSWrad, nCol, nLev, nTracer, nTracerAer aerodp ! Vertical integrated optical depth for various aerosol species type(ty_optical_props_2str),intent(out) :: & sw_optical_props_aerosol ! RRTMGP DDT: Longwave aerosol optical properties (tau) + type(ty_optical_props_1scl),intent(inout) :: & + lw_optical_props_aerosol ! RRTMGP DDT: Longwave aerosol optical properties (tau) integer, intent(out) :: & errflg ! CCPP error flag character(len=*), intent(out) :: & @@ -76,6 +73,7 @@ subroutine rrtmgp_sw_aerosol_optics_run(doSWrad, nCol, nLev, nTracer, nTracerAer aerosolslw ! real(kind_phys), dimension(nCol, nLev, sw_gas_props%get_nband(), NF_AESW) :: & aerosolssw, aerosolssw2 + integer :: iBand ! Initialize CCPP error handling variables errmsg = '' @@ -84,9 +82,10 @@ subroutine rrtmgp_sw_aerosol_optics_run(doSWrad, nCol, nLev, nTracer, nTracerAer if (.not. doSWrad) return ! Call module_radiation_aerosols::setaer(),to setup aerosols property profile - call setaer(p_lev/100., p_lay/100., p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, nCol, nLev, & + call setaer(p_lev*0.01, p_lay*0.01, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, nCol, nLev, & nLev+1, .true., .true., aerosolssw2, aerosolslw, aerodp) + ! Shortwave if (nDay .gt. 0) then ! Store aerosol optical properties ! SW. @@ -100,7 +99,7 @@ subroutine rrtmgp_sw_aerosol_optics_run(doSWrad, nCol, nLev, nTracer, nTracerAer aerosolssw(1:nCol,:,2:sw_gas_props%get_nband(),3) = aerosolssw2(1:nCol,:,1:sw_gas_props%get_nband()-1,3) ! Allocate RRTMGP DDT: Aerosol optics [nCol,nlev,nBands] - call check_error_msg('rrtmgp_sw_aerosol_optics_run',sw_optical_props_aerosol%alloc_2str( & + call check_error_msg('rrtmgp_aerosol_optics_run',sw_optical_props_aerosol%alloc_2str( & nDay, nlev, sw_gas_props%get_band_lims_wavenumber())) ! Copy aerosol optical information to RRTMGP DDT @@ -109,11 +108,16 @@ subroutine rrtmgp_sw_aerosol_optics_run(doSWrad, nCol, nLev, nTracer, nTracerAer sw_optical_props_aerosol%g = aerosolssw(idxday(1:nday),:,:,3) endif - end subroutine rrtmgp_sw_aerosol_optics_run + ! Longwave + if (.not. doLWrad) return + lw_optical_props_aerosol%tau = aerosolslw(:,:,:,1) * (1. - aerosolslw(:,:,:,2)) + + lw_optical_props_aerosol%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() + do iBand=1,lw_gas_props%get_nband() + lw_optical_props_aerosol%band2gpt(1:2,iBand) = iBand + lw_optical_props_aerosol%gpt2band(iBand) = iBand + end do + + end subroutine rrtmgp_aerosol_optics_run - ! ######################################################################################### - ! SUBROUTINE rrtmgp_sw_aerosol_optics_finalize() - ! ######################################################################################### - subroutine rrtmgp_sw_aerosol_optics_finalize() - end subroutine rrtmgp_sw_aerosol_optics_finalize -end module rrtmgp_sw_aerosol_optics +end module rrtmgp_aerosol_optics diff --git a/physics/rrtmgp_sw_aerosol_optics.meta b/physics/rrtmgp_aerosol_optics.meta similarity index 90% rename from physics/rrtmgp_sw_aerosol_optics.meta rename to physics/rrtmgp_aerosol_optics.meta index 2abacd92a..cd7c77d4d 100644 --- a/physics/rrtmgp_sw_aerosol_optics.meta +++ b/physics/rrtmgp_aerosol_optics.meta @@ -1,11 +1,11 @@ [ccpp-table-properties] - name = rrtmgp_sw_aerosol_optics + name = rrtmgp_aerosol_optics type = scheme dependencies = iounitdef.f,machine.F,radiation_aerosols.f,radiation_tools.F90 ######################################################################## [ccpp-arg-table] - name = rrtmgp_sw_aerosol_optics_run + name = rrtmgp_aerosol_optics_run type = scheme [doSWrad] standard_name = flag_for_calling_shortwave_radiation @@ -14,6 +14,13 @@ dimensions = () type = logical intent = in +[doLWrad] + standard_name = flag_for_calling_longwave_radiation + long_name = logical flags for lw radiation calls + units = flag + dimensions = () + type = logical + intent = in [ncol] standard_name = horizontal_loop_extent long_name = horizontal dimension @@ -151,6 +158,13 @@ dimensions = () type = ty_optical_props_2str intent = out +[lw_optical_props_aerosol] + standard_name = longwave_optical_properties_for_aerosols + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_1scl + intent = inout [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/rrtmgp_lw_aerosol_optics.F90 b/physics/rrtmgp_lw_aerosol_optics.F90 deleted file mode 100644 index de42db1cd..000000000 --- a/physics/rrtmgp_lw_aerosol_optics.F90 +++ /dev/null @@ -1,104 +0,0 @@ -module rrtmgp_lw_aerosol_optics - use machine, only: kind_phys - use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp - use mo_optical_props, only: ty_optical_props_1scl - use radiation_tools, only: check_error_msg - use rrtmgp_sw_gas_optics, only: sw_gas_props - use rrtmgp_lw_gas_optics, only: lw_gas_props - use module_radiation_aerosols, only: & - NF_AESW, & ! Number of optical-fields in SW output (3=tau+g+omega) - NF_AELW, & ! Number of optical-fields in LW output (3=tau+g+omega) - setaer, & ! Routine to compute aerosol radiative properties (tau,g,omega) - NSPC1 ! Number of species for vertically integrated aerosol optical-depth - use netcdf - - implicit none - - public rrtmgp_lw_aerosol_optics_init, rrtmgp_lw_aerosol_optics_run, rrtmgp_lw_aerosol_optics_finalize - -contains - - ! ######################################################################################### - ! SUBROUTINE rrtmgp_lw_aerosol_optics_init() - ! ######################################################################################### - subroutine rrtmgp_lw_aerosol_optics_init() - end subroutine rrtmgp_lw_aerosol_optics_init - - ! ######################################################################################### - ! SUBROUTINE rrtmgp_lw_aerosol_optics_run() - ! ######################################################################################### -!! \section arg_table_rrtmgp_lw_aerosol_optics_run -!! \htmlinclude rrtmgp_lw_aerosol_optics.html -!! - subroutine rrtmgp_lw_aerosol_optics_run(doLWrad, nCol, nLev, nspc, nTracer, nTracerAer, & - p_lev, p_lay, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, & - lw_optical_props_aerosol, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doLWrad ! Logical flag for longwave radiation call - integer, intent(in) :: & - nCol, & ! Number of horizontal grid points - nLev, & ! Number of vertical layers - nspc, & ! Number of aerosol optical-depths - nTracer, & ! Number of tracers - nTracerAer ! Number of aerosol tracers - real(kind_phys), dimension(:), intent(in) :: & - lon, & ! Longitude - lat, & ! Latitude - lsmask ! Land/sea/sea-ice mask - real(kind_phys), dimension(:,:),intent(in) :: & - p_lay, & ! Pressure @ layer-centers (Pa) - tv_lay, & ! Virtual-temperature @ layer-centers (K) - relhum, & ! Relative-humidity @ layer-centers - p_lk ! Exner function @ layer-centers (1) - real(kind_phys), dimension(:,:, :),intent(in) :: & - tracer ! trace gas concentrations - real(kind_phys), dimension(:,:, :),intent(in) :: & - aerfld ! aerosol input concentrations - real(kind_phys), dimension(:,:),intent(in) :: & - p_lev ! Pressure @ layer-interfaces (Pa) - - ! Outputs - type(ty_optical_props_1scl),intent(inout) :: & - lw_optical_props_aerosol ! RRTMGP DDT: Longwave aerosol optical properties (tau) - integer, intent(out) :: & - errflg ! CCPP error flag - character(len=*), intent(out) :: & - errmsg ! CCPP error message - - ! Local variables - real(kind_phys), dimension(nCol, nLev, lw_gas_props%get_nband(), NF_AELW) :: & - aerosolslw ! - real(kind_phys), dimension(nCol, nLev, sw_gas_props%get_nband(), NF_AESW) :: & - aerosolssw - real(kind_phys), dimension(nCol,nspc) :: aerodp - integer :: iBand - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doLWrad) return - - ! Call module_radiation_aerosols::setaer(),to setup aerosols property profile - call setaer(p_lev/100., p_lay/100., p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, ncol, nLev, & - nLev+1, .true., .true., aerosolssw, aerosolslw, aerodp) - - ! Copy aerosol optical information to RRTMGP DDT - lw_optical_props_aerosol%tau = aerosolslw(:,:,:,1) * (1. - aerosolslw(:,:,:,2)) - - lw_optical_props_aerosol%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_aerosol%band2gpt(1:2,iBand) = iBand - lw_optical_props_aerosol%gpt2band(iBand) = iBand - end do - - end subroutine rrtmgp_lw_aerosol_optics_run - - ! ######################################################################################### - ! SUBROUTINE rrtmgp_lw_aerosol_optics_finalize() - ! ######################################################################################### - subroutine rrtmgp_lw_aerosol_optics_finalize() - end subroutine rrtmgp_lw_aerosol_optics_finalize -end module rrtmgp_lw_aerosol_optics diff --git a/physics/rrtmgp_lw_aerosol_optics.meta b/physics/rrtmgp_lw_aerosol_optics.meta deleted file mode 100644 index 165051409..000000000 --- a/physics/rrtmgp_lw_aerosol_optics.meta +++ /dev/null @@ -1,153 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_lw_aerosol_optics - type = scheme - dependencies = iounitdef.f,machine.F,radiation_aerosols.f,radiation_tools.F90 - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_lw_aerosol_optics_run - type = scheme -[doLWrad] - standard_name = flag_for_calling_longwave_radiation - long_name = logical flags for lw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[nspc] - standard_name = number_of_species_for_aerosol_optical_depth - long_name = number of species for output aerosol optical depth plus total - units = count - dimensions = () - type = integer - intent = in -[nTracer] - standard_name = number_of_tracers - long_name = number of tracers - units = count - dimensions = () - type = integer - intent = in -[nTracerAer] - standard_name = number_of_aerosol_tracers_MG - long_name = number of aerosol tracers for Morrison Gettelman MP - units = count - dimensions = () - type = integer - intent = in -[p_lev] - standard_name = air_pressure_at_interface_for_RRTMGP - long_name = air pressure at vertical interface for radiation calculation - units = Pa - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[p_lay] - standard_name = air_pressure_at_layer_for_RRTMGP - long_name = air pressure at vertical layer for radiation calculation - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[p_lk] - standard_name = dimensionless_exner_function - long_name = dimensionless Exner function at model layer centers - units = none - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[tv_lay] - standard_name = virtual_temperature - long_name = layer virtual temperature - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[relhum] - standard_name = relative_humidity - long_name = layer relative humidity - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[lsmask] - standard_name = area_type - long_name = landmask: sea/land/ice=0/1/2 - units = flag - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[tracer] - standard_name = chemical_tracers - long_name = chemical tracers - units = g g-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) - type = real - kind = kind_phys - intent = in -[aerfld] - standard_name = mass_number_concentration_of_aerosol_from_gocart_climatology - long_name = GOCART aerosol climatology number concentration - units = kg-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_tracers_MG) - type = real - kind = kind_phys - intent = in -[lon] - standard_name = longitude - long_name = longitude - units = radian - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[lat] - standard_name = latitude - long_name = latitude - units = radian - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[lw_optical_props_aerosol] - standard_name = longwave_optical_properties_for_aerosols - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_1scl - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rrtmgp_lw_cloud_optics.F90 b/physics/rrtmgp_lw_cloud_optics.F90 index 5ddcec078..835261071 100644 --- a/physics/rrtmgp_lw_cloud_optics.F90 +++ b/physics/rrtmgp_lw_cloud_optics.F90 @@ -383,10 +383,13 @@ end subroutine rrtmgp_lw_cloud_optics_init !! \htmlinclude rrtmgp_lw_cloud_optics.html !! subroutine rrtmgp_lw_cloud_optics_run(doLWrad, doG_cldoptics, icliq_lw, icice_lw, & - doGP_cldoptics_PADE, doGP_cldoptics_LUT, doGP_lwscat, nCol, nLev, nbndsGPlw, & - p_lay, cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, & - cld_rwp, cld_rerain, precip_frac, lon, lat, cldtaulw, & - lw_optical_props_cloudsByBand, lw_optical_props_precipByBand, errmsg, errflg) + doGP_cldoptics_PADE, doGP_cldoptics_LUT, doGP_lwscat, do_mynnedmf, imfdeepcnv, & + imfdeepcnv_gf, imfdeepcnv_samf, nCol, nLev, nbndsGPlw , p_lay, cld_frac, cld_lwp, & + cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, cld_rerain, & + precip_frac, cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, cld_cnv_reice, cld_pbl_lwp, & + cld_pbl_reliq, cld_pbl_iwp, cld_pbl_reice, lon, lat, cldtaulw, & + lw_optical_props_cloudsByBand, lw_optical_props_cnvcloudsByBand, & + lw_optical_props_MYNNcloudsByBand, lw_optical_props_precipByBand, errmsg, errflg) ! Inputs logical, intent(in) :: & @@ -394,17 +397,21 @@ subroutine rrtmgp_lw_cloud_optics_run(doLWrad, doG_cldoptics, icliq_lw, icice_lw doG_cldoptics, & ! Use legacy RRTMG cloud-optics? doGP_cldoptics_PADE, & ! Use RRTMGP cloud-optics: PADE approximation? doGP_cldoptics_LUT, & ! Use RRTMGP cloud-optics: LUTs? - doGP_lwscat ! Include scattering in LW cloud-optics? + doGP_lwscat, & ! Include scattering in LW cloud-optics? + do_mynnedmf ! integer, intent(in) :: & - nbndsGPlw, & ! Number of longwave bands + nbndsGPlw, & ! nCol, & ! Number of horizontal gridpoints nLev, & ! Number of vertical levels icliq_lw, & ! Choice of treatment of liquid cloud optical properties (RRTMG legacy) - icice_lw ! Choice of treatment of ice cloud optical properties (RRTMG legacy) - real(kind_phys), dimension(nCol), intent(in) :: & + icice_lw, & ! Choice of treatment of ice cloud optical properties (RRTMG legacy) + imfdeepcnv, & ! + imfdeepcnv_gf, & ! + imfdeepcnv_samf ! + real(kind_phys), dimension(:), intent(in) :: & lon, & ! Longitude lat ! Latitude - real(kind_phys), dimension(ncol,nLev),intent(in) :: & + real(kind_phys), dimension(:,:),intent(in) :: & p_lay, & ! Layer pressure (Pa) cld_frac, & ! Total cloud fraction by layer cld_lwp, & ! Cloud liquid water path @@ -415,7 +422,15 @@ subroutine rrtmgp_lw_cloud_optics_run(doLWrad, doG_cldoptics, icliq_lw, icice_lw cld_resnow, & ! Cloud snow effective radius cld_rwp, & ! Cloud rain water path cld_rerain, & ! Cloud rain effective radius - precip_frac ! Precipitation fraction by layer. + precip_frac, & ! Precipitation fraction by layer. + cld_cnv_lwp, & ! Water path for convective liquid cloud-particles (microns) + cld_cnv_reliq, & ! Effective radius for convective liquid cloud-particles (microns) + cld_cnv_iwp, & ! Water path for convective ice cloud-particles (microns) + cld_cnv_reice, & ! Effective radius for convective ice cloud-particles (microns) + cld_pbl_lwp, & ! Water path for SGS PBL liquid cloud-particles + cld_pbl_reliq, & ! Effective radius for SGS PBL liquid cloud-particles + cld_pbl_iwp, & ! Water path for SGS PBL ice cloud-particles + cld_pbl_reice ! Effective radius for SGS PBL ice cloud-particles ! Outputs character(len=*), intent(out) :: & @@ -423,9 +438,11 @@ subroutine rrtmgp_lw_cloud_optics_run(doLWrad, doG_cldoptics, icliq_lw, icice_lw integer, intent(out) :: & errflg ! CCPP error flag type(ty_optical_props_2str),intent(inout) :: & - lw_optical_props_cloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (clouds) - lw_optical_props_precipByBand ! RRTMGP DDT: Longwave optical properties in each band (precipitation) - real(kind_phys), dimension(ncol,nLev), intent(inout) :: & + lw_optical_props_cloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (clouds) + lw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (convective cloud) + lw_optical_props_MYNNcloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (MYNN-PBL cloud) + lw_optical_props_precipByBand ! RRTMGP DDT: Longwave optical properties in each band (precipitation) + real(kind_phys), dimension(:,:), intent(inout) :: & cldtaulw ! Approx 10.mu band layer cloud optical depth ! Local variables @@ -444,27 +461,60 @@ subroutine rrtmgp_lw_cloud_optics_run(doLWrad, doG_cldoptics, icliq_lw, icice_lw if (.not. doLWrad) return - lw_optical_props_cloudsByBand%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - lw_optical_props_precipByBand%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_cloudsByBand%band2gpt(1:2,iBand) = iBand - lw_optical_props_cloudsByBand%band2gpt(1:2,iBand) = iBand - lw_optical_props_precipByBand%gpt2band(iBand) = iBand - lw_optical_props_precipByBand%gpt2band(iBand) = iBand - end do - ! Compute cloud-optics for RTE. if (doGP_cldoptics_PADE .or. doGP_cldoptics_LUT) then - ! i) RRTMGP cloud-optics. - call check_error_msg('rrtmgp_lw_cloud_optics_run',lw_cloud_props%cloud_optics(& - cld_lwp, & ! IN - Cloud liquid water path (g/m2) - cld_iwp, & ! IN - Cloud ice water path (g/m2) - cld_reliq, & ! IN - Cloud liquid effective radius (microns) - cld_reice, & ! IN - Cloud ice effective radius (microns) - lw_optical_props_cloudsByBand)) ! OUT - RRTMGP DDT containing cloud radiative properties - ! in each band - ! Add in rain and snow(+groupel) + ! i) Cloud-optics. + lw_optical_props_cloudsByBand%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() + do iBand=1,lw_gas_props%get_nband() + lw_optical_props_cloudsByBand%band2gpt(1:2,iBand) = iBand + lw_optical_props_cloudsByBand%gpt2band(iBand) = iBand + end do + call check_error_msg('rrtmgp_lw_cloud_optics_run - clouds',lw_cloud_props%cloud_optics(& + cld_lwp, & ! IN - Cloud liquid water path (g/m2) + cld_iwp, & ! IN - Cloud ice water path (g/m2) + cld_reliq, & ! IN - Cloud liquid effective radius (microns) + cld_reice, & ! IN - Cloud ice effective radius (microns) + lw_optical_props_cloudsByBand)) ! OUT - RRTMGP DDT containing cloud radiative properties + ! in each band + ! ii) Convective cloud-optics + if (imfdeepcnv == imfdeepcnv_samf .or. imfdeepcnv == imfdeepcnv_gf) then + lw_optical_props_cnvcloudsByBand%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() + do iBand=1,lw_gas_props%get_nband() + lw_optical_props_cnvcloudsByBand%band2gpt(1:2,iBand) = iBand + lw_optical_props_cnvcloudsByBand%gpt2band(iBand) = iBand + end do + call check_error_msg('rrtmgp_lw_cnvcloud_optics_run - convective cloud',lw_cloud_props%cloud_optics(& + cld_cnv_lwp, & ! IN - Convective cloud liquid water path (g/m2) + cld_cnv_iwp, & ! IN - Convective cloud ice water path (g/m2) + cld_cnv_reliq, & ! IN - Convective cloud liquid effective radius (microns) + cld_cnv_reice, & ! IN - Convective cloud ice effective radius (microns) + lw_optical_props_cnvcloudsByBand)) ! OUT - RRTMGP DDT containing convective cloud radiative properties + ! in each band + endif + + ! iii) MYNN cloud-optics + if (do_mynnedmf) then + lw_optical_props_MYNNcloudsByBand%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() + do iBand=1,lw_gas_props%get_nband() + lw_optical_props_MYNNcloudsByBand%band2gpt(1:2,iBand) = iBand + lw_optical_props_MYNNcloudsByBand%gpt2band(iBand) = iBand + end do + call check_error_msg('rrtmgp_lw_MYNNcloud_optics_run - MYNN-EDMF cloud',lw_cloud_props%cloud_optics(& + cld_pbl_lwp, & ! IN - MYNN-EDMF PBL cloud liquid water path (g/m2) + cld_pbl_iwp, & ! IN - MYNN-EDMF PBL cloud ice water path (g/m2) + cld_pbl_reliq, & ! IN - MYNN-EDMF PBL cloud liquid effective radius (microns) + cld_pbl_reice, & ! IN - MYNN-EDMF PBL cloud ice effective radius (microns) + lw_optical_props_MYNNcloudsByBand)) ! OUT - RRTMGP DDT containing MYNN-EDMF PBL cloud radiative properties + ! in each band + endif + + ! iv) Cloud precipitation optics: rain and snow(+groupel) + lw_optical_props_precipByBand%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() + do iBand=1,lw_gas_props%get_nband() + lw_optical_props_precipByBand%band2gpt(1:2,iBand) = iBand + lw_optical_props_precipByBand%gpt2band(iBand) = iBand + end do do iCol=1,nCol do iLay=1,nLev if (cld_frac(iCol,iLay) .gt. 0.) then @@ -484,17 +534,7 @@ subroutine rrtmgp_lw_cloud_optics_run(doLWrad, doG_cldoptics, icliq_lw, icice_lw enddo enddo endif - if (doG_cldoptics) then - ! ii) RRTMG cloud-optics. - if (any(cld_frac .gt. 0)) then - call rrtmg_lw_cloud_optics(ncol, nLev, nbndsGPlw, cld_lwp, cld_reliq, cld_iwp,& - cld_reice, cld_rwp, cld_rerain, cld_swp, cld_resnow, cld_frac, icliq_lw, & - icice_lw, tau_cld, tau_precip) - lw_optical_props_cloudsByBand%tau = tau_cld - lw_optical_props_precipByBand%tau = tau_precip - endif - endif - + ! All-sky LW optical depth ~10microns (DJS asks: Same as SW, move to cloud-diagnostics?) cldtaulw = lw_optical_props_cloudsByBand%tau(:,:,7) diff --git a/physics/rrtmgp_lw_cloud_optics.meta b/physics/rrtmgp_lw_cloud_optics.meta index 35e27979e..c58496dc5 100644 --- a/physics/rrtmgp_lw_cloud_optics.meta +++ b/physics/rrtmgp_lw_cloud_optics.meta @@ -141,6 +141,34 @@ dimensions = () type = logical intent = in +[do_mynnedmf] + standard_name = flag_for_mellor_yamada_nakanishi_niino_pbl_scheme + long_name = flag to activate MYNN-EDMF + units = flag + dimensions = () + type = logical + intent = in +[imfdeepcnv] + standard_name = control_for_deep_convection_scheme + long_name = flag for mass-flux deep convection scheme + units = flag + dimensions = () + type = integer + intent = in +[imfdeepcnv_gf] + standard_name = identifier_for_grell_freitas_deep_convection + long_name = flag for Grell-Freitas deep convection scheme + units = flag + dimensions = () + type = integer + intent = in +[imfdeepcnv_samf] + standard_name = identifer_for_scale_aware_mass_flux_deep_convection + long_name = flag for SAMF deep convection scheme + units = flag + dimensions = () + type = integer + intent = in [ncol] standard_name = horizontal_loop_extent long_name = horizontal dimension @@ -235,6 +263,70 @@ type = real kind = kind_phys intent = in +[cld_cnv_lwp] + standard_name = convective_cloud_liquid_water_path + long_name = layer convective cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_iwp] + standard_name = convective_cloud_ice_water_path + long_name = layer convective cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_reliq] + standard_name = mean_effective_radius_for_liquid_convective_cloud + long_name = mean effective radius for liquid convective cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_reice] + standard_name = mean_effective_radius_for_ice_convective_cloud + long_name = mean effective radius for ice convective cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_lwp] + standard_name = MYNN_SGS_cloud_liquid_water_path + long_name = layer convective cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_iwp] + standard_name = MYNN_SGS_cloud_ice_water_path + long_name = layer convective cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_reliq] + standard_name = mean_effective_radius_for_liquid_MYNN_SGS_cloud + long_name = mean effective radius for liquid MYNN_SGS cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_reice] + standard_name = mean_effective_radius_for_ice_MYNN_SGS_cloud + long_name = mean effective radius for ice MYNN_SGS cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in [p_lay] standard_name = air_pressure_at_layer_for_RRTMGP long_name = air pressure layer @@ -281,6 +373,20 @@ dimensions = () type = ty_optical_props_2str intent = inout +[lw_optical_props_cnvcloudsByBand] + standard_name = longwave_optical_properties_for_convective_cloudy_atmosphere_by_band + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + intent = inout +[lw_optical_props_MYNNcloudsByBand] + standard_name = longwave_optical_properties_for_MYNN_EDMF_PBL_cloudy_atmosphere_by_band + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + intent = inout [lw_optical_props_precipByBand] standard_name = longwave_optical_properties_for_precipitation_by_band long_name = Fortran DDT containing RRTMGP optical properties diff --git a/physics/rrtmgp_lw_cloud_sampling.F90 b/physics/rrtmgp_lw_cloud_sampling.F90 index d8d499577..cb11607dc 100644 --- a/physics/rrtmgp_lw_cloud_sampling.F90 +++ b/physics/rrtmgp_lw_cloud_sampling.F90 @@ -18,20 +18,25 @@ module rrtmgp_lw_cloud_sampling !! \section arg_table_rrtmgp_lw_cloud_sampling_run !! \htmlinclude rrtmgp_lw_cloud_sampling_run.html !! - subroutine rrtmgp_lw_cloud_sampling_run(doLWrad, nCol, nLev, icseed_lw, iovr, & + subroutine rrtmgp_lw_cloud_sampling_run(doLWrad, nCol, nLev, icseed_lw, iovr,iovr_convcld,& iovr_max, iovr_maxrand, iovr_rand, iovr_dcorr, iovr_exp, iovr_exprand, isubc_lw, & - cld_frac, precip_frac, cloud_overlap_param, precip_overlap_param, & - doGP_lwscat, lw_optical_props_cloudsByBand, lw_optical_props_precipByBand, & - lw_optical_props_clouds, lw_optical_props_precip, errmsg, errflg) + cld_frac, precip_frac, cloud_overlap_param, precip_overlap_param, cld_cnv_frac, & + cnv_cloud_overlap_param, imfdeepcnv, imfdeepcnv_gf, imfdeepcnv_samf, & + lw_optical_props_cloudsByBand, lw_optical_props_cnvcloudsByBand, & + lw_optical_props_precipByBand, lw_optical_props_clouds, lw_optical_props_cnvclouds, & + lw_optical_props_precip, errmsg, errflg) ! Inputs logical, intent(in) :: & - doLWrad, & ! Logical flag for shortwave radiation call - doGP_lwscat ! Include scattering in LW cloud-optics? + doLWrad ! Logical flag for shortwave radiation call integer, intent(in) :: & nCol, & ! Number of horizontal gridpoints nLev, & ! Number of vertical layers + imfdeepcnv, & ! + imfdeepcnv_gf, & ! + imfdeepcnv_samf, & ! iovr, & ! Choice of cloud-overlap method + iovr_convcld, & ! Choice of convective cloud-overlap iovr_max, & ! Flag for maximum cloud overlap method iovr_maxrand, & ! Flag for maximum-random cloud overlap method iovr_rand, & ! Flag for random cloud overlap method @@ -39,19 +44,21 @@ subroutine rrtmgp_lw_cloud_sampling_run(doLWrad, nCol, nLev, icseed_lw, iovr, iovr_exp, & ! Flag for exponential cloud overlap method iovr_exprand, & ! Flag for exponential-random cloud overlap method isubc_lw - integer,intent(in),dimension(ncol) :: & + integer,intent(in),dimension(:) :: & icseed_lw ! auxiliary special cloud related array when module ! variable isubc_lw=2, it provides permutation seed ! for each column profile that are used for generating ! random numbers. when isubc_lw /=2, it will not be used. - real(kind_phys), dimension(ncol,nLev),intent(in) :: & + real(kind_phys), dimension(:,:),intent(in) :: & cld_frac, & ! Total cloud fraction by layer - precip_frac ! Precipitation fraction by layer - real(kind_phys), dimension(ncol,nLev), intent(in) :: & + cld_cnv_frac, & ! Convective cloud fraction by layer + precip_frac, & ! Precipitation fraction by layer cloud_overlap_param, & ! Cloud overlap parameter + cnv_cloud_overlap_param, & ! Convective cloud overlap parameter precip_overlap_param ! Precipitation overlap parameter type(ty_optical_props_2str),intent(in) :: & lw_optical_props_cloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (clouds) + lw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (convective cloud) lw_optical_props_precipByBand ! RRTMGP DDT: Longwave optical properties in each band (precipitation) ! Outputs @@ -61,6 +68,7 @@ subroutine rrtmgp_lw_cloud_sampling_run(doLWrad, nCol, nLev, icseed_lw, iovr, errflg ! CCPP error code type(ty_optical_props_2str),intent(inout) :: & lw_optical_props_clouds, & ! RRTMGP DDT: Shortwave optical properties by spectral point (clouds) + lw_optical_props_cnvclouds, & ! RRTMGP DDT: Shortwave optical properties by spectral point (convective cloud) lw_optical_props_precip ! RRTMGP DDT: Shortwave optical properties by spectral point (precipitation) ! Local variables @@ -70,7 +78,7 @@ subroutine rrtmgp_lw_cloud_sampling_run(doLWrad, nCol, nLev, icseed_lw, iovr, real(kind_phys), dimension(lw_gas_props%get_ngpt(),nLev,ncol) :: rng3D,rng3D2 real(kind_phys), dimension(lw_gas_props%get_ngpt()*nLev) :: rng2D real(kind_phys), dimension(lw_gas_props%get_ngpt()) :: rng1D - logical, dimension(ncol,nLev,lw_gas_props%get_ngpt()) :: cldfracMCICA,precipfracSAMP + logical, dimension(ncol,nLev,lw_gas_props%get_ngpt()) :: maskMCICA ! Initialize CCPP error handling variables errmsg = '' @@ -119,7 +127,7 @@ subroutine rrtmgp_lw_cloud_sampling_run(doLWrad, nCol, nLev, icseed_lw, iovr, ! Cloud-overlap. ! Maximum-random, random or maximum. if (iovr == iovr_maxrand .or. iovr == iovr_rand .or. iovr == iovr_max) then - call sampled_mask(rng3D, cld_frac, cldfracMCICA) + call sampled_mask(rng3D, cld_frac, maskMCICA) endif ! Exponential decorrelation length overlap if (iovr == iovr_dcorr) then @@ -129,13 +137,13 @@ subroutine rrtmgp_lw_cloud_sampling_run(doLWrad, nCol, nLev, icseed_lw, iovr, call random_number(rng2D,rng_stat) rng3D2(:,:,iCol) = reshape(source = rng2D,shape=[lw_gas_props%get_ngpt(),nLev]) enddo - call sampled_mask(rng3D, cld_frac, cldfracMCICA, & + call sampled_mask(rng3D, cld_frac, maskMCICA, & overlap_param = cloud_overlap_param(:,1:nLev-1), & randoms2 = rng3D2) endif ! Exponential or Exponential-random if (iovr == iovr_exp .or. iovr == iovr_exprand) then - call sampled_mask(rng3D, cld_frac, cldfracMCICA, & + call sampled_mask(rng3D, cld_frac, maskMCICA, & overlap_param = cloud_overlap_param(:,1:nLev-1)) endif @@ -143,50 +151,10 @@ subroutine rrtmgp_lw_cloud_sampling_run(doLWrad, nCol, nLev, icseed_lw, iovr, ! Sampling. Map band optical depth to each g-point using McICA ! call check_error_msg('rrtmgp_lw_cloud_sampling_run_draw_samples',& - draw_samples(cldfracMCICA, doGP_lwscat, & + draw_samples(maskMCICA, .true., & lw_optical_props_cloudsByBand, & lw_optical_props_clouds)) - ! #################################################################################### - ! Next sample the precipitation... - ! (Use same RNGs as was used by the clouds.) - ! #################################################################################### - lw_optical_props_precip%band2gpt = lw_gas_props%get_band_lims_gpoint() - lw_optical_props_precip%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_precip%gpt2band(lw_optical_props_precip%band2gpt(1,iBand):lw_optical_props_precip%band2gpt(2,iBand)) = iBand - end do - - ! Precipitation overlap. - ! Maximum-random, random or maximum. - if (iovr == iovr_maxrand .or. iovr == iovr_rand .or. iovr == iovr_max) then - call sampled_mask(rng3D, precip_frac, precipfracSAMP) - endif - ! Exponential decorrelation length overlap - if (iovr == iovr_dcorr) then - call sampled_mask(rng3D, precip_frac, precipfracSAMP, & - overlap_param = precip_overlap_param(:,1:nLev-1), & - randoms2 = rng3D2) - endif - ! Exponential or Exponential-random - if (iovr == iovr_exp .or. iovr == iovr_exprand) then - call sampled_mask(rng3D, precip_frac, precipfracSAMP, & - overlap_param = precip_overlap_param(:,1:nLev-1)) - endif - - ! - ! Sampling. Map band optical depth to each g-point using McICA - ! - call check_error_msg('rrtmgp_lw_precip_sampling_run_draw_samples',& - draw_samples(precipfracSAMP, doGP_lwscat, & - lw_optical_props_precipByBand, & - lw_optical_props_precip)) - - ! #################################################################################### - ! Just add precipitation optics to cloud-optics - ! #################################################################################### - lw_optical_props_clouds%tau = lw_optical_props_clouds%tau + lw_optical_props_precip%tau - end subroutine rrtmgp_lw_cloud_sampling_run ! ######################################################################################### diff --git a/physics/rrtmgp_lw_cloud_sampling.meta b/physics/rrtmgp_lw_cloud_sampling.meta index 2e4029ae2..c1ae9d139 100644 --- a/physics/rrtmgp_lw_cloud_sampling.meta +++ b/physics/rrtmgp_lw_cloud_sampling.meta @@ -14,12 +14,33 @@ dimensions = () type = logical intent = in -[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 +[imfdeepcnv] + standard_name = control_for_deep_convection_scheme + long_name = flag for mass-flux deep convection scheme units = flag dimensions = () - type = logical + type = integer + intent = in +[imfdeepcnv_gf] + standard_name = identifier_for_grell_freitas_deep_convection + long_name = flag for Grell-Freitas deep convection scheme + units = flag + dimensions = () + type = integer + intent = in +[imfdeepcnv_samf] + standard_name = identifer_for_scale_aware_mass_flux_deep_convection + long_name = flag for SAMF deep convection scheme + units = flag + dimensions = () + type = integer + intent = in +[iovr_convcld] + standard_name = flag_for_convective_cloud_overlap_method_for_radiation + long_name = flag for convective cloud overlap method + units = flag + dimensions = () + type = integer intent = in [ncol] standard_name = horizontal_loop_extent @@ -106,6 +127,14 @@ type = real kind = kind_phys intent = in +[cld_cnv_frac] + standard_name = convective_cloud_fraction_for_RRTMGP + long_name = layer convective cloud fraction + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in [precip_frac] standard_name = precipitation_fraction_by_layer long_name = precipitation fraction in each layer @@ -122,6 +151,14 @@ type = real kind = kind_phys intent = in +[cnv_cloud_overlap_param] + standard_name = convective_cloud_overlap_param + long_name = convective cloud overlap parameter + units = km + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in [precip_overlap_param] standard_name = precip_overlap_param long_name = precipitation overlap parameter @@ -137,6 +174,13 @@ dimensions = () type = ty_optical_props_2str intent = in +[lw_optical_props_cnvcloudsByBand] + standard_name = longwave_optical_properties_for_convective_cloudy_atmosphere_by_band + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + intent = in [lw_optical_props_precipByBand] standard_name = longwave_optical_properties_for_precipitation_by_band long_name = Fortran DDT containing RRTMGP optical properties @@ -158,6 +202,13 @@ dimensions = () type = ty_optical_props_2str intent = inout +[lw_optical_props_cnvclouds] + standard_name = longwave_optical_properties_for_convective_cloudy_atmosphere + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + intent = inout [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/rrtmgp_lw_rte.F90 b/physics/rrtmgp_lw_rte.F90 index aed4f0027..a141a4e08 100644 --- a/physics/rrtmgp_lw_rte.F90 +++ b/physics/rrtmgp_lw_rte.F90 @@ -26,10 +26,12 @@ end subroutine rrtmgp_lw_rte_init !! \htmlinclude rrtmgp_lw_rte_run.html !! subroutine rrtmgp_lw_rte_run(doLWrad, doLWclrsky, use_LW_jacobian, doGP_lwscat, nCol, & - nLev, top_at_1, sfc_emiss_byband, sources, lw_optical_props_clrsky, & - lw_optical_props_clouds, lw_optical_props_aerosol, nGauss_angles, fluxlwUP_allsky, & - fluxlwDOWN_allsky, fluxlwUP_clrsky, fluxlwDOWN_clrsky, fluxlwUP_jac, & - fluxlwUP_radtime, fluxlwDOWN_radtime, errmsg, errflg) + nLev, top_at_1, doGP_sgs_cnv, doGP_sgs_mynn, sfc_emiss_byband, sources, & + lw_optical_props_clrsky, lw_optical_props_clouds, lw_optical_props_precipByBand, & + lw_optical_props_cnvcloudsByBand, lw_optical_props_MYNNcloudsByBand, & + lw_optical_props_aerosol, nGauss_angles, fluxlwUP_allsky, fluxlwDOWN_allsky, & + fluxlwUP_clrsky, fluxlwDOWN_clrsky, fluxlwUP_jac, fluxlwUP_radtime, & + fluxlwDOWN_radtime, errmsg, errflg) ! Inputs logical, intent(in) :: & @@ -37,23 +39,27 @@ subroutine rrtmgp_lw_rte_run(doLWrad, doLWclrsky, use_LW_jacobian, doGP_lwscat, doLWrad, & ! Logical flag for longwave radiation call doLWclrsky, & ! Compute clear-sky fluxes for clear-sky heating-rate? use_LW_jacobian, & ! Compute Jacobian of LW to update radiative fluxes between radiation calls? + doGP_sgs_mynn, & ! Flag for sgs MYNN-EDMF PBL cloud scheme + doGP_sgs_cnv, & ! Flagg for sgs convective cloud scheme doGP_lwscat ! Include scattering in LW cloud-optics? integer, intent(in) :: & nCol, & ! Number of horizontal gridpoints nLev, & ! Number of vertical levels nGauss_angles ! Number of angles used in Gaussian quadrature - real(kind_phys), dimension(lw_gas_props%get_nband(),ncol), intent(in) :: & - sfc_emiss_byband ! Surface emissivity in each band + real(kind_phys), dimension(:,:), intent(in) :: & + sfc_emiss_byband ! Surface emissivity in each band type(ty_source_func_lw),intent(in) :: & - sources ! RRTMGP DDT: longwave source functions + sources ! RRTMGP DDT: longwave source functions type(ty_optical_props_1scl),intent(inout) :: & - lw_optical_props_aerosol, &! RRTMGP DDT: longwave aerosol radiative properties - lw_optical_props_clrsky ! RRTMGP DDT: longwave clear-sky radiative properties + lw_optical_props_aerosol, &! RRTMGP DDT: longwave aerosol optical properties + lw_optical_props_clrsky ! RRTMGP DDT: longwave clear-sky optical properties type(ty_optical_props_2str),intent(inout) :: & - lw_optical_props_clouds ! RRTMGP DDT: longwave cloud radiative properties - + lw_optical_props_clouds, & ! RRTMGP DDT: longwave cloud optical properties + lw_optical_props_precipByBand, & ! RRTMGP DDT: longwave precipitation optical properties + lw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: longwave convective cloud optical properties + lw_optical_props_MYNNcloudsByBand ! RRTMGP DDT: longwave MYNN-EDMF PBL cloud optical properties ! Outputs - real(kind_phys), dimension(ncol,nLev+1), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(inout) :: & fluxlwUP_jac, & ! Jacobian of upwelling LW surface radiation (W/m2/K) fluxlwUP_allsky, & ! All-sky flux (W/m2) fluxlwDOWN_allsky, & ! All-sky flux (W/m2) @@ -121,9 +127,22 @@ subroutine rrtmgp_lw_rte_run(doLWrad, doLWclrsky, use_LW_jacobian, doGP_lwscat, endif ! - ! All-sky fluxes + ! All-sky fluxes (clear-sky + clouds + precipitation) ! + ! Include convective cloud? + if (doGP_sgs_cnv) then + call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_cnvcloudsByBand%increment(lw_optical_props_clrsky)) + endif + + ! Include MYNN-EDMF PBL clouds? + if (doGP_sgs_mynn) then + call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_MYNNcloudsByBand%increment(lw_optical_props_clrsky)) + endif + + ! Add in precipitation + call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_precipByBand%increment(lw_optical_props_clouds)) + ! Include LW cloud-scattering? if (doGP_lwscat) then ! Add clear-sky optics to cloud-optics (2-stream) diff --git a/physics/rrtmgp_lw_rte.meta b/physics/rrtmgp_lw_rte.meta index 069537964..0ad0754b5 100644 --- a/physics/rrtmgp_lw_rte.meta +++ b/physics/rrtmgp_lw_rte.meta @@ -36,6 +36,20 @@ dimensions = () type = logical intent = in +[doGP_sgs_cnv] + standard_name = flag_to_include_sgs_convective_cloud_in_RRTMGP + long_name = logical flag to control sgs convective cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[doGP_sgs_mynn] + standard_name = flag_to_include_sgs_MYNN_EDMF_cloud_in_RRTMGP + long_name = logical flag to control MYNN-EDMF PBL cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in [ncol] standard_name = horizontal_loop_extent long_name = horizontal dimension @@ -86,6 +100,27 @@ dimensions = () type = ty_optical_props_2str intent = inout +[lw_optical_props_precipByBand] + standard_name = longwave_optical_properties_for_precipitation_by_band + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + intent = inout +[lw_optical_props_cnvcloudsByBand] + standard_name = longwave_optical_properties_for_convective_cloudy_atmosphere_by_band + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + intent = inout +[lw_optical_props_MYNNcloudsByBand] + standard_name = longwave_optical_properties_for_MYNN_EDMF_PBL_cloudy_atmosphere_by_band + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + intent = inout [lw_optical_props_aerosol] standard_name = longwave_optical_properties_for_aerosols long_name = Fortran DDT containing RRTMGP optical properties diff --git a/physics/rrtmgp_sw_cloud_optics.F90 b/physics/rrtmgp_sw_cloud_optics.F90 index f80440522..fd648de02 100644 --- a/physics/rrtmgp_sw_cloud_optics.F90 +++ b/physics/rrtmgp_sw_cloud_optics.F90 @@ -395,27 +395,34 @@ end subroutine rrtmgp_sw_cloud_optics_init !! \htmlinclude rrtmgp_sw_cloud_optics.html !! subroutine rrtmgp_sw_cloud_optics_run(doSWrad, doG_cldoptics, icliq_sw, icice_sw, & - doGP_cldoptics_PADE, doGP_cldoptics_LUT, nCol, nLev, nDay, nbndsGPsw, idxday, & - cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, & - cld_rerain, precip_frac, sw_optical_props_cloudsByBand, & - sw_optical_props_precipByBand, cldtausw, errmsg, errflg) + doGP_cldoptics_PADE, doGP_cldoptics_LUT, do_mynnedmf, imfdeepcnv, imfdeepcnv_gf, & + imfdeepcnv_samf, nCol, nLev, nDay, nbndsGPsw, idxday, cld_frac, cld_lwp, cld_reliq, & + cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, cld_rerain, precip_frac, & + cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, cld_cnv_reice, cld_pbl_lwp, cld_pbl_reliq, & + cld_pbl_iwp, cld_pbl_reice, sw_optical_props_cloudsByBand, & + sw_optical_props_cnvcloudsByBand, sw_optical_props_precipByBand, & + sw_optical_props_MYNNcloudsByBand, cldtausw, errmsg, errflg) ! Inputs logical, intent(in) :: & doSWrad, & ! Logical flag for shortwave radiation call doG_cldoptics, & ! Use legacy RRTMG cloud-optics? doGP_cldoptics_PADE, & ! Use RRTMGP cloud-optics: PADE approximation? - doGP_cldoptics_LUT ! Use RRTMGP cloud-optics: LUTs? + doGP_cldoptics_LUT, & ! Use RRTMGP cloud-optics: LUTs? + do_mynnedmf ! integer, intent(in) :: & nbndsGPsw, & ! Number of shortwave bands nCol, & ! Number of horizontal gridpoints nLev, & ! Number of vertical levels nday, & ! Number of daylit points. icliq_sw, & ! Choice of treatment of liquid cloud optical properties (RRTMG legacy) - icice_sw ! Choice of treatment of ice cloud optical properties (RRTMG legacy) - integer,intent(in),dimension(ncol) :: & + icice_sw, & ! Choice of treatment of ice cloud optical properties (RRTMG legacy) + imfdeepcnv, & ! + imfdeepcnv_gf, & ! + imfdeepcnv_samf ! + integer,intent(in),dimension(:) :: & idxday ! Indices for daylit points. - real(kind_phys), dimension(ncol,nLev),intent(in) :: & + real(kind_phys), dimension(:,:),intent(in) :: & cld_frac, & ! Total cloud fraction by layer cld_lwp, & ! Cloud liquid water path cld_reliq, & ! Cloud liquid effective radius @@ -425,18 +432,27 @@ subroutine rrtmgp_sw_cloud_optics_run(doSWrad, doG_cldoptics, icliq_sw, icice_sw cld_resnow, & ! Cloud snow effective radius cld_rwp, & ! Cloud rain water path cld_rerain, & ! Cloud rain effective radius - precip_frac ! Precipitation fraction by layer - + precip_frac, & ! Precipitation fraction by layer + cld_cnv_lwp, & ! Water path for convective liquid cloud-particles (microns) + cld_cnv_reliq, & ! Effective radius for convective liquid cloud-particles (microns) + cld_cnv_iwp, & ! Water path for convective ice cloud-particles (microns) + cld_cnv_reice, & ! Effective radius for convective ice cloud-particles (microns) + cld_pbl_lwp, & ! Water path for SGS PBL liquid cloud-particles + cld_pbl_reliq, & ! Effective radius for SGS PBL liquid cloud-particles + cld_pbl_iwp, & ! Water path for SGS PBL ice cloud-particles + cld_pbl_reice ! Effective radius for SGS PBL ice cloud-particles ! Outputs character(len=*), intent(out) :: & - errmsg ! CCPP error message + errmsg ! CCPP error message integer, intent(out) :: & - errflg ! CCPP error flag + errflg ! CCPP error flag type(ty_optical_props_2str),intent(out) :: & - sw_optical_props_cloudsByBand, & ! RRTMGP DDT: Shortwave optical properties in each band (clouds) - sw_optical_props_precipByBand ! RRTMGP DDT: Shortwave optical properties in each band (cloud precipitation) - real(kind_phys), dimension(ncol,NLev), intent(out) :: & - cldtausw ! Approx 10.mu band layer cloud optical depth + sw_optical_props_cloudsByBand, & ! RRTMGP DDT: Shortwave optical properties in each band (clouds) + sw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: Shortwave optical properties in each band (convective cloud) + sw_optical_props_MYNNcloudsByBand,& ! RRTMGP DDT: Shortwave optical properties in each band (MYNN PBL cloud) + sw_optical_props_precipByBand ! RRTMGP DDT: Shortwave optical properties in each band (cloud precipitation) + real(kind_phys), dimension(:,:), intent(out) :: & + cldtausw ! Approx 10.mu band layer cloud optical depth ! Local variables integer :: iDay, iLay, iBand @@ -457,26 +473,53 @@ subroutine rrtmgp_sw_cloud_optics_run(doSWrad, doG_cldoptics, icliq_sw, icice_sw ! Compute cloud/precipitation optics. if (doGP_cldoptics_PADE .or. doGP_cldoptics_LUT) then - call check_error_msg('rrtmgp_sw_cloud_optics_run',sw_optical_props_cloudsByBand%alloc_2str(& - nday, nLev, sw_cloud_props%get_band_lims_wavenumber())) - sw_optical_props_cloudsByBand%tau(:,:,:) = 0._kind_phys - sw_optical_props_cloudsByBand%ssa(:,:,:) = 1._kind_phys - sw_optical_props_cloudsByBand%g(:,:,:) = 0._kind_phys - call check_error_msg('rrtmgp_sw_cloud_optics_run',sw_optical_props_precipByBand%alloc_2str(& - nday, nLev, sw_cloud_props%get_band_lims_wavenumber())) + ! i) Cloud-optics. + call check_error_msg('rrtmgp_sw_cloud_optics_run - sw_optical_props_cloudsByBand',& + sw_optical_props_cloudsByBand%alloc_2str(nday, nLev, sw_cloud_props%get_band_lims_wavenumber())) + + call check_error_msg('rrtmgp_sw_cloud_optics_run - clouds',sw_cloud_props%cloud_optics(& + cld_lwp(idxday(1:nday),:), & ! IN - Cloud liquid water path + cld_iwp(idxday(1:nday),:), & ! IN - Cloud ice water path + cld_reliq(idxday(1:nday),:), & ! IN - Cloud liquid effective radius + cld_reice(idxday(1:nday),:), & ! IN - Cloud ice effective radius + sw_optical_props_cloudsByBand)) ! OUT - RRTMGP DDT: Shortwave optical properties, + ! in each band (tau,ssa,g) + + ! ii) Convective cloud-optics + if (imfdeepcnv == imfdeepcnv_samf .or. imfdeepcnv == imfdeepcnv_gf) then + call check_error_msg('rrtmgp_sw_cloud_optics_run - sw_optical_props_cnvcloudsByBand',& + sw_optical_props_cnvcloudsByBand%alloc_2str(nday, nLev, sw_cloud_props%get_band_lims_wavenumber())) + + call check_error_msg('rrtmgp_sw_cloud_optics_run - convective clouds',sw_cloud_props%cloud_optics(& + cld_cnv_lwp(idxday(1:nday),:), & ! IN - Convective cloud liquid water path + cld_cnv_iwp(idxday(1:nday),:), & ! IN - Convective cloud ice water path + cld_cnv_reliq(idxday(1:nday),:), & ! IN - Convective cloud liquid effective radius + cld_cnv_reice(idxday(1:nday),:), & ! IN - Convective cloud ice effective radius + sw_optical_props_cnvcloudsByBand)) ! OUT - RRTMGP DDT: Shortwave optical properties, + ! in each band (tau,ssa,g) + endif + + ! iii) MYNN cloud-optics + if (do_mynnedmf) then + call check_error_msg('rrtmgp_sw_cloud_optics_run - sw_optical_props_MYNNcloudsByBand',& + sw_optical_props_MYNNcloudsByBand%alloc_2str(nday, nLev, sw_cloud_props%get_band_lims_wavenumber())) + + call check_error_msg('rrtmgp_sw_MYNNcloud_optics_run - MYNN-EDMF cloud',sw_cloud_props%cloud_optics(& + cld_pbl_lwp(idxday(1:nday),:), & ! IN - MYNN-EDMF PBL cloud liquid water path (g/m2) + cld_pbl_iwp(idxday(1:nday),:), & ! IN - MYNN-EDMF PBL cloud ice water path (g/m2) + cld_pbl_reliq(idxday(1:nday),:), & ! IN - MYNN-EDMF PBL cloud liquid effective radius (microns) + cld_pbl_reice(idxday(1:nday),:), & ! IN - MYNN-EDMF PBL cloud ice effective radius (microns) + sw_optical_props_MYNNcloudsByBand)) ! OUT - RRTMGP DDT containing MYNN-EDMF PBL cloud radiative properties + ! in each band + endif + + ! iv) Cloud precipitation optics: rain and snow(+groupel) + call check_error_msg('rrtmgp_sw_cloud_optics_run - sw_optical_props_precipByBand',& + sw_optical_props_precipByBand%alloc_2str(nday, nLev, sw_cloud_props%get_band_lims_wavenumber())) sw_optical_props_precipByBand%tau(:,:,:) = 0._kind_phys sw_optical_props_precipByBand%ssa(:,:,:) = 1._kind_phys sw_optical_props_precipByBand%g(:,:,:) = 0._kind_phys - ! RRTMGP cloud-optics. - call check_error_msg('rrtmgp_sw_cloud_optics_run',sw_cloud_props%cloud_optics(& - cld_lwp(idxday(1:nday),:), & ! IN - Cloud liquid water path - cld_iwp(idxday(1:nday),:), & ! IN - Cloud ice water path - cld_reliq(idxday(1:nday),:), & ! IN - Cloud liquid effective radius - cld_reice(idxday(1:nday),:), & ! IN - Cloud ice effective radius - sw_optical_props_cloudsByBand)) ! OUT - RRTMGP DDT: Shortwave optical properties, - ! in each band (tau,ssa,g) - ! Cloud precipitation optics: rain and snow(+groupel) do iDay=1,nDay do iLay=1,nLev if (cld_frac(idxday(iDay),iLay) .gt. 1.e-12_kind_phys) then @@ -511,46 +554,6 @@ subroutine rrtmgp_sw_cloud_optics_run(doSWrad, doG_cldoptics, icliq_sw, icice_sw enddo enddo endif - if (doG_cldoptics) then - call check_error_msg('rrtmgp_sw_cloud_optics_run',sw_optical_props_cloudsByBand%alloc_2str(& - nday, nLev, sw_gas_props%get_band_lims_wavenumber())) - sw_optical_props_cloudsByBand%tau(:,:,:) = 0._kind_phys - sw_optical_props_cloudsByBand%ssa(:,:,:) = 1._kind_phys - sw_optical_props_cloudsByBand%g(:,:,:) = 0._kind_phys - call check_error_msg('rrtmgp_sw_cloud_optics_run',sw_optical_props_precipByBand%alloc_2str(& - nday, nLev, sw_gas_props%get_band_lims_wavenumber())) - sw_optical_props_precipByBand%tau(:,:,:) = 0._kind_phys - sw_optical_props_precipByBand%ssa(:,:,:) = 1._kind_phys - sw_optical_props_precipByBand%g(:,:,:) = 0._kind_phys - - ! RRTMG cloud(+precipitation) optics - if (any(cld_frac .gt. 0)) then - call rrtmg_sw_cloud_optics(nday, nLev, sw_gas_props%get_nband(), & - cld_lwp(idxday(1:nday),:), cld_reliq(idxday(1:nday),:), & - cld_iwp(idxday(1:nday),:), cld_reice(idxday(1:nday),:), & - cld_rwp(idxday(1:nday),:), cld_rerain(idxday(1:nday),:), & - cld_swp(idxday(1:nday),:), cld_resnow(idxday(1:nday),:), & - cld_frac(idxday(1:nday),:), icliq_sw, icice_sw, & - tau_cld, ssa_cld, asy_cld, & - tau_precip, ssa_precip, asy_precip) - - ! Cloud-optics (Need to reorder from G->GP band conventions) - sw_optical_props_cloudsByBand%tau(:,:,1) = tau_cld(:,:,sw_gas_props%get_nband()) - sw_optical_props_cloudsByBand%ssa(:,:,1) = ssa_cld(:,:,sw_gas_props%get_nband()) - sw_optical_props_cloudsByBand%g(:,:,1) = asy_cld(:,:,sw_gas_props%get_nband()) - sw_optical_props_cloudsByBand%tau(:,:,2:sw_gas_props%get_nband()) = tau_cld(:,:,1:sw_gas_props%get_nband()-1) - sw_optical_props_cloudsByBand%ssa(:,:,2:sw_gas_props%get_nband()) = ssa_cld(:,:,1:sw_gas_props%get_nband()-1) - sw_optical_props_cloudsByBand%g(:,:,2:sw_gas_props%get_nband()) = asy_cld(:,:,1:sw_gas_props%get_nband()-1) - ! Precipitation-optics (Need to reorder from G->GP band conventions) - sw_optical_props_precipByBand%tau(:,:,1) = tau_precip(:,:,sw_gas_props%get_nband()) - sw_optical_props_precipByBand%ssa(:,:,1) = ssa_precip(:,:,sw_gas_props%get_nband()) - sw_optical_props_precipByBand%g(:,:,1) = asy_precip(:,:,sw_gas_props%get_nband()) - sw_optical_props_precipByBand%tau(:,:,2:sw_gas_props%get_nband()) = tau_precip(:,:,1:sw_gas_props%get_nband()-1) - sw_optical_props_precipByBand%ssa(:,:,2:sw_gas_props%get_nband()) = ssa_precip(:,:,1:sw_gas_props%get_nband()-1) - sw_optical_props_precipByBand%g(:,:,2:sw_gas_props%get_nband()) = asy_precip(:,:,1:sw_gas_props%get_nband()-1) - - endif - endif ! All-sky SW optical depth ~0.55microns (DJS asks: Move to cloud diagnostics?) cldtausw(idxday(1:nDay),:) = sw_optical_props_cloudsByBand%tau(:,:,11) diff --git a/physics/rrtmgp_sw_cloud_optics.meta b/physics/rrtmgp_sw_cloud_optics.meta index d73258cb2..064b7cf80 100644 --- a/physics/rrtmgp_sw_cloud_optics.meta +++ b/physics/rrtmgp_sw_cloud_optics.meta @@ -147,6 +147,34 @@ dimensions = () type = logical intent = in +[do_mynnedmf] + standard_name = flag_for_mellor_yamada_nakanishi_niino_pbl_scheme + long_name = flag to activate MYNN-EDMF + units = flag + dimensions = () + type = logical + intent = in +[imfdeepcnv] + standard_name = control_for_deep_convection_scheme + long_name = flag for mass-flux deep convection scheme + units = flag + dimensions = () + type = integer + intent = in +[imfdeepcnv_gf] + standard_name = identifier_for_grell_freitas_deep_convection + long_name = flag for Grell-Freitas deep convection scheme + units = flag + dimensions = () + type = integer + intent = in +[imfdeepcnv_samf] + standard_name = identifer_for_scale_aware_mass_flux_deep_convection + long_name = flag for SAMF deep convection scheme + units = flag + dimensions = () + type = integer + intent = in [cld_frac] standard_name = total_cloud_fraction long_name = layer total cloud fraction @@ -227,6 +255,70 @@ type = real kind = kind_phys intent = in +[cld_cnv_lwp] + standard_name = convective_cloud_liquid_water_path + long_name = layer convective cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_iwp] + standard_name = convective_cloud_ice_water_path + long_name = layer convective cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_reliq] + standard_name = mean_effective_radius_for_liquid_convective_cloud + long_name = mean effective radius for liquid convective cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_reice] + standard_name = mean_effective_radius_for_ice_convective_cloud + long_name = mean effective radius for ice convective cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_lwp] + standard_name = MYNN_SGS_cloud_liquid_water_path + long_name = layer convective cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_iwp] + standard_name = MYNN_SGS_cloud_ice_water_path + long_name = layer convective cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_reliq] + standard_name = mean_effective_radius_for_liquid_MYNN_SGS_cloud + long_name = mean effective radius for liquid MYNN_SGS cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_reice] + standard_name = mean_effective_radius_for_ice_MYNN_SGS_cloud + long_name = mean effective radius for ice MYNN_SGS cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in [nbndsGPsw] standard_name = number_of_shortwave_bands long_name = number of sw bands used in RRTMGP @@ -255,6 +347,13 @@ dimensions = () type = ty_optical_props_2str intent = out +[sw_optical_props_cnvcloudsByBand] + standard_name = shortwave_optical_properties_for_convective_cloudy_atmosphere_by_band + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + intent = out [sw_optical_props_precipByBand] standard_name = shortwave_optical_properties_for_precipitation_by_band long_name = Fortran DDT containing RRTMGP optical properties @@ -262,6 +361,13 @@ dimensions = () type = ty_optical_props_2str intent = out +[sw_optical_props_MYNNcloudsByBand] + standard_name = shortwave_optical_properties_for_MYNN_EDMF_PBL_cloudy_atmosphere_by_band + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + intent = out [cldtausw] standard_name = cloud_optical_depth_layers_at_0p55mu_band long_name = approx .55mu band layer cloud optical depth diff --git a/physics/rrtmgp_sw_cloud_sampling.F90 b/physics/rrtmgp_sw_cloud_sampling.F90 index 3172ae315..c4a5de4c8 100644 --- a/physics/rrtmgp_sw_cloud_sampling.F90 +++ b/physics/rrtmgp_sw_cloud_sampling.F90 @@ -19,10 +19,12 @@ module rrtmgp_sw_cloud_sampling !! \htmlinclude rrtmgp_sw_cloud_sampling.html !! subroutine rrtmgp_sw_cloud_sampling_run(doSWrad, nCol, nDay, nLev, idxday, iovr, & - iovr_max, iovr_maxrand, iovr_rand, iovr_dcorr, iovr_exp, iovr_exprand, isubc_sw, & - icseed_sw, cld_frac, precip_frac, cloud_overlap_param, precip_overlap_param, & - sw_optical_props_cloudsByBand, sw_optical_props_precipByBand, & - sw_optical_props_clouds, sw_optical_props_precip, errmsg, errflg) + iovr_convcld, iovr_max, iovr_maxrand, iovr_rand, iovr_dcorr, iovr_exp, iovr_exprand, & + isubc_sw,icseed_sw, cld_frac, precip_frac, cloud_overlap_param, precip_overlap_param,& + imfdeepcnv, imfdeepcnv_gf, imfdeepcnv_samf, cnv_cloud_overlap_param, cld_cnv_frac, & + sw_optical_props_cnvcloudsByBand, sw_optical_props_cloudsByBand, & + sw_optical_props_precipByBand, sw_optical_props_clouds, sw_optical_props_cnvclouds, & + sw_optical_props_precip, errmsg, errflg) ! Inputs logical, intent(in) :: & @@ -31,7 +33,11 @@ subroutine rrtmgp_sw_cloud_sampling_run(doSWrad, nCol, nDay, nLev, idxday, iovr, nCol, & ! Number of horizontal gridpoints nDay, & ! Number of daylit points. nLev, & ! Number of vertical layers + imfdeepcnv, & ! + imfdeepcnv_gf, & ! + imfdeepcnv_samf, & ! iovr, & ! Choice of cloud-overlap method + iovr_convcld, & ! Choice of convective cloud-overlap method iovr_max, & ! Flag for maximum cloud overlap method iovr_maxrand, & ! Flag for maximum-random cloud overlap method iovr_rand, & ! Flag for random cloud overlap method @@ -39,21 +45,24 @@ subroutine rrtmgp_sw_cloud_sampling_run(doSWrad, nCol, nDay, nLev, idxday, iovr, iovr_exp, & ! Flag for exponential cloud overlap method iovr_exprand, & ! Flag for exponential-random cloud overlap method isubc_sw - integer,intent(in),dimension(ncol) :: & + integer,intent(in),dimension(:) :: & idxday ! Indices for daylit points. - integer,intent(in),dimension(ncol) :: & + integer,intent(in),dimension(:) :: & icseed_sw ! auxiliary special cloud related array when module ! variable isubc_sw=2, it provides permutation seed ! for each column profile that are used for generating ! random numbers. when isubc_sw /=2, it will not be used. - real(kind_phys), dimension(ncol,nLev),intent(in) :: & + real(kind_phys), dimension(:,:),intent(in) :: & cld_frac, & ! Total cloud fraction by layer + cld_cnv_frac, & ! Convective cloud fraction by layer precip_frac ! Precipitation fraction by layer - real(kind_phys), dimension(ncol,nLev), intent(in) :: & + real(kind_phys), dimension(:,:), intent(in) :: & cloud_overlap_param, & ! Cloud overlap parameter + cnv_cloud_overlap_param, & ! Convective cloud overlap parameter precip_overlap_param ! Precipitation overlap parameter type(ty_optical_props_2str),intent(in) :: & sw_optical_props_cloudsByBand, & ! RRTMGP DDT: Shortwave optical properties in each band (clouds) + sw_optical_props_cnvcloudsByBand,& ! RRTMGP DDT: Shortwave optical properties in each band (convectivecloud) sw_optical_props_precipByBand ! RRTMGP DDT: Shortwave optical properties in each band (precipitation) ! Outputs @@ -63,6 +72,7 @@ subroutine rrtmgp_sw_cloud_sampling_run(doSWrad, nCol, nDay, nLev, idxday, iovr, errflg ! Error flag type(ty_optical_props_2str),intent(out) :: & sw_optical_props_clouds, & ! RRTMGP DDT: Shortwave optical properties at each spectral point (clouds) + sw_optical_props_cnvclouds, & ! RRTMGP DDT: Shortwave optical properties at each spectral point (convectivecloud) sw_optical_props_precip ! RRTMGP DDT: Shortwave optical properties at each spectral point (precipitation) ! Local variables @@ -73,7 +83,7 @@ subroutine rrtmgp_sw_cloud_sampling_run(doSWrad, nCol, nDay, nLev, idxday, iovr, real(kind_phys), dimension(sw_gas_props%get_ngpt(),nLev,nday) :: rng3D,rng3D2 real(kind_phys), dimension(sw_gas_props%get_ngpt()*nLev) :: rng2D real(kind_phys), dimension(sw_gas_props%get_ngpt()) :: rng1D - logical, dimension(nday,nLev,sw_gas_props%get_ngpt()) :: cldfracMCICA,precipfracSAMP + logical, dimension(nday,nLev,sw_gas_props%get_ngpt()) :: maskMCICA ! Initialize CCPP error handling variables errmsg = '' @@ -121,7 +131,7 @@ subroutine rrtmgp_sw_cloud_sampling_run(doSWrad, nCol, nDay, nLev, idxday, iovr, ! Cloud overlap. ! Maximum-random, random, or maximum cloud overlap if (iovr == iovr_maxrand .or. iovr == iovr_max .or. iovr == iovr_rand) then - call sampled_mask(rng3D, cld_frac(idxday(1:nDay),:), cldfracMCICA) + call sampled_mask(rng3D, cld_frac(idxday(1:nDay),:), maskMCICA) endif ! Decorrelation-length overlap if (iovr == iovr_dcorr) then @@ -130,13 +140,13 @@ subroutine rrtmgp_sw_cloud_sampling_run(doSWrad, nCol, nDay, nLev, idxday, iovr, call random_number(rng2D,rng_stat) rng3D2(:,:,iday) = reshape(source = rng2D,shape=[sw_gas_props%get_ngpt(),nLev]) enddo - call sampled_mask(rng3D, cld_frac(idxday(1:nDay),:), cldfracMCICA, & + call sampled_mask(rng3D, cld_frac(idxday(1:nDay),:), maskMCICA, & overlap_param = cloud_overlap_param(idxday(1:nDay),1:nLev-1),& randoms2 = rng3D2) endif ! Exponential or exponential-random cloud overlap if (iovr == iovr_exp .or. iovr == iovr_exprand) then - call sampled_mask(rng3D, cld_frac(idxday(1:nDay),:), cldfracMCICA, & + call sampled_mask(rng3D, cld_frac(idxday(1:nDay),:), maskMCICA, & overlap_param = cloud_overlap_param(idxday(1:nDay),1:nLev-1)) endif @@ -144,76 +154,9 @@ subroutine rrtmgp_sw_cloud_sampling_run(doSWrad, nCol, nDay, nLev, idxday, iovr, ! Sampling. Map band optical depth to each g-point using McICA ! call check_error_msg('rrtmgp_sw_cloud_sampling_run_draw_samples', & - draw_samples(cldfracMCICA, .true., & + draw_samples(maskMCICA, .true., & sw_optical_props_cloudsByBand, & sw_optical_props_clouds)) - - ! ################################################################################# - ! Next sample precipitation (same as clouds for now) - ! ################################################################################# - - ! Allocate space RRTMGP DDTs [nday,nLev,nGpt] - call check_error_msg('rrtmgp_sw_cloud_sampling_run', & - sw_optical_props_precip%alloc_2str( nday, nLev, sw_gas_props)) - - ! Precipitation overlap - ! Maximum-random, random or maximum precipitation overlap - if (iovr == iovr_maxrand .or. iovr == iovr_max .or. iovr == iovr_rand) then - call sampled_mask(rng3D, precip_frac(idxday(1:nDay),:), precipfracSAMP) - endif - ! Exponential decorrelation length overlap - if (iovr == iovr_dcorr) then - call sampled_mask(rng3D, precip_frac(idxday(1:nDay),:), precipfracSAMP, & - overlap_param = precip_overlap_param(idxday(1:nDay),1:nLev-1),& - randoms2 = rng3D2) - endif - if (iovr == iovr_exp .or. iovr == iovr_exprand) then - call sampled_mask(rng3D, precip_frac(idxday(1:nDay),:),precipfracSAMP, & - overlap_param = precip_overlap_param(idxday(1:nDay),1:nLev-1)) - endif - - ! - ! Sampling. Map band optical depth to each g-point using McICA - ! - call check_error_msg('rrtmgp_sw_precip_sampling_run_draw_samples', & - draw_samples(precipfracSAMP, .true., & - sw_optical_props_precipByBand, & - sw_optical_props_precip)) - - ! ################################################################################# - ! Just add precipitation optics to cloud-optics - ! ################################################################################# - do iGpt=1,sw_gas_props%get_ngpt() - do iday=1,nDay - do iLay=1,nLev - tauloc = sw_optical_props_clouds%tau(iday,iLay,iGpt) + & - sw_optical_props_precip%tau(iday,iLay,iGpt) - if (sw_optical_props_precip%tau(iday,iLay,iGpt) > 0) then - ssaloc = (sw_optical_props_clouds%tau(iday,iLay,iGpt) * & - sw_optical_props_clouds%ssa(iday,iLay,iGpt) + & - sw_optical_props_precip%tau(iday,iLay,iGpt) * & - sw_optical_props_precip%ssa(iday,iLay,iGpt)) / & - tauloc - if (ssaloc > 0) then - asyloc = (sw_optical_props_clouds%tau(iday,iLay,iGpt) * & - sw_optical_props_clouds%ssa(iday,iLay,iGpt) * & - sw_optical_props_clouds%g(iday,iLay,iGpt) + & - sw_optical_props_precip%tau(iday,iLay,iGpt) * & - sw_optical_props_precip%ssa(iday,iLay,iGpt) * & - sw_optical_props_precip%g(iday,iLay,iGpt)) / & - (tauloc*ssaloc) - else - tauloc = sw_optical_props_clouds%tau(iday,iLay,iGpt) - ssaloc = sw_optical_props_clouds%ssa(iday,iLay,iGpt) - asyloc = sw_optical_props_clouds%g(iday,iLay,iGpt) - endif - sw_optical_props_clouds%tau(iday,iLay,iGpt) = tauloc - sw_optical_props_clouds%ssa(iday,iLay,iGpt) = ssaloc - sw_optical_props_clouds%g(iday,iLay,iGpt) = asyloc - endif - enddo - enddo - enddo endif end subroutine rrtmgp_sw_cloud_sampling_run diff --git a/physics/rrtmgp_sw_cloud_sampling.meta b/physics/rrtmgp_sw_cloud_sampling.meta index cda161e81..1415108f8 100644 --- a/physics/rrtmgp_sw_cloud_sampling.meta +++ b/physics/rrtmgp_sw_cloud_sampling.meta @@ -14,6 +14,34 @@ dimensions = () type = logical intent = in +[imfdeepcnv] + standard_name = control_for_deep_convection_scheme + long_name = flag for mass-flux deep convection scheme + units = flag + dimensions = () + type = integer + intent = in +[imfdeepcnv_gf] + standard_name = identifier_for_grell_freitas_deep_convection + long_name = flag for Grell-Freitas deep convection scheme + units = flag + dimensions = () + type = integer + intent = in +[imfdeepcnv_samf] + standard_name = identifer_for_scale_aware_mass_flux_deep_convection + long_name = flag for SAMF deep convection scheme + units = flag + dimensions = () + type = integer + intent = in +[iovr_convcld] + standard_name = flag_for_convective_cloud_overlap_method_for_radiation + long_name = flag for convective cloud overlap method + units = flag + dimensions = () + type = integer + intent = in [ncol] standard_name = horizontal_loop_extent long_name = horizontal dimension @@ -121,6 +149,22 @@ type = real kind = kind_phys intent = in +[cld_cnv_frac] + standard_name = convective_cloud_fraction_for_RRTMGP + long_name = layer convective cloud fraction + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cnv_cloud_overlap_param] + standard_name = convective_cloud_overlap_param + long_name = convective cloud overlap parameter + units = km + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in [cloud_overlap_param] standard_name = cloud_overlap_param long_name = cloud overlap parameter @@ -144,6 +188,13 @@ dimensions = () type = ty_optical_props_2str intent = in +[sw_optical_props_cnvcloudsByBand] + standard_name = shortwave_optical_properties_for_convective_cloudy_atmosphere_by_band + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + intent = in [sw_optical_props_precipByBand] standard_name = shortwave_optical_properties_for_precipitation_by_band long_name = Fortran DDT containing RRTMGP optical properties @@ -158,6 +209,13 @@ dimensions = () type = ty_optical_props_2str intent = out +[sw_optical_props_cnvclouds] + standard_name = shortwave_optical_properties_for_convective_cloudy_atmosphere + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + intent = out [sw_optical_props_precip] standard_name = shortwave_optical_properties_for_precipitation long_name = Fortran DDT containing RRTMGP optical properties diff --git a/physics/rrtmgp_sw_rte.F90 b/physics/rrtmgp_sw_rte.F90 index 1726d4bbd..e1879bd7a 100644 --- a/physics/rrtmgp_sw_rte.F90 +++ b/physics/rrtmgp_sw_rte.F90 @@ -24,53 +24,58 @@ end subroutine rrtmgp_sw_rte_init !! \section arg_table_rrtmgp_sw_rte_run !! \htmlinclude rrtmgp_sw_rte.html !! - subroutine rrtmgp_sw_rte_run(doSWrad, doSWclrsky, nCol, nLev, nDay, idxday, coszen, p_lay, & - t_lay, top_at_1, iSFC, sw_optical_props_clrsky, sfc_alb_nir_dir, sfc_alb_nir_dif, & - sfc_alb_uvvis_dir, sfc_alb_uvvis_dif, toa_src_sw, sw_optical_props_clouds, & - sw_optical_props_aerosol, scmpsw, fluxswUP_allsky, fluxswDOWN_allsky, fluxswUP_clrsky,& - fluxswDOWN_clrsky, errmsg, errflg) - + subroutine rrtmgp_sw_rte_run(doSWrad, doSWclrsky, nCol, nLev, nDay, idxday, coszen, p_lay,& + t_lay, top_at_1, doGP_sgs_cnv, doGP_sgs_mynn, iSFC, sfc_alb_nir_dir, sfc_alb_nir_dif,& + sfc_alb_uvvis_dir, sfc_alb_uvvis_dif, toa_src_sw, sw_optical_props_clrsky, & + sw_optical_props_clouds, sw_optical_props_precipByBand, & + sw_optical_props_cnvcloudsByBand, sw_optical_props_MYNNcloudsByBand, & + sw_optical_props_aerosol, scmpsw, fluxswUP_allsky, fluxswDOWN_allsky, & + fluxswUP_clrsky, fluxswDOWN_clrsky, errmsg, errflg) + ! Inputs logical, intent(in) :: & - top_at_1, & ! Vertical ordering flag - doSWrad, & ! Flag to calculate SW irradiances - doSWclrsky ! Compute clear-sky fluxes? + top_at_1, & ! Vertical ordering flag + doGP_sgs_mynn, & ! Flag for MYNN-EDMF PBL cloud scheme + doGP_sgs_cnv, & ! Flag for sgs convective clouds scheme + doSWrad, & ! Flag to calculate SW irradiances + doSWclrsky ! Compute clear-sky fluxes? integer, intent(in) :: & - nCol, & ! Number of horizontal gridpoints - nday, & ! Number of daytime points - nLev, & ! Number of vertical levels - iSFC ! Vertical index for surface-level - integer, intent(in), dimension(ncol) :: & - idxday ! Index array for daytime points - real(kind_phys),intent(in), dimension(ncol) :: & - coszen ! Cosize of SZA - real(kind_phys), dimension(ncol,NLev), intent(in) :: & - p_lay, & ! Pressure @ model layer-centers (Pa) - t_lay ! Temperature (K) + nCol, & ! Number of horizontal gridpoints + nday, & ! Number of daytime points + nLev, & ! Number of vertical levels + iSFC ! Vertical index for surface-level + integer, intent(in), dimension(:) :: & + idxday ! Index array for daytime points + real(kind_phys),intent(in), dimension(:) :: & + sfc_alb_nir_dir, & ! Surface albedo (direct) + sfc_alb_nir_dif, & ! Surface albedo (diffuse) + sfc_alb_uvvis_dir, & ! Surface albedo (direct) + sfc_alb_uvvis_dif, & ! Surface albedo (diffuse) + coszen ! Cosize of SZA + real(kind_phys), dimension(:,:), intent(in) :: & + p_lay, & ! Pressure @ model layer-centers (Pa) + t_lay, & ! Temperature (K) + toa_src_sw ! TOA incident spectral flux (W/m2) type(ty_optical_props_2str),intent(inout) :: & - sw_optical_props_clrsky ! RRTMGP DDT: shortwave clear-sky radiative properties - type(ty_optical_props_2str),intent(in) :: & - sw_optical_props_clouds, & ! RRTMGP DDT: shortwave cloud radiative properties - sw_optical_props_aerosol ! RRTMGP DDT: shortwave aerosol radiative properties - real(kind_phys), dimension(sw_gas_props%get_nband(),ncol), intent(in) :: & - sfc_alb_nir_dir, & ! Surface albedo (direct) - sfc_alb_nir_dif, & ! Surface albedo (diffuse) - sfc_alb_uvvis_dir, & ! Surface albedo (direct) - sfc_alb_uvvis_dif ! Surface albedo (diffuse) - real(kind_phys), dimension(ncol,sw_gas_props%get_ngpt()), intent(in) :: & - toa_src_sw ! TOA incident spectral flux (W/m2) + sw_optical_props_clrsky ! RRTMGP DDT: shortwave clear-sky radiative properties + type(ty_optical_props_2str),intent(in) :: & + sw_optical_props_clouds, & ! RRTMGP DDT: shortwave cloud optical properties + sw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: shortwave convecive cloud optical properties + sw_optical_props_MYNNcloudsByBand, & ! RRTMGP DDT: shortwave MYNN-EDMF PBL cloud optical properties + sw_optical_props_precipByBand, & ! RRTMGP DDT: shortwave precipitation optical properties + sw_optical_props_aerosol ! RRTMGP DDT: shortwave aerosol optical properties ! Outputs character(len=*), intent(out) :: & errmsg ! CCPP error message integer, intent(out) :: & errflg ! CCPP error flag - real(kind_phys), dimension(ncol,NLev+1), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(inout) :: & fluxswUP_allsky, & ! RRTMGP upward all-sky flux profiles (W/m2) fluxswDOWN_allsky, & ! RRTMGP downward all-sky flux profiles (W/m2) fluxswUP_clrsky, & ! RRTMGP upward clear-sky flux profiles (W/m2) fluxswDOWN_clrsky ! RRTMGP downward clear-sky flux profiles (W/m2) - type(cmpfsw_type), dimension(ncol), intent(inout) :: & + type(cmpfsw_type), dimension(:), intent(inout) :: & scmpsw ! 2D surface fluxes, components: ! uvbfc - total sky downward uv-b flux (W/m2) ! uvbf0 - clear sky downward uv-b flux (W/m2) @@ -88,7 +93,9 @@ subroutine rrtmgp_sw_rte_run(doSWrad, doSWclrsky, nCol, nLev, nDay, idxday, cosz real(kind_phys), dimension(nday,NLev+1,sw_gas_props%get_nband()),target :: & fluxSW_up_allsky, fluxSW_up_clrsky, fluxSW_dn_allsky, fluxSW_dn_clrsky, fluxSW_dn_dir_allsky real(kind_phys), dimension(ncol,NLev) :: vmrTemp - integer :: iBand + integer :: iBand, iDay,ibd + real(kind_phys), dimension(2,sw_gas_props%get_nband()) :: bandlimits + real(kind_phys), dimension(2), parameter :: nIR_uvvis_bnd = (/12850,16000/) ! Initialize CCPP error handling variables errmsg = '' @@ -105,23 +112,30 @@ subroutine rrtmgp_sw_rte_run(doSWrad, doSWclrsky, nCol, nLev, nDay, idxday, cosz flux_clrsky%bnd_flux_up => fluxSW_up_clrsky flux_clrsky%bnd_flux_dn => fluxSW_dn_clrsky - ! *Note* Legacy RRTMG code. May need to revisit + ! Use near-IR albedo for bands with wavenumbers extending to 12850cm-1 + ! Use uv-vis albedo for bands with wavenumbers greater than 16000cm-1 + ! For overlapping band, average near-IR and us-vis albedos. + bandlimits = sw_gas_props%get_band_lims_wavenumber() do iBand=1,sw_gas_props%get_nband() - if (iBand .lt. 10) then - sfc_alb_dir(iBand,:) = sfc_alb_nir_dir(iBand,idxday(1:nday)) - sfc_alb_dif(iBand,:) = sfc_alb_nir_dif(iBand,idxday(1:nday)) + if (bandlimits(1,iBand) .lt. nIR_uvvis_bnd(1)) then + sfc_alb_dir(iBand,:) = sfc_alb_nir_dir(idxday(1:nday)) + sfc_alb_dif(iBand,:) = sfc_alb_nir_dif(idxday(1:nday)) endif - if (iBand .eq. 10) then - sfc_alb_dir(iBand,:) = 0.5_kind_phys*(sfc_alb_nir_dir(iBand,idxday(1:nday)) + sfc_alb_uvvis_dir(iBand,idxday(1:nday))) - sfc_alb_dif(iBand,:) = 0.5_kind_phys*(sfc_alb_nir_dif(iBand,idxday(1:nday)) + sfc_alb_uvvis_dif(iBand,idxday(1:nday))) + if (bandlimits(1,iBand) .eq. nIR_uvvis_bnd(1)) then + sfc_alb_dir(iBand,:) = 0.5_kind_phys*(sfc_alb_nir_dir(idxday(1:nday)) + sfc_alb_uvvis_dir(idxday(1:nday))) + sfc_alb_dif(iBand,:) = 0.5_kind_phys*(sfc_alb_nir_dif(idxday(1:nday)) + sfc_alb_uvvis_dif(idxday(1:nday))) + ibd = iBand endif - if (iBand .gt. 10) then - sfc_alb_dir(iBand,:) = sfc_alb_uvvis_dir(iBand,idxday(1:nday)) - sfc_alb_dif(iBand,:) = sfc_alb_uvvis_dif(iBand,idxday(1:nday)) + if (bandlimits(1,iBand) .ge. nIR_uvvis_bnd(2)) then + sfc_alb_dir(iBand,:) = sfc_alb_uvvis_dir(idxday(1:nday)) + sfc_alb_dif(iBand,:) = sfc_alb_uvvis_dif(idxday(1:nday)) endif enddo + ! ! Compute clear-sky fluxes (if requested) + ! + ! Clear-sky fluxes (gas+aerosol) call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_aerosol%increment(sw_optical_props_clrsky)) ! Delta-scale optical properties @@ -139,10 +153,25 @@ subroutine rrtmgp_sw_rte_run(doSWrad, doSWclrsky, nCol, nLev, nDay, idxday, cosz fluxswUP_clrsky(idxday(1:nday),:) = sum(flux_clrsky%bnd_flux_up,dim=3) fluxswDOWN_clrsky(idxday(1:nday),:) = sum(flux_clrsky%bnd_flux_dn,dim=3) endif - + + ! ! Compute all-sky fluxes - ! All-sky fluxes (clear-sky + clouds) + ! + + ! Include convective cloud? + if (doGP_sgs_cnv) then + call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_cnvcloudsByBand%increment(sw_optical_props_clrsky)) + endif + + ! Include MYNN-EDMF PBL cloud? + if (doGP_sgs_mynn) then + call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_MYNNcloudsByBand%increment(sw_optical_props_clrsky)) + endif + + ! All-sky fluxes (clear-sky + clouds + precipitation) + call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_precipByBand%increment(sw_optical_props_clrsky)) call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_clouds%increment(sw_optical_props_clrsky)) + ! Delta-scale optical properties call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_clrsky%delta_scale()) call check_error_msg('rrtmgp_sw_rte_run',rte_sw( & @@ -153,12 +182,26 @@ subroutine rrtmgp_sw_rte_run(doSWrad, doSWclrsky, nCol, nLev, nDay, idxday, cosz sfc_alb_dir, & ! IN - Shortwave surface albedo (direct) sfc_alb_dif, & ! IN - Shortwave surface albedo (diffuse) flux_allsky)) ! OUT - Fluxes, clear-sky, 3D (nCol,NLev,nBand) + ! Store fluxes fluxswUP_allsky(idxday(1:nday),:) = sum(flux_allsky%bnd_flux_up,dim=3) fluxswDOWN_allsky(idxday(1:nday),:) = sum(flux_allsky%bnd_flux_dn,dim=3) - scmpsw(idxday(1:nday))%nirbm = sum(flux_allsky%bnd_flux_dn_dir(1:nday,iSFC,:),dim=2) - scmpsw(idxday(1:nday))%nirdf = sum(flux_allsky%bnd_flux_dn( 1:nday,iSFC,:),dim=2) - & - sum(flux_allsky%bnd_flux_dn_dir(1:nday,iSFC,:),dim=2) + do iDay=1,nDay + ! Near IR + scmpsw(idxday(iDay))%nirbm = sum(flux_allsky%bnd_flux_dn_dir(iDay,iSFC,1:ibd-1)) + & + flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd)/2. + scmpsw(idxday(iDay))%nirdf = (sum(flux_allsky%bnd_flux_dn(iDay,iSFC,1:ibd-1)) + & + flux_allsky%bnd_flux_dn(iDay,iSFC,ibd)/2.) - & + (sum(flux_allsky%bnd_flux_dn_dir(iDay,iSFC,1:ibd-1)) + & + flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd)/2.) + ! UV-VIS + scmpsw(idxday(iDay))%visbm = sum(flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd+1:sw_gas_props%get_nband())) + & + flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd)/2. + scmpsw(idxday(iDay))%visdf = (sum(flux_allsky%bnd_flux_dn(iDay,iSFC,ibd+1:sw_gas_props%get_nband())) + & + flux_allsky%bnd_flux_dn(iDay,iSFC,ibd)/2. ) - & + (sum(flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd+1:sw_gas_props%get_nband())) + & + flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd)/2.) + enddo else fluxswUP_allsky(:,:) = 0._kind_phys fluxswDOWN_allsky(:,:) = 0._kind_phys @@ -166,6 +209,7 @@ subroutine rrtmgp_sw_rte_run(doSWrad, doSWclrsky, nCol, nLev, nDay, idxday, cosz fluxswDOWN_clrsky(:,:) = 0._kind_phys scmpsw = cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ) endif + end subroutine rrtmgp_sw_rte_run ! ######################################################################################### diff --git a/physics/rrtmgp_sw_rte.meta b/physics/rrtmgp_sw_rte.meta index e59698c0f..9ab24c8b3 100644 --- a/physics/rrtmgp_sw_rte.meta +++ b/physics/rrtmgp_sw_rte.meta @@ -73,6 +73,20 @@ dimensions = () type = logical intent = in +[doGP_sgs_cnv] + standard_name = flag_to_include_sgs_convective_cloud_in_RRTMGP + long_name = logical flag to control sgs convective cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[doGP_sgs_mynn] + standard_name = flag_to_include_sgs_MYNN_EDMF_cloud_in_RRTMGP + long_name = logical flag to control MYNN-EDMF PBL cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in [iSFC] standard_name = vertical_index_for_surface_in_RRTMGP long_name = index for surface layer in RRTMGP @@ -102,6 +116,27 @@ dimensions = () type = ty_optical_props_2str intent = in +[sw_optical_props_precipByBand] + standard_name = shortwave_optical_properties_for_precipitation_by_band + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + intent = in +[sw_optical_props_cnvcloudsByBand] + standard_name = shortwave_optical_properties_for_convective_cloudy_atmosphere_by_band + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + intent = in +[sw_optical_props_MYNNcloudsByBand] + standard_name = shortwave_optical_properties_for_MYNN_EDMF_PBL_cloudy_atmosphere_by_band + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + intent = in [sw_optical_props_aerosol] standard_name = shortwave_optical_properties_for_aerosols long_name = Fortran DDT containing RRTMGP optical properties @@ -110,34 +145,34 @@ type = ty_optical_props_2str intent = in [sfc_alb_nir_dir] - standard_name = surface_albedo_nearIR_direct - long_name = near-IR (direct) surface albedo (sfc_alb_nir_dir) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) + standard_name = surface_albedo_due_to_near_IR_direct + long_name = surface albedo due to near IR direct beam + units = frac + dimensions = (horizontal_loop_extent) type = real kind = kind_phys intent = in [sfc_alb_nir_dif] - standard_name = surface_albedo_nearIR_diffuse - long_name = near-IR (diffuse) surface albedo (sfc_alb_nir_dif) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) + standard_name = surface_albedo_due_to_near_IR_diffused + long_name = surface albedo due to near IR diffused beam + units = frac + dimensions = (horizontal_loop_extent) type = real kind = kind_phys intent = in [sfc_alb_uvvis_dir] - standard_name = surface_albedo_uvvis_direct - long_name = UVVIS (direct) surface albedo (sfc_alb_uvvis_dir) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) + standard_name = surface_albedo_due_to_UV_and_VIS_direct + long_name = surface albedo due to UV+VIS direct beam + units = frac + dimensions = (horizontal_loop_extent) type = real kind = kind_phys intent = in [sfc_alb_uvvis_dif] - standard_name = surface_albedo_uvvis_diffuse - long_name = UVVIS (diffuse) surface albedo (sfc_alb_uvvis_dif) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) + standard_name = surface_albedo_due_to_UV_and_VIS_diffused + long_name = surface albedo due to UV+VIS diffused beam + units = frac + dimensions = (horizontal_loop_extent) type = real kind = kind_phys intent = in